diff --git a/Build/app/etc/Konfiguration.txt b/Build/app/etc/Konfiguration.txt index 23c268f..ed35e32 100644 --- a/Build/app/etc/Konfiguration.txt +++ b/Build/app/etc/Konfiguration.txt @@ -51,6 +51,7 @@ dsmtextnotify="on" MessageTo="admin" dsmbeepnotify="on" LOGlevel="1" +LOGmax="" reindex=1 #-------------------------------------------------------------------- diff --git a/Build/edit.sh b/Build/edit.sh index a16c176..94ec043 100644 --- a/Build/edit.sh +++ b/Build/edit.sh @@ -28,7 +28,9 @@ if [[ "$page" == "edit-save" ]]; then "$set_var" "$dir/app/etc/Konfiguration.txt" "dsmtextnotify" "$dsmtextnotify" "$set_var" "$dir/app/etc/Konfiguration.txt" "MessageTo" "$MessageTo" "$set_var" "$dir/app/etc/Konfiguration.txt" "dsmbeepnotify" "$dsmbeepnotify" + "$set_var" "$dir/app/etc/Konfiguration.txt" "PBTOKEN" "$PBTOKEN" "$set_var" "$dir/app/etc/Konfiguration.txt" "LOGlevel" "$LOGlevel" + "$set_var" "$dir/app/etc/Konfiguration.txt" "LOGmax" "$LOGmax" "$set_var" "$dir/app/etc/Konfiguration.txt" "endgueltigloeschen" "$endgueltigloeschen" "$set_var" "$dir/app/etc/Konfiguration.txt" "reindex" "$reindex" "$set_var" "$dir/app/etc/Konfiguration.txt" "cutlistat_ID" "$cutlistat_ID" @@ -86,7 +88,9 @@ if [[ "$page" == "edit-import-query" ]] || [[ "$page" == "edit-import" ]]; then "$set_var" "$dir/app/etc/Konfiguration.txt" "dsmtextnotify" "$dsmtextnotify" "$set_var" "$dir/app/etc/Konfiguration.txt" "MessageTo" "$MessageTo" "$set_var" "$dir/app/etc/Konfiguration.txt" "dsmbeepnotify" "$dsmbeepnotify" + "$set_var" "$dir/app/etc/Konfiguration.txt" "PBTOKEN" "$PBTOKEN" "$set_var" "$dir/app/etc/Konfiguration.txt" "LOGlevel" "$LOGlevel" + "$set_var" "$dir/app/etc/Konfiguration.txt" "LOGmax" "$LOGmax" "$set_var" "$dir/app/etc/Konfiguration.txt" "endgueltigloeschen" "$endgueltigloeschen" "$set_var" "$dir/app/etc/Konfiguration.txt" "reindex" "$reindex" "$set_var" "$dir/app/etc/Konfiguration.txt" "cutlistat_ID" "$cutlistat_ID" @@ -607,14 +611,14 @@ if [[ "$page" == "edit" ]]; then

' - # -> Abschnitt .avi's in native MP4's (MAC OS tauglich) umwandeln + # -> Abschnitt .avi's in native MP4's umwandeln echo '


- AVI-Filme in native MP4-Filme (macOS tauglich) umwandeln + AVI-Filme in native MP4-Filme umwandeln

' @@ -743,6 +747,22 @@ if [[ "$page" == "edit" ]]; then
Auf diese Art kann man sich in Verbindung mit dem Paket "Notification Forwarder" über synOTR-Ereignisse z.B. über einen Pushdienst benachrichtigen lassen.
Bleibt der Wert leer, so wird die Gruppe "administrators" benachrichtigt.

' + # PushBullet-Token + echo ' +

+ ' + if [ -n "$PBTOKEN" ]; then + echo '' + else + echo '' + fi + echo ' + + + Dein persönlicher PushBullet-Token. +
Benachrichtigungen werden an den entsprechenden Account gesendet. +
Bei Nichtgebrauch leer lassen. +

' # dsmbeepnotify echo '

@@ -792,6 +812,22 @@ if [[ "$page" == "edit" ]]; then 0 => es wird keine Log-Datei erstellt
1 => normales Log (standard)
2 => erweitertes Log
Die Logs befinden sich im Dekodierverzeichnis/_LOGsynOTR/

' + # LOGmax + echo ' +

