FragmentedMp4Extractor: mfra-indexed fMP4 with zero moov duration is seekable but reports C.TIME_UNSET duration
I maintainer di solito rispondono entro 5 giorni
@snow2405 ci sta già lavorando.
Dal 7/11/2026.
Valutazione
Questa issue non è ancora stata valutata.
Descrizione
Version
Media3 1.11.1
More version details
Also present on main: the new getTrackDurationUs falls back to the mdhd duration, which is 0 in these files as well.
Devices that reproduce the issue
Pixel 9a, Android 17
Devices that do not reproduce the issue
None known. The behaviour comes from the extractor, not from the device.
Reproducible in the demo app?
Not tested
Reproduction steps
This follows up #3088. Since 1.11, DefaultExtractorsFactory always sets FLAG_READ_MFRA_FOR_SEEK_MAP, so a fragmented MP4 indexed only by a trailing mfra is now seekable. When the moov carries no duration, though, it still has no duration.
ffmpeg writes exactly this layout with -movflags frag_keyframe+empty_moov: mvhd/tkhd/mdhd durations are all 0, there is no mehd and no sidx, and the only index is the mfra at the end:
ftyp, moov (durations 0, mvex with trex only), moof, mdat, moof, mdat, ..., mfra
- Make a 3 s file:
ffmpeg -f lavfi -i color=c=black:s=32x32:r=10:d=3 -f lavfi -i sine=f=440:d=3:sample_rate=8000 -c:v libx264 -g 10 -pix_fmt yuv420p -c:a aac -b:a 16k -shortest -movflags frag_keyframe+empty_moov out.mp4(ffprobe reportsduration=3.2). - Play it with
ProgressiveMediaSourceand the default extractors, or run it throughFragmentedMp4Extractorand look at theSeekMapit outputs.
Instrumented test (Pixel 9a). It sniffs with DefaultExtractorsFactory, drives read(), reopens the input at the offset on RESULT_SEEK, and stops at the first seekMap():
FragmentedMp4Extractor -> FragmentedMp4Extractor$MfraSeekMap
isSeekable = true
durationUs = -9223372036854775807 (C.TIME_UNSET)
getSeekPoints(Long.MAX_VALUE) = [timeUs=2200000, position=7099]
Expected result
The duration is known once the mfra has been read, matching what ffprobe/ffmpeg report (3.2 s here, 292.4 s for the real file below). The player shows the duration and the seek bar can be used from the start.
Actual result
MfraSeekMap is seekable, but its duration is C.TIME_UNSET, because it takes durationUs from the moov. ProgressiveMediaPeriod.onLoadCompleted fills in a duration only after the whole file has loaded. For a 27 MB, 4:52 video with a capped buffer that happens near the end of playback, so until then the UI shows no duration or remaining time and the seek bar has nothing to map onto, even though seeking would work.
The tfra entries only give fragment start times, so they alone would undercount. In the real file the last tfra time is 287.84 s against 292.4 s, and fragments there vary from 0.12 s to 7 s. ffmpeg gets the exact value by also parsing the last fragment: its tfdt plus the trun sample durations (falling back to tfhd/trex defaults).
Possible fix: when the moov duration is unset and the mfra was parsed, read the moof the last tfra entry points to (the extractor is already positioned at the end of the file for mfro/mfra), compute tfdt + sum(sample durations) for the primary track, and pass that as the MfraSeekMap duration. If that read fails, the last tfra time is still a better lower bound than TIME_UNSET.
Media
A real-world file (fragmented MP4, 27,652,257 bytes, 292.4 s, H.264 + AAC, 110 fragments): https://blossom.primal.net/b3553ff5ac31930d6962de5fd16db55594e71dc2abfec8e14447d9205e3e3953.mp4
The 3 s synthetic file from step 1 shows the same behaviour.
Bug Report
- You will email the zip file produced by
adb bugreportto [email protected] after filing this issue.
- Lingua principale
- Java
- Stelle
- 3.1k
- Fork
- 1k
- Merge medio
- 7g 12h
- PR unite (30g)
- 5
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di androidx/media
-
CompositionPlayer.release() leaks its playback thread and FrameProcessor when no composition was setForse già presa @droid-girl l’ha presa 4 giorni fa. Apertaediting preview
Difficoltà 2/5 Mezza giornata Idoneità per principianti 62/100
androidx/media#3506 · 1 commento · 1 assegnatario ·
I maintainer di solito rispondono entro 5 giorni
-
bug needs triage
Difficoltà 4/5 3-5 giorni Idoneità per principianti 38/100
I maintainer di solito rispondono entro 5 giorni
-
playback iphone11 video very laggy in MTK chipsetsForse già presa @microkatz l’ha presa 2 giorni fa. Apertabug needs triage
androidx/media#3520 · 1 commento · 1 assegnatario ·
I maintainer di solito rispondono entro 5 giorni
-
MultipleInputVideoGraph leaks the sync object passed to onInputFrameProcessed (file descriptor exhaustion on Adreno)Forse già presa @claincly l’ha presa 2 giorni fa. Apertaediting
androidx/media#3519 · 1 commento · 1 assegnatario ·
I maintainer di solito rispondono entro 5 giorni
-
Media3 reports H.264 [email protected] as supported by a [email protected] hardware decoderForse già presa @microkatz l’ha presa 2 giorni fa. Apertabug needs triage
Difficoltà 4/5 3-5 giorni Idoneità per principianti 45/100
androidx/media#3518 · 1 commento · 1 assegnatario ·
I maintainer di solito rispondono entro 5 giorni
Tutte le issue di androidx/media
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
commons-app/apps-android-commons#7275 ·
I maintainer di solito rispondono entro 1 giorno
-
documentation
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
liberation-data/drivine4j#682 ·
I maintainer di solito rispondono entro 1 giorno
-
Document and enforce pull request review guidelinesForse già presa @dashorst l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
I maintainer di solito rispondono entro 1 giorno
-
`Time.at(t, in: nil)` returns UTC instead of the local time (or the time zone of `t`), unlike CRubyAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
hermes-queue
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 72/100
chrisalunlloyd2-sudo/mindpalace#349 ·
I maintainer di solito rispondono entro 1 giorno