Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Подробная анатомия простого плагина для XBMC

Anna | 16.06.2014 | нет комментариев

Вступление

Схожая статья на Прогре теснее публиковалась, но в ней основное внимание было уделено парсингу сайта с видео — так сказать, бизнес-логике плагина, а вопросы взаимодействия с XBMC затронуты мимоходом. Я же хочу рассказать о том, что трансформирует скрипт на языке Python (дальше — Питон) в плагин XBMC.
Данный плагин предуготовлен для просмотра видеоподкастов с сайта www.cnet.com в обыкновенном либо высоком качестве, в зависимости от настроек. Плагин не имеет никакого отношения к плагину просмотра подкастов CNET, доступному в официальном репозитории XBMC. Он всецело написан с 0 как учебный план в рамках независимого постижения собственно написания плагинов к XBMC. Плагин не претендует ни на полезность для широкой аудитории, ни на особенно выдающиеся программные решения. Впрочем он всецело рабочий, и в нем есть множество элементов, присущих «серьезным» плагинам: файл XML с метаданными, стержневой скрипт, внешний импортируемый модуль, панель настроек, файлы локализации, файлы источников (картинки). Верю, что плагин и данная статья сумеют послужить отправной точкой как для начинающих плагинописателей, так и для опытных программистов на Питоне, которые захотят приобщиться к написанию плагинов для XBMC.

Всецело плагин дозволено скачать отсель.

Примечание: дальше в тексте в отношении некоторых файлов и папок применяется термин «рабочий». Это обозначает, что XBMC ищет такие папки и файлы без прямого указания на них в коде плагина. «Рабочий» != «непременный», и больше примитивные плагины могут не содержать каких-то служебных файлов.

Всеобщая информация

Для написания плагинов XBMC применяется язык Питон. XBMC под Windows компилируется с версией 2.6.6, а под Linux, как я понимаю, версия Питона зависит от установленных девелоперских библиотек, используемых при сборке. В любом случае, при написании кода плагина стоит ориентироваться на синтаксис и вероятности Питона 2.6.
Питон в XBMC полнофункциональный: присутствует примерно каждая стандартная библиотека, помимо, разве что, Tkinter/ttk/tix (которые тут очевидно лишние). Для взаимодействия с XBMC добавлены 5 модулей: xbmc, xbmcgui, xbmcplugin, xbmcaddon и xbmcvfs, которые совместно составляют XBMC Python API. Короткую справку по модулям дозволено обнаружить тут. К сожалению, в справке встречаются неточности.
Помимо того, оператор print взамен консоли пишет в лог XBMC с ярусом Notice, что дозволено применять при отладке, скажем для итога значений переменных.
Немножко о терминологии: первоначально разработчики XBMC применяли термин «аддон» (addon) для всяких дополнений, которые, в свою очередь, подразделяются на плагины (источники контента), скрипты (программы), скреперы (загрузчики информации к медиаконтенту) и прочие. Впрочем со временем представления «аддон» и «плагин» перепутались, и теперь их Зачастую применяют для обозначения всякого дополнения.

Настройка IDE

Как теснее было сказано, плагины XBMC пишутся на языке Питон. Программа на этом языке представляет собой по сути текстовый файл, с которым дозволено трудиться в любом текстовом редакторе, начиная с Блокнота Windows и заканчивая «продвинутыми вариантами», как бы Notepad . Впрочем для написания всякого больше-менее трудного кода отменнее применять IDE (Integrated Development Environment), которая предлагает целый ряд удобств: подсветка кода, автодополнение ключевых слов, браузер кода, короткая справка по объектам и т. п. Многие программисты на Питоне Зачастую применяют связку Eclipse PyDev, но лично я выбираю больше легкий PyScripter, в котором есть примерно все функции полновесной IDE, помимо, разве что, сворачивания кода (code folding). Правда, план не прогрессирует с 2012 года, но для Питона 2.х его вероятностей больше чем хватает.
Для упрощения разработки плагинов на Питоне в IDE добродушные люди (включая меня) составили комплект питоновских модулей-заглушек, имитирующих настоящие модули XBMC Python API. Эти модули необходимо добавить в пути импорта плана («Properties» > «PYTHONPATH» > «Source folders» в Eclpispe/PyDev либо «Extra Python Path…» в PyScripter), и получаем Profit — начинают трудиться автодополнение кода и короткая справка для классов, способов и прочих элементов XBMC Python API.

