I'd like to be able to download a portion of a video only. For example, being able to specify a start and/or end time for downloading. So, when a user inputs a start and end time of a video, it should only download the portion of the clip within the time stamps. Would this be possible?
5 Answers
There is indeed a plethora of techniques available online to accomplish this. One fairly basic technique is the following one liner which works well enough on my system with a YouTube clip:
ffmpeg -i $(youtube-dl -f 18 --get-url https://www.youtube.com/watch?v=ZbZSe6N_BXs) \
-ss 00:00:10 -t 00:00:30 -c:v copy -c:a copy \
happy.mp4
The 2 sections which govern the clip start and end in this example are:
- -ss 00:00:10: Placed after the input file this encodes and discards samples up until the 10 second mark. This is slower and less efficient than placing the seek options before the input file (input seeking) but works better in this example (in particular when copying audio and video streams)
- -t 00:00:30: This specifies the duration of the encode, in this case 30 seconds only
I have tested this extensively with YouTube and all works well on my own system...
References:
- youtube-dl Download Range: Great discussion of the possibilities, some a little misguided :)
- FFmpeg: Seeking A solid outline of seeking, cutting and the correct time unit syntax
Use the --postprocessor-args
parameter to pass the audio/video output to ffmpeg
to be edited (the processor). Apparently, ffmpeg
is needed to be installed.
--postprocessor-args
takes 3 arguments & values (this is just an example, check manual page of ffmpeg
with man ffmpeg
for more):
-ss HH:MM:SS
: start time to take-to HH:MM:SS
: end time-t HH:MM:SS
: time length to take
Examples:
Start encoding at 15 seconds and stop at 1 minutes 20 seconds:
$ youtube-dl --postprocessor-args "-ss 0:0:15 -to 0:1:20" '[video_URL]'
Start encoding at 15 seconds and take only the next 3 minutes 5 seconds:
$ youtube-dl --postprocessor-args "-ss 0:0:15 -t 0:3:5" '[video_URL]'
PS: youtube-dl
will download the entire media before processing it, and will remove it after.
-
1
-
This solution is totally awesome and thanx. I wanted the ENG version of this 3:05:06 video of The History of The Eagles from the Arte site. So I had to run the -F command to see which as others dubbed FR or GER. The video was downloaded in full but trimmed to my time specs Very impressive!
youtube-dl -f HTTPS_SQ_2 --postprocessor-args "-ss 01:57:00 -t 03:05:06" url
– shantiqAug 14, 2021 at 19:39
The plumber tool allows you to do this easily. Install the application with:
snap install plumber
After installation, it will appear in your applications menu.
When you run the application, paste your desired youtube link in the box (highlighted in red in the screenshot below), or use the built-in youtube search feature, by clicking the youtube icon (highlighted in yellow).
Choose the start and end points. You can save your result as a video or gif.
A nice alternative not shared here is yt-dlp, a fork of youtube-dl
which is far less held back by rate throttling. Its timing is accurate ("albeit slower") when given the --force-keyframes-at-cuts
option:
yt-dlp --download-sections "*1:00:00-1:00:30" --force-keyframes-at-cuts [video_url]
I also passed the --extract-audio --audio-format mp3
options and checked the true length of the resulting file with ffprobe
:
ffprobe extracted_clip.mp3 2>&1 | grep Duration
Duration: 00:00:30.02, start: 0.023021, bitrate: 68 kb/s
So the result is pretty accurate.
Speed
Result: yt-dlp was 20x faster than youtube-dl
for benchmarking, I ran the other answer's example below:
time ffmpeg -ss 00:00:37 -to 00:00:44 -i "$(youtube-dl -f best --get-url 'https://youtu.be/PVGeM40dABA')" -c:v copy -c:a copy coffee_sliding.mp4
This took 36 seconds on my machine.
Then I ran it the way I'm suggesting, using yt-dlp
:
time yt-dlp -f best --download-sections "*0:00:37-0:00:44" --force-keyframes-at-cuts https://youtu.be/PVGeM40dABA
This took 1.8 seconds on my machine.
So by that simple benchmark it's 20 times faster!
I imagine the factor could change for different circumstances, but it's a promising signal.
Accuracy
Result: yt-dlp was 76x more accurate than youtube-dl
A faster method is not necessarily better if the result is worse in its accuracy.
I compared the extracted clips produced above against the expected duration (37s-44s = 7s duration).
The youtube-dl
downloaded file was 8.52 seconds long (off by 1.52s).
ffprobe coffee_sliding.mp4 2>&1 | grep Duration
Duration: 00:00:08.52, start: 0.000000, bitrate: 1702 kb/s
The yt-dlp
downloaded file was 7.02 seconds long (off by 0.02s).
ffprobe coffee_sliding_ytdlp.mp4 2>&1 | grep Duration
Duration: 00:00:07.02, start: 0.000000, bitrate: 1563 kb/s
Again, with all caveats of "just one test", this is 76x more accurate. What inaccuracy there is from yt-dlp, is pretty much negligible.
-
Wow, your
yt-dlp
solution is way better than theyoutube-dl
ones! Thank you! 🙏– GeremiaAug 7, 2023 at 4:51
I followed andrew.46's answer. However, you'd like to put -ss
and -t
or -to
before -i
for proper seeking. Otherwise, you'll download more than you want.
(-t
specifies duration and -to
specifies the output point; be careful as they are different)
In the manual of ffmpeg, we are told to use -t
or -to
after -i
. However, based on my experience with ffmpeg, -to
does not work after -i
; it will be recognized as -t
.
My example command is: (to download the cart sliding part of "Coffee Run")
ffmpeg -ss 00:00:37 -to 00:00:44 -i "$(youtube-dl -f best --get-url 'https://youtu.be/PVGeM40dABA')" -c:v copy -c:a copy coffee_sliding.mp4
youtube-dl
yet: github.com/rg3/youtube-dl/issues/622. Google throws up many websites which provide this option.