txqz memo

64bit版Ubuntu10.04にPT2とFoltiaHDを入れる

foltia用にと思ってSycomでGZ2000P55/870を買ったけどあまり時間がなくて少しずついじってるうちに2ヶ月くらい経ってしまった。いい加減ドキュメント化する。

このサーバにUbuntu10.04を入れて録画サーバとする。Ubuntuなのは趣味。

foltiaユーザを作成

あとからFoltiaと連携させることを考えて、foltiaユーザでできることはなるべくfoltiaユーザでさせる。

$ sudo adduser foltia
ユーザ `foltia' を追加しています...
新しいグループ `foltia' (1001) を追加しています...
新しいユーザ `foltia' (1001) をグループ `foltia' に追加しています...
ホームディレクトリ `/home/foltia' を作成しています...
`/etc/skel' からファイルをコピーしています...
新しいUNIXパスワードを入力してください: 
新しいUNIX パスワードを再入力してください: 
passwd: パスワードは正しく更新されました
Changing the user information for foltia
Enter the new value, or press ENTER for the default
    Full Name []: 
    Room Number []: 
    Work Phone []: 
    Home Phone []: 
    Other []: 
Is the information correct? [Y/n] Y

カードリーダードライバのインストール

$ sudo apt-get install pcsc-tools
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
以下の特別パッケージがインストールされます:
  libpcsc-perl
以下のパッケージが新たにインストールされます:
  libpcsc-perl pcsc-tools
アップグレード: 0 個、新規インストール: 2 個、削除: 0 個、保留: 2 個。
133kB のアーカイブを取得する必要があります。
この操作後に追加で 508kB のディスク容量が消費されます。
続行しますか [Y/n]? Y
取得:1 http://jp.archive.ubuntu.com/ubuntu/ lucid/universe libpcsc-perl 1.4.8-1 [60.0kB]
取得:2 http://jp.archive.ubuntu.com/ubuntu/ lucid/universe pcsc-tools 1.4.16-1 [73.3kB]
133kB を 3s で取得しました (37.6kB/s)
未選択パッケージ libpcsc-perl を選択しています。
(データベースを読み込んでいます ... 現在 124924 個のファイルとディレクトリがインストールされています。)
(.../libpcsc-perl_1.4.8-1_amd64.deb から) libpcsc-perl を展開しています...
未選択パッケージ pcsc-tools を選択しています。
(.../pcsc-tools_1.4.16-1_amd64.deb から) pcsc-tools を展開しています...
man-db のトリガを処理しています ...
desktop-file-utils のトリガを処理しています ...
python-gmenu のトリガを処理しています ...
Rebuilding /usr/share/applications/desktop.ja_JP.utf8.cache...
python-support のトリガを処理しています ...
libpcsc-perl (1.4.8-1) を設定しています ...
pcsc-tools (1.4.16-1) を設定しています …
$ sudo apt-get install libccid
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
以下の特別パッケージがインストールされます:
  pcscd
以下のパッケージが新たにインストールされます:
  libccid pcscd
アップグレード: 0 個、新規インストール: 2 個、削除: 0 個、保留: 2 個。
195kB のアーカイブを取得する必要があります。
この操作後に追加で 627kB のディスク容量が消費されます。
続行しますか [Y/n]? Y
取得:1 http://jp.archive.ubuntu.com/ubuntu/ lucid/universe libccid 1.3.11-1 [111kB]
取得:2 http://jp.archive.ubuntu.com/ubuntu/ lucid/universe pcscd 1.5.3-1ubuntu4 [83.9kB]
195kB を 3s で取得しました (54.2kB/s)
未選択パッケージ libccid を選択しています。
(データベースを読み込んでいます ... 現在 124967 個のファイルとディレクトリがインストールされています。)
(.../libccid_1.3.11-1_amd64.deb から) libccid を展開しています...
未選択パッケージ pcscd を選択しています。
(.../pcscd_1.5.3-1ubuntu4_amd64.deb から) pcscd を展開しています...
man-db のトリガを処理しています ...
ureadahead のトリガを処理しています ...
ureadahead will be reprofiled on next reboot
libccid (1.3.11-1) を設定しています ...

