Estoy buscando una manera de ver videos de YouTube en la terminal (no en un navegador u otra ventana, sino allí mismo, en cualquier sesión de bash).
¿Existe una forma sencilla de hacer esto?
Me imagino algo como esto:
$ youtube <video-url>
Ya sé cómo reproducir un vídeo usando mplayer
:
$ mplayer -vo caca local-file.avi
Sin embargo, esto abre una nueva ventana. Sería genial jugarlo en la terminal.
Además, debería ser compatible con tmux
las sesiones.
hice otra pregunta paracómo evitar abrir una nueva ventana.
Para aquellos que se preguntan dónde necesito tal funcionalidad, comencé un proyecto experimental llamadoTmuxOS-- con el concepto de quetodo debería ejecutarse dentro de una tmux
sesión.
Entonces, de hecho necesito un reproductor de video para videos locales y remotos. :-)
Respuesta1
Puedes descargar videos y/o solo el audio y luego verlos/escucharlos usandoyoutube-dl
. El script está escrito en Python y creo que lo utiliza ffmpeg
.
$ youtube-dl --help
Usage: youtube-dl [options] url [url...]
Options:
General Options:
-h, --help print this help text and exit
--version print program version and exit
-U, --update update this program to latest version.
Make sure that you have sufficient
permissions (run with sudo if needed)
...
...
Para descargar vídeos simplemente le das la URL de la página donde quieres el vídeo y el script hace el resto:
$ youtube-dl https://www.youtube.com/watch?v=OwvZemXJhF4
[youtube] Setting language
[youtube] OwvZemXJhF4: Downloading webpage
[youtube] OwvZemXJhF4: Downloading video info webpage
[youtube] OwvZemXJhF4: Extracting video information
[youtube] OwvZemXJhF4: Encrypted signatures detected.
[youtube] OwvZemXJhF4: Downloading js player 7N
[youtube] OwvZemXJhF4: Downloading js player 7N
[download] Destination: Joe Nichols - Yeah (Audio)-OwvZemXJhF4.mp4
[download] 100% of 21.74MiB in 00:16
Luego puedes usar vlc
o mplayer
para verlos localmente:
$ vlc "Joe Nichols - Yeah (Audio)-OwvZemXJhF4.mp4"
VLC media player 2.1.5 Rincewind (revision 2.1.4-49-gdab6cb5)
[0x1cd1118] main libvlc: Running vlc with the default interface. Use 'cvlc' to use vlc without interface.
Fontconfig warning: FcPattern object size does not accept value "0"
Fontconfig warning: FcPattern object size does not accept value "0"
Fontconfig warning: FcPattern object size does not accept value "0"
Fontconfig warning: FcPattern object size does not accept value "0"
Vale, pero quiero ver estos vídeos mientras se transmiten y en ASCII.
Encontré este artículo de blog titulado:En ascii, youtube y dejarse llevar (Wayback Machine)eso demuestra el método que hablé en la sala de chat, utilizándolo principalmente youtube-dl
como "backend" que podría descargar la transmisión de YouTube y luego redirigirla a alguna otra aplicación.
Este artículo muestra que se hace con mplayer
:
$ youtube-dl http://www.youtube.com/watch?v=OC83NA5tAGE -o - | \
mplayer -vo aa -monitorpixelaspect 0.5 -
El vídeo que se descarga youtube-dl
se redirige a través de STDOUT arriba, -o -
. Hay unademostración del efecto aquí.
Con la instalación de bibliotecas adicionales, el vídeo ASCII se puede mejorar aún más.
Vale, pero ¿quiero el vídeo en mi terminal actual?
Encontré este truco que permite reproducir videos en un xterm
artículo de O'Reilly titulado:Ver vídeos en arte ASCII.
$ xterm -fn 5x7 -geometry 250x80 -e "mplayer -vo aa:driver=curses j.mp4
Lo anterior da como resultado xterm
que se abra una ventana donde se reproduce el video.
Entonces pensé, ¿por qué no juntar la mantequilla de maní y el chocolate así?
$ xterm -fn 5x7 -geometry 250x80 -e \
"youtube-dl http://www.youtube.com/watch?v=OC83NA5tAGE -o - | \
mplayer -vo aa:driver=curses -"
¡Esto casi funciona! No estoy seguro de por qué el vídeo no se puede reproducir en la ventana, pero parece que debería poder hacerlo. La ventana se abre y comienza a reproducirse, pero luego se cierra. Veo el video por unos breves segundos y luego nada.
Quizás lo anterior lo acerque a su solución definitiva, o quizás simplemente necesite modificar un poco las opciones.
Bibliotecas adicionales
Si ha libcaca
instalado (la versión coloreada de aalib
) y reduce el tamaño de fuente gnome-terminal
a algo realmente pequeño, como digamos 3, el siguiente comando mostrará un video ASCII mucho mejor directamente dentro de la terminal:
$ CACA_DRIVER=ncurses mplayer -vo caca video.mp4
Terminales
Parecería que la elección del terminal puede influir mucho en si mplayer
se puede jugar directamente dentro del terminal o si se abre una ventana independiente. El almacenamiento en caché también mplayer
marcó una diferencia dramática al poder jugar directamente en las terminales.
Usando este comando pude reproducir terminator
, al menos durante el primer cuarto del video antes de que se cortara:
$ youtube-dl http://www.youtube.com/watch?v=OC83NA5tAGE -o - | \
mplayer -cache 32767 -vo aa:driver=curses -
La versión en color usó este comando:
$ youtube-dl http://www.youtube.com/watch?v=OC83NA5tAGE -o - | \
CACA_DRIVER=ncurses mplayer -cache 64000 -vo caca -
Estos mismos comandos podrían reproducirse en gnome-terminal
& xterm
también.
NOTA:Eso es (de izquierda a derecha) xterm
, terminator
, gnome-terminal
y terminology
.
Respuesta2
Entonces, conTerminología (por cierto, probablemente lo mejor que le haya pasado a un emulador de terminal) en el momento de escribir este artículolas siguientes obras:
ytplay() (
init() if [ "${#1}" -gt 0 ] && i=$? du= f=
then durl \! \" \# \$ \% \& \' \( \) \* \
\+ \, \/ \: \; \= \? \@ \[ \]
: >"${f:=${2:-/tmp/vid}.$(
durl "$1" 's/.*mime=[^/]*.\([^&]*\).*/\1/'
)}"
init() { loop; }
else ! echo 'NO LINK SPECIFIED!' >&3
fi
durl() if [ "${#du}" -eq 0 ]
then du=$(for c do printf 's/%%%X/\\%s/g;' "'$c" "$c"; done)
else curl -s "$1" | { shift
sed '/.*url_encoded_fmt_stream_map[^,]*url=/!d
s///;s/,.*//;s/\\u0026/\&/g;'"$du$*"; }
fi
loop() if [ "$((i=$i+1))" -le 5 ] &&
sleep "$(($i*2))"
then play || kill "$pid" || :
else ! echo 'ERROR RETRIEVING VIDEO!' >&3
fi
play() if [ -s "$f" ]
then printf '\033}bt%s\0' "$f"; exit
fi
while init "$@" || exit
do curl -s "$(durl "$1")" >"$f" & pid=$!
done 3>&2 2>/dev/null
)
El terminology
bit específico es el then
bloque en play()
la printf \033}...
línea. terminology
acepta escapes de terminal extendidos para imprimir medios en la pantalla, algo así como colores de aviso pero también video de alta definición y básicamente cualquier otra cosa que desee.
El resto es un poco de curl | sed
guión que:
- Acepta un enlace normal de YouTube como primer argumento...
ytplay 'https://www.youtube.com/watch?v=${id}'
etcétera...
- Extrae el HTML y encuentra el código javascript relevante para flujos de descarga alternativos...
- hacer
curl "$yturl" | grep url_encoded_fmt_stream_map
para ver el bloque completo.
- hacer
- Desde dentro de ese bloque, selecciona la primera transmisión alternativa ofrecida.
- Se ofrecen muchos; si hizo lo
grep
anterior, encontrará la lista en el campo"
delimitado por comillas...stream_map: "
. - Aunque al principio pensé que sólo obtendría mp4, cada vez más obtengo webms también. Así que lo edité para que fluya y para asignar la extensión del archivo por tipo de mime.
- hasta ahora- ya sea webm o mp4 - la primera transmisión alternativa es la de mayor calidad ofrecida por video -generalmente720p .mp4: que es lo que estoy buscando de todos modos, por lo que no hay lógica para seleccionar otros. Sin embargo, mi última edición agregó algunas pruebas explícitas/de modularidad para que esto sea posible. Verestepara el script perl al que hice referencia cuando escribí originalmente la función.
- Se ofrecen muchos; si hizo lo
- Analiza la
%[[:hexdigit:]]\{2\}
codificación en enlaces funcionales.- Verestepara mi referencia laboral.
- Intenta descargar el archivo hasta 5 veces con un poco de retraso.
- De forma predeterminada, el archivo lo es,
/tmp/vid.${mime-type}
pero siytplay
se llama con un segundo argumento, lo interpretará como el nombre del archivo de descarga de destino, sin dejar de agregar la extensión de acuerdo con el tipo de mime.
- De forma predeterminada, el archivo lo es,
- Si el objetivo de descarga tiene un tamaño mayor que cero después de cualquiera de sus intentos, permite que la descarga continúe en segundo plano e imprime el
terminology
archivo.coloque los medios en segundo plano ahoraescape del terminal; de lo contrario, simplemente se da por vencido y te deja con un mensaje de error todo en mayúsculas.\033}bt[LINK/FILE]\0
para jugar en ventana completa.pn
lo abriría en una nueva ventana. Hay otros para limitar geométricamente la zona de juego, por ejemplo, sólo en una parte de la ventana.
Esto ha sufrido sólo un poco más demuy mínimopruebas, pero hasta ahora ha funcionado para todos los enlaces sin excepción excepto uno, y como en realidad no estaba interesado en ver el que no funcionaba, no intenté averiguar por qué.
Si bien funcionó para todos ellos, no necesariamentejugarcada uno, y esto se debe a que al principio agregué ciegamente la .mp4
extensión al archivo de destino sin verificar si era correcta. Es posible que el que no investigué antes fuera también este. En cualquier caso, lo cambié para manejar eso.
Como mencioné antes, el único terminology
bit específico está en la última función, play()
por lo que puedes modificarla fácilmente para hacer lo que quieras con el archivo de video descargado/descargado, como usarlo con mplayer
las bibliotecas CACA de en otra terminal. o sáquelo por una vlc
ventana o lo que sea. Pero si te gustas, lo verás en alta definición en terminology
.
Ah, y por último, esto suele sermuy rapido- Mis velocidades han maximizado mi ancho de banda durante todo el tiempo hasta el momento en cada intento, pero terminology
de todos modos no necesito el archivo completo para comenzar a reproducirlo.
Aquí está funcionando:
Respuesta3
Hay un tutorial para esto en youtube:
https://www.youtube.com/watch?v=QCuq0_nY3Xk
Según ese video, lo siguiente debería funcionar:
mplayer -cookies -cookies-file /tmp/cook.txt $(youtube-dl -g --cookies /tmp/cook.txt "https://www.youtube.com/watch?v=QCuq0_nY3Xk")
Puede crear una función simple para este propósito:
playtube () {
mplayer -cookies -cookies-file /tmp/cook.txt $(youtube-dl -g --cookies /tmp/cook.txt "$1")
}
Respuesta4
Dehttps://github.com/mps-youtube/mps-youtube
sudo docker run --device /dev/snd -it --rm --name mpsyt rothgar/mpsyt