Skip to content

ytdl_hook.lua: get the duration of fragmented mp4#17936

Open
guidocella wants to merge 1 commit into
mpv-player:masterfrom
guidocella:bilibili
Open

ytdl_hook.lua: get the duration of fragmented mp4#17936
guidocella wants to merge 1 commit into
mpv-player:masterfrom
guidocella:bilibili

Conversation

@guidocella
Copy link
Copy Markdown
Contributor

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.

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).
Comment thread player/lua/ytdl_hook.lua
hdr[#hdr + 1] = "!delay_open,media_type=" .. sub.media_type ..
",codec=" .. (sub.codec or "null") .. props

if not is_default then
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It already sets the duration below but it doesn't work for bilibili.tv.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why setting duration doesn't work?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see duration. It also works in mpv. Is your installation broken?

"duration": 14020.729
"duration_string": "3:53:40"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry the issue is with bilibili.tv not bilibili.com.

Copy link
Copy Markdown
Member

@kasper93 kasper93 May 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you testing a short video?

43 minutes, it's not so long, but should be enough, no?

It only updates duration up until where the cache is filled.

I tested with --no-cache

is_default is 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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With --no-cache duration is only the current time-pos + 1 for me.

The duration is preserved after changing to a delayed track.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants