Stream Recorder: Unterschied zwischen den Versionen

Aus TV-Browser Wiki
Wechseln zu: Navigation⧼comma-separator⧽Suche
TuxNix⧼word-separator⧽⧼parentheses⧽
⧼parentheses⧽
TuxNix⧼word-separator⧽⧼parentheses⧽
⧼parentheses⧽
Zeile 1: Zeile 1:
Stream Recorder ist ein Script zur zeitgesteuerten Aufnahme von TV Livestreams aus dem TV-Browser heraus.
+
Stream Recorder ist ein Skript zur zeitgesteuerten Aufnahme von TV Livestreams aus dem TV-Browser heraus.
  
 
=== Vorraussetzungen ===
 
=== Vorraussetzungen ===
Zeile 9: Zeile 9:
  
 
=== Installation ===
 
=== Installation ===
<p>Benötigt werden die Pakete at und mencoder.</p>
+
====Das Skript====
 +
<p>Benötigt wird die Installation der Pakete at und mencoder.</p>
 
Der at Dienst wird von systemd gesteuert. Zur Aktivuerung gibt man auf der Konsole <code>(sudo systemctl enable --now atd.service)</code> ein.
 
Der at Dienst wird von systemd gesteuert. Zur Aktivuerung gibt man auf der Konsole <code>(sudo systemctl enable --now atd.service)</code> ein.
<p>Danach das Script kopieren und z.B. mit dem Namen <code>(streamrecoder)</code> abspeichern. Mit <code>(chmod a+rx streamrecorder)</code> wird das Script ausführbar gemacht.</p>
+
<p>Das Skript wird kopieren und z.B. mit dem Namen <code>(streamrecoder)</code> in einen Ordner mit Benutzerschreibrechten abgespeichert und mit <code>(chmod a+rx streamrecorder)</code> ausführbar gemacht.</p>
<p>Im Tv-Browser im Menu Extras > Aufnahmesteuerung > Geräte > Gerät-hinzufügen den Standardtreiber auswählen. Beim Eintrag Gerät kann ein beliebiger Namen angegeben werden.</p>
+
====Konfiguration des TV-Browsers====
<p>Das Script <code>(streamrecoder)</code> wird hier als "Applikation" angegeben.</p>
+
<p> Das Plugin Aufnahmesteuerung wird geladen.
 +
<p>Im Tv-Browser Menu Extras > Aufnahmesteuerung > Geräte > Gerät-hinzufügen den Standardtreiber auswählen. Beim Eintrag Gerät kann ein beliebiger Namen eingetragen werden.</p>
 +
<p>Als "Applikation" wird das Skript <code>(streamrecoder)</code> mit Pfad angegeben.</p>
 
<p><u>Parameter für die Aufnahme:</u><br>
 
<p><u>Parameter für die Aufnahme:</u><br>
 
<code>record {start_hour} {start_minute} {start_year} {start_month} {start_day} {end_hour} {end_minute} {end_year} {end_month} {end_day} {channel_name} "{title}" {production_year} {episode_number} "{episode}"</code></p>
 
<code>record {start_hour} {start_minute} {start_year} {start_month} {start_day} {end_hour} {end_minute} {end_year} {end_month} {end_day} {channel_name} "{title}" {production_year} {episode_number} "{episode}"</code></p>
Zeile 22: Zeile 25:
 
Auch wird die Aufnahme schon laufender Sendungen unterstützt.
 
Auch wird die Aufnahme schon laufender Sendungen unterstützt.
  
Die Sender URLs der öffentlich rechtlichen Sender sind im Script gelistet (Stand Juni 2017). Man kann beliebig viele Sender hinzufügen.
+
Die Sender URLs der öffentlich rechtlichen Sender sind im Script gelistet (Stand November 2017). Man kann beliebig viele Sender hinzufügen.
Die Namen der Sender sollte im TV-Browser und im Script miteinander übereinstimmen. Leerstellen im Sendernamen werden nicht unterstützt.
+
Die Namen der Sender sollten im TV-Browser und im Script miteinander übereinstimmen. Leerstellen im Sendernamen sollten im Skript mit Unterstrich eingetragen werden.
Der Speicherort der Aufnahme ist auf ~/Video vor eingestellt und kann Im Script in der Benutzer Konfiguration auf eigene Bedürfnisse angepasst werden.
+
Der Speicherort der Aufnahme ist auf ~/Video vor eingestellt und kann im Script in der Benutzer Konfiguration auf eigene Bedürfnisse angepasst werden.
 
