Assista a vídeos do YouTube no terminal

107

Estou procurando uma maneira de assistir vídeos do YouTube no terminal (não em um navegador ou outra janela, mas ali mesmo, em qualquer sessão do bash).

Existe uma maneira simples de fazer isso?

Eu imagino algo assim:

$ youtube <video-url>     

Eu já sei como reproduzir um vídeo usando mplayer:

$ mplayer -vo caca local-file.avi

No entanto, isso abre uma nova janela. Seria legal jogá-lo no terminal.

Além disso, deve ser compatível com as tmuxsessões.


Fiz outra pergunta sobre como impedir a abertura de uma nova janela .


Para aqueles que se perguntam onde eu preciso dessa funcionalidade, iniciei um projeto experimental chamado TmuxOS - com o conceito de que tudo deve ser executado dentro de uma tmuxsessão .

Então, de fato, preciso de um player de vídeo para vídeos locais e remotos. :-)

Ionică Bizău
fonte
2
Você quer dizer assim? google.com/…
caos
11
@chaos Exatamente. :-) Estou procurando isso há meses, mas nada foi encontrado ainda. Decidi perguntar aqui ...
Ionică Bizău
O VLC pode reproduzir vídeos do YouTube, embora não tenha certeza se possui recursos de saída de terminal.
Com mpv você pode fazer mpv <youtube url>. Também funciona para vários outros sites de vídeo. Mas isso abre uma nova janela.
Gerardo Marset
11
Esta é uma pergunta fascinante, e eu aprendi muito com as respostas. Mas por curiosidade - por que diabos você precisa fazer isso? ;-)
Digital Trauma

Respostas:

132

Você pode baixar vídeos e / ou apenas o áudio e depois assistir / ouvir usando youtube-dl. O script é escrito em Python e faz uso de ffmpegeu acredito.

$ 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 baixar vídeos, basta fornecer o URL da página em que você deseja que o vídeo e o script façam o 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

Você pode usar vlcou mplayerassistir a eles 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, mas eu quero assistir esses vídeos enquanto eles são transmitidos e em ASCII

Eu encontrei este artigo do blog intitulado: No ASCII, youtube e deixar ir, que demonstra o método que discuti na sala de bate-papo, usando principalmente youtube-dlcomo o "back-end" que poderia fazer o download do fluxo do YouTube e redirecioná-lo para outro aplicativo.

Este artigo mostra que está sendo feito com mplayer:

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

O vídeo baixado por youtube-dlé redirecionado via STDOUT acima -o -,. Há uma demonstração do efeito aqui .

          ss # 1

Com a instalação de bibliotecas adicionais, o vídeo ASCII pode ser aprimorado ainda mais.

               ss # 2

OK, mas eu quero o vídeo no meu terminal atual?

Encontrei esse truque que permite que o vídeo seja reproduzido em uma xtermarticulação de O'Reilly intitulada: Assista a vídeos na arte ASCII .

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

O resultado acima resulta em uma xtermjanela sendo aberta onde o vídeo é reproduzido.

   ss # 3

Então pensei: por que não juntar a manteiga de amendoim e o chocolate assim:

$ xterm -fn 5x7 -geometry 250x80 -e \
    "youtube-dl http://www.youtube.com/watch?v=OC83NA5tAGE -o - | \
    mplayer -vo aa:driver=curses -"

Isso quase funciona! Não sei por que o vídeo não pode ser reproduzido na janela, mas parece que deveria ser capaz. A janela aparece e começa a tocar, mas depois fecha. Eu vejo o vídeo por alguns breves segundos e depois nada.

Talvez o exposto acima o aproxime da sua solução definitiva ou talvez precise apenas de um pouco de ajustes nas opções.

Bibliotecas adicionais

Se você libcacainstalou (a versão colorida aalib) e reduziu o tamanho da fonte gnome-terminalpara algo realmente pequeno, como digamos 3, o comando a seguir exibirá um vídeo ASCII muito mais bonito diretamente no terminal:

$ CACA_DRIVER=ncurses mplayer -vo caca video.mp4

   ss # 4

Terminais

Parece que a escolha do terminal pode ser importante para saber se é mplayerpossível jogar diretamente dentro do terminal ou se ele abre uma janela separada. O armazenamento em cache também mplayerfez uma diferença dramática em poder tocar diretamente nos terminais.

Usando este comando, eu pude reproduzir terminator, pelo menos nos primeiros 1/4 do vídeo antes de cortar:

