Mira videos de YouTube en la terminal

107

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).

¿Hay una manera simple de hacer esto?

Me imagino algo como esto:

$ youtube <video-url>     

Ya sé cómo reproducir un video 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 las tmuxsesiones.


Hice otra pregunta sobre cómo evitar abrir una nueva ventana .


Para aquellos que se preguntan dónde necesito dicha funcionalidad, comencé un proyecto experimental llamado TmuxOS , con el concepto de que todo debería ejecutarse dentro de una tmuxsesión .

Entonces, de hecho necesito un reproductor de video para videos locales y remotos. :-)

Ionică Bizău
fuente
2
Quieres decir así? google.com/…
caos
1
@chaos Exactamente. :-) Estoy buscando esto durante meses, pero aún no se ha encontrado nada. Decidí preguntar aquí ...
Ionică Bizău
VLC puede reproducir videos de YouTube, aunque no estoy seguro si tiene capacidades de salida de terminal.
Con mpv puedes hacer mpv <youtube url>. También funciona para muchos otros sitios de videos. Pero esto abre una nueva ventana.
Gerardo Marset
1
Esta es una pregunta fascinante, y he aprendido mucho de las respuestas. Pero por curiosidad, ¿por qué demonios necesitas hacer esto? ;-)
Trauma digital

Respuestas:

132

Puede descargar videos y / o solo el audio y luego verlos / escucharlos usando youtube-dl. El script está escrito en Python y hace uso de ffmpegcreo.

$ 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 videos, simplemente dele la URL de la página en la que desea el video 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 puede usar vlco mplayerpara 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"

OK, pero quiero ver estos videos mientras se transmiten y en ASCII

Encontré este artículo del blog titulado: En ascii, youtube y dejarlo ir, eso demuestra el método que discutí en la sala de chat, principalmente youtube-dlcomo el "backend" que podría descargar el flujo de YouTube y luego redirigirlo a alguna otra aplicación.

Este artículo muestra que se está haciendo con mplayer:

$ youtube-dl http://www.youtube.com/watch?v=OC83NA5tAGE -o - | \
    mplayer -vo aa -monitorpixelaspect 0.5 - 

El vídeo está descargando por youtube-dlse redirige a través de la salida estándar anterior, -o -. Hay una demostración del efecto aquí .

          ss # 1

Con la instalación de bibliotecas adicionales, el video ASCII se puede mejorar aún más.

               ss # 2

OK pero quiero el video en mi terminal actual?

Encontré este truco que permite reproducir videos en un xtermartículo de O'Reilly titulado: Ver videos en ASCII Art .

$ xterm -fn 5x7 -geometry 250x80 -e "mplayer -vo aa:driver=curses j.mp4

Lo anterior hace xtermque se abra una ventana donde se reproduce el video.

   ss # 3

Entonces pensé, ¿por qué no poner la mantequilla de maní y el chocolate juntos de esta manera:

$ 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 video no se puede reproducir en la ventana, pero parece que debería poder hacerlo. La ventana aparece y comienza a jugar pero luego se cierra. Veo video por unos breves segundos y luego nada.

Quizás lo anterior lo acerque a su solución definitiva, o tal vez solo necesite modificar un poco las opciones.

Bibliotecas adicionales

Si ha libcacainstalado (la versión coloreada de aalib) y reduce el tamaño de la fuente gnome-terminala algo realmente pequeño, como por ejemplo 3, el siguiente comando mostrará un video ASCII mucho mejor directamente en el terminal:

$ CACA_DRIVER=ncurses mplayer -vo caca video.mp4

   ss # 4

Terminales

Parece que la elección del terminal puede hacer un gran problema en cuanto a si mplayerpuede jugar directamente dentro del terminal o si abre una ventana separada. El almacenamiento en caché también mplayermarcó una diferencia dramática al poder jugar directamente en los terminales.

Usando este comando pude jugar 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 coloreada utiliza 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 jugar en gnome-terminal& xtermtambién.

    montaje ss

    NOTA: Eso es (de izquierda a derecha) xterm, terminator, gnome-terminal, y terminology.