Es kann sein, dass sich gelegentlich die URL eines Livestreams ändert. Eine gute Quelle für aktuelle Livestream URLs bietet das Programm Medithek-View.
 
Es kann sein, dass sich gelegentlich die URL eines Livestreams ändert. Eine gute Quelle für aktuelle Livestream URLs bietet das Programm Medithek-View.
  
 
=== Benutzung ===
 
=== Benutzung ===
Die Benutzung ist eigentlich selbsterklärend.
+
Die Benutzung ist im Grunde selbsterklärend.
 
Mit der rechten Maustaste wählt man eine Sendung aus. Mit der Linken Maustaste wird auf Aufnahme gedrückt.
 
Mit der rechten Maustaste wählt man eine Sendung aus. Mit der Linken Maustaste wird auf Aufnahme gedrückt.
 
Zum Rückgängig machen der Aufnahmejobs geht man entsprechend vor.
 
Zum Rückgängig machen der Aufnahmejobs geht man entsprechend vor.
Zeile 34: Zeile 37:
  
 
=== Hintergrund ===
 
=== Hintergrund ===
Zur Zeitsteuerung habe ich at ausgewählt. Cronie und systemd.timers hätten sich nicht so gut für diesen Zweck geeignet.
+
Zur Zeitsteuerung habe ich at ausgewählt. Cronie und systemd.timers sind besser für wiederkehrende Ereignisse geeignet.
Wer wissen möchte wie die Jobs gespeichert werden, kann auf der Konsole die Befehle atq, at -c <job> und atrm <job> mal ausprobieren.
+
Wer wissen möchte wie die at-Jobs gespeichert werden, kann auf der Konsole die Befehle atq, at -c <job> und atrm <job> mal ausprobieren.
Für das eigentliche Streaming ist mencoder verantwortlich.
+
Für das eigentliche streaming ist mencoder verantwortlich.
  
 
===Scriptversionen===
 
===Scriptversionen===
 
Folgende Funktionen wurden bei den Versionen hinzugefügt:
 
Folgende Funktionen wurden bei den Versionen hinzugefügt:
Version 0.2: Paralelle Aufnahmen, Version 0.3: Titelkorrektur, Version 0.4: Aufnahmen laufender Sendungen, Version 0.5 Serien mit Angabe der Episode. 1.0 Bugfixes
+
Version 0.2: Paralelle Aufnahmen, Version 0.3: Titelkorrektur, Version 0.4: Aufnahmen laufender Sendungen, Version 0.5 Serien mit Angabe der Episode. 1.0 Bugfixes, 1.1 Leerstellen beim Sendernamen, Aktualisierung der Sender URLs.
  
 
Viel Spaß damit
 
Viel Spaß damit
Zeile 49: Zeile 52:
 
#!/bin/bash
 
#!/bin/bash
  
##### Programm: streamrecorder Version 1.0 - Aug. 2017
+
##### Programm: streamrecorder Version 1.1 - 19.Nov. 2017
  
##### From TuxNix Lizenz GPLv3 with no garanty at all.
+
##### From TuxNix Lizenz GPLv2 with no garanty at all.
  
  
Zeile 63: Zeile 66:
 
#at
 
#at
 
#mencoder
 
#mencoder
 +
 +
# Der at service muss mit dem Befehl: 'sudo systemctl enable --now atd.service' aktiviert werden.
  
  
Zeile 68: Zeile 73:
  
 
recPath=~/Videos/
 
recPath=~/Videos/
 
  
 
##### Das Script
 
##### Das Script
Zeile 120: Zeile 124:
 
fi
 
fi
  
Kanal=${args[11]}
+
Kanal="${args[11]}"
 +
Kanal=`echo $Kanal | sed 's/ /_/g'`
 +
Kanal=`echo $Kanal | sed 's!"!!g'`
  
 
Titel=${args[12]}
 
Titel=${args[12]}
Zeile 137: Zeile 143:
  
 
Name="$Titel$ProdJahr$EpisodenNr$Episode"
 
Name="$Titel$ProdJahr$EpisodenNr$Episode"
 
 
Name=`echo $Name | sed 's/ /_/g'`
 
Name=`echo $Name | sed 's/ /_/g'`
 
Name=`echo $Name | sed 's!/!-!g'`
 
Name=`echo $Name | sed 's!/!-!g'`
Zeile 145: Zeile 150:
  
  
if [ $Kanal == 'ARD' ] ; then
+
if [ $Kanal == 'Das_Erste_(ARD)' ] ; then
 
     stream_url='http://daserste_live-lh.akamaihd.net/i/daserste_de@91204/master.m3u8'
 
     stream_url='http://daserste_live-lh.akamaihd.net/i/daserste_de@91204/master.m3u8'
  
