2012/12/23

XBMC for Android カスタマイズ

ここでは普通の設定じゃ出来ないけどソース側をちょっと変更することで自分都合ですがいい感じに変更したことを書きたいと思います。こういうわがままもソースがあるからできることなので、オープンソースってやっぱりいいなぁと思います。


「映画」を「録画」変える

以前の記事で.nfoファイルを用意してビデオライブラリをいい感じにするのを行いましたが、地デジ録画ファイルを「映画」として扱っているわけです。それはいいとしても「映画」って違うよねってことで、表示だけでも変更して違和感がないようにしたいと。
ついでに、nfoでstudioにチャンネル、directorに録画日時を入れているので、これらも変更します。

マルチランゲージのファイルはAPKのassetsに入るので、advancedsettings.xmlみたいに外から手出しできません。apkをばらして変更して再構築っていう手もありますが、ビルド環境があるんで普通にやります。

xbmc-android/language/Japanese/string.po っていうファイルが日本語文字列が入っているファイルです。
この中の「映画」ってなっているところを全部「番組」に変更します。
「スタジオ」、「監督」もそれぞれ「チャンネル」、「録画日時」に変更します。

そしたらxbmc-androidのところで
$ make apk
で、apkの構築だけをやれば出来上がり。


ホームアプリ化

http://melea1000.blogspot.jp/2012/09/xbmc-as-launcher.html にも書かれていますが、XBMCをホームアプリ(Lancher)にしてしまおうということです。
XBMCの「プログラム」から別アプリを起動することも出来るんでランチャーとしてXBMCは使えます。
それよりも、リビングで家族でビデオを楽しむSetTopBoxのような環境にしたいわけです。(XBMCが不用意に終わらないようにしたい)

xbmc-android/tools/android/packaging/xbmc/AndroidManifest.xml を変更

<category android:name="android.intent.category.LAUNCHER">
と書かれているところを
<category android:name="android.intent.category.HOME">
<category android:name="android.intent.category.DEFAULT">
に変更します。

常駐するためには、
<application android:hascode="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:persistent="true">
のように、persistentを追加します。が、これやってもやらなくても体感は変わらなかったですね。
すごくレスポンスがよくなるならいいですが、変わらない感じなのでいらないかなと。

これもソースはいじってないので
$ make apk
で、apkの構築だけをやればOKです。

ホームアプリ(ランチャー)を気軽に変更するホームスイッチャー系のアプリを入れておくと便利です。
上記の変更をすると普通のアプリとしては見えなくなる(アプリ管理のAllで見える)ので。


デバッグビルドじゃなくする

ビデオ再生部分とかベースライブラリ群はデバッグビルドじゃないんでパフォーマンスにはほとんど関係ないと思いますが、デバッグログとかXBMC本体のデバッグコードとかちょっとでも処理を減らせたらいいかなと思い、やったことです。

xbmc-android/tools/android/depends/xbmc/Makefile を変更
# configuration settings
CONFIGURE=cp -f $(CONFIG_SUB) $(CONFIG_GUESS) build-aux/ ;\
./configure --prefix=$(PREFIX) --host=$(HOST) \
--enable-neon --enable-gles --enable-debug \
--disable-sdl --disable-x11 --disable-xrandr \
--disable-optical-drive --disable-joystick \
--enable-shared-lib --disable-alsa

って書いてありますが、この中の"--enable-debug"を"--disable-debug"に変更します。

xbmc-android/tools/android/packaging/xbmc/AndroidManifest.xml を変更

ホームアプリ化のところに書いちゃいましたが、
<application android:dabuggable="true" android:hascode="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name">
から、android:debuggable="true"を削除します。
おまじないみたいなものですが、ログ出力とかちょっとでも余計な処理を省けるかなと。

そしてビルド
$ make -C tools/android/depends/xbmc

出来上がったapkのサイズがちょっと減ったので、少しは効果あるかな?と思いましたが体感は全然変わりませんでした。まあ気分ですね。


アップデート

