TvServer on Raspberry Pi
TVServer on Raspberry Pi with BonCasProxy (2021/01/26更新)
BonCasServerをMac上に構成する方法は前回の記事で載せましたが、今回は地上波放送の視聴用サーバーをRaspberry Pi上にサーバーを構築し、Macから既成のVLC media Playerを使用して視聴する方法を検討しました。この方法はWeb上でも多く掲載されており特に難しいことではありませんでしたが、この方法はCard Readerを別に用意する必要があり、せっかく構築したBonCasServerがあるので、これを使用できるようにとプログラムを作成しました。
1. きっかけ
現在はテレビ視聴の為にMac上でVMware Fusionを入れてWindows用プログラムであるTVtestを使用していました。しかしならが最近MacOSがBig Sur になってから、Windows上の画面描画が使い物にならない位遅くなり他の代用プログラムを探していました。Web検索で見つかったのはRaspberry Piでサーバー構築すると言う物でしたがなんとかしてMac上で動作させられないかという検討を進めないました。しかしRaspberry Piの小ささや低価格から外部でもいいかと言うことになり、これを使うことに決めました。ただ、現用のBonCasServerを使用出来るようにプログラムを改造する事にしました。
2.プログラムを動作させる
取り敢えず、Webの記事を参考にPX-S1UD -> Libarib25 -> recdvb -> Mirakurunまでを動作させる事にします。この段階でCard Readerは必要ですが、後にLibarib25に含まれるCard Read部分をBonCasProxyプログラムに入れ替える事とします。
2.1 Mirakurunサーバーまで導入
ここはWeb記事を参考に事を進めます。記事は
uepon日々の備忘録 がいいでしょう。
この記事通りに進めMirakurunサーバーの導入まで行ないます。視聴専用なのでその後のChinachuの導入は不要です。記事にはありませんが、Raspberry P iに local 固定 Ip addressを設定しておくことをお勧めします。
2.2 Macでの視聴
視聴用のMacでApp Storeからではなく、VLC media playerからソフトをダウンロードしてインストールします。
インストールしたら実行させプレイリストを表示させ、VLC Channel.m3uをドロップします。(このファイルは左の青文字を右クリックして”リンク先のファイルをダウンロード”を選択してダウンロードしておきます。)
しかしながら、ダウンロードしたファイルは私の環境設定に合わせてあるので、エラーが出て動作させられないはずです。ここでこのファイルをEditして、環境に合わせる必要があります。
このファイル1チャンネル分の例を見ると、
#EXTINF:0,地上波 - NHK総合
http://192.168.10.192:40772/api/channels/GR/27/services/1024/stream/
となっています。
192.168.10.192はRaspberry PiのIp addressで私の場合です。これを修正します。
GR/以下の/27/services/1024/は物理チャンネルとServiceID(同一チャンネルでも複数の放送があるのでメインチャンネルを選定)を設定します。
このServiceID情報を得るにはRaspberry Pi上で
$ sudo npm install rivarun -g
でrivarunをインストールした後
$ rivarun --list | sed 's/},/},\n/g' > serviceID.txt
とすればserviceID.txtに利用可能なチャンネルやserviceIDが書き込まれ、参照することができます。
自分の環境に合わせてこのVLC Channel.m3uを書き直せば下記の用に表示されるはずです。
この状態でリストをダブルクリックすれば放送を見ることができます。さらにダブルクリックでフル表示画面となります。チャンネル切り替えは(<<)または(>>)で行えます。操作性はtvTestほどではないにせよ汎用のソフトでこれだけの操作が出来るので、特に視聴ソフトを開発することなしに十分使用出来ます。またWindowsやスマホでもVLCメディアプレーヤをインストールできれば、どこでもTVを見ることができます。
3. BonCasServerを利用する為にBonCasProxyを導入
さて、ここからが本題となりますが、改造すべくWebを検索していたら、
Linux で BonCasLink のクライアント側を実現
と言う記事を見つけました。
この記事ではlibarib25のcardreaderプログラムをフックして、BonCasServerのクライアントプログラムを動作させるものです。
実際このプログラムは素晴らしく、うまく動作していることが確認できました。
しかしながら、このプログラムを動作させるにはLD_PRELOADと言う環境変数をセットしなければなりません。ユーザーアカウントからrecdvbを動作させるには問題ないのですが、システムサービスであるMirakurunサーバーからの動作をさせることはできませんでした。これはLD_PRELOADと言う変数が危険な変数でシステムレベルでの設定を制限されているためのようです。
従って、これを使うことは断念し、このプログラムをCに描き直し、libarib25内のb_cas_card.cに付け加えることにしました。
3.1 b_cas_card.cの改造
b_cas_card.cは ~/libarib25/src/ の下にあります。このFileをEditしていくことになります。改造したものをアップしようとも思いましたが、ライセンスの関係もあると思い、ここでは改造方法のみを述べることにしました。
まず下記の2つのファイルをダウンロードします。
(ダウンロードの方法は右クリックで”リンク先のファイルをダウンロード”を選択してダウンロードします。)
b_cas_card.cとSProxyXxxx.cをテキストエディターで開き、SProxyXxxx.cの内容をb_cas_card.cの最後部に追加します。つなぎ目部分は下記の様になります。
r <<= 8;
r |= p[i];
}
return r;
}
//////////////////////////////////////////////////////////////////////
// Rewrite WinSCard hook to SProxy
//////////////////////////////////////////////////////////////////////
LPCSTR B25_SERVER_IP = "192.168.10.210";
#ifndef SCARD_AUTOALLOCATE
#define SCARD_AUTOALLOCATE (DWORD)(-1) //*< see SCardFreeMemory()
#endif
#define TRUE 1
このつなぎ目部分(SProxyXxxx.cの最初の部分)にある、
LPCSTR B25_SERVER_IP = "192.168.10.210";
はBonCasServerのIpアドレスを示すものなので、自分の環境に合わせて、変更します。
次にProtType.cの内容をb_cas_card.cの”function prottypes (interface method)”に追加します。内容は下記の様になります。
#define B_CAS_BUFFER_MAX (4*1024)
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
function prottypes (interface method)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
static void release_b_cas_card(void *bcas);
static int init_b_cas_card(void *bcas);
static int get_init_status_b_cas_card(void *bcas, B_CAS_INIT_STATUS *stat);
static int get_id_b_cas_card(void *bcas, B_CAS_ID *dst);
static int get_pwr_on_ctrl_b_cas_card(void *bcas, B_CAS_PWR_ON_CTRL_INFO *dst);
static int proc_ecm_b_cas_card(void *bcas, B_CAS_ECM_RESULT *dst, uint8_t *src, int len);
static int proc_emm_b_cas_card(void *bcas, uint8_t *src, int len);
LONG SProxyConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard, LPDWORD pdwActiveProtocol);
LONG SProxyDisconnect(SCARDHANDLE hCard, DWORD dwDisposition);
LONG SProxyEstablishContext(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2, LPSCARDCONTEXT phContext);
LONG SProxyListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders);
LONG SProxyTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci, LPCBYTE pbSendBuffer, DWORD cbSendLength, LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer, LPDWORD pcbRecvLength);
LONG SProxyReleaseContext(SCARDCONTEXT hContext);
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
global function implementation
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
ARIB25_API_EXPORT B_CAS_CARD *create_b_cas_card()
{
int n;
そして最後にこのb_cas_card.c内でlibarib25のライブラリーを呼んでいる、"SCasXxxx...."の部分を"SProxyXxxx....."に変更して追加したプログラム呼ぶ様に変更します。10カ所程度あると思いますが、注意深く抜けのないように"Cas"を"Proxy"に置換してください。
3.2 /usr/local/lib/にあるlibarib25.soの再構築
b_cas_card.cの修正が完了したら元の位置に戻して、~/libarib25の位置からmake, make installすれば、libarib25.soは再構築できます。
$ cd ~/libarib25
$ make clean
$ make
$ sudo make install
$ sudo mirakurun restart
これで、BCASカードとCard Readerは不要となります。
4. 結論
我ながら、結構スマートにシステムを構築できたと思っている。気を良くして2台のRaspberryPiを購入して、TVサーバーを2組作成した。
実際に配置した写真を右に載せている。右側のMac Miniは以前構築したBonCasServerがのっており、その右にカードリーダーが見える。Raspberry PiにはそれぞれLANケーブルとUSB端子にPX-S1UDが接続されている。電源はUSB給電が可能なので、Mac MiniのUSB端子からとっている。
BonCasServerは別にある録画用サーバー(Windows10 DOS-V)からもアクセスされているが、負荷としてはそれほど重くない様で、もう十台程度のクライアントから同時アクセスされても問題はないと思う。
Raspbery PiのTvサーバーは場所を選ばず、家の中どこでも配置でき、視聴用PCもどこにあっても良いので、非常に便利である。視聴画質も非常に良好で、大変満足している。
5. 追記(VNCによる接続について)*2021/04/03
この利用方法では、RaspberryPiはサーバーであるのでDisplayは通常接続しておく必要はなくて単に立ち上げておけば事が足りる。しかしながら設定替えなど必要な場合はディスプレーやキーボード等の接続が必要であり、私の場合はVNCを利用して、メインデスクトップから接続している。
ここで問題になるのが、ディスプレーを接続しないで、リブートするとHDMI制御が立ち上がらずVNC接続もできなくなってしまう。(だだTVサーバーの機能には問題ないが)
そこで、/boot/config.txtのファイルをEditして
#hdmi_force_hotplug=1
の#を外し有効化する。さらにGUIからディスプレーを接続しなくとも解像度の変更を可能にできるように、
hdmi_ignore_edid=0xa5000080
をconfig.txtに追加しておくと良い。立ち上げた後Preference->Screen Configurationから自由に解像度を設定できるようになる。