xbmcswift2-Kodiのプラグインを作成するためのマイクロフレームワーク(XBMC)

エントリー



これは、いわば、Kodi Media Center(XBMC)のプラグインに関する一連の記事の「ボーナス」記事です。 まず、バージョン14.0以降、人気のあるメディアセンターの名前がXBMCからKodiに変更されたことに注意してください。 名前が変更された理由については、公式Webサイトとフォーラムで読むことができますが、これらは記事では重要ではありません。 ただし、記事の後半で新しい名前が使用されます-Kodi。



前の記事


XBMCのシンプルなプラグインの詳細な構造

独自のインターフェースを備えたXBMC用のプラグインの作成:パートI-理論と最も単純な例

独自のインターフェースを備えたXBMC用のプラグインの作成:パートII-ダイアログと装飾

独自のインターフェースを備えたXBMC用のプラグインを作成します:パートIII-APIとマイクロフレームワーク



xbmcswift2



最初の記事「XBMC用のシンプルなプラグインの詳細な構造」では 、コンテンツプラグインの基本原則、つまり、さまざまなオンラインリソースから動画を視聴したり音楽を聴いたりできるプラグインについて説明しました。 これらの基本原則には次の2つがあります。

  1. 仮想ディレクトリの各要素(再生するサブセクションまたはファイルへのリンク)は、仮想ディレクトリの要素に関するすべての情報を含むクラスxbmcgui.listItemのオブジェクトです。 要素のリストを作成するとき、 xbmcgui.listItemオブジェクトを順番に作成し、それらのプロパティ(サムネイル、ファンアート、リンク、追加情報)を設定し、これらの要素をxbmcplugin.addDirectoryItem関数に「フィード」します。
  2. マルチレベルディレクトリを作成するために、プラグインは再帰的に自身を呼び出し、sys.argvリストアイテム[2]を介してURLエンコードされた文字列の形式でパラメータを渡します。 この場合、これらのパラメーターをデコードし、コードの対応する部分を呼び出して、たとえば下位レベルのディレクトリ(サブセクション)を形成したり、参照によってビデオを再生したりする必要があります。 つまり、このような再帰呼び出しのルーティングを整理する必要があります。


その結果、プラグイン開発者は、情報の取得、コンテンツの整理、および再生に直接関係しない余分な作業を委ねられます。



xbmcswift2を作成する際、開発者は明らかにWeb開発用の人気のPythonマイクロフレームワークであるFlask and Bottleに触発されました。 再帰呼び出しルーティングメカニズムは、これらのフレームワークから明確に借用されています。呼び出しパスとパラメーターの受け渡しは、関数デコレーターを介して実装されます。

さらに、xbmcswift2は仮想ディレクトリエントリの構造を統一します。 現在、個別の要素は、キーと値のペアの形式で必要なすべてのプロパティを備えたPython辞書です。 これらの要素はリストに結合され、Kodiインターフェイスで要素のリストを表示するには、ルートデコレータで「装飾」された関数がこのリストを返す必要があります。 リストのさらなる処理と、このリストの要素を記述する辞書のデコードは、xbmcswift2によって行われます。

コンテンツリストの作成と再帰呼び出しのルーティングの簡素化に加えて、xbmcswift2は、関数とメソッドによって返されるオブジェクトのキャッシュ、再帰呼び出し間でオブジェクトの状態を保存するための永続的なストレージなどの優れた機能を提供します。 xbmcswift2では、Kodiを使用せずに、コンソールでプラグインコードをデバッグすることもできます。



xbmcswift2の使用法を説明するために、記事「XBMC用の単純なプラグインの詳細な構造」からプラグインを取り上げ、このフレームワークの下でそれを書き直します。 簡単にするために、新しいプラグインは画面にメッセージを表示しないため、言語ファイルはありません。



プラグインコード
# -*- coding: utf-8 -*- # Name: plugin.video.cnet # Author: Roman VM # Created: 02.02.2014 # Licence: GPL v.3: http://www.gnu.org/copyleft/gpl.html #    import sys import os import urllib2 import xml.dom.minidom #  xbmcswift2 from xbmcswift2 import Plugin #   plugin plugin = Plugin() #     addon_path = plugin.addon.getAddonInfo('path').decode('utf-8') #     thumbpath = os.path.join(addon_path, 'resources', 'thumbnails') #     fanart = os.path.join(addon_path, 'fanart.jpg') #    sys.path.append(os.path.join(addon_path, 'resources', 'lib')) from feeds import FEEDS #  ,   (),  30 . @plugin.cached(30) def rss_parser(url): listing = [] try: HEADER = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; rv:18.0) Gecko/20100101 Firefox/20.0'} request = urllib2.Request(url, None, HEADER) rss = xml.dom.minidom.parse(urllib2.urlopen(request, None, 3)) except urllib2.URLError: pass else: titles = rss.getElementsByTagName('title') links = rss.getElementsByTagName('link') for title, link in zip(titles[2:], links[2:]): title = title.toxml().replace('<title><![CDATA[', '').replace(']]></title>', '') link = link.toxml().replace('<link>', '').replace('</link>', '') listing.append((title, link)) return listing #   @plugin.route('/') def feed_index(): feed_list = [] for i in range(len(FEEDS)): #    . #  : feed = {'label': FEEDS[i]['label'], # : 'thumbnail': os.path.join(thumbpath, FEEDS[i]['thumb']), #    (): 'properties': {'fanart_image': fanart}, #    . 'path': plugin.url_for('podcast_index', feed=str(i))} feed_list.append(feed) #       : #       (""   Confluence). return plugin.finish(feed_list, sort_methods=['label'], view_mode=500) #     @plugin.route('/feeds/<feed>') def podcast_index(feed): feedNo = int(feed) quality = plugin.addon.getSetting('quality') #      . podcasts = rss_parser(url=FEEDS[feedNo][quality]) thumb = os.path.join(thumbpath, FEEDS[feedNo]['thumb']) podcast_list = [] for podcast in podcasts: item = {'label': podcast[0], 'thumbnail': thumb, 'properties': {'fanart_image': fanart}, 'path': plugin.url_for('play_podcast', url=podcast[1]), # ,        (  ). 'is_playable': True} podcast_list.append(item) #       return podcast_list @plugin.route('/play/<url>') def play_podcast(url): #   Kodi    . plugin.set_resolved_url(url) if __name__ == '__main__': #  . plugin.run()
      
      









