diff --git a/RELEASENOTES.md b/RELEASENOTES.md index aac69e1438..5d14b6f6a1 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -1,6 +1,14 @@ # Release notes # -### 2.10.6 (2019-10-18) ### +### 2.10.7 (2019-11-12) ### + +* HLS: Fix detection of Dolby Atmos to match the HLS authoring specification. +* MediaSession extension: Update shuffle and repeat modes when playback state + is invalidated ([#6582](https://github.com/google/ExoPlayer/issues/6582)). +* Fix the start of audio getting truncated when transitioning to a new + item in a playlist of opus streams. + +### 2.10.6 (2019-10-17) ### * Add `Player.onPlaybackSuppressionReasonChanged` to allow listeners to detect playbacks suppressions (e.g. transient audio focus loss) directly diff --git a/constants.gradle b/constants.gradle index 2a8d0c5776..59b6b7ff42 100644 --- a/constants.gradle +++ b/constants.gradle @@ -13,8 +13,8 @@ // limitations under the License. project.ext { // ExoPlayer version and version code. - releaseVersion = '2.10.6' - releaseVersionCode = 2010006 + releaseVersion = '2.10.7' + releaseVersionCode = 2010007 minSdkVersion = 16 targetSdkVersion = 28 compileSdkVersion = 28 diff --git a/extensions/leanback/src/main/java/com/google/android/exoplayer2/ext/leanback/LeanbackPlayerAdapter.java b/extensions/leanback/src/main/java/com/google/android/exoplayer2/ext/leanback/LeanbackPlayerAdapter.java index 3f4c5d6229..15af90f38b 100644 --- a/extensions/leanback/src/main/java/com/google/android/exoplayer2/ext/leanback/LeanbackPlayerAdapter.java +++ b/extensions/leanback/src/main/java/com/google/android/exoplayer2/ext/leanback/LeanbackPlayerAdapter.java @@ -308,7 +308,11 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter implements Runnab @Override public void onVideoSizeChanged( int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) { - getCallback().onVideoSizeChanged(LeanbackPlayerAdapter.this, width, height); + // There's no way to pass pixelWidthHeightRatio to leanback, so we scale the width that we + // pass to take it into account. This is necessary to ensure that leanback uses the correct + // aspect ratio when playing content with non-square pixels. + int scaledWidth = Math.round(width * pixelWidthHeightRatio); + getCallback().onVideoSizeChanged(LeanbackPlayerAdapter.this, scaledWidth, height); } @Override diff --git a/extensions/mediasession/src/main/java/com/google/android/exoplayer2/ext/mediasession/MediaSessionConnector.java b/extensions/mediasession/src/main/java/com/google/android/exoplayer2/ext/mediasession/MediaSessionConnector.java index f42e050991..284acd8d11 100644 --- a/extensions/mediasession/src/main/java/com/google/android/exoplayer2/ext/mediasession/MediaSessionConnector.java +++ b/extensions/mediasession/src/main/java/com/google/android/exoplayer2/ext/mediasession/MediaSessionConnector.java @@ -700,6 +700,9 @@ public final class MediaSessionConnector { /* position= */ 0, /* playbackSpeed= */ 0, /* updateTime= */ SystemClock.elapsedRealtime()); + + mediaSession.setRepeatMode(PlaybackStateCompat.REPEAT_MODE_NONE); + mediaSession.setShuffleMode(PlaybackStateCompat.SHUFFLE_MODE_NONE); mediaSession.setPlaybackState(builder.build()); return; } @@ -748,6 +751,18 @@ public final class MediaSessionConnector { sessionPlaybackSpeed, /* updateTime= */ SystemClock.elapsedRealtime()) .setExtras(extras); + + @Player.RepeatMode int repeatMode = player.getRepeatMode(); + mediaSession.setRepeatMode( + repeatMode == Player.REPEAT_MODE_ONE + ? PlaybackStateCompat.REPEAT_MODE_ONE + : repeatMode == Player.REPEAT_MODE_ALL + ? PlaybackStateCompat.REPEAT_MODE_ALL + : PlaybackStateCompat.REPEAT_MODE_NONE); + mediaSession.setShuffleMode( + player.getShuffleModeEnabled() + ? PlaybackStateCompat.SHUFFLE_MODE_ALL + : PlaybackStateCompat.SHUFFLE_MODE_NONE); mediaSession.setPlaybackState(builder.build()); } @@ -1047,21 +1062,11 @@ public final class MediaSessionConnector { @Override public void onRepeatModeChanged(@Player.RepeatMode int repeatMode) { - mediaSession.setRepeatMode( - repeatMode == Player.REPEAT_MODE_ONE - ? PlaybackStateCompat.REPEAT_MODE_ONE - : repeatMode == Player.REPEAT_MODE_ALL - ? PlaybackStateCompat.REPEAT_MODE_ALL - : PlaybackStateCompat.REPEAT_MODE_NONE); invalidateMediaSessionPlaybackState(); } @Override public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) { - mediaSession.setShuffleMode( - shuffleModeEnabled - ? PlaybackStateCompat.SHUFFLE_MODE_ALL - : PlaybackStateCompat.SHUFFLE_MODE_NONE); invalidateMediaSessionPlaybackState(); invalidateMediaSessionQueue(); } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerLibraryInfo.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerLibraryInfo.java index adc05eb204..79d395a858 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerLibraryInfo.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerLibraryInfo.java @@ -29,11 +29,11 @@ public final class ExoPlayerLibraryInfo { /** The version of the library expressed as a string, for example "1.2.3". */ // Intentionally hardcoded. Do not derive from other constants (e.g. VERSION_INT) or vice versa. - public static final String VERSION = "2.10.6"; + public static final String VERSION = "2.10.7"; /** The version of the library expressed as {@code "ExoPlayerLib/" + VERSION}. */ // Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa. - public static final String VERSION_SLASHY = "ExoPlayerLib/2.10.6"; + public static final String VERSION_SLASHY = "ExoPlayerLib/2.10.7"; /** * The version of the library expressed as an integer, for example 1002003. @@ -43,7 +43,7 @@ public final class ExoPlayerLibraryInfo { * integer version 123045006 (123-045-006). */ // Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa. - public static final int VERSION_INT = 2010006; + public static final int VERSION_INT = 2010007; /** * Whether the library was compiled with {@link com.google.android.exoplayer2.util.Assertions} diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java index f10f45ecf3..36db657956 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java @@ -434,13 +434,34 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media } else if (codecInfo.isSeamlessAdaptationSupported( oldFormat, newFormat, /* isNewFormatComplete= */ true)) { return KEEP_CODEC_RESULT_YES_WITHOUT_RECONFIGURATION; - } else if (areCodecConfigurationCompatible(oldFormat, newFormat)) { + } else if (canKeepCodecWithFlush(oldFormat, newFormat)) { return KEEP_CODEC_RESULT_YES_WITH_FLUSH; } else { return KEEP_CODEC_RESULT_NO; } } + /** + * Returns whether the codec can be flushed and reused when switching to a new format. Reuse is + * generally possible when the codec would be configured in an identical way after the format + * change (excluding {@link MediaFormat#KEY_MAX_INPUT_SIZE} and configuration that does not come + * from the {@link Format}). + * + * @param oldFormat The first format. + * @param newFormat The second format. + * @return Whether the codec can be flushed and reused when switching to a new format. + */ + protected boolean canKeepCodecWithFlush(Format oldFormat, Format newFormat) { + // Flush and reuse the codec if the audio format and initialization data matches. For Opus, we + // don't flush and reuse the codec because the decoder may discard samples after flushing, which + // would result in audio being dropped just after a stream change (see [Internal: b/143450854]). + return Util.areEqual(oldFormat.sampleMimeType, newFormat.sampleMimeType) + && oldFormat.channelCount == newFormat.channelCount + && oldFormat.sampleRate == newFormat.sampleRate + && oldFormat.initializationDataEquals(newFormat) + && !MimeTypes.AUDIO_OPUS.equals(oldFormat.sampleMimeType); + } + @Override public MediaClock getMediaClock() { return this; @@ -818,24 +839,6 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media return format.maxInputSize; } - /** - * Returns whether two {@link Format}s will cause the same codec to be configured in an identical - * way, excluding {@link MediaFormat#KEY_MAX_INPUT_SIZE} and configuration that does not come from - * the {@link Format}. - * - * @param oldFormat The first format. - * @param newFormat The second format. - * @return Whether the two formats will cause a codec to be configured in an identical way, - * excluding {@link MediaFormat#KEY_MAX_INPUT_SIZE} and configuration that does not come from - * the {@link Format}. - */ - protected boolean areCodecConfigurationCompatible(Format oldFormat, Format newFormat) { - return Util.areEqual(oldFormat.sampleMimeType, newFormat.sampleMimeType) - && oldFormat.channelCount == newFormat.channelCount - && oldFormat.sampleRate == newFormat.sampleRate - && oldFormat.initializationDataEquals(newFormat); - } - /** * Returns the framework {@link MediaFormat} that can be used to configure a {@link MediaCodec} * for decoding the given {@link Format} for playback. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/Extractor.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/Extractor.java index 083f31bcc3..a9151a1b7c 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/Extractor.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/Extractor.java @@ -89,6 +89,10 @@ public interface Extractor { * {@link #RESULT_SEEK} is returned. If the extractor reached the end of the data provided by the * {@link ExtractorInput}, then {@link #RESULT_END_OF_INPUT} is returned. * + *