変更じゃないですが、上のような変更をするとなると、もう他からのAPKダウンロードじゃだめです。自分でアップデートしていかないと。
ということで、アップデート手順も簡単に書き留めておきます。

$ cd xbmc-android
$ make -C tools/android/depends/xbmc clean (やらないで済むといいな)
$ git pull
$ make apk
$ adb install -r xbmcapp-armeabi-v7a-debug.apk

通常はこんな感じでしょうかね。makeが通らなかったり、ライブラリ側が更新された時はもっと面倒でしょう。
ライブラリのconfigure当たりからやり直しでしょうか。



とにかくこれで、かな~りしっくりくる環境になりました。これならかみさんにも使ってもらえそうです。

2012/12/14

XBMC for Android 設定とMySQL対応

更に快適なXBMC環境にするためにってことで、普通に設定で出来そうなことを色々やってみました。結果、どれも問題なく、いい感じです。以下、自分が行った設定です。


システム設定

外観(Appearance)

日本語化(誰もがやることですね。順番が大事かも)
  1. Skin>Font=>Arial Base
  2. International>Character Set=>Japanese(Shift-JIS)
  3. International>Language=>Japanese
天気予報 (役に立つような立たないような・・)

一般>設定の"Location setup"からLocation 1を選んで、"tokyo"って入れて出てくるメニューから適当に選んで設定。Location 1に"Tokyo,Japan"とか表示されたらOKする。

サーバー

ネットワーク経由のリモートアプリから制御できるように
  • Webサーバー>HTTP経由でのXBMCの制御を有効に=>オン
  • リモートコントロール>システム上のプログラムによるXBMCの制御を許可=>オン
システム
  • オーディオハードウエア>オーディオ出力=>HDMI
  • 入力デバイス>リモコンによるキーボード入力=>オフ
  • 入力デバイス>マウス・タッチスクリーンの有効化=>オフ(これやると外部キーボードだけの操作になる。潔し!)
MK808なので一応HDMIってやりましたが、効果はよくわかりません。パススルーのオーディオ装置をつなげている場合は、パススルー設定にすると処理が軽くなってパフォーマンスがあがるらしいですが、Android端末には関係ない話か。

フルスクリーン化(ナビゲーションバーを消す)

これはXBMCの設定じゃないんですが、XBMCのためにってことで。

Android4.0から(だったかな?)物理キーを持たないPad/Tab系Androidにはシステムナビゲーションバーが画面下に入るようになって、アプリからHide操作しても、’・・・’ってなるだけで完全には消えないんですね。ビデオ再生時もずっといるので目障りで仕方ありません。

HideBarというアプリを使うといいんじゃない?と、http://wiki.xbmc.org/index.php?title=XBMC_for_Android_specific_FAQ で説明されています。ストアには有料版がアップされていますが、無料(デモ)版がいいのでhttp://ppareit.github.com/HideBar/ から、デモバージョン入手してインストールします。たまにバナーが表示されたりしますが気にしません。

それより、これを動かすにはOSがルート化されている必要があるようです。自分は以前の記事の際にやったので大丈夫でしたが、もっと簡単な方法ないですかね。

HideBarとXBMCが連動しているわけではないので、きれいにフルスクリーン化するには手順がちょっとあります。
  1. XBMCが起動していないこと。リジューム状態ではだめです。
  2. HideBarでナビゲーションバーを消す。
  3. XBMCを起動する
すると画面全体をXBMCが使うようになりますので、ビデオ再生でTV画面全部使ってくれます。
逆に、この状態でナビゲーションバーを表示させると、XBMCが上にずれてしまいますが、またバーを消せば元に戻るんで大丈夫。この辺はOS仕様ともに改善されるといいんですが。


advancedsettings.xmlで設定

このファイルにデフォルトを変更するユーザ設定を色々書いてuserdataフォルダに置いておけば反映します。詳細はhttp://wiki.xbmc.org/index.php?title=Advancedsettings.xml

用意したxmlファイルをAndroidの所定の場所にコピーしてXBMCを再起動すれば反映されます。

adbでコピーするなら、コネクトして
$ adb push advancedsettings.xml /sdcard/android/data/org.xbmc.xbmc/files/.xbmc/userdata
ストレージマウントしてコピーしても同じです。

