Stream Recorder: Unterschied zwischen den Versionen
Version vom 9. Juni 2017, 21:51 Uhr ⧼parentheses⧽ TuxNix⧼word-separator⧽⧼parentheses⧽ ⧼parentheses⧽ |
Version vom 18. Juli 2017, 23:50 Uhr ⧼parentheses⧽ TuxNix⧼word-separator⧽⧼parentheses⧽ |
||
Zeile 15: | Zeile 15: | ||
<p>Das Script <code>(streamrecoder)</code> wird hier als "Applikation" angegeben.</p> | <p>Das Script <code>(streamrecoder)</code> wird hier als "Applikation" 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} | + | <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}" |
+ | </p> | ||
<p><u>Parameter für das Löschen:</u><br> | <p><u>Parameter für das Löschen:</u><br> | ||
<code>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}</code></p> | <code>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}</code></p> | ||
Zeile 39: | Zeile 40: | ||
===Scriptversionen=== | ===Scriptversionen=== | ||
− | Version 0.2: Paralelle Aufnahmen, Version 0.3: Titelkorrektur, Version 0.4: Aufnahmen laufender Sendungen. | + | Version 0.2: Paralelle Aufnahmen, Version 0.3: Titelkorrektur, Version 0.4: Aufnahmen laufender Sendungen, Version 0.5 Serien mit Angabe der Episode. |
Viel Spaß damit | Viel Spaß damit | ||
Zeile 48: | Zeile 49: | ||
#!/bin/bash | #!/bin/bash | ||
− | ##### Programm: streamrecorder Version 0. | + | ##### Programm: streamrecorder Version 0.5 - Juli 2017 |
##### From TuxNix Lizenz GPLv3 with no garanty at all. | ##### From TuxNix Lizenz GPLv3 with no garanty at all. | ||
Zeile 54: | Zeile 55: | ||
##### Parameter für Tv-Browser: Aufnahme | ##### 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}" | + | #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 | ##### 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}" | + | #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} |
##### benötigt die Programm-Pakete | ##### benötigt die Programm-Pakete | ||
Zeile 110: | Zeile 111: | ||
eMonat=${args[9]} | eMonat=${args[9]} | ||
− | if (( ${# | + | if (( ${#args[9]} < 2 )) ; then |
− | eMonat="0"$ | + | eMonat="0"${args[9]} |
fi | fi | ||
Zeile 121: | Zeile 122: | ||
Kanal=${args[11]} | Kanal=${args[11]} | ||
− | sTitel= | + | sTitel=${args[12]} |
− | |||
− | |||
− | |||
− | |||
if (( ${#args[13]} > 3 )) ; then | if (( ${#args[13]} > 3 )) ; then | ||
Zeile 131: | Zeile 128: | ||
fi | fi | ||
− | sName=$sTitel$sProdJahr | + | if (( ${#args[14]} > 0 )) ; then |
− | echo $sName | + | sEpisodenNr="-${args[14]}" |
+ | fi | ||
+ | |||
+ | if (( ${#args[15]} > 0 )) ; then | ||
+ | sEpisode="-${args[15]}" | ||
+ | fi | ||
+ | |||
+ | sName="$sTitel$sProdJahr$sEpisodenNr$sEpisode" | ||
+ | |||
+ | sName=`echo $sName | sed 's/ /_/g'` | ||
+ | sName=`echo $sName | sed 's!/!-!g'` | ||
+ | sName=`echo $sName | sed 's![()"]!!g'` | ||
+ | sName=`echo $sName | sed "s!\x27!!g"` | ||
+ | sName=`echo $sName | sed "s!&!u!g"` | ||
+ | |||
if [ $Kanal == 'ARD' ] ; then | if [ $Kanal == 'ARD' ] ; then | ||
Zeile 205: | Zeile 216: | ||
startZeit=$sStunde:$sMinute' '$sJahr-$sMonat-$sTag | startZeit=$sStunde:$sMinute' '$sJahr-$sMonat-$sTag | ||
endZeit=$eStunde:$eMinute' '$eJahr-$eMonat-$eTag | endZeit=$eStunde:$eMinute' '$eJahr-$eMonat-$eTag | ||
+ | |||
if [ $operation == 'record' ] && (( $sysTime > $startTime )) ; then | if [ $operation == 'record' ] && (( $sysTime > $startTime )) ; then | ||
+ | echo "$startNow $sTitel" | ||
echo "" | echo "" | ||
− | echo "Die Aufnahme | + | echo "Die Aufnahme wurde soeben gestartet und nach" |
− | echo $recPath$sName-part".mp4 | + | echo $recPath$sName-part".mp4 abgespeichert." |
echo "mencoder $stream_url -vid 9 -oac pcm -ovc copy -o $recPath$sName-part.mp4" | at $startNow > /dev/null 2>&1 | echo "mencoder $stream_url -vid 9 -oac pcm -ovc copy -o $recPath$sName-part.mp4" | at $startNow > /dev/null 2>&1 | ||
echo "fuser -k -TERM $recPath$sName-part.mp4" | at $endZeit > /dev/null 2>&1 | echo "fuser -k -TERM $recPath$sName-part.mp4" | at $endZeit > /dev/null 2>&1 | ||
Zeile 216: | Zeile 229: | ||
elif [ $operation == 'record' ] && (( $sysTime <= $startTime )) ; then | elif [ $operation == 'record' ] && (( $sysTime <= $startTime )) ; then | ||
+ | echo "$startZeit $sTitel" | ||
echo "" | echo "" | ||
echo "Die Aufnahme wurde veranlasst und wird nach" | echo "Die Aufnahme wurde veranlasst und wird nach" | ||
− | echo $recPath$sName".mp4 | + | echo $recPath$sName".mp4 gespeichert werden." |
− | |||
echo "mencoder $stream_url -vid 9 -oac pcm -ovc copy -o $recPath$sName.mp4" | at $startZeit > /dev/null 2>&1 | echo "mencoder $stream_url -vid 9 -oac pcm -ovc copy -o $recPath$sName.mp4" | at $startZeit > /dev/null 2>&1 | ||
echo "fuser -k -TERM $recPath$sName.mp4" | at $endZeit > /dev/null 2>&1 | echo "fuser -k -TERM $recPath$sName.mp4" | at $endZeit > /dev/null 2>&1 | ||
Zeile 241: | Zeile 254: | ||
fuser -k -TERM $recPath$sName.mp4 > /dev/null 2>&1 | fuser -k -TERM $recPath$sName.mp4 > /dev/null 2>&1 | ||
fuser -k -TERM $recPath$sName-part.mp4 > /dev/null 2>&1 | fuser -k -TERM $recPath$sName-part.mp4 > /dev/null 2>&1 | ||
− | echo "Die laufende Aufnahme wird beendet!" | + | echo "Die laufende Aufnahme von '$sTitel' wird beendet!" |
else | else | ||
Zeile 248: | Zeile 261: | ||
Job=`cut -f1 atq.txt` | Job=`cut -f1 atq.txt` | ||
atrm $Job | atrm $Job | ||
− | echo "Der at Start-Job $Job | + | echo "Der at Start-Job $Job wird gelöscht!" |
fi | fi | ||
Zeile 255: | Zeile 268: | ||
Job=`cut -f1 atq.txt` | Job=`cut -f1 atq.txt` | ||
atrm $Job | atrm $Job | ||
− | echo "Der at Stop-Job $Job | + | echo "Der at Stop-Job $Job wird gelöscht!" |
else | else |
Version vom 18. Juli 2017, 23:50 Uhr
Stream Recorder ist ein Script zur zeitgesteuerten Aufnahme von TV Livestreams aus dem TV-Browser heraus.
Inhaltsverzeichnis
Vorraussetzungen
- Internetanschluß
- Linux Pc
- at (Paket)
- mencoder (Paket)
Installation
Benötigt werden die 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.
Danach das Script kopieren und z.B. mit dem Namen (streamrecoder)
abspeichern. Mit (chmod a+rx streamrecorder)
wird das Script ausführbar gemacht.
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.
Das Script (streamrecoder)
wird hier als "Applikation" 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}"
</p>
<p>Parameter für das Löschen:
<code>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}
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 Juni 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. 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 eigentlich 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 hätten sich nicht so gut für diesen Zweck 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. Für das eigentliche Streaming ist mencoder verantwortlich.
Scriptversionen
Version 0.2: Paralelle Aufnahmen, Version 0.3: Titelkorrektur, Version 0.4: Aufnahmen laufender Sendungen, Version 0.5 Serien mit Angabe der Episode.
Viel Spaß damit TuxNix
Das Script
#!/bin/bash ##### Programm: streamrecorder Version 0.5 - Juli 2017 ##### From TuxNix Lizenz GPLv3 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} ##### benötigt die Programm-Pakete #at #mencoder ##### 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]} sTitel=${args[12]} if (( ${#args[13]} > 3 )) ; then sProdJahr="-${args[13]}" fi if (( ${#args[14]} > 0 )) ; then sEpisodenNr="-${args[14]}" fi if (( ${#args[15]} > 0 )) ; then sEpisode="-${args[15]}" fi sName="$sTitel$sProdJahr$sEpisodenNr$sEpisode" sName=`echo $sName | sed 's/ /_/g'` sName=`echo $sName | sed 's!/!-!g'` sName=`echo $sName | sed 's![()"]!!g'` sName=`echo $sName | sed "s!\x27!!g"` sName=`echo $sName | sed "s!&!u!g"` if [ $Kanal == 'ARD' ] ; then stream_url='http://daserste_live-lh.akamaihd.net/i/daserste_de@91204/master.m3u8' elif [ $Kanal == '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 == 'Tagesschau' ] ; 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 == 'BR' ] ; then stream_url="http://livestreams.br.de/i/bfsnord_germany@119898/master.m3u8" elif [ $Kanal == 'DW' ] ; 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" elif [ $Kanal == 'mdr' ] ; then stream_url="http://mdr_th_hls-lh.akamaihd.net/i/livetvmdrthueringen_de@106903/master.m3u8" elif [ $Kanal == 'NDR' ] ; 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" elif [ $Kanal == 'rbb' ] ; 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 == 'SR' ] ; 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" elif [ $Kanal == 'WDR' ] ; then stream_url="http://wdr_fs_geo-lh.akamaihd.net/i/wdrfs_geogeblockt@112044/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 noch nicht gelistet" echo "Bitte Sendernamen auch im TV-Browser ohne Leerzeichen eintragen" exit 1 fi sysTime=`date --date='now' +%s` startTime=`date --date="$sJahr-$sMonat-$sTag $sStunde:$sMinute" +%s` startNow=`date --date='now' +%R' '%F` startZeit=$sStunde:$sMinute' '$sJahr-$sMonat-$sTag endZeit=$eStunde:$eMinute' '$eJahr-$eMonat-$eTag if [ $operation == 'record' ] && (( $sysTime > $startTime )) ; then echo "$startNow $sTitel" echo "" echo "Die Aufnahme wurde soeben gestartet und nach" echo $recPath$sName-part".mp4 abgespeichert." echo "mencoder $stream_url -vid 9 -oac pcm -ovc copy -o $recPath$sName-part.mp4" | at $startNow > /dev/null 2>&1 echo "fuser -k -TERM $recPath$sName-part.mp4" | at $endZeit > /dev/null 2>&1 elif [ $operation == 'record' ] && (( $sysTime <= $startTime )) ; then echo "$startZeit $sTitel" echo "" echo "Die Aufnahme wurde veranlasst und wird nach" echo $recPath$sName".mp4 gespeichert werden." echo "mencoder $stream_url -vid 9 -oac pcm -ovc copy -o $recPath$sName.mp4" | at $startZeit > /dev/null 2>&1 echo "fuser -k -TERM $recPath$sName.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) sTag=${args[5]} if (( ${#sTag} < 2 )) ; then sTag=" "$sTag fi eTag=${args[10]} if (( ${#eTag} < 2 )) ; then eTag=" "$eTag fi if (( $sysTime >= $startTime )) ; then fuser -k -TERM $recPath$sName.mp4 > /dev/null 2>&1 fuser -k -TERM $recPath$sName-part.mp4 > /dev/null 2>&1 echo "Die laufende Aufnahme von '$sTitel' wird beendet!" else atq | grep "${Monate[${args[4]}]} $sTag $sStunde:$sMinute:00 $sJahr" > atq.txt Job=`cut -f1 atq.txt` atrm $Job echo "Der at Start-Job $Job wird gelöscht!" fi atq | grep "${Monate[${args[9]}]} $eTag $eStunde:$eMinute:00 $eJahr" > atq.txt Job=`cut -f1 atq.txt` atrm $Job echo "Der at Stop-Job $Job wird gelöscht!" else echo "Abbruch: Der Operator $operation ist nicht korrekt. Bitte überprüfe die Parameter im TV-Browser" exit 2 fi
Anregungen und Verbesserungsvorschläge zum Script können im Forum ausgetauscht werden.