elif [ $Kanal == 'alpha' ] ; then
+
elif [ $Kanal == 'ARD-alpha' ] ; then
 
     stream_url="http://livestreams.br.de/i/bralpha_germany@119899/master.m3u8"
 
     stream_url="http://livestreams.br.de/i/bralpha_germany@119899/master.m3u8"
  
elif [ $Kanal == 'one' ] ; then
+
elif [ $Kanal == 'One' ] ; then
 
     stream_url="http://wdr_einsfestival-lh.akamaihd.net/i/wdr_einsfestival@328300/master.m3u8"
 
     stream_url="http://wdr_einsfestival-lh.akamaihd.net/i/wdr_einsfestival@328300/master.m3u8"
  
elif [ $Kanal == 'Tagesschau' ] ; then
+
elif [ $Kanal == 'tagesschau24' ] ; then
 
     stream_url="http://tagesschau-lh.akamaihd.net/i/tagesschau_1@119231/master.m3u8"
 
     stream_url="http://tagesschau-lh.akamaihd.net/i/tagesschau_1@119231/master.m3u8"
  
elif [ $Kanal == 'Arte' ] ; then
+
elif [ $Kanal == 'arte' ] ; then
 
     stream_url="http://artelive-lh.akamaihd.net/i/artelive_de@393591/master.m3u8"
 
     stream_url="http://artelive-lh.akamaihd.net/i/artelive_de@393591/master.m3u8"
 +
 +
elif [ $Kanal == 'ARTE_(francais)' ] ; then
 +
    stream_url="http://artelive-lh.akamaihd.net/i/artelive_fr@344805/master.m3u8"
  
 
elif [ $Kanal == 'BR' ] ; then
 
elif [ $Kanal == 'BR' ] ; then
 
     stream_url="http://livestreams.br.de/i/bfsnord_germany@119898/master.m3u8"
 
     stream_url="http://livestreams.br.de/i/bfsnord_germany@119898/master.m3u8"
  
elif [ $Kanal == 'DW' ] ; then
+
elif [ $Kanal == 'KiKA' ] ; then
    stream_url="http://dwstream72-lh.akamaihd.net/i/dwstream72_live@123556/master.m3u8"
 
 
 
elif [ $Kanal == 'hr' ] ; then
 
    stream_url="http://live1_hr-lh.akamaihd.net/i/hr_fernsehen@75910/master.m3u8"
 
 
 
elif [ $Kanal == 'Kika' ] ; then
 
 
     stream_url="http://kika_geo-lh.akamaihd.net/i/livetvkika_de@75114/master.m3u8"
 
     stream_url="http://kika_geo-lh.akamaihd.net/i/livetvkika_de@75114/master.m3u8"
  
elif [ $Kanal == 'mdr' ] ; then
+
elif [ $Kanal == 'NDR_Niedersachsen' ] ; then
     stream_url="http://mdr_th_hls-lh.akamaihd.net/i/livetvmdrthueringen_de@106903/master.m3u8"
+
     stream_url="http://ndrfs-lh.akamaihd.net/i/ndrfs_nds@430233/master.m3u8"
  
elif [ $Kanal == 'NDR' ] ; then
+
elif [ $Kanal == 'PHOENIX' ] ; then
    stream_url="http://ndr_fs-lh.akamaihd.net/i/ndrfs_nds@119224/master.m3u8"
 
 
 
elif [ $Kanal == 'phoenix' ] ; then
 
 
     stream_url="http://zdf0910-lh.akamaihd.net/i/de09_v1@392871/master.m3u8"
 
     stream_url="http://zdf0910-lh.akamaihd.net/i/de09_v1@392871/master.m3u8"
  
elif [ $Kanal == 'rbb' ] ; then
+
elif [ $Kanal == 'RBB_Brandenburg' ] ; then
 
     stream_url="http://rbblive-lh.akamaihd.net/i/rbb_brandenburg@349369/master.m3u8"
 
     stream_url="http://rbblive-lh.akamaihd.net/i/rbb_brandenburg@349369/master.m3u8"
  
Zeile 187: Zeile 186:
 
     stream_url="http://zdf0910-lh.akamaihd.net/i/dach10_v1@392872/master.m3u8"
 
     stream_url="http://zdf0910-lh.akamaihd.net/i/dach10_v1@392872/master.m3u8"
  