自分は以下の設定を行いました。

<splash>

splashをfalseにすると起動時にスプラッシュロゴ表示がなくなります。

<video>

シーク時間設定
これが出来ないと自分にとって何の意味もないんですが、XBMCはちゃんとできます。

左右キーでのシーク時間変更 timeseekforward と timeseekbackward
上下キーでのシーク時間変更 timeseekforwardbig と timeseekbackwardbig

これ以外にもvideoタグ内では色んな設定が出来ますね。

<videodatabase> と <musicdatabase>

ビデオデータベース変更

ライブラリとか視聴記録とかの管理データを、内臓データベース(SQLite3)から外部データベースへ変更することが出来ます。
メリットは、データベースを外部に持つことで複数のXBMC端末からライブラリを共有できるようになることかなと思いますが、自分が考えているのは、地デジ録画システムから視聴した場合でも情報が連動するように出来たらいいなぁと思ってます。


実際にXBMCに食わせたadvancedsettings.xmlがこちら
<advancedsettings>

<splash>false</splash>

<video>
  <timeseekforward>30</timeseekforward>
  <timeseekbackward>-30</timeseekbackward>
  <timeseekforwardbig>60</timeseekforwardbig>
  <timeseekbackwardbig>-60</timeseekbackwardbig>
</video>

<videodatabase>
  <type>mysql</type>
  <host>{MYSQLサーバーIPアドレス}</host>
  <name>xbmc_video</name>
  <user>xbmc</user>
  <pass>xbmc</pass>
</videodatabase>

<musicdatabase>
  <type>mysql</type>
  <host>{MYSQLサーバーIPアドレス}</host>
  <name>xbmc_music</name>
  <user>xbmc</user>
  <pass>xbmc</pass>
</musicdatabase>

</advancedsettings>


MySQLサーバー側の設定

$ mysql -uroot -p

# ローカルホストとLAN上のホストからアクセス可能なユーザ'xbmc'を作成
create user 'xbmc'@'localhost' identified by 'xbmc';
create user 'xbmc'@'192.168.1.%' identified by 'xbmc';

# 'xbmc'ユーザにデータベース作成権を与える
grant all on *.* to 'xbmc'@'localhost';
grant all on *.* to 'xbmc'@'192.168.1.%';

flush privileges;
exit;

別ホストからアクセスできるように設定変更

$ sudo emacs /etc/mysql/my.conf
bind-addressの行をコメントアウト
$ sudo service mysql restart
リスタート

ポイントは、'xbmc_video'とか、自分でデータベースを作ってはいけないということ。
XBMCがデータベース自体を作成します。最初これを理解していませんでした。

デバッグログ出力を有効にして、/data/data/org.xbmc.xbmc/cache/temp/xbmc.log を読んでエラー箇所を見つけてやっと理解しました。自ら作ろうとしてるぞ?!ってね。

作成できるように強い権限を与える必要があるため、上のように、localhostとLAN内からのアクセスに限定しています。

古いバージョンデータベースを見つけたらアップデートは勝手にやってくれるようですね。空っぽのxbmc_videoDBを最初作ってしまったものだから権限与えてもエラーになっていて、ちょっとハマりました。

advancedsettings.xmlでデータベース名を'xbmc_video'って書いてありますが、データベース名のprefixを指定しているにすぎません。実際のデータベース名はXBMCのライブラリバージョンごとに変わるようです。
実際には'xbmc_video75'と'xbmc_music32'というのがXBMCによって作られました。
最後の数字はライブラリバージョンらしいです。

これで地デジ録画サーバー上のMySQLにXBMCのライブラリが共存するように出来たので、視聴記録の連動とかがしやすいかな。

次はある意味、設定変更なんですが、再ビルドしないとならない自分勝手な変更を行う内容を書く予定。

2012/12/07

XBMC用.nfoファイルを用意する

XMBCがAndroid端末(MK808)で動きましたので、次の段階です。