pcscd (1.5.3-1ubuntu4) を設定しています …

pcsc_scan してみる

$ pcsc_scan 
PC/SC device scanner
V 1.4.16 (c) 2001-2009, Ludovic Rousseau <ludovic.rousseau@free.fr>
Compiled with PC/SC lite version: 1.5.3
Scanning present readers...
0: SCM SCR 3310 NTTCom 00 00

Mon May  3 20:41:54 2010
 Reader 0: SCM SCR 3310 NTTCom 00 00
  Card state: Card inserted, Unresponsive card, 

Unresponsive card というのはカードの裏表が逆だということだそうなので、入れ替える。

$ pcsc_scan
PC/SC device scanner
V 1.4.16 (c) 2001-2009, Ludovic Rousseau <ludovic.rousseau@free.fr>
Compiled with PC/SC lite version: 1.5.3
Scanning present readers...
0: SCM SCR 3310 NTTCom 00 00

Mon May  3 20:43:52 2010
 Reader 0: SCM SCR 3310 NTTCom 00 00
  Card state: Card inserted, 
  ATR: 3B F0 12 00 FF 91 81 B1 7C 45 1F 03 99

ATR: 3B F0 12 00 FF 91 81 B1 7C 45 1F 03 99
+ TS = 3B --> Direct Convention
+ T0 = F0, Y(1): 1111, K: 0 (historical bytes)
  TA(1) = 12 --> Fi=372, Di=2, 186 cycles/ETU
    21505 bits/s at 4 MHz, fMax for Fi = 5 MHz => 26881 bits/s
  TB(1) = 00 --> VPP is not electrically connected
  TC(1) = FF --> Extra guard time: 255 (special value)
  TD(1) = 91 --> Y(i+1) = 1001, Protocol T = 1 
-----
  TA(2) = 81 --> Protocol to be used in spec mode: T=1 - Unable to change - defined by interface bytes
  TD(2) = B1 --> Y(i+1) = 1011, Protocol T = 1 
-----
  TA(3) = 7C --> IFSC: 124
  TB(3) = 45 --> Block Waiting Integer: 4 - Character Waiting Integer: 5
  TD(3) = 1F --> Y(i+1) = 0001, Protocol T = 15 - Global interface bytes following 
-----
  TA(4) = 03 --> Clock stop: not supported - Class accepted by the card: (3G) A 5V B 3V 
+ Historical bytes: 
+ TCK = 99 (correct checksum)

Possibly identified card (using /usr/share/pcsc/smartcard_list.txt):
3B F0 12 00 FF 91 81 B1 7C 45 1F 03 99
    Japanese Chijou Digital B-CAS Card (pay TV)

PT2のドライバを入れる。

Foltia作者のブログに書いてあるドライバを入れる。Debianでの構築例を見つつ、実行。

まず、必要なパッケージの用意

$ sudo apt-get install g++ libboost-filesystem-dev libboost-thread-dev libglib2.0-dev libboost-regex-dev build-essential autoconf libpcsclite-dev mercurial

foltiaユーザでドライバを入れる

$ hg clone http://hg.honeyplanet.jp/pt1/ PT2
全チェンジセットを取得中
チェンジセットを追加中
マニフェストを追加中
ファイルの変更を追加中
117 のチェンジセット(305 の変更を 115 ファイルに適用)を追加
ブランチ default へ更新中
ファイル状態: 更新数 31、マージ数 0、削除数 0、衝突未解決数 0

$ cd PT2/driver/
$ make

バージョンによっては、ここでerror: implicit declaration of function 'schedule_timeout_interruptible'というエラーメッセージが表示される。検索すると2chのスレが出てくるので、そのとおりにpt1_i2c.cに#include <linux/sched.h>を追加すればちゃんとmakeされる。

$ sudo make install
$ sudo cp pt1_drv.ko /lib/modules/`uname -r`/kernel/drivers/video/pt1_drv.ko
$ sudo depmod -a
$ sudo modprobe pt1_drv
$ sudo cp etc/99-pt1.rules /etc/udev/rules.d/

