Sto usando Ubuntu e il comando youtube-dl
funziona perfettamente.
Tuttavia, ora voglio scaricare solo una parte di un video troppo lungo. Quindi voglio scaricare solo pochi minuti di quel video, ad es. dal minuto 13 al minuto 17.
Esiste un modo per farlo?
Risposta
I don “t believe youtube-dl
da solo farà quello che vuoi. Tuttavia puoi combinarlo con unutilità della riga di comando come ffmpeg.
Prima acquisisci lURL effettivo utilizzando youtube -dl:
youtube-dl -g "https://www.youtube.com/watch?v=V_f2QkBdbRI"
Copia loutput del comando e incollalo come parte del parametro -i
del comando successivo:
ffmpeg -ss 00:00:15.00 -i "OUTPUT-OF-FIRST URL" -t 00:00:10.00 -c copy out.mp4
Il parametro -ss
in questa posizione indica di scartare tutto linput fino a 15 secondi nel video. Lopzione -t
indica di catturare per 10 secondi. Il resto del comando gli dice di memorizzare come mp4.
ffmpeg è uno strumento popolare e dovrebbe essere in uno dei più diffusi repository del sistema operativo / gestori di pacchetti.
Commenti
Rispondi
Aggiunta a Risposta di Johnnie:
Usa youtube-dl --youtube-skip-dash-manifest -g "URL"
per ottenere i flussi video e audio.
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 lopzione -ss
per ogni stream. Consiglio anche di farlo circa 30 secondi prima e poi di utilizzare un altro -ss 30
per evitare di perdere i fotogrammi chiave. Ecco “un vero esempio utilizzando uno dei miei video di YouTube.
youtube-dl --youtube-skip-dash-manifest -g https://www.youtube.com/watch?v=gESHIrvIQQo
Risultato:
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 da 43:00 a 50:10, quindi “sto andando a fare -ss 42:30
(concedendomi qualche secondo per catturare un buon fotogramma chiave) su entrambi gli input e poi eseguire un -ss 30
dopo gli input per iniziare alle 43:00.
Utilizzerò quindi map
per mappare il video 0:v
e laudio 1:a
(0 significa primo ingresso, che è il video e 1 indica il secondo ingresso, che è laudio), quindi scegli le mie opzioni di codifica.
# 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
Ringraziamo Jakub Vrána per il --youtube-skip-dash-manifest
soluzione.
Commenti
- Grazie. Non ero sicuro di come ottenere il suono, per il post di @Johnnie. Il tuo post ha risposto.
- In che modo dif vuoi utilizzare
--postprocessor-args
direttamente in youtube-dl? - @daGo – Credo che
youtube-dl --postprocessor-args
scaricherà lintero video e quindi modificalo fino allintervallo selezionato, mentre questa risposta utilizzayoutube-dl
solo per ottenere alcuni URL speciali.ffmpeg
utilizza quindi questi URL per scaricare solo lintervallo richiesto. Quindi, se desideri estrarre 2 minuti da un video di lezione di 2 ore, questa risposta ti farà risparmiare un sacco di download. - Funziona con la maggior parte dei video di YT, ma lo sto provando con un video di 9 ore che è stato precedentemente trasmesso in streaming dal vivo (e ora completato) e ricevo ” Dati non validi rilevati durante lelaborazione dellinput “. La differenza principale è che loutput di
youtube-dl -g
è diverso. Con la maggior parte dei video ha la struttura."https://r3---sn-mv-cvne.googlevideo.com/videoplayback/id/8..."
ma per questo video ha la struttura."https://manifest.googlevideo.com/api/manifest/dash/expire/15956..."
(troncato per spazio). Idee su come farlo funzionare? - @LeftoverSalad Trovato una soluzione .
Risposta
ffmpeg $(youtube-dl -g "https://www.youtube.com/watch?v=oHg5SJYRHA0" | sed "s/.*/-ss 00:05 -i &/") -t 01:00 -c copy out.mkv
Modifica lURL e -ss
, -t
volte per utilizzare questo comando. Crea gli argomenti, utilizzando URL video e audio, simili a questa risposta di @godofgrunts.Non vengono utilizzate virgolette per $()
perché questo produce due argomenti separati per ffmpeg
.
Commenti
- Potresti spiegare cosa fa, come funziona?
- È ‘ solo una versione più concisa di @ Godofgrunts risponde, usando sed per risparmiare un po di tempo acquisendo manualmente gli URL e copiando / incollando negli orari di inizio (-ss 00:05). @godofgrunts ha alcuni flag aggiuntivi
-map 0:v -map 1:a -c:v libx264 -c:a aac
che potrebbero migliorare la qualità. Mi piace anche aggiungereyoutube-dl -f bestvideo+bestaudio
per essere sicuro che ‘ ottenga la versione della massima qualità. - ffmpeg.zeranoe.com/builds per Windows.
- I ” flag aggiuntivi ” si occupano dei due flussi (video e audio) che penso tu stia gestendo male – IIUC non hanno nulla a che fare con il miglioramento della qualità (beh, avere il suono è probabilmente un segno di una migliore qualità :-)) answer di @godofgrunts di seguito sembra essere corretta.
Risposta
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 eseguire la post-elaborazione con ffmpeg
dopo aver scaricato il file prima.
Commenti
- ma sarà comunque necessario farlo Carica lintero video, quindi taglia la parte desiderata
- Ricevo lerrore
unable to obtain file audio codec with ffprobe
. Puoi per favore aiutarmi con quello. Utilizzo CentOS 7 - Nota che il flag
-x
scarica solo laudio. Omettilo dal comando se vuoi sia audio che video. 🙂 - Questo non funzionerà in modo affidabile, poiché
—postprocessor-args
viene applicato più volte in alcuni casi. Vedi github.com/ytdl-org/youtube-dl/issues/26863
Risposta
Questa richiesta di funzione non è ancora implementata in youtube-dl. Consulta il # 622 problema e molti suoi duplicati su GitHub.
Risposta
Utilizza il parametro --postprocessor-args
per passare luscita audio / video a ffmpeg
da modificare (il processore). Il postprocessore deve essere ffmpeg
installato.
--postprocessor-args
accetta 3 argomenti & valori (ad esempio, ce nè di più, controlla la pagina di manuale di ffmpeg
):
-
-ss HH:MM:SS
: ora di inizio da prendere -
-to HH:MM:SS
: ora di fine -
-t HH:MM:SS
: ora lunghezza necessaria
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 a 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à lintero supporto prima di elaborarlo e lo rimuoverà dopo.
Commenti
- Sì! Molto chiaro e facile da ricordare.
- Non funzionerà in modo affidabile, poiché
—postprocessor-args
viene applicato più volte in alcuni casi. Vedi github.com/ytdl-org/youtube-dl/issues/26863
Risposta
Questo non risponde completamente alla domanda di OP, ma cè un modo per scaricare uno stream dallinizio a una durata specifica senza dover scaricare lo stream completo. Poiché YouTube fornisce supporto per il ripristino, potremmo richiedere contenuti parziali utilizzando lintestazione Range
.
Per prima cosa 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...
Questo dovrebbe produrre due URL (ciascuno per flussi video e audio).
Ora invia una richiesta head al primo URL (che collega al flusso video) a recuperare la lunghezza totale dei contenuti di questo stream:
$ curl "1st-URL" -sI | grep Content-Length Content-Length: 64380504
Ora, dividiamo questa lunghezza totale dei contenuti per i secondi totali nel video (il video di YouTube ha una durata di 4 min e 7 sec, ovvero 247 secondi.) per ottenere approssimativamente la lunghezza del contenuto di 1 secondo:
64380504 / 247 ≈ 260650
Moltiplichiamo questo valore con (numero di secondi che vogliamo recuperare dallinizio + 1)
(ne aggiungiamo uno anche per tenere conto più o meno dello spazio extra occupato dai metadati che è posizionato allinizio dello stream)
Ad esempio, per recuperare approssimativamente i primi 10 secondi, dovrai recuperare il primo 260650 * 11 = 2867150
byte, quindi effettuiamo una richiesta con Range
header:
$ curl "1st-URL" -H "Range: bytes=0-2867150" -o ten_secs.mp4
Questo dovrebbe scaricare solo il primo 10 sec.Il file scaricato dovrebbe essere in grado di essere riprodotto ma è meglio lasciare che FFmpeg corregga i metadati errati:
$ ffmpeg -i ten_secs.mp4 -c copy corrected_ten_secs.mp4
Possiamo anche scaricare solo la parte iniziale dellaudio (2a- URL) in modo simile (la lunghezza del contenuto sarebbe diversa ma il totale dei secondi rimarrebbe lo stesso).
Anche il download di qualsiasi parte centrale del video dovrebbe essere possibile in questo modo, ma probabilmente sta andando molto più complicato perché YouTube posiziona i metadati allinizio dello stream (nei primi pochi byte) e senza che siano presenti nel supporto scaricato, lo stream non verrà riprodotto affatto.
EDIT: Funzionerà solo su siti web con supporto per il curriculum, ad esempio YouTube. Non funzionerà per altri siti web.
Risposta
Puoi eseguire il download dallinizio fino a un punto senza scaricando il tutto e modificandolo. Questa è la metà di ciò che fa questa domanda:
interrompi il download con
^C
- Lho “provato solo con
mp4
- non funziona con video separati e audio, hai bisogno di un formato con entrambi. Per impostazione predefinita ytdl spesso ottiene video e audio separati, quindi li unisce. Utilizza
-F
per vedere i formati disponibili e scegli unmp4
che ha entrambi. Ad esempio-f18
o-f22
di solito ci sono. - tu “Dovrò stimare dalla percentuale di download (che non è lineare; il tasso di compressione varia nel tempo).
Sì. È un hack .
Ulteriore domanda: se vuoi i formati video e audio separati, potresti scaricare una parte di ciascuno separatamente (usando ^c
come qui) e poi unirli manualmente? Non credo che funzionerà per alcuni formati.
Answer
Ho creato uno script che implementa @godofgrunts answer 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
Lho anche caricato negli snippet di Gitlab “
Answer
Ho creato unapp flask che può fare quello che vuoi. So che il post è vecchio, ma il problema persiste.
Puoi trovarlo qui
Può analizzare testo anche per i link di YouTube. Fornisci ad esempio:
YouTube.com/blahblah start-1:20
Questo scaricherà un video da 0-1: 22 (possono sorgere lievi differenze a causa dei fotogrammi chiave). Può anche scaricare interi video, in questo caso ometti lintervallo di tempo.
Rispondi
Per tutti i pigri che non “Per utilizzare più di un comando, procedi come segue:
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"
Ora puoi combinare le opzioni di youtube-dl.exe
e ffmpeg
come scegliere il formato, rimuovere il video e tagliare il file audio ecc. (magari tagliare il file video e poi convertirlo in un file audio, qualunque cosa accada prima)
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"
Commenti
- il tuo comando non funziona su GNU / Linux: usiamo
youtube-dl
invece diyoutube-dl.exe
. Effmpeg
mi ha dettoInvalid duration specification for ss: 00.00.10.00
, dovrebbe essere-ss 00:00:30.00
con i due punti anziché i punti tranne lultimo. - @ ewin-goisot Mi dispiace, è successo perché ‘ t ha copiato e incollato lintero comando dopo tes ting esso. Ora dovrebbe funzionare. il problema era la definizione del tempo. deve essere 00: 00: 00.00 2 volte il doppio punto, che solo 1 punto. come hh: mm: ss.ms
- con
00:00:00.0
, funziona meglio, posso scaricare una parte del video. Ho ancora un problema (con il tuo comando e la maggior parte degli altri): scarica 5 o 10 secondi di troppo. La soluzione viene fornita nella risposta di @godofgrunts ‘:-ss 42:30 -i "$video_url" -ss 42:30 -i "$audio_url" -map 0:v -map 1:a -ss 30
a partire da 30 secondi prima dellinizio della porzione e aggiungendo un-ss 30
alla fine. Quindi ho bisogno di usare più volte lopzione-ss
sullo stesso comando. Esiste un modo per fare lo stesso con--external-downloader-args
? - ah scusa, non ho molta familiarità con il mescolare flussi diversi. ma se vuoi prendere solo il miglior materiale audio e video dello stesso video, puoi farlo con youtube-dl
Answer
Per aggiungere alla risposta @hyperpallium: OP non ha menzionato che il video che stava scaricando doveva essere da YouTube.
YouTube è ridicolmente restrittivo con i loro video, hanno diviso il flussi audio e video in file diversi e ti tracciano / vendono i tuoi dati; quindi, si potrebbero avere difficoltà con il metodo per scaricarlo in parte e poi premere Ctrl + C .
Con la youtube-dl
versione 2020.11.17 in Microsoft Windows versione 10.0.17134.1304 ho scaricato parte di un video da 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...]
Il file MKV che ho ottenuto era ” 00:22:57 ” in ” durata totale “, ma è terminata dopo 34 secondi. Il video MP4 che ho ottenuto era di 00:00:34 secondi di durata totale, è terminato dopo 34 secondi e il video e laudio sono stati riprodotti perfettamente / come previsto.
Completo cmd.exe
log è qui
Quindi, in sintesi, esegui
youtube-dl --abort-on-unavailable-fragment [URL to video file]
(lopzione --abort-on-unavailable-fragment
potrebbe essere importante in quanto si finisce per interrompere il download con Ctrl + C ), lascialo scaricare per un po , quindi premi Ctrl + C .
Opzionale: rinomina [file].mkv.part
file in [file].mkv
. Anche la conversione da MKV a MP4 è probabilmente facoltativa.
Risposta
Qualcuno ha creato un script batch (per Windows) che scarica il file ed estrae la parte desiderata:
@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
in realtà scaricherà solo la parte specificata.youtube-dl
con-g
restituirà sempre 403 per me proibito. Usare solo youtube-dl per scaricare il video funzionerà sempre a meraviglia.