- Common library:
- Add
Format.channelMaskto explicitly represent the audio channel mask, and a newUtil.getAudioTrackChannelConfig(Format)overload to safely resolve it. - Upgrade Kotlin from 2.0.20 to 2.2.0.
- Add
- ExoPlayer:
- Fix a timing-dependent concurrency bug that could cause an
IllegalStateExceptionorIndexOutOfBoundsExceptionin ExoPlayer. - Relax ad group count checks in
AdsMediaSourceto allow the ad group count to decrease when an ad group is fully processed
(hasUnplayedAds()isfalse), accommodating dynamic ad group resizing during reset workflows. - Add
getFlags()andFLAG_STRICT_DURATIONtoSampleStreamto allow streams to report flags, and update renderers to check these flags dynamically. - Fall back to the frame rate estimator in
MediaCodecVideoRendererand to the codec output format inMediaCodecAudioRendererto calculate the codec operating rate when the stream formats do not provide a valid value, and avoid unnecessary codec resets. - Remove clipping of content for client-side inserted ads in the core player. Instead,
AdsMediaSourcetakes care of the clipping logic. Custom client-side inserted ads sources need to be updated to implement the content clipping internally. - Mark tracks with a well-formed but unrecognized codec profile or level as
supported=NO_EXCEEDS_CAPABILITIESinstead ofsupported=YES(which is how tracks with missing or malformed profile or level info are marked). This ensures these tracks (which are unlikely to be supported by the device) are not selected when there are better-supported alternatives. - Add
DefaultPreloadManager.SimpleRankingDataComparator, which is aRankingDataComparatorthat compares the ranks of the media items based on their distances to the index of the current playing media item. Apps can override itscompare(Integer, Integer)method if a more fine-tuned comparison logic is needed. The customSimpleRankingDataComparatorcan be injected via a new constructor ofDefaultPreloadManager.Builder. - Reduce the OOM risk of
DefaultLoadControl.prioritizeTimeOverSizeThresholdsby falling back to buffer byte size limits if available heap memory seems tight. - Align handling of still images when
MediaItem.imageDurationUsis not set: JPEG and HEIC still images now 'play' with a very short default duration (the same way PNG and other images previously behaved). - Add
MediaSource.prepareSource(MediaSourceCaller, PlayerId, BandwidthMeter)to plumbBandwidthMetertoMediaSource. The deprecated method with custom implementation will still be called by default though, it is recommended to implement the new method and useBandwidthMeter.getTransferListener()to get parity to the old method. - In
DefaultBandwidthMeter, add support for a customInitialBitrateSupplier. This allows apps to provide their own logic for determining the initial bitrate estimate, which will be used on creation ofDefaultBandwidthMeterand on network type changes. The supplier can be set viaDefaultBandwidthMeter.Builder.setInitialBitrateSupplier(). - Enable dynamic scheduling by default.
ExoPlayerplayback work loop will run dynamically as opposed to on a static interval. - Remove an unnecessary reset that can occur when joining tracks with pre-roll samples to active playback.
- In
DefaultBandwidthMeter, optimizegetInitialBitrateCountryGroupAssignmentto return the country group assignments packed into a 32-bit integer instead of an array, reducing code size and avoiding allocations. - Fix
AudioTrackinitialization failures on some devices by ensuring the retry logic always attempts a minimum of 1 second buffer size if other retries (by halving the buffer size) are unsuccessful (#3207). - Fix codec issue on some devices where the codec was swallowing all samples if previously flushed before receiving input buffers.
- Add experimental
ExoPlayer.Builder.enablePerStreamMediaProgression()to allow advancing media processing on a per-stream basis. This reduces startup latency between playlist items and avoids playback becoming "stuck" with very short content (#3122). - Fix race condition related to audio session id usage where the initial audio session id auto-generated by
ExoPlayerwould be used instead of the value set bysetAudioSessionId(#3241). - Add experimental HAGC (ST 2094-50) timed metadata playback support for progressive media (e.g. MP4, Matroska). The player automatically merges HAGC metadata tracks with the associated video track and delivers the metadata out-of-band to the decoder on API 37+ devices. This behavior can be disabled via
DefaultMediaSourceFactory.setExperimentalEnableHagcPlayback(false). - Add
Format.selectionPriorityrepresenting the relative preference of theFormatin track selection (#3236). - Fix potential scrubbing mode issue where scrubbing could stall when seeking to 'end of stream'.
- Fix a timing-dependent concurrency bug that could cause an
- CompositionPlayer:
- Fix an issue where
TrackSelectorinstances were not being released.
- Fix an issue where
- Transformer:
- Fix an issue where
ExportResult.fileSizeBytesmay be over-reported.
- Fix an issue where
- Track selection:
- Expose
BaseTrackSelection.DEFAULT_FORMAT_COMPARATORand addAdaptiveTrackSelection.Factory.setTrackFormatComparatorto allow custom format ordering and ABR selection priority beyond bitrate-only ordering. - Fix a timing-dependent concurrency issue where rapid sequential updates to track selection parameters could result in some updates being lost or overwritten.
- Expose
- Extractors:
- MP4, MP3, and FLAC: Add
FLAG_DISABLE_ARTWORK_METADATAto allow discarding attached pictures and cover art metadata during container parsing to reduce runtime memory consumption (#2077). This can also be enabled centrally viaDefaultExtractorsFactory.setDisableArtworkMetadata. - MP4: Add support for extracting ITU-T T.35 (
it35) timed metadata tracks. - MP4: Add support for extracting chapter metadata (both Nero and QuickTime formats). QuickTime chapters are preferred if both are present. The extracted chapter information is exposed as
Chapterentries within the track'sMetadata, allowing for native chapter navigation in MP4, M4A, and M4B files (such as audiobooks and podcasts) (#2803). - WAV, Matroska, and MP4: Add support for 64-bit floating point PCM audio (#3090).
- Matroska: Use codec bitstream metadata to populate accurate
ColorInfo. - MP4: Add support for seeking in fragmented MP4 files using the
mfrabox when asidxbox is not present. To enable this, provideFLAG_READ_MFRA_FOR_SEEK_MAPto theFragmentedMp4Extractor, which is now done by default inDefaultExtractorsFactory(#3088). - Ignore
av1Cdata with unsupported version. - MP4: Add support for big-endian floating point PCM in
fpcmboxes. - Matroska: Parse chapter info to
Chapterentries in a track'sMetadata. - MPEG-TS: Improve extraction of DTS-HD and DTS Express streams by combining the Core and Extension Substream into a single sample, fixing playback issues where the two were previously output as separate samples (#3147).
- MP4: Prevent infinite loops and out-of-bounds reads when parsing empty
ilstmetadata tag items (#3191). - MPEG-TS: Ensure the last frame is rendered for streams where the last PES packet has a known length (#3206).
- MP3: Fix bitrate reporting for files with Xing and VBRI header.
- Matroska: Handle tracks defined in the last cluster (#3250).
- Matroska: Add support for ALAC (#3268).
- MP4: Allow variable length
sgpdboxes in fragmented MP4 files (#3243). - AVI: Fix an issue where playing files without keyframe flags on audio tracks caused audio loss and
OutOfMemoryError. - MP3: Use gapless-aware durations from Xing/Info headers (#3183).
- MP3: Adjust LAME/Xing encoder delay and padding metadata to match decoded PCM trimming (#3200).
- MP4, MP3, and FLAC: Add
- Audio:
- Add a 100ms grace period in ExoPlayer's audio renderers when transitioning from ready to not-ready state, to debounce transient underruns and avoid unexpected buffering states during active playout (#3210).
- Change the default PCM buffer size logic in
DefaultAudioTrackBufferSizeProviderto use a fixed 500ms buffer to make it less device dependent. - Update
MediaCodecAudioRendererto extract the spatial channelMask from the platform decoder, allowingDefaultAudioSinkto use this explicit mask instead of inferring one from the channel count. - Convert parameters of
AudioSink.configureto data class. Custom overrides ofForwardingAudioSink.configureneed to be migrated to the new method signature. - Add support for maintaining pitch when time-stretching an audio stream with
EditedMediaItem.Builder#setSpeed(SpeedParameters). - Enhance
ToFloatPcmAudioProcessorto support converting 8-bit PCM, 16-bit big-endian PCM, and 64-bit floating point PCM to 32-bit floating point PCM (#3090). - Change return value of
DecoderAudioRenderer.getChannelMappingtoImmutableIntArray. - Fix bug where playback gets stuck when playing a playlist of gapless audio in compressed offload mode.
- Forward
Timelineand period UID toAudioSink.configureandAudioProcessor.StreamMetadatato provide playlist context to the audio processors (#418). - Set correct
AudioProcessor.StreamMetadata.positionOffsetUsto allow time-based audio processing (#418). - Add support for big endian 32-bit and 64-bit floating point PCM.
- Remove fallback path of EAC3-JOC to EAC3 for playback on Google Pixel devices as their standard EAC3 decoders cannot decode EAC3-JOC streams (#3257).
- Video:
- Fix video joining logic to count dropped buffers during joining as skipped instead of dropped.
- Fix immediate rendering decision when setting new surface to avoid frame drops on devices that don't support placeholder surfaces.
- Fix frame rate estimation in
MediaCodecVideoRendererto be more accurate by accounting for dropped or skipped frames. - Allow configuration of the threshold used to schedule frames early. The default is 50ms but one can customize the value through
MediaCodecVideoRenderer.Builder.setMaxEarlyUsThreshold(). - Fix bug in
VideoFrameReleaseHelperwhere display changes could trigger redundantChoreographercallbacks and excessive CPU wakeups on the main thread.
- Text:
- Metadata:
- Add
MediaMetadata.discSubtitlefield and parse it from ID3v2.4TSSTand VorbisDISCSUBTITLEdata. - Parse disc number & count from ID3
TPOSframe.
- Add
- Effect:
- Clear redraw state in
FinalShaderProgramWrapperwhen flushing to prevent the player from freezing when seeking.
- Clear redraw state in
- Muxers:
- Add support for track references (the
trefbox) inMp4Muxervia a newaddTrackReferenceAPI. This allows establishing relationships between tracks, such as linking a metadata track to the video track it describes. - Add
OggMuxerto allow muxing ofOPUSorVORBISmedia streams into theoggfile format. - Add
WavMuxerfor WAV file generation (supports integer and floating-point PCM). - Add
setAttemptStreamableOutputEnabledtoInAppMp4Muxer.Factoryto allow writing smaller non-streamable files without reserved space. - Add support for IAMF audio in
Mp4MuxerandFragmentedMp4Muxer.
- Add support for track references (the
- IMA extension:
- Add
ImaServerSideAdInsertionMediaSource.AdsLoader.Builder.setPauseAdSlotto allow providing an ad slot to use for pause ads. - Fix bug where back-to-back skippable VAST ads show the skip button immediately on the second ad (#3165).
- Add
- Session:
- Fix potential deadlocks and
IllegalStateExceptioncrashes insideMediaNotificationManagerwhen using a session with a background thread player looper. - Enforce stricter threading requirements for
MediaSessionmethods. Void methods now automatically post execution to the application looper thread, and state accessors (getters) explicitly throw anIllegalStateExceptionif called from a thread other than the application looper. - Fix an out-of-bounds timeline merge crash (
IllegalStateExceptioninMediaUtils.mergePlayerInfo) by tracking state consistency per-controller on the session side. - Add
androidx.media3.session.MediaSessionManagerto provide support for querying active media sessions and returning Media3SessionTokeninstances. - Change default behavior of
MediaSession.Callback.onConnectif the method is not overridden to only provide read access to untrusted controllers. - Add support to override package name while creating
MediaSessionvia a new APIMediaSession.Builder#setPackageNameOverride. The caller must haveandroid.permission.OVERRIDE_MEDIA_SESSION_OWNERpermission to override the package name of the session. - Add
MediaSession.Callback.onConnectAsync(). The new method allows to asynchronously process the connection attempt of a controller. Apps can return an immediateFuturewithFutures.immediateFuture(ConnectionResult)to achieve the previous behaviour. It's recommended to migrate to the new method becauseCallback.onConnectis a candidate to be deprecated. - Fix issue where Bluetooth AVRCP browsing didn't recognise
MediaLibraryServiceon API 36 and 37. - Fix double-downscaling of artwork in
MediaSessionwhen the image size is close to the platform limit, resolving blurriness in notifications (#3134). - Fix
ForegroundServiceStartNotAllowedExceptioncrash inMediaNotificationManagerwhen an asynchronous artwork bitmap load callback attempts to start the foreground service while the app is in the background (#3270). - Fix an issue where
PositionInfoobjects received by aMediaControllerwere missing their originalTimelineUIDs. The session now reliably translates and propagates these UIDs during state updates. - Fix crash by catching
ForegroundServiceStartNotAllowedExceptioninMediaSessionService.stopSelfSafely()(#3310). - Fix unexpected
onMediaItemTransition()callback onMediaControllerwhen seeking inside the same media item (#3248).
- Fix potential deadlocks and
- UI:
- Fix first frame rendering at the wrong size when
ContentFrameis recomposed mid-playback (#3238). - Add
CurrentMediaItemStateclass and the correspondingrememberCurrentMediaItemStateComposable tomedia3-ui-composemodule. This state holder is used indemo-composeto display various metadata information about the currently playingMediaItem. - Add
PlaylistStateclass and the correspondingrememberPlaylistStateComposable tomedia3-ui-composemodule. This state holder is used indemo-composeto display various metadata information about theMediaItemsset on the Player. - Add fastforwarding/slow motion API to
PlaybackSpeedState. Use this functionality indemo-composeto showcase fastforwarding with a long press. - Add
MiniControllercomposable tomedia3-ui-compose-material3module. It provides a compact affordance to control thePlayerwhile displaying the title, artist, artwork, and progress of the current media item. - Add
ErrorStateclass and the correspondingrememberErrorStateComposable tomedia3-ui-composemodule. AddErrorTextComposable tomedia3-ui-compose-material3and make it a default overlay on thePlayer. - Publish
PlayerDefaultsobject with composables forTopControls,CenterControls,BottomControls, andErrorOverlay. - Add
FocusRequestertoPlayerComposable and its content slots. - Publish
PlayerPool(common-ktx) andrememberPooledPlayer(ui-compose) to support preloading ofMediaItemsin sliding window UI environments. Showcase this functionality indemo-composewith a newShortFormPlayerScreen. - Fix shutter suppression bug in
PlayerViewand ComposePresentationStatethat caused crashes on timelines that do not support period UID lookup (#3264).
- Fix first frame rendering at the wrong size when
- Downloads:
- Resolve HLS variables in media playlist when fetched for download (#3258).
- Ktor extension:
- HLS extension:
- Add support for HLS Content Steering and Pathway Cloning (#1689).
- Add
setWithAssetListResettoHlsInterstitialsAdsLoaderto allow apps to reset fully processed asset list interstitials back to an unavailable state for on-demand re-resolution. - Parse
SCOREattribute ofEXT-X-STREAM-INFandEXT-X-I-FRAME-STREAM-INF, and populate it toFormat.selectionPriority(#3236). - Fix bug where scheduled HLS playlist refreshes continue even if the playlist is no longer primary or active (#3254).
- Fix calculation of content resume offset when resolving interstitial asset lists (#3322).
- Fix unexpected audio track timestamp discontinuity when resuming low latency live playback after a playlist request failure (#3311).
- Fix bug in
HlsMediaPeriod.getStreamKeys()where the ID3 track in audio renditions is considered as subtitles (#3333).
- DASH extension:
- Separate CEA closed captions into different
TrackGroups based on language (#3113). - Add support for parsing multiple
Locationelements from the manifest (MPD) and performing location fallback inDashMediaSourcewhen manifest loads fail. - Fix crash (
IndexOutOfBoundsException) when opening manifests with an empty<SegmentTimeline/>element (#3326).
- Separate CEA closed captions into different
- RTSP extension:
- Fix transient playback stalls or failures during RTSP playback preparation caused by UDP port binding errors.
- Cast extension:
- Add new
CastParamsclass to allow configuration of Cast by callingCast.initialize(CastParams). - Add new
CastParams.getShowSystemOutputSwitcherOnCastIconClick()option, which triggers the use of the SystemUI Output Switcher instead of the in-app Cast device picker when available. - Add
MediaRouteButtonStateandrememberMediaRouteButtonStateto support observing the visibility state of the media route picker, and addstateparameter toMediaRouteButton(#3172). - Fix bug where
RemoteCastPlayercould get permanently stuck in a track-masking state after a track selection, causing it to ignore subsequent track updates from the Cast receiver (#3237). - Fix bug where
DefaultMediaItemConverterthrows aNullPointerExceptionwhen trying to join a cast session started from a non-Media3 sender. - Prevent
CastPlayerfrom transferringMediaItemsthat are not playable when changing the active player (#3199). - Fix bug where unconfigured live streams (
liveConfiguration == UNSET) were queued asSTREAM_TYPE_BUFFERED(#3318).
- Add new
- Test utilities:
- Expand
DataSourceContractTestto include support forPOSTrequests with headers & bodies, add somePOSTresources toHttpDataSourceTestEnv, and add assertions for the expected HTTP method, headers & body inWebServerDispatcher. - Tighten assertions in
DataSourceContractTestfor lengths returned fromDataSource.open(). Resources that may result inC.LENGTH_UNSETshould indicate this by usingTestResource.Builder.setMayResolveToUnknownLength(boolean). - Add
setPlaybackLoopertoTestExoPlayerBuilder.
- Expand
- Remove deprecated symbols:
- Remove
androidx.media3.exoplayer.MetadataRetriever. Useandroidx.media3.inspector.MetadataRetrieverinstead. - Remove
androidx.media3.exoplayer.MediaExtractorCompat. Useandroidx.media3.inspector.MediaExtractorCompatinstead. - Remove
Mp4Extractor.FLAG_READ_MOTION_PHOTO_METADATA. UseHeifExtractorto extract motion photo metadata from HEIC files instead. - Remove
androidx.media3.extractor.metadata.mp4.MotionPhotoMetadata. Useandroidx.media3.extractor.metadata.MotionPhotoMetadatainstead. - Remove
androidx.media3.extractor.DummyTrackOutput. Useandroidx.media3.extractor.DiscardingTrackOutputinstead. - Remove
androidx.media3.extractor.DummyExtractorOutput. Useandroidx.media3.extractor.NoOpExtractorOutputinstead. - Remove
androidx.media3.common.C.generateAudioSessionIdV21. Useandroidx.media3.common.util.Util.generateAudioSessionIdinstead.
- Remove
- Build
- Updated the
README.mdinstructions for depending on Media3 locally to use Gradle Composite Builds (includeBuild). Thecore_settings.gradlescript has been removed, and theandroidxMediaModulePrefixandandroidxMediaEnableMidiModuleproperties are no longer used.
- Updated the