Skip to content
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

Add methods for replacing playlist items in Player #8046

Closed
georgi-neykov-hub opened this issue Oct 6, 2020 · 13 comments
Closed

Add methods for replacing playlist items in Player #8046

georgi-neykov-hub opened this issue Oct 6, 2020 · 13 comments
Assignees

Comments

@georgi-neykov-hub
Copy link

[REQUIRED] Use case description

In Exoplayer v2.12.0 the new playlist/MediaItem API is missing methods for replacing an existing item(s) at a given position.
The feature is needed if someone needs to refresh the metadata/clipping data/duration/... of an item already in the playlist. In my case I am using a diffing library to update the playlist via a change script which results in add/remove/change/move calls. Yes, one can always do a remove/add, but calling Player.addMediaItems() then Player.removeMediaItems() results in multiple playlist change notifications. I was a bit amazed that there's even a bulk move method (Player.moveMediaItems()), but nothing for changing an existing item.

Proposed solution

Add Player.replaceItem(int, MediaItem) and Player.replaceItems(Int, List<MediaItem>) methods or something similar.

@marcbaechinger
Copy link
Contributor

Yes, that's a very reasonable request. Thanks for filing!

@tonihei
Copy link
Collaborator

tonihei commented Oct 6, 2020

but calling Player.addMediaItems() then Player.removeMediaItems() results in multiple playlist change notifications

Out of interest, why is getting multiple playlist change notifications a problem for your case? I think we discussed replaceItem at some point and concluded you can always use remove+add to achieve the same goal. Note that this is different from moveMediaItem that provides additional functionality to ensure even the currently playing item can move without interrupting playback.

@georgi-neykov-hub
Copy link
Author

With the new media2 extension each player timeline change notification triggers notifications for media session's playlist changes which involve posting on a Handler, submitting (and allocating) Runnable s to an Executor and so on. Adding and using the requested methods during calls to SessionPlayerConnector.replacePlaylistItem () or direcly calling Player.replaceItem() on an instance hooked to a SessionPlayerConnector would reduce the overhead significantly.

@georgi-neykov-hub
Copy link
Author

Note that this is different from moveMediaItem that provides additional functionality to ensure even the currently playing item can move without interrupting playback.

@tonihei , how can the MediaItem for the currently playing item be updated? With the current properties it's basically the title of the item?
Would the playback be interrupted if the currently played item's MediaItem is replaced with a new one with the same mediaId, but with possible differences in other fields?

@marcbaechinger
Copy link
Contributor

Replacing the media item would mean replacing the underlying MediaSource and this would interrupt the currently playing media when replaced and prepare the new media source that's created for the new media item internally.

Do I understand correctly that you actually would rather want to only update the MetaData part (currently only holding the title) or the MediaItem.PlaybackProperties.tag?

@georgi-neykov-hub
Copy link
Author

Do I understand correctly that you actually would rather want to only update the MetaData part (currently only holding the title) or the MediaItem.PlaybackProperties.tag?

Well, not explicitly, but I am also interested how this can be achieved with the current API.

The reason for the request is to be able run any player playlist updates though a diffing library and apply a list of minimal changes so that bigger playlists can be updated in a efficient manner. The obvious choice is DiffUtil in the androidx.recyclerview library, which uses E. Myers' algorithm and builds a change script with add/remove/change/move operations.

Not that the setup doesn't work with the current APIs, I'm just worried about the unnecesary playback state updates and notifications done on each step and searching for ways to reduce them.

I'm even considering of adding a feature request for methods for controlling these notifications or the ability to do batches of changes and report them as a single change.

@marcbaechinger
Copy link
Contributor

Ok, thanks for clarification. If you are going to replace items in the queue in that sense 'blindly' by just running the recorded changes of another object graph, you can probably not know in advance whether this will remove or replace the playing media item which would led to a interruption of playback. This will be the case with a replaceMediaItems(...) method as well, when the range of replaced items contains the playing item.

I suggest we leave this issue being an enhancement about this request around adding a method replaceMediaItems to keep things manageable.

@Colaman0
Copy link

I have the same need to update the playlist.
I try to call setMediaItems to replace the playlist but it will interrupt playing short time.
Is there any progress now?

@emagombe
Copy link

emagombe commented Dec 24, 2022

I have the same need.
But I got a writing this code
int count = exoPlayer.getMediaItemCount();
exoPlayer.addMediaSources(count, mediaSources);
exoPlayer.seekTo(count, 0);
if(count > 0) {
exoPlayer.removeMediaItems(0, count);
}
exoPlayer.prepare();
Basically it adds a list of mediasources below the current list, changes the index to the first item of the new list and then removes all the items above and reindex to 0.
It works fine. I tried exoPlayer.clearMediaItems() but for me it crashes the notification so this method works better.

