Matroska: Handle recursive SeekHead elements
Version Media3 1.2.1
Reproduction steps
- Use Below Video URI for Testing
- Try to Seek to Any Position, it will drag the player Back to Position 0
- Even Seek bar won't work from PlayerView
Video URI https://firebasestorage.googleapis.com/v0/b/sample-fefcc.appspot.com/o/demo.viki.mkv?alt=media&token=ba09dffc-c076-4a43-ae36-6cdc8a16223e
Video Info Duration-> 4060070 size-> 649047285 mimeType -> video/x-matroska
I'm proving some Sample Video URL for testing purpose where I found this Issue where I'm unable to seek to any duration in Media3 Exoplayer.
I'm Using Exoplayer Playerview In this Even Default Seekbar I'm unable to interact with that the seekbar is not even moving in PlayerView.
When I try to seek to any duration Like exoPlayer.seekTo(exoPlayer.currentPosition + 20000) It's seek back to starting position of 0,If I haven't any seek than the full video is playing perfectly but when I touch seek the video current position is going to 0.
The symptoms you're seeing are due to ExoPlayer considering the file 'unseekable'. Often with MKV files this happens because the file doesn't contain a Cues element: https://github.com/google/ExoPlayer/issues/9901
However in this case I do see a Cues element when inspecting the video with mkvinfo.
Looking at this video further, it seems to have two SeekHead elements, with the first one pointing to the second and the second one pointing on to the Cues element:
$ mkvinfo --all --continue demo.viki.mkv | grep -U5 -i seek
|+ Maximum EBML size length: 8
|+ Document type: matroska
|+ Document type version: 4
|+ Document type read version: 2
+ Segment: size 649047233
|+ Seek head
| + Seek entry
| + Seek ID: 0x11 0x4d 0x9b 0x74 (KaxSeekHead)
| + Seek position: 649047145
|+ EBML void: size 40
|+ Segment information
| + Timestamp scale: 1000000
| + Title: DA_Rips.TG.Group
| + Multiplexing application: Lavf59.27.100
--
| + Attached
| + File name: cover.jpg
| + MIME type: image/jpeg
| + File UID: 15772195979298410693
| + File data: size 232825
|+ Seek head
| + Seek entry
| + Seek ID: 0x12 0x54 0xc3 0x67 (KaxTags)
| + Seek position: 961
| + Seek entry
| + Seek ID: 0x1c 0x53 0xbb 0x6b (KaxCues)
| + Seek position: 648756852
| + Seek entry
| + Seek ID: 0x15 0x49 0xa9 0x66 (KaxInfo)
| + Seek position: 71
| + Seek entry
| + Seek ID: 0x16 0x54 0xae 0x6b (KaxTracks)
| + Seek position: 170
| + Seek entry
| + Seek ID: 0x19 0x41 0xa4 0x69 (KaxAttachments)
| + Seek position: 648814267
We only parse the first one, and don't follow the link to the second one, which means we never find the Cues element.
I will mark this as an enhancement to support MKV videos with such recursive SeekHead elements. This is the first such video I'm aware of - do you know how it was produced? Knowing how prevalent videos of this format are will help us to assess the priority of this issue. It's not immediately obvious to me why this recursive structure is useful, and why the video couldn't just have a single SeekHead element.
I met several similar mkv files
It looks like this recursive SeekHead layout might be produced by mkvtoolnix (though it could be produced by other muxers too ofc): https://gitlab.com/mbunkus/mkvtoolnix/-/wikis/All-tracks-vanished-after-mkvpropedit,-the-header-or-chapter-editors
Any update on this issue, as it is still not fixed. I have confirmed this exact same issue when playing mkv files on media3 1.5.1.
I solved this in our app by adding support for ID_SEEK_HEAD in this PR if anyone else is having these issues https://github.com/recloudstream/cloudstream/pull/1604
It is like a 30 line change to the matroska extractor, so is there any reason why the official android mediaplayer has not added this? It might not be 100% correct, but works on the MKV files me and other tested.
is there any reason why the official android mediaplayer has not added this
We just haven't implemented it. If you would like to send a PR to this project we can take a look at merging it. It would be good to also include a test matroska file with the 'new' structure, probably by modifying one of our existing files and adding a test case to MatroskaExtractorTest.