elif [ $Kanal == 'SR' ] ; then
+
elif [ $Kanal == 'SWR_BW' ] ; then
    stream_url="http://live2_sr-lh.akamaihd.net/i/sr_universal02@107595/master.m3u8"
 
 
 
elif [ $Kanal == 'SWR' ] ; then
 
 
     stream_url="http://swrbw-lh.akamaihd.net/i/swrbw_live@196738/master.m3u8"
 
     stream_url="http://swrbw-lh.akamaihd.net/i/swrbw_live@196738/master.m3u8"
  
 
elif [ $Kanal == 'WDR' ] ; then
 
elif [ $Kanal == 'WDR' ] ; then
     stream_url="http://wdr_fs_geo-lh.akamaihd.net/i/wdrfs_geogeblockt@112044/master.m3u8"
+
     stream_url="http://wdrfsgeo-lh.akamaihd.net/i/wdrfs_geogeblockt@530016/master.m3u8"
         
+
         
 
elif [ $Kanal == 'ZDF' ] ; then
 
elif [ $Kanal == 'ZDF' ] ; then
 
     stream_url="http://zdf1314-lh.akamaihd.net/i/de14_v1@392878/master.m3u8"
 
     stream_url="http://zdf1314-lh.akamaihd.net/i/de14_v1@392878/master.m3u8"
Zeile 206: Zeile 202:
 
    
 
    
 
else
 
else
     echo "Abbruch: Der Sender $Kanal ist im Aufnahmeskript noch nicht gelistet"
+
     echo "Abbruch: Der Sender '$Kanal' ist im Aufnahmeskript nicht gelistet"
     echo "Bitte Sendernamen auch im TV-Browser ohne Leerzeichen eintragen"
+
     echo "Bitte Groß und Kleinschreibung beachten"
 +
    echo "Die Namen der Sender die im TV-Browser ein Leerzeichen haben, müssen im Skript mit Unterstrich eintragen werden"
 +
    echo "Umlaute werden nicht unterstützt"
 
     exit 1
 
     exit 1
 
fi
 
fi
Zeile 214: Zeile 212:
 
startTime=`date --date="$sJahr-$sMonat-$sTag $sStunde:$sMinute" +%s`
 
startTime=`date --date="$sJahr-$sMonat-$sTag $sStunde:$sMinute" +%s`
 
startNow=`date --date='now' +%R' '%F`
 
startNow=`date --date='now' +%R' '%F`
 +
stopNow=`date --date="1 minute" +%R' '%F`
 
startZeit=$sStunde:$sMinute' '$sJahr-$sMonat-$sTag
 
startZeit=$sStunde:$sMinute' '$sJahr-$sMonat-$sTag
 
endZeit=$eStunde:$eMinute' '$eJahr-$eMonat-$eTag
 
endZeit=$eStunde:$eMinute' '$eJahr-$eMonat-$eTag
Zeile 220: Zeile 219:
 
if [ $operation == 'record' ] && (( $sysTime > $startTime )) ; then
 
if [ $operation == 'record' ] && (( $sysTime > $startTime )) ; then
  
     echo "$Kanal $startNow bis $endZeit: $Titel"
+
     echo "`date --date='now' +%R` - $eStunde:$eMinute Uhr $eTag.$eMonat.$eJahr: $Titel"
 
     echo ""
 
     echo ""
     echo "Die Aufnahme wurde soeben gestartet und wird nach"
+
     echo "Die Aufnahme wurde gestartet und wird nach"
 
     echo $recPath$Name"-part.mp4 gespeichert."
 
     echo $recPath$Name"-part.mp4 gespeichert."
 
     echo "mencoder $stream_url -vid 9 -oac pcm -ovc copy -o $recPath$Name-part.mp4" | at $startNow > /dev/null 2>&1
 
     echo "mencoder $stream_url -vid 9 -oac pcm -ovc copy -o $recPath$Name-part.mp4" | at $startNow > /dev/null 2>&1
 
     echo "fuser -k -TERM $recPath$Name-part.mp4" | at $endZeit > /dev/null 2>&1
 
     echo "fuser -k -TERM $recPath$Name-part.mp4" | at $endZeit > /dev/null 2>&1
     
+
     
 
elif [ $operation == 'record' ] && (( $sysTime <= $startTime )) ; then
 
elif [ $operation == 'record' ] && (( $sysTime <= $startTime )) ; then
  
     echo "$Kanal $startZeit bis $endZeit: $Titel"