再生時の操作については別途書きたいなと思ってますが、今回のテーマは録画ビデオファイルのリスト表示を、ファイル名だけとかサムネイルだけとかじゃなくてちゃんと番組名、内容説明を表示するようにしたいということへの取り組みです。

詳しくはないんですが、XBMCのImport-export library を読むと、nfoファイルというものを用意すれば、無機質なファイル名ではなくて、タイトル名やらなんやら、オンデマンドコンテンツのように表示させることが出来るとありますね。

ビデオファイル名.nfoファイルを作ってあげればよいと

初めは、XBMCの方でそのファイルをインポートするなんて操作をしなければならないのかな?面倒だな。なんて勘違いしてましたが、全然大丈夫でした。
ビデオファイルが入っている同じフォルダ内に拡張子を"nfo"にして置いておけば勝手に読んでライブラリ化してくれます。これなら自動化も楽ちんです。

nfoファイルの中身

XBMCがライブラリ化できるのは大きく分けて、映画(movie)、TV番組(tvshow)、TVエピソード(episodedetails)及び音楽ビデオ(musicvideo)のようです。

メジャーコンテンツ扱う場合なら、オンラインデータベースからの情報とリンクさせてより詳しいデータとかを取得出来たりするようですね。そういうのが一切関係ないローカルで汎用的なビデオ(video)とかあればいいなと思いましたがね。

どのライブラリタイプを使うか

どれが一番適しているか色々試してみました。

本来はtvshow(TV番組)としてライブラリ化するのが自然だろうなぁと思いましたが、tvshowは"tvshow.nfo"と名前が決まっていて、1ファイル1ディレクトリ管理じゃないとだめっぽい。
TV_Show_files_naming_conventions
この辺を読むと、さらにその下にepisodedetailsを置いて、ファイル名とか色々構成を整えないといい感じにならないらしい。

movieとmusicvideoは、ファイル単位のnfoを作るだけで読まれたので、どっちでもよさそうでしたが、musicvideoだと、並べ替えで「日付」を選ぶことが出来なくて、リストがいまいち使いにくい。どちらもpodcastのような公開日とかがないので、実ファイルの作成日が使えることが重要だったりします。

消去法で、内容はTV番組ですが、映画ライブラリとして構成するのが一番使い勝手が良いようです。結論を先に書きましたが、作成と読み込み手順は以下のような感じで進めました。

nfoファイル作成

録画サーバーから提供できる番組情報は、元々地デジEPG情報なので、番組名・内容・日時・長さ(分)・ジャンル・チャンネル位なので、それをどうにか対応させます。
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<movie>
 <id>番組ID</id>
 <title>番組名</title>
 <outline>内容</outline>
 <plot>内容</plot>
 <runtime>長さ</runtime>
 <genre>ジャンル</genre>
 <studio>チャンネル</studio>
 <director>録画日時</director>
 <set>番組名のサブセット</set>
</movie>
outline,plotどっちで内容が出てくれるのかよく分からないので両方に。
チャンネル項目がないので、studioに適当に入れました。
録画日時を表示させたいので、directorに適当に入れました。
studioとdirectorがとにかく目立つところに表示されるのでね。意味が全然違いますけど・・・
idってのがあったのでチケットID入れてみましたが、どこにも表示されませんな。

このnfoファイルを作成する録画システム上のスクリプトがこちら
xbmc-movie.rb

#!/usr/bin/ruby
# -*- coding: utf-8 -*-
#
require 'rubygems'
require 'active_record'
require 'rexml/document'
require 'digest/md5'

@media_path = '/opt/videos/'

ActiveRecord::Base.establish_connection(
        :adapter => 'mysql2',
        :host => 'localhost',
        :username => 'redmine',
        :password => 'redmine',
        :database => 'redmine'
)

class Issue < ActiveRecord::Base; end
class IssueCategories < ActiveRecord::Base; end
class Attachments < ActiveRecord::Base; end
class CustomValues < ActiveRecord::Base; end

def add_element_with_text (parent, element, text)
  e = parent.add_element element
  e.text = text
end