slm
fuente
2
Puedes jugarlo terminology, y no solo con las bibliotecas de caca. Puede usar escapes de terminal para especificar una parte asignada de la ventana terninal y reproducirla allí en alta definición. Incluso puedes configurar el video como fondo y trabajar sobre él. terminologytambién comprende los URI: obtenga un enlace webm a su video de youtube y solo printfa la pantalla como un indicador de terminal.
mikeserv
@mikeserv: eso es genial, nunca he oído hablar de ese emulador de terminal. Lo probé y es genial que puedas reproducir videos en segundo plano, tybg my.avi¿no?
slm
Sí, prefiero el printfmétodo. Haga tybg somefile | sed -n lpara ver cómo funciona: solo usa escapes de terminal extendidos. Están documentados en la manpágina. Puedes hacer lo mismo con ty{ls,cat}. Pero esas pequeñas aplicaciones son solo viejos envoltorios de demostración de lo real y tal vez no tan capaces. De todos modos, si su versión se ha creado en los últimos dos meses, es posible que le guste la miniview tanto como a mí: ctrl + shift + h. Toda la iluminación es igual de buena, es por eso que te sugerí que la probaras recientemente. También es una locura rápida.
mikeserv
3
¿Cuáles son las bibliotecas ASCII adicionales mencionadas?
PythonNut
1
@slm muy mal, supongo que solo las compilaciones de deb-multimedia lo tienen habilitado. Me pregunto por qué los demás no lo hacen, supongo que probablemente consideran que la libcaca es una broma e hinchazón.
derobert
14

Entonces, con Terminología (probablemente lo mejor que le haya pasado a un emulador de terminal, por cierto) en el momento de escribir este artículo, funciona lo siguiente:

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 terminologybit específico es el thenbloque en play()la printf \033}...línea. terminologyacepta escapes de terminal extendidos para imprimir medios en la pantalla, algo así como colores rápidos, pero también video de alta definición y, básicamente, cualquier otra cosa que desee.

El resto es un poco de curl | sedscript que:

  1. Acepta un enlace normal de youtube como primer argumento ...
    • ytplay 'https://www.youtube.com/watch?v=${id}' y así...
  2. Extrae el HTML y encuentra el código de JavaScript relevante para secuencias de descarga alternativas ...
    • hacer curl "$yturl" | grep url_encoded_fmt_stream_mappara ver todo el bloque.
  3. Desde dentro de ese bloque, selecciona la primera secuencia alternativa ofrecida.
    • se ofrecen muchos: si hizo lo grepanterior, encontrará la lista en el campo "delimitado por comillas ...stream_map: ".
    • mientras que al principio pensé que solo obtendría mp4s cada vez más, también obtengo webms. Así que lo he editado para flujo y para asignar la extensión de archivo por tipo mime.
    • hasta ahora , ya sea webm o mp4, la primera transmisión alternativa es la más alta calidad ofrecida por video, generalmente 720p .mp4, que es lo que estoy buscando de todos modos, por lo que no hay lógica aquí para seleccionar otros. Sin embargo, mi última edición agregó algunas pruebas de modularidad / explícitas para hacer esto posible. Vea esto para el script perl al que hice referencia cuando escribí originalmente la función.
  4. Analiza la %[[:hexdigit:]]\{2\}codificación en enlaces de trabajo.
    • Vea esto para mi referencia de trabajo.
  5. Intenta descargar el archivo hasta 5 veces con un poco de retraso.
    • De manera predeterminada, el archivo es, /tmp/vid.${mime-type}pero si ytplayse llama con un segundo argumento, lo interpretará como el nombre de archivo de descarga específico, a la vez que agrega la extensión según el tipo MIME.
  6. 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 terminologylos medios colocados en segundo plano ahora escape de terminal, de lo contrario simplemente se da por vencido y le deja un mensaje de error en mayúsculas
    • \033}bt[LINK/FILE]\0para jugar a ventana completa. pnlo abriría a una nueva ventana. Hay otros para limitar geométricamente el área de juego, por ejemplo, solo para una parte de la ventana.

