Open akshdeep-singh opened 2 days ago
This is happening because the file has a VBRI header where the table of contents (ToC) only covers 2255081
bytes, while the file on disk is 13605001
bytes long.
When I play this file in ExoPlayer I see a warning logged about this:
VbriSeeker androidx.media3.demo.main W VBRI data size mismatch: 13605001, 2255081
The result of this that we indicate the frame just before byte 2255081
is the last sample, and so playback stops at that point. With some extra logging I see dataEndPosition=2255081, extractorInput.getPeekPosition()=2255491
at these lines:
We are currently assuming that the ToC in the VBRI frame covers the whole file. This is perhaps an unreasonable assumption.
The VBRI frame also has a bytes
field to indicate the amount of MP3 data in the file (which we don't use atm). This should be the number of MP3 bytes, not including the VBRI frame itself.
In your file, the VBRI frame has bytes=13603849
, so based on that we'd expect the end of the MP3 data to be at:
vbriFrameStart + vbriFrameSize + bytes
= 1024 + 522 + 13603849
= 13605395
This seems incorrect, because the file on disk is only 13605001
bytes long!
With a bit of guesswork, and noting that the VBRI frame also has a frameSize=128
field (which is meant to be the average frame size of the rest of the file), we can re-run the calculation assuming whatever populated the bytes
field incorrectly assumed the VBRI frame itself was 128 bytes long:
vbriFrameStart + avgFrameSize + bytes
= 1024 + 128 + 13603849
= 13605001
And this now exactly matches the file on disk.
Aside: We can also derive the MP3 data length from the VBRI frame size & count values: numFrames * frameSize = 2882048
. This is clearly also incorrect in this file (but roughly consistent with the ToC).
Summary:
This file has a strange VBRI frame, with a ToC that only covers the first ~1:40 of the file, an incorrect average frameSize
value, and an incorrect bytes
value which assumes the VBRI frame itself is 128 bytes long (when it's actually 522 bytes long) - meaning it's wrong by 394 bytes.
If we switch to using the bytes
field from the VBRI header then other parts of ExoPlayer's MP3 machinery handle the 394 length error fairly gracefully and playback continues for the whole duration of the file. I'll send a change for this.
This file has a strange VBRI frame, with a ToC that only covers the first ~1:40 of the file
This also results in seeking being broken/nonsensical for this file, because the VBRI ToC assumes that each of the N entries covers an Nth of the file. The result of this is that (with the bytes
fix applied), when I play your file and seek near the end, playback continues well past the 9:48 'duration' - because the "seek near the end" actually resulted in us seeking near the end of the first 2255081
bytes, so there's lots more MP3 data left to consume.
Version
Media3 1.4.1
More version details
No response
Devices that reproduce the issue
Pixel 8 running Android 15 Emulator Pixel 5 Android 14
Devices that do not reproduce the issue
No response
Reproducible in the demo app?
Not tested
Reproduction steps
Expected result
The media plays successfully
Actual result
Either the player starts playing next item in the playlist, or the sound stops but position is increasing. No Error shown by player. Following warnings are there:
I am observing this issue with more mp3 files also but at different positions. The issue is not observed by other softwares, such as Windows Media Player, Chrome Browser Player.
Media
MP3 file link
Bug Report
adb bugreport
to android-media-github@google.com after filing this issue.