-
Notifications
You must be signed in to change notification settings - Fork 6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(playlist): remove MediaSource range #4564
Changes from 2 commits
c9b6a73
2c801ca
cc7f011
7878bf6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -50,6 +50,7 @@ public class ConcatenatingMediaSource extends CompositeMediaSource<MediaSourceHo | |
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_REMOVE_RANGE = 200; | ||
private static final int MSG_MOVE = 3; | ||
private static final int MSG_CLEAR = 4; | ||
private static final int MSG_NOTIFY_LISTENER = 5; | ||
|
@@ -265,6 +266,9 @@ public final synchronized void addMediaSources( | |
* <p>Note: If you want to move the instance, it's preferable to use {@link #moveMediaSource(int, | ||
* int)} instead. | ||
* | ||
* <p>Note: If you want to remove a set of contiguous sources, it's preferable to use | ||
* {@link #removeMediaSourceRange(int, int)} instead. | ||
* | ||
* @param index The index at which the media source will be removed. This index must be in the | ||
* range of 0 <= index < {@link #getSize()}. | ||
*/ | ||
|
@@ -276,7 +280,10 @@ public final synchronized void removeMediaSource(int index) { | |
* Removes a {@link MediaSource} from the playlist and executes a custom action on completion. | ||
* | ||
* <p>Note: If you want to move the instance, it's preferable to use {@link #moveMediaSource(int, | ||
* int)} instead. | ||
* int, Runnable)} instead. | ||
* | ||
* <p>Note: If you want to remove a set of contiguous sources, it's preferable to use | ||
* {@link #removeMediaSourceRange(int, int, Runnable)} instead. | ||
* | ||
* @param index The index at which the media source will be removed. This index must be in the | ||
* range of 0 <= index < {@link #getSize()}. | ||
|
@@ -297,6 +304,79 @@ public final synchronized void removeMediaSource( | |
} | ||
} | ||
|
||
/** | ||
* Removes a range of {@link MediaSource}s from the playlist, by specifying an initial index | ||
* (included) and a final index (excluded). | ||
* | ||
* <p>Note: when specified range is empty, no actual media source is removed and no exception | ||
* is thrown. | ||
* | ||
* @param fromIndex The initial range index, pointing to the first media source that will be | ||
* removed. This index must be in the range of 0 <= index < {@link #getSize()}. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Both ranges should be "in the range of 0 <= index <= {@link #getSize()}." That is, including the getSize index. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At a given time, "occupied" track indices are 0, 1, ... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As the end index is exclusive, the method must allow getSize() as end index. And to support the example you gave in the issue, to keep an element at index N only, it would be nice to be able to call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We've abandoned the "simplicity" implied by initial issue example when we "gave up" on API tolerance (so to say). Since then, the idea seemed: have a clear API with errors when arguments are not correct. And for Staying consistent with allowed param values in signature seems quite a thing. By allowing passing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd say it's best to follow the existing behaviour of List.subList and the like. That is, throwing if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cool. Just to tease a little bit, in case like "remove everything behind element N" when N is the last element, then Anyway, changes are coming There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
And if I'm not mistaken There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Q1: correct, current implementation would remove element at Q2: Cool |
||
* @param toIndex The final range index, pointing to the first media source that will be left | ||
* untouched. The last media source to be removed is at index {@code toIndex} - 1. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "The last media source to be removed is at index {@code toIndex} - 1." - That seems redundant and can be removed. |
||
* This index must be in the range of 0 <= index < {@link #getSize()}. | ||
* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
* @throws IndexOutOfBoundsException when either index is out of playlist bounds, i.e. {@code | ||
* fromIndex} < 0 or >= {@link #getSize()}, {@code toIndex} < 0 or > {@link | ||
* #getSize()} | ||
* @throws IndexOutOfBoundsException when range is malformed, i.e. {@code fromIndex} > | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Totally agree with grouping. Are you also suggesting to slim down the number of (broken) examples provided in JavaDoc? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. As we already require fromIndex>lastIndex, the other two examples are not needed. |
||
* {@code toIndex} | ||
*/ | ||
public final synchronized void removeMediaSourceRange(int fromIndex, int toIndex) { | ||
removeMediaSourceRange(fromIndex, toIndex, null); | ||
} | ||
|
||
/** | ||
* Removes a range of {@link MediaSource}s from the playlist, by specifying an initial index | ||
* (included) and a final index (excluded), and executes a custom action on completion.. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove second full stop. |
||
* | ||
* <p>Note: when specified range is empty, no actual media source is removed and no exception | ||
* is thrown. | ||
* | ||
* @param fromIndex The initial range index, pointing to the first media source that will be | ||
* removed. This index must be in the range of 0 <= index < {@link #getSize()}. | ||
* @param toIndex The final range index, pointing to the first media source that will be left | ||
* untouched. The last media source to be removed is at index {@code toIndex} - 1. | ||
* This index must be in the range of 0 <= index < {@link #getSize()}. | ||
* | ||
* @throws IndexOutOfBoundsException when either index is out of playlist bounds, i.e. {@code | ||
* fromIndex} < 0 or >= {@link #getSize()}, {@code toIndex} < 0 or > {@link | ||
* #getSize()} | ||
* @throws IndexOutOfBoundsException when range is malformed, i.e. {@code fromIndex} > | ||
* {@code toIndex} | ||
* @param actionOnCompletion A {@link Runnable} which is executed immediately after the media | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This param should be together with the other params above. |
||
* source range has been removed from the playlist. | ||
*/ | ||
public final synchronized void removeMediaSourceRange( | ||
int fromIndex, int toIndex, @Nullable Runnable actionOnCompletion) { | ||
if (fromIndex < 0 || fromIndex >= mediaSourcesPublic.size()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to do the explicit bound checks here. As soon as you call the subList method, the IndexOutOfBoundsException will be thrown anyway. |
||
throw new IndexOutOfBoundsException(String.format("Cannot remove source range: initial index (%d) out of bounds", fromIndex)); | ||
} | ||
if (toIndex < 0 || toIndex > mediaSourcesPublic.size()) { | ||
throw new IndexOutOfBoundsException(String.format("Cannot remove source range: final index (%d) out of bounds", toIndex)); | ||
} | ||
if (fromIndex > toIndex) { | ||
throw new IndexOutOfBoundsException(String.format("Cannot remove source range: range malformed (%d, %d)", fromIndex, toIndex)); | ||
} | ||
if (fromIndex == toIndex) { | ||
if (actionOnCompletion != null) { | ||
actionOnCompletion.run(); | ||
} | ||
return; | ||
} | ||
mediaSourcesPublic.subList(fromIndex, toIndex).clear(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you replace that with Util.removeRange(mediaSourcesPublic, fromIndex, toIndex)? That calls the same method but is slightly more readable. Also move it above the if(fromIndex == toIndex) check to ensure the exceptions are thrown first. |
||
if (player != null) { | ||
player | ||
.createMessage(this) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These should be indented by 4 spaces (relative to "player") |
||
.setType(MSG_REMOVE_RANGE) | ||
.setPayload(new MessageData<>(fromIndex, toIndex, actionOnCompletion)) | ||
.send(); | ||
} else if (actionOnCompletion != null) { | ||
actionOnCompletion.run(); | ||
} | ||
} | ||
|
||
/** | ||
* Moves an existing {@link MediaSource} within the playlist. | ||
* | ||
|
@@ -489,6 +569,18 @@ public final void handleMessage(int messageType, Object message) throws ExoPlayb | |
removeMediaSourceInternal(removeMessage.index); | ||
scheduleListenerNotification(removeMessage.actionOnCompletion); | ||
break; | ||
case MSG_REMOVE_RANGE: | ||
MessageData<Integer> removeRangeMessage = (MessageData<Integer>) message; | ||
int fromIndex = removeRangeMessage.index; | ||
int toIndex = removeRangeMessage.customData; | ||
for (int index = toIndex - 1; index >= fromIndex; index--) { | ||
shuffleOrder = shuffleOrder.cloneAndRemove(index); | ||
} | ||
for (int index = toIndex - 1; index >= fromIndex; index--) { | ||
removeMediaSourceInternal(index); | ||
} | ||
scheduleListenerNotification(removeRangeMessage.actionOnCompletion); | ||
break; | ||
case MSG_MOVE: | ||
MessageData<Integer> moveMessage = (MessageData<Integer>) message; | ||
shuffleOrder = shuffleOrder.cloneAndRemove(moveMessage.index); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you renumber this to be 3 and change the numbers below accordingly?