8
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

VLC Extensionsからサーバのrecpt1を起動、停止させる

はじめに

家では録画サーバとして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の終了時に呼ばれるメソッドはもしかしたら存在しないのかもしれない。

参考

VLCのエクステンションで地デジをリアルタイム視聴する
VLC Extensions Readme

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
8
Help us understand the problem. What are the problem?