El siguiente comando procesa la salida de youtube-dl con sed para obtener el nombre de archivo del video.
youtube-dl "$URL" 2> /dev/null | \
sed -n 's/^\[download\] Destination: //p; s/^\[download\] \(.*\) has already been downloade.*/\1/p'
Inmediatamente después de que youtube-dl termina de buscar y analizar el HTML y comienza a descargar el video, que es un par de segundos después de que comienza a ejecutarse, muestra cuál será el nombre de archivo del video una vez que haya terminado de descargarse (con el posfijo " .part
while it's downloading"). )
Entonces, el quid de la cuestión y en lo que estoy atascado es: ¿Cómo puedo pasar el comando anterior al fondo (para que siga descargándose) y obtener el nombre del archivo de video de su salida estándar, para poder usarlo para abrir el video? archivo antes de que termine de descargarse.
Respuesta1
Podrías usar inotifywait
:
$ youtube-dl "$URL" &
$ inotifywait --event create --format '"%f"' . | xargs vlc
Hay una condición de carrera allí, si su conexión es muy rápida (la mía ahora lo es), el archivo se puede descargar y cambiar de nombre antes de que el reproductor lo abra. Además, si youtube-dl
hace algo como descargar audio y vídeo por separado, es posible que acabe abriendo el archivo equivocado.
Respuesta2
El comentario de @fra-san me recordó el read
bucle while que puedes usar para procesar la salida línea por línea/proceduralmente (en lugar de funcionalmente, con canalizaciones), puedes usar el <
operador para canalizar la salida de un archivo a ese bucle. con la sustitución del proceso Bash del comando youtube-dl, y también puede enviarlo a un segundo plano agregando un &
bucle while que aún puede leer su salida (solo está leyendo un archivo, que creó BPS).
A través de las pruebas descubrí que puedo seguir reproduciendo el video normalmente incluso después de que termine de descargarse y se le cambie el nombre, aunque esto podría ser una característica de mpv.
#!/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)&