Der folgende Befehl verarbeitet die Ausgabe von youtube-dl mit sed, um den Dateinamen des Videos zu erhalten
youtube-dl "$URL" 2> /dev/null | \
sed -n 's/^\[download\] Destination: //p; s/^\[download\] \(.*\) has already been downloade.*/\1/p'
Unmittelbar nachdem youtube-dl mit dem Abrufen und Parsen des HTML fertig ist und mit dem Herunterladen des Videos beginnt, also einige Sekunden nach dem Start der Ausführung, gibt es den Dateinamen des Videos aus, sobald der Download abgeschlossen ist (mit einem Postfix für die .part
Dauer des Downloads).
Der Kern des Problems und das, woran ich nicht weiterkomme, ist: Wie bekomme ich den obigen Befehl in den Hintergrund (damit er weiter heruntergeladen wird) und wie erhalte ich den Videodateinamen aus der Standardausgabe, damit ich ihn verwenden kann, um die Videodatei zu öffnen, bevor der Download abgeschlossen ist.
Antwort1
Du könntest benutzen inotifywait
:
$ youtube-dl "$URL" &
$ inotifywait --event create --format '"%f"' . | xargs vlc
Es gibt hier einen Race Condition. Wenn Ihre Verbindung sehr schnell ist (meine ist es im Moment), könnte die Datei heruntergeladen und umbenannt werden, bevor Ihr Player sie öffnet. Wenn youtube-dl
Sie beispielsweise Audio und Video separat herunterladen, öffnen Sie möglicherweise die falsche Datei.
Antwort2
Der Kommentar von @fra-san hat mich an die While- read
Schleife erinnert, mit der Sie die Ausgabe zeilenweise/prozedural verarbeiten können (im Gegensatz zu funktional mit Pipes). Sie können den <
Operator verwenden, um die Ausgabe einer Datei mit der Bash-Prozesssubstitution des Befehls „youtube-dl“ an diese Schleife weiterzuleiten. Außerdem können Sie sie in den Hintergrund senden, indem Sie ein hinzufügen, &
und die While-Schleife kann die Ausgabe weiterhin lesen (es wird nur eine Datei gelesen, was BPS erstellt hat).
Durch Tests habe ich festgestellt, dass ich das Video auch nach Abschluss des Downloads und der Umbenennung normal weiter abspielen kann. Dies könnte jedoch eine Funktion von mpv sein.
#!/bin/bash
# ytdl-stream - use youtube-dl to stream videos i.e watch videos as they download
# usage: ytdl-stream [YOUTUBE_DL_OPTIONS] URL
# you can pipe into it a command to open you video player, e.g:
# echo mpv --mute=yes | ytdl-stream -f 'best[width<=1920,height<=1080]' --write-auto-sub [URL]
test ! -t 0 && player_cmd="$(cat /dev/stdin)" || player_cmd="mpv"
while IFS="" read -r line; do
filename=$(echo "$line" | sed -n 's/^\[download\] Destination: //p')
if [[ -z "$filename" ]]; then
filename=$(echo "$line" | sed -n 's/^\[download\] \(.*\) has already been downloade.*/\1/p')
[[ -z "$filename" ]] && continue || notify-send "file already downloaded, opening.."
else
notify-send "downloading.."
fi
withoutExtensions="${filename%.*}"
withoutExtensions="${withoutExtensions%.*}"
if [[ -e "$filename" ]]; then
sleep 0.5 && ($player_cmd "$filename")&
elif [[ -e "$filename".part ]]; then
sleep 2
if [[ -e "$filename".part ]]; then
notify-send "found .part after sleep again"
($player_cmd "$filename".part)&
else
sleep 0.5 && ($player_cmd "$withoutExtensions"*)&
fi
fi
done < <(youtube-dl "$@" 2> /dev/null)&