Allow moving media source within DynamicConcatenatingMediaSource.
This option allows to move the currently playing media source to another position and also to move other media source without creating a new MediaSource object. Issue:#1706 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=161402022
This commit is contained in:
parent
06b3b3ca8d
commit
45f94eab62
@ -85,6 +85,24 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
|
||||
TimelineAsserts.assertPeriodCounts(timeline, 2, 4, 1, 5, 6, 7, 3);
|
||||
TimelineAsserts.assertWindowIds(timeline, 222, 444, 111, 555, 666, 777, 333);
|
||||
|
||||
// Move sources.
|
||||
mediaSource.moveMediaSource(2, 3);
|
||||
waitForTimelineUpdate();
|
||||
TimelineAsserts.assertPeriodCounts(timeline, 2, 4, 5, 1, 6, 7, 3);
|
||||
TimelineAsserts.assertWindowIds(timeline, 222, 444, 555, 111, 666, 777, 333);
|
||||
mediaSource.moveMediaSource(3, 2);
|
||||
waitForTimelineUpdate();
|
||||
TimelineAsserts.assertPeriodCounts(timeline, 2, 4, 1, 5, 6, 7, 3);
|
||||
TimelineAsserts.assertWindowIds(timeline, 222, 444, 111, 555, 666, 777, 333);
|
||||
mediaSource.moveMediaSource(0, 6);
|
||||
waitForTimelineUpdate();
|
||||
TimelineAsserts.assertPeriodCounts(timeline, 4, 1, 5, 6, 7, 3, 2);
|
||||
TimelineAsserts.assertWindowIds(timeline, 444, 111, 555, 666, 777, 333, 222);
|
||||
mediaSource.moveMediaSource(6, 0);
|
||||
waitForTimelineUpdate();
|
||||
TimelineAsserts.assertPeriodCounts(timeline, 2, 4, 1, 5, 6, 7, 3);
|
||||
TimelineAsserts.assertWindowIds(timeline, 222, 444, 111, 555, 666, 777, 333);
|
||||
|
||||
// Remove in the middle.
|
||||
mediaSource.removeMediaSource(3);
|
||||
waitForTimelineUpdate();
|
||||
@ -138,7 +156,9 @@ public final class DynamicConcatenatingMediaSourceTest extends TestCase {
|
||||
mediaSource.addMediaSource(childSources[0]);
|
||||
mediaSource.addMediaSource(childSources[1]);
|
||||
mediaSource.addMediaSource(0, childSources[2]);
|
||||
mediaSource.removeMediaSource(1);
|
||||
mediaSource.moveMediaSource(0, 2);
|
||||
mediaSource.removeMediaSource(0);
|
||||
mediaSource.moveMediaSource(1, 0);
|
||||
mediaSource.addMediaSource(1, childSources[3]);
|
||||
assertNull(timeline);
|
||||
|
||||
|
@ -44,6 +44,7 @@ public final class DynamicConcatenatingMediaSource implements MediaSource, ExoPl
|
||||
private static final int MSG_ADD = 0;
|
||||
private static final int MSG_ADD_MULTIPLE = 1;
|
||||
private static final int MSG_REMOVE = 2;
|
||||
private static final int MSG_MOVE = 3;
|
||||
|
||||
// Accessed on the app thread.
|
||||
private final List<MediaSource> mediaSourcesPublic;
|
||||
@ -126,7 +127,8 @@ public final class DynamicConcatenatingMediaSource implements MediaSource, ExoPl
|
||||
/**
|
||||
* Removes a {@link MediaSource} from the playlist.
|
||||
*
|
||||
* @param index The index at which the media source will be removed.
|
||||
* @param index The index at which the media source will be removed. This index must be in the
|
||||
* range of 0 <= index < {@link #getSize()}.
|
||||
*/
|
||||
public synchronized void removeMediaSource(int index) {
|
||||
mediaSourcesPublic.remove(index);
|
||||
@ -135,6 +137,25 @@ public final class DynamicConcatenatingMediaSource implements MediaSource, ExoPl
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves an existing {@link MediaSource} within the playlist.
|
||||
*
|
||||
* @param currentIndex The current index of the media source in the playlist. This index must be
|
||||
* in the range of 0 <= index < {@link #getSize()}.
|
||||
* @param newIndex The target index of the media source in the playlist. This index must be in the
|
||||
* range of 0 <= index < {@link #getSize()}.
|
||||
*/
|
||||
public synchronized void moveMediaSource(int currentIndex, int newIndex) {
|
||||
if (currentIndex == newIndex) {
|
||||
return;
|
||||
}
|
||||
mediaSourcesPublic.add(newIndex, mediaSourcesPublic.remove(currentIndex));
|
||||
if (player != null) {
|
||||
player.sendMessages(new ExoPlayerMessage(this, MSG_MOVE,
|
||||
Pair.create(currentIndex, newIndex)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of media sources in the playlist.
|
||||
*/
|
||||
@ -225,6 +246,11 @@ public final class DynamicConcatenatingMediaSource implements MediaSource, ExoPl
|
||||
removeMediaSourceInternal((Integer) message);
|
||||
break;
|
||||
}
|
||||
case MSG_MOVE: {
|
||||
Pair<Integer, Integer> messageData = (Pair<Integer, Integer>) message;
|
||||
moveMediaSourceInternal(messageData.first, messageData.second);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
@ -304,6 +330,21 @@ public final class DynamicConcatenatingMediaSource implements MediaSource, ExoPl
|
||||
holder.mediaSource.releaseSource();
|
||||
}
|
||||
|
||||
private void moveMediaSourceInternal(int currentIndex, int newIndex) {
|
||||
int startIndex = Math.min(currentIndex, newIndex);
|
||||
int endIndex = Math.max(currentIndex, newIndex);
|
||||
int windowOffset = mediaSourceHolders.get(startIndex).firstWindowIndexInChild;
|
||||
int periodOffset = mediaSourceHolders.get(startIndex).firstPeriodIndexInChild;
|
||||
mediaSourceHolders.add(newIndex, mediaSourceHolders.remove(currentIndex));
|
||||
for (int i = startIndex; i <= endIndex; i++) {
|
||||
MediaSourceHolder holder = mediaSourceHolders.get(i);
|
||||
holder.firstWindowIndexInChild = windowOffset;
|
||||
holder.firstPeriodIndexInChild = periodOffset;
|
||||
windowOffset += holder.timeline.getWindowCount();
|
||||
periodOffset += holder.timeline.getPeriodCount();
|
||||
}
|
||||
}
|
||||
|
||||
private void correctOffsets(int startIndex, int windowOffsetUpdate, int periodOffsetUpdate) {
|
||||
windowCount += windowOffsetUpdate;
|
||||
periodCount += periodOffsetUpdate;
|
||||
|
Loading…
x
Reference in New Issue
Block a user