Come scaricare parte del video con il comando youtube-dl?


64

Sto usando Ubuntu e il comando youtube-dl funziona perfettamente.

Voglio scaricare solo una parte del video troppo lungo. Quindi voglio scaricare solo pochi minuti del video. Esempio da 13 minuti a 17 minuti.

C'è un modo per farlo

Risposte:


46

Non credo che youtube-dlsolo farà ciò che vuoi. Tuttavia è possibile combinarlo con un'utilità della riga di comando come ffmpeg.

Per prima cosa acquisisci l'URL effettivo usando youtube-dl:

youtube-dl -g "https://www.youtube.com/watch?v=V_f2QkBdbRI"

Copia l'output del comando e incollalo come parte del -iparametro del comando successivo:

ffmpeg -i "OUTPUT-OF-FIRST URL" -ss 00:00:15.00 -t 00:00:10.00 -c copy out.mp4

Il -ssparametro in questa posizione indica di eliminare tutti gli input fino a 15 secondi nel video. L' -topzione indica di acquisire per 10 secondi. Il resto del comando dice di memorizzarlo come mp4.

ffmpeg è uno strumento popolare e dovrebbe trovarsi in uno dei più popolari repository / gestori di pacchetti del sistema operativo.


8
Quindi, in sostanza, devi ancora scaricare l'intero video e ritagliarlo tu stesso
Antony,

12
È possibile utilizzare l'opzione -to anziché -t se si desidera specificare il tempo per terminare la sezione video. ffmpeg -i "OUTPUT-OF-FIRST URL" -ss 00:13:00.00 -to 00:17:00.00 -c copy out.mp4
ˆᵛˆ

5
@Antony scaricherà ffmpegeffettivamente solo la parte specificata.
Akaihola,

Essa non ha salvato l'audio per un video nel mio caso a differenza @godofgrunts risposta.
daGo

19
ffmpeg $(youtube-dl -g 'https://www.youtube.com/watch?v=oHg5SJYRHA0' | sed "s/.*/-ss 00:05 -i &/") -t 01:00 -c copy out.mkv

5
Potresti spiegare, cosa fa, come funziona?
user259412

3
È solo una versione più concisa della risposta di @godofgrunts, usando sed per risparmiare un po 'di tempo afferrando manualmente gli URL e copiando / incollando nei tempi di inizio (-ss 00:05). @godofgrunts ha alcuni flag extra -map 0:v -map 1:a -c:v libx264 -c:a aacche potrebbero migliorare la qualità. Mi piace anche aggiungere youtube-dl -f bestvideo+bestaudioper essere sicuro di ottenere la versione di massima qualità.
Steve Goranson,


18

Aggiungendo alla risposta di Johnnie:

Utilizzare youtube-dl -g "URL"per ottenere i flussi audio e video.

Ora usa:

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

Dovrai utilizzare l' -ssopzione per ogni flusso. Consiglio anche di farlo circa 30 secondi prima e poi di usarne un altro -ss 30per evitare di perdere i fotogrammi chiave. Ecco un esempio reale usando uno dei miei video di YouTube.

video

youtube-dl -g https://www.youtube.com/watch?v=gESHIrvIQQo

Produzione:

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/

Volevo tagliare dalle 43:00 alle 50:10, quindi ho intenzione di farlo -ss 42:30(dandomi qualche secondo per catturare un buon fotogramma chiave) su entrambi gli ingressi e quindi fare un -ss 30dopo gli ingressi per iniziare alle 43:00.

Userò quindi mapper mappare il video 0:ve l'audio 1:a(0 significa primo input, che è il video e 1 significa il secondo input, che è l'audio) e quindi scegliere le mie opzioni di codifica.

ffmpeg -ss 42:30 -i "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/" -ss 42:30 -i "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/" -map 0:v -map 1:a -ss 30 -t 7:10 -c:v libx264 -c:a aac gog-vs-triv.mkv

1
Grazie. Non ero sicuro di come ottenere l'audio, per il post @Johnnie. Il tuo post ha risposto.
Manny_Mar

Wow, non sapevo che la -ibandiera di ffmpeg potesse prendere gli URL. pulito
Geremia

In che cosa differisce dall'utilizzare --postprocessor-argsdirettamente in youtube-dl?
daGo

13

Questa richiesta di funzionalità non è ancora implementata in youtube-dl. Vedi il numero 622 e molti duplicati di esso su github.


10

youtube-dl supporta il passaggio di argomenti al postprocessore sottostante (testato con la versione 2017.08.27.1):

youtube-dl -x --postprocessor-args "-ss 00:13:00.00 -t 00:04:00.00" https://youtu.be/...

Questo è fondamentalmente lo stesso che fare il postprocessing con ffmpegte stesso dopo aver scaricato prima il file.


4
ma questo richiederà comunque di scaricare l'intero video, quindi tagliare la parte desiderata
Kasparov92,

Ricevo un unable to obtain file audio codec with ffprobeerrore. Potete per favore aiutarmi con quello. Sto usando CentOS 7
Hassaan il

3
Si noti che il -xflag scarica solo l'audio. Omettilo dal comando se desideri sia audio che video. :)
grooveplex,

2

Puoi scaricare dall'inizio fino a un certo punto senza scaricare tutto e modificarlo. Questa è la metà di ciò che questa domanda pone:

interrompere il download con ^C

  • Ci ho provato solo con mp4
  • non funziona con video e audio separati, è necessario un formato con entrambi. Per impostazione predefinita, ytdl spesso ottiene video e audio separati, quindi li unisce. Usa -Fper vedere i formati disponibili e scegli uno mp4che ha entrambi. ad esempio -f18o di -f22solito ci sono.
  • dovrai stimare dalla percentuale scaricata (che non è lineare; il tasso di compressione varia nel tempo).

Sì. È un trucco .

Ulteriore domanda: se desideri formati video e audio separati, potresti scaricare parte di ciascuno separatamente (usando ^ccome qui) e poi unirli manualmente? Non penso che funzionerà per alcuni formati.


2

Questo non risponde completamente alla domanda di OP ma esiste un modo per scaricare uno stream dall'inizio a una durata specifica senza dover scaricare lo stream completo. Poiché YouTube fornisce il supporto per il ripristino del curriculum, potremmo richiedere contenuti parziali utilizzando l' Rangeintestazione.

Innanzitutto recuperiamo gli URL dello 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...

Ciò dovrebbe generare due URL (ciascuno per flussi video e audio).

Ora invia una richiesta principale al primo URL (che collega al flusso video) per recuperare la lunghezza totale del contenuto di questo flusso:

$ curl "1st-URL" -sI | grep Content-Length
Content-Length: 64380504

Dividiamo ora questa lunghezza totale del contenuto per secondi totali nel video (il video di YouTube ha una durata di 4 minuti e 7 secondi, ovvero 247 secondi) per ottenere circa la durata del contenuto di 1 secondo:

64380504 / 247 ≈ 260650

Moltiplichiamo questo valore per (numero di secondi che vogliamo recuperare dall'inizio + 1)

(ne aggiungiamo uno anche per tenere conto approssimativamente dello spazio aggiuntivo occupato dai metadati che viene posizionato all'inizio dello stream)

Ad esempio, per recuperare approssimativamente i primi 10 secondi, dovrai recuperare i primi 260650 * 11 = 2867150byte, quindi facciamo una richiesta con l' Rangeintestazione:

$ curl "1st-URL" -H "Range: bytes=0-2867150" -o ten_secs.mp4

Questo dovrebbe scaricare solo i primi 10 secondi. Il file scaricato dovrebbe essere in grado di essere riprodotto, ma è meglio lasciare che FFmpeg ripari i metadati errati:

$ ffmpeg -i ten_secs.mp4 -c copy corrected_ten_secs.mp4

Possiamo anche scaricare solo la parte iniziale dell'audio (2o URL) in modo simile (la lunghezza del contenuto sarebbe diversa ma i secondi totali rimarrebbero uguali).

Anche il download di qualsiasi porzione centrale dal video dovrebbe essere possibile in questo modo, ma probabilmente sarà molto più complicato perché YouTube posiziona i metadati all'inizio dello stream (nei primi byte) e senza che sia presente nei media scaricati, il lo stream non funzionerà affatto.

EDIT: Funzionerà solo su siti Web con supporto per riprendi, ad esempio YouTube. Non funzionerà per altri siti Web.


1

Usa il parametro --postprocessor-args per passare l'uscita audio / video a ffmpeg da modificare (il processore), quindi devi installare ffmpeg.

--postprocessor-args accetta 3 argomenti e valori (ad esempio, c'è di più, controlla la pagina di manuale di ffmpeg):

  • -ss HH: MM: SS: ora di inizio da prendere
  • -a HH: MM: SS: ora di fine
  • -t HH: MM: SS: durata del tempo da prendere

Esempi:

  • Inizia la codifica a 15 secondi e termina a 1 minuto e 20 secondi

$ youtube-dl --postprocessor-args "-ss 0: 0: 15 -to 0: 1: 20" '[video_URL]'

  • Inizia la codifica da 15 secondi e impiega solo i successivi 3 minuti e 5 secondi

$ youtube-dl --postprocessor-args "-ss 0: 0: 15 -t 0: 3: 5" '[video_URL]'

PS: youtube-dl scaricherà l'intero supporto prima di elaborarlo e lo rimuoverà dopo.


1

Ho creato uno script che implementa la risposta @godofgrunts qui

#!/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

Ho anche caricato su Gitlab frammenti s'

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.