デバイスファイルの生成を確認

$ ls -l /dev/pt1*
crw-rw-rw- 1 root video 250, 0 2010-05-16 12:10 /dev/pt1video0
crw-rw-rw- 1 root video 250, 1 2010-05-16 12:10 /dev/pt1video1
crw-rw-rw- 1 root video 250, 2 2010-05-16 12:10 /dev/pt1video2
crw-rw-rw- 1 root video 250, 3 2010-05-16 12:10 /dev/pt1video3

カーネルを更新したあとなど、Cannot tune to the spcified channelのエラーが出ることがある。その場合は、上のdepmodmodprobeを行えばよい。

recpt1の設定をする。最新リビジョンにはb25デコードライブラリが同梱されていないので、同梱されているリビジョンをチェックアウトする。

$ hg clone http://hg.honeyplanet.jp/pt1/ PT2_old -r 73
$ cd PT2_old/arib25
$ make
cd src; make all
make[1]: ディレクトリ `/home/foltia/PT2_old/arib25/src' に入ります
gcc -O2 -g -fPIC -Wall `pkg-config libpcsclite --cflags` -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64  -c -o b_cas_card.o b_cas_card.c
gcc -O2 -g -fPIC -Wall `pkg-config libpcsclite --cflags` -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64  -c -o multi2.o multi2.c
gcc -O2 -g -fPIC -Wall `pkg-config libpcsclite --cflags` -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64  -c -o ts_section_parser.o ts_section_parser.c
gcc -O2 -g -fPIC -Wall `pkg-config libpcsclite --cflags` -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64  -c -o td.o td.c
gcc  -o b25 arib_std_b25.o b_cas_card.o multi2.o ts_section_parser.o td.o `pkg-config libpcsclite --libs` -lm
gcc  -shared -o libarib25.so arib_std_b25.o b_cas_card.o multi2.o ts_section_parser.o `pkg-config libpcsclite --libs` -lm -Wl,-soname,libarib25.so.0
make[1]: ディレクトリ `/home/foltia/PT2_old/arib25/src' から出ます

$ sudo make install
cd src; make install
make[1]: ディレクトリ `/home/foltia/PT2_old/arib25/src' に入ります
mkdir -p /usr/local/include/arib25
install -m644 arib_std_b25.h b_cas_card.h portable.h /usr/local/include/arib25
install -m755 b25 /usr/local/bin
install -m755 libarib25.so /usr/local/lib/libarib25.so.0.2.4
ln -sf /usr/local/lib/libarib25.so.0.2.4 /usr/local/lib/libarib25.so.0
ln -sf /usr/local/lib/libarib25.so.0 /usr/local/lib/libarib25.so
ldconfig
make[1]: ディレクトリ `/home/foltia/PT2_old/arib25/src' から出ます

$ cd ../recpt1
$ make
revh=`hg parents --template 'const char *version = "r{rev}:{node|short} ({date|isodate})";\n' 2>/dev/null`; \
    if [ -n "$revh" ] ; then \
        echo "$revh" > version.h; \
    else \
        echo "const char *version = \"'1.0.0'\";" > version.h; \
    fi
gcc -MM recpt1.c decoder.c mkpath.c -I../driver -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DB25 > .deps
gcc -O2 -g -pthread -I../driver -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DB25  -c -o recpt1.o recpt1.c
gcc -O2 -g -pthread -I../driver -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DB25  -c -o decoder.o decoder.c
gcc -O2 -g -pthread -I../driver -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DB25  -c -o mkpath.o mkpath.c
gcc  -o recpt1 recpt1.o decoder.o mkpath.o `pkg-config libpcsclite --libs` -larib25 -lm -lpthread

$ sudo make install
install -m 755 recpt1 /usr/local/bin
$ sudo sh -c 'echo "/usr/local/lib" > /etc/ld.so.conf.d/recpt1.conf'
$ sudo ldconfig

pt1のスレッドが走っているか確認する。

$ dmesg | grep pt1
[    9.343588] pt1-pci.c: r116:38a793ac3d9d 2010-03-25 
[   10.418279] pt1_thread run

録画してみる

$ recpt1 --b25 --strip 19 30 ~/test.ts
using B25...
enable B25 strip
Signal=34.658791dB
Recording…

VLCで再生してみるとローカルでは問題なく再生できたが、UDPを飛ばしてMacのVLCで再生しようとすると上手くいかなかった。VLCメニューの「ファイル」→「ネットワークを開く」→「RTP/UDPストリームを開く」と進んでいき、IPアドレスを録画鯖のIPアドレス、ポートはそのまま1234にしたが、うまく再生できなかった。よくよく調べると、これはモードがマルチキャストになっていたからで、ユニキャストモードにしてポート番号だけ指定すれば受信できた。よく考えれば、録画鯖のrecpt1で宛先IPアドレスを指定してUDPパケットを垂れ流しているので、受信側で改めてIPアドレスを指定するのも変な話だ。

UDP以外の他マシン再生方法を探していたらLinux板のデジタル放送スレでHTTP版を公開している人がいた。

とりあえずhttpサーバー版の暫定版をアップしてみました。 makeの方法は最近のrecpt1と同じでいけると思います。

(driveとarib25をインストールした後)

``` ./autogen.sh ./configure --enable-b25 ./make

recpt1 --b25 --strip --http 8888 ```

みたいにすると8888番ポートでデーモン起動し、 VLCなどで http://hostname:8888/25

などするとUHF25チャンネルが視聴できるはずです。

http://2sen.dip.jp/cgi-bin/pt1up/source/up0280.gz

ログをちゃんと吐かないとか、家にBSアンテナがないので試していないとか 色々問題がありますが・・

動作報告等ありましたら嬉しいです。 (サポートできるかどうかは不明ですが・・)

(当方は32bit ubuntu 8.10でテストしました)

FoltiaHDのインストール

さて、recpt1は動いたので次はFoltiaのインストールをする。foltia - SQLite対応へを見ながらすすめる。

必要なパッケージをあらかた入れておく。wineはTsSplitterのために必要なので、TS分割をtss.py(後述)で行う場合は不要だった。

$ sudo apt-get install wine mplayer imagemagick subversion git-core yasm sqlite3 postgresql php5 php5-sqlite

sqliteのテーブルを作成するSQLファイルが付属されているので、これを使ってテーブルを作成する。

$ sqlite3 /home/foltia/foltia.sqlite < mktable.sqlite.txt

Apacheの設定を行う。Apacheをfoltia:foltiaで動かし、ドキュメントルートなどを適切に設定する。デフォルトの設定では、Foltiaは録画したTSファイルを/home/foltia/php/tvに、WebUIのPHPスクリプトを/home/foltia/phpに置く。

$ vi /etc/apache2/apache2.conf
User foltia
Group foltia
DocumentRoot "/home/foltia/php"
AddDefaultCharset off
Alias /foltia/ "/home/foltia/php/"

<Directory "/home/foltia/php">
</Directory>

$ /etc/init.d/apache2 restart

configファイルは推奨設定が.templateの拡張子付きで設置されているので、コピーして編集する。

$ cd /home/foltia/php
$ cp foltia_config2.php.template foltia_config2.php

$ cd ../perl
$ cp foltia_conf1.pl.template foltia_conf1.pl

$ ./getxml2db.pl long

DBIとDBI::SQLiteが必要だそうなのでCPANで入れる。また、今回はPostgreSQLは使わないが、Perlのソース中でDBD:Pgを読み込むようになっているので、ことごとくコメントアウトしてしまう。

ここまで行ってhttp://host/foltia にアクセスすると、放映予定が表示される。

ログローテート

デバッグログがすべて~foltia/debuglog.txtに残され、とくにインストールしたてで設定のおぼつかない状態ではエラーログ祭りになっている。私の場合、1週間くらいほかっておいたらこのファイルのサイズが4GBに達していてトレースも満足にできない状態だった。ちゃんとローテートしておく。

