mirror of
https://github.com/androidx/media.git
synced 2025-05-13 02:29:52 +08:00
Remove assertion that prevents masking of ad periods
The assertion asserts against a `Period` and an `AdPlaybackState` which actually asserts against a resolved ad which is what `ExoPlayerImplInternal` does later and what gives us a `SEEK_ADJUSTMENT`. However, this assertion is not required at the moment of masking, because we are sure that the resolved seek results in a content period and never an ad period. #minor-release Issue: androidx/media#122 PiperOrigin-RevId: 471827072 (cherry picked from commit 73f86682e94024c780564dbc287f06d47dfeca26)
This commit is contained in:
parent
2dfca4fca8
commit
1b7060776b
@ -43,6 +43,8 @@
|
|||||||
([#99](https://github.com/androidx/media/issues/99)).
|
([#99](https://github.com/androidx/media/issues/99)).
|
||||||
* `SimpleBitmapLoader` can load bitmap from `file://` URIs
|
* `SimpleBitmapLoader` can load bitmap from `file://` URIs
|
||||||
([#108](https://github.com/androidx/media/issues/108)).
|
([#108](https://github.com/androidx/media/issues/108)).
|
||||||
|
* Fix assertion that prevents `MediaController` to seek over an ad in a
|
||||||
|
period ([#122](https://github.com/androidx/media/issues/122)).
|
||||||
* Fix bug where the `MediaSessionService` was kept started in the
|
* Fix bug where the `MediaSessionService` was kept started in the
|
||||||
foreground and a notification with a pause button was still shown when
|
foreground and a notification with a pause button was still shown when
|
||||||
the player completed playback. Now, once playback is completed, the
|
the player completed playback. Now, once playback is completed, the
|
||||||
|
@ -2674,7 +2674,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
|||||||
return playerInfo;
|
return playerInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkState(!isAd(newPeriod, newPositionUs));
|
checkState(playerInfo.sessionPositionInfo.positionInfo.adGroupIndex == C.INDEX_UNSET);
|
||||||
|
|
||||||
PositionInfo oldPositionInfo =
|
PositionInfo oldPositionInfo =
|
||||||
new PositionInfo(
|
new PositionInfo(
|
||||||
@ -2685,8 +2685,8 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
|||||||
oldPeriodIndex,
|
oldPeriodIndex,
|
||||||
/* positionMs= */ usToMs(oldPeriod.positionInWindowUs + oldPositionUs),
|
/* positionMs= */ usToMs(oldPeriod.positionInWindowUs + oldPositionUs),
|
||||||
/* contentPositionMs= */ usToMs(oldPeriod.positionInWindowUs + oldPositionUs),
|
/* contentPositionMs= */ usToMs(oldPeriod.positionInWindowUs + oldPositionUs),
|
||||||
playerInfo.sessionPositionInfo.positionInfo.adGroupIndex,
|
/* adGroupIndex= */ C.INDEX_UNSET,
|
||||||
playerInfo.sessionPositionInfo.positionInfo.adIndexInAdGroup);
|
/* adIndexInAdGroup= */ C.INDEX_UNSET);
|
||||||
|
|
||||||
timeline.getPeriod(newPeriodIndex, newPeriod);
|
timeline.getPeriod(newPeriodIndex, newPeriod);
|
||||||
Window newWindow = new Window();
|
Window newWindow = new Window();
|
||||||
@ -2700,8 +2700,8 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
|||||||
newPeriodIndex,
|
newPeriodIndex,
|
||||||
/* positionMs= */ usToMs(newPeriod.positionInWindowUs + newPositionUs),
|
/* positionMs= */ usToMs(newPeriod.positionInWindowUs + newPositionUs),
|
||||||
/* contentPositionMs= */ usToMs(newPeriod.positionInWindowUs + newPositionUs),
|
/* contentPositionMs= */ usToMs(newPeriod.positionInWindowUs + newPositionUs),
|
||||||
playerInfo.sessionPositionInfo.positionInfo.adGroupIndex,
|
/* adGroupIndex= */ C.INDEX_UNSET,
|
||||||
playerInfo.sessionPositionInfo.positionInfo.adIndexInAdGroup);
|
/* adIndexInAdGroup= */ C.INDEX_UNSET);
|
||||||
playerInfo =
|
playerInfo =
|
||||||
playerInfo.copyWithPositionInfos(
|
playerInfo.copyWithPositionInfos(
|
||||||
oldPositionInfo, newPositionInfo, DISCONTINUITY_REASON_SEEK);
|
oldPositionInfo, newPositionInfo, DISCONTINUITY_REASON_SEEK);
|
||||||
@ -2768,10 +2768,6 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
|||||||
return getPeriodInfo(timeline, window, period, windowIndex, Util.msToUs(windowPositionMs));
|
return getPeriodInfo(timeline, window, period, windowIndex, Util.msToUs(windowPositionMs));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAd(Period period, long periodPosition) {
|
|
||||||
return period.getAdGroupIndexForPositionUs(periodPosition) != C.INDEX_UNSET;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private PeriodInfo getPeriodInfo(
|
private PeriodInfo getPeriodInfo(
|
||||||
Timeline timeline, Window window, Period period, int windowIndex, long windowPositionUs) {
|
Timeline timeline, Window window, Period period, int windowIndex, long windowPositionUs) {
|
||||||
|
@ -404,7 +404,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
!currentTimeline.isEmpty()
|
!currentTimeline.isEmpty()
|
||||||
? currentTimeline.getWindow(newMediaItemIndex, new Window()).mediaItem
|
? currentTimeline.getWindow(newMediaItemIndex, new Window()).mediaItem
|
||||||
: null,
|
: null,
|
||||||
newPositionMs);
|
newPositionMs,
|
||||||
|
/* isPlayingAd= */ false);
|
||||||
PlayerInfo maskedPlayerInfo =
|
PlayerInfo maskedPlayerInfo =
|
||||||
controllerInfo.playerInfo.copyWithSessionPositionInfo(
|
controllerInfo.playerInfo.copyWithSessionPositionInfo(
|
||||||
createSessionPositionInfo(
|
createSessionPositionInfo(
|
||||||
@ -656,7 +657,11 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
controllerInfo.playerInfo.copyWithTimelineAndSessionPositionInfo(
|
controllerInfo.playerInfo.copyWithTimelineAndSessionPositionInfo(
|
||||||
newQueueTimeline,
|
newQueueTimeline,
|
||||||
createSessionPositionInfo(
|
createSessionPositionInfo(
|
||||||
createPositionInfo(startIndex, mediaItems.get(startIndex), startPositionMs),
|
createPositionInfo(
|
||||||
|
startIndex,
|
||||||
|
mediaItems.get(startIndex),
|
||||||
|
startPositionMs,
|
||||||
|
/* isPlayingAd= */ false),
|
||||||
/* isPlayingAd= */ false,
|
/* isPlayingAd= */ false,
|
||||||
/* durationMs= */ C.TIME_UNSET,
|
/* durationMs= */ C.TIME_UNSET,
|
||||||
/* bufferedPositionMs= */ 0,
|
/* bufferedPositionMs= */ 0,
|
||||||
@ -2089,7 +2094,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
|
|
||||||
@Nullable MediaItem currentMediaItem = currentTimeline.getMediaItemAt(currentMediaItemIndex);
|
@Nullable MediaItem currentMediaItem = currentTimeline.getMediaItemAt(currentMediaItemIndex);
|
||||||
PositionInfo positionInfo =
|
PositionInfo positionInfo =
|
||||||
createPositionInfo(currentMediaItemIndex, currentMediaItem, currentPositionMs);
|
createPositionInfo(currentMediaItemIndex, currentMediaItem, currentPositionMs, isPlayingAd);
|
||||||
|
|
||||||
SessionPositionInfo sessionPositionInfo =
|
SessionPositionInfo sessionPositionInfo =
|
||||||
new SessionPositionInfo(
|
new SessionPositionInfo(
|
||||||
@ -2142,7 +2147,10 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static PositionInfo createPositionInfo(
|
private static PositionInfo createPositionInfo(
|
||||||
int mediaItemIndex, @Nullable MediaItem mediaItem, long currentPositionMs) {
|
int mediaItemIndex,
|
||||||
|
@Nullable MediaItem mediaItem,
|
||||||
|
long currentPositionMs,
|
||||||
|
boolean isPlayingAd) {
|
||||||
return new PositionInfo(
|
return new PositionInfo(
|
||||||
/* windowUid= */ null,
|
/* windowUid= */ null,
|
||||||
/* mediaItemIndex= */ mediaItemIndex,
|
/* mediaItemIndex= */ mediaItemIndex,
|
||||||
@ -2151,8 +2159,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
/* periodIndex= */ mediaItemIndex,
|
/* periodIndex= */ mediaItemIndex,
|
||||||
/* positionMs= */ currentPositionMs,
|
/* positionMs= */ currentPositionMs,
|
||||||
/* contentPositionMs= */ currentPositionMs,
|
/* contentPositionMs= */ currentPositionMs,
|
||||||
/* adGroupIndex= */ C.INDEX_UNSET,
|
/* adGroupIndex= */ isPlayingAd ? 0 : C.INDEX_UNSET,
|
||||||
/* adIndexInAdGroup= */ C.INDEX_UNSET);
|
/* adIndexInAdGroup= */ isPlayingAd ? 0 : C.INDEX_UNSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SessionPositionInfo createSessionPositionInfo(
|
private static SessionPositionInfo createSessionPositionInfo(
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package androidx.media3.session;
|
package androidx.media3.session;
|
||||||
|
|
||||||
|
import static androidx.media3.common.util.Assertions.checkArgument;
|
||||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@ -83,6 +84,7 @@ import java.lang.annotation.Target;
|
|||||||
long currentLiveOffsetMs,
|
long currentLiveOffsetMs,
|
||||||
long contentDurationMs,
|
long contentDurationMs,
|
||||||
long contentBufferedPositionMs) {
|
long contentBufferedPositionMs) {
|
||||||
|
checkArgument(isPlayingAd == (positionInfo.adGroupIndex != C.INDEX_UNSET));
|
||||||
this.positionInfo = positionInfo;
|
this.positionInfo = positionInfo;
|
||||||
this.isPlayingAd = isPlayingAd;
|
this.isPlayingAd = isPlayingAd;
|
||||||
this.eventTimeMs = eventTimeMs;
|
this.eventTimeMs = eventTimeMs;
|
||||||
|
@ -18,9 +18,11 @@ package androidx.media3.session;
|
|||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.MediaItem;
|
import androidx.media3.common.MediaItem;
|
||||||
import androidx.media3.common.Player.PositionInfo;
|
import androidx.media3.common.Player.PositionInfo;
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
@ -34,7 +36,7 @@ public class SessionPositionInfoTest {
|
|||||||
new SessionPositionInfo(
|
new SessionPositionInfo(
|
||||||
new PositionInfo(
|
new PositionInfo(
|
||||||
/* windowUid= */ null,
|
/* windowUid= */ null,
|
||||||
/* windowIndex= */ 33,
|
/* mediaItemIndex= */ 33,
|
||||||
new MediaItem.Builder().setMediaId("1234").build(),
|
new MediaItem.Builder().setMediaId("1234").build(),
|
||||||
/* periodUid= */ null,
|
/* periodUid= */ null,
|
||||||
/* periodIndex= */ 44,
|
/* periodIndex= */ 44,
|
||||||
@ -56,4 +58,31 @@ public class SessionPositionInfoTest {
|
|||||||
SessionPositionInfo.CREATOR.fromBundle(sessionPositionInfoBundle);
|
SessionPositionInfo.CREATOR.fromBundle(sessionPositionInfoBundle);
|
||||||
assertThat(sessionPositionInfo).isEqualTo(testSessionPositionInfo);
|
assertThat(sessionPositionInfo).isEqualTo(testSessionPositionInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void constructor_invalidIsPlayingAd_throwsIllegalArgumentException() {
|
||||||
|
Assert.assertThrows(
|
||||||
|
IllegalArgumentException.class,
|
||||||
|
() ->
|
||||||
|
new SessionPositionInfo(
|
||||||
|
new PositionInfo(
|
||||||
|
/* windowUid= */ null,
|
||||||
|
/* mediaItemIndex= */ 33,
|
||||||
|
MediaItem.EMPTY,
|
||||||
|
/* periodUid= */ null,
|
||||||
|
/* periodIndex= */ 44,
|
||||||
|
/* positionMs= */ 233L,
|
||||||
|
/* contentPositionMs= */ 333L,
|
||||||
|
/* adGroupIndex= */ 2,
|
||||||
|
/* adIndexInAdGroup= */ C.INDEX_UNSET),
|
||||||
|
/* isPlayingAd= */ false,
|
||||||
|
/* eventTimeMs= */ 103L,
|
||||||
|
/* durationMs= */ 400L,
|
||||||
|
/* bufferedPositionMs= */ 200L,
|
||||||
|
/* bufferedPercentage= */ 50,
|
||||||
|
/* totalBufferedDurationMs= */ 500L,
|
||||||
|
/* currentLiveOffsetMs= */ 20L,
|
||||||
|
/* contentDurationMs= */ 400L,
|
||||||
|
/* contentBufferedPositionMs= */ 223L));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -331,6 +331,7 @@ public class MediaControllerListenerTest {
|
|||||||
AtomicReference<Timeline> timelineRef = new AtomicReference<>();
|
AtomicReference<Timeline> timelineRef = new AtomicReference<>();
|
||||||
AtomicReference<MediaMetadata> playlistMetadataRef = new AtomicReference<>();
|
AtomicReference<MediaMetadata> playlistMetadataRef = new AtomicReference<>();
|
||||||
AtomicReference<AudioAttributes> audioAttributesRef = new AtomicReference<>();
|
AtomicReference<AudioAttributes> audioAttributesRef = new AtomicReference<>();
|
||||||
|
AtomicBoolean isPlayingAdRef = new AtomicBoolean();
|
||||||
AtomicInteger currentAdGroupIndexRef = new AtomicInteger();
|
AtomicInteger currentAdGroupIndexRef = new AtomicInteger();
|
||||||
AtomicInteger currentAdIndexInAdGroupRef = new AtomicInteger();
|
AtomicInteger currentAdIndexInAdGroupRef = new AtomicInteger();
|
||||||
AtomicBoolean shuffleModeEnabledRef = new AtomicBoolean();
|
AtomicBoolean shuffleModeEnabledRef = new AtomicBoolean();
|
||||||
@ -373,6 +374,7 @@ public class MediaControllerListenerTest {
|
|||||||
PositionInfo oldPosition,
|
PositionInfo oldPosition,
|
||||||
PositionInfo newPosition,
|
PositionInfo newPosition,
|
||||||
@DiscontinuityReason int reason) {
|
@DiscontinuityReason int reason) {
|
||||||
|
isPlayingAdRef.set(controller.isPlayingAd());
|
||||||
currentAdGroupIndexRef.set(newPosition.adGroupIndex);
|
currentAdGroupIndexRef.set(newPosition.adGroupIndex);
|
||||||
currentAdIndexInAdGroupRef.set(newPosition.adIndexInAdGroup);
|
currentAdIndexInAdGroupRef.set(newPosition.adIndexInAdGroup);
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
@ -398,6 +400,7 @@ public class MediaControllerListenerTest {
|
|||||||
.setPlaylistMetadata(testPlaylistMetadata)
|
.setPlaylistMetadata(testPlaylistMetadata)
|
||||||
.setShuffleModeEnabled(testShuffleModeEnabled)
|
.setShuffleModeEnabled(testShuffleModeEnabled)
|
||||||
.setRepeatMode(testRepeatMode)
|
.setRepeatMode(testRepeatMode)
|
||||||
|
.setIsPlayingAd(true)
|
||||||
.setCurrentAdGroupIndex(testCurrentAdGroupIndex)
|
.setCurrentAdGroupIndex(testCurrentAdGroupIndex)
|
||||||
.setCurrentAdIndexInAdGroup(testCurrentAdIndexInAdGroup)
|
.setCurrentAdIndexInAdGroup(testCurrentAdIndexInAdGroup)
|
||||||
.build();
|
.build();
|
||||||
|
@ -1166,6 +1166,8 @@ public class MediaControllerStateMaskingTest {
|
|||||||
.setCurrentPosition(initialPosition)
|
.setCurrentPosition(initialPosition)
|
||||||
.setContentPosition(initialPosition)
|
.setContentPosition(initialPosition)
|
||||||
.setIsPlayingAd(/* isPlayingAd= */ true)
|
.setIsPlayingAd(/* isPlayingAd= */ true)
|
||||||
|
.setCurrentAdGroupIndex(0)
|
||||||
|
.setCurrentAdIndexInAdGroup(0)
|
||||||
.build();
|
.build();
|
||||||
remoteSession.setPlayer(playerConfig);
|
remoteSession.setPlayer(playerConfig);
|
||||||
|
|
||||||
|
@ -899,6 +899,8 @@ public class MediaControllerTest {
|
|||||||
.setDuration(10_000L)
|
.setDuration(10_000L)
|
||||||
.setIsPlaying(true)
|
.setIsPlaying(true)
|
||||||
.setIsPlayingAd(true)
|
.setIsPlayingAd(true)
|
||||||
|
.setCurrentAdGroupIndex(0)
|
||||||
|
.setCurrentAdIndexInAdGroup(0)
|
||||||
.setPlaybackParameters(new PlaybackParameters(/* speed= */ 2.0f))
|
.setPlaybackParameters(new PlaybackParameters(/* speed= */ 2.0f))
|
||||||
.build();
|
.build();
|
||||||
remoteSession.setPlayer(playerConfig);
|
remoteSession.setPlayer(playerConfig);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user