54

I am using Ubuntu, and youtube-dl command is working absolutely fine.

I want to download only portion the video that is too long. So I want to download only few minutes portion of the video. Example from 13 minutes to 17 minutes.

Is there any way to do that

34

I don't believe youtube-dl alone will do what you want. However you can combine it with a command line utility like ffmpeg.

First acquire the actual URL using youtube-dl:

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

Copy the output of the command and paste it as part of the -i parameter of the next command:

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

The -ss parameter in this position states to discard all input up until 15 seconds into the video. The -t option states to capture for 10 seconds. The rest of the command tells it to store as an mp4.

ffmpeg is a popular tool and should be in any of the popular OS repositories/package managers.

  • 7
    So essentially, you still have to download the whole video and crop it yourself – Antony Jun 17 '16 at 0:08
  • 7
    You can use the -to option instead of -t if you want to specify the time for ending the video slice. ffmpeg -i "OUTPUT-OF-FIRST URL" -ss 00:13:00.00 -to 00:17:00.00 -c copy out.mp4 – ˆᵛˆ Apr 7 '17 at 14:41
  • 1
    @Antony ffmpeg will actually only download the part you specify. – akaihola Dec 21 '18 at 20:29
13
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
    Could you explain, what it does, how it works? – peterh Sep 15 '17 at 4:49
  • 2
    It's just a more terse version of @godofgrunts answer, using sed to save some time manually grabbing the URLs and copying/pasting in the start times (-ss 00:05). @godofgrunts has some extra flags -map 0:v -map 1:a -c:v libx264 -c:a aac that might improve quality. I also like to add youtube-dl -f bestvideo+bestaudio to be sure I'm getting the highest quality version. – Steve Goranson Sep 16 '17 at 7:13
  • ffmpeg.zeranoe.com/builds for Windows. – Wolfpack'08 Jun 5 at 3:29
11

This feature request is not yet implemented in youtube-dl. See #622 issue and many duplicates of it on github.

10

Adding to Johnnie's answer:

Use youtube-dl -g "URL" to get the video and audio streams.

Now 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

You'll need to use the -ss option for each stream. I also recommend doing it about 30 seconds earlier and then using another -ss 30 to avoid losing any key frames. Here's a real example using one of my youtube videos.

Video

youtube-dl -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/

I wanted to cut from 43:00 to 50:10 so I'm going to do -ss 42:30(giving me a few seconds to catch a good keyframe) on both inputs and then do a -ss 30 after the inputs to start at 43:00.

I'll then use map to map the video 0:v and audio 1:a (0 means first input, which is the video and 1 means the second input, which is the audio) and then choose my encoding options.

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
7

youtube-dl supports passing arguments to the underlying postprocessor (tested with version 2017.08.27.1):

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

This is basically the same as doing the postprocessing with ffmpeg yourself after downloading the file first.

  • 4
    but this will still require to download the whole video, then cut the desired part – Kasparov92 Sep 15 '18 at 10:52
  • I am getting unable to obtain file audio codec with ffprobe error. Can you please help me with that. I am using CentOS 7 – Hassaan Nov 22 '18 at 9:40
  • 3
    Note that the -x flag downloads the audio only. Omit it from the command if you want both audio and video. :) – grooveplex Jan 9 at 11:29
2

You can download from the start up to a point without downloading the whole thing and editing. That's half of what this question asks:

interrupt the download with ^C

  • I've only tried this with mp4
  • won't work with separate video and audio, you need a format with both. By default ytdl often gets separate video and audio, then merges them. Use -F to see the formats available, and choose an mp4 that has both. e.g. -f18 or -f22 are usually there.
  • you'll have to estimate from percentage downloaded (which isn't linear; the compression rate varies over time).

Yes. It's a hack.

Further question: if you do want the separate video and audio formats, could you download part of each separately (using ^c as here), and then merge them manually? I don't think it willl work for some formats.

1

This doesn't completely answer OP's question but there is way to download a stream from beginning to a specific duration without having to download the complete stream. Since YouTube provides resume support, we could request for partial content using the Range header.

We first fetch the stream URLs:

$ 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...

This should output two URLs (each for video and audio streams).

Now send a head request to the first URL (which links to the video stream) to fetch the total content length of this stream:

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

Now, we divide this total content length by total seconds in video (the YouTube video has a duration of 4 min and 7 secs which is 247 seconds.) to approximately get the content length of 1 second:

64380504 / 247 ≈ 260650

We multiply this value with (number of seconds we want to fetch from the beginning + 1)

(we add one to also roughly account for extra space taken by metadata which is placed at the beginning of the stream)

For example to fetch approximately the first 10 seconds, you will need to fetch the first 260650 * 11 = 2867150 bytes, so we make a request with the Range header:

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

This should only download the first 10 secs. The downloaded file should be able to play but best let FFmpeg fix the incorrect metadata:

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

We can also download only the initial part of the audio (2nd-URL) in a similar fashion (content-length would differ but total seconds would remain same).

Downloading any middle portion from the video should also be possible in this way but is going probably way much trickier because YouTube places the metadata at the beginning of the stream (in the first few bytes) and without it being present in the downloaded media, the stream won't play at all.

EDIT: This will only work on websites with resume support, say YouTube. It won't work for other websites.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.