mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Allow to remove all playlist items
PiperOrigin-RevId: 343437513
This commit is contained in:
parent
3f2eb9d732
commit
6edf52b2c5
4 changed files with 66 additions and 22 deletions
|
|
@ -51,6 +51,7 @@
|
||||||
* Media2 extension:
|
* Media2 extension:
|
||||||
* Notify onBufferingEnded when the state of origin player becomes
|
* Notify onBufferingEnded when the state of origin player becomes
|
||||||
STATE_IDLE or STATE_ENDED.
|
STATE_IDLE or STATE_ENDED.
|
||||||
|
* Allow to remove all playlist items that makes the player reset.
|
||||||
|
|
||||||
### 2.12.1 (2020-10-23) ###
|
### 2.12.1 (2020-10-23) ###
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.ext.media2;
|
package com.google.android.exoplayer2.ext.media2;
|
||||||
|
|
||||||
|
import static androidx.media2.common.SessionPlayer.PLAYER_STATE_IDLE;
|
||||||
import static androidx.media2.common.SessionPlayer.PLAYER_STATE_PAUSED;
|
import static androidx.media2.common.SessionPlayer.PLAYER_STATE_PAUSED;
|
||||||
import static androidx.media2.common.SessionPlayer.PLAYER_STATE_PLAYING;
|
import static androidx.media2.common.SessionPlayer.PLAYER_STATE_PLAYING;
|
||||||
import static androidx.media2.common.SessionPlayer.PlayerResult.RESULT_INFO_SKIPPED;
|
import static androidx.media2.common.SessionPlayer.PlayerResult.RESULT_INFO_SKIPPED;
|
||||||
|
|
@ -60,6 +61,7 @@ import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
|
@ -762,18 +764,42 @@ public class SessionPlayerConnectorTest {
|
||||||
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
|
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
|
||||||
public void setPlaylist_setsPlaylistAndCurrentMediaItem() throws Exception {
|
public void setPlaylist_setsPlaylistAndCurrentMediaItem() throws Exception {
|
||||||
List<MediaItem> playlist = TestUtils.createPlaylist(10);
|
List<MediaItem> playlist = TestUtils.createPlaylist(10);
|
||||||
CountDownLatch onCurrentMediaItemChangedLatch = new CountDownLatch(1);
|
PlayerCallbackForPlaylist callback = new PlayerCallbackForPlaylist(playlist, 1);
|
||||||
sessionPlayerConnector.registerPlayerCallback(
|
sessionPlayerConnector.registerPlayerCallback(executor, callback);
|
||||||
executor, new PlayerCallbackForPlaylist(playlist, onCurrentMediaItemChangedLatch));
|
|
||||||
|
|
||||||
assertPlayerResultSuccess(sessionPlayerConnector.setPlaylist(playlist, null));
|
assertPlayerResultSuccess(sessionPlayerConnector.setPlaylist(playlist, null));
|
||||||
assertThat(onCurrentMediaItemChangedLatch.await(PLAYLIST_CHANGE_WAIT_TIME_MS, MILLISECONDS))
|
assertThat(callback.await(PLAYLIST_CHANGE_WAIT_TIME_MS, MILLISECONDS)).isTrue();
|
||||||
.isTrue();
|
|
||||||
|
|
||||||
assertThat(sessionPlayerConnector.getPlaylist()).isEqualTo(playlist);
|
assertThat(sessionPlayerConnector.getPlaylist()).isEqualTo(playlist);
|
||||||
assertThat(sessionPlayerConnector.getCurrentMediaItem()).isEqualTo(playlist.get(0));
|
assertThat(sessionPlayerConnector.getCurrentMediaItem()).isEqualTo(playlist.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@LargeTest
|
||||||
|
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
|
||||||
|
public void setPlaylistAndRemoveAllPlaylistItem_playerStateBecomesIdle() throws Exception {
|
||||||
|
List<MediaItem> playlist = new ArrayList<>();
|
||||||
|
playlist.add(TestUtils.createMediaItem(R.raw.video_1));
|
||||||
|
PlayerCallbackForPlaylist callback =
|
||||||
|
new PlayerCallbackForPlaylist(playlist, 2) {
|
||||||
|
@Override
|
||||||
|
public void onPlayerStateChanged(@NonNull SessionPlayer player, int playerState) {
|
||||||
|
countDown();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
sessionPlayerConnector.registerPlayerCallback(executor, callback);
|
||||||
|
|
||||||
|
assertPlayerResultSuccess(sessionPlayerConnector.setPlaylist(playlist, null));
|
||||||
|
assertPlayerResultSuccess(sessionPlayerConnector.prepare());
|
||||||
|
assertThat(callback.await(PLAYLIST_CHANGE_WAIT_TIME_MS, MILLISECONDS)).isTrue();
|
||||||
|
assertThat(sessionPlayerConnector.getPlayerState()).isEqualTo(PLAYER_STATE_PAUSED);
|
||||||
|
|
||||||
|
callback.resetLatch(1);
|
||||||
|
assertPlayerResultSuccess(sessionPlayerConnector.removePlaylistItem(0));
|
||||||
|
assertThat(callback.await(PLAYLIST_CHANGE_WAIT_TIME_MS, MILLISECONDS)).isTrue();
|
||||||
|
assertThat(sessionPlayerConnector.getPlayerState()).isEqualTo(PLAYER_STATE_IDLE);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@LargeTest
|
@LargeTest
|
||||||
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
|
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
|
||||||
|
|
@ -958,14 +984,12 @@ public class SessionPlayerConnectorTest {
|
||||||
int listSize = 2;
|
int listSize = 2;
|
||||||
List<MediaItem> playlist = TestUtils.createPlaylist(listSize);
|
List<MediaItem> playlist = TestUtils.createPlaylist(listSize);
|
||||||
|
|
||||||
CountDownLatch onCurrentMediaItemChangedLatch = new CountDownLatch(1);
|
PlayerCallbackForPlaylist callback = new PlayerCallbackForPlaylist(playlist, 1);
|
||||||
sessionPlayerConnector.registerPlayerCallback(
|
sessionPlayerConnector.registerPlayerCallback(executor, callback);
|
||||||
executor, new PlayerCallbackForPlaylist(playlist, onCurrentMediaItemChangedLatch));
|
|
||||||
|
|
||||||
assertPlayerResultSuccess(sessionPlayerConnector.setPlaylist(playlist, null));
|
assertPlayerResultSuccess(sessionPlayerConnector.setPlaylist(playlist, null));
|
||||||
assertThat(sessionPlayerConnector.getCurrentMediaItemIndex()).isEqualTo(0);
|
assertThat(sessionPlayerConnector.getCurrentMediaItemIndex()).isEqualTo(0);
|
||||||
assertThat(onCurrentMediaItemChangedLatch.await(PLAYLIST_CHANGE_WAIT_TIME_MS, MILLISECONDS))
|
assertThat(callback.await(PLAYLIST_CHANGE_WAIT_TIME_MS, MILLISECONDS)).isTrue();
|
||||||
.isTrue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -1193,16 +1217,15 @@ public class SessionPlayerConnectorTest {
|
||||||
int listSize = playlist.size();
|
int listSize = playlist.size();
|
||||||
|
|
||||||
// Any value more than list size + 1, to see repeat mode with the recorded video.
|
// Any value more than list size + 1, to see repeat mode with the recorded video.
|
||||||
CountDownLatch onCurrentMediaItemChangedLatch = new CountDownLatch(listSize + 2);
|
|
||||||
CopyOnWriteArrayList<MediaItem> currentMediaItemChanges = new CopyOnWriteArrayList<>();
|
CopyOnWriteArrayList<MediaItem> currentMediaItemChanges = new CopyOnWriteArrayList<>();
|
||||||
PlayerCallbackForPlaylist callback =
|
PlayerCallbackForPlaylist callback =
|
||||||
new PlayerCallbackForPlaylist(playlist, onCurrentMediaItemChangedLatch) {
|
new PlayerCallbackForPlaylist(playlist, listSize + 2) {
|
||||||
@Override
|
@Override
|
||||||
public void onCurrentMediaItemChanged(
|
public void onCurrentMediaItemChanged(
|
||||||
@NonNull SessionPlayer player, @NonNull MediaItem item) {
|
@NonNull SessionPlayer player, @NonNull MediaItem item) {
|
||||||
super.onCurrentMediaItemChanged(player, item);
|
super.onCurrentMediaItemChanged(player, item);
|
||||||
currentMediaItemChanges.add(item);
|
currentMediaItemChanges.add(item);
|
||||||
onCurrentMediaItemChangedLatch.countDown();
|
countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -1223,7 +1246,7 @@ public class SessionPlayerConnectorTest {
|
||||||
assertWithMessage(
|
assertWithMessage(
|
||||||
"Current media item didn't change as expected. Actual changes were %s",
|
"Current media item didn't change as expected. Actual changes were %s",
|
||||||
currentMediaItemChanges)
|
currentMediaItemChanges)
|
||||||
.that(onCurrentMediaItemChangedLatch.await(PLAYBACK_COMPLETED_WAIT_TIME_MS, MILLISECONDS))
|
.that(callback.await(PLAYBACK_COMPLETED_WAIT_TIME_MS, MILLISECONDS))
|
||||||
.isTrue();
|
.isTrue();
|
||||||
|
|
||||||
int expectedMediaItemIndex = 0;
|
int expectedMediaItemIndex = 0;
|
||||||
|
|
@ -1285,9 +1308,9 @@ public class SessionPlayerConnectorTest {
|
||||||
private List<MediaItem> playlist;
|
private List<MediaItem> playlist;
|
||||||
private CountDownLatch onCurrentMediaItemChangedLatch;
|
private CountDownLatch onCurrentMediaItemChangedLatch;
|
||||||
|
|
||||||
PlayerCallbackForPlaylist(List<MediaItem> playlist, CountDownLatch latch) {
|
PlayerCallbackForPlaylist(List<MediaItem> playlist, int count) {
|
||||||
this.playlist = playlist;
|
this.playlist = playlist;
|
||||||
onCurrentMediaItemChangedLatch = latch;
|
onCurrentMediaItemChangedLatch = new CountDownLatch(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -1296,5 +1319,17 @@ public class SessionPlayerConnectorTest {
|
||||||
assertThat(sessionPlayerConnector.getCurrentMediaItemIndex()).isEqualTo(currentIndex);
|
assertThat(sessionPlayerConnector.getCurrentMediaItemIndex()).isEqualTo(currentIndex);
|
||||||
onCurrentMediaItemChangedLatch.countDown();
|
onCurrentMediaItemChangedLatch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void resetLatch(int count) {
|
||||||
|
onCurrentMediaItemChangedLatch = new CountDownLatch(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
|
||||||
|
return onCurrentMediaItemChangedLatch.await(timeout, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void countDown() {
|
||||||
|
onCurrentMediaItemChangedLatch.countDown();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -202,6 +202,9 @@ import java.util.List;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean removePlaylistItem(@IntRange(from = 0) int index) {
|
public boolean removePlaylistItem(@IntRange(from = 0) int index) {
|
||||||
|
if (player.getMediaItemCount() <= index) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
player.removeMediaItem(index);
|
player.removeMediaItem(index);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -367,7 +370,9 @@ import java.util.List;
|
||||||
case Player.STATE_IDLE:
|
case Player.STATE_IDLE:
|
||||||
return SessionPlayer.PLAYER_STATE_IDLE;
|
return SessionPlayer.PLAYER_STATE_IDLE;
|
||||||
case Player.STATE_ENDED:
|
case Player.STATE_ENDED:
|
||||||
return SessionPlayer.PLAYER_STATE_PAUSED;
|
return player.getCurrentMediaItem() == null
|
||||||
|
? SessionPlayer.PLAYER_STATE_IDLE
|
||||||
|
: SessionPlayer.PLAYER_STATE_PAUSED;
|
||||||
case Player.STATE_BUFFERING:
|
case Player.STATE_BUFFERING:
|
||||||
case Player.STATE_READY:
|
case Player.STATE_READY:
|
||||||
return playWhenReady
|
return playWhenReady
|
||||||
|
|
@ -428,7 +433,9 @@ import java.util.List;
|
||||||
postOrRun(handler, pollBufferRunnable);
|
postOrRun(handler, pollBufferRunnable);
|
||||||
break;
|
break;
|
||||||
case Player.STATE_ENDED:
|
case Player.STATE_ENDED:
|
||||||
listener.onPlaybackEnded();
|
if (player.getCurrentMediaItem() != null) {
|
||||||
|
listener.onPlaybackEnded();
|
||||||
|
}
|
||||||
player.setPlayWhenReady(false);
|
player.setPlayWhenReady(false);
|
||||||
updateBufferingState(/* isBuffering= */ false);
|
updateBufferingState(/* isBuffering= */ false);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -559,12 +559,16 @@ public final class SessionPlayerConnector extends SessionPlayer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Remove this suppress warnings and call onCurrentMediaItemChanged with a null item
|
||||||
|
// once AndroidX media2 1.2.0 is released
|
||||||
|
@SuppressWarnings("nullness:argument.type.incompatible")
|
||||||
private void handlePlaylistChangedOnHandler() {
|
private void handlePlaylistChangedOnHandler() {
|
||||||
List<MediaItem> currentPlaylist = player.getPlaylist();
|
List<MediaItem> currentPlaylist = player.getPlaylist();
|
||||||
MediaMetadata playlistMetadata = player.getPlaylistMetadata();
|
MediaMetadata playlistMetadata = player.getPlaylistMetadata();
|
||||||
|
|
||||||
MediaItem currentMediaItem = player.getCurrentMediaItem();
|
MediaItem currentMediaItem = player.getCurrentMediaItem();
|
||||||
boolean notifyCurrentMediaItem = !ObjectsCompat.equals(this.currentMediaItem, currentMediaItem);
|
boolean notifyCurrentMediaItem =
|
||||||
|
!ObjectsCompat.equals(this.currentMediaItem, currentMediaItem) && currentMediaItem != null;
|
||||||
this.currentMediaItem = currentMediaItem;
|
this.currentMediaItem = currentMediaItem;
|
||||||
|
|
||||||
long currentPosition = getCurrentPosition();
|
long currentPosition = getCurrentPosition();
|
||||||
|
|
@ -573,9 +577,6 @@ public final class SessionPlayerConnector extends SessionPlayer {
|
||||||
callback.onPlaylistChanged(
|
callback.onPlaylistChanged(
|
||||||
SessionPlayerConnector.this, currentPlaylist, playlistMetadata);
|
SessionPlayerConnector.this, currentPlaylist, playlistMetadata);
|
||||||
if (notifyCurrentMediaItem) {
|
if (notifyCurrentMediaItem) {
|
||||||
Assertions.checkNotNull(
|
|
||||||
currentMediaItem, "PlaylistManager#currentMediaItem() cannot be changed to null");
|
|
||||||
|
|
||||||
callback.onCurrentMediaItemChanged(SessionPlayerConnector.this, currentMediaItem);
|
callback.onCurrentMediaItemChanged(SessionPlayerConnector.this, currentMediaItem);
|
||||||
|
|
||||||
// Workaround for MediaSession's issue that current media item change isn't propagated
|
// Workaround for MediaSession's issue that current media item change isn't propagated
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue