はじめに
家では録画サーバとしてPT3を使用している。
PT3をリアルタイム試聴するには、一度サーバにログインし、recpt1を実行しなければならないが、これがめんどくさい。
なので今回サーバのrecpt1を起動、停止させるVLC Extensionsを作った。
BitBucket
ファイル構成
作成したのは以下のファイル
- startrecpt1.php
- stoprecpt1.php
- watchTV.lua
startrecpt1.php
- アクセスするとrecpt1を実行する。レスポンスとしてpidを返す。実行に失敗した場合は何もしない。
- recpt1が既に実行済の場合はそのpidを返す。
- パラメータとして、?start=trueを受け取らないと開始しない(誤動作防止のため)。受け取らない場合は何もしない。
stoprecpt1.php
- パラメータとして、?pid=pidを受け取る。受け取らない場合は何もしない。
- pid受け取り時、recpt1のpidと一致するか確認する。
- 受け取ったpidのプロセスを殺す。
watchTV.lua
- 実行時にサーバ側でrecpt1が起動する。
- ドロップダウンからチャンネルを選択可能。VLCのプレイリストにもチャンネル一覧が追加される。
- 終了する場合は、地デジ視聴ダイアログを閉じるか、視聴中にQキーを押すようにする。
コード
startrecpt1.php
<?php
$start = false;
if( isset( $_GET['start'] ) ){
$start = $_GET['start'];
}
// recpt1が既に実行されているか確認。
// 実行されていればpidを、されていなければfalseを返す。
function checkPidOfRecpt1(){
$ret = false;
$command = "ps aux | grep recpt | awk '$11 ~ /^recpt1/ && /http/{print $2}'";
$handle = popen($command , "r");
if($handle){
$ret = fread($handle , 10);
}
pclose($handle);
return $ret;
}
// recpt1実行。pidを出力する。
function startRecpt1(){
$handle = popen("recpt1 --b25 --strip --sid hd --http 8080 2>&1" , "r");
if($handle){
while(!feof($handle)){
$buffer = fgets($handle);
if(preg_match('/pid\s*=\s*(\d+)/', $buffer, $m)){
print($m[1]."\n");
break;
}
}
}
pclose($handle);
}
if( $start == "true" ){
if( $pid = checkPidOfRecpt1() ){
print($pid);
}else{
startRecpt1();
}
}
?>
stoprecpt1.php
<?php
$pid = false;
if( isset( $_GET['pid'] ) ){
$pid = intval($_GET['pid']);
}
// 届いたpidがrecpt1のpidか確認する
// pidが数字であることを確認してからこの関数を呼ぶこと
function isPidOfRecpt1($pid){
$ret = false;
$command = "ps aux | grep recpt | awk '$1 == \"www-data\" && $11 ~ /^recpt1/ && $2 == " . $pid . " && /http/{print $2}'";
$handle = popen($command , "r");
if($handle){
$buffer = fread($handle , 10);
if($buffer){
$ret = true;
}
}
pclose($handle);
return $ret;
}
// 受け取ったpidを殺す
// pidが存在するか確認してからこの関数を呼ぶこと
function killPid($pid){
$command = "kill -9 ". $pid . " 2>&1";
$handle = popen($command , "r");
if($handle){
$buffer = fread($handle , 100);
print($buffer . "<br>"); // デバッグ用
}
pclose($handle);
}
if( $pid ){
if( isPidOfRecpt1($pid) ){
killPid($pid);
print($pid); // デバッグ用
}
}
?>
watchTV.lua
channel_name_to_number = {}
channel_name_to_number["MBS毎日放送"] = 16
channel_name_to_number["ABCテレビ"] = 15
channel_name_to_number["NHK総合"] = 24
channel_name_to_number["NHK教育"] = 13
channel_name_to_number["テレビ大阪"] = 18
channel_name_to_number["関西テレビ"] = 17
channel_name_to_number["読売テレビ"] = 14
channel_name_to_number["サンテレビ"] = 26
channel_name_to_number["KBS京都"] = 23
pid = nil
dlg = nil
dropdown = nil
quit_key = 113 -- Qキー
function descriptor()
return { title = "地デジ視聴" ,capabilities={} }
end
function activate()
pid = nil
dlg = nil
dropdown = nil
local s = vlc.stream( "http://192.168.1.2/epgrec/startrecpt1.php?start=true" )
pid = tonumber(s:read(10))
local path = "http://192.168.1.2:8080/15"
local name = "ABCテレビ"
local mytable = {path = path; name = name}
vlc.playlist.add({mytable})
for name, number in pairs(channel_name_to_number) do
local path = "http://192.168.1.2:8080/" .. number
local mytable = {path = path; name = name}
vlc.playlist.enqueue({mytable})
end
create_dialog()
vlc.var.add_callback(vlc.object.libvlc() , "key-pressed", key_press)
end
function deactivate()
local s = vlc.stream( "http://192.168.1.2/epgrec/stoprecpt1.php?pid=" .. pid )
vlc.playlist.clear()
vlc.var.del_callback(vlc.object.libvlc() , "key-pressed", key_press)
vlc.deactivate()
end
function close()
local s = vlc.stream( "http://192.168.1.2/epgrec/stoprecpt1.php?pid=" .. pid )
vlc.var.del_callback(vlc.object.libvlc() , "key-pressed", key_press)
vlc.deactivate()
end
function create_dialog()
dlg = vlc.dialog("地デジ視聴")
dropdown = dlg:add_dropdown(1,1,1,1)
for name, number in pairs(channel_name_to_number) do
dropdown:add_value(name, number)
end
dlg:add_button("視聴", click_select_button, 2,1,1,1)
end
function key_press(var , old , new , data)
if new == quit_key then
dlg:hide()
dlg:update()
dlg:delete()
vlc.deactivate()
end
end
function click_select_button()
local channel = dropdown:get_value()
local path = "http://192.168.1.2:8080/" .. channel
local name = "テレビ"
local mytable = {path = path; name = name}
vlc.playlist.add({mytable})
end
どうしてもできなかったこと
watchTV.luaを終了せずにVLCを終了した場合、サーバ側のrecpt1は起動したままになってしまう。
watchTV.lua内のclose()で終了するようにしているはずだが、なぜだろう。
VLCの終了時に呼ばれるメソッドはclose()じゃないのだろうか。
また、VLCの終了時に呼ばれるメソッドはもしかしたら存在しないのかもしれない。