Esto ha experimentado solo un poco más que pruebas muy mínimas , pero hasta ahora ha funcionado para cada enlace sin falta, excepto uno, y debido a que no estaba realmente interesado en ver el que no se jugó, no intenté averiguarlo por qué.

Si bien funcionó para todos ellos, no necesariamente se reprodujo cada uno, y esto se debe a que al principio adjunté ciegamente la .mp4extensión al archivo de destino sin verificar si era correcta. Es posible que el que no examiné antes fuera solo esto también. En cualquier caso, lo cambié para manejar eso.

Como mencioné antes, el único terminologybit específico está en la última función, play()por lo que puede modificarlo fácilmente para hacer lo que quiera con el archivo de video descargado / descargado, como usarlo con mplayerlas bibliotecas CACA en otro terminal, o salta a la vlcventana o lo que sea. Pero si te gustas, lo verás en alta definición terminology.

Ah, y por último, esto suele ser muy rápido : mis velocidades han maximizado mi ancho de banda hasta el momento en cada intento, pero de terminologytodos modos no necesito el archivo completo para comenzar a reproducirlo.

Aquí está funcionando:

rocas de terminología

mikeserv
fuente
1
En lugar de /tmp/vid.mp4tal vez deberías usar mktemp --suffix=.mp4, ¿no?
Braiam
@Braiam: es una muy buena idea, pero probablemente tendría que agregar lógica para limpiar. De esta manera, al menos, siempre se sobrescribe. El archivo nunca es leído por nada que intente ejecutarlo, por lo que no lo considero un vector, a menos que terminologyel gstreamerbackend accidentalmente pueda ejecutar código ejecutable en un archivo de video ... Tal vez. Lo dudo, pero no tengo suficiente para decir con certeza. De todos modos, prefiero que siempre escriba sobre el mismo archivo a menos que diga lo contrario, pero si consigo mejorarlo, como la selección de tamaños y tal, definitivamente lo arreglaré también.
mikeserv
@Braiam, reelaborado, eche un vistazo. Probablemente un tmp dir / mktemp dedicado sea el siguiente.
mikeserv
@Ramesh: mira de nuevo. Si utilizó la última versión, esto es mejor.
mikeserv
1
@DmitriDB - el problema es que no estás imprimiendo esos escapes a terminologyen todos - los que van a tmux's ptyporque tmuxposee el lado del maestro de los que intervienen ptys y terminologypropietaria de la parte principal de tmux' s pty. Para manejar eso se puede hacer, como ... PTTY=$(tty) tmux ...entonces en la tmuxsesión como ... tybg >"$PTTY". De hecho, acabo de responder el mismo problema que tienes aquí ayer. La secuencia de comandos anterior debería funcionar como ytplay ... >"$PTTY"dentro de un multiplexor de esa manera.
mikeserv
6

Hay un tutorial para esto en youtube:

https://www.youtube.com/watch?v=QCuq0_nY3Xk

De acuerdo con 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")
}
jimmij
fuente
Esto es lo que obtengo en mi máquina: paste.ubuntu.com/8527219
Ionică Bizău
1
@ IonicăBizău intenta:mplayer <(youtube-dl -o - "https://www.youtube.com/watch?v=QCuq0_nY3Xk")
Martin von Wittich
@MartinvonWittich Está funcionando, pero no es un video ASCII, en la terminal sino en otra ventana ...: - /
Ionică Bizău
2
Alguien necesita envolver esto en un programa que permita buscar videos de youtube en la terminal y marcarlos para la descarga por lotes. y luego envolverlo una vez más para quitar el mp3 y eliminar el mp4. Podría hacerlo en algún momento si nadie más lo hace, pero no será en los próximos días.
Millie Smith
@ IonicăBizău mplayerelige automáticamente el mejor controlador de salida, y si tiene Xorg ejecutándose, probablemente elegirá el xvcontrolador. Trate de añadir la siguiente opción de mplayerelegir el controlador de la consola arte ASCII: -vo caca.
Martin von Wittich