Tuesday, February 24, 2009

epg.cgi, player.pl差し替え版look




OneSeg24 for Linux 付属epg.cgiにplayer.pl差し替え版のcssやカレンダーのjavascriptを移植して、それっぽくしてみた。
一見player.pl差し替え版にみえるが、放送中や未放送の部分をみると



時間指定や検索は未実装。

Monday, February 2, 2009

24時間ワンセグ野郎引越

いままでWindowsで動かしていた24時間ワンセグ野郎を自宅サーバーのマザーボード交換に伴いCPUパワーもアップしたことからFreeBSDへ引っ越した。
チューナーもLOG-J100からDUS-01へ変更。
UGEN経由のプログラムをここにあるとおりに書いてみた。SIGTERMとかの処理はさぼっているが(録画用perlプログラムからSIGTERMがやってくる)、一応動くようなのでOKということで。ただ、USB2.0ハブを通すと動かないのでK師匠に相談したところ、FreeBSD StableのEHCIドライバではUSB1.1のアイソクロナス転送がまだサポートされてないとのこと。引き出しの奥からひっぱり出してきたUSB1.1ハブにUSB2.0を2つ繋ぎ、そこにチューナーを8つ繋ぐことになった。
録画プログラムはOneSeg24 for Linux
を使用。dvbstreamのかわりに自作プログラムを使うので、オプション -c (num) で/dev/ugen(num) を使用するように、また -f で周波数設定 -o は無視してデフォルトで標準出力にTSを吐き出すようにした。
再生はperlrtmp(これもFreeBSD側に引越)とOneSeg24 for Linux付属のepg.cgi+player.cgiまたはplayer.pl差し替え版を使用、mp4変換や再エンコード機能は殺しているが今のところ必要なし。
今回はアンテナを分配器から鰐口クリップで接続したので、安定して録画できている。いやあ便利。
プログラムの作者のみなさんに感謝。
# その後1ヶ月分のTSファイルをWindowsからSAMBA経由でコピーするのに2日。

---
dus-01用手抜きプログラムFreeBSD版、ご自由にお使いいただいてかまいませんが、ご自分の責任で。
---

#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <dev/usb/usb.h>

#define TS_PACKET_SIZE 188
#define CMD_LEN 10
#define RET_MAX 3

char *ugenNum = "0";
int EP0,EP1,EP3;

unsigned char channelCmd[]={ 0x10,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
unsigned char chkRecCmd[] ={ 0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
unsigned char mpgOnCmd[] ={ 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
unsigned char mpgOffCmd[] ={ 0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };

int chkVnd()
{
struct usb_device_info udi;

if(ioctl(EP0,USB_GET_DEVICEINFO,&udi)<0){
perror("chkVnd");
return 0;
}
if(udi.udi_vendorNo != 0x1bc8 || udi.udi_productNo != 0x0001)
return 0;
return 1;
}

void wrCmd(unsigned char *cmdArr)
{
if(-1==write(EP1,cmdArr,CMD_LEN)){
perror("wrCmd");
}
}

void rdRet(unsigned char *retArr)
{
if(-1==read(EP1,retArr,RET_MAX)){
perror("rdRet");
}
}

int setCH(int freq)
{
int i;
unsigned char retArr[RET_MAX];

wrCmd(mpgOffCmd);
channelCmd[3] = (freq >> 16) & 0xFF;
channelCmd[4] = (freq >> 8) & 0xFF;
channelCmd[5] = freq & 0xFF;
wrCmd(channelCmd);
usleep(500000);
for(i=0;i<10;i++){
wrCmd(chkRecCmd);
rdRet(retArr);
if(retArr[0]){
wrCmd(mpgOnCmd);
return 1;
}
usleep(100000);
}
return 0;
}

int getTS(unsigned char *pdata)
{
int i;

if(TS_PACKET_SIZE > read(EP3, pdata, TS_PACKET_SIZE))
return 0;
for (i = 1; i < TS_PACKET_SIZE; i++)
pdata[i] ^= 0xb5;
return 1;
}

int main(int argc, char *argv[])
{

char devName[PATH_MAX],EPname[PATH_MAX];
unsigned char TsPkt[TS_PACKET_SIZE];
int opt;
int freq= 545143;
int i=1;

while((opt=getopt(argc, argv,"f:c:o"))!=-1){
switch(opt){
case 'o':break;
case 'c':
ugenNum=optarg;
break;
case 'f':
freq=atoi(optarg);
break;
default:break;
}
}
sprintf(devName,"/dev/ugen%s",ugenNum);
if(-1==(EP0=open(devName, O_RDWR))){
perror("open EP0");
exit(-1);
}

if(!chkVnd()){
fprintf(stderr,"this is not dus01\n");
exit(-1);
}

sprintf(EPname,"%s.1",devName);
if(-1==(EP1=open(EPname,O_RDWR))){
perror("open EP1");
exit(-1);
}

sprintf(EPname,"%s.3",devName);
if(-1==(EP3=open(EPname,O_RDONLY))){
perror("open EP3");
exit(-1);
}

ioctl(EP1,USB_SET_SHORT_XFER,&i);
if(!setCH(freq)){
fprintf(stderr,"No Signal\n");
exit(-1);
}

while(getTS(TsPkt))
write(STDOUT_FILENO,TsPkt,TS_PACKET_SIZE);
wrCmd(mpgOffCmd);
return 1;
}