Внимание: это именно модули-заглушки, не содержащие пригодного кода, и попытка запустить программу, которая на них ссылается, прямо из IDE приведет к непредвиденным итогам. Впрочем, желающие могут добавить в эти модули отладочный код, имитирующий поведение реальных функций и способов XBMC Python API.

Конструкция плагина

Мой «учебный» плагин имеет следующую конструкцию:

addon.xml
changelog.txt
default.py
fanart.jpg
icon.png
License.txt
resources
	settings.xml
	language
		English
			strings.po
		Russian
			strings.po
		Ukrainian
			strings.po
	lib
		feeds.py
	thumbnails

Сейчас подробнее о назначении всех этих файлов и папок.

addon.xml

addon.xml — рабочий файл плагина, из которого встроенный каталогизатор плагинов XBMC берет всю нужную информацию. Это исключительный непременный файл плагина, и некоторые типы плагинов (скреперы, репозитории и т. п.) могут вообще не содержать программного кода и других служебных файлов.

Содержимое файла:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Основная информация -->
<addon id="plugin.video.cnet"
version="0.0.1"
name="CNET Video Podcasts"
provider-name="Roman_V_M">
<!-- Зависимости -->
<requires>
  <import addon="xbmc.python" version="2.0"/>
</requires>
<!-- Тип (предназначение) плагина -->
<extension point="xbmc.python.pluginsource" library="default.py">
  <provides>video</provides>
</extension>
<!-- Изложение -->
<extension point="xbmc.addon.metadata"> 
  <summary lang="en">CNET Video Podcasts</summary>
  <summary lang="ru">Видео-подкасты CNET</summary>
  <summary lang="uk">Відео-подкасти CNET</summary>
  <description lang="en">Addon for watching CNET video podcasts from XBMC.</description>
  <description lang="ru">Дополнение для просмотра видео-подкастов CNET из XBMC.</description>
  <description lang="uk">Надбудова для прегляду відео-подкастів CNET з XBMC.</description>
  <platform>all</platform> 
</extension>
</addon>

Сейчас подробнее о содержимом. Для отображения номеров строк откройте файл в текстовом редакторе, поддерживающем такую вероятность.

Строки 3—6 содержат основную информацию о плагине: неповторимый идентификатор, совпадающий с именем папки плагина; версия; наименование, отображаемое в интерфейсе XBMC; автор(-ы) плагина.

Строки 8—10 содержат информацию о внешних зависимостях — других компонентах, нужных для работы плагина. Как видно, данный плагин требует только XBMC Python API версии не ниже 2.0. Точный номер применяемой в реальное время версии я не знаю, но 2.0 — заведомо рабочий вариант.
Если для работы вашего плагина требуется какой-либо иной плагин, указываем его тут в таком же тэге. Скажем, если для вашего плагина для чего-то требуется плагин Youtube, в раздел необходимо добавить дальнейший тэг:

<import addon="plugin.video.youtube" version="4.0.0"/>

Теоретически, отсутствующие зависимости обязаны установиться механически при установке плагина.

