google / ExoPlayer

This project is deprecated and stale. The latest ExoPlayer code is available in https://github.com/androidx/media
https://developer.android.com/media/media3/exoplayer
Apache License 2.0
21.7k stars 6.02k forks source link

How to: Override exo_styled_controls_play in a downstream Android library (not app) #10008

Open JessHolle opened 2 years ago

JessHolle commented 2 years ago

In trying to move to ExoPlayer 2.17.0 I discover that PlayerView is now deprecated in favor of StyledPlayerView.

Okay, so I switched all usages of PlayerView to StyledPlayerView in my code and layouts. The app built and ran. But the play/pause buttons were broken.

So I dug in and replaced the separate play and pause buttons with the combined play/pause button. That button's logic is hardwired to use exo_styled_controls_play and exo_styled_controls_pause drawables for its play and pause icons.

Okay, so great. I'll just override them in the downstream library module where I use ExoPlayer. That doesn't work in testing when I build my test app. I don't want to have every app where I use this library to separately have to perform this override. I want the override done by the library.

On a larger note, ideally I don't want to override this for the entire app. Rather I'd like to tell StyledPlayerView the DrawableRes ids that I want it to use.

Help would be appreciated here -- as I'm about to just stick with PlayerView as it doesn't have these issues.

marcbaechinger commented 2 years ago

Thanks for reporting! Let me make sure I correctly understand what you are trying to achieve:

Normally, an app depends on the exoplayer-ui module that defines the drawableRes ids for the icons in the PlayerControleView in drawable.xml. The app then can create it's own drawable.xml to override these icons with custom icons. I have done this for instance in the demo app like so and it seems to work when done in the app:

<resources>
  <drawable name="exo_styled_controls_play">@drawable/exo_icon_repeat_off</drawable>
  <drawable name="exo_styled_controls_pause">@drawable/exo_icon_repeat_one</drawable>
</resources>

With the above the player now shows different icons for play/pause as overriden in the drawable.xml.

I understand that in your case you have a drawable.xml in a library module that depends on exoplayer-ui module and on which apps depend. You now observe, that the values in your library's drawables.xml do not land in the apps's APK when the app is built and hence the the override don't take effect.

Can you let me know whether I have understood your report correctly?

JessHolle commented 2 years ago

So... live and learn.

I had created my own drawables of the same name in my library project -- and expected those to take priority over those in ExoPlayer since my library is the one that introduces the dependency on ExoPlayer.

That did not work. But putting those drawables in the app did.

But the XML rename/redirect approach above works in the library project, so this satisfies my immediate need. Thank you!

I do wonder about the special, magic drawable names here. Seems like one should be able to call some instance methods like setPlayDrawable(@DrawableRes int playDrawable) and `setPauseDrawable(@DrawableRes int pauseDrawable) that allow movie playing to be customized per instance rather than necessarily at an app-wide level.

draganstojanov commented 2 years ago

Solution with overriding drawables works well. But, i have two sets of icons, one for vertical oriented video and other for horizontal oriented. Is there any way to programmatically override drawables?

@JessHolle said:

I do wonder about the special, magic drawable names here. Seems like one should be able to call some instance methods like setPlayDrawable(@DrawableRes int playDrawable) and `setPauseDrawable(@DrawableRes int pauseDrawable) that allow movie playing to be customized per instance rather than necessarily at an app-wide level.<

I think this would be the proper solution, but until it is and if ever published, any ideas?