+
     echo "$sStunde:$sMinute - $eStunde:$eMinute Uhr $eTag.$eMonat.$eJahr: $Titel"
 
     echo ""
 
     echo ""
 
     echo "Die Aufnahme wird veranlasst und nach"
 
     echo "Die Aufnahme wird veranlasst und nach"
Zeile 235: Zeile 234:
 
     echo "mencoder $stream_url -vid 9 -oac pcm -ovc copy -o $recPath$Name.mp4" | at $startZeit > /dev/null 2>&1
 
     echo "mencoder $stream_url -vid 9 -oac pcm -ovc copy -o $recPath$Name.mp4" | at $startZeit > /dev/null 2>&1
 
     echo "fuser -k -TERM $recPath$Name.mp4" | at $endZeit > /dev/null 2>&1
 
     echo "fuser -k -TERM $recPath$Name.mp4" | at $endZeit > /dev/null 2>&1
 
+
 
 
elif [ $operation == 'delete' ] ; then
 
elif [ $operation == 'delete' ] ; then
  
 
     Monate=([1]=Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)
 
     Monate=([1]=Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)
 
+
 
 
     if (( $sysTime >= $startTime )) ; then
 
     if (( $sysTime >= $startTime )) ; then
 +
   
 +
        echo "fuser -k -TERM $recPath$Name.mp4" | at $stopNow > /dev/null 2>&1
 +
        echo "fuser -k -TERM $recPath$Name-part.mp4" | at $stopNow > /dev/null 2>&1
 +
        echo "Die laufende Aufnahme von '$Titel' wird beendet!"
 
        
 
        
        fuser -k -TERM $recPath$Name.mp4 > /dev/null 2>&1
 
        fuser -k -TERM $recPath$Name-part.mp4 > /dev/null 2>&1
 
        echo "Die laufende Aufnahme von '$Titel' wird beendet!"
 
     
 
 
     else
 
     else
 