+ ' + if [ -n "$LOGmax" ]; then + echo '' + else + echo '' + fi + echo ' + + + LOG-Files können automatisch gelöscht werden, indem hier die maximal gewünschte Anzahl angegeben wird. +
Sobald hier ein Wert vergeben wird, werden grundsätzlich alle leeren LOGs gelöscht. +
(Die Anzahl bezieht sich also nur auf LOGs mit Einträgen) +

' # reindex echo '

diff --git a/Build/help.sh b/Build/help.sh index 803de7a..a455943 100644 --- a/Build/help.sh +++ b/Build/help.sh @@ -16,7 +16,8 @@ echo '

  • Um synOTR regelmäßig laufen zu lassen (was sich empfiehlt), erstelle als nächstes
    einen automatisierten Programmaufruf.

    - Dazu hast du 2 Möglichkeiten:
    verwende den Zeitplaner für einen programmierten synOTR-Start.


    + Dazu hast du 2 Möglichkeiten:
    verwende den Zeitplaner für einen programmierten synOTR-Start. +

    Hierbei ist zu beachten, dass der DSM-Sicherheitsbereater den Zusätzlichen Croneintrag (da für DSM unbekannt) bemängelt!


    Oder, erstelle alternativ im Aufgabenplaner einen neuen Task mit diesem Programmpfad
    (zu empfehlen, sofern du kürzere Intervalle als "stündlich" benötigst):

    /usr/syno/synoman/webman/3rdparty/synOTR/synOTR-start.sh

    diff --git a/Build/status.sh b/Build/status.sh index 54f0d2a..af191f1 100644 --- a/Build/status.sh +++ b/Build/status.sh @@ -85,17 +85,11 @@ func_main_LastLog () { # Dateistatus auslesen: # --------------------------------------------------------------------- # .otrkey-Files: - count_otrkey=0 - for i in $(find "$OTRkeydir" -maxdepth 1 -name "*.otrkey" -type f) - do - count_otrkey=$(( count_otrkey + 1 )) - done + count_otrkey=$( ls -t "${OTRkeydir}" | egrep -o '.*.otrkey$' | wc -l ) # wie viele Dateien + # wait of cutlist: - count_waitofcutlist=0 - for i in $(find "$DECODIR" -maxdepth 1 -name "*.avi" -o -name "*.mp4" -type f) - do - count_waitofcutlist=$(( count_waitofcutlist + 1 )) - done + count_waitofcutlist=$( expr $( ls -t "${DECODIR}" | egrep -o '.*.avi$' | wc -l ) + $( ls -t "${DECODIR}" | egrep -o '.*.mp4$' | wc -l ) ) # wie viele Dateien + # manueller synOTR-Start: # --------------------------------------------------------------------- diff --git a/Build/synOTR.sh b/Build/synOTR.sh index f2ea053..ab5f676 100644 --- a/Build/synOTR.sh +++ b/Build/synOTR.sh @@ -8,8 +8,8 @@ echo " -----------------------------------" echo -e - CLIENTVERSION="4.0.8" # [2018-12-17] - DevChannel="Release" # beta + CLIENTVERSION=`get_key_value /var/packages/synOTR/INFO version` + DevChannel="Release" # beta [2019-01-07] # --------------------------------------------------------------------------------- # GRUNDKONFIGRUATIONEN / INDIVIDUELLE ANPASSUNGEN / Standardwerte | @@ -685,6 +685,18 @@ if [ $decoderactiv = "on" ] && [ ! -z "$filetest" ] ; then echo 2 > /dev/ttyS1 #short beep sleep 1 fi + if [ ! -z $PBTOKEN ] ; then + PB_LOG=`curl $cURLloglevel --header "Access-Token:${PBTOKEN}" https://api.pushbullet.com/v2/pushes -d type=note -d title="synOTR" -d body="Film [$filename] ist fertig."` + if [ $LOGlevel = "2" ] ; then + echo " PushBullet-LOG:" + echo "$PB_LOG" + elif echo "$PB_LOG" | grep -q "error"; then # für Loglevel 1 nur Errorausgabe + echo -n " PushBullet-Error: " + echo "$PB_LOG" | jq -r '.error_code' + fi + else + echo " (PushBullet-TOKEN nicht gesetzt)" + fi wget --timeout=30 --tries=2 -q -O - "http://${synotrdomain}/synOTR/synOTR_FILECOUNT" >/dev/null 2>&1 needindex=1 fi @@ -1577,6 +1589,18 @@ if [ $OTRcutactiv = "on" ] ; then if [ $dsmbeepnotify = "on" ] ; then echo 2 > /dev/ttyS1 #short beep fi + if [ ! -z $PBTOKEN ] ; then + PB_LOG=`curl $cURLloglevel --header "Access-Token:${PBTOKEN}" https://api.pushbullet.com/v2/pushes -d type=note -d title="synOTR" -d body="Film [$filedestname] ist fertig."` + if [ $LOGlevel = "2" ] ; then + echo " PushBullet-LOG:" + echo "$PB_LOG" + elif echo "$PB_LOG" | grep -q "error"; then # für Loglevel 1 nur Errorausgabe + echo -n " PushBullet-Error: " + echo "$PB_LOG" | jq -r '.error_code' + fi + else + echo " (PushBullet-TOKEN nicht gesetzt)" + fi wget --timeout=30 --tries=2 -q -O - "http://${synotrdomain}/synOTR/synOTR_FILECOUNT" >/dev/null 2>&1 needindex=1 fi @@ -1749,7 +1773,7 @@ if [ $OTRcutactiv = "on" ] ; then if [ $dsmtextnotify = "on" ] ; then title=${filename%.*} sleep 1 - synodsmnotify $MessageTo "synOTR" "[$title] ist fertig" + synodsmnotify $MessageTo "synOTR" "Film [$title] ist fertig" sleep 1 fi if [ $dsmbeepnotify = "on" ] ; then @@ -1757,6 +1781,18 @@ if [ $OTRcutactiv = "on" ] ; then echo 2 > /dev/ttyS1 #short beep sleep 1 fi + if [ ! -z $PBTOKEN ] ; then + PB_LOG=`curl $cURLloglevel --header "Access-Token:${PBTOKEN}" https://api.pushbullet.com/v2/pushes -d type=note -d title="synOTR" -d body="Film [$title] ist fertig."` + if [ $LOGlevel = "2" ] ; then + echo " PushBullet-LOG:" + echo "$PB_LOG" + elif echo "$PB_LOG" | grep -q "error"; then # für Loglevel 1 nur Errorausgabe + echo -n " PushBullet-Error: " + echo "$PB_LOG" | jq -r '.error_code' + fi + else + echo " (PushBullet-TOKEN nicht gesetzt)" + fi wget --timeout=30 --tries=2 -q -O - "http://${synotrdomain}/synOTR/synOTR_FILECOUNT" >/dev/null 2>&1 needindex=1 fi @@ -1880,7 +1916,7 @@ if [ $OTRavi2mp4active = "on" ] && [ ! -z "$filetest" ] ; then fi elif $(echo "$encoders" | grep -q "AAC (Advanced Audio Coding)" ) ; then # Native FFmpeg AAC encoder echo "Erkannter Encoder: nativ (ffmpeg > 3.0) [2.Wahl]" - if [ $normalizeAudio = "on_" ] ; then + if [ $normalizeAudio = "on" ] ; then # ------- Audio normalisieren: volumeinfo=$(ffmpeg -i "$audiofile" -af "volumedetect" -f null - 2>&1 | awk '-F: ' '/max_volume/ { gsub(/ .*/, "", $2); print $2 }' | sed 's/-//g') # |grep max_volume | awk -F: '{ print $2 }' | sed 's/ dB//g' | sed 's/ -//g') echo "Lautstärkeanhebung um: $volumeinfo dB" @@ -1969,7 +2005,7 @@ if [ $OTRavi2mp4active = "on" ] && [ ! -z "$filetest" ] ; then synoindex -a "${pfad}${title}.mp4" if [ $dsmtextnotify = "on" ] ; then sleep 1 - synodsmnotify $MessageTo "synOTR" "[$title] ist fertig" + synodsmnotify $MessageTo "synOTR" "Film [$title] ist fertig" sleep 1 fi if [ $dsmbeepnotify = "on" ] ; then @@ -1977,6 +2013,18 @@ if [ $OTRavi2mp4active = "on" ] && [ ! -z "$filetest" ] ; then echo 2 > /dev/ttyS1 #short beep sleep 1 fi + if [ ! -z $PBTOKEN ] ; then + PB_LOG=`curl $cURLloglevel --header "Access-Token:${PBTOKEN}" https://api.pushbullet.com/v2/pushes -d type=note -d title="synOTR" -d body="Film [$title] ist fertig."` + if [ $LOGlevel = "2" ] ; then + echo " PushBullet-LOG:" + echo "$PB_LOG" + elif echo "$PB_LOG" | grep -q "error"; then # für Loglevel 1 nur Errorausgabe + echo -n " PushBullet-Error: " + echo "$PB_LOG" | jq -r '.error_code' + fi + else + echo " (PushBullet-TOKEN nicht gesetzt)" + fi wget --timeout=30 --tries=2 -q -O - "http://${synotrdomain}/synOTR/synOTR_FILECOUNT" >/dev/null 2>&1 needindex=1 fi @@ -2285,7 +2333,7 @@ for i in $(find "$WORKDIR" -maxdepth 1 -name "*TVOON*avi" -o -name "*TVOON*mp4" synoindex -a "${WORKDIR}${NewName}" if [ $dsmtextnotify = "on" ] ; then sleep 1 - synodsmnotify $MessageTo "synOTR" "[$title] ist fertig" + synodsmnotify $MessageTo "synOTR" "Film [$title] ist fertig" sleep 1 fi if [ $dsmbeepnotify = "on" ] ; then @@ -2293,6 +2341,18 @@ for i in $(find "$WORKDIR" -maxdepth 1 -name "*TVOON*avi" -o -name "*TVOON*mp4" echo 2 > /dev/ttyS1 #short beep sleep 1 fi + if [ ! -z $PBTOKEN ] ; then + PB_LOG=`curl --header "Access-Token:${PBTOKEN}" https://api.pushbullet.com/v2/pushes -d type=note -d title="synOTR" -d body="Filme [$film] ist fertig."` + if [ $LOGlevel = "2" ] ; then + echo "PushBullet-LOG:" + echo "$PB_LOG" + elif echo "$PB_LOG" | grep -q "error"; then # für Loglevel 1 nur Errorausgabe + echo -n "PushBullet-Error: " + echo "$PB_LOG" | jq -r '.error_code' + fi + else + echo "PushBullet-TOKEN nicht erkannt" + fi wget --timeout=30 --tries=2 -q -O - "http://${synotrdomain}/synOTR/synOTR_FILECOUNT" >/dev/null 2>&1 needindex=1 fi @@ -2404,7 +2464,7 @@ if [ $OTRrenameactiv = "on" ] && [ $firstrunonday == "1" ] ; then if jq -e . >/dev/null 2>&1 <<<"$serieninfo"; then # prüfen, ob korrektes JSON-Format verarbeitet werden kann (https://stackoverflow.com/questions/46954692/check-if-string-is-a-valid-json-with-jq) echo -e "gefunden:" echo "OTRID: $OTRID" - serietitle=`echo "$serieninfo" | jq -r '.Serie' | sed "s/://g" ` # jq ist ein Kommandozeilen-JSON-Parser + serietitle=`echo "$serieninfo" | jq -r '.Serie' | sed "s/://g" ` echo "serietitle: $serietitle" season=`echo "$serieninfo" | awk -F, '{print $3}' | awk -F: '{print $2}' | sed "s/\"//g"` season="$(printf '%02d' "$season")" # 2stellig mit führender Null @@ -2513,7 +2573,7 @@ if [ $OTRrenameactiv = "on" ] && [ $firstrunonday == "1" ] ; then if [ $dsmtextnotify = "on" ] ; then sleep 1 - synodsmnotify $MessageTo "synOTR" "[$title] ist fertig" + synodsmnotify $MessageTo "synOTR" "Film [$title] ist fertig" sleep 1 fi if [ $dsmbeepnotify = "on" ] ; then @@ -2712,7 +2772,7 @@ if [ $useWORKDIR == "yes" ] && [ ! -z "$filetest" ]; then if [ $dsmtextnotify = "on" ] ; then sleep 1 - synodsmnotify $MessageTo "synOTR" "[$filename] ist fertig" + synodsmnotify $MessageTo "synOTR" "Film [$filename] ist fertig" sleep 1 fi if [ $dsmbeepnotify = "on" ] ; then @@ -2720,6 +2780,18 @@ if [ $useWORKDIR == "yes" ] && [ ! -z "$filetest" ]; then echo 2 > /dev/ttyS1 #short beep sleep 1 fi + if [ ! -z $PBTOKEN ] ; then + PB_LOG=`curl $cURLloglevel --header "Access-Token:${PBTOKEN}" https://api.pushbullet.com/v2/pushes -d type=note -d title="synOTR" -d body="Film [$filename] ist fertig."` + if [ $LOGlevel = "2" ] ; then + echo " PushBullet-LOG:" + echo "$PB_LOG" + elif echo "$PB_LOG" | grep -q "error"; then # für Loglevel 1 nur Errorausgabe + echo -n " PushBullet-Error: " + echo "$PB_LOG" | jq -r '.error_code' + fi + else + echo " (PushBullet-TOKEN nicht gesetzt)" + fi wget --timeout=30 --tries=2 -q -O - "http://${synotrdomain}/synOTR/synOTR_FILECOUNT" >/dev/null 2>&1 needindex=1 @@ -2744,7 +2816,7 @@ if [ $useWORKDIR == "yes" ] && [ ! -z "$filetest" ]; then if [ $dsmtextnotify = "on" ] ; then sleep 1 - synodsmnotify $MessageTo "synOTR" "[$filename] ist fertig" + synodsmnotify $MessageTo "synOTR" "Film [$filename] ist fertig" sleep 1 fi if [ $dsmbeepnotify = "on" ] ; then @@ -2752,6 +2824,18 @@ if [ $useWORKDIR == "yes" ] && [ ! -z "$filetest" ]; then echo 2 > /dev/ttyS1 #short beep sleep 1 fi + if [ ! -z $PBTOKEN ] ; then + PB_LOG=`curl $cURLloglevel --header "Access-Token:${PBTOKEN}" https://api.pushbullet.com/v2/pushes -d type=note -d title="synOTR" -d body="Film [$filename] ist fertig."` + if [ $LOGlevel = "2" ] ; then + echo " PushBullet-LOG:" + echo "$PB_LOG" + elif echo "$PB_LOG" | grep -q "error"; then # für Loglevel 1 nur Errorausgabe + echo -n " PushBullet-Error: " + echo "$PB_LOG" | jq -r '.error_code' + fi + else + echo " (PushBullet-TOKEN nicht gesetzt)" + fi wget --timeout=30 --tries=2 -q -O - "http://${synotrdomain}/synOTR/synOTR_FILECOUNT" >/dev/null 2>&1 needindex=1 else @@ -2781,6 +2865,73 @@ if [ -f "/usr/syno/bin/synoindex" ] && [ $firstrunonday == "1" ] && [ $reindex = fi } + +PURGELOG() +{ +######################################################################################### +# Diese Funktion löscht zu erst alle leeren Logs und anschließend die überzähligen # +######################################################################################### + +if [ -z $LOGmax ]; then + return +fi + +logdir="${DECODIR}/_LOGsynOTR/" + +# leere Logs löschen: +for i in `ls -tr "${logdir}" | egrep -o '^synOTR.*.log$' ` # Auflistung aller LOG-Dateien + do + if [ $( cat "${logdir}$i" | tail -n7 | head -n4 | wc -c ) -le 15 ] && cat "${logdir}$i" | grep -q "synOTR ENDE" ; then + if [ $endgueltigloeschen = "on" ] ; then + rm "${logdir}$i" + else + mv "${logdir}$i" "$OTRkeydeldir" + fi + fi + done + +# überzählige Logs löschen: +count2del=$( expr $( ls -t "${logdir}" | egrep -o '^synOTR.*.log$' | wc -l ) - $LOGmax ) # wie viele Dateien sind überzählig +if [ $count2del -ge 0 ]; then + for i in `ls -tr "${logdir}" | egrep -o '^synOTR.*.log$' | head -n${count2del} ` + do + if [ $endgueltigloeschen = "on" ] ; then + rm "${logdir}$i" + else + mv "${logdir}$i" "$OTRkeydeldir" + fi + done +fi + +# überzählige searches löschen: +count2del=$( expr $(ls -t "${logdir}" | egrep -o '^search.*.xml$' | wc -l) - $LOGmax ) +if [ ${count2del} -ge 0 ]; then + for i in `ls -tr "${logdir}" | egrep -o '^search.*.xml$' | head -n${count2del} ` + do + if [ $endgueltigloeschen = "on" ] ; then + rm "${logdir}$i" + else + mv "${logdir}$i" "$OTRkeydeldir" + fi + done +fi + +# überzählige cutlists löschen: +count2del=$( expr $(ls -t "${logdir}" | egrep -o '.*.cutlist$' | wc -l) - $LOGmax ) +if [ ${count2del} -ge 0 ]; then + for i in `ls -tr "${logdir}" | egrep -o '.*.cutlist$' | head -n${count2del} ` + do + if [ $endgueltigloeschen = "on" ] ; then + rm "${logdir}$i" + else + mv "${logdir}$i" "$OTRkeydeldir" + fi + done +fi + +} + + # _______________________________________________________________________________ # | | # | AUFRUF DER FUNKTIONEN | @@ -2799,6 +2950,7 @@ fi OTRopenrename MOVE2DESTDIR FRESHUPMEDIAINDEX + PURGELOG echo -e; echo -e diff --git a/Build/upgradeconfig.sh b/Build/upgradeconfig.sh index 7000d49..8d1beaa 100644 --- a/Build/upgradeconfig.sh +++ b/Build/upgradeconfig.sh @@ -28,9 +28,15 @@ if ! cat ./$CONFIG | grep -q "dsmbeepnotify" ; then echo "dsmbeepnotify=\"on\"" >> ./$CONFIG fi + if ! cat ./$CONFIG | grep -q "PBTOKEN" ; then + echo "PBTOKEN=\"\"" >> ./$CONFIG + fi if ! cat ./$CONFIG | grep -q "LOGlevel" ; then echo "LOGlevel=\"1\"" >> ./$CONFIG fi + if ! cat ./$CONFIG | grep -q "LOGmax" ; then + echo "LOGmax=\"1\"" >> ./$CONFIG + fi if ! cat ./$CONFIG | grep -q "reindex" ; then echo "reindex=\"1\"" >> ./$CONFIG fi diff --git a/Build/usersettings/Konfiguration_org.txt b/Build/usersettings/Konfiguration_org.txt index a1a656e..1b30891 100644 --- a/Build/usersettings/Konfiguration_org.txt +++ b/Build/usersettings/Konfiguration_org.txt @@ -49,8 +49,10 @@ MP4BOX_DELAY="100" #-------------------------------------------------------------------- dsmtextnotify="on" MessageTo="admin" +PBTOKEN="" dsmbeepnotify="on" LOGlevel="1" +LOGmax="" reindex=1 #-------------------------------------------------------------------- diff --git a/Pack/CHANGELOG b/Pack/CHANGELOG index c04dd8e..d8c2792 100644 --- a/Pack/CHANGELOG +++ b/Pack/CHANGELOG @@ -1,4 +1,13 @@ -Release Notes +Release Notes + +4.1.0 (RELEASE) + IMPLEMENTIERUNGEN: + - PushBullet integriert. Dazu muss lediglich der persönliche Token in der Konfiguration hinterlegt werden + - Die max. Anzahl von LOGs kann nun begrenzt werden. Dadurch werden zu erst alle leeren Logs und anschließend die überzähligen gelöscht + BUGFIXES: + - es wurde ein Fehler behoben, dass bei aktivem nativen aac-Encoder keine Normalisierung der Tonspur möglich war + - Detailänderungen in der GUI + - Detailänderungen der Benachrichtigungstexte 4.0.8 (RELEASE) BUGFIXES: diff --git a/Pack/INFO b/Pack/INFO index 62e1073..c7b163f 100644 --- a/Pack/INFO +++ b/Pack/INFO @@ -1,6 +1,6 @@ package="synOTR" displayname="synOTR" -version="4.0.8" +version="4.0.9" thirdparty="yes" description="SynOTR liefert einen Workflow für TV-Aufnahmen von onlineTVrecorder (OTR) auf Synology NAS. synOTR übernimmt *decodieren *AC3-muxing (BETA) *schneiden *MP4-Konvertierung und *umbenennung (inkl. Serieninformationen von www.thetvdb.com und www.otr-serien.de). onlineTVrecorder (OTR) ist der freie Videorecorder im Internet, der rund um die Uhr fast alle Sendungen von rund 100 TV-Sender aus Deutschland, USA, UK und anderen Lädern aufnimmt." maintainer="geimist"