čtvrtek 9. října 2014

DVB-T rekordér pro Turris

Nahrávač se skládá z několika sh a php skriptů. Nahrávač předpokládám zprovozněné streamování například pomocí MumuDVB, jak bylo popsáno v předchozím příspěvku. Každý program (TV kanál) má vyhrazen vlastní TCP port. Uživatelé tedy mohou zároveň sledovat všechny kanály jednoho multiplexu a ještě každý kanál nahrávat. Díky třem DVB-T kartám máme streamované všechny tři multiplexy. Pro zpracování uživatelem zadaných dat je soubor new_record.php. Ošetří, alespoň doufám, vstupní hodnoty a zavolá další soubor.

<html>
<head>
<meta charset="utf-8">
</head>
<body>
<?php
setlocale(LC_ALL, 'czech');
if (   isset($_REQUEST["DOBA_NAHRAVANI_MIN"])
    && isset($_REQUEST["ZACATEK_NAHRAVANI"])
    && isset($_REQUEST["NAZEV_SOUBORU"])
    && isset($_REQUEST["CISLO_KANALU"]))
{
    $DOBA_NAHRAVANI_MIN = intval($_REQUEST["DOBA_NAHRAVANI_MIN"]);
    $ZACATEK_NAHRAVANI = date("H:i d.m.y", strtotime(urldecode($_REQUEST["ZACATEK_NAHRAVANI"]))); // 11:35 01.10.14
    $URL = htmlspecialchars(urldecode($_REQUEST["NAZEV_SOUBORU"]));
    /*$URL = rtrim($URL, "_.");
    $URL = str_replace(" ", "_", $URL);*/
    echo "<p>\$URL=\"$URL\"</p>\n";
    $NAZEV_SOUBORU = preg_replace("/[^a-zA-Z0-9áäčďéěëíµňôóöŕřšťúůüýžÁÄČĎÉĚËÍĄŇÓÖÔŘŔŠŤÚŮÜÝŽ _-]/", "", $URL);
    $CISLO_KANALU = intval($_REQUEST["CISLO_KANALU"]);
   
    echo "<p>\$DOBA_NAHRAVANI_MIN=\"$DOBA_NAHRAVANI_MIN\"</p>\n";
    echo "<p>\$ZACATEK_NAHRAVANI=\"$ZACATEK_NAHRAVANI\"</p>\n";
    echo "<p>\$NAZEV_SOUBORU=\"$NAZEV_SOUBORU\"</p>\n";
    echo "<p>\$CISLO_KANALU=\"$CISLO_KANALU\"</p>\n";
   
    $PARAMETRY = $DOBA_NAHRAVANI_MIN.' "'.$ZACATEK_NAHRAVANI.'" '.'"'.$NAZEV_SOUBORU.'" '.$CISLO_KANALU;
    //$PARAMETRY = "1 \"20:45 02.10.14\" \"pokus\" 1000";
    // 1 "20:31 02.10.14" "pokus" 1000
    $PRIKAZ = "new_record.sh $PARAMETRY";
    //$PRIKAZ="sudo -u recorder whoami";//"whoami";
    echo "<pre>$PRIKAZ</pre>\n";
    $VYSTUP = shell_exec($PRIKAZ);
    //echo "<pre>$VYSTUP</pre>\n";
}
else echo "Neočekávaná data!";
?>
</body>


Sice soubor new_record.sh, ten již plánuje nahrávky pomocí at. Ve složce nahrávačů uloží soubor, který bude puštěn ve vhodnou dobu.

#!/bin/sh

DOBA_NAHRAVANI_MIN=$1 #"1" # 1 minuta
ZACATEK_NAHRAVANI=$2 #"11:35 01.10.14" # datum a čas nahrávání (formát "HH:MM DD.MM.YY")
NAZEV_SOUBORU=$3 #"pokus" # název souboru
CISLO_KANALU=$4 #"1000" # TCP port nahrávaného poradu
UMISTENI_NAHRAVACU="/etc/dvb-t/timetable/"
if [ "$#" -ne 4 ]; then
    echo -e "\n\e[0;31mŠpatně zadané parametry\e[0m"
    echo -e "\nnew_record.sh DOBA_NAHRAVANI_MIN ZACATEK_NAHRAVANI NAZEV_SOUBORU CISLO_KANALU\n"
    echo "DOBA_NAHRAVANI - délka pořadu v minutách"
    echo "ZACATEK_NAHRAVANI - začátek nahrávání (11:35 01.10.14)"
    echo "NAZEV_SOUBORU - název nahrávky"
    echo -e "CISLO_KANALU - číslo kanálu (např.: ČT1 1000)\n"
