Repository navigation
demux_timeline: update delay_open streams when they are opened - #17936
guidocella wants to merge 1 commit into
Conversation
| hdr[#hdr + 1] = "!delay_open,media_type=" .. sub.media_type .. | ||
| ",codec=" .. (sub.codec or "null") .. props | ||
|
|
||
| if not is_default then |
There was a problem hiding this comment.
Why is this not delay_open anymore? I think you should be initializing duration as documentation says, instead of removing this flag
Using multiple segments requires you to specify all offsets and durations
There was a problem hiding this comment.
It already sets the duration below but it doesn't work for bilibili.tv.
There was a problem hiding this comment.
Why setting duration doesn't work?
There was a problem hiding this comment.
For bilibili.tv it's not present in the JSON (e.g. yt-dlp -J https://www.bilibili.com/video/BV1tywge6EWy/ > /tmp/bilibili.json). I don't know if other extractors share this problem.
There was a problem hiding this comment.
I see duration. It also works in mpv. Is your installation broken?
"duration": 14020.729
"duration_string": "3:53:40"
There was a problem hiding this comment.
Are you testing a short video? It only updates duration up until where the cache is filled.
is_default is only true for the tracks in the selected format. Others are still delayed.
There was a problem hiding this comment.
Are you testing a short video?
43 minutes, it's not so long, but should be enough, no?
It only updates
durationup until where the cache is filled.
I tested with --no-cache
is_defaultis only true for the tracks in the selected format. Others are still delayed.
And what about other tracks, they still don't have duration set.
There was a problem hiding this comment.
With --no-cache duration is only the current time-pos + 1 for me.
The duration is preserved after changing to a delayed track.
There was a problem hiding this comment.
Could we instead reevaluate the coded parameters of delayed tracks when they are selected/opened for the first time?
This not only involves duration, but also codec and dozen other fields in mp_codec_params which are not populated for delayed open.
You can see that we show null codec for all those tracks, if they are not mapped upfront. You can do this to test:
--- a/player/lua/ytdl_hook.lua
+++ b/player/lua/ytdl_hook.lua
@@ -556,7 +556,7 @@ local function formats_to_edl(json, formats, use_all_formats)
props = props .. ",samplerate=" .. as_integer(track.asr)
end
hdr[#hdr + 1] = "!delay_open,media_type=" .. sub.media_type ..
- ",codec=" .. (sub.codec or "null") .. props
+ ",codec=null" .. props
-- Add bitrate information etc. for better user selection.
local byterate = 0There was a problem hiding this comment.
I updated it as suggested, but there is this limitation:
Limitation: --start=50% still ends up at about 1:26 on the bilibili video. The duration isn't known until the selected segment opens, which happens after the initial seek. The old ytdl_hook approach avoided this because it opened the requested formats immediately; this fix doesn't.
|
Non-fragmented |
delay_open streams are added with the codec parameters specified in the EDL, so fields like the codec, dimensions and sample rate are missing or just hints. Moreover, the duration is unknown unless the EDL specifies a length, e.g. because ytdl's JSON doesn't include it, as with bilibili.tv videos since all_formats defaults to true. When a delayed segment is opened, replace the codec parameters of its streams with the real ones, and set the duration from the opened demuxer if it was unknown. The duration is still unknown when the initial seek is performed, because segments are opened lazily on the first read, so percentage seeks like --start=50% still don't work in this case. Fixes mpv-player#17762 (comment).
Changing all_formats' default to true broke reporting the duration of bilibili.tv videos because fragmented MP4 files have the duration in a segment index box and not in the container header.
With all_formats=false the requested formats are opened immediately and libavformat uses HTTP range requests to probe the fragmented MP4 and reads the correct duration.
With all_formats=true every format gets !delay_open and libavformat can't seek for the sidx in that sub-demuxer context.
Fix this by not applying delay_open to the requested formats.
Fixes
#17762 (comment).
Found by Claude.