Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] The fastest way to download the time interval from Youtube #686

Closed
PureOcean opened this issue Aug 12, 2021 · 26 comments
Closed
Assignees
Labels
enhancement New feature or request

Comments

@PureOcean
Copy link

Firstly, thank you for YT-DLP. This fork have very useful new features. Besides, features increasing day by day.

I have a request.

There are different methods to download a specific time interval of a video on Youtube.

yt-dlp.exe -f 22 "https://www.youtube.com/watch?v=OQSMr-3GGvQ" --postprocessor-args "ffmpeg:-ss 00:05:05 -to 00:05:50" -o "%(title)s_method1.%(ext)s"

yt-dlp.exe -f 22 "https://www.youtube.com/watch?v=OQSMr-3GGvQ" --external-downloader ffmpeg --external-downloader-args "-ss 00:05:05 -to 00:05:50" -o "%(title)s_method2.%(ext)s"

But this methods cause slow download. Because YT-DLP/Youtube-DL uses --external-downloader-args / --postprocessor-args after the -i (source direct URL) in external/internal FFmpeg. For example from ProcMon:

ffmpeg -y -hide_banner -headers "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3634.1 Safari/537.36
Accept-Charset: ISO-8859-1,utf-8;q=0.7,;q=0.7
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,
/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-us,en;q=0.5
" -i https://r2---sn-u0g3oxu-pnus.googlevideo.com/videoplayback........ -ss 00:05:05 -to 00:05:50 -c copy -f mp4 "file:..............mp4.part"

The fastest download for a given time interval is possible only if the -ss and -to arguments are specified before the -i switch in FFmpeg. The popular workaround:

FOR /F "delims=" %i in ('yt-dlp.exe -f 22 -g "https://www.youtube.com/watch?v=OQSMr-3GGvQ"') do set YoutubeURL=%i
ffmpeg -ss 00:05:05 -to 00:05:50 -i "%YoutubeURL%" -c copy -y video_extracted.mp4

Is there a way to make (internal and external) FFmpeg use --postprocessor-args & --external-downloader-args arguments before the-iswitch (source downloadable link)?

If you add this support as an option, no longer will need the two-command workaround to fastest way download the audio/video range from Youtube.

@pukkandan
Copy link
Member

pukkandan commented Aug 12, 2021

yt-dlp.exe -f 22 "youtube.com/watch?v=OQSMr-3GGvQ" --postprocessor-args "ffmpeg:-ss 00:05:05 -to 00:05:50" -o "%(title)s_method1.%(ext)s"

For this case, it is already possible to pass the args before the -i using --ppa "ffmpeg_i:-ss 5:0 -to 5:50". Though, using postprocessor like this would download the entire video first and then cut out the section you need.

yt-dlp.exe -f 22 "youtube.com/watch?v=OQSMr-3GGvQ" --external-downloader ffmpeg --external-downloader-args "-ss 00:05:05 -to 00:05:50" -o "%(title)s_method2.%(ext)s"

For this, you are right. I never noticed that the seeking is slow. But running a few tests, it seems significant. Let me see how to extend the --ppa syntax to the downloader as well

@pukkandan
Copy link
Member

For example from ProcMon:

btw, this isnt needed. The verbose -v output shows the command being run

@fstirlitz
Copy link
Contributor

How about just a native --clip option that forces the downloader to FFmpeg and passes the appropriate -ss and -to?

@pukkandan
Copy link
Member

How about just a native --clip option that forces the downloader to FFmpeg and passes the appropriate -ss and -to?

This was a planned feature in youtube-dl at some point (ytdl-org/youtube-dl#8851) and the basic version of this feature actually exists in youtube-dl already but is intentionally disabled. I believe the reason is that we do not allow ffmpeg to download dash formats. So depending on the format selected, the clipping may or maynot happen. Or conversely, the format selection must be restricted when using this feature. Due to the same reason, I always suggest that users provide a -f string that excludes dash formats when trying to cut the videos

PS: While I was looking into a reference of why ffmpeg can't download DASH, I found that since FFmpeg/FFmpeg@3249c75, it can! If so, we should be able to implement this (#52) and also #159 by allowing ffmpeg to handle the dash fragments

@PureOcean
Copy link
Author

PureOcean commented Aug 12, 2021

@pukkandan
Thank you for your replies and the information. A few notes:

  • I tried --ppa ffmpeg_i:-ss 00:05:05 -to 00:05:50 but YT-DLP was starting to download the whole video and I was always pressing CTRL+C. Now I know how --postprocessor-args works. Maybe need new another switch: --preprocessor-args?

  • You're right; FFmpeg doesn't get along well with Youtube's DASH URLs. I've tried many times downloading videdo and audio links separaely the duration range from YT's DASH URLs. Then muxing phase. The audio sometimes have out of sync.
    (Now, thanks to you, I learned that the reason for this belongs to FFmpeg.)

Since the download process is done for both video and audio together from DASH URLs, it is naturally slow.

An example for 480p AVC/AAC DASH:

FOR /F "tokens=*" %i in ('yt-dlp -f 135 -g "https://www.youtube.com/watch?v=lZhT0t4D0m4"') do set YoutubeDASHVideoURL=%i
FOR /F "tokens=*" %i in ('yt-dlp -f 140 -g "https://www.youtube.com/watch?v=lZhT0t4D0m4"') do set YoutubeDASHAudioURL=%i
FFmpeg -ss 00:05:00 -to 00:05:50 -i "%YoutubeDASHVideoURL%" -ss 00:05:00 -to 00:05:50 -i "%YoutubeDASHAudioURL%" -c:v copy -c:a copy -y "480pAVCDASHvideo&AACaudio.mp4"

An example for 1080p AVC/Opus DASH:

FOR /F "tokens=*" %i in ('yt-dlp -f 137 -g "https://www.youtube.com/watch?v=OQSMr-3GGvQ"') do set YoutubeDASHVideo1080pURL=%i
FOR /F "tokens=*" %i in ('yt-dlp -f 251 -g "https://www.youtube.com/watch?v=OQSMr-3GGvQ"') do set YoutubeDASHOpus108AudioURL=%i
FFmpeg -ss 00:05:00 -to 00:05:50 -i "%YoutubeDASHVideo1080pURL%" -ss 00:05:00 -to 00:05:50 -i "%YoutubeDASHOpus108AudioURL%" -c:v copy -c:a copy -y "1080pAVC&108kOpusAudio.mp4"

That's why if I'm going to get the duration range of a video on Youtube, I choose the parameters without DASH. So -f 18 or -f 22 that contains both the video and the audio. The fastest way to download the time interval from Youtube:

FOR /F "tokens=*" %i in ('yt-dlp -f 22 -g "https://www.youtube.com/watch?v=OQSMr-3GGvQ"') do set Youtube720pVideo129AACAudioURL=%i
FFmpeg -ss 00:05:00 -to 00:05:50 -i "%Youtube720pVideo129AACAudioURL%" -c:v copy -c:a copy -y "720pAVC-129AAC.mp4"

I hope it will be possible to do this workaround with a single command by YT-DLP.

@pukkandan pukkandan added the enhancement New feature or request label Aug 13, 2021
@pukkandan pukkandan self-assigned this Aug 13, 2021
@pukkandan
Copy link
Member

With 330690a, you can now do --downloader-args "ffmpeg_i:-ss..." (ffmpeg_i means before input files). The issue of adding a range download option can be tracked in #52

@PureOcean
Copy link
Author

With 330690a, you can now do --downloader-args "ffmpeg_i:-ss..." (ffmpeg_i means before input files). The issue of adding a range download option can be tracked in #52

Thank you very much for this support and writing the all codes that provided it.

I just installed and tried the master branch of YT-DLP: python -m pip install --upgrade git+https://github.com/yt-dlp/yt-dlp

Format 18 (AVC 640x360, AAC) and (AVC 1280720, AAC)

yt-dlp -f 18 "https://www.youtube.com/watch?v=q5egaM2hibs" --external-downloader ffmpeg --external-downloader-args "ffmpeg_i:-ss 00:10:11 -to 14:01:25" -o "%(title)s_Extract_Format18.%(ext)s"

yt-dlp -f 22 "https://www.youtube.com/watch?v=q5egaM2hibs" --external-downloader ffmpeg --external-downloader-args "ffmpeg_i:-ss 00:10:11 -to 00:14:25" -o "%(title)s_Extract_Format22.%(ext)s"

Result: Fastest Download/seeking. Thanks to YTP-DLP's support for using pre -i arguments like FFmpeg's -ss -to.

Of course, the seeking/download process, when if use -format containing DASH links, is slow. For example:

yt-dlp.exe -f 135+140 "https://www.youtube.com/watch?v=q5egaM2hibs" --external-downloader ffmpeg --external-downloader-args "ffmpeg_i:-ss 00:10:11 -to 00:14:25" -o "%(title)s_Extract_Format135+140.%(ext)s"

This is normal. Because, as mentioned before, FFmpeg is incapable DASH URLs of YouTube. Nevertheless, with this new support, it's now easier to download specific time intervals from a Youtube video directly with YT-DLP without assigning audio-video URLs to a environment variable.

@pukkandan , Thank you so much for your all efforts.

@paul1149
Copy link

If this is the wrong place, or off topic, please tell me or delete.

Using the above information, I set up a bash alias to download a portion of a video:
alias vs="yt-dlp -f 18 --external-downloader ffmpeg --external-downloader-args 'ffmpeg_i:-ss 00:0:11 -to 00:00:25'"
So that the following command,
vs https://www.youtube.com/watch?v=1-SZ1r1dnho
works perfectly, downloading only the specified time segment.

But in order for the alias to be genuinely helpful, I need to be able to pass the start -ss and end -to times to ffmpeg. Is that possible?

Thanks.

Copy link

Nov 20, 2021

vs() { yt-dlp -f 18 --external-downloader ffmpeg --external-downloader-args "ffmpeg_i:-ss $1 -to $2" "$@"; }

Use as:

vs 00:00:11 00:00:25 [options] url

@paul1149
Copy link

That is amazing. Worked perfectly. Many Thanks!

Follow up:
I don't know what happened, but now I''m getting errors on the time stamps. yt-dlp seems to think they are URLs :

$ vs 00:00:03 00:00:08 https://www.youtube.com/watch?v=g_a7dQXilCo
[generic] 00:00:03: Requesting header
WARNING: [generic] Could not send HEAD request to 00:00:03: <urlopen error unknown url type: 00>
[generic] 00:00:03: Downloading webpage
ERROR: [generic] Unable to download webpage: <urlopen error unknown url type: 00> (caused by URLError('unknown url type: 00'))
[generic] 00:00:08: Requesting header
WARNING: [generic] Could not send HEAD request to 00:00:08: <urlopen error unknown url type: 00>
[generic] 00:00:08: Downloading webpage
ERROR: [generic] Unable to download webpage: <urlopen error unknown url type: 00> (caused by URLError('unknown url type: 00'))
[youtube] g_a7dQXilCo: Downloading webpage

Once the errors are done processing, the actual URL is processed correctly.

Also, according to the ffmpeg manual, the -ss argument acts differently when placed before rather than after the input URL. Should then the URL get its own argument which is passed before -ss?

-ss position (input/output)
When used as an input option (before -i), seeks in this input file to position. Note that in most formats it is not possible to seek exactly, so ffmpeg will seek to the closest seek point before position. When transcoding and -accurate_seek is enabled (the default), this extra segment between the seek point and position will be decoded and discarded. When doing stream copy or when -noaccurate_seek is used, it will be preserved.

When used as an output option (before an output url), decodes but discards input until the timestamps reach position.

position must be a time duration specification, see (ffmpeg-utils)the Time duration section in the ffmpeg-utils(1) manual.

Copy link

Nov 20, 2021

Ah yes, change "$@" to `"${@:3}".

Since you are already using ffmpeg_i, that means "pass these arguments to ffmpeg before the input URL", so the order of arguments to yt-dlp itself won't matter.

@paul1149
Copy link

Here's the command I now have:

vs() { yt-dlp -f 18 --external-downloader ffmpeg --external-downloader-args "ffmpeg_i:-ss $1 -to $2" "${@:3}"; }

I'm still getting errors of the type:

[generic] 00:00:03: Requesting header
WARNING: [generic] Could not send HEAD request to 00:00:03: <urlopen error unknown url type: 00>
[generic] 00:00:03: Downloading webpage
ERROR: [generic] Unable to download webpage: <urlopen error unknown url type: 00> (caused by URLError('unknown url type: 00'))

But again, when the actual URL kicks in it works correctly.

@paul1149
Copy link

I made a trivial change in the command, and now it's working perfectly. No idea why that should be.

vs() { yt-dlp -f 18 --downloader ffmpeg --external-downloader-args "ffmpeg_i:-ss $1 -to $2" "${@:3}"; }

This is great. Thanks much for your help.

@JohnWickSmith
Copy link

I'm having issues getting this code to operate in cmd. I've tried using doskey to take the place of the alias, but now I'm experiencing issues with getting it to run beyond that, I've added the program I've made to regedit as an auto run. I've realize I need to replace alias with doskey, and I've tried copying the code given and mashing it up in a couple ways to play with it and see if it would work and so far I can't get it to manage. I double checked my path in regedit and in system enviornment varriables. the path isn't wrong. My path is c:\users\myself\youtube-dl> and i'm trying to run from that path in cmd too when I put in the vs command. It doesn't seem to recognize the vs command though despite the doskey. I've tried a few variations of this code:
DOSKEY vs="yt-dlp -f mp4 --downloader ffmpeg --external-downloader-arg "ffmpeg_i-ss %1 -to %2" "%{@:3}"; %3"
I've attempted with $ instead of %s, I've tried creating another line of code with the
vs() { yt-dlp -f 18 --downloader ffmpeg --external-downloader-args "ffmpeg_i:-ss $1 -to $2" "${@:3}"; }
code in it. that had no effect. I keep getting "the filename, directory name, or volume label is incorrect. as a response.
I tried running
yt-dlp vs 00:00:00 00:00:01 (inserturlherewithnobrackets)
But all that does is try the vs, the times, and then the url as possible addresses to DL from. resulting in the full video with no cuts as intended. The file I pointed the autorun to in pathing is a .cmd file. I'm just struggling at this point with exactly what the file needs to have in it. I'm not really one for coding inside shell stuff like this. I'm on windows 11, I have a background in XHTML, HTML, and a small amount in XML but I am not knowledgeable in cmd beyond things like changing directories, ip release renewing, and trace routing. So suffice it to say this is all new to me for the most part. Following the conversation above idk if I am missing a piece of code, or maybe there was an intended command I didn't realize was needed to run the code because of my inexperience.
I couldn't follow if I needed to just change alias to doskey and use pauls code of:
alias vs="yt-dlp -f 18 --external-downloader ffmpeg --external-downloader-args 'ffmpeg_i:-ss 00:0:11 -to 00:00:25'"
or if I needed to also add:
vs() { yt-dlp -f 18 --downloader ffmpeg --external-downloader-args "ffmpeg_i:-ss $1 -to $2" "${@:3}"; }
Or somehow combine them, or maybe it's just the code isn't for the programing language I'm opperating in in CMD and I need to do some other step i've missed entirely.

TL;DR
Can I get instructions as to the exact file I need to put where and what extention it is and what code I put in?
I know I'm asking you to treat me like a bit of an idiot, but in this language I am one. So tell me slow. Like super slow.

TIA,
<3
John

P.S. it'd be great if this shortcut was programmed into yt-dlp in an update. I'm new here too so idk if it's planned and in the works and just hasn't release yet or I just didn't find it in the --help stuff or on the main github page for it. Sry. v.v

@pukkandan
Copy link
Member

Questions regarding doskey/autorun have nothing to do with yt-dlp and should be asked in appropriate forums, not here.

P.S. it'd be great if this shortcut was programmed into yt-dlp in an update. I'm new here too so idk if it's planned and in the works and just hasn't release yet or I just didn't find it in the --help stuff or on the main github page for it. Sry. v.v

This is an extremely old issue. --download-sections *start-end is the currently recommended option to cut videos

@JohnWickSmith
Copy link

Sorry this wasn't the right place, Your info helped me complete my work though. So thank you!
For any who may end up wondering my code ended up being:
DOSKEY vs=yt-dlp --download-sections $1 $2
The shorthand becomes then
vs *00:00:00-00:00:00`(URL-here)
to me this is much quicker than typing out: vs=yt-dlp --download-sections 00:00:00-xx:xx:xx (URL)

So thanks pukkandan for the help :)
And this doskey runs commands in CMD which reduce the amount of required typing for yt-dlp so I think it is a bit relevant for the sake of being more user friendly/efficient and therefore does have something to do with yt-dlp.

@rafaleo
Copy link

rafaleo commented Feb 18, 2023

Maybe, it's old stuff, but it worked. Now, when I write yt-dlp -i https://www.youtube.com/watch?v=JS4itxO3G7Q --external-downloader ffmpeg --download-section -ss 00:47:36 -t 00:02" -o "c:\Users\cp\Downloads\NET\x1.mp4", I get error yt-dlp: error: no such option: -t. Even if I use -to 00:47:38" instead of -tparameter. While executing this: ```yt-dlp -i https://www.youtube.com/watch?v=JS4itxO3G7Q --download-section "-ss 00:47:36 -to 00:47:38" -o "c:\Users\cp\Downloads\NET\x1.mp4"``` I get error[info] JS4itxO3G7Q: Cannot match chapters since chapter information is unavailable`. What else should I try?

@pukkandan
Copy link
Member

What makes you think that is correct syntax?

yt-dlp/README.md

Lines 574 to 581 in 17ca19a

--download-sections REGEX Download only chapters whose title matches
the given regular expression. Time ranges
prefixed by a "*" can also be used in place
of chapters to download the specified range.
Needs ffmpeg. This option can be used
multiple times to download multiple
sections, e.g. --download-sections
"*10:15-inf" --download-sections "intro"

@rafaleo
Copy link

rafaleo commented Feb 18, 2023

Aha! This worked when I put yt-dlp -i https://www.youtube.com/watch?v=JS4itxO3G7Q --download-section "*00:47:36-00:47:38" -o "c:\Users\cp\Downloads\NET\x1.mp4".
So, is it possible to use -t parameter still? Didn't know youtube-dl became so different now.

@pukkandan
Copy link
Member

pukkandan commented Feb 18, 2023

The old commands work exactly as it did before. There's just new better/easier method to do the same

@NicTanghe

This comment was marked as off-topic.

@bashonly

This comment was marked as off-topic.

@NicTanghe

This comment was marked as off-topic.

@bashonly

This comment was marked as off-topic.

@deepernewbie
Copy link

How about downloading a specific range from a live video stream from youtube? Is it possible youtube player allows going back about 24h back so the data is there and seekable

@pukkandan
Copy link
Member

#6498

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

9 participants