$ youtube-dl http://www.youtube.com/watch?v=OC83NA5tAGE -o - | \
    mplayer -cache 32767 -vo aa:driver=curses -

A versão colorida usou este comando:

$ youtube-dl http://www.youtube.com/watch?v=OC83NA5tAGE -o - | \
    CACA_DRIVER=ncurses mplayer -cache 64000 -vo caca -

Esses mesmos comandos também podem ser reproduzidos no gnome-terminal& xterm.

    montagem ss

    NOTA: É (da esquerda para direita) xterm, terminator, gnome-terminal, e terminology.

slm
fonte
2
Você pode jogar terminology- e não apenas com os caca libs. Você pode usar escapes de terminal para especificar uma parte mapeada da janela terninal e reproduzi-la ali mesmo em alta definição. Você pode até definir o vídeo como pano de fundo e trabalhar nele. terminologytambém entende os URIs - obtenha um link de webm para o seu vídeo do youtube e apenas printfna tela como um prompt de terminal.
mikeserv
@ mikeserv - isso é legal, nunca ouvi falar desse emulador de terminal. Eu tentei e é legal que você possa reproduzir vídeos em segundo plano, tybg my.avifaça.
slm
Sim - eu prefiro o printfmétodo. Faça tybg somefile | sed -n lpara ver como funciona - ele apenas usa escapes de terminal estendidos. Eles estão documentados na manpágina. Você pode fazer o mesmo com ty{ls,cat}. Mas esses pequenos aplicativos são apenas antigos invólucros de demonstração da coisa real e talvez não sejam tão capazes. De qualquer forma, se sua versão foi criada nos últimos dois meses, você pode gostar da miniview tanto quanto eu - pressione ctrl + shift + h. Toda a iluminação é igualmente boa - é por isso que sugeri que você a experimentasse recentemente. Também é uma loucura rápida.
mikeserv
3
Quais são as bibliotecas ASCII adicionais mencionadas?
PythonNut
11
@ slm muito ruim, acho que apenas as compilações deb-multimedia o habilitam. Me pergunto por que os outros não, acho que provavelmente consideram a libcaca uma piada e inchaço.
Derobert 15/10
14

Portanto, com a Terminologia (provavelmente a melhor coisa que já aconteceu a um emulador de terminal, a propósito) no momento da redação deste artigo, o seguinte funciona:

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
)

O terminologybit específico é o thenbloco play()- a printf \033}...linha. terminologyaceita fugas de terminal estendidas para mídia de impressão na tela - como cores prontas, mas também vídeo em alta definição e basicamente o que mais você quiser.

O resto é um pouco de curl | sedscript que:

  1. Aceita um link regular do youtube como seu primeiro argumento ...
    • ytplay 'https://www.youtube.com/watch?v=${id}' e assim por diante...
  2. Puxa o HTML e encontra o código javascript relevante para fluxos de download alternativos ...
    • fazer curl "$yturl" | grep url_encoded_fmt_stream_mappara ver todo o bloco.
  3. Dentro desse bloco, ele seleciona o primeiro fluxo alternativo oferecido.
    • muitos são oferecidos - se você fez o grepexposto acima, encontrará a lista no campo "delimitado por aspas ...stream_map: ".
    • enquanto no começo eu pensava que só conseguiria mp4s mais e mais também conseguiria webms. Então, eu o editei para fluxo e para atribuir a extensão do arquivo por tipo MIME.
    • até agora - seja webm ou mp4 - o primeiro fluxo alternativo é a mais alta qualidade oferecida por vídeo - geralmente 720p .mp4 - que é o que estou procurando de qualquer maneira e, portanto, não há lógica aqui para selecionar outras. Minha edição mais recente adicionou alguns testes de modularidade / explícitos para tornar isso possível. Veja isso para o script perl que referi ao escrever originalmente a função.
  4. Analisa a %[[:hexdigit:]]\{2\}codificação em links de trabalho.
    • Veja isso para minha referência de trabalho.
  5. Tenta baixar o arquivo até 5 vezes com um pouco de retirada.
    • Por padrão, o arquivo é, /tmp/vid.${mime-type}mas se ytplayfor chamado com um segundo argumento, ele interpretará isso como o nome do arquivo de download direcionado - enquanto ainda anexa a extensão de acordo com o tipo mime.
  6. Se o destino do download estiver em um tamanho maior que zero após uma de suas tentativas, ele permitirá que o download continue em segundo plano e imprima terminologya mídia de impressão em segundo plano agora escape terminal; caso contrário, ele simplesmente desiste e deixa uma mensagem de erro em maiúsculas.
    • \033}bt[LINK/FILE]\0para reprodução em janela cheia. pnabriria para uma nova janela. Existem outras para limitar geometricamente a área de jogo - como apenas para uma parte da janela, por exemplo.