+
 
 
         sTag=${args[5]}
 
         sTag=${args[5]}
 
         if (( ${#sTag} < 2 )) ; then
 
         if (( ${#sTag} < 2 )) ; then
 
             sTag=" "$sTag
 
             sTag=" "$sTag
 
         fi
 
         fi
       
+
     
 
         atq | grep "${Monate[${args[4]}]} $sTag $sStunde:$sMinute:00 $sJahr" > atq.txt
 
         atq | grep "${Monate[${args[4]}]} $sTag $sStunde:$sMinute:00 $sJahr" > atq.txt
 
         Jobs=`cut -f1 atq.txt`
 
         Jobs=`cut -f1 atq.txt`
Zeile 258: Zeile 257:
 
             if at -c $Job | grep $Name > /dev/null 2>&1 ; then
 
             if at -c $Job | grep $Name > /dev/null 2>&1 ; then
 
               atrm $Job
 
               atrm $Job
               echo "Der at Start-Job $Job wurde gelöscht!"
+
               echo "Der at Start-Job $Job wurde geloescht!"
 
             fi
 
             fi
 
         done
 
         done
 
     fi
 
     fi
 
+
 
 
         eTag=${args[10]}
 
         eTag=${args[10]}
 
         if (( ${#eTag} < 2 )) ; then
 
         if (( ${#eTag} < 2 )) ; then
 
             eTag=" "$eTag
 
             eTag=" "$eTag
 
         fi
 
         fi
 
+
 
 
         atq | grep "${Monate[${args[9]}]} $eTag $eStunde:$eMinute:00 $eJahr" > atq.txt
 
         atq | grep "${Monate[${args[9]}]} $eTag $eStunde:$eMinute:00 $eJahr" > atq.txt
 
         Jobs=`cut -f1 atq.txt`
 
         Jobs=`cut -f1 atq.txt`
Zeile 273: Zeile 272:
 
             if at -c $Job | grep $Name > /dev/null 2>&1 ; then
 
             if at -c $Job | grep $Name > /dev/null 2>&1 ; then
 
                 atrm $Job
 
                 atrm $Job
                 echo "Der at Stop-Job $Job wurde gelöscht!"
+
                 echo "Der at Stop-Job $Job wurde geloescht!"
 
             fi
 
             fi
 
         done
 
         done
 
+
 
 
else
 
else
  
     echo "Abbruch: Der Operator $operation ist nicht korrekt. Bitte überprüfe die Parameter im TV-Browser"
+
     echo "Abbruch: Der Operator $operation ist nicht korrekt. Bitte überprüfe die Parameter im TV-Browser Aufnahme Plugin"
 
     exit 2
 
     exit 2
 
fi
 
fi

Version vom 19. November 2017, 22:47 Uhr

Stream Recorder ist ein Skript zur zeitgesteuerten Aufnahme von TV Livestreams aus dem TV-Browser heraus.

Vorraussetzungen

  • Internetanschluß
  • Linux Pc
  • at (Paket)
  • mencoder (Paket)

Installation

Das Skript

Benötigt wird die Installation der Pakete at und mencoder.

Der at Dienst wird von systemd gesteuert. Zur Aktivuerung gibt man auf der Konsole (sudo systemctl enable --now atd.service) ein.

Das Skript wird kopieren und z.B. mit dem Namen (streamrecoder) in einen Ordner mit Benutzerschreibrechten abgespeichert und mit (chmod a+rx streamrecorder) ausführbar gemacht.

Konfiguration des TV-Browsers

Das Plugin Aufnahmesteuerung wird geladen. <p>Im Tv-Browser Menu Extras > Aufnahmesteuerung > Geräte > Gerät-hinzufügen den Standardtreiber auswählen. Beim Eintrag Gerät kann ein beliebiger Namen eingetragen werden.

Als "Applikation" wird das Skript (streamrecoder) mit Pfad angegeben.

Parameter für die Aufnahme:
record {start_hour} {start_minute} {start_year} {start_month} {start_day} {end_hour} {end_minute} {end_year} {end_month} {end_day} {channel_name} "{title}" {production_year} {episode_number} "{episode}"

Parameter für das Löschen:
delete {start_hour} {start_minute} {start_year} {start_month} {start_day} {end_hour} {end_minute} {end_year} {end_month} {end_day} {channel_name} "{title}" {production_year} {episode_number} "{episode}"

Bei den Einstellungen können mehere Aufnahme gleichzeitig erlaubt werden.
Auch wird die Aufnahme schon laufender Sendungen unterstützt.

Die Sender URLs der öffentlich rechtlichen Sender sind im Script gelistet (Stand November 2017). Man kann beliebig viele Sender hinzufügen. Die Namen der Sender sollten im TV-Browser und im Script miteinander übereinstimmen. Leerstellen im Sendernamen sollten im Skript mit Unterstrich eingetragen werden. Der Speicherort der Aufnahme ist auf ~/Video vor eingestellt und kann im Script in der Benutzer Konfiguration auf eigene Bedürfnisse angepasst werden. Es kann sein, dass sich gelegentlich die URL eines Livestreams ändert. Eine gute Quelle für aktuelle Livestream URLs bietet das Programm Medithek-View.

Benutzung

Die Benutzung ist im Grunde selbsterklärend. Mit der rechten Maustaste wählt man eine Sendung aus. Mit der Linken Maustaste wird auf Aufnahme gedrückt. Zum Rückgängig machen der Aufnahmejobs geht man entsprechend vor. Ein Dialogfenster von TV-Browser öffnet sich und gibt jeweils Auskunft über den Programmablauf.

Hintergrund

Zur Zeitsteuerung habe ich at ausgewählt. Cronie und systemd.timers sind besser für wiederkehrende Ereignisse geeignet. Wer wissen möchte wie die at-Jobs gespeichert werden, kann auf der Konsole die Befehle atq, at -c <job> und atrm <job> mal ausprobieren. Für das eigentliche streaming ist mencoder verantwortlich.

Scriptversionen

Folgende Funktionen wurden bei den Versionen hinzugefügt: Version 0.2: Paralelle Aufnahmen, Version 0.3: Titelkorrektur, Version 0.4: Aufnahmen laufender Sendungen, Version 0.5 Serien mit Angabe der Episode. 1.0 Bugfixes, 1.1 Leerstellen beim Sendernamen, Aktualisierung der Sender URLs.

Viel Spaß damit TuxNix

Das Script

#!/bin/bash

##### Programm: streamrecorder Version 1.1 - 19.Nov. 2017

##### From TuxNix Lizenz GPLv2 with no garanty at all.


##### Parameter für Tv-Browser: Aufnahme
#record {start_hour} {start_minute} {start_year} {start_month} {start_day} {end_hour} {end_minute} {end_year} {end_month} {end_day} {channel_name} "{title}" {production_year} {episode_number} "{episode}"

##### Parameter für Tv-Browser: Löschen
#delete {start_hour} {start_minute} {start_year} {start_month} {start_day} {end_hour} {end_minute} {end_year} {end_month} {end_day} {channel_name} "{title}" {production_year} {episode_number} "{episode}"

##### benötigt die Programm-Pakete
#at
#mencoder

# Der at service muss mit dem Befehl: 'sudo systemctl enable --now atd.service' aktiviert werden.


##### Benutzer Konfiguration

recPath=~/Videos/

##### Das Script

args=("$@")

operation=${args[0]}

sStunde=${args[1]}
if (( ${#sStunde} < 2 )) ; then
   sStunde="0"${args[1]}
fi

sMinute=${args[2]}
if (( ${#sMinute} < 2 )) ; then
   sMinute="0"$sMinute
fi

sJahr=${args[3]}

sMonat=${args[4]}
if (( ${#sMonat} < 2 )) ; then
   sMonat="0"$sMonat
fi

sTag=${args[5]}
if (( ${#sTag} < 2 )) ; then
   sTag="0"$sTag
fi

eStunde=${args[6]}
if (( ${#eStunde} < 2 )) ; then
   eStunde="0"$eStunde
fi

eMinute=${args[7]}
if (( ${#eMinute} < 2 )) ; then
   eMinute="0"$eMinute
fi

eJahr=${args[8]}

eMonat=${args[9]}
if (( ${#args[9]} < 2 )) ; then
   eMonat="0"${args[9]}
fi

eTag=${args[10]}
if (( ${#args[10]} < 2 )) ; then
   eTag="0"${args[10]}
fi

Kanal="${args[11]}"
Kanal=`echo $Kanal | sed 's/ /_/g'`
Kanal=`echo $Kanal | sed 's!"!!g'`

Titel=${args[12]}

if (( ${#args[13]} > 3 )) ; then
   ProdJahr="-${args[13]}"
fi

if (( ${#args[14]} > 2 )) ; then
    EpisodenNr="-${args[14]}"
fi

if (( ${#args[15]} > 0 )) ; then
    Episode="-${args[15]}"
fi

Name="$Titel$ProdJahr$EpisodenNr$Episode"
Name=`echo $Name | sed 's/ /_/g'`
Name=`echo $Name | sed 's!/!-!g'`
Name=`echo $Name | sed 's![()"]!!g'`
Name=`echo $Name | sed "s!\x27!!g"`
Name=`echo $Name | sed "s!&!u!g"`


if [ $Kanal == 'Das_Erste_(ARD)' ] ; then
    stream_url='http://daserste_live-lh.akamaihd.net/i/daserste_de@91204/master.m3u8'

elif [ $Kanal == 'ARD-alpha' ] ; then
    stream_url="http://livestreams.br.de/i/bralpha_germany@119899/master.m3u8"

elif [ $Kanal == 'One' ] ; then
    stream_url="http://wdr_einsfestival-lh.akamaihd.net/i/wdr_einsfestival@328300/master.m3u8"

elif [ $Kanal == 'tagesschau24' ] ; then
    stream_url="http://tagesschau-lh.akamaihd.net/i/tagesschau_1@119231/master.m3u8"

elif [ $Kanal == 'arte' ] ; then
    stream_url="http://artelive-lh.akamaihd.net/i/artelive_de@393591/master.m3u8"

elif [ $Kanal == 'ARTE_(francais)' ] ; then
    stream_url="http://artelive-lh.akamaihd.net/i/artelive_fr@344805/master.m3u8"

elif [ $Kanal == 'BR' ] ; then
    stream_url="http://livestreams.br.de/i/bfsnord_germany@119898/master.m3u8"

elif [ $Kanal == 'KiKA' ] ; then
    stream_url="http://kika_geo-lh.akamaihd.net/i/livetvkika_de@75114/master.m3u8"

elif [ $Kanal == 'NDR_Niedersachsen' ] ; then
    stream_url="http://ndrfs-lh.akamaihd.net/i/ndrfs_nds@430233/master.m3u8"

elif [ $Kanal == 'PHOENIX' ] ; then
    stream_url="http://zdf0910-lh.akamaihd.net/i/de09_v1@392871/master.m3u8"

elif [ $Kanal == 'RBB_Brandenburg' ] ; then
    stream_url="http://rbblive-lh.akamaihd.net/i/rbb_brandenburg@349369/master.m3u8"

elif [ $Kanal == '3sat' ] ; then
    stream_url="http://zdf0910-lh.akamaihd.net/i/dach10_v1@392872/master.m3u8"

elif [ $Kanal == 'SWR_BW' ] ; then
    stream_url="http://swrbw-lh.akamaihd.net/i/swrbw_live@196738/master.m3u8"

elif [ $Kanal == 'WDR' ] ; then
    stream_url="http://wdrfsgeo-lh.akamaihd.net/i/wdrfs_geogeblockt@530016/master.m3u8"
          
elif [ $Kanal == 'ZDF' ] ; then
    stream_url="http://zdf1314-lh.akamaihd.net/i/de14_v1@392878/master.m3u8"

elif [ $Kanal == 'ZDFinfo' ] ; then
    stream_url="http://zdf1112-lh.akamaihd.net/i/de12_v1@392882/master.m3u8"

elif [ $Kanal == 'ZDFneo' ] ; then
    stream_url="http://zdf1314-lh.akamaihd.net/i/de13_v1@392877/master.m3u8"
   
else
    echo "Abbruch: Der Sender '$Kanal' ist im Aufnahmeskript nicht gelistet"
    echo "Bitte Groß und Kleinschreibung beachten"
    echo "Die Namen der Sender die im TV-Browser ein Leerzeichen haben, müssen im Skript mit Unterstrich eintragen werden"
    echo "Umlaute werden nicht unterstützt"
    exit 1
fi

sysTime=`date --date='now' +%s`
startTime=`date --date="$sJahr-$sMonat-$sTag $sStunde:$sMinute" +%s`
startNow=`date --date='now' +%R' '%F`
stopNow=`date --date="1 minute" +%R' '%F`
startZeit=$sStunde:$sMinute' '$sJahr-$sMonat-$sTag
endZeit=$eStunde:$eMinute' '$eJahr-$eMonat-$eTag


if [ $operation == 'record' ] && (( $sysTime > $startTime )) ; then

    echo "`date --date='now' +%R` - $eStunde:$eMinute Uhr $eTag.$eMonat.$eJahr: $Titel"
    echo ""
    echo "Die Aufnahme wurde gestartet und wird nach"
    echo $recPath$Name"-part.mp4 gespeichert."
    echo "mencoder $stream_url -vid 9 -oac pcm -ovc copy -o $recPath$Name-part.mp4" | at $startNow > /dev/null 2>&1
    echo "fuser -k -TERM $recPath$Name-part.mp4" | at $endZeit > /dev/null 2>&1
      
elif [ $operation == 'record' ] && (( $sysTime <= $startTime )) ; then

    echo "$sStunde:$sMinute - $eStunde:$eMinute Uhr $eTag.$eMonat.$eJahr: $Titel"
    echo ""
    echo "Die Aufnahme wird veranlasst und nach"
    echo $recPath$Name".mp4 gespeichert."
    echo "mencoder $stream_url -vid 9 -oac pcm -ovc copy -o $recPath$Name.mp4" | at $startZeit > /dev/null 2>&1
    echo "fuser -k -TERM $recPath$Name.mp4" | at $endZeit > /dev/null 2>&1
  
elif [ $operation == 'delete' ] ; then

    Monate=([1]=Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)
  
    if (( $sysTime >= $startTime )) ; then
     
        echo "fuser -k -TERM $recPath$Name.mp4" | at $stopNow > /dev/null 2>&1
        echo "fuser -k -TERM $recPath$Name-part.mp4" | at $stopNow > /dev/null 2>&1
        echo "Die laufende Aufnahme von '$Titel' wird beendet!"
      
    else
  
        sTag=${args[5]}
        if (( ${#sTag} < 2 )) ; then
            sTag=" "$sTag
        fi
       
        atq | grep "${Monate[${args[4]}]} $sTag $sStunde:$sMinute:00 $sJahr" > atq.txt
        Jobs=`cut -f1 atq.txt`
        for Job in $Jobs ; do
            if at -c $Job | grep $Name > /dev/null 2>&1 ; then
               atrm $Job
               echo "Der at Start-Job $Job wurde geloescht!"
            fi
        done
    fi
  
        eTag=${args[10]}
        if (( ${#eTag} < 2 )) ; then
            eTag=" "$eTag
        fi
  
        atq | grep "${Monate[${args[9]}]} $eTag $eStunde:$eMinute:00 $eJahr" > atq.txt
        Jobs=`cut -f1 atq.txt`
        for Job in $Jobs ; do
             if at -c $Job | grep $Name > /dev/null 2>&1 ; then
                atrm $Job
                echo "Der at Stop-Job $Job wurde geloescht!"
             fi
        done
  
else

    echo "Abbruch: Der Operator $operation ist nicht korrekt. Bitte überprüfe die Parameter im TV-Browser Aufnahme Plugin"
    exit 2
fi

Anregungen und Verbesserungsvorschläge zum Script können im Forum ausgetauscht werden.