else
    PARAMETRY="\"$DOBA_NAHRAVANI_MIN\" \"$NAZEV_SOUBORU\" $CISLO_KANALU"
    NAZEV_NAHRAV_SOUBORU=`increment_write.sh "/usr/bin/record_now.sh $PARAMETRY"` # vytvoření nahrávacího skriptu
    chmod +x "$NAZEV_NAHRAV_SOUBORU"
    echo "->$NAZEV_NAHRAV_SOUBORU<-->$ZACATEK_NAHRAVANI<-"
    if sudo at -f $NAZEV_NAHRAV_SOUBORU $ZACATEK_NAHRAVANI
    then
        echo "Nahrávání pořadu $NAZEV_SOUBORU nastaveno."
    else
        rm $NAZEV_NAHRAV_SOUBORU
        echo -e "\e[0;31mNahrávání pořadu $NAZEV_SOUBORU se nepodařilo nastavit!.\e[0m"
    fi
fi

 Využívá pomocný skript pro inkrementální generování souborů pro zápis.

increment_write.sh

#!/bin/sh
# zapíše text do souboru 1.rec, když existuje, tak zapíše do 2.rec
if [[ -n "$2" ]]
then
  PRIPONA=$2
else
  PRIPONA="rec"
fi
UMISTENI="/etc/dvb-t/timetable/"
for i in $(seq 5)
do
  file=$UMISTENI/$i.$PRIPONA
  if [ ! -f "$file" ]
  then
    echo $1 > $UMISTENI/$i.$PRIPONA
    break
  fi
done
echo $UMISTENI/$i.$PRIPONA


A nyní k vlastnímu způsobu nahrávání, soubor se v podstatě jen stahuje po určitou dobu pomocí wgetu.
#!/bin/sh

UMISTENI_NAHRAVEK="/mnt/hdd/movie"
#DOBA_NAHRAVANI_MIN="1" # 1 minuta
#ZACATEK_NAHRAVANI="" # datum a čas nahrávání
#NAZEV_SOUBORU="pokus" # název souboru
#CISLO_KANALU="1000" # TCP port nahrávaného poradu

DOBA_NAHRAVANI_MIN=$1
ZACATEK_NAHRAVANI=`date +"%T %d.%m.%Y"`
NAZEV_SOUBORU=$2".TS"
CISLO_KANALU=$3

#echo -en "\e[1;32m" # light green
echo -en "\e[0;32m" # green
echo `date +"%T %d.%m.%Y"`" spuštěno nahrávání pořadu "$NAZEV_SOUBORU
echo -en "\e[0m" # no color

wget localhost:$CISLO_KANALU -O "$UMISTENI_NAHRAVEK/$NAZEV_SOUBORU" &
ID_PROCESU=$!
echo "ID procesu = "$ID_PROCESU
sleep $DOBA_NAHRAVANI_MIN"m"
kill $ID_PROCESU
#echo -en "\e[1;32m" # light green
echo -en "\e[0;32m" # green
echo -en `date +"%T %d.%m.%Y"`" ukončeno nahrávání pořadu \e[1;34m"$NAZEV_SOUBORU"\e[0;32m\n"
VYSLEDEK=`du -h "$UMISTENI_NAHRAVEK/$NAZEV_SOUBORU"`
VELIKOST=`echo $VYSLEDEK | sed -n "s/\(.*\) .*/\1B/p"`
logger "Ukončeno nahrávání pořadu $NAZEV_SOUBORU ($VELIKOSTB)"
echo -en "Velikost nahraného souboru je \e[1;34m$VELIKOST\e[0;32m\n"
echo -en "\e[0m" # no color


Pro povolení spouštění příkazu /usr/bin/at je nutné nainstalovat sudo a v konfiguraci doplnit následující řádek. Ale pozor needitovat přímo soubor /etc/sudoers ale pomocí visudo.

nobody ALL= NOPASSWD: /usr/bin/at

