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

is it possible to download only desired time interval? #4821

Closed
lapaci opened this issue Jan 30, 2015 · 25 comments
Closed

is it possible to download only desired time interval? #4821

lapaci opened this issue Jan 30, 2015 · 25 comments

Comments

@lapaci
Copy link

@lapaci lapaci commented Jan 30, 2015

I want to download small part of a video which is 2 hours long and 1080p. How can i do that with youtube-dl?

@phihag
Copy link
Contributor

@phihag phihag commented Jan 30, 2015

At the moment, there is no such functionality. This is quite complicated internally, because we need to find a table of which times correspond to which byte intervals, interpret that table, download the partial file (that's actually the easy part), and then reassemble the whole shebang so that the headers are valid.

@Reino17
Copy link

@Reino17 Reino17 commented Jan 30, 2015

You could try to let youtube-dl only generate the url and then feed that url to ffmpeg.
Something like this:

SET /P url=
FOR /F %%A IN ('youtube-dl.exe -g %url%') DO (
ffmpeg.exe -ss 00:41:55 -i "%%A" -c copy -t 00:03:00 output.mp4
)
@mannemvamsi
Copy link

@mannemvamsi mannemvamsi commented Feb 10, 2015

Thank You.. !!

@nixxquality
Copy link

@nixxquality nixxquality commented Feb 16, 2015

+1

Long Twitch videos can sometimes be upwards of 5 GiB or more, and if you just want watch a small part of them, you have to wait a long time to be able to even watch that.

@AlexanderMatveev
Copy link

@AlexanderMatveev AlexanderMatveev commented Apr 28, 2015

@corone17 This command downloads a full video to /tmp files or somewhere, loads it for cutting OR it naturally retrieves a part of remote file?

@AlexanderMatveev
Copy link

@AlexanderMatveev AlexanderMatveev commented Apr 28, 2015

@corone17 This didn't work with long video: http://www.youtube.com/watch?v=eyU3bRy2x44 :-(

@Reino17
Copy link

@Reino17 Reino17 commented Apr 29, 2015

@alexmatveev I didn't actually test it 3 months ago, so you could try and run the following as a batch-file:

@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

If you make sure youtube-dl.exe and ffmpeg.exe are in the same directory, then this will work fine for your 3hour fireplace video :p.
Youtube-dl.exe will generate the direct videolink. This link will be the input for ffmpeg, which will then only download the section you specify.

@jaimeMF
Copy link
Collaborator

@jaimeMF jaimeMF commented Sep 2, 2015

Closing as a duplicate of #622.

@sergiy-talashko
Copy link

@sergiy-talashko sergiy-talashko commented Apr 6, 2017

@Reino17 Could you please write a shell script? (for linux users)

@Reino17
Copy link

@Reino17 Reino17 commented Apr 6, 2017

I'm sorry, but I'm not a Linux user. I have very little experience with Linux's shell script.

@sergiy-talashko
Copy link

@sergiy-talashko sergiy-talashko commented Apr 6, 2017

@Reino17 Ok, still thanks

@andreikobe
Copy link

@andreikobe andreikobe commented Nov 2, 2017

i finally made an account because I'm desperate for a clipconverter dot cc alternative because they've recently made impossible restrictions to what they could download. Really hope you find a way :(

@KeithCu
Copy link

@KeithCu KeithCu commented Jan 31, 2018

I know this is a somewhat difficult feature, but it is a great one to add. Right now, I want to grab a 2 minute clip from a 3 gig video file! I'd love to be able to give you the -ss and -t flags like ffmpeg.

@josephomorrow
Copy link

@josephomorrow josephomorrow commented May 1, 2018

youtube-dl does have a --postprocessor-args command-line parameter. Example:

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

where -ss indicates start position (13 minutes in) and -t indicates new length (4 minutes) of output video. Just tried it with a 47-minute video that had about 4 hours of nothing on the end of it. I used --postprocessor-args "-t 00:47:00.0" and it worked fine.

@teocci
Copy link

@teocci teocci commented May 3, 2018

I know that this question is long but you can do it using this command:

ffmpeg -ss 3:59:10 -i $(youtube-dl -f 22 -g 'https://www.youtube.com/watch?v=mMZriSvaVP8') \
-t 3:06:00

You need to have the ffmpeg installed.

@andreikobe
Copy link

@andreikobe andreikobe commented May 3, 2018

Yes, but that would mean I will have to download what could be a 1 gb file to get a few seconds

@josephomorrow
Copy link

@josephomorrow josephomorrow commented May 3, 2018

I was primarily giving a command-line-friendly solution. If your download speed is too slow, then what alternative would you suggest for downloading a smaller chunk of the original?

@noureddin
Copy link

@noureddin noureddin commented May 3, 2018

teocci's command works perfectly and doesn't download the entire video; I just tried it.

Inspired by it and Reino17's script, I hacked together a non-interactive Bash function that downloads a range of any youtube-dl downloadable video, provided you have ffmpeg.

You can put it in you ~/.bashrc. It should also work in Zsh.

download-clip() {
    # $1: url or Youtube video id
    # $2: starting time, in seconds, or in hh:mm:ss[.xxx] form
    # $3: duration, in seconds, or in hh:mm:ss[.xxx] form
    # $4: format, as accepted by youtube-dl (default: best)
    # other args are passed directly to youtube-dl; eg, -r 40K
    local fmt=${4:-best}
    local url="$(youtube-dl --get-url "$1" -f $fmt ${@:5})" 
    local filename="$(youtube-dl --get-filename "$1" ${@:5})"
    ffmpeg -loglevel warning -hide_banner \
        -ss $2 -i "$url" -c copy -t $3 "$filename"
    printf "Saved to: %s\n" "$filename"
    # based on Reino17's and teocci's comments in https://github.com/rg3/youtube-dl/issues/4821
}

A few catches:

  • No download progress bar.

  • If a video has a higher resolution in a video-only format, which youtube-dl downloads by default, than the format labeled "(best)", you'll get a "HTTP error 400 Bad Request". Thus, I made it by default download the best single audio+video file. You can easily change it as it's a function argument.
    See this comment also.

@Reino17
Copy link

@Reino17 Reino17 commented May 4, 2018

Very nice.
Lately I've become more and more familiar with Bash (although I'm still a Windows user), but some things are still new to me.
Does ${4:-best} mean: default to "-best" if the 4th parameter is empty?
What does ${@:5} exactly do/mean (the @ in particular)?
You know the $url-assignment can be simplified by doing $(youtube-dl -gf $fmt ${@:5} "$1")?
Also note Usage: youtube-dl.exe [OPTIONS] URL [URL...] that options (officially) need to go before the url.

@noureddin
Copy link

@noureddin noureddin commented May 4, 2018

Thanks, Reino17.

${4:-best} returns the value of $4 if it has a value, otherwise (if it's unset or null) the value after the :- is used, ie, best.
This is one of the Parameter Expansions listed in man bash. ;)

$@ is an array holding all the parameters passed to the function; ie, it's equivalent to $1 $2 $3 ....
${@:5} returns $@ without the first four elements.

I preferred --get-url over -g mainly to be consistent with --get-filename, and also to be more readable, because it's not an option I use every day. But I've already used the short option -f. So I guess you're right.

I also forgot to add the format option to the get-filename command, because it can change the extension.

As I can't find a documentation for the urls-options order except what you mentioned, I will change the code to put the urls at the end. Thanks.

I also added the -stats option to ffmpeg to show the progress bar of the encoding. (It shows after some time; I guess it downloads the relevant segment first.)

For quieter output, you can remove -stats, and change -loglevel warning to -loglevel quiet.

download-clip() {
    # $1: url or Youtube video id
    # $2: starting time, in seconds, or in hh:mm:ss[.xxx] form
    # $3: duration, in seconds, or in hh:mm:ss[.xxx] form
    # $4: format, as accepted by youtube-dl (default: best)
    # other args are passed directly to youtube-dl; eg, -r 40K
    local fmt=${4:-best}
    local url="$(youtube-dl -g -f $fmt ${@:5} "$1")"
    local filename="$(youtube-dl --get-filename -f $fmt ${@:5} "$1")"
    ffmpeg -loglevel warning -hide_banner -stats \
        -ss $2 -i "$url" -c copy -t $3 "$filename"
    printf "Saved to: %s\n" "$filename"
    # based on Reino17's and teocci's comments in https://github.com/rg3/youtube-dl/issues/4821
}
@KeithCu
Copy link

@KeithCu KeithCu commented May 10, 2018

That's a great step. Do you think you could convert it to Python and submit it as a patch?

@noureddin
Copy link

@noureddin noureddin commented May 11, 2018

I am not familiar enough with youtube-dl source code to be able to make a patch, but I will try.

In the mean time, there are some other discussions about this feature, mainly: #8851, and #622.
And johnhawkinson suggested a good idea in #12347, but it doesn't seem to work in all cases.

@satnatantas
Copy link

@satnatantas satnatantas commented May 21, 2018

@noureddin do you know a way of doing same but with support for resuming?

@noureddin
Copy link

@noureddin noureddin commented May 29, 2018

@satnatantas, if ffmpeg can resume a paused transcoding, it can be done. But unfortunately I couldn't find a way to do that reliably; the best way I was able to find is to pause using ctrl-z and then resume using fg. I will be interested if you find a better way. :)

@estathop
Copy link

@estathop estathop commented Sep 17, 2018

any progress ?

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

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.