ytdl_hook.lua: get the duration of fragmented mp4#17936
Conversation
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 mpv-player#17762 (comment).
| 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.
Sorry the issue is with bilibili.tv not bilibili.com.
There was a problem hiding this comment.
I see. What's the issue though? It fetches whole timeline pretty quickly.
You could always skip delay-open when there is no duration, but this will fetch all formats, which is slower.
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.
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.