youtube-dl: Youtube-dl can't merge VP9+Opus youtube videos
Checklist
- I’m reporting a broken site support
- I’ve verified that I’m running youtube-dl version 2021.01.24.1
- I’ve checked that all provided URLs are alive and playable in a browser
- I’ve checked that all URLs and arguments with special characters are properly quoted or escaped
- I’ve searched the bugtracker for similar issues including closed ones
Verbose log
youtube-dl -v --abort-on-unavailable-fragment -f (bestvideo[vcodec=vp9])+(bestaudio[acodec=opus]) https://youtu.be/g6zva0stnOY --no-continue
[debug] System config: []
[debug] User config: []
[debug] Custom config: []
[debug] Command-line args: ['-v', '--abort-on-unavailable-fragment', '-f', '(bestvideo[vcodec=vp9])+(bestaudio[acodec=opus])', 'https://youtu.be/g6zva0stnOY', '--no-continue']
[debug] Encodings: locale UTF-8, fs utf-8, out utf-8, pref UTF-8
[debug] youtube-dl version 2021.01.24.1
[debug] Python version 3.8.7 (CPython) - Linux-5.10.11-0-lts-x86_64-with
[debug] exe versions: ffmpeg 4.3.1, ffprobe 4.3.1
[debug] Proxy map: {}
[youtube] g6zva0stnOY: Downloading webpage
[youtube] g6zva0stnOY: Downloading MPD manifest
[debug] Invoking downloader on [REDACTED]
[dashsegments] Total fragments: 280
[download] Destination: المحاضرة الثانية _ الثرموداينمك _ الجزء الثاني 2021-g6zva0stnOY.f302.webm
[download] 100% of 417.83MiB in 24:16
[debug] Invoking downloader on [REDACTED]
[dashsegments] Total fragments: 157
[download] Destination: المحاضرة الثانية _ الثرموداينمك _ الجزء الثاني 2021-g6zva0stnOY.f251.webm
[download] 100% of 22.60MiB in 00:36
[ffmpeg] Merging formats into "المحاضرة الثانية _ الثرموداينمك _ الجزء الثاني 2021-g6zva0stnOY.webm"
[debug] ffmpeg command line: ffmpeg -y -loglevel repeat+info -i 'file:المحاضرة الثانية _ الثرموداينمك _ الجزء الثاني 2021-g6zva0stnOY.f302.webm' -i 'file:المحاضرة الثانية _ الثرموداينمك _ الجزء الثاني 2021-g6zva0stnOY.f251.webm' -c copy -map 0:v:0 -map 1:a:0 'file:المحاضرة الثانية _ الثرموداينمك _ الجزء الثاني 2021-g6zva0stnOY.temp.webm'
ERROR: Conversion failed!
Traceback (most recent call last):
File "/usr/lib/python3.8/site-packages/youtube_dl/YoutubeDL.py", line 2102, in post_process
files_to_delete, info = pp.run(info)
File "/usr/lib/python3.8/site-packages/youtube_dl/postprocessor/ffmpeg.py", line 523, in run
self.run_ffmpeg_multiple_files(info['__files_to_merge'], temp_filename, args)
File "/usr/lib/python3.8/site-packages/youtube_dl/postprocessor/ffmpeg.py", line 235, in run_ffmpeg_multiple_files
raise FFmpegPostProcessorError(msg)
youtube_dl.postprocessor.ffmpeg.FFmpegPostProcessorError: Conversion failed!
FFmpeg gives me the following error when I run the command mentioned in the above output manually:
[webm @ 0x7fe94ccf40c0] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 5620 >= 5600 av_interleaved_write_frame(): Invalid argument
I’ve tried to re-download it multiple times and the issue persists. Other videos can be merged fine, so it seems like this is a problem with this particular video.
About this issue
- Original URL
- State: open
- Created 3 years ago
- Reactions: 2
- Comments: 54 (10 by maintainers)
@Vangelis66
You have bigger shit to worry about if you’re on Windows Vista. You do realize you’re on an operating system with no security from Microsoft? There should be no reason for you to be on there other than pure incompetence.
Hello 😃
We have narrowed down the problematic ffmpeg commit to https://github.com/FFmpeg/FFmpeg/commit/2e6636aa87303d37b112e79f093ca39500f92364
This commit disabled the ability for ffmpeg to correct DTS errors when the encoding is VP9, and the mode is a simple copy.
We are testing some patches right now to see if we can restore DTS correction for VP9 without re-introducing 4313.
Talked to FFmpeg developers on
#ffmpeg-devel
IRC. They stopped publishing IRC logs in June 2020 (https://lists.ffmpeg.org/pipermail/ffmpeg-devel-irc/), so here is the short summary:https://trac.ffmpeg.org/ticket/9086 is now closed.
If someone is tired waiting for FFmpeg devs to fix this issue, FFmpeg builds with a patch by @danny-wu can be found here: https://github.com/nihil-admirari/FFmpeg-With-VP9-Timestamp-Fix/releases. Builds are based on https://github.com/BtbN/FFmpeg-Builds.
When it comes to
setts
filter, looks like bitstream filter parser is based on a simple tokenizer, which completely ignores escape sequences. Most likely it’s a bug, but until it is fixed,setts
cannot be used to correct timestamps.A Googler has filed an issue about their malformed VP9 encoding in their internal bug tracker.
Patch submitted to ffmpeg-devel mailing list 😄
Video playback is perfect on VLC.
https://github.com/FFmpeg/FFmpeg/commit/301d275301d72387732ccdc526babaf984ddafe5 has not been backported to 4.4 release branch. Problem with commas is still reproducible there.
Turns out that
eval
doesn’t support conditional operators, only functions. Correct syntax is:With PTS part present,
Invalid DTS
warning goes away. It should reproduce the C code, assuming thatPREV_OUTDTS
isost->last_mux_dts
,DTS
ispkt->dts
,PTS
ispkt->pts
, and that VP9 holding containers are non-strict.Hi @Vangelis66, I will continue working on the patch with the goals of incorporating it into ffmpeg.
Unfortunately I do not develop on Windows, and have no clue how to compile for Windows. Sorry! But someone else is of course welcome to compile (although I cannot endorse the security of any binaries, and do not encourage running untrusted binaries).
I think this is a valid case that calls for introducing a
postprocessor-args-prepend
flag toyoutube-dl
.@Vangelis66 I have relayed that to them, in addition to the results of your testing to track down the error in past builds. I don’t know that it’ll matter due to the stipulation of using the current git head (which I surmise is the most recent version) but I figured it wouldn’t hurt to try.
Thanks again.
I have opened an issue: https://trac.ffmpeg.org/ticket/9187#ticket Lets see what happens
Doesn’t work atleast without any parameters and I have no idea what params to use
Continuing the investigation. One merge was done with vanilla FFmpeg using
setts
filter:A second merge was done with patched FFmpeg without using any filters:
FFprobe was used to show the packet structure:
Diff is empty. (If you know a better way to diff videos, please let me know.)
Looks like
setts
filter expression is in fact identical to what the patch does. For example, replacingPREV_OUTDTS
withPREV_OUTDTS + 1
produces a non-empty diff.Once
-bsf
fix is propagated to FFmpeg releases,setts
may become a viable solution to this problem. Currently it works only onmaster
builds of FFmpeg.Handling of commas was fixed in https://github.com/FFmpeg/FFmpeg/commit/301d275301d72387732ccdc526babaf984ddafe5, almost a month after my comment.
If you were to read what is written above carefully, you would’ve found the following:
I wasn’t claiming that any TS filter expression results in an error, I was claiming that expressions containing commas do not parse. The error message was also presented, I don’t quite understand how that isn’t a proof:
That said, I’ve retested everything again with latest FFmpeg from BtbN. Looks like a problem with commas has been fixed since June (now it’s a problem with parentheses, see below).
Video downloaded with
does merge with an additional
-bsf:v 'setts=dts=max(DTS\, PREV_OUTDTS)'
, producing a warning:Full FFmpeg command line:
However, an attempt to set PTS in addition to DTS with
-bsf:v 'setts=pts=if((DTS < PREV_OUTDTS) * (PTS >= DTS)\, max(PTS\, PREV_OUTDTS)\, PTS):dts=max(DTS\, PREV_OUTDTS)'
fails with:Quoting myself:
Looks like WebM & Matroska are both non-strict: https://github.com/FFmpeg/FFmpeg/blob/master/libavformat/webm_chunk.c#L298, https://github.com/FFmpeg/FFmpeg/blob/master/libavformat/matroskaenc.c#L2842 (correct me if I’m wrong, or if VP9 could be merged into a container that is strict).
The task is to convert the C code above into FFmpeg eval expression. My attempt:
partially worked. I’d be happy to hear how to write a conditional that doesn’t result in
Your information about setts filter is incorrect and misleading. Also you provided no proofs for your claims. Here is one possible example how to use setts filter:
-bsf:v setts=ts=‘N*(1001/60000)/TB’
I’m sure if you know how to properly overwrite non-monotonic PTS/DTS in stream that if you provide working formula I can write expression for you to be used in setts filter.
@danny-wu wrote:
That is actually
ffmpeg-n3.1-dev-541-N-79004-git-20160311-g2e6636a
so just 15 commits away from the last win32 build (I found to be the one) in which the remux works:ffmpeg-n3.1-dev-526-N-78989-git-20160310-gcaeed04
So glad I was able to help pinpoint a regression window!Many thanks, indeed! 👍 This is the actual mailing list thread:
http://ffmpeg.org/pipermail/ffmpeg-devel/2021-May/280189.html
The one dev that replied as of now appears to be yet unconvinced… 😞
Knowing how evil Google are 😠 👎 , I wouldn’t rule out them “fixing” their HFR encodes on purpose, just to spoil it for “downloaders”…
Knowing the ffmpeg devs, it’ll probably take eons to review/approve/merge submitted patch; @danny-wu, are you willing to post your patch here, too, and, optimally, compile win32 FFmpeg builds for us Windows people (preferably ones that would launch on Vista, too, as that is the minimum ffmpeg supports currently) ?
I haven’t been idle myself on this, despite not posting here… 😜 I have been going through FFmpeg’s vast documentation in search of an interim “workaround”, until this is addressed in FFmpeg code…
-fflags "+noparse +nofillin"
supposedly will make FFmpeg disregard the
non-monotonus DTS
inside the VP9 video stream (rather than correct it, as with FFmpeg-3.0.1) and proceed with the mux; thus, the “issue” is then delegated to the player asked to play back the muxed streams…However, that switch has to be specified before the “invalid” VP9 file, e.g.
works
but
fails 😭 (ffmpeg44 a renamed ffmpeg.exe v4.4) …
Where I am currently stuck is that when I supply the switch to
yt-dl
via, e.g.--postprocessor-args "-fflags +noparse -fflags +nofillin"
, this gets added in the ffmpeg command after the input files and mux fails… 😞@Vangelis66 and @pukkandan, I just want to thank you for the investigation. I’ve been troubleshooting and I believe the root cause is that there was a regression in this specific function that aims to correct DTS non-linearity:
https://github.com/FFmpeg/FFmpeg/blob/fd5f4ac0813c27c34c387f00044905a859e29e37/fftools/ffmpeg.c#L757
Reading the code, it seems clear the intention is not to exit/abort when there is a DTS non-linearity, but rather correct it. Unfortunately, this correction logic broke after ffmpeg3, and is no longer working correctly.
I’ve passed this information to the ffmpeg developers, and I hope they are able to fix it, but as this is an open source project, to anyone with C knowledge, it would be amazing if anyone could investigate this specific function and see why this stopped properly correcting around
ffmpeg-n3.1-dev-1443-N-79906-git-20160510-gc8c14d0
.Hopefully we can get to the bottom of this and finally fix it 😃
OK, I think I may have made some progress, the findings of which, sadly, won’t apply to the vast majority of
yt-dl
users… 😢 FTR, I am on Windows Vista SP2 32-bit, it is currently extremely hard for me to find 1: recent 32-bit ffmpeg compiles, as all of the ffmpeg Windows-binary repos (linked to in the official ffmpeg site) now offer 64-bit compiles exclusively… 💢 2: recent 32-bit ffmpeg builds that have been compiled with appropriate compiler flags to target Vista (NT 6.0) as the minimum WinOS; FTR, the ffmpeg source still supports fully NT 6.0 (but some third party libs don’t - others [e.g. libx265] need special compatibility flags to be set at build time) … Many thanks to @AnimMouse for his Vista-compatible 32-bit ffmpeg builds - my “progress” in this issue wouldn’t be possible without his builds 👍 .Now, to the point:
@mechalincoln wrote:
@pukkandan wrote:
The first thing is, that the “setts bitstream filter” is a very recent addition to FFmpeg code; I first conducted my experiments with a ffmpeg build version n4.3.2, and that filter was missing there! But, it is present in latest stable n4.4 release:
ffmpeg -hide_banner -bsfs
=>Documentation for that new bsf is provided in
https://ffmpeg.org/ffmpeg-bitstream-filters.html#setts
The syntax for bsfs is documented in
https://ffmpeg.org/ffmpeg-bitstream-filters.html#Description
In previous logs of this thread, muxing fails because of discrepancies in the DTS of the input video file (formats
-f=302|303
) ; I first fetched the two elementary streams by issuing:youtube-dl --console-title -c --no-part --fixup never -f 302 "W9mNLFseTT4" -o VP9_674p60.webm
youtube-dl --console-title -c --no-part --fixup never -f 251 "W9mNLFseTT4" -o opus96k.webm
… and after some brief experimentation, I achieved successful muxing to a WEBM container, with FFmpeg-n4.4, by issuing:
ffmpeg -i "VP9_674p60.webm" -i "opus96k.webm" -c copy -bsf:v setts=dts=0 "VP9+opus.webm"
=>MediaInfo Log of produced file: VP9+opus.webm.txt
However, the only software player on my system that produces a trouble-free playback of the resultant webm file is the mpv-based SMPlayer:
YMMV, of course, especially on systems (Win10) with VP9 hardware decoding… So, we’re getting there, but not currently THERE…
@pukkandan : I don’t think the FFmpeg people would engage further in this… @mechalincoln: Could you revisit the ffmpeg-user mailing list and kindly ask for more clarification towards “fine-tuning” the
bsf:v setts
syntax/arguments? I have little experience in filter syntax, less so with this very new one, for which no working examples can be currently found on-line… 😢Of course, migrating every
yt-dl
user to FFmpeg 4.4+ isn’t very practical currently, plus the fact the issue at hand manifests itself at random youtube video IDs discourages, probably, the devs from writing code exclusive to ffmpeg 4.4+… Additionally, a lot more testing is needed on how the muxed file (with using the setts bsf) behaves on popular media players… ❓Addition: The webm file produced by OLD ffmpeg (N-78989-gcaeed04 in my tests) plays absolutely fine in ALL players available in my machine (MPC-HC, MPC-BE, PotPlayer, VLC 3 and SMPlayer), thus I still consider using an ol’n’good ffmpeg build to be the definitive cure for this… 😉