androidx / media

Jetpack Media3 support libraries for media use cases, including ExoPlayer, an extensible media player for Android
Apache License 2.0
1.4k stars 327 forks source link

Allow apps to provide custom Bundle equality logic #1368

Open derat opened 2 months ago

derat commented 2 months ago

I'm having trouble with PlayerInterface.Listener.onTimelineChanged() not being consistently called when my SimpleBasePlayer-derived class updates an item's MediaMetadata.extra bundle and calls invalidateState().

I can see that this behavior is documented in various places:

I'm using the extras bundle to store information that changes at runtime (e.g. user-controlled tags), so I need some way to notify clients about changes. In order to force a playlist change when I modify the extras bundle, is my best bet changing the value of some arbitrary field in MediaMetadata, MediaItem, or SimpleBasePlayer.MediaItemData that I'm not currently using?

icbaker commented 1 month ago

As you've pointed out, the equality of Bundle extras fields has come up a few times. We have no plans to implement general-purpose equality comparisons for these fields - but we have recently discussed the idea of allowing apps to provide a custom equality comparison, which I think would solve your issue (since you know the key values you want to inspect/compare).

We would likely try and do this in a way that's consistent for all the various extras fields in the library, which will require a bit of design thought (especially how we can keep the comparison consistent across both sides of the session/controller IPC for some of the extras fields) - so I'm afraid we don't have capacity to work on this soon - but it would be helpful if you could let us know if you agree whether this sort of approach would solve your problem.

In the meantime, I suspect what you've proposed is the best approach - or you could wire up your own direct side-channel from your SimpleBasePlayer to notify your clients of changes directly (assuming they are invoking your type directly, rather than via MediaSession/Controller).

derat commented 1 month ago

@icbaker, thanks for the reply! I think that being able to supply a custom comparison as you suggested would work for my case.

In the meantime, here's what I went with in case it helps anyone else:

if (itemData.equals(old)) {
    itemData = itemData.buildUpon().setManifest(object {}).build()
}

(I wasn't using the manifest field for anything.)

icbaker commented 2 weeks ago

Updating title and labels to use this to track the idea of allowing apps to provide a custom equality for bundles.