Строки 12—14 содержат информацию о типе плагина. extension point="xbmc.python.pluginsource"обозначает, что это плагин-источник контента, library="default.py" указывает на стартовый скрипт плагина, а video обозначает, что это видео-плагин. Если плагин предоставляет доступ к различному контенту, в тэге дозволено указать типы доступного контента через пробел. Допустимые значения: video, music и image. Эти значения определяют, в каком разделе будет отображаться данный плагин: «Видео», «Музыка» либо «Фото». Плагин для доступа к различным видам контента может отображаться в нескольких разделах.
Как теснее было сказано, «xbmc.python.pluginsource» обозначает, что это плагин-источник контента. Т. е., применяя терминологию разработчиков XBMC, это и есть подлинный плагин, в различие от скриптов и прочих типов аддонов. Основное отличие между плагинами-источниками и плагинами-скриптами (программными плагинами) заключается в том, что плагин-источник представляет пользователю мультимедийное оглавление в виде многоуровневых списков (каталогов), содержащих папки (виртуальные и/или настоящие) и файлы (локальные и/или в сети), в то время как скORE_THE) # Конец списка xbmcplugin.endOfDirectory(addon_id) # Переключаемся на необходимый вид. switch_view() # Переключаемся на необходимый вид в зависимости от нынешнего скина. def switch_view(): skin_used = xbmc.getSkinDir() if skin_used == ‘skin.confluence’: xbmc.executebuiltin(‘Container.SetViewMode(500)’) # Вид “Эскизы”. elif skin_used == ‘skin.aeon.nox’: xbmc.executebuiltin(‘Container.SetViewMode(512)’) # Вид “Инфо-стена” # Составляем список подкастов. def podcast_list(addon_id, fanart, thumb, listing): for item in listing: # Создаем элемент списка. list_item = xbmcgui.ListItem(item[0], thumbnailImage=thumb) # Определяем доп. свойства. list_item.setProperty(‘fanart_image’, fanart) # Добавляем элемент к списку. isFolder=False обозначает, что это файл для проигрывания. xbmcplugin.addDirectoryItem(addon_id, item[1], list_item, isFolder=False) # Конец списка. xbmcplugin.endOfDirectory(addon_id) def main(): # Пути к картинкам. thumbpath = os.path.join(_addon_path, ‘resources’, ‘thumbnails’) fanart = os.path.join(_addon_path, ‘fanart.jpg’) # Получаем имя требуемой ленты из параметра вызова плагина. feed = get_feed_name() # Если плагин запущен прямо из XBMC (не рекурсивно), то имя ленты будет пустое. if feed: # Получаем необходимое качество подкастов из настроек плагина. quality = _addon.getSetting(‘quality’) # Получаем список подкастов. listing = rss_parser(url=feeds.FEEDS[feed][quality]) if listing: # Пишем в лог. xbmc.log(‘%s: Started – Opening podcasts List’ % _ADDON_NAME, xbmc.LOGNOTICE) thumb = os.path.join(thumbpath, feeds.FEEDS[feed]['thumb']) # Выводим список подкастов. podcast_list(addon_id=_addon_id, fanart=fanart, thumb=thumb, listing=listing) else: # Если не удалось открыть ленту (оплошность сети), пишем об этом в лог xbmc.log(‘%s: Failed to retrieve %s feed data!’ % (_ADDON_NAME, feed), xbmc.LOGERROR) # и выводим сообщение об ошибке в интерфейсе XBMC. xbmc.executebuiltin(‘Notification(%s,%s)’ % (_string(100501), _string(100502))) else: # Если плагин запущен из XBMC (не рекурсивно), то вначале пишем в лог, xbmc.log(‘%s: Started – Opening feeds List’ % _ADDON_NAME, xbmc.LOGNOTICE) # а после этого выводим список лент. feed_list(addon_id=_addon_id, addon_url=_addon_url, fanart=fanart, thumbpath=thumbpath, feeds=feeds.FEEDS) if __name__ == ‘__main__’: main()

Дальше подробнейший разбор. ?вственные вещи пропускаю.

Строки 11—15 — определение параметров плагина. В большинстве плагинов применяются переменные с двойными подчеркиваниями, но мне они эстетически не нравятся, и, к тому же, их не рекомендует PEP 8.

Построчный разбор:

11: задаем имя плагина. Имя плагина должно совпадать с именем, указанным в addon.xml, и именем папки (в случае плагин может не трудиться).

12: создаем экземпляр класса Addon для доступа к настройкам плагина.

13: получаем runtime-идентификатор плагина (handle). Идентификатор — это целое число, которое передается как 2-й довод при вызове плагина из XBMC. Данный идентификатор применяется как один из доводов функции образования списков контента addDirectoryItem(). Тут стоит подробнее остановиться на параметрах вызова плагина. Как было сказано выше, различие от плагинов-источников контента и плагинов-скриптов заключается в том, что в плагины-источники представляют собой списки (каталоги) контента, в то время как скрипты могут делать всё что желательно в пределах вероятностей языка Питон и XBMC API. Дополнительное различие заключается в параметрах вызова, передаваемых плагину. При вызове из интерфейса XBMC либо рекурсивном вызове из самого себя (об этом ниже) плагин-источник получает 3 параметра в списке sys.argv: свой воображаемый URL, runtime-идентификатор (строка, содержащая целое число), и добавочные параметры вызова в виде URL-encoded последовательности. Плагин-скрипт, в свою очередь, не получает никаких параметров, и для него sys.argv представляет собой пустой список. Следственно функции и способы, требующие runtime-идентификатор плагина в качестве довода, скажем addDirectoryItem(), в плагинах-скриптах трудиться не будут. О виртуальном URL и дополнительных параметрах вызова ниже.

14: получаем воображаемый URL плагина. Воображаемый URL представляет собой адрес в виде ”plugin://” (имя плагина) ”/”. Воображаемый URL нашего плагина будет иметь вид: «plugin://plugin.video.cnet/». Данный URL применяется для образования виртуальных адресов виртуальных папок (умоляю помилования за тавтологию) в каталоге контента, формируемого скриптом. Это значит, что, встретив сходственный адрес, XBMC будет знать, что для открытия (реально — образования) соответствующего подраздела списка ему необходимо запустить указанный скрипт. Тут, я Ощущаю, необходимы добавочные пояснения.
Воображаемый каталоого раздела. Функция представляет собой простой парсер XML и иллюстрирует бизнес-логику плагина. Взамен нее могут быть использованы сколь желательно трудные парсеры, заточенные для доступа к разделам какого-либо сайта и приобретения прямых ссылок на помещенные на нем мультимедийные материалы (видео, музыку, фото).

52—64: функция образования списка групп подкастов сайта cnet.com — по сути, списка виртуальных папок. Разглядим ее детально.

57: тут для всякого элемента списка мы создаем экземпляр класса xbmcgui.ListItem. Данный класс представляет собой контейнер для хранения свойств некоторого элемента списка, представляющего мультимедийный контент. Элемент списка должен иметь, как минимум, текстовую подпись, но для положительного оформления для него желанно указать картинку (эскиз) и обои (фанарт).

59: добавляем фанарт к элементу списка. Как видно, для всех элементов списка применяется фанарт плагина, но ничто не мешает назначить всякому элементу личный фанарт.

61: составляем ссылку для рекурсивного вызова плагина. В качестве доводов вызова выступают очищенные от лишних символов наименования групп подкастов. Соответственно, при выборе соответствующей группы запущенный рекурсивно плагин сформирует список подкастов этой группы.

63: функция добавления элемента в список контента. Именно тут нам необходим идентификатор плагина, полученный из sys.argv[1]. Напомнию, что данный параметр передается только плагинам-источникам контента. Соответственно, во всех других видах плагинов функцию addDirectoryItem() применять невозможно. Параметр isFolder=True говорит XBMC, что данный элемент списка — виртуальная папка, т. е. при выборе этого элемента необходимо отобразить некоторый вложенный список, а не открыть эту ссылку в плеере. В параметре url мы добавляем ссылки на виртуальные папки, формируемые плагином, но тут также дозволено применять пути к реальным папкам с мультимедийными файлами на локальном либо сетевом диске.

65: добавляем способ сортировки. Дело в том, что по умолчанию элементы списка отображаются в порядке добавления, что не неизменно желанно.

67: говорим XBMC, что образование списка завершено.

69: вызываем функцию переключения вида (представления). Для списков контента, формируемых плагинами, применяется типовой вид нынешнего скина (как правило, примитивный список), и если мы хотим для своего плагина применять вид, чудесный от стандартного, то логику придется писать самому, причем для всякого скина индивидуально. Параметр Container.SetViewMode(ХХХ) как раз и представляет собой числовой код надобного вида скина, тот, что дозволено обнаружить в файлах MyVideoNav.xml, MyMusicNav.xml и MyPics.xml соответствующего скина для видео, музыки и фото соответственно.
К сожалению, переключение вида редко применяется в плагинах. Один из немногих реальных примеров применения — плагин Youtube.

72—77: собственно функция переключения вида. Мы получаем нынешний скин и переключаемся на необходимый вид. Код 500 соответствует виду «Эскизы» стандартного скина Confluence, а код 512 — виду «Инфо-стена» скина «Aeon-Nox». Для всех остальных скинов будет применяться их типовой вид.

80—89: функция составления списка подкастов, содержащего ссылки на файлы для проигрывания. Тут всё примерно так же, как в функции feed_list(), за исключением того, что URL элементов списка представляют собой ссылки непринужденно на видеофайлы и параметр isFolder для элемента списка равен False, т. е. это не папка (виртуальная либо настоящая) а медиафайл, тот, что передается плееру.

92—119: основная функция плагина. Думаю, тут всё ясно из комментариев. Я бы только хотел остановиться на паре строк.

101: получаем необходимое качество подкастов, выбранное в панели настроек плагина. Всякие настройки неизменно возвращаются в виде строк, и их необходимо приводить к необходимому типу, если нужно.

114: выводим сообщение об ошибке в интерфейсе XBMC. Тут как раз и применяется наша вспомогательная функция _string(), которая извлекает надобные строки из языковых файлов XBMC. Подробнее о языковых файлах ниже.

resources

Папка resources — служебная, и в ней содержатся разные добавочные файлы плагина.

settings.xml

settings.xml — рабочий файл, в котором на особом языке, основанном на XML, описывается панель настроек плагина, которая вызывается при выборе подменю «Настройки». Вследствие такому подходу панель настроек плагина неизменно имеет «родной» вид в любом скине.

Содержимое файла:

<?xml version="1.0" encoding="UTF-8"?>
<settings>
  <category label="128">
    <setting id="quality" type="labelenum" label="100500" values="HD|SD" default="HD" />
  </category>
</settings>

В данном случае панель настроек имеет один орган управления — спинбокс (labelenum) для выбора качества показываемых подкастов (HD либо SD). Параметры label= содержат текстовые изложения элементов панели настроек, и в них может быть как легкой текст, так и номера строк из языковых файлов. Для доступа к определенным настройкам применяются текстовые идентификаторы в параметрах id=”" (см. строку 101 default.py).
Подробное изложение синтаксиса файла settings.xml и доступных элементов управления дозволено обнаружить в начальстве «XBMC Addon Developers Guide» (английский язык). Это начальство по написанию плагинов несколько устарело, но всё равно содержит много пригодной информации, в том числе и об организации панели настроек плагина.

language

Подпапка language является служебной. В ней, в подпапках нижнего яруса, имеющих имена, соответствующие английским наименованиям различных языков, лежат языковые файлы плагина strings.po. В нашем плагине имеются подпапки English, Russian и Ukrainian, т. е. плагин имеет интерфейс на английском, русском и украинском языках. Плагин, имеющий свой интерфейс, должен содержать как минимум папку English с соответствующим языковым файлом. Однако, в некоторых случаях дозволено обойтись и без своих языковых файлов, но об этом чуть ниже.