@marcbaechinger
Copy link
Contributor

I'm not sure I understand what is the difference of the code above and this line

exoPlayer.setMediaSources(mediaSources, /* startIndex= */ 0, /* startPositionMs= */ 0);

The above line seems to do the same, but with less code. Is there a difference in behaviour with your approach?

@emagombe
Copy link

emagombe commented Feb 8, 2023

Lol, yeah, it works the same way. Thanks!

icbaker pushed a commit to androidx/media that referenced this issue May 16, 2023
This methods allows to replace single items or a range of items directly
without using separate operations for add and remove. The advantage is
more readable code for apps and the potential for player
implementations to optimize this process (e.g. only replace values
without interrupting playback).

The current change just introduces the API with its default behavior.
The default logic will be removed again in the future in favor of
better logic in the Player implementations.

Issue: google/ExoPlayer#8046
PiperOrigin-RevId: 532151471
icbaker pushed a commit that referenced this issue May 16, 2023
This methods allows to replace single items or a range of items directly
without using separate operations for add and remove. The advantage is
more readable code for apps and the potential for player
implementations to optimize this process (e.g. only replace values
without interrupting playback).

The current change just introduces the API with its default behavior.
The default logic will be removed again in the future in favor of
better logic in the Player implementations.

Issue: #8046
PiperOrigin-RevId: 532151471
tonihei added a commit to androidx/media that referenced this issue May 25, 2023
This change moves the default logic into the actual Player
implementations, but does not introduce any behavior changes compared
to addMediaItems+removeMediaItems except to make the updates "atomic"
in ExoPlayerImpl, SimpleBasePlayer and MediaController. It also
provides backwards compatbility for cases where Players don't support
the operation.

Issue: google/ExoPlayer#8046

#minor-release

PiperOrigin-RevId: 534945089
tonihei added a commit that referenced this issue May 25, 2023
This change moves the default logic into the actual Player
implementations, but does not introduce any behavior changes compared
to addMediaItems+removeMediaItems except to make the updates "atomic"
in ExoPlayerImpl, SimpleBasePlayer and MediaController. It also
provides backwards compatbility for cases where Players don't support
the operation.

Issue: #8046

#minor-release

PiperOrigin-RevId: 534945089
tof-tof pushed a commit to androidx/media that referenced this issue May 30, 2023
This methods allows to replace single items or a range of items directly
without using separate operations for add and remove. The advantage is
more readable code for apps and the potential for player
implementations to optimize this process (e.g. only replace values
without interrupting playback).

The current change just introduces the API with its default behavior.
The default logic will be removed again in the future in favor of
better logic in the Player implementations.

Issue: google/ExoPlayer#8046
PiperOrigin-RevId: 532151471
(cherry picked from commit b1cfeb0)
tof-tof pushed a commit to androidx/media that referenced this issue May 30, 2023
This change moves the default logic into the actual Player
implementations, but does not introduce any behavior changes compared
to addMediaItems+removeMediaItems except to make the updates "atomic"
in ExoPlayerImpl, SimpleBasePlayer and MediaController. It also
provides backwards compatbility for cases where Players don't support
the operation.

Issue: google/ExoPlayer#8046

#minor-release

PiperOrigin-RevId: 534945089
(cherry picked from commit 2c07468)
tof-tof pushed a commit that referenced this issue Jun 14, 2023
This methods allows to replace single items or a range of items directly
without using separate operations for add and remove. The advantage is
more readable code for apps and the potential for player
implementations to optimize this process (e.g. only replace values
without interrupting playback).

The current change just introduces the API with its default behavior.
The default logic will be removed again in the future in favor of
better logic in the Player implementations.

Issue: #8046
PiperOrigin-RevId: 532151471
(cherry picked from commit 7289186)
tof-tof pushed a commit that referenced this issue Jun 14, 2023
This change moves the default logic into the actual Player
implementations, but does not introduce any behavior changes compared
to addMediaItems+removeMediaItems except to make the updates "atomic"
in ExoPlayerImpl, SimpleBasePlayer and MediaController. It also
provides backwards compatbility for cases where Players don't support
the operation.

Issue: #8046

#minor-release

PiperOrigin-RevId: 534945089
(cherry picked from commit 6309b11)
@Mohammad3638363

This comment was marked as spam.

@tonihei tonihei closed this as completed Aug 3, 2023
@Mohammad3638363
Copy link

شكرا جزيلا

@google google locked and limited conversation to collaborators Oct 3, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants