mimikakimemo

自分用メモ。

Ubuntu 11.10 へ recfsusb2n for linux を導入

秋葉原ソフマップKTV-FSUSB2を購入。3,980円で、S/NはK1108だった。

KEIAN KEIAN USBフルセグ&ワンセグチューナー KTV-FSUSB2

KEIAN KEIAN USBフルセグ&ワンセグチューナー KTV-FSUSB2

Wiki等を参考に必要な改造を施し、Windows上のTVTestで視聴・録画できることを確認しておく。ちなみに強敵だと評判のネジだが、ドライバは上から押し付けるだけにして本体の方を廻すようにしたらうまくいった。プロテクトについてはカッターで7番ピンを切除した。

以下、このKTV-FSUSB2をLinuxで使えるようにする。

デバイスの接続

配布ページ:recfsusb2n for linux

まずデバイスを接続していない状態で、使用するユーザーを video グループに追加。

$ sudo gpasswd -a ユーザー名 video

/lib/udev/rules.d/89-tuner.rules を以下の内容で作成。

# FSUSB2N
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="0511", ATTRS{idProduct}=="0029", MODE="0664", GROUP="video"

そしてデバイスを接続し、認識されているか確認。

$ lsusb -d 0511:
Bus 002 Device 003: ID 0511:0029 N'Able (DataBook) Technologies, Inc.

ここで上記 Bus 002 Device 003 のグループ(root になっている)を video に変更する必要があるみたい?

$ sudo chgrp video /dev/bus/usb/002/003

これをやらずに進んだら最後の動作確認で "usb open failed13!!" と出てうまくいかなかった。

どうやら 89-tuner.rules の "usb_device" の部分を "usb device" と typo していたのが原因っぽい。あとグループの追加を反映させるには、ログアウトしてからログインし直す必要がある。

recfsusb2n の make

g++ とライブラリをインストール。

$ sudo apt-get install g++ libboost-thread-dev libboost-filesystem-dev

配布ページからソース(現在の最新版は 0.9.2 (2011/04/06 23:55))をダウンロードして make。が、エラーが出た。

$ tar xvzf recfsusb2n-0.9.2.tar.gz
$ cd FSUSB2N/
$ make
g++ -g -Wall -pthread -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DB25   -c -o fsusb2n.o fsusb2n.cpp
g++ -g -Wall -pthread -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DB25   -c -o usbops.o usbops.cpp
g++ -g -Wall -pthread -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DB25   -c -o em2874-core.o em2874-core.cpp
em2874-core.cpp: 静的メンバ関数 ‘static EM2874Device* EM2874Device::AllocDevice()’ 内:
em2874-core.cpp:126:37: エラー: ‘class boost::filesystem3::directory_entry’ has no member named ‘string’
em2874-core.cpp:128:47: エラー: ‘class boost::filesystem3::directory_entry’ has no member named ‘string’
make: *** [em2874-core.o] エラー 1

ググったら以下のページでパッチが公開されていたのでこの2つを適用。ついでにその下の「先頭のパケットを棄てる」パッチも当ててみる。

em2874-core.cpp:

@@ -123,9 +123,9 @@
 				// バスに繋がっているデバイスでループ
 				if (!boost::filesystem::is_directory(*dev_iter)) {
 					// 開く
-					if (pDev->openDevice(dev_iter->string().c_str())) {
+					if (pDev->openDevice(dev_iter->path().string().c_str())) {
 						isFound = true;
-						if(log) *log << "device: " << dev_iter->string() << std::endl;
+						if(log) *log << "device: " << dev_iter->path().string() << std::endl;
 						break;
 					}
 				}

Makefile:

@@ -10,8 +10,8 @@
 CXX	= g++
 CXXFLAGS = -g -Wall -pthread -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 $(B25)
 OBJS	= fsusb2n.o usbops.o em2874-core.o ktv.o IoThread?.o $(B25_OBJS)
-#LIBS	= -lpthread -lboost_system -lboost_thread-mt -lboost_filesystem
-LIBS	= -lpthread -lboost_thread-mt -lboost_filesystem
+LIBS	= -lpthread -lboost_system -lboost_thread-mt -lboost_filesystem
+#LIBS	= -lpthread -lboost_thread-mt -lboost_filesystem
 TARGET	= recfsusb2n
 
 all: $(TARGET)

fsusb2n.cpp:(先頭のパケットを棄てる)

@@ -183,10 +183,17 @@
 	usbDev->startStream();
 
 	// Main loop
+	int stream_counter = 0;
 	while (!caughtSignal && (args.forever || time(NULL) <= time_start + args.recsec)) {
 		usleep(750000);
 		const void *buf = NULL;
 		int rlen = usbDev->getStream(&buf);
+
+		stream_counter++;
+		if (stream_counter < 2) {
+			continue;
+		}
+
 		if (0 == rlen) continue;
 #ifdef B25
 			// B25を経由して受け取る

追記:この他に以下の問題があるので、このパッチも当てておく。

再度 make したら今度はうまくいった。

動作確認

$ ./recfsusb2n -bv 27 40 test.ts

ちゃんと録画されていることを確認したら、パスの通っているところにコピーしておく。

$ sudo cp recfsusb2n /usr/local/bin