Estou usando o Ubuntu e o comando youtube-dl
está funcionando perfeitamente bem.
Porém, agora eu quero baixar apenas uma parte de um vídeo que é muito longo. Então, eu quero baixar apenas alguns minutos desse vídeo, por exemplo, do minuto 13 ao minuto 17.
Existe alguma maneira de fazer isso?
Resposta
I não acredite que youtube-dl
sozinho fará o que você deseja. No entanto, você pode combiná-lo com um utilitário de linha de comando como o ffmpeg.
Primeiro adquira o URL real usando o youtube -dl:
youtube-dl -g "https://www.youtube.com/watch?v=V_f2QkBdbRI"
Copie a saída do comando e cole-a como parte do parâmetro -i
do próximo comando:
ffmpeg -ss 00:00:15.00 -i "OUTPUT-OF-FIRST URL" -t 00:00:10.00 -c copy out.mp4
O parâmetro -ss
nesta posição indica para descartar todas as entradas até 15 segundos no vídeo. A opção -t
indica capturar por 10 segundos. O resto do comando diz para armazenar como um mp4.
ffmpeg é uma ferramenta popular e deve estar em qualquer um dos gerenciadores de pacotes / repositórios de SO populares.
Comentários
Resposta
Adicionando a Resposta de Johnnie:
Use youtube-dl --youtube-skip-dash-manifest -g "URL"
para obter os fluxos de vídeo e áudio.
Agora use:
ffmpeg -ss 12:15 -i "1st-URL" -ss 12:15 -i "2nd-URL" -t 5:15 -map 0:v -map 1:a -c:v libx264 -c:a aac output.mkv
Você “precisará usar a opção -ss
para cada fluxo. Também recomendo fazer isso cerca de 30 segundos antes e depois usar outro -ss 30
para evitar a perda de quadros-chave. Aqui está um exemplo real usando um dos meus vídeos do youtube.
youtube-dl --youtube-skip-dash-manifest -g https://www.youtube.com/watch?v=gESHIrvIQQo
Resultado:
https://r3---sn-mv-cvne.googlevideo.com/videoplayback/id/80448722bbc8410a/itag/298/source/youtube/requiressl/yes/mn/sn-mv-cvne/ei/BgifWfmmL4iE8wSlv47oCA/mm/31/pl/23/mv/m/ms/au/initcwndbps/11447500/ratebypass/yes/mime/video%2Fmp4/otfp/1/gir/yes/clen/5231968228/lmt/1502479662079137/dur/18575.164/key/dg_yt0/signature/4FFB9B0B7E1703B31F5D07DAD579B55F17EF7BAA.0CB63905C89DD4D33F90CF3AAD728F1ECDFCB9B3/mt/1503594423/ip/206.34.122.70/ipbits/0/expire/1503616102/sparams/ip,ipbits,expire,id,itag,source,requiressl,mn,ei,mm,pl,mv,ms,initcwndbps,ratebypass,mime,otfp,gir,clen,lmt,dur/ https://r3---sn-mv-cvne.googlevideo.com/videoplayback/id/80448722bbc8410a/itag/140/source/youtube/requiressl/yes/mn/sn-mv-cvne/ei/BgifWfmmL4iE8wSlv47oCA/mm/31/pl/23/mv/m/ms/au/initcwndbps/11447500/ratebypass/yes/mime/audio%2Fmp4/otfp/1/gir/yes/clen/295235970/lmt/1502480001536214/dur/18575.243/key/dg_yt0/signature/4CD42047D1D5C714377350905C1CC5CBA37C0009.6EED1FC92D17A096235C32E48F4B15DEF7DD99B0/mt/1503594423/ip/206.34.122.70/ipbits/0/expire/1503616102/sparams/ip,ipbits,expire,id,itag,source,requiressl,mn,ei,mm,pl,mv,ms,initcwndbps,ratebypass,mime,otfp,gir,clen,lmt,dur/
Eu queria cortar de 43:00 para 50:10, então “vou fazer -ss 42:30
(me dando alguns segundos para capturar um bom quadro-chave) em ambas as entradas e, em seguida, faça um -ss 30
após as entradas para começar às 43:00.
Usarei map
para mapear o vídeo 0:v
e o áudio 1:a
(0 significa a primeira entrada, que é o vídeo e 1 significa a segunda entrada, que é o áudio) e, em seguida, escolha minhas opções de codificação.
# The first URL video_url="https://r3---sn-mv-cvne.googlevideo.com/videoplayback/id/80448722bbc8410a/itag/298/source/youtube/requiressl/yes/pl/23/ei/5wCfWY6dBeOj8gSSxZaACQ/mv/m/initcwndbps/5055000/ms/au/mm/31/mn/sn-mv-cvne/ratebypass/yes/mime/video%2Fmp4/otfp/1/gir/yes/clen/5231968228/lmt/1502479662079137/dur/18575.164/key/dg_yt0/beids/%5B9466591%5D/mt/1503592562/signature/8CCFBF5CAB97341D0CB1F34E85AB6EE20FC7A03E.7679F39A8603CF41A95F10232E2A921EB0774101/ip/206.34.122.70/ipbits/0/expire/1503614279/sparams/ip,ipbits,expire,id,itag,source,requiressl,pl,ei,mv,initcwndbps,ms,mm,mn,ratebypass,mime,otfp,gir,clen,lmt,dur/" # The second URL audio_url="https://r3---sn-mv-cvne.googlevideo.com/videoplayback/id/80448722bbc8410a/itag/140/source/youtube/requiressl/yes/pl/23/ei/5wCfWY6dBeOj8gSSxZaACQ/mv/m/initcwndbps/5055000/ms/au/mm/31/mn/sn-mv-cvne/ratebypass/yes/mime/audio%2Fmp4/otfp/1/gir/yes/clen/295235970/lmt/1502480001536214/dur/18575.243/key/dg_yt0/beids/%5B9466591%5D/mt/1503592562/signature/4AACC8E27F9036D36D4D623A771A9F2BAC4674BA.7E4F4FB4DC023E3FE491A991F0F9F2329648DE9D/ip/206.34.122.70/ipbits/0/expire/1503614279/sparams/ip,ipbits,expire,id,itag,source,requiressl,pl,ei,mv,initcwndbps,ms,mm,mn,ratebypass,mime,otfp,gir,clen,lmt,dur/" ffmpeg -ss 42:30 -i "$video_url" -ss 42:30 -i "$audio_url" -map 0:v -map 1:a -ss 30 -t 7:10 -c:v libx264 -c:a aac gog-vs-triv.mkv
Crédito a Jakub Vrána por --youtube-skip-dash-manifest
solução.
Comentários
- Obrigado. Eu não tinha certeza de como obter um som para postar @Johnnie. Seu post respondeu.
- Qual é a diferença fer de usar
--postprocessor-args
diretamente no youtube-dl? - @daGo – acredito que
youtube-dl --postprocessor-args
baixará o vídeo inteiro e então edite-o até o intervalo selecionado, enquanto esta resposta usayoutube-dl
apenas para obter alguns URLs especiais.ffmpeg
então usa esses URLs para baixar apenas o intervalo necessário. Então, se você quiser extrair 2 minutos de um vídeo de aula de 2 horas, esta resposta vai economizar muito download. - Isso funciona com a maioria dos vídeos do YT, mas estou tentando isso com um vídeo de 9 horas que foi transmitido ao vivo anteriormente (e agora concluído) e recebo ” Dados inválidos encontrados ao processar a entrada “. A principal diferença é que a saída de
youtube-dl -g
é diferente. Com a maioria dos vídeos, tem a estrutura."https://r3---sn-mv-cvne.googlevideo.com/videoplayback/id/8..."
mas para este vídeo tem a estrutura."https://manifest.googlevideo.com/api/manifest/dash/expire/15956..."
(truncado para espaço). Idéias para fazer isso funcionar? - @LeftoverSalad Encontrou uma solução .
Resposta
ffmpeg $(youtube-dl -g "https://www.youtube.com/watch?v=oHg5SJYRHA0" | sed "s/.*/-ss 00:05 -i &/") -t 01:00 -c copy out.mkv
Edite o URL e -ss
, -t
vezes para usar este comando. Ele cria os argumentos, usando URLs de vídeo e áudio, semelhantes a esta resposta de @godofgrunts.Nenhuma aspa é usada para $()
porque isso produz dois argumentos separados para ffmpeg
.
Comentários
- Você poderia explicar o que ele faz, como funciona?
- É ‘ apenas uma versão mais concisa de @ Godofgrunts responde, usando sed para economizar algum tempo pegando manualmente as URLs e copiando / colando nos horários de início (-ss 00:05). @godofgrunts tem alguns sinalizadores extras
-map 0:v -map 1:a -c:v libx264 -c:a aac
que podem melhorar a qualidade. Também gosto de adicionaryoutube-dl -f bestvideo+bestaudio
para ter certeza de que ‘ estou recebendo a versão da mais alta qualidade. - ffmpeg.zeranoe.com/builds para Windows.
- Os ” sinalizadores extras ” lidar com os dois fluxos (vídeo e áudio) que eu acho que você está manipulando mal – IIUC eles não têm nada a ver com a melhoria da qualidade (bem, ter som é provavelmente uma marca de qualidade aprimorada :-)) a resposta de @godofgrunts abaixo parece estar correta.
Resposta
youtube-dl
suporta a passagem de argumentos para o pós-processador subjacente (testado com a versão 2017.08.27.1):
youtube-dl -x --postprocessor-args "-ss 00:13:00.00 -t 00:04:00.00" https://youtu.be/...
Isso é basicamente o mesmo que fazer o pós-processamento com ffmpeg
por conta própria depois de baixar o arquivo primeiro.
Comentários
- mas ainda será necessário fazer wnload o vídeo inteiro e, em seguida, corte a parte desejada
- Estou recebendo o erro
unable to obtain file audio codec with ffprobe
. Você pode me ajudar com isso. Estou usando o CentOS 7 - Observe que o sinalizador
-x
baixa apenas o áudio. Omita-o do comando se quiser áudio e vídeo. 🙂 - Isso não funcionará de maneira confiável, pois
—postprocessor-args
é aplicado várias vezes em alguns casos. Veja github.com/ytdl-org/youtube-dl/issues/26863
Resposta
Esta solicitação de recurso ainda não foi implementada no youtube-dl. Veja o problema # 622 e muitas duplicatas dele no github.
Resposta
Use o parâmetro --postprocessor-args
para passar a saída de áudio / vídeo para ffmpeg
para ser editado (o processador). O pós-processador precisa ser ffmpeg
instalado.
--postprocessor-args
leva 3 argumentos & valores (por exemplo, há mais, verifique a página de manual de ffmpeg
):
-
-ss HH:MM:SS
: hora de início para levar -
-to HH:MM:SS
: hora de término -
-t HH:MM:SS
: hora duração necessária
Exemplos:
- Comece a codificação em 15 segundos e pare em 1 minuto e 20 segundos
$ youtube-dl --postprocessor-args "-ss 0:0:15 -to 0:1:20" "[video_URL]"
- Comece a codificação em 15 segundos e leve apenas os próximos 3 minutos 5 segundos
$ youtube-dl --postprocessor-args "-ss 0:0:15 -t 0:3:5" "[video_URL]"
PS: youtube-dl
fará download de toda a mídia antes de processá-la e a removerá depois.
Comentários
- Sim! Muito limpo e fácil de lembrar.
- Isso não funcionará de maneira confiável, pois
—postprocessor-args
é aplicado várias vezes em alguns casos. Veja github.com/ytdl-org/youtube-dl/issues/26863
Resposta
Isso não responde completamente à pergunta de OP, mas há uma maneira de baixar um stream do início até uma duração específica sem ter que baixar o stream completo. Como o YouTube oferece suporte para currículos, podemos solicitar conteúdo parcial usando o cabeçalho Range
.
Primeiro buscamos os URLs de stream:
$ youtube-dl -g https://www.youtube.com/watch?v=yysk8s2vih8 https://r1---sn-npoeenee.googlevideo.com/videoplayback?source=youtu... https://r1---sn-npoeenee.googlevideo.com/videoplayback?source=youtu...
Isso deve gerar dois URLs (cada um para fluxos de vídeo e áudio).
Agora, envie uma solicitação principal para o primeiro URL (que vincula ao fluxo de vídeo) para obter a duração total do conteúdo deste stream:
$ curl "1st-URL" -sI | grep Content-Length Content-Length: 64380504
Agora, dividimos a duração total do conteúdo pelo total de segundos no vídeo (o vídeo do YouTube tem uma duração de 4 min e 7 segundos, que são 247 segundos.) para obter aproximadamente a duração do conteúdo de 1 segundo:
64380504 / 247 ≈ 260650
Nós multiplicamos esse valor com (número de segundos que queremos buscar desde o início + 1)
(adicionamos um para também contabilizar aproximadamente o espaço extra ocupado pelos metadados que são colocados no início do fluxo)
Por exemplo, para buscar aproximadamente os primeiros 10 segundos, você precisará buscar os primeiros 260650 * 11 = 2867150
bytes, então fazemos uma solicitação com o cabeçalho Range
:
$ curl "1st-URL" -H "Range: bytes=0-2867150" -o ten_secs.mp4
Isso deve baixar apenas o primeiro 10 segs.O arquivo baixado deve poder ser reproduzido, mas é melhor deixar o FFmpeg corrigir os metadados incorretos:
$ ffmpeg -i ten_secs.mp4 -c copy corrected_ten_secs.mp4
Também podemos baixar apenas a parte inicial do áudio (2º- URL) de forma semelhante (o comprimento do conteúdo seria diferente, mas o total de segundos permaneceria o mesmo).
Baixar qualquer parte do meio do vídeo também deve ser possível desta forma, mas provavelmente será muito mais complicado porque o YouTube coloca os metadados no início do stream (nos primeiros bytes) e sem estar presente na mídia baixada, o stream não será reproduzido.
EDITAR: Isso só funcionará em sites com suporte para currículo, digamos o YouTube. Não funcionará para outros sites.
Resposta
Você pode baixar desde o início até um ponto sem baixando tudo e editando. Essa é a metade do que esta pergunta pergunta:
interromper o download com
^C
- Eu só tentei isso com
mp4
- não funcionarei com vídeo separado e áudio, você precisa de um formato com ambos. Por padrão, ytdl geralmente obtém vídeo e áudio separados e depois os mescla. Use
-F
para ver os formatos disponíveis e escolha ummp4
que tem ambos. Por exemplo,-f18
ou-f22
geralmente estão lá. - você “Terei que estimar a partir da porcentagem baixada (que não é linear; a taxa de compactação varia com o tempo).
Sim. É um hack .
Outra pergunta: se você quiser os formatos de vídeo e áudio separados, você poderia baixar parte de cada um separadamente (usando ^c
como aqui) e depois mesclá-los manualmente? Não acho que funcionará para alguns formatos.
Resposta
Fiz um script implementando @godofgrunts answer aqui
#!/bin/bash #taken from https://unix.stackexchange.com/a/388148/48971 if [ $# -lt 4 ]; then echo "Usage: $0 <youtube"s URL> <HH:mm:ss from time> <HH:mm:ss to time> <output_file_name>" echo "e.g.:" echo "$0 https://www.youtube.com/watch?v=T1n5gXIPyws 00:00:25 00:00:42 intro.mp4" exit 1 fi echo "processing..." from=$(date "+%s" -d "UTC 01/01/1970 $2") to=$(date "+%s" -d "UTC 01/01/1970 $3") from_pre=$(($from - 30)) if [ $from_pre -lt 0 ] then from_pre=0 fi from_pre_command_print=$(date -u "+%T" -d @$from_pre) from_command_print=$(date -u "+%T" -d @$(($from - $from_pre)))$(grep -o "\..*" <<< $2) to_command_print=$(date -u "+%T" -d @$(($to - $from_pre)))$(grep -o "\..*" <<< $3) command="ffmpeg " for uri in $(youtube-dl -g $1) do command+="-ss $from_pre_command_print -i $uri " done command+="-ss $from_command_print -to $to_command_print $4" echo "downloading with the following command:" echo "$command" $command
Eu também enviei para Gitlab “trechos
Resposta
Fiz um aplicativo de frasco que pode fazer o que você quiser. Sei que a postagem é antiga, mas o problema persiste.
Você pode encontrá-lo aqui
Ele pode analisar texto para links do YouTube também. Basta fornecer, por exemplo:
YouTube.com/blahblah start-1:20
Isso fará o download de um vídeo de 0-1: 22 (podem surgir pequenas diferenças por causa dos quadros-chave). Ele também pode baixar vídeos inteiros, apenas omita o intervalo de tempo nesse caso.
Resposta
Para todos os preguiçosos que não “t deseja usar mais de um comando, faça o seguinte:
youtube-dl.exe https://www.youtube.com/watch?v=MJD39Aja1Is --external-downloader ffmpeg --external-downloader-args "-ss 00:00:10.00 -t 00:01:00.00"
Agora você pode combinar as opções de youtube-dl.exe
e ffmpeg
como escolher o formato, remover o vídeo e cortar o arquivo de áudio etc. (talvez cortar o arquivo de vídeo e não converter em um arquivo de áudio, o que quer que aconteça primeiro)
youtube-dl.exe -f 251 https://www.youtube.com/watch?v=MJD39Aja1Is -x --external-downloader ffmpeg --external-downloader-args "-ss 00:00:10.00 -t 00:01:00.00"
Comentários
- seu comando não funciona no GNU / Linux: usamos
youtube-dl
em vez deyoutube-dl.exe
. Effmpeg
me disseInvalid duration specification for ss: 00.00.10.00
, deve ser-ss 00:00:30.00
com dois pontos em vez de pontos, exceto para o último. - @ ewin-goisot Lamento, mas aconteceu porque não ‘ t copiar e colar todo o comando após os testes ting it. Agora deve funcionar. o problema era a definição do tempo. tem que ser 00: 00: 00.00 2 vezes o dobro do ponto, do que apenas 1 ponto. como hh: mm: ss.ms
- com
00:00:00.0
, funciona melhor, posso baixar uma parte do vídeo. Ainda tenho um problema (com o seu comando e a maioria dos outros): ele baixa 5 ou 10 segundos a mais. A solução é dada na resposta de @godofgrunts ‘:-ss 42:30 -i "$video_url" -ss 42:30 -i "$audio_url" -map 0:v -map 1:a -ss 30
começando 30 segundos antes do início da porção e adicionando-ss 30
no final. Portanto, preciso usar várias vezes a opção-ss
no mesmo comando. Existe uma maneira de fazer o mesmo com--external-downloader-args
? - ah, desculpe, não estou familiarizado com a mistura de diferentes fluxos. mas se você quiser pegar apenas o melhor material de áudio e vídeo do mesmo vídeo, pode fazê-lo com o youtube-dl
Resposta
Para adicionar à resposta do @hyperpallium: OP não mencionou que o vídeo que estava baixando tinha que ser do YouTube.
O YouTube é ridiculamente restritivo com seus vídeos, eles dividem o fluxos de áudio e vídeo em arquivos diferentes e rastreiam você / vendem seus dados; portanto, pode-se ter dificuldades com o método de baixá-lo parcialmente e depois pressionar Ctrl + C .
Com a youtube-dl
versão 2020.11.17 no Microsoft Windows versão 10.0.17134.1304 baixei parte de um vídeo de archive.org:
E:\cs>youtube-dl --abort-on-unavailable-fragment https://archive.org/download/beastars-season-1-1080p/%5BHCS%5D%20Beastars%20-%2003%20%5B1080p%5D.mkv [generic] [HCS] Beastars - 03 [1080p]: Requesting header [redirect] Following redirect to https://ia601504.us.archive.org/14/items/beastars-season-1-1080p/%5BHCS%5D%20Beastars%20-%2003%20%5B1080p%5D.mkv [generic] [HCS] Beastars - 03 [1080p]: Requesting header WARNING: Falling back on generic information extractor. [generic] [HCS] Beastars - 03 [1080p]: Downloading webpage WARNING: URL could be a direct video link, returning it as such. [download] Destination: [HCS] Beastars - 03 [1080p]-[HCS] Beastars - 03 [1080p].mkv [download] 2.3% of 513.77MiB at 839.68KiB/s ETA 10:12 ERROR: Interrupted by user E:\cs>ren "[HCS] Beastars - 03 [1080p]-[HCS] Beastars - 03 [1080p].mkv.part" "[HCS] Beastars - 03 [1080p]-[HCS] Beastars - 03 [1080p].mkv" E:\cs>ffmpeg -i "[HCS] Beastars - 03 [1080p]-[HCS] Beastars - 03 [1080p].mkv" "[HCS] Beastars - 03 [1080p].mp4" ffmpeg version N-91990-g49c67e79ca Copyright (c) 2000-2018 the FFmpeg developers built with gcc 8.2.1 (GCC) 20180813 [stdout text] Stream #0:1(jpn): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default) Metadata: encoder : Lavc58.30.100 aac [matroska,webm @ 0000020c8f28a2c0] Read errorme=00:00:33.96 bitrate=2099.5kbits/s speed=0.0185x frame= 823 fps=0.3 q=-1.0 Lsize= 9677kB time=00:00:34.56 bitrate=2293.8kbits/s speed=0.0147x video:9134kB audio:519kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.248960% [libx264 @ 0000020c8f3423c0] frame I:25 Avg QP:14.71 size: 56865 [stdout] E:\cs>youtube-dl -v [debug] System config: [] [debug] User config: [] [debug] Custom config: [] [debug] Command-line args: ["-v"] [debug] Encodings: locale cp1252, fs mbcs, out cp437, pref cp1252 [debug] youtube-dl version 2020.11.17 [debug] Python version 3.4.4 (CPython) - Windows-10-10.0.17134 [debug] exe versions: ffmpeg 3.4, ffprobe N-91990-g49c67e79ca [debug] Proxy map: {} Usage: youtube-dl [OPTIONS] URL [URL...]
O arquivo MKV que terminei era ” 00:22:57 ” em ” duração total “, mas terminou após 34 segundos. O vídeo MP4 que terminei tinha 00:00:34 segundos de duração total, terminou depois de 34 segundos, e o vídeo e o áudio foram reproduzidos perfeitamente / como pretendido.
Completo cmd.exe
o log está aqui
Então, em resumo, execute
youtube-dl --abort-on-unavailable-fragment [URL to video file]
(a opção --abort-on-unavailable-fragment
pode ser importante, pois você acaba interrompendo o download com Ctrl + C ), deixe-o baixar um pouco e pressione Ctrl + C .
Opcional: renomeie o [file].mkv.part
arquivo para [file].mkv
. Converter o MKV em MP4 provavelmente também é opcional.
Resposta
Alguém fez um script em lote (para Windows) que baixa o arquivo e extrai a parte desejada:
@ECHO off :Input ECHO. SET url= ECHO Enter Youtube-url: SET /P url= IF "%url%" EQU "" GOTO End IF "%url: =%" NEQ "%url%" GOTO Input ECHO Enter start time (in seconds, or in hh:mm:ss[.xxx] form): SET /P start= ECHO Enter duration (in seconds, or in hh:mm:ss[.xxx] form): SET /P dur= ECHO. FOR /F "delims==" %%A IN ("youtube-dl.exe --no-warnings --get-filename "%url%"") DO SET filename=%%A FOR /F %%B IN ("youtube-dl.exe -g "%url%"") DO ( ffmpeg.exe -hide_banner -ss "%start%" -i "%%B" -c copy -t "%dur%" "%filename%" ) GOTO Input :End
ffmpeg -i "OUTPUT-OF-FIRST URL" -ss 00:13:00.00 -to 00:17:00.00 -c copy out.mp4
ffmpeg
fará o download apenas da parte que você especificar.youtube-dl
com o-g
a opção sempre retornará 403 proibido para mim. Usar o youtube-dl sozinho para baixar o vídeo sempre funcionará perfeitamente.