Nyní již může uživatel nobody pouštět at (pomocí sudo /usr/bin/at).

Výsledné naplánované nahrávky vypadají takto, soubory vždy obsahují informace o nahrávaném pořadu, do budoucna bude ještě doplněn popis apod. Pomocí příkazu atq je možné si zobrazit seznam a stav naplánovaných nahrávek. Nahrané úlohy zůstávají v složce plánovačů nahrávek, je možné je tedy zpětně dohledat a nebo rovnou mazat.

root@turris:/etc/dvb-t/timetable# ls
1.rec  2.rec  3.rec
root@turris:/etc/dvb-t/timetable# cat 3.rec
/usr/bin/record_now.sh "220" "Nejlepší z Brooklynu" 1012
root@turris:/etc/dvb-t/timetable# atq
17      Thu Oct  9 22:35:00 2014 a root
root@turris:/etc/dvb-t/timetable#

Dále jsem si připravil jednoduché načítání xml souborů EPG.

<!DOCTYPE html>
<html>
<meta charset="utf-8">
<style type="text/css">
    .cerveny {color: red}
    .zeleny {color: green}
</style>
<body>
<script>
function nahrazeniNazvu(vstup)
{
    for (i=0;i<poleNazvu.length;i++)
    {
        if (poleNazvu[i][0] == vstup) return poleNazvu[i][1];
    }
    return vstup;
}

if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
<?php
$soubor="sit1.xml";
if (isset($_GET["multiplex"]))
{
    switch ($_GET["multiplex"])
    {
        case "MUX1":
            $soubor = "sit1.xml";
        break;
        case "MUX2":
            $soubor = "sit2.xml";
        break;
        case "MUX3":
            $soubor = "sit3.xml";
        break;
    }
}
echo "xmlhttp.open(\"GET\",\"$soubor\",false)\n";  
?>
xmlhttp.send();
xmlDoc=xmlhttp.responseXML;

document.write("<table border='1' cellpadding='6'>");
// načtení skutečných názvů DVB kanálů
var x=xmlDoc.getElementsByTagName("channel");
var poleNazvu = new Array();
var p=0;
for (i=0;i<x.length;i++)
{
    poleNazvu[p++] = [x[i].id, x[i].getElementsByTagName("display-name")[0].childNodes[0].nodeValue];  
}
// načtení položek seznamu pořadů
x=xmlDoc.getElementsByTagName("programme");
for (i=0;i<x.length;i++)
{
    document.write("<tr>");
    try
    {
        if (x[i].hasAttribute("channel"))
        {
            document.write("<td>");
            //document.write(nahrazeniNazvu(x[i].attributes.getNamedItem("channel").value));
            document.write(x[i].attributes.getNamedItem("channel").value);
            document.write("</td>");
        }
        if (x[i].hasAttribute("start"))
        {
            document.write("<td>");
            document.write(x[i].attributes.getNamedItem("start").value);
            document.write("</td>");
        }
        if (x[i].hasAttribute("stop"))
        {
            document.write("<td>");
            document.write(x[i].attributes.getNamedItem("stop").value);
            document.write("</td>");
        }
        //if (x[i].childNodes[0].hasAttribute("title"))
        try
        {
            document.write("<td>");
            document.write(x[i].getElementsByTagName("title")[0].childNodes[0].nodeValue);
            document.write("</td>");
        }
        catch (chyba){}
        //if (x[i].childNodes[0].hasAttribute("sub-title"))
        try
        {
            document.write("<td>");
            document.write(x[i].getElementsByTagName("sub-title")[0].childNodes[0].nodeValue);
            document.write("</td>");
        }
        catch (chyba){}
    }
    catch (chyba)
    {
    }
    /*document.write(x[i].getElementsByTagName("start")[0].childNodes[0].nodeValue);
    document.write("</td><td>");
    document.write(x[i].getElementsByTagName("stop")[0].childNodes[0].nodeValue);
    document.write("</td><td>");
    document.write(x[i].getElementsByTagName("title")[0].childNodes[0].nodeValue);
    document.write("</td><td>");
    document.write(x[i].getElementsByTagName("sub-title")[0].childNodes[0].nodeValue);*/
    document.write("</tr>");
   
}
document.write("</table>");
</script>
</body>
</html>


Žádné komentáře:

Okomentovat