This release includes the following changes since the 1.7.1 release:
- Common Library:
- Add support for replacing the player in
ForwardingSimpleBasePlayer.
- Add support for replacing the player in
- ExoPlayer:
- Add getter for shuffle mode to the
ExoPlayerinterface (#2522). - More clearly throw an exception if
DefaultAudioSinkis accessed from multiple threads. If this happens due to a call toRendererCapabilities.getFormatSupportoutside of the player, make sure to call this method on the same thread as ExoPlayer's playback thread or use a different instance than the one used for playback (#1191). - Fix bug where non-stereo audio formats on TVs may be marked as unsupported by
DefaultTrackSelector. - Ensure the last frame is correctly rendered when using MediaCodec's
DECODE_ONLYflag (which is enabled by default in scrubbing mode). - Add support for using the virtual device ID from the
Contextpassed toExoPlayer.Builder. - Enable dynamic scheduling by default in scrubbing mode.
- Avoid unnecessary reload of a source when seeking to the end of an item.
- Use
MediaCodec.BUFFER_FLAG_DECODE_ONLYby default in scrubbing mode. - Throw
IllegalStateExceptionwhenPreloadMediaSourceis played by anExoPlayerwith a playback thread that is different than the preload thread (#2495). - Add
cloneAndMovetoShuffleModewith a default implementation (#2226). - Change default behavior of
Renderer.getMinDurationToProgressUsto return a larger value if no call torenderis required. - Fix bug where internal scheduling delayed last frame when seeking to the end while paused. For now, the bug fix only takes effect if
ExoPlayer.Builder.experimentalSetDynamicSchedulingEnabledis enabled. - Add
ExoPlayer.setScrubbingModeEnabled(boolean)method. This optimizes the player for many frequent seeks (for example, from a user dragging a scrubber bar around). The behavior of scrubbing mode can be customized withsetScrubbingModeParameters(..)onExoPlayerandExoPlayer.Builder. - Allow customizing fractional seek tolerance in scrubbing mode.
- Increase codec operating rate in scrubbing mode.
- Fix bug where prepare errors in the content of
AdsMediaSourcemay be never reported (#2337). - Fix memory leak in
MergingMediaSource, for example used when sideloading subtitles (#2338). - Allow
CmcdConfiguration.Factoryto returnnullto disable CMCD logging for specific media items (#2386). - Increase default image buffer size from 128kB (copy-paste mistake from text tracks) to 26MB, which is large enough for 50MP Ultra HDR images (#2417).
- Add
PreCacheHelperthat allows apps to pre-cache a single media with specified start position and duration. - Add support of preloading from specified position in
DefaultPreloadManager.
- Add getter for shuffle mode to the
- Transformer:
- Add
CodecDbLitethat enables chipset specific optimizations of video encoding settings. - Add
setEnableCodecDbLiteflag to theDefaultEncoderFactoryto enable CodecDB Lite settings optimization. By default, this flag is set to false. - Filling an initial gap (added via
addGap()) with silent audio now requires explicitly settingexperimentalSetForceAudioTrack(true)inEditedMediaItemSequence.Builder. If the gap is in the middle of the sequence, then this flag is not required. - Move
Muxerinterface frommedia3-transformertomedia3-muxer. - Make setting
MediaItem.Builder().setImageDuration(long)mandatory to import a media item as an image. - Add
Transformer.Builder().experimentalSetMp4EditListTrimEnabled(boolean)which includes an MP4 edit list when trimming to instruct players to ignore samples between the key frame before the trim start point, and the trim start point. - Update Composition Demo app to use Kotlin and Jetpack Compose, and add a custom
VideoCompositorSettingsto arrange sequences into a 2x2 or PiP layout.
- Add
- Extractors:
- Parse metadata from fragmented MP4 files (#2084).
- JPEG: Support motion photos that don't have an Exif segment at the start (#2552).
- Add support for seeking in fragmented MP4 with multiple
sidxatoms. This behavior can be enabled using theFLAG_MERGE_FRAGMENTED_SIDXflag onFragmentedMp4Extractor(#9373). - Ignore empty seek tables in FLAC files (including those containing only placeholder seek points), and fall back to binary search seeking if the duration of the file is known (#2327).
- Fix parsing of H.265 SEI units to fully skip unrecognized SEI types (#2456).
- Update
WavExtractorto use the header extension's SubFormat data for the audio format when parsing aWAVE_FORMAT_EXTENSIBLEtype file. - MP4: Add support for
ipcmandfpcmboxes defining raw PCM audio tracks (64-bit floating point PCM is not supported). - MP4: Handle the rotation part of
tkhdtransformation matrices that both rotate and reflect the video. This ensures that reflected videos taken by the iPhone front facing camera display the right way up, but incorrectly reflected in the y-axis (#2012). - MP3: Use duration and data size from unseekable Xing, VBRI and similar variable bitrate metadata when falling back to constant bitrate seeking due to
FLAG_ENABLE_CONSTANT_BITRATE_SEEKING(_ALWAYS)(#2194).
- Audio:
- Fix bug where
AnalyticsListener.onAudioPositionAdvancingis not called when the audio playback is started very close to the end of the media. - Add support for all linear PCM sample formats in
ChannelMappingAudioProcessorandTrimmingAudioProcessor. - Add support for audio gaps in
CompositionPlayer. - Remove spurious call to
BaseAudioProcessor#flush()fromBaseAudioProcessor#reset(). - Allow constant power upmixing/downmixing in DefaultAudioMixer.
- Make
ChannelMappingAudioProcessor,TrimmingAudioProcessorandToFloatPcmAudioProcessorpublic (#2339). - Use
AudioTrack#getUnderrunCount()inAudioTrackPositionTrackerto detect underruns inDefaultAudioSinkinstead of best-effort estimation. - Improve audio timestamp smoothing for unexpected position drift from the audio output device.
- Fix bug where A/V sync is broken for the first 10 seconds after resuming from pause when connected to Bluetooth devices.
- Fix bug that
AnalyticsListener.onAudioPositionAdvancingwas not reporting the time when the audio started advancing but the time of the first measurement. - Fix recovery to multichannel audio after fallback to stereo audio on some devices (#2258).
- Fix bug where
- Video:
- Extend detached surface workaround to "lenovo" and "motorola" devices (#2059).
- Improve smooth video frame release at startup when audio samples don't start at exactly the requested position.
- Extend detached surface workaround to "realme" devices (#2059).
- Add experimental
ExoPlayerAPI to include theMediaCodec.BUFFER_FLAG_DECODE_ONLYflag when queuing decode-only input buffers. This flag will signal the decoder to skip the decode-only buffers thereby resulting in faster seeking. Enable it withDefaultRenderersFactory.experimentalSetEnableMediaCodecBufferDecodeOnlyFlag. - Improve codec performance checks for software video codecs. This may lead to some additional tracks being marked as
EXCEEDS_CAPABILITIES. - Fix VP9 Widevine playback errors on some devices (#2408).
- Text:
- Add support for VobSub tracks in MP4 files (#2510).
- Fix a playback stall when a subtitle segment initially fails to load and later loads successfully, followed by several empty subtitle segments (#2517).
- Fix SSA and SubRip to display an in-progress cue when enabling subtitles (#2309).
- Fix playback getting stuck when switching from a stream with a subtitle error to a live stream with an empty subtitle track (#2328).
- Fix garbled CEA-608 subtitles when playing H.262 streams containing B-frames (#2372).
- Add support for SSA subtitles with
CodecId = S_TEXT/SSAin Matroska files. PreviouslyMatroskaExtractoronly supportedCodecId = S_TEXT/ASSwhich is meant to represent the 'advanced' (v4+) variant of SubStation Alpha subtitles (but ExoPlayer's parsing logic is the same for both variants) (#2384). - Add support for the
layerproperty in SubStation Alpha (SSA) subtitle files which is used to define the z-order of cues when more than one is shown on screen at the same time (#2124).
- Metadata:
- Added support for retrieving media duration and
TimelinetoMetadataRetrieverand migrated it to an instance-based,AutoCloseableAPI. Use the newBuilderto create an instance for aMediaItem, then callretrieveTrackGroups(),retrieveTimeline(), andretrieveDurationUs()to getListenableFutures for the metadata. The previous static methods are now deprecated (#2462).
- Added support for retrieving media duration and
- Image:
- Limit decoded bitmaps to the display size in
BitmapFactoryImageDecoder, to avoid an app crashing withCanvas: trying to draw too large bitmap.�from�PlayerViewwhen trying to display very large (e.g. 50MP) images. - Change the signature of
DefaultRenderersFactory.getImageDecoderFactory()to take aContextparameter. - Align the max bitmap output size used in
CompositionPlayerwith that already used inTransformer(meaningCompositionPlayerdoes not consider the display size when decoding bitmaps, unlikeExoPlayer).
- Limit decoded bitmaps to the display size in
- DRM:
- Add new overload of
OfflineLicenseHelper.newWidevineInstanceaccepting aMediaItem.DrmConfigurationso that HTTP request headers can be applied correctly (#2169).
- Add new overload of
- Effect:
- Add
Presentation.createForShortSide(int)that creates aPresentationthat ensures the shortest side always matches the given value, regardless of input orientation.
- Add
- Muxers:
- Fix a bug where correct sample flags were not set for audio samples in fragmented MP4.
writeSampleData()API now uses muxer specificBufferInfoclass instead ofMediaCodec.BufferInfo.- Add
Muxer.Factory#supportsWritingNegativeTimestampsInEditListwhich defaults to false.
- IMA extension:
- Fix a bug where a load error in one ad may accidentally invalidate another ad group.
- Fix bug where ad groups after the end of a VOD window stalled playback. Ads groups with a start time after the window are not enqueued into the
MediaPeriodQueueanymore (#2215).
- Session:
- Fix bug where connections from third-party non-privileged Media3 controllers are ignored.
- Remove check for available commands when sending custom commands to a legacy
MediaBrowserServiceCompat. This is in parity with the behavior of legacy controllers/browsers when connected to a legacy app. - Fix a bug that causes a player's first playback error to be incorrectly treated as a persistent custom exception. This prevents the application from recovering.
- Fix bug where some controller changes that are not handled by the session may cause
IllegalStateExceptions. - Fix bug where controller actions that are not handled by the session may leave the controller in an invalid state.
- Fix StrictMode unsafe launch violation warning (#2330).
- Fix bug where calling
setSessionExtrasfrom the main thread when running the player from a different application thread then the main thread caused anIllegalStateException(#2265). - Don't automatically show a notification if a player is set up with media items without preparing or playing them (#2423#2423). This behavior is configurable via
MediaSessionService.setShowNotificationForIdlePlayer. - Add custom
PlaybackExceptionfor all or selected controllers. - Fix bug where seeking in a live stream on a
MediaControllercan cause anIllegalArgumentException. - For live streams, stop publishing a playback position and the ability to seek in the current item for platform media controllers, to avoid position artefacts in the Android Auto UI (and other controllers using this information from the platform media session) (#1758).
- Fix a bug where passing null into
getLibraryRootof aMediaBrowserconnected to a legacyMediaBrowserServiceCompatproduced aNullPointerException. - Fix a bug where sending custom actions, a search result or a getItem request crashed the legacy session app with a
ClassNotFoundException. - Fix a bug where
MediaItem.LocalConfiguration.uriwas shared to the platform sessions'sMediaMetadata. To intentionally share a URI to allow controllers to re-request the media, setMediaItem.RequestMetadata.mediaUriinstead.
- UI:
- Fix bug where
PlayerSurfaceinside re-usable components likeLazyColumndidn't work correctly (#2493). - Fix a Compose bug which resulted in a gap between setting the initial button states and observing the change in state (e.g. icon shapes or being enabled). Any changes made to the Player outside of the observation period are now picked up (#2313).
- Add state holders and composables to the
media3-ui-composemodule forSeekBackButtonStateandSeekForwardButtonState. - Add support for ExoPlayer's scrubbing mode to
PlayerControlView. When enabled, this puts the player into scrubbing mode when the user starts dragging the scrubber bar, issues aplayer.seekTocall for every movement, and then exits scrubbing mode when the touch is lifted from the screen. This integration can be enabled with eithertime_bar_scrubbing_enabled = truein XML or thesetTimeBarScrubbingEnabled(boolean)method from Java/Kotlin. - Make
PlayerSurfaceaccept a nullablePlayerargument.
- Fix bug where
- Downloads:
- Add partial download support for progressive streams. Apps can prepare a progressive stream with
DownloadHelper, and request aDownloadRequestfrom the helper with specifying the time-based media start and end positions that the download should cover. The returnedDownloadRequestcarries the resolved byte range, with which aProgressiveDownloadercan be created and download the content correspondingly. - Add
DownloadHelper.Factorywith which the staticDownloadHelper.forMediaItem()methods are replaced. - Add
FactoryforSegmentDownloaderimplementations. - Add partial download support for adaptive streams. Apps can prepare an adaptive stream with
DownloadHelper, and request aDownloadRequestfrom the helper with specifying the time-based media start and end positions that the download should cover. The returnedDownloadRequestcarries the resolved time range, with which a concreteSegmentDownloadercan be created and download the content correspondingly.
- Add partial download support for progressive streams. Apps can prepare a progressive stream with
- Cronet extension:
- Add automatic cookie handling (#5975).
- HLS extension:
- Fix bug where
HlsSampleStreamWrapperattempts to seek inside buffer when there are no chunks available in the buffer #2598. - Fix bug where track selection changes after loading low-latency parts and preload hints can cause playback to get stuck or freeze (#2299).
- Prevent excessive reloads by waiting for half the target duration when
CAN-BLOCK-RELOAD=YESis not honored by the server (#2317). - Fix bug where playback was stalled when starting an interstitials stream before a mid roll and asset list resolution was attempted for the wrong ad (#2558).
- Fix playlist parsing to accept
\f(form feed) in quoted string attribute values (#2420). - Support updating interstitials with the same ID (#2427).
- Fix bug where playlist load errors are sometimes not propagated once a live stream runs out of segments to load (#2401#2401).
- Group subtitle renditions by NAME tag, similar to how audio renditions are grouped already (#1666).
- Support X-ASSET-LIST and live streams with
HlsInterstitialsAdsLoader.
- Fix bug where
- DASH extension:
- Fix issue where trick-play adaptation set is merged with its main adaptation set to form an invalid
TrackGroup(#2148). - Fix bug where shortening a DASH period duration can throw an exception when samples beyond the new duration have already been read by the rendering pipeline (#2440).
- Fix bug where redirect wasn't followed when using CMCD query parameters (#2475).
- Fix issue where trick-play adaptation set is merged with its main adaptation set to form an invalid
- RTSP extension:
- Decoder extensions (FFmpeg, VP9, AV1, etc.):
- Fix bug where
DefaultTrackSelector.setAllowInvalidateSelectionsOnRendererCapabilitiesChangehas no effect for audio decoder extensions (#2258).
- Fix bug where
- Cast extension:
- Test Utilities:
- Add
advance(player).untilPositionAtLeastanduntilMediaItemIndextoTestPlayerRunHelperin order to advance the player until a specified position is reached. In most cases, these methods are more reliable than the existinguntilPositionanduntilStartOfMediaItemmethods. - Move
FakeDownloadertotest-utils-robolectricmodule for reuse in other tests. - Removed
transformer.TestUtil.addAudioDecoders(String...),transformer.TestUtil.addAudioEncoders(String...), andtransformer.TestUtil.addAudioEncoders(ShadowMediaCodec.CodecConfig, String...).�Use�ShadowMediaCodecConfigto configure shadow encoders and decoders instead. - Replaced the "exotest" prefix with "media3" in codec names reported by
ShadowMediaCodecConfig.
- Add
- Remove deprecated symbols:
- Removed deprecated
SegmentDownloaderconstructorSegmentDownloader(MediaItem, Parser<M>, CacheDataSource.Factory, Executor)and the corresponding constructors in its subclassesDashDownloader,HlsDownloaderandSsDownloader. - Removed deprecated
Player.hasNext(),Player.hasNextWindow(). UsePlayer.hasNextMediaItem()instead. - Removed deprecated
Player.next(). UsePlayer.seekToNextMediaItem()instead. - Removed deprecated
Player.seekToPreviousWindow(). UsePlayer.seekToPreviousMediaItem()instead. - Removed deprecated
Player.seekToNextWindow(). UsePlayer.seekToNextMediaItem()instead. - Removed deprecated
BaseAudioProcessorinexoplayermodule. UseBaseAudioProcessorundercommonmodule. - Remove deprecated
MediaCodecVideoRendererconstructorMediaCodecVideoRenderer(Context, MediaCodecAdapter.Factor, MediaCodecSelector, long, boolean, @Nullable Handler, @Nullable VideoRendererEventListener, int, float, @Nullable VideoSinkProvider).
- Removed deprecated