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

"begin" option doesn't affect when the video starts #129

Closed
joek13 opened this issue Mar 20, 2017 · 10 comments
Closed

"begin" option doesn't affect when the video starts #129

joek13 opened this issue Mar 20, 2017 · 10 comments

Comments

@joek13
Copy link

joek13 commented Mar 20, 2017

As the title says, when invoking ytdl, the begin option doesn't actually affect where the video starts to download.

An example:

const ytdl = require("ytdl-core");
const fs = require("fs");
ytdl("https://www.youtube.com/watch?v=q6EoRBvdVPQ", {begin: "5s"}).pipe(fs.createWriteStream("out.mp4"));

The resulting downloaded video starts at the very beginning, regardless of the value of "begin."

@fent
Copy link
Owner

fent commented Mar 20, 2017

I tested this with a longer video. And for some odd reason, when I try the begin option with 5s or anything below that, the video starts at 0. But with 6s or anything above that, it downloads starting at the requested time.

I'm going to guess that this is some YouTube limitation where it won't let you request the download if the time is too close to the start of the video, or the video is too short.

@joek13
Copy link
Author

joek13 commented Mar 24, 2017

I tested this with a longer video. And for some odd reason, when I try the begin option with 5s or anything below that, the video starts at 0. But with 6s or anything above that, it downloads starting at the requested time.

I'm going to guess that this is some YouTube limitation where it won't let you request the download if the time is too close to the start of the video, or the video is too short.

I tested what you're saying here and saw similar results -- longer videos didn't ignore the "begin" option. Maybe this should be noted in the docs, just as a warning?

@fent fent closed this as completed in 3749dda Apr 1, 2017
@shrineofmaya
Copy link

I also was having some issues with the begin option not working correctly, but then I saw this issue was closed. However, I found something interesting.

In the original video that @joek13 uses in the example, if you use the begin option at 6s, the video starts at the beginning. But with this similar video of identical length (https://www.youtube.com/watch?v=0tjUqKNf7gU), using the begin option at 6s works exactly as intended. The only difference between the two videos as far as I could tell was the quality, the former being 360p and the latter being 1080p.

I did some further testing and found that the begin option consistently did not work with any videos 480p quality and below, even taking into consideration the "five second rule" thing. So I think the length of the video doesn't actually matter if it's longer than 5s, but the quality does in terms of whether the begin options works or not.

Is there anything obvious that I might be missing to cause this to not work, or is this an actual new bug?

@fent
Copy link
Owner

fent commented Apr 12, 2017

That's really weird. I wish things were more consistent with YouTube.

@TinyMan
Copy link
Contributor

TinyMan commented May 14, 2017

Any update on this ?

I am using filter 'audioonly' and I couldn't find a video wich works with begin parameter.
With only "highest" quality it works (at least for the video I tested).

@fent
Copy link
Owner

fent commented May 14, 2017

As above states, it looks like it won't work with any video 480p or below. I also tried using it with a super long video that's in 1080p, and it also wouldn't work with audioonly.

There's not much that can be done, except.... post-processing with something like ffmpeg. But even so, the whole file including the non-wanted starting section would have to be downloaded.

@TinyMan
Copy link
Contributor

TinyMan commented May 14, 2017

There's not much that can be done, except.... post-processing with something like ffmpeg. But even so, the whole file including the non-wanted starting section would have to be downloaded.

Yes that's what I was trying to avoid ...

Couldn't it be possible to use range option to download from a start point and use ffmpeg convert it ?

I already use ffmpeg to convert to 16bit PCM so ... I tried to feed the stream to ffmpeg but it keep failing because it cannot recognize input format I guess. But I don't see how to specify it.. Any clue ?

Otherwise with ffmpeg we can specify seekInput but that implies downloading the file from the beginning.

@fent
Copy link
Owner

fent commented May 14, 2017

Couldn't it be possible to use range option to download from a start point and use ffmpeg convert it ?

I already use ffmpeg to convert to 16bit PCM so ... I tried to feed the stream to ffmpeg but it keep failing because it cannot recognize input format I guess. But I don't see how to specify it.. Any clue ?

The range options specifies byte range. Often, the received file won't have their metadata since that is usually specified in the beginning. And ffmpeg will have a hard time guessing what the file is.

It's also difficult to guess the byte range based on a given time.

@TinyMan
Copy link
Contributor

TinyMan commented May 15, 2017

The range options specifies byte range. Often, the received file won't have their metadata since that is usually specified in the beginning. And ffmpeg will have a hard time guessing what the file is.

That's what I want: give ffmpeg a hint on the format .. but I can't figure out any option of ffmpeg that does that. The other solution here is to download metadata and then only starts at the given range. Writing them to the stream should hint ffmpeg. I'll try investigate that ..

It's also difficult to guess the byte range based on a given time.

If we know the format we should be able to calculate the byte position of a given time.

@TinyMan
Copy link
Contributor

TinyMan commented May 15, 2017

Okay downloading the beginning and then jump at a given time works (if we have the offset corresponding to the given time). For example, for itag 251(opus audio only, bitrate 160) I have to download bytes 0-x (depending on the video) and after that I can directly jump at the wanted location.

The header length depends on the itag so I guess the simpler will be to map header lengths into format metas.

But you were right, I find it very hard to calculate the offset of a given time .. HTML5 media element does that, and chromium uses ffmpeg (https://www.chromium.org/developers/design-documents/video) ...

Maybe you have an idea on how to get this offset ?

For now I am using fluent-ffmpeg's .seekInput() method, but downloading the whole file becomes a problem with long video (and we need to seek only in long video ..)

EDIT: I found a way to predict time -> range, is that okay if I create a PR ?

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

Successfully merging a pull request may close this issue.

4 participants