When this method throws an {@link IOException} or an {@link InterruptedException}, + * extraction may continue by providing an {@link ExtractorInput} with an unchanged {@link + * ExtractorInput#getPosition() read position} to a subsequent call to this method. + * * @param input The {@link ExtractorInput} from which data should be read. * @param seekPosition If {@link #RESULT_SEEK} is returned, this holder is updated to hold the * position of the required data. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/AtomParsers.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/AtomParsers.java index c4e6ef17c4..58bd59a448 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/AtomParsers.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/mp4/AtomParsers.java @@ -348,9 +348,7 @@ import java.util.List; } long durationUs = Util.scaleLargeTimestamp(duration, C.MICROS_PER_SECOND, track.timescale); - if (track.editListDurations == null || gaplessInfoHolder.hasGaplessInfo()) { - // There is no edit list, or we are ignoring it as we already have gapless metadata to apply. - // This implementation does not support applying both gapless metadata and an edit list. + if (track.editListDurations == null) { Util.scaleLargeTimestampsInPlace(timestamps, C.MICROS_PER_SECOND, track.timescale); return new TrackSampleTable( track, offsets, sizes, maximumSize, timestamps, flags, durationUs); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/ogg/FlacReader.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/ogg/FlacReader.java index 4efd5c5e11..e1218b5572 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/ogg/FlacReader.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/ogg/FlacReader.java @@ -78,17 +78,17 @@ import java.util.List; List initializationData = Collections.singletonList(metadata); setupData.format = Format.createAudioSampleFormat( - null, + /* id= */ null, MimeTypes.AUDIO_FLAC, - null, - Format.NO_VALUE, + /* codecs= */ null, streamMetadata.bitRate(), + /* maxInputSize= */ Format.NO_VALUE, streamMetadata.channels, streamMetadata.sampleRate, initializationData, - null, - 0, - null); + /* drmInitData= */ null, + /* selectionFlags= */ 0, + /* language= */ null); } else if ((data[0] & 0x7F) == SEEKTABLE_PACKET_TYPE) { flacOggSeeker = new FlacOggSeeker(); flacOggSeeker.parseSeekTable(packet); diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/wav/WavHeader.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/wav/WavHeader.java index 6e3c5988a9..228151339a 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/wav/WavHeader.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/wav/WavHeader.java @@ -23,7 +23,7 @@ import com.google.android.exoplayer2.util.Util; /** Header for a WAV file. */ /* package */ final class WavHeader implements SeekMap { - /** Number of audio chanels. */ + /** Number of audio channels. */ private final int numChannels; /** Sample rate in Hertz. */ private final int sampleRateHz; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecInfo.java b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecInfo.java index 8581f279d0..f5c6926c30 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecInfo.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecInfo.java @@ -328,13 +328,13 @@ public final class MediaCodecInfo { /** * Whether the decoder supports video with a given width, height and frame rate. - *

- * Must not be called if the device SDK version is less than 21. + * + *

Must not be called if the device SDK version is less than 21. * * @param width Width in pixels. * @param height Height in pixels. - * @param frameRate Optional frame rate in frames per second. Ignored if set to - * {@link Format#NO_VALUE} or any value less than or equal to 0. + * @param frameRate Optional frame rate in frames per second. Ignored if set to {@link + * Format#NO_VALUE} or any value less than or equal to 0. * @return Whether the decoder supports video with the given width, height and frame rate. */ @TargetApi(21) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/text/Cue.java b/library/core/src/main/java/com/google/android/exoplayer2/text/Cue.java index 3f6ff44248..54e7c869e1 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/text/Cue.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/text/Cue.java @@ -32,7 +32,8 @@ public class Cue { public static final Cue EMPTY = new Cue(""); /** An unset position or width. */ - public static final float DIMEN_UNSET = Float.MIN_VALUE; + // Note: We deliberately don't use Float.MIN_VALUE because it's positive & very close to zero. + public static final float DIMEN_UNSET = -Float.MAX_VALUE; /** * The type of anchor, which may be unset. One of {@link #TYPE_UNSET}, {@link #ANCHOR_TYPE_START}, diff --git a/library/core/src/test/assets/ogg/bear_flac.ogg.0.dump b/library/core/src/test/assets/ogg/bear_flac.ogg.0.dump index dbe97c02bd..5b8d893f1a 100644 --- a/library/core/src/test/assets/ogg/bear_flac.ogg.0.dump +++ b/library/core/src/test/assets/ogg/bear_flac.ogg.0.dump @@ -5,11 +5,11 @@ seekMap: numberOfTracks = 1 track 0: format: - bitrate = -1 + bitrate = 768000 id = null containerMimeType = null sampleMimeType = audio/flac - maxInputSize = 768000 + maxInputSize = -1 width = -1 height = -1 frameRate = -1.0 diff --git a/library/core/src/test/assets/ogg/bear_flac.ogg.1.dump b/library/core/src/test/assets/ogg/bear_flac.ogg.1.dump index d1246a3e64..fff76c5b05 100644 --- a/library/core/src/test/assets/ogg/bear_flac.ogg.1.dump +++ b/library/core/src/test/assets/ogg/bear_flac.ogg.1.dump @@ -5,11 +5,11 @@ seekMap: numberOfTracks = 1 track 0: format: - bitrate = -1 + bitrate = 768000 id = null containerMimeType = null sampleMimeType = audio/flac - maxInputSize = 768000 + maxInputSize = -1 width = -1 height = -1 frameRate = -1.0 diff --git a/library/core/src/test/assets/ogg/bear_flac.ogg.2.dump b/library/core/src/test/assets/ogg/bear_flac.ogg.2.dump index ec0336309a..b4d3534161 100644 --- a/library/core/src/test/assets/ogg/bear_flac.ogg.2.dump +++ b/library/core/src/test/assets/ogg/bear_flac.ogg.2.dump @@ -5,11 +5,11 @@ seekMap: numberOfTracks = 1 track 0: format: - bitrate = -1 + bitrate = 768000 id = null containerMimeType = null sampleMimeType = audio/flac - maxInputSize = 768000 + maxInputSize = -1 width = -1 height = -1 frameRate = -1.0 diff --git a/library/core/src/test/assets/ogg/bear_flac.ogg.3.dump b/library/core/src/test/assets/ogg/bear_flac.ogg.3.dump index 1e3254a9fc..27c29cba58 100644 --- a/library/core/src/test/assets/ogg/bear_flac.ogg.3.dump +++ b/library/core/src/test/assets/ogg/bear_flac.ogg.3.dump @@ -5,11 +5,11 @@ seekMap: numberOfTracks = 1 track 0: format: - bitrate = -1 + bitrate = 768000 id = null containerMimeType = null sampleMimeType = audio/flac - maxInputSize = 768000 + maxInputSize = -1 width = -1 height = -1 frameRate = -1.0 diff --git a/library/core/src/test/assets/ogg/bear_flac.ogg.unklen.dump b/library/core/src/test/assets/ogg/bear_flac.ogg.unklen.dump index dbe97c02bd..5b8d893f1a 100644 --- a/library/core/src/test/assets/ogg/bear_flac.ogg.unklen.dump +++ b/library/core/src/test/assets/ogg/bear_flac.ogg.unklen.dump @@ -5,11 +5,11 @@ seekMap: numberOfTracks = 1 track 0: format: - bitrate = -1 + bitrate = 768000 id = null containerMimeType = null sampleMimeType = audio/flac - maxInputSize = 768000 + maxInputSize = -1 width = -1 height = -1 frameRate = -1.0 diff --git a/library/core/src/test/assets/ogg/bear_flac_noseektable.ogg.0.dump b/library/core/src/test/assets/ogg/bear_flac_noseektable.ogg.0.dump index cce7bf2450..2ecdc9784c 100644 --- a/library/core/src/test/assets/ogg/bear_flac_noseektable.ogg.0.dump +++ b/library/core/src/test/assets/ogg/bear_flac_noseektable.ogg.0.dump @@ -5,11 +5,11 @@ seekMap: numberOfTracks = 1 track 0: format: - bitrate = -1 + bitrate = 768000 id = null containerMimeType = null sampleMimeType = audio/flac - maxInputSize = 768000 + maxInputSize = -1 width = -1 height = -1 frameRate = -1.0 diff --git a/library/core/src/test/assets/ogg/bear_flac_noseektable.ogg.1.dump b/library/core/src/test/assets/ogg/bear_flac_noseektable.ogg.1.dump index ac36a48412..0ed2a86b9e 100644 --- a/library/core/src/test/assets/ogg/bear_flac_noseektable.ogg.1.dump +++ b/library/core/src/test/assets/ogg/bear_flac_noseektable.ogg.1.dump @@ -5,11 +5,11 @@ seekMap: numberOfTracks = 1 track 0: format: - bitrate = -1 + bitrate = 768000 id = null containerMimeType = null sampleMimeType = audio/flac - maxInputSize = 768000 + maxInputSize = -1 width = -1 height = -1 frameRate = -1.0 diff --git a/library/core/src/test/assets/ogg/bear_flac_noseektable.ogg.2.dump b/library/core/src/test/assets/ogg/bear_flac_noseektable.ogg.2.dump index dae0d878fa..229e90584e 100644 --- a/library/core/src/test/assets/ogg/bear_flac_noseektable.ogg.2.dump +++ b/library/core/src/test/assets/ogg/bear_flac_noseektable.ogg.2.dump @@ -5,11 +5,11 @@ seekMap: numberOfTracks = 1 track 0: format: - bitrate = -1 + bitrate = 768000 id = null containerMimeType = null sampleMimeType = audio/flac - maxInputSize = 768000 + maxInputSize = -1 width = -1 height = -1 frameRate = -1.0 diff --git a/library/core/src/test/assets/ogg/bear_flac_noseektable.ogg.3.dump b/library/core/src/test/assets/ogg/bear_flac_noseektable.ogg.3.dump index c9570ab58e..89c6d178ff 100644 --- a/library/core/src/test/assets/ogg/bear_flac_noseektable.ogg.3.dump +++ b/library/core/src/test/assets/ogg/bear_flac_noseektable.ogg.3.dump @@ -5,11 +5,11 @@ seekMap: numberOfTracks = 1 track 0: format: - bitrate = -1 + bitrate = 768000 id = null containerMimeType = null sampleMimeType = audio/flac - maxInputSize = 768000 + maxInputSize = -1 width = -1 height = -1 frameRate = -1.0 diff --git a/library/core/src/test/assets/ogg/bear_flac_noseektable.ogg.unklen.dump b/library/core/src/test/assets/ogg/bear_flac_noseektable.ogg.unklen.dump index 7a3e7ef5ac..7a4ba81f23 100644 --- a/library/core/src/test/assets/ogg/bear_flac_noseektable.ogg.unklen.dump +++ b/library/core/src/test/assets/ogg/bear_flac_noseektable.ogg.unklen.dump @@ -5,11 +5,11 @@ seekMap: numberOfTracks = 1 track 0: format: - bitrate = -1 + bitrate = 768000 id = null containerMimeType = null sampleMimeType = audio/flac - maxInputSize = 768000 + maxInputSize = -1 width = -1 height = -1 frameRate = -1.0 diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java index 030520f8cb..7ccbaf5d59 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistParser.java @@ -445,7 +445,15 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser variableDefinitions) { - String channelsString = parseOptionalStringAttr(line, REGEX_CHANNELS, variableDefinitions); - return channelsString != null - ? Integer.parseInt(Util.splitAtFirst(channelsString, "/")[0]) - : Format.NO_VALUE; - } - @Nullable private static SchemeData parseDrmSchemeData( String line, String keyFormat, Map variableDefinitions) diff --git a/library/ui/src/main/java/com/google/android/exoplayer2/ui/PlayerNotificationManager.java b/library/ui/src/main/java/com/google/android/exoplayer2/ui/PlayerNotificationManager.java index 8b20557d3d..1cdd9d28e6 100644 --- a/library/ui/src/main/java/com/google/android/exoplayer2/ui/PlayerNotificationManager.java +++ b/library/ui/src/main/java/com/google/android/exoplayer2/ui/PlayerNotificationManager.java @@ -1348,7 +1348,12 @@ public class PlayerNotificationManager { } @Override - public void onRepeatModeChanged(int repeatMode) { + public void onRepeatModeChanged(@Player.RepeatMode int repeatMode) { + startOrUpdateNotification(); + } + + @Override + public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) { startOrUpdateNotification(); } } diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeAdaptiveMediaPeriod.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeAdaptiveMediaPeriod.java index 1e3b3bf82b..a9c19fbc8d 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeAdaptiveMediaPeriod.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/FakeAdaptiveMediaPeriod.java @@ -60,6 +60,7 @@ public class FakeAdaptiveMediaPeriod extends FakeMediaPeriod this.transferListener = transferListener; this.durationUs = durationUs; this.sampleStreams = newSampleStreamArray(0); + this.sequenceableLoader = new CompositeSequenceableLoader(new SequenceableLoader[0]); } @Override