Пример русского языкового файла strings.po:

# XBMC Media Center language file
msgid ""
msgstr ""

"Content-Type: text/plain; charset=UTF-8n"
"Content-Transfer-Encoding: 8bitn"
"Language: run"

msgctxt "#100500"
msgid "Quality:"
msgstr "Качество:"

msgctxt "#100501"
msgid "Access error!"
msgstr "Оплошность доступа!"

msgctxt "#100502"
msgid "Failed to retrieve the feed data."
msgstr "Не удалось получить данные с ленты."

Как видно, файл имеет формат .po GNU Gettext. Впрочем XBMC не использует подлинный Gettext: двуязычные файлы не компилируются в .mo, и для идентификации отдельных строк интерфейса применяются номера, указываемые в параметрах msgctxt. Связано это с историческими причинами: ранее XBMC применял личный формат языковых файлов на базе XML, впрочем с переходом на онлайновую систему перевода www.transifex.net было решено перейти на больше общеизвестный и поддерживаемый формат локализации. По-видимому, такой промежуточный вариант с применением текстовых файлов .po было внедрить проще, чем всецело перейти на Gettext.
Как теснее было сказано, строки интерфейса извлекаются способом getLocalizedString() по номеру в msgctxt. При этом применяется сквозная нумерация: стержневой языковый файл XBMC языковый файл плагина. Желанно, Дабы номера строк основного языкового файла и плагина не повторялись. В тезисе, при совпадении номеров в обоих файлах приоритет имеет языковый файл плагина, но, абсолютно допустимо, это является багом, и полагаться на такое поведение невозможно. Следственно выбирайте для строк интерфейса плагина личные номера. Номера строк языковых файлов применяются как в коде плагина при создании элементов интерфейса и итоге сообщений, так и в файле с изложением панели настроек settings.xml для отображения подписей к элементам управления.
В тезисе, если все надобные строки интерфейса дозволено обнаружить в основном языковом файле XBMC, то в самом плагине языковые файлы дозволено не создавать. В таком случае в соответствующих местах будут применяться номера строк из основного языкового файла.

lib

В подпапке lib содержится наш добавочный питоновский модуль, экспортируемый в плагин. Подапка lib не служебная. Она может именоваться как желательно, и сами экспортируемые модули могут располагаться где желательно: рядом с основным скриптом плагина, в подпапке первого яруса и т. п. Основное, Дабы они были доступны для импорта. Легко, как правило, комфортнее, если все добавочные файлы плагина, как служебные, так и нет, размещались в одном месте.

thumbnails

В подпапке thumbnails лежат картинки с логотипами подкастов cnet.com. Как иlib, эта подпапка не служебная, и картинки могут лежать в любом доступном месте по вашему выбору.

Отладка

Несколько слов об отладке плагинов. При отсутствии консоли для итога сообщений применяется лог XBMC. В него механически записываются все непойманные исключения. Также в лог дозволено выводить дополнительную информацию при помощи оператора print и функции xbmc.log().
Помимо того, XBMC поддерживает удаленную отладку при помощи Eclipse PyDev. Подробнее об этом дозволено прочитать тут.

Завершение

На этом разбор конструкции касательно простого плагина XBMC закончен. Невзирая на свою простоту, плагин имеет примерно все элементы, присущие больше трудным плагинам. Желающие могут применять данный плагин в качестве «скелета» для собственного плагина.
В дальнейший раз, если будет время и желание, я расскажу о том, как сделать плагин с собственным интерфейсом.

Источники информации

Темы, посвященные разработке плагинов, в официальной Wiki XBMC: http://wiki.xbmc.org/index.php?title=Category:Addon_Development
Документ «XBMC Addon Developers Guide»: yadi.sk/d/NvfFuXYw92paL
Короткая справка по модулям XBMC Python API: mirrors.xbmc.org/docs/python-docs

Источник: programmingmaster.ru
Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB