Title: HLS: every exposed track Format has a null id in 1.11.0 (regression from 1.9.x)
Version
Media3 1.11.0
More version details
Regression relative to Media3 1.9.0 (same app, same content, same device).
Devices that reproduce the issue
- NVIDIA SHIELD Android TV (2019, mdarcy) running Android 11 (API 30)
Devices that do not reproduce the issue
- The same device with the same app built against Media3 1.9.0 exposes the ids as expected.
Reproducible in the demo app?
Not tested
Reproduction steps
- Play an HLS multivariant playlist that carries
EXT-X-STREAM-INF variants and EXT-X-MEDIA audio renditions (the one used here has 13 variants and four audio rendition groups, aud-aac, aud-ec3, aud-ac3, aud-aac-lo, all named Audio). Default DefaultTrackSelector, default HlsMediaSource.Factory (chunkless preparation left enabled).
- In
Player.Listener.onTracksChanged (or any time after prepare), iterate player.getCurrentTracks().getGroups() and read group.getTrackFormat(i).id for every track of every group.
Expected result
Ids are present, as on 1.9.x:
- variants: the variant index (
"0", "1", ...), matching HlsManifest.multivariantPlaylist.variants[i].format.id
- audio renditions:
"<GROUP-ID>:<NAME>", e.g. "aud-aac:Audio", matching multivariantPlaylist.audios[i].format.id
- subtitle renditions: likewise
Actual result
Format.id is null (and Format.metadata is null) for every exposed HLS track: video, audio and text. Playback itself is fine. Sources played through ProgressiveMediaSource (a Matroska file in the same app) are unaffected, their formats keep their ids.
Cause, as far as I can tell from the 1.11.0 source:
HlsRedundantGroup.GroupKey builds the format it stores with format.buildUpon().setId(null).setMetadata(null).build() so that "only fields affecting identity are part of the key".
HlsMediaPeriod now prepares the track groups from those key formats rather than the original playlist formats: selectedRedundantGroupFormats[outIndex] = variantRedundantGroup.groupKey.format in buildAndPrepareMainSampleStreamWrapper, scratchRedundantGroupFormats.add(audioRedundantGroup.groupKey.format) in buildAndPrepareAudioSampleStreamWrappers, and the same for subtitles.
- With chunkless preparation those formats are exposed as-is, and
HlsSampleStreamWrapper.deriveFormat copies playlistFormat.id (now null) onto formats derived from sample data, so the id never comes back.
Impact: anything that identifies or selects tracks by Format.id (documented as the identifier of a track) can no longer do so for HLS, and exposed formats can no longer be joined back to HlsManifest.multivariantPlaylist entries by id. TrackSelectionOverride by group and index still works, which is why playback and the default selection are unaffected.
A possible fix: keep using the normalized format as the key of the redundant group, but expose the original playlist Format (with its id, or the stable id) in the prepared track groups.
Media
Reproduced with a private multivariant playlist; it should reproduce with any playlist that has EXT-X-MEDIA audio renditions, since the id is cleared unconditionally in GroupKey. Happy to email the playlist to android-media-github@google.com after filing if needed.
Bug Report
Title: HLS: every exposed track Format has a null id in 1.11.0 (regression from 1.9.x)
Version
Media3 1.11.0
More version details
Regression relative to Media3 1.9.0 (same app, same content, same device).
Devices that reproduce the issue
Devices that do not reproduce the issue
Reproducible in the demo app?
Not tested
Reproduction steps
EXT-X-STREAM-INFvariants andEXT-X-MEDIAaudio renditions (the one used here has 13 variants and four audio rendition groups,aud-aac,aud-ec3,aud-ac3,aud-aac-lo, all namedAudio). DefaultDefaultTrackSelector, defaultHlsMediaSource.Factory(chunkless preparation left enabled).Player.Listener.onTracksChanged(or any time after prepare), iterateplayer.getCurrentTracks().getGroups()and readgroup.getTrackFormat(i).idfor every track of every group.Expected result
Ids are present, as on 1.9.x:
"0","1", ...), matchingHlsManifest.multivariantPlaylist.variants[i].format.id"<GROUP-ID>:<NAME>", e.g."aud-aac:Audio", matchingmultivariantPlaylist.audios[i].format.idActual result
Format.idisnull(andFormat.metadataisnull) for every exposed HLS track: video, audio and text. Playback itself is fine. Sources played throughProgressiveMediaSource(a Matroska file in the same app) are unaffected, their formats keep their ids.Cause, as far as I can tell from the 1.11.0 source:
HlsRedundantGroup.GroupKeybuilds the format it stores withformat.buildUpon().setId(null).setMetadata(null).build()so that "only fields affecting identity are part of the key".HlsMediaPeriodnow prepares the track groups from those key formats rather than the original playlist formats:selectedRedundantGroupFormats[outIndex] = variantRedundantGroup.groupKey.formatinbuildAndPrepareMainSampleStreamWrapper,scratchRedundantGroupFormats.add(audioRedundantGroup.groupKey.format)inbuildAndPrepareAudioSampleStreamWrappers, and the same for subtitles.HlsSampleStreamWrapper.deriveFormatcopiesplaylistFormat.id(now null) onto formats derived from sample data, so the id never comes back.Impact: anything that identifies or selects tracks by
Format.id(documented as the identifier of a track) can no longer do so for HLS, and exposed formats can no longer be joined back toHlsManifest.multivariantPlaylistentries by id.TrackSelectionOverrideby group and index still works, which is why playback and the default selection are unaffected.A possible fix: keep using the normalized format as the key of the redundant group, but expose the original playlist
Format(with its id, or the stable id) in the prepared track groups.Media
Reproduced with a private multivariant playlist; it should reproduce with any playlist that has
EXT-X-MEDIAaudio renditions, since the id is cleared unconditionally inGroupKey. Happy to email the playlist to android-media-github@google.com after filing if needed.Bug Report
adb bugreportto android-media-github@google.com after filing this issue.