Jag använder Ubuntu och kommandot youtube-dl
fungerar helt bra.
Men nu vill jag bara ladda ner en del av en video som är för lång. Så jag vill bara ladda ner några minuter av den videon, t.ex. från minut 13 till minut 17.
Finns det något sätt att göra det?
Svar
I tror inte youtube-dl
ensam kommer att göra vad du vill. Men du kan kombinera det med ett kommandoradsverktyg som ffmpeg.
Först skaffa dig den faktiska webbadressen med youtube -dl:
youtube-dl -g "https://www.youtube.com/watch?v=V_f2QkBdbRI"
Kopiera kommandot och klistra in det som en del av parametern -i
nästa kommando:
ffmpeg -ss 00:00:15.00 -i "OUTPUT-OF-FIRST URL" -t 00:00:10.00 -c copy out.mp4
Parametern -ss
i denna position anger att alla inmatningar ska kasseras upp till 15 sekunder in i video. Alternativet -t
anger att fånga i 10 sekunder. Resten av kommandot säger att det ska lagras som en mp4.
ffmpeg är ett populärt verktyg och bör vara i någon av de populära OS-arkiv / pakethanterare.
Kommentarer
Svar
Lägger till Johnnies svar:
Använd youtube-dl --youtube-skip-dash-manifest -g "URL"
för att hämta video- och ljudströmmar.
Använd nu:
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
Du måste använda alternativet -ss
för varje ström. Jag rekommenderar också att du gör det cirka 30 sekunder tidigare och sedan använder en annan -ss 30
för att undvika att förlora några nyckelramar. Här är ett riktigt exempel med en av mina youtube-videor.
youtube-dl --youtube-skip-dash-manifest -g https://www.youtube.com/watch?v=gESHIrvIQQo
Output:
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/
Jag ville klippa från 43:00 till 50:10 så jag ska göra -ss 42:30
(ger mig några sekunder att fånga en bra keyframe) på båda ingångarna och gör sedan en -ss 30
efter ingångarna för att starta kl. 43:00.
I ”ll använd sedan map
för att mappa videon 0:v
och ljud 1:a
(0 betyder första ingången, vilket är videon och 1 betyder den andra ingången, vilket är ljudet) och välj sedan mina kodningsalternativ.
# 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
Tack till Jakub Vrána för --youtube-skip-dash-manifest
lösning.
Kommentarer
- Tack. Jag var inte säker på hur jag skulle få ljud, för @Johnnie-inlägg. Ditt inlägg svarade på det.
- Hur skiljer sig vill du använda
--postprocessor-args
direkt i youtube-dl? - @daGo – Jag tror att
youtube-dl --postprocessor-args
laddar ner hela videon och redigera sedan ner till det valda intervallet, medan det här svaret använderyoutube-dl
bara för att få några speciella webbadresser.ffmpeg
använder sedan dessa webbadresser för att bara ladda ner det önskade intervallet. Så om du vill extrahera två minuter från en 2 timmars föreläsningsvideo sparar det här svaret dig mycket nedladdning. - Detta fungerar med de flesta YT-videor, men jag försöker detta med en 9-timmars video som streamades tidigare live (och nu slutförd) och jag får ” Ogiltiga data hittades vid bearbetning av input ”. Huvudskillnaden är att utdata från
youtube-dl -g
är annorlunda. Med de flesta videor har den strukturen."https://r3---sn-mv-cvne.googlevideo.com/videoplayback/id/8..."
men för den här videon har den strukturen."https://manifest.googlevideo.com/api/manifest/dash/expire/15956..."
(trunkerad för utrymme). Idéer om hur detta ska fungera? - @LeftoverSalad Hittade en lösning .
Svar
ffmpeg $(youtube-dl -g "https://www.youtube.com/watch?v=oHg5SJYRHA0" | sed "s/.*/-ss 00:05 -i &/") -t 01:00 -c copy out.mkv
Redigera webbadressen och -ss
, -t
gånger för att använda detta kommando. Det skapar argumenten, med både video- och ljud-URL: er, liknande det här svaret av @godofgrunts.Inga citat används för $()
eftersom detta ger två separata argument för ffmpeg
.
Kommentarer
- Kan du förklara, vad det gör, hur det fungerar?
- Det ’ är bara en mer kortfattad version av @ godofgrunts svarar, använder sed för att spara lite tid manuellt att ta tag i webbadresserna och kopiera / klistra in i starttiderna (-ss 00:05). @godofgrunts har några extra flaggor
-map 0:v -map 1:a -c:v libx264 -c:a aac
som kan förbättra kvaliteten. Jag gillar också att lägga tillyoutube-dl -f bestvideo+bestaudio
för att vara säker på att jag ’ får versionen av högsta kvalitet. - ffmpeg.zeranoe.com/builds för Windows.
- ” extra flaggor ” hantera de två strömmarna (video och ljud) som jag tror att du hanterar fel – IIUC de har inget att göra med att förbättra kvaliteten (ja, att ha ljud är förmodligen ett tecken på förbättrad kvalitet :-)) svar av @godofgrunts nedan verkar vara korrekt.
Svar
youtube-dl
stöder överföring av argument till den underliggande postprocessorn (testad med version 2017.08.27.1):
youtube-dl -x --postprocessor-args "-ss 00:13:00.00 -t 00:04:00.00" https://youtu.be/...
Detta är i princip samma sak som att göra efterbehandlingen med ffmpeg
själv efter att du laddat ner filen först.
Kommentarer
- men detta kommer fortfarande att krävas ladda ner hela videon och klipp sedan ut önskad del
- Jag får
unable to obtain file audio codec with ffprobe
fel. Kan du snälla hjälpa mig med det. Jag använder CentOS 7 - Observera att
-x
-flaggan hämtar endast ljudet. Utelämna det från kommandot om du vill ha både ljud och video. 🙂 - Detta fungerar inte pålitligt, eftersom
—postprocessor-args
tillämpas flera gånger i vissa fall. Se github.com/ytdl-org/youtube-dl/issues/26863
Svar
Denna funktionsförfrågan är ännu inte implementerad i youtube-dl. Se nummer 622 och många kopior av det på github.
Svar
Använd parametern --postprocessor-args
för att skicka ljud- / videoutgången till ffmpeg
som ska redigeras (processorn). Efterprocessorn måste ffmpeg
installeras.
--postprocessor-args
tar 3 argument & värden (till exempel finns det mer, kolla manuell sida för ffmpeg
):
-
-ss HH:MM:SS
: starttid att ta -
-to HH:MM:SS
: sluttid -
-t HH:MM:SS
: tid längd att ta
Exempel:
- Börja kodning vid 15 sekunder och sluta vid 1 minut och 20 sekunder
$ youtube-dl --postprocessor-args "-ss 0:0:15 -to 0:1:20" "[video_URL]"
- Börja koda vid 15 sekunder och ta bara de närmaste 3 minuterna 5 sekunder
$ youtube-dl --postprocessor-args "-ss 0:0:15 -t 0:3:5" "[video_URL]"
PS: youtube-dl
laddar ner hela mediet innan det bearbetas och tar bort det efter.
Kommentarer
- Ja! Mycket rent och lätt att komma ihåg.
- Detta fungerar inte på ett tillförlitligt sätt eftersom
—postprocessor-args
tillämpas flera gånger i vissa fall. Se github.com/ytdl-org/youtube-dl/issues/26863
Svar
Detta svarar inte helt på OP: s fråga men det finns ett sätt att ladda ner en ström från början till en viss varaktighet utan att behöva ladda ner hela strömmen. Eftersom YouTube tillhandahåller CV-stöd kan vi begära delvis innehåll med Range
-rubriken.
Vi hämtar först stream-webbadresserna:
$ 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...
Detta ska mata ut två webbadresser (vardera för video- och ljudströmmar).
Skicka nu en huvudförfrågan till den första webbadressen (som länkar till videoströmmen) till hämta den totala innehållslängden för den här strömmen:
$ curl "1st-URL" -sI | grep Content-Length Content-Length: 64380504
Nu delar vi den totala innehållslängden med totalt antal sekunder i videon (YouTube-videon har en varaktighet på 4 min och 7 sekunder vilket är 247 sekunder.) för att ungefär få innehållslängden på 1 sekund:
64380504 / 247 ≈ 260650
Vi multiplicerar detta värde med (antal sekunder vi vill hämta från början + 1)
(vi lägger till en för att ungefär ta hänsyn till extra utrymme som tas av metadata som placeras i början av strömmen)
Till exempel för att hämta ungefär de första 10 sekunderna måste du hämta den första 260650 * 11 = 2867150
byte, så vi gör en begäran med Range
rubrik:
$ curl "1st-URL" -H "Range: bytes=0-2867150" -o ten_secs.mp4
Detta bör bara ladda ner den första 10 sekunderDen nedladdade filen ska kunna spela men bäst låter FFmpeg fixa de felaktiga metadata:
$ ffmpeg -i ten_secs.mp4 -c copy corrected_ten_secs.mp4
Vi kan också bara ladda ner den första delen av ljudet (2: a- URL) på ett liknande sätt (innehållslängden skulle skilja sig men de totala sekunderna skulle förbli desamma).
Nedladdning av vilken mittdel som helst från videon borde också vara möjlig på det här sättet men går förmodligen mycket svårare eftersom YouTube placerar metadata i början av strömmen (i de första byten) och utan att den finns i det nedladdade mediet, kommer strömmen inte att spela alls.
REDIGERA: Detta fungerar bara på webbplatser med CV-stöd, säg YouTube. Det fungerar inte för andra webbplatser.
Svar
Du kan ladda ner från början till en punkt utan ladda ner det hela och redigera. Det är hälften av vad den här frågan ställer:
avbryta nedladdningen med
^C
- Jag har bara provat detta med
mp4
- kommer inte att arbeta med separat video och ljud behöver du ett format med båda. Som standard får ytdl ofta separat video och ljud och slår sedan ihop dem. Använd
-F
för att se tillgängliga format och välj ettmp4
som har båda. t.ex.-f18
eller-f22
finns vanligtvis där. - du ”Jag måste uppskatta från nedladdningsprocenten (som inte är linjär; kompressionshastigheten varierar över tiden).
Ja. Det är” sa hack .
Ytterligare fråga: om du vill ha de olika video- och ljudformaten, kan du ladda ner en del av var och en separat (med ^c
som här) och sedan slå samman dem manuellt? Jag tror inte att det kommer att fungera i vissa format.
Svar
Jag skapade ett skript för att implementera @godofgrunts svar här
#!/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
Jag laddade också upp den till Gitlab s utdrag
Svar
Jag skapade en kolvapp som kan till vad du vill. Jag vet att inlägget är gammalt, men problemet kvarstår.
Du hittar det här
Det kan analyseras text för YouTube-länkar också. Du anger bara t.ex.:
YouTube.com/blahblah start-1:20
Detta hämtar en video från 0-1: 22 (lite skillnader kan uppstå på grund av keyframes). Det kan också ladda ner hela videor, bara utelämna tidsintervallet i så fall.
Svar
För alla lata killar som inte ”t vill använda mer än ett kommando, gör följande:
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"
Du kan nu kombinera alternativen för youtube-dl.exe
och ffmpeg
som att välja format, ta bort videon och klippa ljudfilen etc. (kanske klippa videofilen och än att konvertera till en ljudfil, vad som än händer först)
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"
Kommentarer
- ditt kommando fungerar inte på GNU / Linux: vi använder
youtube-dl
istället föryoutube-dl.exe
. Ochffmpeg
sa till migInvalid duration specification for ss: 00.00.10.00
, det borde vara-ss 00:00:30.00
med kolon istället för perioder förutom den sista. - @ ewin-goisot Jag är ledsen, detta hände för att jag inte ’ t kopierade in hela kommandot efter tes ting det. Nu ska det fungera. problemet var tidsdefinitionen. den måste vara 00: 00: 00.00 två gånger dubbelpunkt än bara 1 poäng. som hh: mm: ss.ms
- med
00:00:00.0
, det fungerar bättre, jag kan ladda ner en del av videon. Jag har fortfarande ett problem (med ditt kommando och de flesta andra): det laddar ner 5 eller 10 sekunder för mycket. Lösningen ges på @godofgrunts ’ s svar:-ss 42:30 -i "$video_url" -ss 42:30 -i "$audio_url" -map 0:v -map 1:a -ss 30
börjar 30 sekunder före delens start och lägger till en-ss 30
i slutet. Så jag måste använda alternativet-ss
på samma kommando. Finns det ett sätt att göra detsamma med--external-downloader-args
? - ah förlåt, jag är inte så bekant med att blanda olika strömmar. men om du vill ta bara det bästa ljud- och videomaterialet av samma video, kan du istället göra det med youtube-dl
Svara
För att lägga till svaret på @hyperpallium: OP nämnde inte att videon han laddade ner måste vara från YouTube.
YouTube är löjligt restriktivt med sina videor, de delade upp ljud- och videoströmmar till olika filer, och de spårar dig / säljer dina data; därför kan man ha svårigheter med metoden att ladda ner den delvis och sedan slå Ctrl + C .
Med youtube-dl
version 2020.11.17 i Microsoft Windows version 10.0.17134.1304 laddade jag ner en del av en video från 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...]
MKV-filen som jag hamnade med var ” 00:22:57 ” i ” total varaktighet ”, men det slutade efter 34 sekunder. MP4-videon jag slutade med var 00:00:34 sekunder totalt, slutade efter 34 sekunder och videon och ljudet spelades helt bra / som avsett.
Full cmd.exe
logg är här
Så sammanfattningsvis, kör
youtube-dl --abort-on-unavailable-fragment [URL to video file]
(alternativ --abort-on-unavailable-fragment
kan vara viktigt när du slutar avbryta nedladdningen med Ctrl + C ), låt det ladda ner lite och tryck sedan på Ctrl + C .
Valfritt: byt namn på [file].mkv.part
fil till [file].mkv
. Att konvertera MKV till MP4 är förmodligen också valfritt.
Svar
Någon gjorde en batch-skript (för Windows) som hämtar filen och extraherar önskad del:
@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
laddar faktiskt bara den del du anger.youtube-dl
med-g
alternativet returnerar alltid 403 förbjudet för mig. Att bara använda youtube-dl för att ladda ner videoklippet fungerar alltid som en charm.