# create a nfo file
def create_nfo (issue)

  video = Attachments.first(:conditions => {
                              :container_id => issue.id,
                              :content_type => "video/mp4"})
  channel = CustomValues.first(:conditions => {
                                 :customized_id => issue.id,
                                 :custom_field_id => 2})
  time_tmp = format("%04d", CustomValues.first( :conditions => {
                                                  :customized_id => issue.id,
                                                  :custom_field_id => 1}).value.to_i)
  time = "#{time_tmp[0..1]}:#{time_tmp[2..3]}"

  # 試行錯誤の末こんな感じに
  set = issue.subject.sub(/[  ”’#(「・◇].*/,'')

  xml = REXML::Document.new
  info = xml.add_element 'movie'
  add_element_with_text info, 'id', issue.id
  add_element_with_text info, 'title', issue.subject
  add_element_with_text info, 'year', issue.start_date
  add_element_with_text info, 'runtime', issue.estimated_hours
  add_element_with_text info, 'outline', issue.description
  add_element_with_text info, 'plot', issue.description
  add_element_with_text info, 'genre', IssueCategories.find(issue.category_id).name
  add_element_with_text info, 'director', "#{issue.start_date} / #{time}"
  add_element_with_text info, 'studio', channel.value
  add_element_with_text info, 'set', set

  nfo_file = video.filename.to_s.sub(/.mp4/,".nfo")
  puts "#{nfo_file}:#{set}"

  nfo = File.open(@media_path + nfo_file,"w")
  nfo.puts '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>'
  xml.write nfo
  nfo.puts "\n"
  nfo.close

  # 本件に関係ないので省略
  #attach "nfoファイル", issue.id, nfo_file, "xbmc/nfo"
end

# 公開ステータスの録画チケット
Issue.find( :all, :conditions => {:tracker_id => 3,:status_id => 4}).each {|issue|
  create_nfo issue
#  break
}

今までのビデオファイル全てにnfoファイルを作成するものになってますが、録画システムとしては番組録画後にそれ用のnfoファイルを作成するフローにしています。以前podcastがらみでやったこととほとんど同じ要領なので、ちゃちゃと出来ました。

XBMC側で読んでもらうには

ビデオソースを追加して、HTTPとかSMBとかで、ビデオフォルダを見れるようにします。
この辺の手順は他のHOWTO記事を参考にされた方が親切でいいです。

コンテンツの種類として”(映画)”を選んで設定ボタンを押して、有効になっているやつを全部外します。外さなくてもいいけれど勝手にDBへアクセスしに行ったりするようなので。
設定を全部OKしてダイアログを全部閉じるとライブラリ化はその瞬間から自動で開始されます。

終了するまで数分時間がかかりました。その最中でも大丈夫そうでしたが、落ち着いたかなぁという頃合いにXBMCのホームに戻るとビデオの下にはにはライブラリ、横に「映画」という項目が増えています。この辺をたどっていくとnfoファイルで設定した内容でビデオファイルが表示されました。

新しい順にリストさせるには、表示オプションで、並べ替えを「日付」にソートを「降順」にすれば新しい順に出ます。後は表示の種類を自分の好みにしてみる。うーん。いい感じです。

setがいい

setタグのところで、番組名のサブセットと書きましたが、XBMC上で同じセット名は仮想的なサブディレクトリとして扱われます。
毎週録画している番組とか、本来はエピソード番号とかで管理されるといいと思いますが、地デジ情報からは得られないので、番組名の共通項をセット名として定義することでシリーズ番組とかを同じセットグループとして分類が出来て便利です。

日本語での検索

表示オプションから検索が出来ますが、残念ながら日本語入力が出来ません。これはがっかりですが、xbmcユーザからすると周知の事実らしいですね。バージョンが上がると解決するんでしょうか。パッチとかあるんでしょうか?

別のAndroid/iOS/その他デバイスでXBMCリモートアプリを使って検索すれば日本語検索できるんで、さほど問題ではないですけど、出来れば普通に本体だけで済ませたいですね。

何だか思っていた以上の環境が整いそうな予感です。
もっといい感じにできるのか調べてみましょう。