2021-05-12 14:32:11
為 Kodi 自製遙控器
通過執行在 Android 手機上的自製遙控器來控制你的家庭媒體播放器。
Kodi 是一款很優秀的軟體,能夠將幾乎所有電腦變身成媒體中心。它可以播放音樂和視訊,顯示圖片,甚至還能顯示天氣預報。為了在設定成家庭影院後方便使用,你可以通過手機 app 存取執行在連線到 Wi-Fi 的 XBMC 機器上的服務來控制它。可以找到很多這種工具,幾乎覆蓋所有智慧手機系統。
XBMC
Kodi 原名叫做 XBMC,在你閱讀這篇文章的時候,XBMC 已經成為歷史。因為法律原因(因為名字 XBMC 或 X-Box Media Center 裡參照了不再支援的過時硬體)專案組決定使用新的名字 Kodi。不過,除了名字,其他的都會保持原樣。或者說除開通常新版本中所期待的大量新改進。這一般不會影響到遙控軟體,它應該能在已有的 XBMC 系統和新的 Kodi 系統上都能工作。
我們目前已經設定好了一個用於播放音樂的 Kodi 系統,不過我們找到的所有 Kodi 遙控沒一個好用的,特別是和媒體中心連線的電視沒開啟的時候。它們都有點太複雜了,整合了太多功能在手機的小螢幕上。我們希望能有這樣的系統,從最開始就是設計成只用於存取音樂庫和電台外掛,所以我們決定自己實現一個。它不需要用到 Kodi 的所有功能,因為除了音樂以外的任務,我們可以簡單地切換使用通用的 Kodi 遙控。我們的測試系統是一個刷了 RaspBMC 發行版的樹莓派,但是我們要做的工具並不受限於樹莓派或Kodi那個發行版,它應該可以匹配任何安裝了相關外掛的基於 Linux 的 Kodi 系統。
如何在 Ubuntu 14.04 和 Linux Mint 17 中安裝 Kodi14(XBMC) http://www.linuxidc.com/Linux/2015-02/113664.htm
XBMC 移植到 Android 上,發布每日構建版本 http://www.linuxidc.com/Linux/2012-08/68157.htm
XBMC Romote:用 Android 手機控制 XBMC 媒體播放 http://www.linuxidc.com/Linux/2011-07/38166.htm
Ubuntu中安裝XBMC 媒體中心11.0 http://www.linuxidc.com/Linux/2012-03/57519.htm
首先,遙控程式需要一個使用者介面。大多數 Kodi 遙控程式都是獨立的 app。不過對於我們要做的這個音樂控制程式,我們希望使用者可以不用安裝任何東西就可以使用。顯然我們需要使用網頁介面。Kodi 本身自帶網頁伺服器,但是為了獲得更多許可權,我們還是使用了獨立的網頁框架。在同一台電腦上跑兩個以上網頁伺服器沒有問題,只不過它們不能使用相同的埠。
有幾個網頁框架可以使用。而我們選用 Bottle 是因為它是一個簡單高效的框架,而且我們也確實用不到任何高階功能。Bottle 是一個 Python 模組,所以這也將是我們編寫伺服器模組的語言。
你應該能在軟體包管理器裡找到 Bottle。在基於 Debian 的系統(包括 RaspBMC)裡,你可以通過下面的命令安裝:
sudo apt-get install python-bottle
遙控程式實際上只是連線使用者和系統的中間層。Bottle 提供了和使用者互動的方式,而我們將通過 JSON API 來和 Kodi 互動。這樣可以讓我們通過傳送 JSON 格式訊息的方式去控制媒體播放器。
我們將用到一個叫做 xbmcjson 的簡單 XBMC JASON API 封裝。足夠用來傳送控制請求,而不需要關心實際的 JSON 格式以及和伺服器通訊的無聊事。它沒有包含在 PIP 包管理中,所以你得直接從 GitHub 安裝:
git clone https://github.com/jcsaaddupuy/python-xbmc.git
cd python-xbmc
sudo python setup.py install
萬事俱備,只欠程式碼。
先從 Bottle 開始
我們程式的基本結構:
from xbmcjson import XBMC
from bottle import route, run,template, redirect, static_file, request
import os
xbmc = XBMC("http://192.168.0.5/jsonrpc","xbmc","xbmc")
@route('/hello/<name>')
def index(name):
returntemplate('<h1>Hello {{name}}!</h1>', name=name)
run(host="0.0.0.0", port=8000)
這樣程式將連線到 Kodi(不過實際上用不到);然後 Bottle 會開始提供網站服務。在我們的程式碼裡,它將監聽主機 0.0.0.0(意味著允許所有主機連線)的埠 8000。它只設定了一個站點,就是 /hello/XXXX,這裡的 XXXX 可以是任何內容。不管 XXXX 是什麼都將作為引數名傳遞給 index()。然後再替換進去 HTML 網頁模版。
你可以先試著把上面內容寫到一個檔案(我們取的名字是 remote.py),然後用下面的命令啟動:
python remote.py
然後你可以在瀏覽器裡存取 localhost:8000/hello/world 看看模版生效的效果。
@route() 用來設定網頁伺服器的路徑,而函數 index() 會返回該路徑的資料。通常是返回由模版生成的 HTML 頁面,但是並不是說只能這樣(後面會看到)。
隨後,我們將給應用新增更多頁面入口,讓它變成一個全功能的 Kodi 遙控,但仍將採用相同程式碼結構。
XBMC JSON API 介面可以從和 Kodi 機器同網段的任意電腦上存取。也就是說你可以在自己的筆電上開發,然後再布置到媒體中心上,而不需要浪費時間上傳每次改動。
模版 - 比如前面例子裡的那個簡單模版 - 是一種結合 Python 和 HTML 來控制輸出的方式。理論上,這倆能做很多很多事,但是會非常混亂。我們將只是用它們來生成正確格式的資料。不過,在開始動手之前,我們先得準備點資料。
Paste
Bottle 自帶網頁伺服器,我們用它來測試遙控程式。不過,我們發現它效能有時不夠好。當我們的遙控程式正式上線時,我們希望頁面能更快一點顯示出來。Bottle 可以和很多不同的網頁伺服器配合工作,而我們發現 Paste 用起來非常不錯。而要使用的話,只要簡單地安裝(Debian 系統裡的 python-paste 包),然後修改一下程式碼裡的 run 呼叫:
run(host=hostname, port=hostport, server="paste")
你可以在 http://bottlepy.org/docs/dev/deployment.html 找到如何使用其他伺服器的相關細節。
從 Kodi 獲取資料
XBMC JSON API 分成 14 個名稱空間:JSONRPC, Player, Playlist, Files, AudioLibrary, VideoLibrary, Input, Application, System, Favourites, Profiles, Settings, Textures 和 XBMC。每個都可以通過 Python 的 XBMC 物件存取(Favourites 除外,明顯是個疏忽)。每個名稱空間都包含許多方法用於對程式的控制。例如,Playlist.GetItems() 可以用來獲取某個特定播放列表的內容。伺服器會返回給我們 JSON 格式的資料,但 xbmcjson 模組會為我們轉化成 Python 詞典。
我們需要用到 Kodi 裡的兩個元件來控制播放:播放器和播放列表。播放器處理播放列表並在每首歌結束時從列表裡取下一首。為了檢視當前正在播放的內容,我們需要獲取正在工作的播放器的 ID,然後根據它找到當前播放列表的 ID。這個可以通過下面的程式碼來實現:
def get_playlistid():
player = xbmc.Player.GetActivePlayers()
if len(player['result'])>0:
playlist_data = xbmc.Player.GetProperties({"playerid":0,"properties":["playlistid"]})
if len(playlist_data['result'])>0and"playlistid"in playlist_data['result'].keys():
return playlist_data['result']['playlistid']
return-1
如果當前沒有播放器在工作(就是說,返回資料的結果部分的長度是 0),或者當前播放器沒有處理播放列表,這樣的話函數會返回 -1。其他時候,它會返回當前播放列表的數位 ID。
當我們拿到當前播放列表的 ID 後,就可以獲取該列表的細節內容。按照我們的需求,有兩個重要的地方:播放列表裡包含的項,以及當前播放所處的位置(已經播放過的項並不會從播放列表移除,只是移動當前播放位置)。
def get_playlist():
playlistid = get_playlistid()
if playlistid >=0:
data = xbmc.Playlist.GetItems({"playlistid":playlistid,"properties":["title","album","artist","file"]})
position_data = xbmc.Player.GetProperties({"playerid":0,'properties':["position"]})
position =int(position_data['result']['position'])
return data['result']['items'][position:], position
return[],-1
這樣可以返回正在播放的項開始的列表(因為我們並不關心已經播放過的內容),而且也包含了用來從列表裡移除項的位置資訊。
Image
API 文件在這裡:http://wiki.xbmc.org/?title=JSON-RPC_API/v6。它列出了所有支援的函數,但是關於具體如何使用的描述有點太簡單了。
JSON
JSON 是 JavaScript Object Notation 的縮寫,最初設計用於 JavaScript 物件的序列化。目前仍然起到這個作用,但是它也是用來編碼任意資料的一種很好用的方式。
JSON 物件都是這樣的格式:
{property1:value1, property2:value2, property3:value3}
支援任意數目的屬性/值配對。對 Python 程式設計師來說,看上去和字典資料結構很相似,不過這兩個確實很像。
在字典資料結構裡,值本身可以是另一個 JSON 物件,或者一個列表,所以下面的格式也是正確的:
{"name":"Ben","jobs":["cook","bottle-washer"],"appearance":{"height":195,"skin":"fair"}}
JSON 通常在網路服務中用來傳送和接收資料,並且大多數程式語言都能很好地支援,所以如果你熟悉 Python 的話,你應該可以使用你熟悉的程式語言呼叫相同的介面來輕鬆地控制 Kodi。
更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2015-07/120483p2.htm
相關文章