2998 lines
158 KiB
Bash
2998 lines
158 KiB
Bash
#!/bin/sh
|
|
# /usr/syno/synoman/webman/3rdparty/synOTR/synOTR.sh
|
|
|
|
###################################################################################
|
|
|
|
echo " -----------------------------------"
|
|
echo " | ==> Installationsinfo <== |"
|
|
echo " -----------------------------------"
|
|
echo -e
|
|
|
|
CLIENTVERSION=$(get_key_value /var/packages/synOTR/INFO version)
|
|
set -E -o functrace # for function failure()
|
|
DevChannel="Release" # [2023-08-18]
|
|
|
|
# ---------------------------------------------------------------------------------
|
|
# GRUNDKONFIGRUATIONEN / INDIVIDUELLE ANPASSUNGEN / Standardwerte |
|
|
# (alle Werte können durch setzen in der Konifiguration.txt |
|
|
# überschrieben werden) |
|
|
# ---------------------------------------------------------------------------------
|
|
SMARTRENDERING="on" # Smartrendering profilaktisch aktivieren
|
|
OTRlocalcutlistdir="" # optionaler Ordner für lokale Cutlist => diese Cutlist werden geprüft und müssen daher direkt zum Film passen / bei Nichtnutzung leer lassen
|
|
normalizeAudio="on" # Audiospur normalisieren (nur in Verbindung mit avi2mp4)
|
|
autoupdate="off"
|
|
forceupdate="off" # Updateaufruf ohne Prüfung erzwingen
|
|
synotrdomain="geimist.eu" # notwendig für Update, Konsitenzprüfung, DEV-Report und evtl. in Zukunft zum abfragen der API-Keys
|
|
endgueltigloeschen="off" # das endgültige Löschen der Quelldateien erst einmal grundsätzlich deaktivieren
|
|
# Frameversatz, um Cuts manuell zu justieren (positive Werte verschieben den Cut nach hinten, negative nach vorn):
|
|
FrameversatzAnfangCut=1 # = verschiebt den Beginn des gewünschten Filmteils beim framegenauen Schneiden
|
|
FrameversatzEndeCut=1 # = verschiebt das Ende des gewünschten Filmteils beim framegenauen Schneiden
|
|
MP4BOX_DELAY="" # in Millisekunden / Feinabstimmung für den Audio-Video-Sync / Positive Werte verzögern den Ton; negative Werte 'holen den Ton nach vorn'
|
|
niceness=15 # Die Priorität liegt im Bereich von -20 bis +19 (in ganzzahligen Schritten), wobei -20 die höchste Priorität (=meiste Rechenleistung) und 19 die niedrigste Priorität (=geringste Rechenleistung) ist. Die Standardpriorität ist 0. AUF NEGATIVE WERTE SOLLTE UNBEDINGT VERZICHTET WERDEN!
|
|
reindex=1 # Standard 1 - einamlige Reindexierung des Zielordners nach dem ersten Programmlauf des Tages
|
|
needindex=0 # wird bei einem fertigen Film auf 1 gesetzt um den Zielordnerindex für die VideoStation neu zuindexieren
|
|
DEBUGINFO="on" # ich bin dankbar, wenn der Wert auf 'on' gestellt bleibt - deaktivieren sofern keine anonyme Systeminfo an den Entwickler gesendet werden darf (Installationstrigger beinhaltet folgende anonymen Geräteinfos: DSM-Build / Prüfsumme der MAC-Adresse als Hardware-ID [anonyme Zahlenfolge um Installationen zu zählen] / Architektur / Geräte-Typ)
|
|
WaitOfCutlist="on" # mit dem weiterverarbeiten eines Filmes wird so lange gewartet, bis eine Cutlist verfügbar ist
|
|
useallcutlistformat=0 # Cutlits für alternative Formate berücksichtigen
|
|
timediff=1 # Abweichung der Dateiänderungszeit in Minuten um laufende FTP-Pushaufträge nicht zu decodieren
|
|
TVDBlang="de" # Sprache, in welcher nach Serien auf theTVDB.com gesucht werden soll
|
|
TVDB_APIKEY="" # eigenen API-Key für theTVDB.com verwenden
|
|
today=`date +%d | sed -e 's/^0*//'` # Datum (Tag) ohne führende Null (lässt sich sonst nicht als Berechnungsgrundlage nutzen)
|
|
regInt='^[0-9]+$' # Vorlage: Regex check Integer
|
|
|
|
# an welchen User/Gruppe soll die DSM-Benachrichtigung gesendet werden :
|
|
# ---------------------------------------------------------------------
|
|
synOTR_user=`whoami`; echo "synOTR-User: $synOTR_user"
|
|
if cat /etc/group | grep administrators | grep -q "$synOTR_user"; then
|
|
isAdmin=yes
|
|
else
|
|
isAdmin=no
|
|
fi
|
|
MessageTo="@administrators" # Administratoren (Standardeinstellung)
|
|
#MessageTo="$synOTR_user" # User, welche synOTR aufgerufen hat (funktioniert natürlich nicht bei root, da root kein DSM-GUI-LogIn hat und die Message ins leere läuft)
|
|
|
|
# Arbeitsverzeichnis auslesen und hineinwechseln:
|
|
# ---------------------------------------------------------------------
|
|
OLDIFS=$IFS # ursprünglichen Fieldseparator sichern
|
|
UNIXTIME=$(date +%s)
|
|
APPDIR=$(cd $(dirname $0);pwd)
|
|
cd ${APPDIR}
|
|
|
|
# Konfigurationsdatei einbinden:
|
|
# ---------------------------------------------------------------------
|
|
CONFIG=app/etc/Konfiguration.txt
|
|
. ./$CONFIG
|
|
|
|
# Variable "lastjob" für Benachrichtigung setzen:
|
|
# ---------------------------------------------------------------------
|
|
if [ $OTRrenameactiv = "on" ] ; then
|
|
lastjob=4
|
|
elif [ $OTRavi2mp4active = "on" ] ; then
|
|
lastjob=3
|
|
elif [ $OTRcutactiv = "on" ] ; then
|
|
lastjob=2
|
|
else
|
|
lastjob=1
|
|
fi
|
|
|
|
# Aufgabenindex:
|
|
# ---------------------------------------------------------------------
|
|
if [ $decoderactiv = "on" ] ; then idx1=1 ; else idx1=0 ; fi
|
|
if [ $OTRcutactiv = "on" ] ; then idx2=1 ; else idx2=0 ; fi
|
|
if [ $OTRavi2mp4active = "on" ]; then idx3=1 ; else idx3=0 ; fi
|
|
if [ $OTRrenameactiv = "on" ]; then idx4=1 ; else idx4=0 ; fi
|
|
idx=${idx1}${idx2}${idx3}${idx4}
|
|
|
|
# Systeminformation / LIBRARY_PATH anpassen / PATH anpassen:
|
|
# ---------------------------------------------------------------------
|
|
echo "synOTR-Version: $CLIENTVERSION"
|
|
machinetyp=`uname --machine`; echo "Architektur: $machinetyp"
|
|
dsmbuild=`uname -v | awk '{print $1}' | sed "s/#//g"`; echo "DSM-Build: $dsmbuild"
|
|
read MAC </sys/class/net/eth0/address
|
|
sysID=`echo $MAC | cksum | awk '{print $1}'`; sysID="$(printf '%010d' $sysID)" #echo "Prüfsumme der MAC-Adresse als Hardware-ID: $sysID" 10-stellig
|
|
device=`uname -a | awk -F_ '{print $NF}' | sed "s/+/plus/g" `; echo "Gerät: $device ($sysID)" # | sed "s/ds//g"
|
|
# für HD-Aufnahmen mit avcut mindestens 500 MB free:
|
|
echo -n " RAM installiert: "; RAMmax=`free -m | grep 'Mem:' | awk '{print $2}'`; echo "$RAMmax MB" # verbauter RAM
|
|
echo -n " RAM verwendet: "; RAMused=`free -m | grep 'Mem:' | awk '{print $3}'`; echo "$RAMused MB" # genutzter RAM
|
|
echo -n " RAM verfügbar: "; RAMfree=$(( $RAMmax - $RAMused )); echo "$RAMfree MB"
|
|
|
|
# synOTR Programmlauf auf die Hardware abstimmen:
|
|
# ---------------------------------------------------------------------
|
|
save_ENV ()
|
|
{
|
|
# https://forum.ubuntuusers.de/post/2099580/
|
|
# http://www.linux-praxis.de/lpic1/lpi101/1.102.4.html
|
|
# man kann mit synOTR_ENV und restore_ENV zwischen den beiden ENV-Versionen wechseln
|
|
export SAVED_PATH=$PATH
|
|
export SAVED_LD_LIBRARY_PATH=$LD_LIBRARY_PATH
|
|
}
|
|
|
|
restore_ENV ()
|
|
{
|
|
# echo "Die Standard-Pathvariablen werden geladen …"
|
|
export PATH=$SAVED_PATH
|
|
export LD_LIBRARY_PATH=$SAVED_LD_LIBRARY_PATH
|
|
}
|
|
|
|
save_ENV
|
|
|
|
if [ $machinetyp = "x86_64" ] && [ $dsmbuild -gt 7134 ]; then # DSM-Build 7135 = DSM 6.0 BETA 1
|
|
echo " System arbeitet mit DSM 6.0 oder höher. Der LD_LIBRARY_PATH wird angepasst."
|
|
synOTR_LD_LIBRARY_PATH=${APPDIR}/app/lib:$LD_LIBRARY_PATH
|
|
synOTR_PATH=$PATH:${APPDIR}/app/bin
|
|
bsy="${APPDIR}/app/bin/busybox"
|
|
# ffmpeg="${APPDIR}/app/bin/ffmpeg"
|
|
# ffmpeg=`which ffmpeg` # mitgeliefertes ffmpeg läuft derzeit nicht korrekt
|
|
ffmpeg="/usr/local/bin/ffmpeg6" # ffmpeg 6 von synocommunity
|
|
avcut="${APPDIR}/app/bin/avcut64"
|
|
ionice="${APPDIR}/app/bin/ionice64"
|
|
elif [ `echo $machinetyp | grep "armv7" ` ] ; then
|
|
synOTR_LD_LIBRARY_PATH=${APPDIR}/app/libARMv7l:$LD_LIBRARY_PATH
|
|
synOTR_PATH=$PATH:${APPDIR}/app/binARMv7l:/opt/bin
|
|
bsy="${APPDIR}/app/binARMv7l/busybox"
|
|
# ffmpeg="${APPDIR}/app/binARMv7l/ffmpeg"
|
|
# ffmpeg=`which ffmpeg` # mitgeliefertes ffmpeg läuft derzeit nicht korrekt
|
|
ffmpeg="/usr/local/bin/ffmpeg6" # ffmpeg 6 von synocommunity
|
|
avcut="${APPDIR}/app/binARMv7l/avcut"
|
|
if [[ `uname -a | grep "armadaxp" ` ]] ; then
|
|
echo " alternative avcut-Version ohne asm wird verwendet"
|
|
avcut="${APPDIR}/app/binARMv7l/avcut_disable-asm"
|
|
fi
|
|
ionice="${APPDIR}/app/binARMv7l/ionice"
|
|
elif [ $machinetyp = "i686" ] ; then
|
|
bsy="${APPDIR}/app/bin/busybox"
|
|
# ffmpeg="${APPDIR}/app/bin/ffmpeg"
|
|
# ffmpeg=`which ffmpeg` # mitgeliefertes ffmpeg läuft derzeit nicht korrekt
|
|
ffmpeg="/usr/local/bin/ffmpeg6" # ffmpeg 6 von synocommunity
|
|
avcut="${APPDIR}/app/bin/avcut32"
|
|
synOTR_LD_LIBRARY_PATH=$SAVED_LD_LIBRARY_PATH
|
|
synOTR_PATH=$PATH:${APPDIR}/app/bin
|
|
ionice="${APPDIR}/app/bin/ionice32"
|
|
elif [ $machinetyp = "x86_64" ] ; then
|
|
bsy="${APPDIR}/app/bin/busybox"
|
|
# ffmpeg="${APPDIR}/app/bin/ffmpeg"
|
|
ffmpeg=`which ffmpeg` # mitgeliefertes ffmpeg läuft derzeit nicht korrekt
|
|
avcut="${APPDIR}/app/bin/avcut64"
|
|
synOTR_LD_LIBRARY_PATH=$SAVED_LD_LIBRARY_PATH
|
|
synOTR_PATH=$PATH:${APPDIR}/app/bin
|
|
ionice="${APPDIR}/app/bin/ionice64"
|
|
else
|
|
message="Deine CPU-Plattform [${machinetyp}] wird leider von synOTR nicht unterstützt oder ist nicht bekannt …"
|
|
echo "$message"
|
|
synodsmnotify $MessageTo "$message"
|
|
exit
|
|
fi
|
|
|
|
synOTR_ENV ()
|
|
{
|
|
# restore_ENV
|
|
# echo "Die angepassten Pathvariablen werden geladen …"
|
|
export PATH=$synOTR_PATH
|
|
export LD_LIBRARY_PATH=$synOTR_LD_LIBRARY_PATH
|
|
}
|
|
|
|
synOTR_ENV
|
|
|
|
# alle Kommandos und Kindprozesse des Skriptes mit niedrigst möglicher Priorität ausgeführen:
|
|
echo "Priorität anpassen: $(renice -n 19 -p $$)"
|
|
echo " $($ionice -c 2 -n 7 -p $$)"
|
|
|
|
# Info der Datenbank auslesen:
|
|
# ---------------------------------------------------------------------
|
|
if [ -f "${APPDIR}/app/etc/synOTR.sqlite" ] ; then
|
|
rowcount=$(sqlite3 "${APPDIR}/app/etc/synOTR.sqlite" "SELECT COUNT(*) FROM raw")
|
|
dbsize=$(ls -lh "${APPDIR}/app/etc/synOTR.sqlite" | awk '{ print $5 }')
|
|
echo "DB-Größe: ${dbsize}Byte / $rowcount Datensätze"
|
|
fi
|
|
|
|
# spezielle Programmpfade / sonstige Variablen anpassen :
|
|
# ---------------------------------------------------------------------
|
|
# (oder andere gewünschte Version / nicht benötigte ggfs. auskommentieren)
|
|
# ffmpeg="${APPDIR}/app/bin/ffmpeg_fdk/ffmpeg"
|
|
# ffmpeg="${APPDIR}/app/bin/ffmpeg"
|
|
# ffmpeg=`which ffmpeg` # erstes ffmpeg in PATH
|
|
echo "ffmpeg-Version: $ffmpeg"
|
|
|
|
# Konfiguration für LogLevel:
|
|
# ---------------------------------------------------------------------
|
|
# LOGlevel: 0 => Logging inaktiv / 1 => normal / 2 => erweitert
|
|
if [ $LOGlevel = "1" ] ; then
|
|
echo "Loglevel: normal"
|
|
ffloglevel="warning" # ffmpeg LogLevel (https://ffmpeg.org/ffmpeg.html)
|
|
mp4boxloglevel="-quiet"
|
|
CUTloglevel="-w"
|
|
cURLloglevel="-s"
|
|
wgetloglevel="-q"
|
|
elif [ $LOGlevel = "2" ] ; then
|
|
echo "Loglevel: erweitert"
|
|
ffloglevel="info"
|
|
mp4boxloglevel=""
|
|
CUTloglevel="-v"
|
|
cURLloglevel="-v"
|
|
wgetloglevel="-v"
|
|
else
|
|
ffloglevel="quiet"
|
|
mp4boxloglevel="-quiet"
|
|
CUTloglevel="-w"
|
|
fi
|
|
|
|
# Verzeichnisse prüfen bzw. anlegen und anpassen:
|
|
# ---------------------------------------------------------------------
|
|
echo "Anwendungsverzeichnis: ${APPDIR}"
|
|
|
|
# Variablenkorrektur für ältere Konfiguration.txt und Slash anpassen:
|
|
if [ -d "$destdir" ] ; then
|
|
DESTDIR="${destdir%/}/"
|
|
fi
|
|
if [ -d "$DESTDIR" ] ; then
|
|
DESTDIR="${DESTDIR%/}/"
|
|
fi
|
|
if [ -d "$OTRkeydeldir" ] ; then
|
|
OTRkeydeldir="${OTRkeydeldir%/}/"
|
|
fi
|
|
if [ -d "$WORKDIR" ] ; then
|
|
WORKDIR="${WORKDIR%/}/"
|
|
fi
|
|
|
|
if [ $endgueltigloeschen = "on" ] ; then
|
|
echo "Endgültiges Löschen ist aktiviert!"
|
|
else
|
|
if [ -d "$OTRkeydeldir" ]; then
|
|
echo "Löschverzeichnis: $OTRkeydeldir"
|
|
else
|
|
mkdir -p "$OTRkeydeldir"
|
|
echo "Löschverzeichnis wurde erstellt [$OTRkeydeldir]"
|
|
fi
|
|
fi
|
|
|
|
if [ -z "$WORKDIR" ] ; then
|
|
WORKDIR="${DESTDIR}"
|
|
useWORKDIR="no"
|
|
echo "Variable WORKDIR nicht gesetzt. Es wird im Zielverzeichnis gearbeitet!"
|
|
elif [ "${WORKDIR}" = "${DESTDIR}" ] ; then
|
|
useWORKDIR="no"
|
|
echo "Variable WORKDIR entspricht dem Zielverzeichnis. Es wird im Zielverzeichnis gearbeitet!"
|
|
else
|
|
useWORKDIR="yes"
|
|
fi
|
|
|
|
if [ -d "$OTRkeydir" ] ; then
|
|
echo "Quellverzeichnis: $OTRkeydir"
|
|
else
|
|
echo "kein gültiges Quellverzeichnis gefunden!"
|
|
fi
|
|
|
|
if [ -d "$DESTDIR" ] ; then
|
|
echo "Zielverzeichnis: $DESTDIR"
|
|
else
|
|
mkdir -p "$DESTDIR"
|
|
echo "Zielverzeichnis [$DESTDIR] wurde erstellt"
|
|
fi
|
|
|
|
if [ -d "$WORKDIR" ]; then
|
|
echo "Arbeitsverzeichnis: $WORKDIR"
|
|
else
|
|
mkdir -p "$WORKDIR"
|
|
echo "Arbeitsverzeichnis [$WORKDIR] wurde erstellt."
|
|
fi
|
|
|
|
if [ $OTRcutactiv = "off" ] ; then
|
|
DECODIR="$WORKDIR"
|
|
echo "Decodierverzeichnis: $DECODIR"
|
|
else
|
|
DECODIR="${WORKDIR%/}/_decodiert"
|
|
if [ -d "$DECODIR" ]; then
|
|
echo "Decodierverzeichnis: $DECODIR"
|
|
else
|
|
mkdir -p "$DECODIR"
|
|
echo "Decodierverzeichnis [$DECODIR] wurde erstellt"
|
|
fi
|
|
fi
|
|
|
|
#################################################################################################
|
|
# _______________________________________________________________________________ #
|
|
# | | #
|
|
# | BEGINN DER FUNKTIONEN | #
|
|
# |_______________________________________________________________________________| #
|
|
# #
|
|
#################################################################################################
|
|
|
|
|
|
failure()
|
|
{
|
|
# this function show error line
|
|
# --------------------------------------------------------------
|
|
# https://unix.stackexchange.com/questions/462156/how-do-i-find-the-line-number-in-bash-when-an-error-occured
|
|
local lineno=$1
|
|
local msg=$2
|
|
echo "Failed at $lineno: $msg"
|
|
}
|
|
trap 'failure ${LINENO} "$BASH_COMMAND"' ERR
|
|
|
|
|
|
sec_to_time()
|
|
{
|
|
#########################################################################################
|
|
# diese Funktion wandelt einen Sekundenwert nach hh:mm #
|
|
# Aufruf: sec_to_time "string" #
|
|
# https://blog.jkip.de/in-bash-sekunden-umrechnen-in-stunden-minuten-und-sekunden/ #
|
|
#########################################################################################
|
|
local seconds=$1
|
|
local sign=""
|
|
if [[ ${seconds:0:1} == "-" ]]; then
|
|
seconds=${seconds:1}
|
|
sign="-"
|
|
fi
|
|
local hours=$(( seconds / 3600 ))
|
|
local minutes=$(( (seconds % 3600) / 60 ))
|
|
seconds=$(( seconds % 60 ))
|
|
printf "%s%02d:%02d:%02d" "$sign" $hours $minutes $seconds
|
|
}
|
|
|
|
|
|
MovieDB_query()
|
|
{
|
|
#########################################################################################
|
|
# Diese Funktion sucht auf theTVDB.com nach Serieninformationen #
|
|
#########################################################################################
|
|
|
|
echo -e
|
|
echo "MovieDB_query ==> nicht implementiert …"
|
|
|
|
}
|
|
|
|
|
|
TVDB_query()
|
|
{
|
|
#########################################################################################
|
|
# Diese Funktion sucht auf theTVDB.com nach Serieninformationen #
|
|
#########################################################################################
|
|
|
|
#LOGlevel="2"
|
|
# Token erstellen, sofern nicht vorhanden oder älter als 24h:
|
|
sSQL="SELECT day_created,TOKEN,APIKEY FROM tvdb WHERE rowid=1 "
|
|
sqlerg=`sqlite3 -separator $'\t' ${APPDIR}/app/etc/synOTR.sqlite "$sSQL"`
|
|
TOKEN_DAY_CREATED=`echo "$sqlerg" | awk -F'\t' '{print $1}' `
|
|
TOKEN=`echo "$sqlerg" | awk -F'\t' '{print $2}' `
|
|
TVDB_APIKEY=`echo "$sqlerg" | awk -F'\t' '{print $3}' `
|
|
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo "DB-Abfrageergebnis: $sqlerg"
|
|
#echo "APIKEY: $TVDB_APIKEY"
|
|
fi
|
|
|
|
if [ "$TOKEN_DAY_CREATED" -ne $today ] || [ "$TOKEN_DAY_CREATED" == "" ] || [ "$TOKEN" == "" ] || [ "$TOKEN" == "NULL" ]; then
|
|
echo "TVDB-Token wird erneuert …"
|
|
|
|
if [ "$TVDB_APIKEY" == "" ] || [ "$TVDB_APIKEY" == "NULL" ] ; then # prüfen, ob der Updatedatensatz vorhanden ist, ggfls. einfügen
|
|
echo "Kein TVDB-APIKEY gefunden! Belege die Variable \"TVDB_APIKEY=\" mit einem gültigen TVDB-APIKEY, oder wende dich an den Entwickler (synotr@$synotrdomain)"
|
|
else
|
|
restore_ENV
|
|
# TVDB_TOKEN=`curl $cURLloglevel -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{
|
|
# "apikey": "'${TVDB_APIKEY}'"
|
|
# }' 'https://api.thetvdb.com/login' | jq '.token' | sed "s/\"//g" 2>&1` # | tr -d '"' 2>&1`
|
|
TVDB_TOKEN=`curl $cURLloglevel -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{
|
|
"apikey": "'${TVDB_APIKEY}'"
|
|
}' 'https://api.thetvdb.com/login' ` #| jq '.token' | sed "s/\"//g" 2>&1` # | tr -d '"' 2>&1`
|
|
|
|
if echo "$TVDB_TOKEN" | egrep -q "Connection timed out"; then
|
|
echo "Serverfehler (Zeitüberschreitung)"
|
|
continue
|
|
else
|
|
TVDB_TOKEN=`echo $TVDB_TOKEN | jq '.token' | sed "s/\"//g" 2>&1`
|
|
fi
|
|
|
|
synOTR_ENV
|
|
|
|
sSQLupdate="UPDATE tvdb SET TOKEN='$TVDB_TOKEN', day_created=$today, timestamp=(datetime('now','localtime')) WHERE rowid=1"
|
|
sqlite3 ${APPDIR}/app/etc/synOTR.sqlite "$sSQLupdate"
|
|
fi
|
|
fi
|
|
|
|
TVDB_TOKEN=$(sqlite3 "${APPDIR}/app/etc/synOTR.sqlite" "SELECT TOKEN FROM tvdb WHERE rowid=1")
|
|
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo "TVDB_TOKEN: $TVDB_TOKEN"
|
|
fi
|
|
|
|
serietitletmp="${serietitle}"
|
|
echo -e ;
|
|
|
|
TVDB_seriesquery()
|
|
{
|
|
echo -n "Abfrage [$serietitletmp] an theTVDB.com ==> "
|
|
# URL-Encoding für String (https://de.wikipedia.org/wiki/URL-Encoding):
|
|
serieTitleQuery=`echo "$serietitletmp" | sed "s/_s_/%27s_/g ; s/ s /%27s /g ; s/ /%20/g ; s/_/%20/g ; s/Ä/%C3%84/g ; s/ä/%C3%A4/g ; s/Ö/%C3%96/g ; s/ö/%C3%B6/g ; s/Ü/%C3%9C/g ; s/ü/%C3%BC/g ; s/ß/%C3%9F/g" | sed s/"("/%28/ | sed s/")"/%29/ ` # | sed 's/"("/%28/;s/")"/%29/' ` #| sed "s/\)/%29/g" | sed "s/\+/%2B/g" `
|
|
|
|
# Ä %C3%84
|
|
# ä %C3%A4
|
|
# Ö %C3%96
|
|
# ö %C3%B6
|
|
# Ü %C3%9C
|
|
# ü %C3%BC
|
|
# ß %C3%9F
|
|
restore_ENV # für curl unter ARMv7
|
|
TVDB_FilmID=`curl $cURLloglevel -X GET --header 'Accept: application/json' --header "Accept-Language: $TVDBlang" --header "Authorization: Bearer $TVDB_TOKEN" "https://api.thetvdb.com/search/series?name=$serieTitleQuery" ` #| jq '.data[].id' | sed "s/\"//g" | sed -n '1{p;q}' ` #| awk '{print $1}' ` #TVDB_FilmID=`echo "$TVDB_FilmID" | jq '.data[].id' | sed "s/\"//g" ` # ` #| tr -d '"' `
|
|
synOTR_ENV
|
|
|
|
if echo "$TVDB_FilmID" | egrep -q "Connection timed out"; then
|
|
echo "Serverfehler (Zeitüberschreitung)"
|
|
fi
|
|
}
|
|
|
|
TVDB_episodequery()
|
|
{
|
|
TVDB_SerieName=` echo "$TVDB_FilmID" | jq '.data[].seriesName' | sed "s/\"//g" | sed -n '1{p;q}' | sed "s/://g ; s/\?//g ; s/\*//g" ` # nur das erste Ergebnis wählen
|
|
echo "$TVDB_SerieName"
|
|
title="$TVDB_SerieName" # verwende erkannten Serientitel als Filmtitel
|
|
TVDB_FilmID=` echo "$TVDB_FilmID" | jq '.data[].id' | sed "s/\"//g" | sed -n '1{p;q}'`
|
|
|
|
if [[ `echo "$TVDB_FilmID" | grep [[:digit:]]` ]]; then # Test, ob Ergebnis eine Zahl ist / gültiges Ergebnis
|
|
echo -e "Serie auf theTVDB.com gefunden - TVDB_FilmID: $TVDB_FilmID"
|
|
restore_ENV # für curl unter ARMv7
|
|
episodeninfo=`curl $cURLloglevel -X GET --header 'Accept: application/json' --header "Accept-Language: $TVDBlang" --header "Authorization: Bearer $TVDB_TOKEN" "https://api.thetvdb.com/series/$TVDB_FilmID/episodes/query?airedSeason=0$season&airedEpisode=0$episode" `
|
|
synOTR_ENV
|
|
if echo "$episodeninfo" | egrep -q "Connection timed out"; then
|
|
echo "Serverfehler (Zeitüberschreitung)"
|
|
fi
|
|
if jq -e . >/dev/null 2>&1 <<<"$episodeninfo"; then
|
|
episodetitle=` echo $episodeninfo | jq '.data[].episodeName' | sed "s/\"//g ; s/://g ; s/\?//g ; s/\*//g ; s/\?//g ; s/\///g" ` # | tr -d '"' `
|
|
description=` echo $episodeninfo | jq '.data[].overview' | sed "s/\"//g" ` # | tr -d '"' `
|
|
else
|
|
echo "Serverantwort konnte nicht verarbeitet werden (kein kompatibles JSON)"
|
|
fi
|
|
if [ -z "$episodetitle" ] || [ "$episodetitle" == "null" ] ; then
|
|
echo -e "Die Serie wurde zwar auf theTVDB.com gefunden, allerdings keine passende Episode!"
|
|
episodetitle=""
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo "Abfrageergebnis: $episodeninfo"
|
|
fi
|
|
fi
|
|
missSeries=0
|
|
wget --timeout=30 --tries=2 $wgetloglevel -O - "http://${synotrdomain}/synOTR/synOTR_FILECOUNT_TVDB" >/dev/null 2>&1
|
|
else
|
|
echo -e "Keine Serieninformationen auf theTVDB.com gefunden."
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo "Abfrageergebnis: $TVDB_FilmID"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
TVDB_seriesquery
|
|
|
|
if echo "$TVDB_FilmID" | egrep -q "request|Error"; then # modifiziere die Abfrage (u.a. Großbuchstaben zusammenziehen)
|
|
echo "Keine Serieninformationen auf theTVDB.com gefunden."
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo "Abfrageergebnis: $TVDB_FilmID"
|
|
fi
|
|
# einzelnstehende Großbuchstaben zusammenziehen / Unterstriche ersetzen:
|
|
serietitletmp=`echo $serietitletmp | sed 's/__/ - /g ; s/_/ /g ; s/ //g' | sed -e "s/ \([A-Z][a-z]\)/§tmp§\1/g ; s/\([A-Z]\) \([a-z]\)/\1§tmp§\2/g ; s/\([A-Z]\) /\1/g ; s/§tmp§/ /g ; s/[[:space:]]\{1,\}/ /g"`
|
|
# Wenn Groß-klein, setze immer §tmp§ davor; s/ \([A-Z][a-z]\)/§tmp§\1/g
|
|
# Wenn Groß-Leerzeichen-klein, ersetze Leerzeichen durch §tmp§; s/\([A-Z]\) \([a-z]\)/\1§tmp§\2/g
|
|
# Entferne alle Leerzeichen nach Großbuchstaben; s/\([A-Z]\) /\1/g
|
|
# Ersetze alle §tmp§ durch Leerzeichen; s/§tmp§/ /g
|
|
# Ersetze alle doppelten Leerzeichen durch je ein einziges; s/[[:space:]]\{1,\}/ /g
|
|
|
|
TVDB_seriesquery
|
|
|
|
if echo "$TVDB_FilmID" | egrep -q "request|Error"; then # versuche es mit Umlauten und Punkten zwischen einzeln stehenden Großbuchstaben
|
|
echo "Keine Serieninformationen auf theTVDB.com gefunden."
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo "Abfrageergebnis: $TVDB_FilmID"
|
|
fi
|
|
# einzelnstehende Großbuchstaben mit Punkt trennen / Unterstriche ersetzen / Umlaute wiederherstellen (Umlautersetzung nur nach einem Konsonanten):
|
|
serietitletmp=`echo "${serietitle}" | sed 's/__/ - /g ; s/_/ /g ; s/ //g' | sed -e "s/\<ue/ü/g ; s/\<ae/ä/g ; s/\<oe/ö/g ; s/\<UE/Ü/g ; s/\<AE/Ä/g ; s/\<OE/Ö/g ; s/\([BCDFGHJKLMNPQRSTVWXYZ]\)\(ae\)/\1ä/g ; s/\([BCDFGHJKLMNPQRSTVWXYZ]\)\(ue\)/\1ü/g ; s/\([BCDFGHJKLMNPQRSTVWXYZ]\)\(oe\)/\1ö/g ; s/\([bcdfghjklmnpqrstvwxyz]\)\(oe\)/\1ö/g ; s/\([bcdfghjklmnpqrstvwxyz]\)\(ue\)/\1ü/g ; s/\([bcdfghjklmnpqrstvwxyz]\)\(ae\)/\1ä/g ; s/\([BCDFGHJKLMNPQRSTVWXYZ]\)\(AE\)/\1Ä/g ; s/\([BCDFGHJKLMNPQRSTVWXYZ]\)\(OE\)/\1Ö/g ; s/\([BCDFGHJKLMNPQRSTVWXYZ]\)\(UE\)/\1Ü/g" | sed -e "s/ \([A-Z][a-z]\)/§tmp§\1/g ; s/\([A-Z]\) \([a-z]\)/\1\. \2/g ; s/\([A-Z]\) /\1\./g ; s/§tmp§/ /g ; s/[[:space:]]\{1,\}/ /g" | sed -f ${APPDIR}/includes/textersetzung.txt`
|
|
# ersetze alle großen UE (> Ü) nach einem großen Konsonaten s/\([BCDFGHJKLMNPQRSTVWXYZ]\)\(UE\)/\1Ü/g
|
|
# ersetze alle UE am Anfang der Zeile s/^UE/Ü/g
|
|
# > ersetzt durch: \< (= Anfang jedes Wortes) s/\<UE/Ü/g
|
|
|
|
TVDB_seriesquery
|
|
|
|
if echo $TVDB_FilmID | egrep -q "request|Error" ; then # versuche es mit dem OTR-Metadatentitel
|
|
echo "Keine Serieninformationen auf theTVDB.com gefunden."
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo "Abfrageergebnis: $TVDB_FilmID"
|
|
fi
|
|
if [ ! -z "$OTRtitle" ] && [ ! "$OTRtitle" == "null" ] ; then
|
|
serietitletmp="$OTRtitle"
|
|
TVDB_seriesquery
|
|
|
|
if echo "$TVDB_FilmID" | egrep -q "request|Error"; then
|
|
echo "Keine Serieninformationen auf theTVDB.com gefunden."
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo "Abfrageergebnis: $TVDB_FilmID"
|
|
fi
|
|
else
|
|
TVDB_episodequery
|
|
fi
|
|
fi
|
|
else
|
|
TVDB_episodequery
|
|
fi
|
|
else
|
|
TVDB_episodequery
|
|
fi
|
|
else
|
|
TVDB_episodequery
|
|
fi
|
|
}
|
|
|
|
|
|
OTRserien_query()
|
|
{
|
|
#########################################################################################
|
|
# Diese Funktion sucht nach Serieninformationen #
|
|
# VIELEN DANK AN Daniel Dieth VON www.otr-serien.de #
|
|
#########################################################################################
|
|
|
|
serieninfo=$(wget --timeout=60 --tries=2 -q -O - "http://www.otr-serien.de/myapi/reverseotrkeycheck.php?otrkey=$originalfilename&who=synOTR" )
|
|
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo " http://www.otr-serien.de/myapi/reverseotrkeycheck.php?otrkey=$originalfilename&who=synOTR" ; echo -e
|
|
echo "Rückgabewert von otr-serien.de ==>"; echo " $serieninfo" ; echo -e # Erfolglosmeldung Serieninfo: <!DOCTYPE html> Keine Serien zuordnung vorhanden
|
|
fi
|
|
|
|
serieninfo="{ ${serieninfo#*\{}" # 2018-02-13 Rückgabe von otr-serien.de wurde scheinbar geändert (vorgelagerte Infos vor jason-Container > werden jetzt abgeschnitten)
|
|
# Zeichenkorrektur:
|
|
serieninfo=`echo $serieninfo | sed "s/<!DOCTYPE html>//g" | sed -f ${APPDIR}/includes/decode.sed `
|
|
OTRID=`echo "$serieninfo" | awk -F, '{print $1}' | awk -F: '{print $2}' | sed "s/\"//g"`
|
|
|
|
#echo "$serieninfo"
|
|
if echo "$serieninfo" | grep -q "Keine Serien zuordnung vorhanden"; then
|
|
missSeries=1 # Trigger für fehlende Serieninformation in SQLite-DB
|
|
echo -e "kein Suchergebnis"
|
|
elif echo "$serieninfo" | grep -q "Kein OTR DB Eintrag vorhanden"; then
|
|
missSeries=1 # Trigger für fehlende Serieninformation in SQLite-DB
|
|
echo -e "Film konnte von OTRserien nicht identifiziert werden (wahrscheinlich wurde der Film manuell umbenannt) --> Standardumbenennung wird verwendet"
|
|
# elif echo "$serieninfo" | grep -q "Diese Datei ist nicht verfügbar"; then
|
|
# missSeries=1 # Trigger für fehlende Serieninformation in SQLite-DB
|
|
# echo -e "nicht vorhanden (vom Server gesperrt!)"
|
|
elif [ -z "$serieninfo" ] ; then
|
|
echo -e ">>> Keine Serverantwort <<<"
|
|
#elif [ ! -z "$serieninfo" ] ; then # ist nicht zuverlässig < 2018-06-14
|
|
elif [[ "$OTRID" =~ $regInt ]]; then # Ist die OTR-Id eine echte Zahl?
|
|
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:"
|
|
# Zeichenkorrektur:
|
|
# serieninfo=`echo $serieninfo | sed "s/<!DOCTYPE html>//g" | sed 's/\\\u00e4/ä/g' | sed 's/\\\u00f6/ö/g' | sed 's/\\\u00c4/Ä/g' | sed 's/\\\u00d6/Ö/g' | sed 's/\\\u00fC/ü/g' | sed 's/\\\u00dC/Ü/g' | sed 's/\\\u00dF/ß/g' `
|
|
# serieninfo=`echo $serieninfo | sed "s/<!DOCTYPE html>//g" | sed -f ${APPDIR}/includes/decode.sed `
|
|
# OTRID=`echo "$serieninfo" | awk -F, '{print $1}' | awk -F: '{print $2}' | sed "s/\"//g"`
|
|
|
|
missSeries=0 # Trigger für fehlende Serieninformation in SQLite-DB
|
|
serietitle=`echo "$serieninfo" | jq -r '.Serie' | sed "s/://g" `
|
|
season=`echo "$serieninfo" | awk -F, '{print $3}' | awk -F: '{print $2}' | sed "s/\"//g"`
|
|
season="$(printf '%02d' "$season")" # 2stellig mit führender Null
|
|
episode=`echo "$serieninfo" | awk -F, '{print $4}' | awk -F: '{print $2}' | sed "s/\"//g"`
|
|
episode="$(printf '%02d' "$episode")" # 2stellig mit führender Null
|
|
episodetitle=`echo "$serieninfo" | jq -r '.Folgenname' | sed "s/\"//g ; s/://g ; s/\?//g ; s/\*//g ; s/\?//g ; s/\///g" `
|
|
description=`echo "$serieninfo" | jq -r '.Folgenbeschreibung' | sed "s/:/ -/g" `
|
|
wget --timeout=30 --tries=2 -q -O - "http://${synotrdomain}/synOTR/synOTR_FILECOUNT_OTRSERIEN" >/dev/null 2>&1
|
|
else
|
|
# "Failed to parse JSON, or got false/null"
|
|
missSeries=1 # Trigger für fehlende Serieninformation in SQLite-DB
|
|
echo -e "Serverantwort konnte nicht verarbeitet werden (kein kompatibles JSON)"
|
|
fi
|
|
else
|
|
missSeries=1 # Trigger für fehlende Serieninformation in SQLite-DB
|
|
echo -e "unbekannter Fehler …"
|
|
fi
|
|
}
|
|
|
|
|
|
OTRdecoder()
|
|
{
|
|
#########################################################################################
|
|
# Diese Funktion dekodiert heruntergeladene otrkey-Dateien #
|
|
#########################################################################################
|
|
|
|
AC3ReMux ()
|
|
{
|
|
#########################################################################################
|
|
# Diese Funktion ersetzt die MP3-Audiospur durch eine heruntergeladene AC3-Audiospur #
|
|
#########################################################################################
|
|
|
|
filetest=`find "$DECODIR" -maxdepth 1 -name "*.ac3" -type f`
|
|
if [ ! -z "$filetest" ] ; then
|
|
echo -e ; echo -e
|
|
echo "==> integriere AC3-Audiospur:"
|
|
if [ $OTRcutactiv = "on" ] && [ "$SMARTRENDERING" != "on" ] ; then
|
|
echo " Bei aktiviertem Schneiden ist die AC3-Tonspurintegration nur in Verbindung mit aktiviertem Smartrendering möglich."
|
|
else
|
|
echo " (Bitte beachte: die AC3-Funktion hat experimentellen Charakter."
|
|
echo " Es gibt immer wieder Filme, wo es nicht 100% passt, bzw. es zu Problemen kommt.)"
|
|
|
|
IFS=$'\012'
|
|
for i in $(find "$DECODIR" -maxdepth 1 -name "*.ac3" -type f)
|
|
do
|
|
IFS=$OLDIFS
|
|
ac3filename=`basename "$i"`
|
|
videosource=`find "$DECODIR" -maxdepth 1 -name "${ac3filename%.HD*}*" -type f -and ! -name "*.ac3" -type f`
|
|
videosourcefilename=`basename "$videosource"`
|
|
videosourcetitle=${videosourcefilename%.*}
|
|
|
|
muxerror=0 # nur für Log
|
|
if [ -f "${DECODIR}/${videosourcetitle}.avi" ]; then
|
|
echo -e; echo "MUXING: ---> ${ac3filename}" #; echo -e
|
|
muxingLOG=$($ffmpeg -threads 2 -loglevel $ffloglevel -i "${DECODIR}/${videosourcetitle}.avi" -i "$i" -map 0:0 -map 1:0 -c:a copy -async 1 -c:v copy -sn -y "${DECODIR}/${videosourcetitle}.ac3tmp.avi" 2>&1)
|
|
|
|
if [ -f "${DECODIR}/${videosourcetitle}.ac3tmp.avi" ]; then
|
|
# Original löschen / umbenennen:
|
|
if [ $endgueltigloeschen = "on" ] ; then
|
|
rm "$i"
|
|
rm "${DECODIR}/${videosourcetitle}.avi"
|
|
else
|
|
mv "$i" "$OTRkeydeldir"
|
|
mv "${DECODIR}/${videosourcetitle}.avi" "${OTRkeydeldir}/${videosourcetitle}.mp3.avi"
|
|
fi
|
|
mv "${DECODIR}/${videosourcetitle}.ac3tmp.avi" "${DECODIR}/${videosourcetitle}.avi"
|
|
echo " L==> fertig"
|
|
wget --timeout=30 --tries=2 -q -O - "http://${synotrdomain}/synOTR/synOTR_FILECOUNT_AC3" >/dev/null 2>&1
|
|
needindex=1
|
|
else
|
|
echo " L==> muxen fehlgeschlagen [Datei im Zielverzeichnis nicht gefunden …]"; echo -e
|
|
echo "muxingLOG: $muxingLOG"
|
|
muxerror=1
|
|
fi
|
|
else
|
|
echo " > keine passende Videodatei gefunden!"
|
|
fi
|
|
if [ $LOGlevel = "2" ] && [ $muxerror = "0" ] ; then
|
|
echo "LogLevelinfo:"
|
|
echo "muxingLOG: $muxingLOG"
|
|
fi
|
|
done
|
|
sleep 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
filetest=`find "${OTRkeydir}" -maxdepth 1 -name "*.otrkey" -mmin +"$timediff" -type f`
|
|
|
|
if [ $decoderactiv = "on" ] && [ ! -z "$filetest" ] ; then
|
|
echo -e ;
|
|
echo "==> decodieren:"
|
|
OTRkeydir="${OTRkeydir%/}/"
|
|
|
|
IFS=$'\012' # entspricht einem $'\n' Newline
|
|
for i in $(find "${OTRkeydir}" -maxdepth 1 -name "*.otrkey" -mmin +"$timediff" -type f)
|
|
do
|
|
IFS=$OLDIFS
|
|
echo -e
|
|
filename=`basename "$i"`
|
|
decofilename=${filename%.*}
|
|
echo " DECODIERE: ---> $filename"
|
|
echo -n " "; date
|
|
|
|
if [ $machinetyp = "x86_64" ]; then
|
|
if [ "$(synogetkeyvalue /etc.defaults/VERSION buildnumber)" -ge 60000 ]; then
|
|
# verwende passenden Decoder ab DSM7.2:
|
|
otrdecoderLOG=$(otrdecoder64_72 -q -i "$i" -o "$DECODIR" -e "$OTRuser" -p "$OTRpw" 2>&1)
|
|
else
|
|
otrdecoderLOG=$(otrdecoder64 -q -i "$i" -o "$DECODIR" -e "$OTRuser" -p "$OTRpw" 2>&1)
|
|
fi
|
|
elif [ $machinetyp = "i686" ]; then
|
|
otrdecoderLOG=$(otrdecoder32 -q -i "$i" -o "$DECODIR" -e "$OTRuser" -p "$OTRpw" 2>&1)
|
|
elif [ `echo $machinetyp | grep "armv" ` ] ; then
|
|
otrdecoderLOG=$(otrpidecoder -d "$i" -O "${DECODIR}/${decofilename}" -e "$OTRuser" -p "$OTRpw" 2>&1)
|
|
fi
|
|
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo "OTRdecoder LOG: $otrdecoderLOG"
|
|
fi
|
|
if echo $otrdecoderLOG | grep -q "No connection to server" ; then
|
|
echo -e; echo " ! ! ! OTRDecoder konnte keine Verbindung zum OTR-Server aufbauen. Datei wird übersprungen." # behält Quellvideo
|
|
echo -e; echo "OTRdecoder LOG:"; echo "$otrdecoderLOG"
|
|
continue ;
|
|
else
|
|
if [ -f "${DECODIR}/$decofilename" ]; then # nur löschen, wenn erfolgreich decodiert:
|
|
if [ $endgueltigloeschen = "on" ] ; then
|
|
rm "$i"
|
|
else
|
|
mv "$i" "$OTRkeydeldir"
|
|
fi
|
|
|
|
ffprobeSourceInfo=$(ffprobe -v quiet -print_format json -show_format -show_streams "${DECODIR}/$decofilename" 2>&1)
|
|
# ffprobeSourceInfo=$(ffprobe -v quiet -print_format json -show_format -show_streams -show_programs "${DECODIR}/$decofilename" 2>&1)
|
|
# Errormeldung vor jason ab DSM 6.2 (wird hier abgeschnitten): ERROR:
|
|
# ld.so: object 'openhook.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored. { …
|
|
ffprobeSourceInfo="{ ${ffprobeSourceInfo#*\{}"
|
|
|
|
OTRtitle=`echo "$ffprobeSourceInfo" | jq '.format.tags.title' | sed "s/\" //g" | sed "s/\"//g" | sed "s/'/''/g" | sed "s/\"//g" | uconv -f utf-8 -t utf-8 -x NFC `
|
|
OTRcomment=`echo "$ffprobeSourceInfo" | jq '.format.tags.comment' | sed "s/\" //g" | sed "s/\"//g" | sed "s/'/''/g" | sed "s/\"//g" | uconv -f utf-8 -t utf-8 -x NFC `
|
|
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo -e; echo " ------------------------->"
|
|
echo " OTRtitle: > $OTRtitle"
|
|
echo " OTRcomment: > $OTRcomment"
|
|
echo -n " Datenbank schreiben ==> "
|
|
fi
|
|
|
|
sSQL="INSERT INTO raw ( file_original, OTRtitle, OTRcomment) VALUES ('$decofilename', '$OTRtitle', '$OTRcomment')"
|
|
# leider werden Umlaute und Sonderzeichen nicht korrekt codiert … !
|
|
sqlite3 ${APPDIR}/app/etc/synOTR.sqlite "$sSQL"
|
|
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo " sSQL: $sSQL"
|
|
echo "fertig"; echo " <-------------------------"
|
|
fi
|
|
echo " L==> fertig"
|
|
else
|
|
echo " L==> decodieren fehlgeschlagen [Datei im Zielverzeichnis nicht gefunden …]"; echo -e
|
|
echo "OTRdecoder LOG: $otrdecoderLOG"
|
|
continue
|
|
fi
|
|
|
|
if [ $lastjob -eq 1 ] && [ $useWORKDIR == "no" ] ; then
|
|
# füge Datei dem Index der Videostation hinzu:
|
|
synoindex -a "${DECODIR}/${decofilename}"
|
|
if [ $dsmtextnotify = "on" ] ; then
|
|
sleep 1
|
|
synodsmnotify $MessageTo "synOTR" "$filename ist fertig"
|
|
sleep 1
|
|
fi
|
|
if [ $dsmbeepnotify = "on" ] ; then
|
|
sleep 1
|
|
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
|
|
fi
|
|
done
|
|
elif [ $decoderactiv = "off" ] ; then
|
|
echo -e ; echo -e ; echo "==> decodieren ist deaktiviert"
|
|
fi
|
|
sleep 1
|
|
|
|
AC3ReMux
|
|
|
|
}
|
|
|
|
|
|
OTRautocut()
|
|
{
|
|
#########################################################################################
|
|
# Diese Funktion schneidet die Filme anhand einer lokalen Cutlist, oder #
|
|
# einer automatisch auf cutlist.at gefundenen Cutlist #
|
|
# #
|
|
# #
|
|
# #
|
|
# Die meisten Cut-Funktionen stammen ursprünglich von: #
|
|
# Author: Daniel Siegmanski #
|
|
# Homepage: http://www.siggimania4u.de #
|
|
# OtrCut Download: http://otrcut.siggimania4u.de #
|
|
# Source github.com: https://github.com/adlerweb/otrcut.sh/blob/master/otrcut.sh #
|
|
#########################################################################################
|
|
|
|
IFS=$'\012'
|
|
|
|
filetest=`find "$DECODIR" -maxdepth 1 -name "*.avi" -o -name "*.mp4" -type f`
|
|
|
|
#if [ $OTRavi2mp4active = "on" ] && [ ! -z "$filetest" ] ; then
|
|
if [ -z "$filetest" ] ; then
|
|
return
|
|
fi
|
|
|
|
if [ $OTRcutactiv = "on" ] ; then
|
|
echo -e ; echo -e
|
|
# Es wird geprüft, ob SmartRendering mit avcut überhaupt
|
|
# möglich ist, sonst Fallback auf avisplit:
|
|
# ---------------------------------------------------------------------
|
|
avisplitpath=`which avisplit`
|
|
if [ ! -f "$avcut" ] && [ "$SMARTRENDERING" = "on" ] ; then # ist avcut vorhanden?
|
|
SMARTRENDERING="off"
|
|
echo "Smartrendierung (framegenaues Schneiden) nicht möglich, da das Programm \"avcut\" fehlt."
|
|
fi
|
|
|
|
if [ ! -f "$avisplitpath" ] && [ "$SMARTRENDERING" != "on" ] ; then
|
|
echo "avisplit wurde nicht gefunden - Schneiden wird übersprungen!"; echo "Installiere Transcode via iPKG/oPKG"; echo -e
|
|
break
|
|
else
|
|
echo "==> schneiden:"
|
|
|
|
if [ ${RAMmax} -lt 490 ]; then
|
|
SMARTRENDERING="off"
|
|
echo "Für das framegenaue Schneiden wird mindestens 500 MB installierter RAM benötigt ($RAMmax MB installiert)."
|
|
echo "Smartrendering wird aufgrund fehlenden Arbeitsspeichers deaktivert"
|
|
echo "Es wird mit der herkömmlichen Methode (avisplit) geschnitten."; echo -e
|
|
fi
|
|
|
|
tmp="${APPDIR}/app/tmp"
|
|
server="http://cutlist.at/"
|
|
|
|
AC_test ()
|
|
{
|
|
# Diese Funktion überprüft verschiedene Einstellungen:
|
|
# ---------------------------------------------------------------------
|
|
if [ -d "$tmp/otrcut" ] && [ -w "$tmp" ]; then
|
|
AC_testLOG="Verwende $tmp/otrcut als tmp-Ausgabeordner."
|
|
tmp="$tmp/otrcut"
|
|
elif [ -d "$tmp" ] && [ ! -w "$tmp" ]; then
|
|
AC_testLOG="Sie haben keine Schreibrechte in $tmp!"
|
|
fi
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo "$AC_testLOG"
|
|
fi
|
|
}
|
|
|
|
AC_ffprobe ()
|
|
{
|
|
# Diese Funktion ließt via ffprobe Dateiinformationen aus:
|
|
# ---------------------------------------------------------------------
|
|
AC_ffprobeInfo=$(ffprobe -v quiet -print_format json -show_format -show_streams "$i" 2>&1)
|
|
|
|
# Errormeldung vor jason ab DSM 6.2 (wird hier abgeschnitten):
|
|
# ERROR:
|
|
# ld.so: object 'openhook.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored. { …
|
|
AC_ffprobeInfo="{ ${AC_ffprobeInfo#*\{}"
|
|
}
|
|
|
|
AC_check_software ()
|
|
{
|
|
# Steht die 'date'-Funktion zum Umrechnen der Cuts zur Verfügung?:
|
|
# ---------------------------------------------------------------------
|
|
# Hier wird ueberprueft ob date zum umrechnen der Zeit benutzt werden kann
|
|
date_varLOG="Überpruefe welche Methode zum Umrechnen der Zeit benutzt wird --> "
|
|
date_var=$(date -u -d @120 +%T 2>/dev/null)
|
|
if [ "$date_var" == "00:02:00" ]; then
|
|
date_okay=yes
|
|
date_varLOG="${date_varLOG} date"
|
|
else
|
|
date_okay=no
|
|
date_varLOG="${date_varLOG} date"
|
|
fi
|
|
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo "$date_varLOG"
|
|
fi
|
|
}
|
|
|
|
AC_name ()
|
|
{
|
|
# DIESE FUNKTION WIRD GERADE AUFGEGÄUMT …
|
|
|
|
|
|
# Diese Funktion definiert den Cutlist- und Dateinamen
|
|
# und üperprüft um welches Dateiformat es sich handelt:
|
|
# ---------------------------------------------------------------------
|
|
film="$i" # Der komplette Filmname und gegebenfalls der Pfad
|
|
film_ohne_anfang="$i"
|
|
AC_nameLOG="Überprüfe um welches Aufnahmeformat es sich handelt --> "
|
|
|
|
|
|
# ToDo: Variablen streichen / vereinheitlichen:
|
|
# film_ohne_anfang > nur hier
|
|
# film_ohne_ende > nur hier und in Rename auskommentiert
|
|
# filmname > nur hier
|
|
# format > nur hier im Sinn von Qualität
|
|
|
|
|
|
if echo "$film_ohne_anfang" | grep -q ".HQ."; then #Wenn es sich um eine "HQ" Aufnahme handelt
|
|
film_ohne_ende=${film%%.mpg.HQ.avi} # Filmname ohne Dateiendung
|
|
CUTLIST=${CUTLIST/.avi/}.cutlist # Der lokale Cutlistname
|
|
# format=hq
|
|
AC_nameLOG="${AC_nameLOG}HQ"
|
|
elif echo "$film_ohne_anfang" | grep -q ".mp4"; then #Wenn es sich um eine "mp4" Aufnahme handelt
|
|
film_ohne_ende=${film%%.mpg.mp4} # Filmname ohne Dateiendung
|
|
# format=mp4
|
|
CUTLIST=${CUTLIST/.mp4/}.cutlist # Der lokale Cutlistname
|
|
AC_nameLOG="${AC_nameLOG}mp4"
|
|
else
|
|
film_ohne_ende=${film%%.mpg.avi} # Filmename ohne Dateiendung
|
|
# format=avi
|
|
CUTLIST=${CUTLIST/.avi/}.cutlist # Der lokale Cutlistname
|
|
AC_nameLOG="${AC_nameLOG}avi"
|
|
fi
|
|
|
|
if echo "$film" | grep / >> /dev/null; then # Wenn der Dateiname einen Pfad enthält
|
|
film_ohne_anfang=${film##*/} # Filmname ohne Pfad
|
|
if echo "$film_ohne_anfang" | grep -q ".HQ."; then #Wenn es sich um eine "HQ" Aufnahme handelt
|
|
film_ohne_ende=${film_ohne_anfang%%.mpg.HQ.avi}
|
|
# format=hq
|
|
elif echo "$film_ohne_anfang" | grep -q ".mp4"; then #Wenn es sich um eine "mp4" Aufnahme handelt
|
|
film_ohne_ende=${film_ohne_anfang%%.mpg.mp4}
|
|
# format=mp4
|
|
else
|
|
film_ohne_ende=${film_ohne_anfang%%.mpg.avi}
|
|
# format=avi
|
|
fi
|
|
fi
|
|
|
|
if echo "$film_ohne_anfang" | grep -q ".HQ."; then
|
|
outputfile="${WORKDIR}$film_ohne_ende.HQ-cut.avi"
|
|
# outputfile="${WORKDIR}$film_ohne_ende.mpg.HQ-cut.avi"
|
|
elif echo "$film_ohne_anfang" | grep -q ".mp4"; then
|
|
outputfile="${WORKDIR}$film_ohne_ende-cut.mp4"
|
|
# outputfile="${WORKDIR}$film_ohne_ende.mpg-cut.mp4"
|
|
else
|
|
outputfile="${WORKDIR}$film_ohne_ende-cut.avi"
|
|
# outputfile="${WORKDIR}$film_ohne_ende.mpg-cut.avi"
|
|
fi
|
|
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo "$AC_nameLOG"
|
|
fi
|
|
}
|
|
|
|
AC_getlocalcutlist_CheckedVersion () # Nicht aktiv
|
|
{
|
|
#In dieser Funktion wird die lokale Cutlist überprüft:
|
|
# ---------------------------------------------------------------------
|
|
local_cutlists=$(ls *.cutlist 2>/dev/null) #Variable mit allen Cutlists in $PWD
|
|
match_cutlists="" ## passende Cutlisten zum Film
|
|
filesize=$(ls -l "$film" | awk '{ print $5 }') #Dateigröße des Filmes
|
|
goodCount=0 #Passende Cutlists
|
|
arraylocal=1 #Nummer des Arrays
|
|
for f in $local_cutlists; do
|
|
echo -n "Überprüfe ob eine der gefundenen Cutlists zum Film passt --> "
|
|
if [ -z $f ]; then
|
|
echo -e "Keine Cutlist gefunden!"
|
|
vorhanden=no
|
|
continue=1
|
|
fi
|
|
|
|
OriginalFileSize=$(cat $f | grep OriginalFileSizeBytes | cut -d"=" -f2 | /usr/bin/tr -d "\r") #Dateigröße des Films
|
|
|
|
if cat $f | grep -q "$film"; then #Wenn der Dateiname mit ApplyToFile übereinstimmt
|
|
echo -e -n "ApplyToFile "
|
|
ApplyToFile=yes
|
|
vorhanden=yes
|
|
fi
|
|
if [ "$OriginalFileSize" == "$filesize" ]; then #Wenn die Dateigröße mit OriginalFileSizeBytes übereinstimmt
|
|
echo -e -n "OriginalFileSizeBytes"
|
|
OriginalFileSizeBytes=yes
|
|
vorhanden=yes
|
|
fi
|
|
if [ "$vorhanden" == "yes" ]; then #Wenn eine passende Cutlist vorhanden ist
|
|
goodCount=$(( goodCount + 1 ))
|
|
namelocal[$arraylocal]="$f"
|
|
arraylocal=$(( arraylocal + 1 ))
|
|
continue=0
|
|
else
|
|
echo -e "false"
|
|
fi
|
|
done
|
|
|
|
if [ "$goodCount" -eq 1 ]; then #Wenn nur eine Cutlist gefunden wurde
|
|
echo "Es wurde eine passende Cutlist gefunden. Diese wird nun verwendet."
|
|
CUTLIST="$f"
|
|
cp "$CUTLIST" "$tmp"
|
|
elif [ "$goodCount" -gt 1 ]; then #Wenn mehrere Cutlists gefunden wurden
|
|
echo "Es wurden $goodCount Cutlists gefunden. Bitte wählen Sie aus:"
|
|
echo ""
|
|
number=1
|
|
|
|
for (( i=1; i <= $goodCount ; i++ )); do
|
|
echo "$number: ${namelocal[$number]}"
|
|
number=$(( number + 1 ))
|
|
done
|
|
|
|
echo -n "Bitte die Nummer der zu verwendenden Cutlist eingeben:"
|
|
read NUMBER
|
|
|
|
while [ "$NUMBER" -gt "$goodCount" ]; do
|
|
echo "false. Noch mal:"
|
|
read NUMBER
|
|
done
|
|
|
|
echo "Verwende ${namelocal[$NUMBER]} als Cutlist."
|
|
CUTLIST=$namelocal[$NUMBER]
|
|
cp "$CUTLIST" "$tmp"
|
|
vorhanden=yes
|
|
fi
|
|
}
|
|
|
|
AC_getlocalcutlist_withCheck ()
|
|
{
|
|
# In dieser Funktion wird die lokale Cutlist überprüft (Input von Stafan Weiss)
|
|
# Diese Methode greift, sobald die Variable '$OTRlocalcutlistdir' (in der Konfiguration.txt) gesetzt wurde:
|
|
# ---------------------------------------------------------------------
|
|
pushd "$OTRlocalcutlistdir" >> /dev/null
|
|
filmOhnePfad=`basename "$film"`
|
|
local_cutlists=$(ls *.cutlist 2>/dev/null) # Variable mit allen Cutlists in $PWD
|
|
filesize=$(ls -l "$film" | awk '{ print $5 }') # Dateigröße des Filmes
|
|
vorhanden=no # nehme erstmal an, es wurde keine Cutlist gefunden
|
|
continue=1
|
|
ApplyToFile=no
|
|
OriginalFileSizeBytes=no
|
|
|
|
if [ -z "$local_cutlists" ]; then
|
|
echo -e "Keine lokale Cutlist gefunden!"
|
|
else
|
|
echo "okey"
|
|
echo -e "(localcutlistdir mit Prüfung ist aktiviert)"
|
|
echo -e "Überprüfe ob eine der lokalen Cutlists zum Film passt:"
|
|
|
|
for f in $local_cutlists; do
|
|
echo -e -n "File: $f"
|
|
OriginalFileSize=$(cat $f | grep OriginalFileSizeBytes | cut -d"=" -f2 | /usr/bin/tr -d "\r") #Dateigröße des Films
|
|
if cat $f | grep -q "$filmOhnePfad"; then # Wenn der Dateiname mit ApplyToFile übereinstimmt
|
|
echo -e -n " ApplyToFile passt."
|
|
ApplyToFile=yes
|
|
fi
|
|
if [ "$OriginalFileSize" == "$filesize" ]; then # Wenn die Dateigröße mit OriginalFileSizeBytes übereinstimmt
|
|
echo -e -n " OriginalFileSizeBytes passt."
|
|
OriginalFileSizeBytes=yes
|
|
fi
|
|
if [ "$ApplyToFile" == "yes" ] || [ "$OriginalFileSizeBytes" = "yes" ]; then # Wenn eine passende Cutlist vorhanden ist
|
|
echo
|
|
vorhanden=yes
|
|
continue=0
|
|
break;
|
|
else
|
|
echo -e " passt nicht."
|
|
vorhanden=no
|
|
continue=1
|
|
fi
|
|
done
|
|
|
|
if [ "$vorhanden" == "yes" ]; then
|
|
echo "Es wurde eine passende Cutlist gefunden. Diese wird nun verwendet."
|
|
CUTLIST="$f"
|
|
cp "$CUTLIST" "$tmp"
|
|
fi
|
|
fi
|
|
popd >> /dev/null
|
|
}
|
|
|
|
AC_getlocalcutlist_withoutCheck ()
|
|
{
|
|
#In dieser Funktion wird die lokale Cutlist ohne Prüfung gewählt (Standard):
|
|
# ---------------------------------------------------------------------
|
|
echo -n "Lade LOCALCUTLIST ${LOCAL_CUTLIST} --> "
|
|
cp "${LOCAL_CUTLIST}" "$tmp"
|
|
CUTLIST="${filename}.cutlist"
|
|
continue=0
|
|
UseLocalCutlist="yes"
|
|
cutlist_okay=yes # wird hier ohne Prüfung angenommen
|
|
|
|
if [ -f "${tmp}/$CUTLIST" ] && [ "$cutlist_okay" == "yes" ]; then
|
|
echo -e "okay"
|
|
echo "Es wird eine lokale Cutlist verwendet"
|
|
echo -e
|
|
continue=0
|
|
cp "${tmp}/$CUTLIST" "${DECODIR}/_LOGsynOTR/${CUTLIST}"
|
|
vorhanden="yes"
|
|
else
|
|
echo -e "false"
|
|
echo "Es wurde zwar eine lokale Cutlist gefunden, aber leider wurde ein Fehler festgestellt"
|
|
continue=1
|
|
fi
|
|
}
|
|
|
|
AC_getcutlist ()
|
|
{
|
|
#In dieser Funktion wird versucht eine Cutlist aus den Internet zu laden
|
|
# ---------------------------------------------------------------------
|
|
|
|
AC_test_cutlist ()
|
|
{
|
|
#In dieser Funktion wird geprüft, ob die geladene Cutlist okay ist
|
|
# ---------------------------------------------------------------------
|
|
cutlist_size=$(ls -l "$tmp/$CUTLIST" | awk '{ print $5 }')
|
|
if [ "$cutlist_size" -lt "100" ]; then
|
|
cutlist_okay=no
|
|
echo "Die Cutlist scheint beschädigt zu sein"
|
|
if [ -f "$tmp/$CUTLIST" ]; then
|
|
rm -f "$tmp/$CUTLIST"
|
|
fi
|
|
return 1
|
|
else
|
|
cutlist_okay=yes
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
parseXmlTag ()
|
|
{
|
|
#In dieser Funktion wird der gesucht Parameter einer XML-Zeile zurückgegeben
|
|
# ---------------------------------------------------------------------
|
|
sed -n '/<\/'$1'>/p' "$tmp/search.xml" | sed -n ''$2'p' | sed 's/<'$1'>//' | sed 's/<\/'$1'>//g' | sed 's/^[ \t]*//'
|
|
}
|
|
|
|
continue=0
|
|
filesize=$(ls -l "$film" | awk '{ print $5 }')
|
|
filesizeMB=$(echo | gawk '{print '$filesize'/1000000}' | awk '{printf "%.2f\n", $1}')
|
|
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo "Dateigröße: $filesize Byte / $filesizeMB MB"
|
|
fi
|
|
|
|
echo -n "Suche anhand des Dateinamens ---> "
|
|
wget -U "synOTR/$CLIENTVERSION" --timeout=30 --tries=2 $wgetloglevel -O "$tmp/search.xml" "${server}getxml.php?name=$filename"
|
|
|
|
if [ $? -eq 0 ] && grep -q '<id>' "$tmp/search.xml"; then
|
|
echo -e "okay"
|
|
else
|
|
echo "Keine Cutlist anhand des Namens gefunden!"
|
|
echo -n "Suche anhand der Dateigröße ---> "
|
|
wget -U "synOTR/$CLIENTVERSION" --timeout=30 --tries=2 $wgetloglevel -O "$tmp/search.xml" "${server}getxml.php?ofsb=$filesize"
|
|
|
|
if [ $? -eq 0 ] && grep -q '<id>' "$tmp/search.xml"; then
|
|
echo -e "okay"
|
|
else
|
|
echo -e "Keine Cutlist anhand der Dateigröße gefunden!"
|
|
if [ "$useallcutlistformat" == "1" ]; then
|
|
# es werden Cutlists für andere Qualitäten gesucht.
|
|
echo -n "Suche alternatives Cutlistformat ---> "
|
|
search=$(echo $filename | sed 's/.avi//g' | sed 's/.mpg//g' | sed 's/.HQ//g' | sed 's/.HD//g' | sed 's/.mp4//g' | sed 's/.ac3//g' | sed 's/DivFix++.//g' | sed 's/DivFix.//g' )
|
|
wget -U "synOTR/$CLIENTVERSION" --timeout=30 --tries=2 $wgetloglevel -O "$tmp/search.xml" "${server}getxml.php?name=$search"
|
|
|
|
if ([ $? -eq 0 ] && grep -q '<id>' "$tmp/search.xml") && ( grep -q '<withtime>1</withtime>' "$tmp/search.xml" ); then # Aufgrund der unterschiedlichen Frameraten, werde derzeit nur Cutlists mit Zeitangaben verwendet
|
|
useonlytimecuts=1
|
|
echo -e "okay (eine alternative Cutlist kann ungenaue Schnitte erzeugen!)"
|
|
else
|
|
echo -e "Kein alternatives Cutlistformat gefunden!"
|
|
continue=1
|
|
fi
|
|
else
|
|
continue=1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Hier wird die Suchanfrage überprüft
|
|
if [ "$continue" == "1" ]; then
|
|
echo -e " L==> Es wurde leider keine Cutlist gefunden!"
|
|
else
|
|
sed -i 's/<rating><\/rating>/<rating>0.00<\/rating>/g' "$tmp/search.xml" # fehlendes rating durch 0.00 ersetzen / -i ändert die Quelldatei
|
|
sed -i $'s/\r$//' "$tmp/search.xml" # convert Dos to Unix
|
|
|
|
cutlist_anzahl=$(grep --text -c '/cutlist' "$tmp/search.xml" | /usr/bin/tr -d "\r")
|
|
|
|
echo -e
|
|
echo "Anzahl gefunden: $cutlist_anzahl"
|
|
|
|
array=0
|
|
|
|
if [ "$cutlist_anzahl" -ge "1" ] ; then # Wenn Cutlists gefunden wurden
|
|
# schreibe ratings in je ein array:
|
|
tail=1
|
|
unset rating;
|
|
unset ratingbyauthor;
|
|
while [ "$cutlist_anzahl" -gt "0" ]; do
|
|
# XML-Parsing über Funktion => macht ab dem 2. Film Probleme bei dem array "ratingbyauthor"
|
|
ratingbyauthor[$array]=$(parseXmlTag "ratingbyauthor" $tail )
|
|
rating[$array]=$(parseXmlTag "rating" $tail )
|
|
|
|
# direktes XML-Parsing:
|
|
#rating[$array]=$(grep --text "<rating>" "$tmp/search.xml" | cut -d">" -f2 | cut -d"<" -f1 | tail -n$tail | head -n1 | /usr/bin/tr -d "\r")
|
|
#ratingbyauthor[$array]=$(grep --text "<ratingbyauthor>" "$tmp/search.xml" | cut -d">" -f2 | cut -d"<" -f1 | tail -n$tail | head -n1 | /usr/bin/tr -d "\r")
|
|
|
|
tail=$((tail + 1))
|
|
cutlist_anzahl=$((cutlist_anzahl - 1))
|
|
array=$(( array + 1))
|
|
array1=array
|
|
done
|
|
|
|
# Sortieren / größten Wert ermitteln:
|
|
IFS=$'\n' # den `Internal Field Separator` so verändern, dass Felder nur noch durch Zeilenumbrüche (und nicht zusätzlich durch Leerzeichen) getrennt werden.
|
|
maxuserrating=$(echo "${rating[*]}" | sort -nr | head -n1)
|
|
maxautorrating=$(echo "${ratingbyauthor[*]}" | sort -nr | head -n1)
|
|
IFS=$OLDIFS
|
|
|
|
echo "Max-Userrating: ${maxuserrating}"
|
|
echo "Max-Autorrating: ${maxautorrating}"
|
|
|
|
if [[ "$maxuserrating" == "0" ]] || [[ "$maxuserrating" == "0.00" ]] || [[ -z "$maxuserrating" ]]; then
|
|
echo "Auswahl aufgrund: Autorbewertung"
|
|
maxrating=$maxautorrating
|
|
ratingsource=fromautor
|
|
cutlist_nummer=$(grep --text "<ratingbyauthor>" "$tmp/search.xml" | grep -n "<ratingbyauthor>${maxautorrating}" | cut -d: -f1 | head -n1 )
|
|
#echo " cutlist-nummer: $cutlist_nummer"
|
|
else
|
|
echo "Auswahl aufgrund: Benutzerbewertung"
|
|
maxrating=$maxuserrating
|
|
ratingsource=fromuser
|
|
cutlist_nummer=$( grep --text "<rating>" "$tmp/search.xml" | grep -n "<rating>${maxuserrating}" | cut -d: -f1 | head -n1 )
|
|
#echo " cutlist-nummer: $cutlist_nummer"
|
|
fi
|
|
|
|
#id=$(grep --text "<id>" "$tmp/search.xml" | head -n$cutlist_nummer | tail -n1 | cut -d">" -f2 | cut -d"<" -f1) # ID der best bewertetsten Cutlist
|
|
id=$(parseXmlTag "id" $cutlist_nummer)
|
|
#downloadcount=$(grep --text "<downloadcount>" "$tmp/search.xml" | head -n$cutlist_nummer | tail -n1 | cut -d">" -f2 | cut -d"<" -f1)
|
|
downloadcount=$(parseXmlTag "downloadcount" $cutlist_nummer)
|
|
#autor=$(grep --text "<author>" "$tmp/search.xml" | head -n$cutlist_nummer | tail -n1 | cut -d">" -f2 | cut -d"<" -f1)
|
|
autor=$(parseXmlTag "author" $cutlist_nummer)
|
|
#CUTLIST=$(grep --text "<name>" "$tmp/search.xml" | head -n$cutlist_nummer | tail -n1 | cut -d">" -f2 | cut -d"<" -f1)
|
|
CUTLIST=$(parseXmlTag "name" $cutlist_nummer)
|
|
# CUTLIST=$(grep --text "<name>" "$tmp/search.xml" | cut -d">" -f2 | cut -d"<" -f1 | head -n$cutlist_nummer | tail -n1 | /usr/bin/tr -d "\r") # Name der Cutlist
|
|
#usercomment=$(grep --text "<usercomment>" "$tmp/search.xml" | head -n$cutlist_nummer | tail -n1 | cut -d">" -f2 | cut -d"<" -f1)
|
|
usercomment=$(parseXmlTag "usercomment" $cutlist_nummer)
|
|
SuggestedMovieName=$(parseXmlTag "filename" $cutlist_nummer)
|
|
|
|
if [ "$useonlytimecuts" == "1" ]; then
|
|
if [ ! $(parseXmlTag "withtime" $cutlist_nummer) == "1" ]; then
|
|
# ToDo:
|
|
# werden in der best bewertetsten Cutlist keine Zeit-Cuts gefunden, wird derzeit nicht in der nächst best bewertetsten gesucht
|
|
# durch eine zusätzliche Umrechnung der Cuts von Frame auf Zeit könnten noch mehr alternative Cutlists gefunden werden
|
|
echo "Die alternative Cutlist basiert auf Frameangaben und kann daher nicht ohne Umrechnung verwendet werden."
|
|
continue=1
|
|
fi
|
|
fi
|
|
|
|
if [ -z "$autor" ]; then
|
|
autorinfo=""
|
|
else
|
|
autorinfo=" / Autor: ${autor}"
|
|
fi
|
|
|
|
# Benachrichtigung / LOG-Info erstellen:
|
|
if [ "$ratingsource" = "fromuser" ]; then
|
|
ratingcount=$(grep --text "<ratingcount>" "$tmp/search.xml" | head -n$cutlist_nummer | tail -n1 | cut -d">" -f2 | cut -d"<" -f1)
|
|
cutlistinfo="Bewertungdetails: ${ratingcount}x bewertet / ${downloadcount}x geladen${autorinfo}"
|
|
else
|
|
cutlistinfo="Bewertungdetails: ${downloadcount}x geladen${autorinfo}"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
if [ "$toprated" == "yes" ] && [ "$continue" == "0" ]; then
|
|
echo "Autor-Kommentar: $usercomment"
|
|
echo "SuggestedMovieName: $SuggestedMovieName"
|
|
echo "$cutlistinfo"
|
|
echo -e
|
|
if [ $LOGlevel = "1" ] || [ $LOGlevel = "2" ] ; then
|
|
cp "$tmp/search.xml" "${DECODIR}/_LOGsynOTR/search_${filename}.xml"
|
|
fi
|
|
fi
|
|
|
|
if [ "$continue" == "0" ]; then
|
|
if [ $(echo -n "$cutlistat_ID" | wc -c) -ne 64 ] || [ "$useonlytimecuts" == "1" ] ; then # auch alternative Cutlisten ohne Userangaben laden, da eine Bewertung schlecht objektiv möglich ist
|
|
server_tmp="${server}"
|
|
if [ $(echo -n "$cutlistat_ID" | wc -c) -ne 64 ]; then
|
|
echo "ACHTUNG: deine Cutlist-ID ($cutlistat_ID) ist ungültig!"
|
|
fi
|
|
else
|
|
server_tmp="${server}${cutlistat_ID}/"
|
|
fi
|
|
|
|
echo -n "Lade $CUTLIST (ID: $id) --> "
|
|
|
|
wget --timeout=30 --tries=2 $wgetloglevel -O "$tmp/$CUTLIST" "${server_tmp}getfile.php?id=$id"
|
|
|
|
if [ $? -eq 0 ] && AC_test_cutlist && [ -f "$tmp/$CUTLIST" ]; then
|
|
echo -e "okay"
|
|
continue=0
|
|
if [ $LOGlevel = "1" ] || [ $LOGlevel = "2" ] ; then
|
|
cp "$tmp/$CUTLIST" "${DECODIR}/_LOGsynOTR/${CUTLIST}"
|
|
fi
|
|
|
|
# ------------------ ID der verwendeten Cutlist speichern:
|
|
sSQL="SELECT rowid FROM raw WHERE file_original LIKE '${filename}%' ORDER BY rowid DESC LIMIT 1"
|
|
sqlerg=`sqlite3 -separator $'\t' ${APPDIR}/app/etc/synOTR.sqlite "$sSQL"`
|
|
rowid=`echo "$sqlerg" | awk -F'\t' '{print $1}' `
|
|
sSQL="UPDATE raw SET cutlist_ID='$id' WHERE rowid='$rowid'"
|
|
sqlite3 ${APPDIR}/app/etc/synOTR.sqlite "$sSQL"
|
|
else
|
|
echo -e "false"
|
|
continue=1
|
|
fi
|
|
fi
|
|
|
|
}
|
|
|
|
AC_get_CutlistFormat ()
|
|
{
|
|
#Hier wird überprüft um welches Cutlist-Format es sich handelt (Zeit / Frames)
|
|
# ---------------------------------------------------------------------
|
|
echo -n "Format der Cuts: "
|
|
if cat "$tmp/$CUTLIST" | grep "Start=" >> /dev/null; then
|
|
echo -e "Zeit"
|
|
format=zeit
|
|
elif cat "$tmp/$CUTLIST" | grep "StartFrame=" >> /dev/null; then
|
|
echo -e "Frames"
|
|
format=frames
|
|
else
|
|
echo -e "false"
|
|
echo -e "Wahrscheinlich wurde das Limit von '$server' überschritten!"
|
|
continue=1
|
|
fi
|
|
}
|
|
|
|
AC_cutlist_error ()
|
|
{
|
|
#Hier wir die Cutlist überprüft, auf z.B. EPGErrors, MissingEnding, MissingVideo, ...
|
|
# ---------------------------------------------------------------------
|
|
IFS=$OLDIFS
|
|
# Diese Variable beinhaltet alle möglichen Fehler
|
|
errors="EPGError MissingBeginning MissingEnding MissingVideo MissingAudio OtherError"
|
|
for e in $errors; do
|
|
error_check=$(cat "$tmp/$CUTLIST" | grep -m1 $e | cut -d"=" -f2 | /usr/bin/tr -d "\r")
|
|
if [ "$error_check" == "1" ]; then
|
|
echo -e ; echo -e "! ! ! [CUTLIST-INFO] Es wurde ein Fehler gefunden: \"$e\""
|
|
error_yes=$e
|
|
if [ "$error_yes" == "OtherError" ]; then
|
|
othererror=$(cat "$tmp/$CUTLIST" | grep "OtherErrorDescription")
|
|
othererror=${othererror##*=}
|
|
echo -e "Grund für \"OtherError\": \"$othererror\""
|
|
fi
|
|
if [ "$error_yes" == "EPGError" ]; then
|
|
epgerror=$(cat "$tmp/$CUTLIST" | grep "ActualContent")
|
|
epgerror=${epgerror##*=}
|
|
echo -e "ActualContent: $epgerror"
|
|
fi
|
|
error_found=1
|
|
cutlistWithError="${cutlistWithError} $id"
|
|
fi
|
|
done
|
|
IFS=$'\012'
|
|
}
|
|
|
|
AC_get_fps ()
|
|
{
|
|
# Hier wird geprüft, welche Bildrate der Film hat.
|
|
# ---------------------------------------------------------------------
|
|
echo -n "Framerate des Films: "
|
|
fps=""
|
|
|
|
rframerate_1=`echo "$AC_ffprobeInfo" | jq '.streams[0].r_frame_rate' | sed "s/\"//g" | awk -F '/' '{print $1}'`
|
|
rframerate_2=`echo "$AC_ffprobeInfo" | jq '.streams[0].r_frame_rate' | sed "s/\"//g" | awk -F '/' '{print $2}'`
|
|
fps=$(echo | gawk '{print '$rframerate_1'/'$rframerate_2'}')
|
|
|
|
if [ "$fps" == "" ]; then #Wenn fps nicht per ffprobe gelesen werden konnte
|
|
fps=`cat "$tmp/$CUTLIST" | grep "FramesPerSecond=" | sed "s/FramesPerSecond\=//g" | /usr/bin/tr -d "\r" ` #| awk -F. '{print $1}'`
|
|
echo "${fps}fps [Quelle: Cutlist]"
|
|
else
|
|
echo "${fps}fps [Quelle: ffprobe]"
|
|
fi
|
|
}
|
|
|
|
AC_cutlist_seriencheck ()
|
|
{
|
|
# Hier wird geprüft, ob in der Cutlist Serieninfos zu finden sind und schreibt diese ggf. in die DB
|
|
# -------------------------------------------------------------------------------------------------
|
|
parseRegex ()
|
|
{
|
|
# NICHT MEHR BENUTZT ! ! !
|
|
|
|
# In dieser Funktion wird der mit einem regulären Ausdruck beschriebene Teilstring zurückgegeben
|
|
# Aufruf: parseRegex "string" "regex"
|
|
# https://stackoverflow.com/questions/5536018/how-to-print-matched-regex-pattern-using-awk
|
|
# --------------------------------------------------------------
|
|
echo "$1" | awk '{
|
|
for(i=1; i<=NF; i++) {
|
|
tmp=match($i, /'"${2}"'/)
|
|
if(tmp) {
|
|
print $i
|
|
}
|
|
}
|
|
}'
|
|
}
|
|
|
|
# ToDo: entweder auf Titel beschränken, oder RegEx nicht auf Ende ($) beschränken! > gesamte Prüfung auskommentiert / vorhandene Daten werden eh priorisiert
|
|
# if ! echo "$filename" | grep -q "S[0-9][0-9]E[0-9][0-9]$" ; then # nur weiter, wenn im Dateinamen keine Infos gefunden wurden
|
|
SuggestedMovieName=""
|
|
usercomment=""
|
|
CL_serieninfofound=0
|
|
SuggestedMovieName=`cat "$tmp/$CUTLIST" | grep "SuggestedMovieName=" | sed "s/SuggestedMovieName\=//g;s/[0-9]\{2,4\}[.][0-9]\{1,2\}[.][0-9]\{1,2\}[ _][0-9]\{2\}[\-][0-9]\{2\}/Datum_Zeit/g;s/[0-9]\{2,4\}[.][0-9]\{1,2\}[.][0-9]\{1,2\}/Datum/g;s/_/ /g" | /usr/bin/tr -d "\r" ` #| awk -F. '{print $1}'` # Datum, Zeit im OTR-Format und Unterstriche werden entfernt
|
|
usercomment=`cat "$tmp/$CUTLIST" | grep "UserComment=" | sed "s/UserComment\=//g;s/[0-9]\{2,4\}[.][0-9]\{1,2\}[.][0-9]\{1,2\}[ _][0-9]\{2\}[\-][0-9]\{2\}/Datum_Zeit/g;s/[0-9]\{2,4\}[.][0-9]\{1,2\}[.][0-9]\{1,2\}/Datum/g;s/_/ /g" | /usr/bin/tr -d "\r" ` #| awk -F. '{print $1}'`
|
|
|
|
if echo "$SuggestedMovieName" | grep -q "[sST]\?[0-9]\{1,2\}[.\-xX]\?[eE]\?[0-9]\{1,2\}" ; then # [[:space:]] # S01E01 / S01.E01 / 01-01 / 01x01 / teilweise ohne führende Null
|
|
#CL_serieninfo=$(parseRegex "$SuggestedMovieName" ".[sST]?[0-9]{1,2}[.\-xX]?[eE]?[0-9]{1,2}" | head -n1) # head -n1: nur der erste Fund im String wird verwendet
|
|
CL_serieninfo=$(echo "$SuggestedMovieName" | egrep -o "[sST]?[0-9]{1,2}[.\-xX]?[eE]?[0-9]{1,2}" | head -n1)
|
|
CL_serieninfo_season=$(echo "$CL_serieninfo" | awk '{print toupper($0) }' | sed "s/S/ /g;s/T/ /g;s/E/ /g;s/X/ /g;s/-/ /g;s/\./ /g;s/ / /g" | awk '{print $1}')
|
|
CL_serieninfo_episode=$(echo "$CL_serieninfo" | awk '{print toupper($0) }' | sed "s/S/ /g;s/T/ /g;s/E/ /g;s/X/ /g;s/-/ /g;s/\./ /g;s/ / /g" | awk '{print $2}')
|
|
CL_serieninfofound=1
|
|
elif echo "$usercomment" | grep -q "[sST]\?[0-9]\{1,2\}[.\-xX]\?[eE]\?[0-9]\{1,2\}" ; then
|
|
#CL_serieninfo=$(parseRegex "$usercomment" "[sST]?[0-9]{1,2}[.\-xX]?[eE]?[0-9]{1,2}" | head -n1)
|
|
CL_serieninfo=$(echo "$usercomment" | egrep -o "[sST]?[0-9]{1,2}[.\-xX]?[eE]?[0-9]{1,2}" | head -n1)
|
|
CL_serieninfo_season=$(echo "$CL_serieninfo" | awk '{print toupper($0) }' | sed "s/S/ /g;s/T/ /g;s/E/ /g;s/X/ /g;s/-/ /g;s/\./ /g;s/ / /g" | awk '{print $1}')
|
|
CL_serieninfo_episode=$(echo "$CL_serieninfo" | awk '{print toupper($0) }' | sed "s/S/ /g;s/T/ /g;s/E/ /g;s/X/ /g;s/-/ /g;s/\./ /g;s/ / /g" | awk '{print $2}')
|
|
CL_serieninfofound=1
|
|
fi
|
|
|
|
if [[ $CL_serieninfofound = 1 ]] && [[ "$CL_serieninfo_season" =~ $regInt ]] && [[ "$CL_serieninfo_episode" =~ $regInt ]]; then
|
|
echo "Serieninfo aus Cutlist: S${CL_serieninfo_season}E${CL_serieninfo_episode}"
|
|
# ------------------ schreibe Serieninformation in DB:
|
|
sSQL="UPDATE raw SET miss_series='0', serie_season='$CL_serieninfo_season', serie_episode='$CL_serieninfo_episode' WHERE file_original='$filename'"
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo "sSQL Serieninfo: $sSQL"
|
|
fi
|
|
sqlite3 ${APPDIR}/app/etc/synOTR.sqlite "$sSQL"
|
|
fi
|
|
# fi
|
|
|
|
}
|
|
|
|
AC_time1 ()
|
|
{
|
|
#Hier wird nun die Zeit ins richtige Format für avisplit umgerechnet
|
|
# ---------------------------------------------------------------------
|
|
time=""
|
|
cut_anzahl=$(cat "$tmp/$CUTLIST" | grep "NoOfCuts" | cut -d"=" -f2 | /usr/bin/tr -d "\r")
|
|
echo -e
|
|
echo "---- Cuts ----"
|
|
if [ "$format" == "zeit" ]; then #Wenn das verwendete Format "Zeit" ist
|
|
head1=1
|
|
echo "Es müssen $cut_anzahl Cuts umgerechnet werden."
|
|
while [ "$cut_anzahl" -gt "0" ]; do
|
|
#Die Sekunde in der der Cut beginnen soll
|
|
time_seconds_start=$(cat "$tmp/$CUTLIST" | grep "Start=" | cut -d"=" -f2 | head -n$head1 | tail -n1 | cut -d"." -f1 | /usr/bin/tr -d "\r")
|
|
echo "Startcut: $time_seconds_start. Sekunde"
|
|
time=${time}$(date -u -d @$time_seconds_start +%T-) #Die Sekunden umgerechned in das Format hh:mm:ss
|
|
#Wie viele Sekunden der Cut dauert
|
|
time_seconds_ende=$(cat "$tmp/$CUTLIST" | grep "Duration=" | cut -d"=" -f2 | head -n$head1 | tail -n1 | cut -d"." -f1 | /usr/bin/tr -d "\r")
|
|
time_seconds_ende=$(( time_seconds_ende + time_seconds_start )) #Die Sekunde in der der Cut endet
|
|
echo "Endcut: $time_seconds_ende. Sekunde"
|
|
time=${time}$(date -u -d @$time_seconds_ende +%T,) #Die Endsekunde im Format hh:mm:ss
|
|
head1=$(( head1 + 1 ))
|
|
cut_anzahl=$(( cut_anzahl - 1 ))
|
|
#In der Variable $time sind alle Cuts wie folgt aufgelistet:
|
|
#hh:mm:ss-hh:mm:ss,hh:mm:ss-hh:mm:ss,...
|
|
#$time: 00:00:59-00:26:25,00:34:12-00:51:34,00:59:42-01:05:12,
|
|
done
|
|
elif [ "$format" == "frames" ]; then #Wenn das verwendete Format "Frames" ist
|
|
head1=1
|
|
echo "Es müssen $cut_anzahl Cuts umgerechnet werden."
|
|
while [ $cut_anzahl -gt 0 ]; do
|
|
#Der Frame bei dem der Cut beginnt
|
|
startframe=$(cat "$tmp/$CUTLIST" | grep "StartFrame=" | cut -d= -f2 | head -n$head1 | tail -n1 | /usr/bin/tr -d "\r")
|
|
echo "Startframe= $startframe"
|
|
time="${time}$startframe-"
|
|
#Wie viele Frames dauert der Cut
|
|
stopframe=$(cat "$tmp/$CUTLIST" | grep "DurationFrames=" | cut -d= -f2 | head -n$head1 | tail -n1 | /usr/bin/tr -d "\r")
|
|
stopframe=$(( stopframe + startframe )) # Der Frame bei dem der Cut endet
|
|
echo "Endframe= $stopframe"
|
|
time="${time}$stopframe," #Auflistung alles Cuts
|
|
head1=$(( head1 + 1 ))
|
|
cut_anzahl=$(( cut_anzahl - 1 ))
|
|
done
|
|
fi
|
|
|
|
echo "---- ENDE ----" ; echo -e
|
|
sleep 1
|
|
}
|
|
|
|
AC_time2 ()
|
|
{
|
|
# Hier wird nun die Zeit ins richtige Format für avisplit umgerechnet,
|
|
# falls die date-Variante nicht funktioniert (fällt bald weg …)
|
|
# ---------------------------------------------------------------------
|
|
time=""
|
|
cut_anzahl=$(cat "$tmp/$CUTLIST" | grep "NoOfCuts" | cut -d= -f2 | /usr/bin/tr -d "\r")
|
|
echo -e
|
|
echo "---- Cuts ----"
|
|
if [ $format == "zeit" ]; then
|
|
head1=1
|
|
echo "Es müssen $cut_anzahl Cuts umgerechnet werden"
|
|
while [ $cut_anzahl -gt 0 ]; do
|
|
#Die Sekunde in der der Cut startet
|
|
time_seconds_start=$(cat "$tmp/$CUTLIST" | grep "Start=" | cut -d= -f2 | head -n$head1 | tail -n1 | cut -d"." -f1 | /usr/bin/tr -d "\r")
|
|
ss=$time_seconds_start # Setze die Skunden auf $time_seconds_start
|
|
mm=0 # Setze die Minuten auf 0
|
|
hh=0 # Setze die Stunden auf 0
|
|
while [ $ss -ge "60" ]; do # Wenn die Sekunden >= 60 sind
|
|
mm=$(( mm + 1)) # Zaehle Minuten um 1 hoch
|
|
ss=$(( ss - 60)) # Zaehle Sekunden um 60 runter
|
|
while [ $mm -ge "60" ]; do # Wenn die Minuten >= 60 sind
|
|
hh=$(( hh + 1 )) # Zaehle Stunden um 1 hoch
|
|
mm=$(( mm - 60 )) # Zaehle Minuten um 60 runter
|
|
done
|
|
done
|
|
time2_start=$hh:$mm:$ss # Bringe die Zeit ins richtige Format
|
|
echo "Startcut= $time2_start"
|
|
time="${time}${time2_start}-" # Auflistung aller Zeiten
|
|
#Sekunden wie lange der Cut dauert
|
|
time_seconds_ende=$(cat "$tmp/$CUTLIST" | grep "Duration=" | cut -d= -f2 | head -n$head1 | tail -n1 | cut -d"." -f1 | /usr/bin/tr -d "\r")
|
|
time_seconds_ende=$time_seconds_ende+$time_seconds_start #Die Sekunde in der der Cut endet
|
|
ss=$time_seconds_ende # Setze die Sekunden auf $time_seconds_ende
|
|
mm=0 # Setze die Minuten auf 0
|
|
hh=0 # Setze die Stunden auf 0
|
|
while [ $ss -ge "60" ]; do # Wenn die Sekunden >= 60 sind
|
|
mm=$(( mm + 1 )) # Zaehle Minuten um 1 hoch
|
|
ss=$(( ss - 60 )) # Zaehle Sekunden um 60 runter
|
|
while [ $mm -ge "60" ]; do # Wenn die Minuten >= 60 sind
|
|
hh=$(( hh + 1 )) # Zaehle Stunden um 1 hoch
|
|
mm=$(( mm - 60 )) # Zaehle Minuten um 60 runter
|
|
done
|
|
done
|
|
time2_ende=$hh:$mm:$ss # Bringe die Zeit ins richtige Format
|
|
echo "Endcut= $time2_ende"
|
|
time="${time}${time2_ende}," # Auflistung alles Zeiten
|
|
head1=$(( head1 + 1 ))
|
|
cut_anzahl=$(( cut_anzahl - 1 ))
|
|
done
|
|
elif [ $format == "frames" ]; then
|
|
head1=1
|
|
echo "Es müssen $cut_anzahl Cuts umgerechnet werden"
|
|
while [ $cut_anzahl -gt 0 ]; do
|
|
# Der Frame bei dem der Cut beginnt
|
|
startframe=$(cat "$tmp/$CUTLIST" | grep "StartFrame=" | cut -d= -f2 | head -n$head1 | tail -n1 | /usr/bin/tr -d "\r")
|
|
echo "Startframe= $startframe"
|
|
time="${time}$startframe-" # Auflistung der Cuts
|
|
# Die Frames wie lange der Cut dauert
|
|
stopframe=$(cat "$tmp/$CUTLIST" | grep "DurationFrames=" | cut -d= -f2 | head -n$head1 | tail -n1 | /usr/bin/tr -d "\r")
|
|
stopframe=$(( stopframe + startframe)) # Der Frame bei dem der Cut endet
|
|
echo "Endframe= $stopframe"
|
|
time="${time}$stopframe," # Auflistung der Cuts
|
|
head1=$(( head1 + 1 ))
|
|
cut_anzahl=$(( cut_anzahl - 1 ))
|
|
done
|
|
fi
|
|
echo "---- ENDE ----" ; echo -e
|
|
sleep 1
|
|
}
|
|
|
|
AC_time3 ()
|
|
{
|
|
# Hier wird nun die Zeit ins richtige Format für avcut umgerechnet
|
|
# ---------------------------------------------------------------------
|
|
time="0 "
|
|
framediff=$(echo | gawk '{print 1/'${fps}'}') # Zeitdifferenz für genau 1 Frame, da avcut mit Zeitwerten arbeitet
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo "Zeitdifferenz für genau 1 Frame für die manuelle Cutlistkorrektur für avcut: $framediff"
|
|
echo "FrameversatzAnfangCut: $FrameversatzAnfangCut"
|
|
echo "FrameversatzEndeCut: $FrameversatzEndeCut"
|
|
fi
|
|
cut_anzahl=$(cat "$tmp/$CUTLIST" | grep "NoOfCuts" | cut -d"=" -f2 | /usr/bin/tr -d "\r")
|
|
echo -e
|
|
echo "---- Cuts ----"
|
|
if [ "$format" == "zeit" ]; then # Wenn das verwendete Format "Zeit" ist
|
|
head1=1
|
|
echo "Es müssen $cut_anzahl Cuts für avcut umgerechnet werden."
|
|
while [ "$cut_anzahl" -gt "0" ]; do
|
|
# Die Zeit, bei der der Cut beginnt
|
|
time_seconds_start=$(cat "$tmp/$CUTLIST" | grep "Start=" | cut -d"=" -f2 | head -n$head1 | tail -n1 | /usr/bin/tr -d "\r" )
|
|
time_seconds_start=$(echo | gawk '{print '$time_seconds_start'+('$FrameversatzAnfangCut'*'$framediff')}')
|
|
echo "Startcut: $time_seconds_start Sekunden"
|
|
time="${time}${time_seconds_start} "
|
|
# Wie viele Sekunden der Cut dauert
|
|
time_seconds_ende=$(cat "$tmp/$CUTLIST" | grep "Duration=" | cut -d"=" -f2 | head -n$head1 | tail -n1 | /usr/bin/tr -d "\r" )
|
|
time_seconds_ende=$(echo | gawk '{print '$time_seconds_ende'+'$time_seconds_start'+('$FrameversatzEndeCut'*'$framediff')}')
|
|
echo "Endcut: $time_seconds_ende Sekunden"
|
|
time="${time}${time_seconds_ende} "
|
|
head1=$(( head1 + 1 ))
|
|
cut_anzahl=$(( cut_anzahl - 1 ))
|
|
done
|
|
elif [ "$format" == "frames" ]; then # Wenn das verwendete Format "Frames" ist
|
|
head1=1
|
|
echo "Es müssen $cut_anzahl Cuts für avcut umgerechnet werden."
|
|
while [ $cut_anzahl -gt 0 ]; do
|
|
# Der Frame bei dem der Cut beginnt
|
|
startframe=$(cat "$tmp/$CUTLIST" | grep "StartFrame=" | cut -d= -f2 | head -n$head1 | tail -n1 | /usr/bin/tr -d "\r" )
|
|
echo "Startframe= $startframe"
|
|
startframe=$(( $startframe + $FrameversatzAnfangCut )) # mit manueller Framekorrektur
|
|
time_seconds_start=$(echo | gawk '{print '$startframe'/'$fps'}')
|
|
time="${time}${time_seconds_start} "
|
|
# Wie viele Frames dauert der Cut
|
|
stopframe=$(cat "$tmp/$CUTLIST" | grep "DurationFrames=" | cut -d= -f2 | head -n$head1 | tail -n1 | /usr/bin/tr -d "\r" )
|
|
# Der Frame bei dem der Cut endet
|
|
stopframe=$(( stopframe + startframe + $FrameversatzEndeCut )) # mit manueller Framekorrektur
|
|
echo "Endframe= $stopframe"
|
|
time_seconds_ende=$(echo | gawk '{print '$stopframe'/'$fps'}')
|
|
time="${time}${time_seconds_ende} "
|
|
head1=$(( head1 + 1 ))
|
|
cut_anzahl=$(( cut_anzahl - 1 ))
|
|
done
|
|
fi
|
|
|
|
time="${time}- " # Rest des Films verwerfen
|
|
echo "---- ENDE ----" ; echo -e
|
|
sleep 1
|
|
}
|
|
|
|
AC_split ()
|
|
{
|
|
# Hier wird nun das Video an das Cut-Programm übergeben:
|
|
# ---------------------------------------------------------------------
|
|
IFS=$OLDIFS
|
|
if [ "$SMARTRENDERING" = "on" ]; then
|
|
echo "> Übergebe die Cuts an avcut"
|
|
|
|
# für ARMv7 unterstützt avcut noch nicht die Operanten -i & -o ==> Abhilfe: avcut-0.4 für ARMv7 kompilieren (ohne Nachteil)
|
|
if [ $machinetyp = "x86_64" ] || [ $machinetyp = "i686" ]; then
|
|
AVCUTLOG=$(time $avcut -p "${APPDIR}/includes/avcut_otr.profile" -i "$film" -o "$outputfile" $time 2>&1) # Befehl ausführen
|
|
else
|
|
AVCUTLOG=$(time $avcut "$film" "$outputfile" $time 2>&1) # noch avcut v0.2 mit entsprechender Parameterangabe
|
|
fi
|
|
|
|
echo -e; echo -n "Die Schnittpunkte befinden sich"
|
|
AVCUTPOINTS=`echo "$AVCUTLOG" | grep "cutting points in" | awk -F '"' '{print $3}' | sed -e 's/at: /an diesen Zeitmarken: \n /g' | sed -e 's#s[)] #s\) \n #g'`
|
|
echo -e "$AVCUTPOINTS"
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo "avcut Command: avcut $film $outputfile $time"
|
|
echo "avcut LOG: $AVCUTLOG"
|
|
fi
|
|
else
|
|
echo "> Übergebe die Cuts an avisplit/avimerge"
|
|
AVISPLITLOG=$(avisplit -i "$film" -o "$outputfile" -t $time -c 1>/dev/null) # Hier wird avisplit gestartet, avimerge wird on-the-fly über den Parameter -c gestartet
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo "avisplit Command: avisplit -i $film -o $outputfile -t $time -c"
|
|
echo "avisplit-LOG: $AVISPLITLOG"
|
|
fi
|
|
fi
|
|
|
|
if [ -f "$outputfile" ]; then
|
|
filedestname=`basename $outputfile`
|
|
echo -n " L==> "
|
|
echo -e "$filedestname wurde erstellt"
|
|
if [ $lastjob -eq 2 ] ; then
|
|
if [ $dsmtextnotify = "on" ] ; then
|
|
synodsmnotify $MessageTo "synOTR" "$filedestname ist fertig"
|
|
fi
|
|
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
|
|
|
|
if [ $endgueltigloeschen = "on" ] ; then
|
|
if [ -f "$film" ]; then
|
|
rm "$film"
|
|
fi
|
|
if [ -f "$LOCAL_CUTLIST" ]; then # lokale Cutlist in Downloadordner oder Dekodierordner
|
|
rm "$LOCAL_CUTLIST"
|
|
fi
|
|
|
|
else
|
|
# echo "Verschiebe Quellvideo und Cutlist nach $OTRkeydeldir"
|
|
mv "$film" "$OTRkeydeldir"
|
|
if [ -f "$LOCAL_CUTLIST" ]; then # lokale Cutlist in Downloadordner oder Dekodierordner
|
|
mv "$LOCAL_CUTLIST" "$OTRkeydeldir"
|
|
fi
|
|
fi
|
|
else
|
|
if [ "$SMARTRENDERING" = "on" ]; then
|
|
echo -e "avcut muss einen Fehler verursacht haben."
|
|
else
|
|
echo -e "Avisplit oder avimerge muss einen Fehler verursacht haben."
|
|
fi
|
|
continue=1
|
|
fi
|
|
}
|
|
|
|
AC_del_tmp ()
|
|
{
|
|
#Hier werden nun die temporären Dateien gelöscht
|
|
# ---------------------------------------------------------------------
|
|
if [ "$tmp" == "" ] || [ "$tmp" == "/" ] || [ "$tmp" == "/home" ]; then
|
|
echo -e "Achtung, bitte überprüfe die Einstellung von \$tmp"
|
|
exit 1
|
|
else
|
|
if [ -d "$tmp" ] ; then
|
|
rm -rf "$tmp"/*
|
|
fi
|
|
fi
|
|
}
|
|
|
|
AC_check_software
|
|
|
|
# -----------------------------------------------------------------------
|
|
# Es folgt die eigentliche Schleife zum Abarbeiten der Videos: |
|
|
# -----------------------------------------------------------------------
|
|
for i in $(find "$DECODIR" -maxdepth 1 -name "*.avi" -o -name "*.mp4" -type f)
|
|
do
|
|
error_found=0 # Fehlertrigger zurücksetzen
|
|
continue=0 # Cut-Skript unterbrechen
|
|
array=0
|
|
cutlistWithError="" # Cutlists die, einen Fehler haben auf Null setzen
|
|
toprated=yes # automatisch die Cutlist mit der besten User-Bewertung benutzen?
|
|
format="" # Um welches Format handelt es sich? AVI, HQ, mp4 - hier auf Null setzen
|
|
UseLocalCutlist=no # zurücksetzen
|
|
filename=`basename "$i"`
|
|
vorhanden=no
|
|
useonlytimecuts="" # aus alternativen Cutlists (für anderes Format) sollen nur Zeit-Cuts verwendet werden
|
|
SMARTRENDERINGold=$SMARTRENDERING # bei nicht genügend RAM wird temporär Smartrendering deaktiviert und die ursprüngliche Einstellung hier gespeichert
|
|
|
|
if [ "$SMARTRENDERING" != "on" ]; then # avisplit kann keine mp4-Videos verarbeiten
|
|
if echo "$filename" | grep -q ".mp4"; then
|
|
echo "$filename [.mp4-Datei] kann mit avisplit / avimerge nicht geschnitten werden und wird in Zielordner verschoben. Aktiviere alternativ Smartrendering in den Einstellungen."
|
|
mv "$i" "$WORKDIR"
|
|
continue # nächste Datei
|
|
fi
|
|
fi
|
|
|
|
echo -e ; echo " SCHNEIDE: ---> $filename"
|
|
echo -n " "; date; echo -e
|
|
|
|
AC_ffprobe
|
|
AC_test
|
|
AC_del_tmp
|
|
AC_name
|
|
|
|
if [ "$SMARTRENDERING" = "on" ]; then # Ist genügend RAM zum Schneiden für diese Aufnahme vorhanden?
|
|
PXheight=`echo "$AC_ffprobeInfo" | jq '.streams[0].height' `
|
|
if [ "$PXheight" -ge 700 ] && [ ${RAMmax} -ge 1000 ]; then
|
|
echo "Es ist genügend RAM für HQ und HD-Schnitte vorhanden."; echo -e
|
|
elif [ "$PXheight" -ge 700 ] && [ ${RAMmax} -ge 500 ]; then
|
|
audiocodec=`echo "$AC_ffprobeInfo" | jq '.streams[1].codec_name' | sed "s/\"//g" `
|
|
# Filme mit AC3-Tonspur können nicht mit avisplit geschnitten werden (problemanfällig / endlose Temp-Datei bei mp4box / grobe Asynchronität) und werden ungeschnitten weiterverarbeitet
|
|
if [ $audiocodec = "null" ] || [ $audiocodec = "ac3" ]; then # 'null', da es bereits beim mergen auf kleinen Maschinen zu Problemen kam und die Spur nicht mehr auslesbar war.
|
|
echo "Der Film hat eine AC3-Tonspur und das Gerät verfügt nicht über genügend RAM für Smartrendering (>= 1GB nötig, aber nur $RAMmax MB RAM verfügbar)."
|
|
echo "Der Film wird ungeschnitten weiterverarbeitet."
|
|
mv "$i" "$WORKDIR"
|
|
continue # nächste Datei
|
|
fi
|
|
SMARTRENDERING="off"
|
|
echo "Smartrendering wird für diesen Film vorrübergehend deaktiviert (HD-Film aber nur $RAMmax MB RAM)."
|
|
echo "Avcut benötigt für HD-Filme mindestens 1 GB RAM. Dieser Film wird mit avisplit geschnitten."; echo -e
|
|
fi
|
|
else
|
|
audiocodec=`echo "$AC_ffprobeInfo" | jq '.streams[1].codec_name' | sed "s/\"//g" `
|
|
# Filme mit AC3-Tonspur können nicht mit avisplit geschnitten werden (problemanfällig / endlose Temp-Datei bei mp4box / grobe Asynchronität) und werden ungeschnitten weiterverarbeitet
|
|
if [ $audiocodec = "null" ] || [ $audiocodec = "ac3" ]; then # 'null', da es bereits beim mergen auf kleinen Maschinen zu Problemen kam und die Spur nicht mehr auslesbar war.
|
|
echo "Der Film hat eine AC3-Tonspur und das Gerät verfügt nicht über genügend RAM für Smartrendering (>= 1GB nötig, aber nur $RAMmax MB RAM verfügbar)."
|
|
echo "Der Film wird ungeschnitten weiterverarbeitet."
|
|
mv "$i" "$WORKDIR"
|
|
continue # nächste Datei
|
|
fi
|
|
fi
|
|
|
|
# Es gibt zwei Methoden, um auf lokal vorhandene Cutlist zu testen
|
|
# sollen AC3-Remuxte Filme mit eigener Cutlist geschnitten werden, ist vorzugsweise die Methode 2 zu wählen,
|
|
# d.h. die Variable "OTRlocalcutlistdir" in den Einstellungen nicht zu setzen (weil sich die Filmgröße geändert hat)
|
|
echo -n "Suche nach einer lokalen Cutlist ---> "
|
|
if [ -d "$OTRlocalcutlistdir" ]; then
|
|
# Methode 1:
|
|
# hier werden nur Cutlist verwendet wo Filmgröße und Name übereinstimmen
|
|
# Die Variable OTRlocalcutlistdir mit dem Quellordner der Cutlist muss gesetzt sein
|
|
AC_getlocalcutlist_withCheck
|
|
else
|
|
# Methode 2:
|
|
# es findet keine Prüfung der Cutlist statt
|
|
if [ -f "${i}.cutlist" ]; then # die Cutlist muss sich im Dekodierordner befinden und den gleichen Namen wie der Film haben (inkl. Dateiendung .avi / .mp4 vor .cutlist)
|
|
echo "okey"
|
|
LOCAL_CUTLIST="${i}.cutlist"
|
|
AC_getlocalcutlist_withoutCheck
|
|
elif [ -f "${OTRkeydir}${filename}.cutlist" ]; then # die Cutlist muss sich im Downloadordner / Quellordner befinden und den gleichen Namen wie der Film haben (inkl. Dateiendung .avi / .mp4 vor .cutlist)
|
|
echo "okey"
|
|
LOCAL_CUTLIST="${OTRkeydir}${filename}.cutlist"
|
|
AC_getlocalcutlist_withoutCheck
|
|
else
|
|
echo -e "Keine lokale Cutlist gefunden!"
|
|
fi
|
|
fi
|
|
|
|
if [ "$UseLocalCutlist" == "no" ] || [ "$vorhanden" == "no" ]; then AC_getcutlist ; fi
|
|
if [ "$continue" == "0" ]; then AC_get_CutlistFormat ; fi
|
|
if [ "$continue" == "0" ]; then AC_get_fps ; fi
|
|
if [ "$continue" == "0" ]; then AC_cutlist_seriencheck ; fi
|
|
if [ "$continue" == "0" ] ; then AC_cutlist_error ; fi
|
|
if [ "$error_found" == "1" ] && [ "$UseLocalCutlist" == "no" ] && [ "$toprated" == "yes" ]; then
|
|
#break
|
|
if [ "$WaitOfCutlist" == "off" ]; then
|
|
mv "$i" "${WORKDIR}"
|
|
echo " L=> Film wird ohne Schneiden weiterverarbeitet"
|
|
else
|
|
echo " L=> Film wird übersprungen"
|
|
fi
|
|
continue
|
|
fi
|
|
if [ $continue == "0" ]; then
|
|
if [ "$SMARTRENDERING" = "on" ]; then
|
|
AC_time3
|
|
else
|
|
if [ "$date_okay" = "yes" ]; then
|
|
AC_time1
|
|
elif [ "$date_okay" = "no" ]; then
|
|
AC_time2
|
|
fi
|
|
fi
|
|
AC_split
|
|
else
|
|
if [ "$WaitOfCutlist" == "off" ]; then
|
|
mv "$i" "${WORKDIR}"
|
|
echo " L=> Film wird (entsprechend der Einstellung [WaitOfCutlist=\"off\"] ohne Schneiden weiterverarbeitet"
|
|
fi
|
|
fi
|
|
AC_del_tmp
|
|
continue=0
|
|
|
|
if [ $lastjob -eq 2 ] && [ $useWORKDIR == "no" ] ; then
|
|
# füge Datei dem Index der Videostation hinzu:
|
|
synoindex -a "$outputfile"
|
|
if [ $dsmtextnotify = "on" ] ; then
|
|
title=${filename%.*}
|
|
sleep 1
|
|
synodsmnotify $MessageTo "synOTR" "Film [$title] ist fertig"
|
|
sleep 1
|
|
fi
|
|
if [ $dsmbeepnotify = "on" ] ; then
|
|
sleep 1
|
|
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
|
|
SMARTRENDERING=$SMARTRENDERINGold
|
|
done
|
|
fi
|
|
elif [ $OTRcutactiv = "off" ] ; then
|
|
echo -e ; echo -e ; echo "==> schneiden ist deaktiviert"
|
|
else
|
|
echo "==> Variable für Cutaktivität falsch gesetzt ==> Wert >OTRcutactiv< in den Einstellungen überprüfen!"
|
|
fi
|
|
IFS=$OLDIFS
|
|
sleep 1
|
|
}
|
|
|
|
|
|
OTRavi2mp4()
|
|
{
|
|
#########################################################################################
|
|
# Diese Funktion konvertiert die Filmdateien in das MP4-Format #
|
|
#########################################################################################
|
|
|
|
cd "$WORKDIR"
|
|
|
|
filetest=`find "$WORKDIR" -maxdepth 1 -name "*.avi" -type f`
|
|
|
|
if [ $OTRavi2mp4active = "on" ] && [ ! -z "$filetest" ] ; then
|
|
echo -e ; echo -e; echo "==> in MP4 konvertieren:"
|
|
IFS=$'\012'
|
|
for i in $(find "$WORKDIR" -maxdepth 1 -name "*.avi" -type f) #
|
|
do
|
|
IFS=$OLDIFS
|
|
echo -e
|
|
title=`basename "$i"`
|
|
pfad=`dirname "$i"`
|
|
pfad="$pfad/"
|
|
echo -e
|
|
echo " KONVERTIERE: ---> $title"
|
|
echo -n " "; date; echo -e
|
|
|
|
title=${title%.*}
|
|
# fileinfo=$($ffmpeg -i "$i" 2>&1)
|
|
# fileinfo=$($ffmpeg -i "$i" -f null - 2>&1)
|
|
|
|
ffprobeInfo=$(ffprobe -v quiet -print_format json -show_format -show_streams "$i" 2>&1)
|
|
# Errormeldung vor jason ab DSM 6.2 (wird hier abgeschnitten): ERROR:
|
|
# ld.so: object 'openhook.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored. { …
|
|
ffprobeInfo="{ ${ffprobeInfo#*\{}"
|
|
|
|
# ------- AUDIOCODEC:
|
|
audiocodec=`echo "$ffprobeInfo" | jq '.streams[1].codec_name' | sed "s/\"//g" `
|
|
# Workaround, sofern "codec_name" nicht mit von ffprobe ausgegeben wird:
|
|
if [ $audiocodec = "null" ]; then
|
|
echo "keine Codec_name in ffprobeInfo gefunden / Audiocodec wird alternativ ausgelesen:"
|
|
ffmpegaudioinfo=$(ffmpeg -i "$i" 2>&1)
|
|
if echo "$ffmpegaudioinfo" | grep -q "Audio: ac3" ; then
|
|
audiocodec=ac3
|
|
elif echo "$ffmpegaudioinfo" | grep -q "Audio: mp3" ; then
|
|
audiocodec=mp3
|
|
elif echo "$ffmpegaudioinfo" | grep -q "Audio: aac" ; then
|
|
audiocodec=aac
|
|
elif echo "$ffmpegaudioinfo" | grep -q "Audio: none" ; then # sehr experimenteller Workaround …
|
|
audiocodec=ac3
|
|
echo "ac3-Codec wird lediglich angenommen …"
|
|
else
|
|
echo "Audiocodec nicht erkannt"
|
|
continue
|
|
fi
|
|
fi
|
|
audiofile="${WORKDIR}$title.$audiocodec"
|
|
echo "Audiocodec: $audiocodec"
|
|
|
|
# ------- VIDEOCODEC:
|
|
videocodec=$(echo "${ffprobeInfo}" | jq -r '.streams[0].codec_tag_string' | tr '[:upper:]' '[:lower:]' ) # | sed "s/\"//g"
|
|
|
|
if [ $videocodec = "mpeg4" ] ; then
|
|
videocodec="divx"
|
|
vExt="tmp.m4v";
|
|
elif [ $videocodec = "h264" ]; then
|
|
videocodec="h264"
|
|
vExt="h264"
|
|
else
|
|
videocodec="unknown"
|
|
echo "Videoformat nicht erkannt. ==> springe zu nächster Datei:"
|
|
continue ;
|
|
fi
|
|
echo "Videocodec: $videocodec"
|
|
videofile="${WORKDIR}$title.$vExt"
|
|
|
|
# ------- FRAMERATE:
|
|
rframerate_1=`echo "$ffprobeInfo" | jq '.streams[0].r_frame_rate' | sed "s/\"//g" | awk -F '/' '{print $1}'`
|
|
rframerate_2=`echo "$ffprobeInfo" | jq '.streams[0].r_frame_rate' | sed "s/\"//g" | awk -F '/' '{print $2}'`
|
|
fps=$(echo | gawk '{print '$rframerate_1'/'$rframerate_2'}')
|
|
echo "Framerate: $fps"
|
|
|
|
# ------- DEMUX:
|
|
# ------- Audio extrahieren / konvertieren:
|
|
AUDIODEMUXINFO=$($ffmpeg -loglevel $ffloglevel -i "$i" -c:a copy -vn "$audiofile" 2>&1)
|
|
if [ $LOGlevel = "2" ] ; then #aufgeblähtes LOG bei AC3-Audio …
|
|
echo "ffmpeg-AudioDemux LOG: $AUDIODEMUXINFO"
|
|
fi
|
|
|
|
if [ $audiocodec = "mp3" ] ; then
|
|
#----------------------------------------------------------------------------------------
|
|
# HIER SIND INDIVIDUELLE PARAMETER FÜR VERSCHIEDENE AAC-Encoder ANZUPASSEN |
|
|
# - libfdk_aac hat die beste Qualität, ist aber nicht in DSM enthalten |
|
|
# - Native AAC encoder hat die 2.beste Qualität, ist aber nicht in DSM enthalten |
|
|
# - libfaac ist in DSM-ffmpeg enthalten, hat aber die schlechteste Qualität |
|
|
#----------------------------------------------------------------------------------------
|
|
|
|
echo -e; echo " > Konvertiere Audiospur:"
|
|
encoders=`$ffmpeg -loglevel $ffloglevel -encoders 2>&1` # Auflistung der installierten ffmpeg-Encoder
|
|
|
|
if $(echo "$encoders" | grep -q "libfdk_aac" ); then # für libfdk_aac
|
|
echo "Erkannter Encoder: fdk-aac [1.Wahl]"
|
|
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"
|
|
convertLOG=$($ffmpeg -threads 2 -loglevel $ffloglevel -i "$audiofile" -c:a libfdk_aac -b:a "${OTRaacqal%k}k" -af "volume=$volumeinfo"dB "$audiofile.m4a" 2>&1)
|
|
else
|
|
convertLOG=$($ffmpeg -threads 2 -loglevel $ffloglevel -i "$audiofile" -c:a libfdk_aac -b:a "${OTRaacqal%k}k" "$audiofile.m4a" 2>&1)
|
|
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
|
|
# ------- 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"
|
|
convertLOG=$($ffmpeg -loglevel $ffloglevel -threads 2 -i "$audiofile" -c:a aac -strict -2 -b:a "${OTRaacqal%k}k" -af "volume=$volumeinfo"dB "$audiofile.m4a" 2>&1)
|
|
else
|
|
convertLOG=$($ffmpeg -loglevel $ffloglevel -threads 2 -i "$audiofile" -c:a aac -strict -2 -b:a "${OTRaacqal%k}k" "$audiofile.m4a" 2>&1)
|
|
fi
|
|
elif $(echo "$encoders" | grep -q libfaac ) ; then # libfaac > syno-ffmpeg
|
|
echo "Erkannter Encoder: libfaac [3.Wahl]"
|
|
if [ 128 -gt ${OTRaacqal%k} ]; then
|
|
echo " Die aac-Zielbitrate ist mit ${OTRaacqal%k}k für den libfaac-Encoder sehr gering. Erhöhe den Wert >OTRaacqal< in den Einstellungen für eine bessere Qualität."
|
|
fi
|
|
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"
|
|
convertLOG=$($ffmpeg -loglevel $ffloglevel -threads 2 -i "$audiofile" -acodec libfaac -ab "${OTRaacqal%k}k" -af "volume=$volumeinfo"dB "$audiofile.m4a" 2>&1)
|
|
else
|
|
convertLOG=$($ffmpeg -loglevel $ffloglevel -threads 2 -i "$audiofile" -acodec libfaac -ab "${OTRaacqal%k}k" "$audiofile.m4a" 2>&1)
|
|
fi
|
|
else
|
|
echo " finde keinen ffmpeg-Audioencoder!"; echo " Gebe den Pfad zu einer aac-kompatiblen ffmpeg-Version an."
|
|
fi
|
|
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo "Encoderliste:"
|
|
echo "$encoders"
|
|
echo "Audio-Konverinfo:"
|
|
echo "$convertLOG"
|
|
fi
|
|
|
|
rm "$audiofile"
|
|
audiofile="$audiofile.m4a"
|
|
fi
|
|
|
|
# ------- Video extrahieren:
|
|
VIDEODEMUXINFO=$($ffmpeg -loglevel $ffloglevel -i "$i" -an -c:v copy "$videofile" 2>&1)
|
|
if [ $LOGlevel = "2" ] ; then #aufgeblähtes LOG bei AC3-Audio …
|
|
echo "ffmpeg-VideoDemux LOG:"
|
|
echo "$VIDEODEMUXINFO"
|
|
fi
|
|
|
|
# -------REMUX:
|
|
echo -e; echo " > mp4box Remux:"
|
|
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo "Audiodatei: $audiofile"
|
|
echo "Videodatei: $videofile"
|
|
fi
|
|
|
|
# Audio-Video-Syncparameter anpassen:
|
|
if [ ! -z "$MP4BOX_DELAY" ] ; then
|
|
if echo "$MP4BOX_DELAY" | grep -q '-' ; then # wenn ein negativer Wert:
|
|
VIDEODELAY=`echo "$MP4BOX_DELAY" | sed 's/-//g'`
|
|
videofiledelay="$videofile#video:delay=$VIDEODELAY"
|
|
echo "Audio-Video-Sync: Video wird um ${VIDEODELAY}ms verzögert"
|
|
audiofiledelay="$audiofile"
|
|
else
|
|
AUDIODELAY=`echo "$MP4BOX_DELAY" | sed 's/-//g'`
|
|
audiofiledelay="$audiofile#audio:delay=$AUDIODELAY"
|
|
echo "Audio-Video-Sync: Audio wird um ${AUDIODELAY}ms verzögert"
|
|
videofiledelay="$videofile"
|
|
fi
|
|
mp4box $mp4boxloglevel -add "$videofiledelay" -add "$audiofiledelay" -fps $fps -tmp "$pfad" "${pfad}${title}.mp4"
|
|
else
|
|
mp4box $mp4boxloglevel -add "$videofile" -add "$audiofile" -fps $fps -tmp "$pfad" "${pfad}${title}.mp4"
|
|
fi
|
|
|
|
# ------- Temp löschen:
|
|
rm "$videofile"
|
|
rm "$audiofile"
|
|
|
|
# ------- Original löschen:
|
|
if [ -f "${pfad}${title}.mp4" ]; then # nur löschen, wenn erfolgreich konvertiert:
|
|
if [ $endgueltigloeschen = "on" ] ; then
|
|
rm "$i"
|
|
else
|
|
mv "$i" "$OTRkeydeldir"
|
|
fi
|
|
else
|
|
echo "FEHLER: Zieldatei nicht gefunden!"
|
|
fi
|
|
|
|
if [ $lastjob -eq 3 ] && [ $useWORKDIR == "no" ] ; then
|
|
# füge Datei dem Index der Videostation hinzu:
|
|
synoindex -a "${pfad}${title}.mp4"
|
|
if [ $dsmtextnotify = "on" ] ; then
|
|
sleep 1
|
|
synodsmnotify $MessageTo "synOTR" "Film [$title] ist fertig"
|
|
sleep 1
|
|
fi
|
|
if [ $dsmbeepnotify = "on" ] ; then
|
|
sleep 1
|
|
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
|
|
done
|
|
elif [ $OTRavi2mp4active = "off" ] ; then
|
|
echo -e ; echo -e ; echo "==> in MP4 konvertieren ist deaktiviert"
|
|
fi
|
|
IFS=$OLDIFS
|
|
sleep 1
|
|
}
|
|
|
|
|
|
OTRrename()
|
|
{
|
|
#########################################################################################
|
|
# Diese Funktion sammelt techn. Metadaten zu einem Film und benennt die #
|
|
# Filme nach dem vorgegebenen Muster um #
|
|
#########################################################################################
|
|
|
|
filetest=`find "$WORKDIR" -maxdepth 1 -name "*TVOON*avi" -o -name "*TVOON*mp4" -type f`
|
|
if [ -z "$filetest" ]; then
|
|
return
|
|
fi
|
|
|
|
echo -e ; echo -e
|
|
echo "==> Umbenennen nach Schema"; echo -e
|
|
echo " [Umbenennungssyntax: $NameSyntax]"
|
|
echo " [Umbenennungssyntax Serientitel: $NameSyntaxSerientitel]:"
|
|
|
|
IFS=$'\012'
|
|
for i in $(find "$WORKDIR" -maxdepth 1 -name "*TVOON*avi" -o -name "*TVOON*mp4" -type f)
|
|
do
|
|
IFS=$OLDIFS
|
|
missSeries=1
|
|
serietitle=""
|
|
episodetitle=""
|
|
description=""
|
|
season=""
|
|
episode=""
|
|
filename=`basename "$i"`
|
|
sourcename="$filename"
|
|
echo -e ;
|
|
echo " UMBENENNEN: ---> $filename:"
|
|
echo -n " "; date; echo -e
|
|
|
|
fileextension="${filename##*.}"
|
|
filename=`echo $filename | sed 's/HQ-cut/mpg.HQ/g ; s/HD-cut/mpg.HD/g ; s/mpg.HD.avi-cut/mpg.HD/g ; s/-cut/.mpg/g'` # Korrektur für geschnittene Files
|
|
|
|
# ------------------ frage für die alternative Suche auf theTVDB.com OTR-Metadaten-Titel aus der DB ab:
|
|
sSQL="SELECT rowid,file_original,OTRtitle,serie_season,serie_episode FROM raw WHERE file_original LIKE '${filename%.*}%' ORDER BY rowid DESC LIMIT 1"
|
|
sqlerg=`sqlite3 -separator $'\t' ${APPDIR}/app/etc/synOTR.sqlite "$sSQL"`
|
|
|
|
rowid=`echo "$sqlerg" | awk -F'\t' '{print $1}' `
|
|
originalfilename=`echo "$sqlerg" | awk -F'\t' '{print $2}' `
|
|
OTRtitle=`echo "$sqlerg" | awk -F'\t' '{print $3}' `
|
|
serie_seasonDB=`echo "$sqlerg" | awk -F'\t' '{print $4}' `
|
|
serie_episodeDB=`echo "$sqlerg" | awk -F'\t' '{print $5}' `
|
|
|
|
echo " [Original: $originalfilename]"; echo -e
|
|
echo "Fileextension: $fileextension"
|
|
|
|
# ------------------ technische Filmdaten via ffmpeg und ffprobe auslesen:
|
|
ffprobeInfo=$(ffprobe -v quiet -print_format json -show_format -show_streams "$i" 2>&1)
|
|
|
|
# Errormeldung vor jason ab DSM 6.2 (wird hier abgeschnitten): ERROR:
|
|
# ld.so: object 'openhook.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored. { …
|
|
ffprobeInfo="{ ${ffprobeInfo#*\{}"
|
|
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo "Dateiinformation von ffprobe ausgelesen:"; echo "$ffprobeInfo"; echo -e
|
|
fi
|
|
|
|
# ------------------ FORMAT (QUALTIÄT):
|
|
if echo "$originalfilename" | grep -q ".HQ.avi"; then
|
|
format=HQ
|
|
elif echo "$originalfilename" | grep -q ".HD.avi"; then
|
|
format=HD
|
|
elif echo "$originalfilename" | grep -q ".mpg.mp4"; then
|
|
format=LQ
|
|
elif echo "$originalfilename" | grep -q ".mpg.avi"; then
|
|
format=SD
|
|
fi
|
|
echo "Format: $format"
|
|
|
|
# ------------------ Referenzpunkt suchen:
|
|
ersterpunkt=`echo $filename | awk '{print index($filename, ".")}'`
|
|
# ------------------ Titel:
|
|
titleend=$(($ersterpunkt-4))
|
|
titleOTR=`echo $filename | cut -c -$titleend `
|
|
title=`echo $titleOTR | sed 's/__+/ - /g' | sed 's/_/ /g' | sed "s/ +//g"`
|
|
# ------------------ auf Serieninformation prüfen:
|
|
if echo "$title" | grep -q "S[0-9][0-9]E[0-9][0-9]$" ; then
|
|
serieInfo=${title##* } # alles, bis zum letzten Leerzeichen
|
|
echo " als Serie erkannt (Serieninfo: $serieInfo)"
|
|
# serietitle=`echo $title | sed 's/ S[0-9][0-9]E[0-9][0-9]$//g'`
|
|
serietitle=`echo $titleOTR | sed 's/_S[0-9][0-9]E[0-9][0-9]$//g'`
|
|
season=`echo $serieInfo | cut -c 2-3 ` #| sed -e 's/^0*//'` # ohne führende Null > nicht nötig
|
|
episode=`echo $serieInfo | cut -c 5-6 ` #| sed -e 's/^0*//'`
|
|
TVDB_query
|
|
if [ $missSeries = "1" ] ; then
|
|
echo -e ; echo -n "Check otr-serien.de ---> "
|
|
OTRserien_query
|
|
else
|
|
if [ ! -z "$TVDB_SerieName" ] ; then
|
|
# title="$TVDB_SerieName"
|
|
serietitle="$TVDB_SerieName"
|
|
fi
|
|
fi
|
|
elif [[ "$serie_episodeDB" =~ $regInt ]] ; then # wenn in der Cutlist Serieninfos gefunden wurden (Episode ist in der DB eine Zahl), wird mit diesen weitergearbeitet
|
|
serieInfo=${title##* } # alles, bis zum letzten Leerzeichen
|
|
serietitle="$titleOTR"
|
|
season=$(printf '%02d' ${serie_seasonDB})
|
|
episode=$(printf '%02d' ${serie_episodeDB})
|
|
echo " als Serie erkannt (aus Cutlist - Serieninfo: ${titleOTR}_S${season}E${episode})"
|
|
TVDB_query
|
|
if [ $missSeries = "1" ] ; then
|
|
echo -e ; echo -n "Check otr-serien.de ---> "
|
|
OTRserien_query
|
|
else
|
|
if [ ! -z "$TVDB_SerieName" ] ; then
|
|
# title="$TVDB_SerieName"
|
|
serietitle="$TVDB_SerieName"
|
|
fi
|
|
fi
|
|
else # auf otr-serien.de sind auch Episoden verzeichnet, die als solche nicht durch den Dateinamen identifizierbar sind
|
|
echo -e ; echo -n "Check otr-serien.de ---> "
|
|
OTRserien_query
|
|
fi
|
|
|
|
echo "Staffel-Nr.: $season"
|
|
echo "Episoden-Nr.: $episode"
|
|
echo "Episodentitel: $episodetitle"
|
|
echo "Beschreibung: $description"
|
|
|
|
if [ $missSeries = "0" ] ; then
|
|
title="$serietitle"
|
|
else
|
|
title=`echo "$title" | sed "s/__/ - /g ; s/_/ /g ; s/ / /g ; s/ s /\'s /g ; s/\"//g ; s/://g ; s/\?//g ; s/\*//g" | sed -e "s/\<ue/ü/g ; s/\<ae/ä/g ; s/\<oe/ö/g ; s/\<UE/Ü/g ; s/\<AE/Ä/g ; s/\<OE/Ö/g ; s/\([BCDFGHJKLMNPQRSTVWXYZ]\)\(ae\)/\1ä/g ; s/\([BCDFGHJKLMNPQRSTVWXYZ]\)\(ue\)/\1ü/g ; s/\([BCDFGHJKLMNPQRSTVWXYZ]\)\(oe\)/\1ö/g ; s/\([bcdfghjklmnpqrstvwxyz]\)\(oe\)/\1ö/g ; s/\([bcdfghjklmnpqrstvwxyz]\)\(ue\)/\1ü/g ; s/\([bcdfghjklmnpqrstvwxyz]\)\(ae\)/\1ä/g ; s/\([BCDFGHJKLMNPQRSTVWXYZ]\)\(AE\)/\1Ä/g ; s/\([BCDFGHJKLMNPQRSTVWXYZ]\)\(OE\)/\1Ö/g ; s/\([BCDFGHJKLMNPQRSTVWXYZ]\)\(UE\)/\1Ü/g" | sed -f ${APPDIR}/includes/textersetzung.txt `
|
|
# Umlauterkennung nur nach einem Konsonanten:
|
|
# ersetze alle großen UE (> Ü) nach einem großen Konsonaten s/\([BCDFGHJKLMNPQRSTVWXYZ]\)\(UE\)/\1Ü/g
|
|
# ersetze alle UE am Anfang der Zeile s/^UE/Ü/g
|
|
# > ersetzt durch: \< (= Anfang jedes Wortes) s/\<UE/Ü/g
|
|
fi
|
|
echo "Titel: $title"
|
|
# ------------------ Jahr:
|
|
YY=$(echo "$filename" | awk -F '.' '{print $1}' | awk -F '_' '{print $NF}')
|
|
echo "YY: $YY"
|
|
YYYY="20$YY"
|
|
echo "YYYY: $YYYY"
|
|
# ------------------ Monat:
|
|
Mo=$(echo "$filename" | awk -F '.' '{print $2}')
|
|
echo "Monat: $Mo"
|
|
# ------------------ Tag:
|
|
DD=$(echo "$filename" | awk -F '.' '{print $3}' | awk -F '_' '{print $1}')
|
|
echo "Tag: $DD"
|
|
# ------------------ Stunde:
|
|
HH=$(echo "$filename" | awk -F '.' '{print $3}' | awk -F '_' '{print $2}' | awk -F '-' '{print $1}')
|
|
echo "Stunde: $HH"
|
|
# ------------------ Minute:
|
|
Min=$(echo "$filename" | awk -F '.' '{print $3}' | awk -F '_' '{print $2}' | awk -F '-' '{print $2}')
|
|
echo "Minute: $Min"
|
|
# ------------------ Dauer:
|
|
duration=$(echo "$filename" | awk -F '.' '{print $3}' | awk -F '_' '{print $4}')
|
|
echo "EPG-Dauer: $duration"
|
|
realduration=`echo "$ffprobeInfo" | jq '.streams[0].duration' | sed "s/\"//g" | awk -F '.' '{print $1}' `
|
|
realduration=$(($realduration/60))
|
|
echo "Realdauer: $realduration"
|
|
# ------------------ Sender:
|
|
Channel=$(echo "$filename" | awk -F '.' '{print $3}' | awk -F '_' '{print $3}' | awk '{ print toupper($0) }') # < 2018-06-16 | $bsy tr [:lower:] [:upper:]) # ? ! ? ! ? systeminternes /usr/bin/tr verfälscht Zeichen vox => vpx
|
|
echo "Sender: $Channel"
|
|
# ------------------ Bildwiederholrate:
|
|
rframerate_1=`echo "$ffprobeInfo" | jq '.streams[0].r_frame_rate' | sed "s/\"//g" | awk -F '/' '{print $1}'`
|
|
rframerate_2=`echo "$ffprobeInfo" | jq '.streams[0].r_frame_rate' | sed "s/\"//g" | awk -F '/' '{print $2}'`
|
|
fps=$(echo | gawk '{print '$rframerate_1'/'$rframerate_2'}')
|
|
echo "Framerate: $fps"
|
|
# ------------------ ScanType:
|
|
# http://www.aktau.be/2013/09/22/detecting-interlaced-video-with-ffmpeg/
|
|
# scantype=$($ffmpeg -filter:v idet -frames:v 10 -an -f rawvideo -y /dev/null -i "$i" 2>&1)
|
|
# scantype=$(echo "$fileinfo2" | grep "Scan type" | awk -F: '{print $2}' )
|
|
if [ $(echo "$scantype" | grep "Progressive") ] ; then
|
|
scantype="p"
|
|
elif [ $(echo "$scantype" | grep "not interlaced") ] ; then
|
|
scantype="p"
|
|
elif [ $(echo "$scantype" | grep "is interlaced") ] ; then
|
|
scantype="i"
|
|
fi
|
|
scantype="" # deaktiviert
|
|
# echo "Scantype: ${scantype}"
|
|
# ------------------ Auflösung:
|
|
height=`echo "$ffprobeInfo" | jq '.streams[0].height' `
|
|
echo "Auflösung Höhe: ${height}"
|
|
width=`echo "$ffprobeInfo" | jq '.streams[0].width' `
|
|
echo "Auflösung Breite: ${width}"
|
|
# ------------------ Seitenverhältnis:
|
|
aspect_ratio=`echo "$ffprobeInfo" | jq '.streams[0].display_aspect_ratio' | sed "s/\"//g" | sed "s/\:/-/g" `
|
|
echo "Seitenverhältnis: ${aspect_ratio}"
|
|
# ------------------ Audiocodec:
|
|
a_codec=`echo "$ffprobeInfo" | jq '.streams[1].codec_name' | sed "s/\"//g" `
|
|
echo "Audiocodec: ${a_codec}"
|
|
# ------------------ Videocodec:
|
|
v_codec=`echo "$ffprobeInfo" | jq '.streams[0].codec_name' | sed "s/\"//g" `
|
|
echo "Videocodec: ${v_codec}"
|
|
|
|
NewName=$NameSyntax # Muster aus Konfiguration laden
|
|
|
|
# ------------------ Neuer Name:
|
|
if [ $missSeries = "0" ] ; then
|
|
if [ ! -z "$NameSyntaxSerientitel" ] ; then # nur, wenn Serientitel angepasst / gesetzt wurde
|
|
title="$NameSyntaxSerientitel"
|
|
else
|
|
title="$serietitle.S${season}.E${episode} $episodetitle" # optimiert für VideoStation
|
|
fi
|
|
fi
|
|
|
|
NewName=`echo $NewName | sed "s/§tit/${title}/g"`
|
|
NewName=`echo $NewName | sed "s/§sertit/${serietitle}/g"`
|
|
NewName=`echo $NewName | sed "s/§epitit/${episodetitle}/g"`
|
|
NewName=`echo $NewName | sed "s/§sta/${season}/g"`
|
|
NewName=`echo $NewName | sed "s/§epi/${episode}/g"`
|
|
NewName=`echo $NewName | sed "s/§dur/${duration}/g"`
|
|
NewName=`echo $NewName | sed "s/§ylong/${YYYY}/g"`
|
|
NewName=`echo $NewName | sed "s/§yshort/${YY}/g"`
|
|
NewName=`echo $NewName | sed "s/§mon/${Mo}/g"`
|
|
NewName=`echo $NewName | sed "s/§day/${DD}/g"`
|
|
NewName=`echo $NewName | sed "s/§hou/${HH}/g"`
|
|
NewName=`echo $NewName | sed "s/§min/${Min}/g"`
|
|
NewName=`echo $NewName | sed "s/§cha/${Channel}/g"`
|
|
NewName=`echo $NewName | sed "s/§qua/${format}/g"`
|
|
NewName=`echo $NewName | sed "s/§fps/${fps}/g"`
|
|
NewName=`echo $NewName | sed "s/§redur/${realduration}/g"`
|
|
NewName=`echo $NewName | sed "s/§scty/${scantype}/g"`
|
|
NewName=`echo $NewName | sed "s/§height/${height}/g"`
|
|
NewName=`echo $NewName | sed "s/§width/${width}/g"`
|
|
NewName=`echo $NewName | sed "s/§asra/${aspect_ratio}/g"`
|
|
NewName=`echo $NewName | sed "s/§acod/${a_codec}/g"`
|
|
NewName=`echo $NewName | sed "s/§vcod/${v_codec}/g"`
|
|
|
|
if [ $missSeries = "0" ] ; then
|
|
title="$serietitle - S${season}E${episode} $episodetitle" # Titel für DSM-Benachrichtigung generieren
|
|
fi
|
|
if [ $a_codec = "ac3" ] ; then
|
|
NewName=`echo $NewName | sed "s/§ac01/ ${a_codec}/g"`
|
|
else
|
|
NewName=`echo $NewName | sed "s/§ac01//g"`
|
|
fi
|
|
|
|
NewName="$NewName.$fileextension"
|
|
echo -e; echo "Neuer Dateiname: $NewName" ; echo -e
|
|
|
|
if [ $OTRrenameactiv = "on" ] ; then
|
|
echo "==> umbenennen:"
|
|
if [ -f "${WORKDIR}${NewName}" ]; then # Prüfen, ob Zielname bereits vorhanden ist
|
|
echo "Die Datei $NewName ist bereits vorhanden und $filename wird nicht umbenannt."
|
|
touch -t $YY$Mo$DD$HH$Min "$i" # Dateidatum auf Ausstrahlungsdatum setzen
|
|
else
|
|
mv -i "$i" "${WORKDIR}${NewName}"
|
|
|
|
# Tags schreiben (MP4 only):
|
|
echo -n " L==> Tags schreiben AtomicParsley (MP4 only):"
|
|
if [ $fileextension = "mp4" ] ; then
|
|
# --TVNetwork (string) Set the TV Network name
|
|
# --TVShowName (string) Set the TV Show name
|
|
# --TVEpisode (string) Set the TV episode/production code
|
|
# --TVSeasonNum (number) Set the TV Season number
|
|
# --TVEpisodeNum (number) Set the TV Episode number
|
|
# --description
|
|
# --artwork
|
|
# --genre
|
|
AtomicParsleyLOG=$(AtomicParsley "${WORKDIR}${NewName}" --overWrite --TVNetwork "$Channel" --TVShowName "$serietitle" --TVEpisode "$episodetitle" --TVSeasonNum "$season" --TVEpisodeNum "$episode" --title "$title" 2>&1)
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo " AtomicParsleyLOG= $AtomicParsleyLOG"
|
|
fi
|
|
echo -e " ==> fertig"
|
|
touch -t $YY$Mo$DD$HH$Min "${WORKDIR}${NewName}" # Dateidatum auf Ausstrahlungsdatum setzen
|
|
else
|
|
touch -t $YY$Mo$DD$HH$Min "${WORKDIR}${NewName}" # Dateidatum auf Ausstrahlungsdatum setzen
|
|
fi
|
|
echo " L==> umbenannt von"; echo " $filename"; echo " zu"; echo " $NewName"
|
|
|
|
echo -e; echo " ------------------------->"; echo -n " Datenbank schreiben ==> "
|
|
# Hochkommas für SQL-String maskieren:
|
|
NewNameMask=$( echo "$NewName" | sed "s/'/''/g" )
|
|
titleMask=$(echo "$title" | sed "s/'/''/g")
|
|
serietitleMask=$(echo "$serietitle" | sed "s/'/''/g")
|
|
episodetitleMask=$(echo "$episodetitle" | sed "s/'/''/g")
|
|
descriptionMask=$(echo "$description" | sed "s/'/''/g")
|
|
|
|
if [ ! -z "$rowid" ] ; then
|
|
echo -n "aktualisiere Datensatz $rowid"
|
|
sSQL="UPDATE raw SET file_rename='$NewNameMask', miss_series='$missSeries', format='$format', titel='$titleMask', datum='$YYYY-$Mo-$DD', zeit='$HH:$Min:00', dauer='$duration', sender='$Channel', otrid='$OTRID', serie_titel='$serietitleMask', serie_season='$season', serie_episode='$episode', serie_episodentitel='$episodetitleMask', serie_episodebeschreibung='$descriptionMask', lastcheckday=$today, checkcount=0, fps='$fps', realdauer='$realduration', scantype='$scantype', pix_height='$height', pix_width='$width', aspect_ratio='$aspect_ratio', v_codec='$v_codec', a_codec='$a_codec' WHERE rowid=$rowid"
|
|
else
|
|
echo -n "füge neuen Datensatz ein"
|
|
sSQL="INSERT INTO raw ( file_original, file_rename, miss_series, format, titel, datum, zeit, dauer, sender, otrid, serie_titel, serie_season, serie_episode, serie_episodentitel, serie_episodebeschreibung, lastcheckday, checkcount, fps, realdauer, scantype, pix_height, pix_width, aspect_ratio, v_codec, a_codec) VALUES ('$filename', '$NewNameMask', '$missSeries', '$format', '$titleMask', '$YYYY-$Mo-$DD', '$HH:$Min:00', '$duration', '$Channel', '$OTRID', '$serietitleMask', '$season', '$episode', '$episodetitleMask', '$descriptionMask', '$today', '0', '$fps', '$realduration', '$scantype', '$height', '$width', '$aspect_ratio', '$v_codec', '$a_codec')"
|
|
fi
|
|
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo " sSQL= $sSQL"
|
|
fi
|
|
sqlite3 ${APPDIR}/app/etc/synOTR.sqlite "$sSQL"
|
|
echo " ==> fertig"; echo " <-------------------------"
|
|
|
|
if [ $lastjob -eq 4 ] && [ $useWORKDIR == "no" ] ; then
|
|
# füge Datei dem Index der Videostation hinzu:
|
|
synoindex -a "${WORKDIR}${NewName}"
|
|
if [ $dsmtextnotify = "on" ] ; then
|
|
sleep 1
|
|
synodsmnotify $MessageTo "synOTR" "Film [$title] ist fertig"
|
|
sleep 1
|
|
fi
|
|
if [ $dsmbeepnotify = "on" ] ; then
|
|
sleep 1
|
|
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
|
|
fi
|
|
elif [ $OTRrenameactiv = "off" ] ; then
|
|
echo -e ; echo -e ; echo "==> umbenennen ist deaktiviert"
|
|
else
|
|
echo "==> Variable für Renameaktivität falsch gesetzt ==> Wert >OTRrenameactiv< in den Einstellungen überprüfen!"
|
|
fi
|
|
done
|
|
sleep 1
|
|
}
|
|
|
|
|
|
OTRopenrename()
|
|
{
|
|
#########################################################################################
|
|
# Diese Funktion sucht in der DB nach noch nicht erkannten Fernsehserien #
|
|
# und prüft erneut auf otr-serien.de auf evtl. Verfügbarkeit #
|
|
#########################################################################################
|
|
|
|
IFS=$'\n'; # ==> den 'Internal Field Separator' so verändern, dass Felder nur noch durch Zeilenumbrüche (und nicht [zusätzlich] durch Leerzeichen) getrennt werden.
|
|
NewName=$NameSyntax # Muster aus Konfiguration laden
|
|
if [ $OTRrenameactiv = "on" ] && [ $firstrunonday == "1" ] ; then
|
|
echo -e ; echo -e
|
|
echo "==> OTRopenrename via SQLite [Umbenennungssyntax: $NameSyntax]"
|
|
echo " [Umbenennungssyntax Serientitel: $NameSyntaxSerientitel]:"
|
|
echo " undefinierte Serien suchen:"
|
|
|
|
sSQL="SELECT rowid,file_rename,file_original,checkcount,format,titel,datum,zeit,dauer,sender,fps,realdauer,scantype,pix_height,pix_width,aspect_ratio,v_codec,a_codec FROM raw WHERE miss_series=1 AND NOT lastcheckday=$today AND checkcount<8"
|
|
|
|
sqlerg=`sqlite3 -separator $'\t' ${APPDIR}/app/etc/synOTR.sqlite "$sSQL"`
|
|
IFS=$'\012'
|
|
for entry in $sqlerg; do
|
|
IFS=$OLDIFS
|
|
NewName=$NameSyntax # Muster aus Konfiguration laden / vorherigen Schleifendurchlauf zurücksetzen
|
|
# Datensatzfelder separieren:
|
|
id=`echo "$entry" | awk -F'\t' '{print $1}' `
|
|
file_rename=`echo "$entry" | awk -F'\t' '{print $2}' `
|
|
filename=`echo "$entry" | awk -F'\t' '{print $3}' `
|
|
checkcount=`echo "$entry" | awk -F'\t' '{print $4}' `
|
|
format=`echo "$entry" | awk -F'\t' '{print $5}' `
|
|
title=`echo "$entry" | awk -F'\t' '{print $6}' `
|
|
YYYY=`echo "$entry" | awk -F'\t' '{print $7}' | awk -F'-' '{print $1}'`
|
|
YY=`echo "$entry" | awk -F'\t' '{print $7}' | awk -F'-' '{print $1}' | cut -c 3-4`
|
|
Mo=`echo "$entry" | awk -F'\t' '{print $7}' | awk -F'-' '{print $2}'`
|
|
DD=`echo "$entry" | awk -F'\t' '{print $7}' | awk -F'-' '{print $3}'`
|
|
HH=`echo "$entry" | awk -F'\t' '{print $8}' | awk -F':' '{print $1}'`
|
|
Min=`echo "$entry" | awk -F'\t' '{print $8}' | awk -F':' '{print $2}'`
|
|
duration=`echo "$entry" | awk -F'\t' '{print $9}' `
|
|
Channel=`echo "$entry" | awk -F'\t' '{print $10}' `
|
|
fps=`echo "$entry" | awk -F'\t' '{print $11}' `
|
|
realduration=`echo "$entry" | awk -F'\t' '{print $12}' `
|
|
scantype=`echo "$entry" | awk -F'\t' '{print $13}' `
|
|
height=`echo "$entry" | awk -F'\t' '{print $14}' `
|
|
width=`echo "$entry" | awk -F'\t' '{print $15}' `
|
|
aspect_ratio=`echo "$entry" | awk -F'\t' '{print $16}' `
|
|
v_codec=`echo "$entry" | awk -F'\t' '{print $17}' `
|
|
a_codec=`echo "$entry" | awk -F'\t' '{print $18}' `
|
|
|
|
fileextension="${file_rename##*.}"
|
|
|
|
if [ -f "${DESTDIR}/$file_rename" ]; then
|
|
if [ $LOGlevel = "1" ] ; then
|
|
echo " -> prüfe: "$filename
|
|
elif [ $LOGlevel = "2" ] ; then
|
|
echo " -> SQL-Abfrage: "$sSQL
|
|
echo " -> prüfe Datei: "$filename
|
|
echo " ${DESTDIR}/$file_rename vorhanden"
|
|
echo " -> otr-serien Abfrage: http://www.otr-serien.de/myapi/reverseotrkeycheck.php?otrkey=$filename&who=synOTR" ; echo -e
|
|
fi
|
|
|
|
serieninfo=$(wget --timeout=60 --tries=2 -q -O - "http://www.otr-serien.de/myapi/reverseotrkeycheck.php?otrkey=$filename&who=synOTR" )
|
|
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo " Rückgabewert von otr-serien.de ==> $serieninfo" ; echo -e
|
|
fi
|
|
|
|
serieninfo="{ ${serieninfo#*\{}" # 2018-02-13 Rückgabe von otr-serien.de wurde scheinbar geändert (vorgelagerte Infos vor jason-Container > werden jetzt abgeschnitten)
|
|
# Zeichenkorrektur:
|
|
serieninfo=`echo $serieninfo | sed "s/<!DOCTYPE html>//g" | sed -f ${APPDIR}/includes/decode.sed `
|
|
OTRID=`echo "$serieninfo" | awk -F, '{print $1}' | awk -F: '{print $2}' | sed "s/\"//g"`
|
|
|
|
if echo "$serieninfo" | grep -q "Keine Serien zuordnung vorhanden"; then
|
|
echo -e " L=> kein Suchergebnis"
|
|
sSQLupdate="UPDATE raw SET lastcheckday=$today, checkcount=$(($checkcount+1)) WHERE rowid=$id"
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo " $serieninfo"
|
|
echo " -> SQLupdate: $sSQLupdate"
|
|
fi
|
|
sqlite3 ${APPDIR}/app/etc/synOTR.sqlite "$sSQLupdate"
|
|
elif echo "$serieninfo" | grep -q "Kein OTR DB Eintrag vorhanden"; then
|
|
echo -e " L=> Film konnte von OTRserien nicht identifiziert werden (wahrscheinlich wurde der Film manuell umbenannt) --> Standardumbenennung wird verwendet"
|
|
sSQLupdate="UPDATE raw SET lastcheckday=$today, checkcount=$(($checkcount+1)) WHERE rowid=$id"
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo " $serieninfo"
|
|
echo " -> SQLupdate: $sSQLupdate"
|
|
fi
|
|
sqlite3 ${APPDIR}/app/etc/synOTR.sqlite "$sSQLupdate"
|
|
elif [ -z "$serieninfo" ] ; then
|
|
echo -e " >>> Keine Serverantwort <<<"
|
|
sSQLupdate="UPDATE raw SET lastcheckday=$today, checkcount=$(($checkcount+1)) WHERE rowid=$id"
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo " -> SQLupdate: $sSQLupdate"
|
|
fi
|
|
sqlite3 ${APPDIR}/app/etc/synOTR.sqlite "$sSQLupdate"
|
|
elif [[ "$OTRID" =~ $regInt ]]; then # Ist die OTR-Id eine echte Zahl?
|
|
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" `
|
|
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
|
|
echo "season: $season"
|
|
episode=`echo "$serieninfo" | awk -F, '{print $4}' | awk -F: '{print $2}' | sed "s/\"//g"`
|
|
episode="$(printf '%02d' "$episode")" # 2stellig mit führender Null
|
|
echo "episode: $episode"
|
|
episodetitle=`echo "$serieninfo" | jq -r '.Folgenname' | sed "s/://g" | sed "s/\?//g" `
|
|
echo "episodetitle: $episodetitle"
|
|
description=`echo "$serieninfo" | jq -r '.Folgenbeschreibung' | sed "s/:/ -/g" `
|
|
echo "description: $description"
|
|
|
|
if [ ! -z "$NameSyntaxSerientitel" ] ; then # nur, wenn Serientitel angepasst / gesetzt wurde
|
|
title="$NameSyntaxSerientitel"
|
|
else
|
|
title="$serietitle.S${season}.E${episode} $episodetitle" # optimiert für VideoStation
|
|
fi
|
|
|
|
# ------------------ Neuer Name:
|
|
NewName=`echo $NewName | sed "s/§tit/${title}/g"`
|
|
title="$serietitle - S${season}E${episode} $episodetitle" # Titel für DSM-Benachrichtigung generieren
|
|
NewName=`echo $NewName | sed "s/§dur/${duration}/g"`
|
|
NewName=`echo $NewName | sed "s/§tit/${title}/g"`
|
|
NewName=`echo $NewName | sed "s/§ylong/${YYYY}/g"`
|
|
NewName=`echo $NewName | sed "s/§yshort/${YY}/g"`
|
|
NewName=`echo $NewName | sed "s/§mon/${Mo}/g"`
|
|
NewName=`echo $NewName | sed "s/§day/${DD}/g"`
|
|
NewName=`echo $NewName | sed "s/§hou/${HH}/g"`
|
|
NewName=`echo $NewName | sed "s/§min/${Min}/g"`
|
|
NewName=`echo $NewName | sed "s/§cha/${Channel}/g"`
|
|
NewName=`echo $NewName | sed "s/§qua/${format}/g"`
|
|
NewName=`echo $NewName | sed "s/§fps/${fps}/g"`
|
|
NewName=`echo $NewName | sed "s/§redur/${realduration}/g"`
|
|
NewName=`echo $NewName | sed "s/§scty/${scantype}/g"`
|
|
NewName=`echo $NewName | sed "s/§height/${height}/g"`
|
|
NewName=`echo $NewName | sed "s/§width/${width}/g"`
|
|
NewName=`echo $NewName | sed "s/§asra/${aspect_ratio}/g"`
|
|
NewName=`echo $NewName | sed "s/§acod/${a_codec}/g"`
|
|
NewName=`echo $NewName | sed "s/§vcod/${v_codec}/g"`
|
|
NewName=`echo $NewName | sed "s/§sertit/${serietitle}/g"`
|
|
NewName=`echo $NewName | sed "s/§epitit/${episodetitle}/g"`
|
|
NewName=`echo $NewName | sed "s/§sta/${season}/g"`
|
|
NewName=`echo $NewName | sed "s/§epi/${episode}/g"`
|
|
if [ $a_codec = "ac3" ] ; then
|
|
NewName=`echo $NewName | sed "s/§ac01/ ${a_codec}/g"`
|
|
else
|
|
NewName=`echo $NewName | sed "s/§ac01//g"`
|
|
fi
|
|
|
|
NewName="$NewName.$fileextension"
|
|
echo -e; echo " Neuer Dateiname: $NewName" ; echo -e
|
|
echo " ==> umbenennen:"
|
|
|
|
if [ -f "${DESTDIR}/$NewName" ]; then # Prüfen, ob Zielname bereits vorhanden ist
|
|
echo " Die Datei $NewName ist bereits vorhanden und $file_rename wird nicht umbenannt."
|
|
sSQLupdate="UPDATE raw SET lastcheckday=$today, checkcount=$(($checkcount+1)), miss_series=0 WHERE rowid=$id"
|
|
sqlite3 ${APPDIR}/app/etc/synOTR.sqlite "$sSQLupdate"
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo " sSQLupdate= $sSQLupdate"
|
|
fi
|
|
else
|
|
mv -i "${DESTDIR}/$file_rename" "${DESTDIR}/$NewName"
|
|
|
|
# Tags schreiben (MP4 only):
|
|
echo -n " L==> Tags schreiben AtomicParsley (MP4 only):"
|
|
|
|
if [ $fileextension = "mp4" ] ; then
|
|
# --TVNetwork (string) Set the TV Network name
|
|
# --TVShowName (string) Set the TV Show name
|
|
# --TVEpisode (string) Set the TV episode/production code
|
|
# --TVSeasonNum (number) Set the TV Season number
|
|
# --TVEpisodeNum (number) Set the TV Episode number
|
|
# --description
|
|
# --artwork
|
|
# --genre
|
|
AtomicParsleyLOG=$(AtomicParsley "${DESTDIR}/$NewName" --overWrite --TVNetwork "$Channel" --TVShowName "$serietitle" --TVEpisode "$episodetitle" --TVSeasonNum "$season" --TVEpisodeNum "$episode" --title "$title" 2>&1)
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo " AtomicParsleyLOG= $AtomicParsleyLOG"
|
|
fi
|
|
echo -e " ==> fertig"
|
|
|
|
touch -t $YY$Mo$DD$HH$Min "${DESTDIR}/$NewName" # Dateidatum auf Ausstrahlungsdatum setzen
|
|
else
|
|
touch -t $YY$Mo$DD$HH$Min "${DESTDIR}/$NewName" # Dateidatum auf Ausstrahlungsdatum setzen
|
|
fi
|
|
|
|
echo " L==> umbenannt von"; echo " $filename"; echo " zu"; echo " $NewName"
|
|
echo -e; echo " ------------------------->"; echo -n " Datenbank schreiben ==> "
|
|
# Hochkommas für SQL-String maskieren (SQLite3 einfache Hochkommas maskieren durch hinzufügen eines weiteren):
|
|
NewNameMask=$( echo "$NewName" | sed "s/'/''/g" )
|
|
serietitleMask=$(echo "$serietitle" | sed "s/'/''/g")
|
|
episodetitleMask=$(echo "$episodetitle" | sed "s/'/''/g")
|
|
descriptionMask=$(echo "$description" | sed "s/'/''/g")
|
|
|
|
sSQLupdate="UPDATE raw SET file_rename='$NewNameMask', otrid='$OTRID', serie_titel='$serietitleMask', serie_season='$season', serie_episode='$episode', serie_episodentitel='$episodetitleMask', serie_episodebeschreibung='$descriptionMask', lastcheckday=$today, checkcount=$(($checkcount+1)), miss_series=0 WHERE rowid=$id"
|
|
|
|
sqlite3 ${APPDIR}/app/etc/synOTR.sqlite "$sSQLupdate"
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo " sSQLupdate= $sSQLupdate"
|
|
fi
|
|
echo "fertig"; echo " <-------------------------"
|
|
|
|
if [ $lastjob -eq 4 ] ; then
|
|
# Videostation Index korrigieren:
|
|
synoindex -n "${DESTDIR}/$NewName" "${DESTDIR}/$filename"
|
|
|
|
if [ $dsmtextnotify = "on" ] ; then
|
|
sleep 1
|
|
synodsmnotify $MessageTo "synOTR" "Film [$title] ist fertig"
|
|
sleep 1
|
|
fi
|
|
if [ $dsmbeepnotify = "on" ] ; then
|
|
sleep 1
|
|
echo 2 > /dev/ttyS1 #short beep
|
|
sleep 1
|
|
fi
|
|
wget --timeout=30 --tries=2 -q -O - "http://${synotrdomain}/synOTR/synOTR_FILECOUNT" >/dev/null 2>&1
|
|
needindex=1
|
|
fi
|
|
wget --timeout=30 --tries=2 -q -O - "http://${synotrdomain}/synOTR/synOTR_FILECOUNT_OTRSERIENopen" >/dev/null 2>&1
|
|
fi
|
|
else
|
|
# JSON nicht lesbar
|
|
echo -e "Serverantwort konnte nicht verarbeitet werden (kein kompatibles JSON)"
|
|
echo " $serieninfo"
|
|
sSQLupdate="UPDATE raw SET lastcheckday=$today, checkcount=$(($checkcount+1)) WHERE rowid=$id"
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo " ==> SQLupdate: $sSQLupdate"
|
|
fi
|
|
sqlite3 ${APPDIR}/app/etc/synOTR.sqlite "$sSQLupdate"
|
|
fi
|
|
else
|
|
echo -e "unbekannter Fehler …"
|
|
echo " $serieninfo"
|
|
sSQLupdate="UPDATE raw SET lastcheckday=$today, checkcount=$(($checkcount+1)) WHERE rowid=$id"
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo " ==> SQLupdate: $sSQLupdate"
|
|
fi
|
|
sqlite3 ${APPDIR}/app/etc/synOTR.sqlite "$sSQLupdate"
|
|
fi
|
|
sleep 15 # Wartezeit in Sekunden, um die Serverlast auf otr-serien.de zu reduzieren
|
|
else
|
|
echo " -> nicht gefunden: $file_rename"
|
|
echo " L==> Datei liegt nicht mehr im Zielordner [$WORKDIR]"
|
|
sSQLupdate="UPDATE raw SET lastcheckday=$today, checkcount=$(($checkcount+1)), miss_series=0 WHERE rowid=$id"
|
|
sqlite3 ${APPDIR}/app/etc/synOTR.sqlite "$sSQLupdate"
|
|
if [ $LOGlevel = "2" ] ; then
|
|
echo " sSQLupdate= $sSQLupdate"
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
sleep 1
|
|
}
|
|
|
|
|
|
UPDATE()
|
|
{
|
|
#########################################################################################
|
|
# Diese Funktion sucht nach einer neuen Version und sorgt für die Dateiintegrität #
|
|
#########################################################################################
|
|
|
|
CREATEDB ()
|
|
{
|
|
#########################################################################################
|
|
# Diese Funktion prüft, ob die SQLite-DB vorhanden ist und erstellt #
|
|
# diese gegebenenfalls. Außerdem werden ältere DB-Versionen aktualisiert #
|
|
#########################################################################################
|
|
IFS=$'\012'
|
|
if [ ! -f "${APPDIR}/app/etc/synOTR.sqlite" ]; then
|
|
echo " Die synOTR-Datenbank ist nicht vorhanden und wird erstellt."
|
|
# cp "${APPDIR}/app/etc/synOTR.sqlite_template" "${APPDIR}/app/etc/synOTR.sqlite"
|
|
# ==> DB nativ per SQL erzeugen:
|
|
sqlinst="CREATE TABLE \"raw\" (\"timestamp\" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP) ,\"file_original\" varchar(500) ,\"file_rename\" varchar(500) ,\"miss_series\" tinyint(1) ,\"format\" varchar(5) ,\"titel\" varchar(500) ,\"datum\" date ,\"zeit\" time ,\"dauer\" int(5) ,\"sender\" varchar(100) ,\"otrid\" int(11) ,\"serie_titel\" varchar(500) ,\"serie_season\" int(11) ,\"serie_episode\" int(11) ,\"serie_episodentitel\" varchar(500) ,\"serie_episodebeschreibung\" varchar(10000) ,\"lastcheckday\" int(3) ,\"checkcount\" int(3) DEFAULT (null) ,\"fps\" Numeric(500) ,\"realdauer\" int(5) ,\"scantype\" varchar(2) ,\"pix_height\" int(5) ,\"pix_width\" int(5) ,\"aspect_ratio\" varchar(20) ,\"v_codec\" varchar(100) ,\"a_codec\" varchar(100) ,\"OTRtitle\" varchar(500) ,\"OTRcomment\" varchar(10000) ,\"cutlist_ID\" int(20) ); CREATE INDEX \"IDX_raw_check\" ON \"raw\" (\"lastcheckday\" ASC, \"checkcount\" ASC);"
|
|
sqliteinfo=$(sqlite3 "${APPDIR}/app/etc/synOTR.sqlite" "$sqlinst")
|
|
echo " $sqliteinfo"
|
|
|
|
sqlinstNewTable="CREATE TABLE \"checkversion\" (\"timestamp\" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP) ,\"VERSIONcurrent\" varchar(500) ,\"VERSIONserver\" varchar(500) ,\"lastcheckday\" int(3) ); " # CREATE INDEX \"IDX_raw_check\" ON \"raw\" (\"lastcheckday\" ASC, \"checkcount\" ASC);"
|
|
sqliteinfo=$(sqlite3 "${APPDIR}/app/etc/synOTR.sqlite" "$sqlinstNewTable")
|
|
echo " $sqliteinfo"
|
|
|
|
sqlinstNewTable="CREATE TABLE \"tvdb\" (\"timestamp\" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP) ,\"APIKEY\" varchar(500) ,\"TOKEN\" varchar(2000) ,\"day_created\" int(3) ); "
|
|
sqliteinfo=$(sqlite3 "${APPDIR}/app/etc/synOTR.sqlite" "$sqlinstNewTable")
|
|
echo " $sqliteinfo"
|
|
if [ -f "${APPDIR}/app/etc/synOTR.sqlite" ]; then
|
|
echo " L==> DB erfolgreich erstellt [${APPDIR}/app/etc/synOTR.sqlite]"; echo -e
|
|
else
|
|
echo " L==> fehlgeschlagen … !"; echo -e
|
|
fi
|
|
fi
|
|
|
|
# Tabelle "checkversion" erstellen:
|
|
sqlinstNewTable="CREATE TABLE IF NOT EXISTS \"checkversion\" (\"timestamp\" timestamp NOT NULL DEFAULT (datetime('now','localtime')) ,\"VERSIONcurrent\" varchar(500) ,\"VERSIONserver\" varchar(500) ,\"lastcheckday\" int(3) ); " # CREATE INDEX \"IDX_raw_check\" ON \"raw\" (\"lastcheckday\" ASC, \"checkcount\" ASC);"
|
|
sqliteinfo=$(sqlite3 "${APPDIR}/app/etc/synOTR.sqlite" "$sqlinstNewTable")
|
|
echo " $sqliteinfo"
|
|
|
|
sqlerg=$(sqlite3 "${APPDIR}/app/etc/synOTR.sqlite" "SELECT rowid FROM checkversion WHERE rowid=1")
|
|
if [ "$sqlerg" == "" ] ; then # prüfen, ob der Updatedatensatz vorhanden ist, ggfls. einfügen
|
|
sSQL="INSERT INTO checkversion ( VERSIONcurrent, timestamp, lastcheckday) VALUES ( '$CLIENTVERSION', datetime('now','localtime'), $(($today-1)) )"
|
|
sqliteinfo=$(sqlite3 ${APPDIR}/app/etc/synOTR.sqlite "$sSQL")
|
|
echo " > Updatedatensatz eingefügt ($sqliteinfo)"
|
|
fi
|
|
|
|
sqlinstNewTable="CREATE TABLE IF NOT EXISTS \"tvdb\" (\"timestamp\" timestamp NOT NULL DEFAULT (CURRENT_TIMESTAMP) ,\"APIKEY\" varchar(500) ,\"TOKEN\" varchar(2000) ,\"day_created\" int(3) ); "
|
|
sqliteinfo=$(sqlite3 "${APPDIR}/app/etc/synOTR.sqlite" "$sqlinstNewTable")
|
|
echo " $sqliteinfo"
|
|
|
|
sqlerg=$(sqlite3 "${APPDIR}/app/etc/synOTR.sqlite" "SELECT rowid FROM tvdb WHERE rowid=1")
|
|
if [ "$sqlerg" == "" ] ; then # prüfen, ob der Datensatz vorhanden ist, ggfls. einfügen
|
|
if [ "$TVDB_APIKEY" == "" ] ; then
|
|
# voreingesteller API-Key, sofern kein persönlicher verwendet wird (Rot13):
|
|
TVDB_APIKEY=`echo "6P0N9Q9NORS401P7" | tr [a-zA-Z] [n-za-mN-ZA-M]`
|
|
fi
|
|
sSQL="INSERT INTO tvdb ( APIKEY, timestamp, day_created) VALUES ( '$TVDB_APIKEY', datetime('now','localtime'), $(($today-1)) )"
|
|
sqliteinfo=$(sqlite3 ${APPDIR}/app/etc/synOTR.sqlite "$sSQL")
|
|
fi
|
|
|
|
# Prüfen (und ggf. einfügen) der Spalten OTRtitle und OTRcomment:
|
|
sqlerg=`sqlite3 "${APPDIR}/app/etc/synOTR.sqlite" "SELECT * FROM sqlite_master WHERE TYPE='table' AND tbl_name = 'raw' AND SQL LIKE '%OTRtitle%' "`
|
|
|
|
if [ "$sqlerg" == "" ] ; then
|
|
echo " > Spalten (OTRtitle, OTRcomment) werden hinzugefügt"
|
|
sqlite3 "${APPDIR}/app/etc/synOTR.sqlite" "ALTER TABLE raw ADD COLUMN \"OTRtitle\" VARCHAR "
|
|
sqlite3 "${APPDIR}/app/etc/synOTR.sqlite" "ALTER TABLE raw ADD COLUMN \"OTRcomment\" VARCHAR "
|
|
fi
|
|
|
|
# Prüfen (und ggf. einfügen) der Spalte cutlist_ID:
|
|
sqlerg=`sqlite3 "${APPDIR}/app/etc/synOTR.sqlite" "SELECT * FROM sqlite_master WHERE TYPE='table' AND tbl_name = 'raw' AND SQL LIKE '%cutlist_ID%' "`
|
|
|
|
if [ "$sqlerg" == "" ] ; then
|
|
echo " > Spalte (cutlist_ID) wird hinzugefügt"
|
|
sqlite3 "${APPDIR}/app/etc/synOTR.sqlite" "ALTER TABLE raw ADD COLUMN \"cutlist_ID\" VARCHAR "
|
|
fi
|
|
|
|
IFS=$OLDIFS
|
|
sleep 1
|
|
}
|
|
|
|
CREATEDB
|
|
|
|
# Installationstrigger beinhaltet folgende anonymen Geräteinfos:
|
|
# DSM-Build / Prüfsumme der MAC-Adresse als Hardware-ID [anonyme Zahlenfolge
|
|
# um Installationen zu zählen] / Architektur / Geräte-Typ / synOTR-Version)
|
|
# ---------------------------------------------------------------------
|
|
if [ $DEBUGINFO = "on" ] ; then
|
|
restore_ENV
|
|
curl --max-time 60 -i -X POST -d '{"requests":["?idsite=11&url=http://'${synotrdomain}'/synOTR/installwatch.php&dimension1='${machinetyp}'&dimension2='${dsmbuild}'&dimension3='${sysID}_${device}'&dimension4='${device}'&dimension5='${CLIENTVERSION}'&rec=1&uid='${sysID}_${device}'&action_name=synOTR Shell-run/'${sysID}_${device}_${dsmbuild}_${machinetyp}_idx${idx}_synOTR${CLIENTVERSION}-${DevChannel}'&ua=curl/7.9.8 (i686-pc-linux-gnu)&new_visit=1"]}' http://$synotrdomain/piwik/piwik.php &>/dev/null # http://developer.piwik.org/api-reference/tracking-api # curl an dieser Stelle, da nach Einbindung der Librarys auf ARM eine Inkompatibilität vorhanden ist. ==> Alternative: Library-Path sichern und an späterer Stelle temporär rückspielen
|
|
synOTR_ENV
|
|
fi
|
|
|
|
# Versionsdaten aus DB lesen:
|
|
# Versionscheck wird für das Update (SPK) nicht mehr verwendet,
|
|
# aber die Ermittlung des ersten Programmlauf des Tages
|
|
# ---------------------------------------------------------------------
|
|
sSQL="SELECT rowid,VERSIONcurrent,VERSIONserver,lastcheckday FROM checkversion WHERE rowid=1 "
|
|
sqlerg=`sqlite3 -separator $'\t' ${APPDIR}/app/etc/synOTR.sqlite "$sSQL"`
|
|
|
|
lastcheckday=`echo "$sqlerg" | awk -F'\t' '{print $4}' `
|
|
|
|
ONLINEVERSION=$(wget --timeout=30 --tries=2 -q -O - http://$synotrdomain/synOTR/VERSION2 | /usr/bin/tr -d "\r")
|
|
ONLINEVERSION=`echo "$ONLINEVERSION" | grep "$DevChannel" | awk -F" " '{print $1}'`
|
|
|
|
# Beim ersten Programmlauf des Tages auf Update prüfen:
|
|
# ---------------------------------------------------------------------
|
|
#if ( [ "$lastcheckday" -ne $today ] || [ "$lastcheckday" == "" ] ) || ( [ $forceupdate == "on" ] ); then
|
|
if [ "$lastcheckday" -ne $today ] || [ "$lastcheckday" == "" ] ; then
|
|
firstrunonday=1 # Der erste Programmlauf des Tages > Trigger u.a. für Videostation Reindexierung, openrename …
|
|
IFS=$'\012'
|
|
|
|
# Datenbank aktualisieren:
|
|
# sSQLupdate="UPDATE checkversion SET VERSIONcurrent='$CLIENTVERSION', VERSIONserver='$ONLINEVERSION', lastcheckday=$today, timestamp=(datetime('now','localtime')) WHERE rowid=1"
|
|
sSQLupdate="UPDATE checkversion SET VERSIONcurrent='$CLIENTVERSION', VERSIONserver='SPK', lastcheckday=$today, timestamp=(datetime('now','localtime')) WHERE rowid=1"
|
|
sqlite3 ${APPDIR}/app/etc/synOTR.sqlite "$sSQLupdate"
|
|
|
|
else
|
|
firstrunonday=0
|
|
fi
|
|
|
|
IFS=$OLDIFS
|
|
sleep 1
|
|
}
|
|
|
|
|
|
MOVE2DESTDIR()
|
|
{
|
|
#########################################################################################
|
|
# Diese Funktion verschiebt die fertigen Filme in den Zielordner #
|
|
#########################################################################################
|
|
|
|
filetest=`find "${WORKDIR}" -maxdepth 1 -name "*.avi" -o -name "*.mp4" -type f`
|
|
if [ $useWORKDIR == "yes" ] && [ ! -z "$filetest" ]; then
|
|
echo -e; echo "==> Verschiebe fertige Filme in Zielordner"
|
|
IFS=$'\012'
|
|
for i in $(find "${WORKDIR}" -maxdepth 1 -name "*.avi" -o -name "*.mp4" -type f)
|
|
do
|
|
IFS=$OLDIFS
|
|
filename=`basename "$i"`
|
|
|
|
if [ ! -f "${DESTDIR}/${filename}" ]; then
|
|
mv "$i" "${DESTDIR}"
|
|
echo " L=> verschiebe ${filename}"
|
|
# füge Datei dem Index der Videostation hinzu:
|
|
synoindex -a "${DESTDIR}/${filename}"
|
|
|
|
if [ $dsmtextnotify = "on" ] ; then
|
|
sleep 1
|
|
synodsmnotify $MessageTo "synOTR" "Film [$filename] ist fertig"
|
|
sleep 1
|
|
fi
|
|
if [ $dsmbeepnotify = "on" ] ; then
|
|
sleep 1
|
|
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
|
|
# prüfen und zählen von gleichnamigen Filmen in der DB:
|
|
# ToDo: evtl. mit einer Zählschleife von Dateinamen im Zielordner realisieren => wäre von DB unabhängig und sicherer
|
|
filenameMask=$(echo "$filename" | sed "s/'/''/g")
|
|
sSQL="SELECT count(rowid) FROM raw WHERE file_rename='$filenameMask' "
|
|
|
|
FilenameCount=`sqlite3 -separator $'\t' ${APPDIR}/app/etc/synOTR.sqlite "$sSQL"`
|
|
|
|
if [ "$FilenameCount" == "0" ] || [ -z "$FilenameCount" ]; then
|
|
echo " Film [$filename] kann nicht in Zielordner verschoben werden, da er darin bereits vorhanden ist und in der Datenbank kein Zählgrundlage gefunden wurde!"
|
|
else
|
|
filename=`echo "$filename" | sed "s/.avi/ \(${FilenameCount}\).avi/g" | sed "s/.mp4/ \(${FilenameCount}\).mp4/g" `
|
|
echo " Dateiname wird um einen Zähler ergänzt (${FilenameCount}), da die Datei bereits im Zielordner existiert."
|
|
if [ ! -f "${DESTDIR}/${filename}" ]; then
|
|
mv "$i" "${DESTDIR}/${filename}"
|
|
echo " L=> verschiebe ${filename}"
|
|
# füge Datei dem Index der Videostation hinzu:
|
|
synoindex -a "${DESTDIR}//${filename}"
|
|
|
|
if [ $dsmtextnotify = "on" ] ; then
|
|
sleep 1
|
|
synodsmnotify $MessageTo "synOTR" "Film [$filename] ist fertig"
|
|
sleep 1
|
|
fi
|
|
if [ $dsmbeepnotify = "on" ] ; then
|
|
sleep 1
|
|
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
|
|
echo " Alternativer Dateiname [$filename] ebenfalls bereits vergeben …"
|
|
fi
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# DEV:
|
|
# echo "run FileBot:"
|
|
# filebot -script 'fn:amc' /volume1/video/_synOTR/FileBot_input --output '/volume1/video/+NEU' --action move --conflict index --lang de --def 'music=y' 'unsorted=y' 'deleteAfterExtract=y' 'minFileSize=0' 'seriesFormat={n}.S{s.pad(2)+'\''.E'\''}{e.pad(2)} - {t}' 'animeFormat={n} ({y}){ext}' 'movieFormat={n} ({y})' 'musicFormat={n} ({y}){ext}' 'unsortedFormat={fn}.{ext}' --log all --log-file '/volume1/@appstore/filebot-node/data/filebot.log'
|
|
}
|
|
|
|
|
|
FRESHUPMEDIAINDEX()
|
|
{
|
|
#########################################################################################
|
|
# Diese Funktion startet die Medienindexierung nach Bedarf #
|
|
# INFO: http://www.synology-wiki.de/index.php/Problembehebung_DLNA-Server_(Index) #
|
|
#########################################################################################
|
|
|
|
if [ -f "/usr/syno/bin/synoindex" ] && [ $firstrunonday == "1" ] && [ $reindex == "1" ] ; then # prüfen, ob Mediaserver/VideoStation installiert und Reindexierung nötig ist
|
|
echo -e; echo "==> vollständige Aktualisierung des Zielordner-Indexes für die VideoStation / MediaServer"
|
|
synoindex -R video:"$DESTDIR"
|
|
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 -n9 | 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=$(( $( 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=$(($(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=$(($(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 |
|
|
# |_______________________________________________________________________________|
|
|
|
|
echo -e; echo -e
|
|
echo " ----------------------------------"
|
|
echo " | ==> Funktionsaufrufe <== |"
|
|
echo " ----------------------------------"
|
|
|
|
UPDATE
|
|
OTRdecoder
|
|
OTRautocut
|
|
OTRavi2mp4
|
|
OTRrename
|
|
# OTRopenrename # 2019-10 deaktivert, da otr-serien.de die Pflege neuer Serien eingestellt hat
|
|
MOVE2DESTDIR
|
|
FRESHUPMEDIAINDEX
|
|
PURGELOG
|
|
|
|
echo -e; echo -e
|
|
echo " -----------------------------------"
|
|
echo " | ==> synOTR ENDE <== |"
|
|
echo " -----------------------------------"
|
|
echo -e; echo " Gesamtzeit: $(sec_to_time $(( $(date +%s)-${UNIXTIME})))"
|
|
|
|
exit
|