$ vi /etc/logrotate.d/foltia
/home/foltia/debuglog.txt {
    dayly
    rotate 6
    size=100k
    missingok
}

インストール後につまずいたところ

音がずれる

Foltiaのキモの処理の一つ、録画したファイルのiPod向け変換はipodtranscode.plが行っている。mplayerでサムネイルを作成し、ffmepgでh.264ファイルを作成し、mplayerでwavを切り出し、それをneroAacEncかfaacでaacに変換してMP4Boxでくっつけてipod向けmp4ファイルにしている。

この処理中、MP4Boxでaacファイルをbase.mp4にaddしようとするとbuffer overflow detectedというエラーがでた。検索したところ、どうやらUbuntuのバグなのらしい。ここに書いてある通りmpeg4ip-serverパッケージのmp4creatorで代用し、うまくいったが今度は音がずれた。なのでneroAacEncは使わずに、faacを使うことにした。こちらはうまくいった。

音が出ない

あまり詳しいログをとってないので良くないのだけど、ipodtranscode.plのやり方で動画ファイルを作成してiTunesに取り込むと、音声が再生されなかった。なので、mplayerでwavを切りだしてaacにしてMP4Boxで動画と合わせる処理を全てコメントアウトして、ffmpeg内で音声のエンコードも行うことにした。これでiTunesでの再生でも音声が再生されるようになった。

iTunesに取り込めない

それで喜んでいたのだが、そのうちPodcast経由でiTunesに取り込めなくなった。動画をMacにダウンロードしてiTunesの「ムービー」に突っ込めば再生できるのに、なぜかPodcast経由だと取り込めないということがあった。それでほっておくと翌日の更新では取り込めたりした。よくわからない。

いろいろ試行錯誤して、iPhone3G向けに以下のフォーマットでエンコードすればだいたい上手く行くことがわかった。

ffmpeg -y -i hoge.m2t -vcodec libx264 -b 512k -bt 512k -coder 0 -level 30 -s 640x360 -aspect 16:9 -qmin 10 -r 30000/1001 -acodec libfaac -ar 44100 -ab 128k -threads 8 -vpre hq -vpre ipod640 hoge.mp4

ffmpegのバージョン・オプションは以下のとおり:

$ ffmpeg -version
FFmpeg version SVN-r23392, Copyright (c) 2000-2010 the FFmpeg developers
  built on Jun  1 2010 00:01:38 with gcc 4.4.3
  configuration: --enable-libmp3lame --enable-libx264 --enable-libxvid
--enable-libfaac --enable-libfaad --enable-pthreads --enable-gpl
--enable-nonfree
  libavutil     50.16. 0 / 50.16. 0
  libavcodec    52.72. 0 / 52.72. 0
  libavformat   52.67. 0 / 52.67. 0
  libavdevice   52. 2. 0 / 52. 2. 0
  libavfilter    1.20. 0 /  1.20. 0
  libswscale     0.10. 0 /  0.10. 0
FFmpeg SVN-r23392
libavutil     50.16. 0 / 50.16. 0
libavcodec    52.72. 0 / 52.72. 0
libavformat   52.67. 0 / 52.67. 0
libavdevice   52. 2. 0 / 52. 2. 0
libavfilter    1.20. 0 /  1.20. 0
libswscale     0.10. 0 /  0.10. 0

……と喜んでいたら、このオプションでうまくいかないものもあった。tss.pyでTS分割を事前にしておけば上手くこともあった。

$ tss.py motoneta.m2t

なので、TS分割させたファイルをffmpegにかけ、その後mp4ファイルが生成されていなければTS分割させてないファイルをffmpegにかけ直すようにipodtranscode.plを書き換えた。

その他失敗するケース

録画中に解像度が変わるとエンコードに失敗し、解像度が変わったタイミングで映像は止まり、音声だけが再生されるようになる。仕様上番組開始の30秒前から録画が始まるので、前の番組と録画したい番組とで解像度が異なると失敗してしまう。

いじっている間見ていたサイト