今、いつものように、行ごとの解析。 行番号を表示するには、メモ帳++などの適切な機能を備えたテキストエディターを使用します。 明らかなことやコメントから明らかなことを見逃しています。



30: @ plugin.cached()デコレーターは、関数またはメソッドによって返されたオブジェクトをキャッシュするために使用されます。 このようなデコレータは、これらのサイトに不必要な負荷をかけないように、Webサイトからコンテンツを受け取る機能を「装飾」することをお勧めします。 キャッシュ時間は分単位でデコレーターパラメーターとして設定されます。

49: @ plugin.route()デコレーターは、プラグイン呼び出しのルーティングに使用されます。 プラグインには、少なくともルートルート( '/')が含まれている必要があります。

55–61:リストアイテムのプロパティは、かなり単純で理解しやすい辞書の形式で設定されます。

61: url_for()メソッドは、プラグインの再帰呼び出しの正しいパスを生成し、このパスをxbmcswift2でデコードできるようにします 文字列として呼び出された関数の名前が最初のパラメーターとして使用され、追加情報は名前付きパラメーターを介して渡されます。 パラメータとして使用できるのは、単純な文字列のみです。 したがって、他のすべてのデータ型は文字列にキャストする必要があります。 非ASCII文字は、URLエンコードシーケンスとして送信できます(たとえば、「Vasya」>「%D0%92%D0%B0%D1%81%D1%8F」またはbase64エンコード)。

65: finish()メソッドは、コンテンツリストを表示するための追加パラメーター(リスト自体に加えて)を渡すために使用されます。 追加のパラメーターを返す必要がない場合は、 finish()メソッドを使用せずにリスト自体を返すことができます。

69.70:ポッドキャストのリストを形成する関数を呼び出します。 パラメーターとして、FEEDSのリスト(より正確にはタプル)内のセクションの番号を渡します。

83:この要素にネストされた要素が含まれていないことを示します(この場合、リスト要素は再生するファイルです)。 デフォルトでは、このパラメーターはFalseであるため、前の関数では省略されています。

89-90:ここでは、ファイルをKodiメインコードに送信して再生するために、特別な関数play_podcast()が使用されます 。この関数は、 set_resolved_url()メソッドを呼び出します。 このメソッドは、標準のKodi Python API 関数xbmcplugin.setResolvedUrl()を囲むxbmcswift2の「ラッパー」です。 xbmcplugin.setResolvedUrl()の使用についてはあまり文書化されていませんが、マルチメディアファイルの再生を開始するのにこの方法が望ましいです。 もちろん、これらのファイルへの直接リンクを使用できます(そして記事「XBMC用の単純なプラグインの詳細な解剖」の例では、直接リンクを使用した単純なオプションが使用されました)が、直接リンクを使用する場合、望ましくない副作用があります。 たとえば、ファイルのリストを作成するとき、Kodiはこれらのファイルのメタデータを読み取ろうとします。リストアイテムの数が多く、接続が遅いと、リストが非常に長時間にわたって形成されます。 また、直接リンクを使用する場合、閲覧者の自動ブックマークとマークはサポートされていません。 後者の理由は理解できない(明らかにバグ)。しかし、xbmcplugin.setResolvedUrl()およびxbmcswift2からの類似物-set_resolved_url()を使用する場合、これらの副作用は観察されません。



おわりに



microframework xbmcswift2は公式のKodiリポジトリで利用でき、それに基づいてプラグインを作成する場合、Kodiプラグインメタデータファイルaddon.xmlでマイクロフレームワークを依存関係として指定する必要があります。 詳細については、以前の記事と公式Wikiを参照してください。

xbmcswift2に基づく既製のデモプラグインは、こちらからダウンロードできます



これらの記事の情報が、Kodiの便利なプラグインの作成に役立つことを願っています。 実践が示すように、プラグインを作成する際の最も難しいタスクは、特定のサイトからビデオまたは音楽へのリンクを取得することであり、プラグイン内の情報とリンクを整理することははるかに簡単です。



情報源



公式のxbmcswift2ドキュメント



All Articles