occivink / mpv-scripts

Various scripts for mpv
The Unlicense
417 stars 38 forks source link

Add support for downloading youtube-videos #55

Closed m-braunschweig closed 8 months ago

m-braunschweig commented 3 years ago

This is done by using regex to look if the path is in the mpv-googlevideo format. If this is the case, youtube-dl is used to get a normal googlevideo.com url that ffmpeg can handle.

This is currently only tested a few times under Linux, but should close #32 and #46

Currently working formats:

Currently not working:

m-braunschweig commented 3 years ago

Another thing that maybe should be implemented is that the output-title could be changed to the youtube-title, because currently it's just the video-id from YouTube.

This has now been implemented

occivink commented 3 years ago

Hello, I would prefer to rely on the builtin youtube-dl integration to do this, rather than using it directly. To do this, we would have to parse the URLs from the EDL and pass them on to ffmpeg. I need to investigate if each track URL can be retrieved at runtime. So far I've assumed that there is only one input path, but this is not true.

m-braunschweig commented 3 years ago

I think the intern youtube-dl method would be better too. This is rather a workaround, because I don't know much about lua and mpv

dardo82 commented 2 years ago

Thanks for a solutions, but it has two problems:

m-braunschweig commented 2 years ago

I wrote a function parse_edl. You can test it with

data = parse_edl(mp.get_property("stream-path"))
for _, v in pairs(data) do
    print(v)
end

(e.g. in start_encoding). But it has 2 Problems: Firstly this method relies on having only 1 "real" steam and all other are going to be mapped. (https://github.com/mpv-player/mpv/blob/master/DOCS/edl-mpv.rst#separate-files-for-tracks). Secondly I only wrote the function without adding it to the ffmpeg args, because I don't know which arguments you would have to pass to ffmpeg.

@dardo82 what exactly do you mean by sanitizing filenames? Do you mean something like only allowing ASCII with restricting some chars as \, / and &?

dardo82 commented 2 years ago

Using the video title as the file name can easily cause problems with some character, so it's not recommendable without having the necessary care...

dardo82 commented 2 years ago

I suppose you mean stream instead of steam... What do you mean by are going to be mapped? Can you tell us what does the function returns?

m-braunschweig commented 2 years ago

I suppose you mean stream instead of steam

Yes.

Can you tell us what does the function returns?

As you wrote audio and video can be separated. Mpv seems to typically use an own edl format for this case. This function partly parses the edl format, gets all URLs and puts them into a table. With pairs you then can get all tracks. (As I wrote this doesn't parse the full edl format and expects some stuff)

dardo82 commented 2 years ago

Maybe we should delegate yt-dlp to clip the video, instead of calling ffmpeg directly, it's now doable?

https://github.com/yt-dlp/yt-dlp/issues/686#issuecomment-907778993

dardo82 commented 2 years ago

Thanks for being so active on these issues...

m-braunschweig commented 2 years ago

Maybe we should delegate yt-dlp to clip the video, instead of calling ffmpeg directly, it's now doable?

yt-dlp/yt-dlp#686 (comment)

I think that's a great idea. Since that would allow only YouTube videos matching the pattern I'm going to add an option.

dardo82 commented 2 years ago

I haven't tried these new features yet,I'll do it soon...

m-braunschweig commented 2 years ago

I now implemented the 2 options. Please note, that things like filter aren't added when using dlp and edl uses the automatic mapping of ffmpeg. But as far as I tested it the last didn't seem to have problems.

dardo82 commented 2 years ago

The filter can be added to the individual clips. Also if there is just one audio, video and text stream ffmpeg can map them automatically. I'll let you know about the results tomorrow...

shvchk commented 11 months ago

I found a bug: often ffmpeg fails with an error "-to value smaller than -ss; aborting"

Log `` are loooong youtube URLs and headers ``` ffmpeg started on 2023-09-08 at 11:53:16 Report written to "ffmpeg-report-20230908-115316.log" Log level: 48 Command line: ffmpeg -y -hide_banner -headers "" -ss 07:11.633 -to 14.85 -i "https://" -c copy -map 0:0 -map 1:0 -f matroska "file: 07.09.23_0:07:11.633-0:07:26.483_1.mp4.mkv.part" Splitting the commandline. Reading option '-y' ... matched as option 'y' (overwrite output files) with argument '1'. Reading option '-hide_banner' ... matched as option 'hide_banner' (do not show program banner) with argument '1'. Reading option '-headers' ... matched as AVOption 'headers' with argument 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Sec-Fetch-Mode: navigate '. Reading option '-ss' ... matched as option 'ss' (set the start time offset) with argument '07:11.633'. Reading option '-to' ... matched as option 'to' (record or transcode stop time) with argument '14.85'. Reading option '-i' ... matched as input url with argument 'https://'. Reading option '-headers' ... matched as AVOption 'headers' with argument 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Sec-Fetch-Mode: navigate '. Reading option '-ss' ... matched as option 'ss' (set the start time offset) with argument '07:11.633'. Reading option '-to' ... matched as option 'to' (record or transcode stop time) with argument '14.85'. Reading option '-i' ... matched as input url with argument 'https://'. Reading option '-c' ... matched as option 'c' (codec name) with argument 'copy'. Reading option '-map' ... matched as option 'map' (set input stream mapping) with argument '0:0'. Reading option '-map' ... matched as option 'map' (set input stream mapping) with argument '1:0'. Reading option '-f' ... matched as option 'f' (force format) with argument 'matroska'. Reading option 'file: 07.09.23_0:07:11.633-0:07:26.483_1.mp4.mkv.part' ... matched as output url. Finished splitting the commandline. Parsing a group of options: global . Applying option y (overwrite output files) with argument 1. Applying option hide_banner (do not show program banner) with argument 1. Successfully parsed a group of options. Parsing a group of options: input url https://. Applying option ss (set the start time offset) with argument 07:11.633. Applying option to (record or transcode stop time) with argument 14.85. Successfully parsed a group of options. Opening an input file: https://. -to value smaller than -ss; aborting. ```

Thank you for working on this patch, though : )

dardo82 commented 11 months ago

It could be that -to should be -t? 🤓

shvchk commented 11 months ago

yep

lines 203 and 270

dardo82 commented 11 months ago

Glad to hear that,it's already happened to me before. Could you maybe help fixing the script for everyone?

m-braunschweig commented 11 months ago

Looking back at this I didn't create the best commit history/good code. I think I will try to re-implement this via the --download-sections flag from yt-dlp and create a new PR. I would ignore the "raw ffmpeg" method for now which would make the script only work for YouTube by guessing the URL from the filename property

dardo82 commented 11 months ago

Thanks for your efforts,do you need help?

m-braunschweig commented 11 months ago

I should be good since I can copy some code from this PR

m-braunschweig commented 11 months ago

I created the new PR #71. Please feel free to test it