Isso passou por um pouco mais do que testes mínimos , mas até agora funcionou para todos os links sem falhas, exceto um - e porque eu não estava realmente interessado em assistir ao que não tocava, não tentei descobrir porque.

Embora funcionasse para todos eles, não necessariamente reproduzia cada um - e isso ocorre porque no começo eu anexei cegamente a .mp4extensão ao arquivo de destino sem verificar se estava correta. É possível que o que eu não examinei antes fosse apenas isso também. De qualquer forma, eu mudei para lidar com isso.

Como mencionei antes, o único terminologybit específico está na última função - play()- e você pode alterá-lo facilmente para fazer o que quiser com o arquivo de vídeo baixado / baixado - como usá-lo com mplayeras bibliotecas CACA de outro terminal, ou então abra-o em uma vlcjanela ou o que for. Mas se você gosta de si mesmo, assistirá em alta definição terminology.

Ah, e por último, isso geralmente é muito rápido - minhas velocidades aumentaram minha largura de banda pela duração até agora em todas as tentativas, mas terminologynão precisam do arquivo inteiro para começar a reproduzi-lo.

Aqui está funcionando:

rochas terminológicas

mikeserv
fonte
11
Em vez de /tmp/vid.mp4talvez você deva usar mktemp --suffix=.mp4, não?
Braiam
@ Braiam - é uma ideia muito boa, mas provavelmente teria que adicionar lógica para limpar. Desta forma, pelo menos, sempre se substitui. O arquivo nunca é lido por nada que tente executá-lo e, portanto, não o considero um vetor - a menos que terminologyo gstreamerback-end possa acidentalmente executar código executável em um arquivo de vídeo ... Talvez. Duvido, mas não o suficiente para ter certeza. De qualquer forma, prefiro que sempre escreva sobre o mesmo arquivo, a menos que eu diga o contrário, mas se eu tentar melhorar - como a escolha do tamanho e outras coisas - definitivamente vou corrigir isso também.
mikeserv
@Braiam - reformulado - dê uma olhada. Provavelmente, um tmp dir / mktemp dedicado é o próximo.
mikeserv
@Ramesh - olhe novamente. Se você usou a última versão, isso é melhor.
mikeserv
11
@DmitriDB - o problema é que você não está imprimindo esses escapes para terminologya todos - aqueles vão tmux's ptyporque tmuxdetém lado o mestre dos intervenientes ptys e terminologyé dono de lado o mestre de tmux' s pty. Para lidar com isso você pode fazer como ... PTTY=$(tty) tmux ...então na tmuxsessão como ... tybg >"$PTTY". Na verdade, acabei de responder o mesmo problema que você está tendo aqui ontem. O script acima deve funcionar como ytplay ... >"$PTTY"dentro de um multiplexador dessa maneira.
mikeserv
6

Há um tutorial para isso no youtube:

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

De acordo com o vídeo, o seguinte deve funcionar:

mplayer -cookies -cookies-file /tmp/cook.txt $(youtube-dl -g --cookies /tmp/cook.txt "https://www.youtube.com/watch?v=QCuq0_nY3Xk")

Você pode criar uma função simples para esta finalidade:

playtube () {
mplayer -cookies -cookies-file /tmp/cook.txt $(youtube-dl -g --cookies /tmp/cook.txt "$1")
}
jimmij
fonte
Isto é o que recebo na minha máquina: paste.ubuntu.com/8527219
Ionică Bizău
11
@ IonicăBizău try:mplayer <(youtube-dl -o - "https://www.youtube.com/watch?v=QCuq0_nY3Xk")
Martin von Wittich
@MartinvonWittich Está funcionando, mas não é um vídeo ASCII, no terminal, mas em outra janela ...: - /
Ionică Bizău
2
Alguém precisa agrupar isso em um programa que permita procurar vídeos do youtube no terminal e marcá-los para download em lote. e envolva-o mais uma vez para remover o mp3 e excluir o mp4. Eu poderia fazê-lo em algum momento, se mais ninguém fizer, mas não será nos próximos dias.
Millie Smith
O @ IonicăBizău mplayerescolhe automaticamente o melhor driver de saída e, se você tiver o Xorg em execução, provavelmente escolherá o xvdriver. Tente adicionar a seguinte opção mplayerde escolher o driver arte consola ASCII: -vo caca.
Martin von Wittich