SRGSSR / srgletterbox-apple

The official SRG SSR media playback experience
https://srgssr.github.io/marketing/letterbox/
MIT License
14 stars 7 forks source link

Managing MPRemoteControlCenter in SRGMediaPlayerController #214

Open va1da opened 4 years ago

va1da commented 4 years ago

Hi guys, this is more ask for help than issue.

I'm trying to setup MPRemoteControlCenter and nowPlayingInfo in my custom "mini-audio" player view which doesn't use LetterboxService but SRGMediaPlayerController and other SRG components.

I have successfully setup nowPlayingInfo and MPRemote actions but it doesn't work properly: on Lock Screen all buttons are disabled and in control center it usually stops working after first action.

Is there some way how to enable MPRemoteControlCenter events easily for SRGMediaPlayerController? Or is there some trick how to setup MPRemoteControlCenter properly? I studied your code in LetterboxService and tried everything.

Thanks for any suggestion.

I'm attaching my custom view code.

MinimizedAudioPlayerView.zip

defagos commented 4 years ago

Hi!

MPRemoteControlCenter and MPNowPlayingInfo are quite tricky to implement. We even fixed issues lately in Letterbox 3.0.0.

We do not provide any helpers or direct integration for SRG Media Player, as these APIs are entirely separated from AVFoundation. So you are basically on your own. Good news is that the API is very simple, bad news is that it is extremely poorly documented, especially regarding how it must be used and which parameters have an effect or not.

Having a look at how we do it in SRGLetterboxService is a good start. I’ll have a look at your implementation to see if something obvious explains the issues you encounter. I’ll keep in touch.

defagos commented 4 years ago

I had a quick look at your implementation, which seems based on our old pre-3.0.0 code. This is not why your implementation does not work (ours worked but had some issues), but at least I would recommend you to have a look at how Letterbox service 4.0.0 works.

Before I investigate your code further, could you please tell me why you are avoiding Letterbox service in the first place, so that I better understand what you are trying to achieve? This is of course legitimate (we even provide an API to disable control center integration entirely), but I didn’t see in which way your implementation would differ from ours, so I was just asking myself why implementing it yourself was worth the trouble.

Thanks in advance for the clarifications.

va1da commented 4 years ago

Thanks for answer. I will study most recent sources. I have github "SRGSSR/srgletterbox-apple" "4.0.0" in my Cartfile.resolved. Where I can get most recent sources?

Regarding why I'm doing it this way: I need to achieve this: Screenshot 2020-04-29 at 14 35 49

So I don't need video player: I just need controlls to play audio. Idea behind this is to use less space when there is no video anyway. If my problem could be somehow solved by using LetterboxService directly it would be great.

Maybe you can make my minimized-audio view part of Letterbox as an option and connect it to LetterboxService. It would be amazing.

defagos commented 4 years ago

Hi,

I will study most recent sources. I have github "SRGSSR/srgletterbox-apple" "4.0.0" in my Cartfile.resolved. Where I can get most recent sources?

I thought you got your inspiration from an older version since, as of version 3.0.0, fake command actions are only kept for compatibility with iOS 11 and below, which is not really the case in the code you sent us.

To answer your question, all Letterbox code is publicly available on GitHub, so the latest stable version can always be seen on master.

I need to achieve this:

Great, that means you can (and should) use SRGLetterboxService. SRGLetterboxController can be used without any SRGLetterboxView. We do not provide any standard player bar, though: Since applications will want to have their own look and feel, we don't provide any standard such component at the moment.

To implement your own control bar, you need to listen to the playback and media metadata change notifications (SRGLetterboxMetadataDidChangeNotification and SRGLetterboxPlaybackStateDidChangeNotification) and register for periodic time updates for the slider (-addPeriodicTimeObserverForInterval:queue:block). Then update your UI accordingly, based on playback state and metadata information available from the Letterbox controller.

We have a player bar in Play SRG, you can look at its source code for an example. Our player bar does a bit more since we support background video playback and interaction with Google Cast, so it might be better for you to start with a smaller implementation. I also see that we are still cheating by accessing Letterbox internals. You should not have to do that (and neither should we; I'll write a GitHub issue to remove this bit of sorcery).

This way you avoid having to integrate with the control center and can benefit from further Letterbox updates regarding control center support directly (e.g. we recently added the ability to seek directly from the control center).

Just get in touch with us if you need more help in implementing this feature.

Best regards.

va1da commented 4 years ago

Got it.

Just one more question: is there any way I can connect SRG controls (like SRGTimeSlider) to LetterboxControler? Rather then implementing them myself from scratch?

pyby commented 4 years ago

Sadly, not with an official public way.

We have a private property mediaPlayerController on SRGLetterboxController, we do not expose for the reason we documented "Do not alter properties of this player controller, this could lead to undefined behavior. Only use in a readonly way or to register observers".

From what you want, you would like to do like SRGLetterboxView: use the SRGTimeSlider from SRGMediaPlayer, and just connect to the mediaPlayerController property.

All is internal today. We should investigate with @defagos to add a SRGLetterboxTimeSlider (inherits SRGTimeSlider with a property to connect to the SRGLetterboxController. It would be more safe for you, that working with private letterbox property.

First time a SRG application is asking to do a custom player with the seek bar. Thank you.

va1da commented 4 years ago

Great idea. Only two controls I'm using are slider and SRGPlaybackButton. Thanks.

va1da commented 4 years ago

Hi guys, last question. If you decide to make SRGLetterboxSlider and playButton, do you have any timeframe when you will be able to do it.

I need to finish my mini-audio player this week, so if you will not have time to make it I will make my own.

Thanks.

defagos commented 4 years ago

Sorry for the late answer, we were quite busy working on our products.

You must do it on your own, sorry. This requires further API discussions from us, and we clearly didn't have the time this week with all the work expected from us.

I'll discuss this with our PO so that we can free some time to work on it next sprint. In the meantime, the easiest for you is to cheat like we do in Play, by accessing the mediaPlayerController private property, and connecting a slider and playback button to it.

Exposing this property publicly would be an option (this would avoid us having to create similar public Letterbox components), and while I might like the idea, I prefer evaluating the risks and rewards with @pyby first.

va1da commented 4 years ago

OK, no problem, thanks for info.

defagos commented 4 years ago

I gave some more thought about this issue. I think we should expose the underlying MP controller. This would make KVO registrations possible for many values which should now be KV-observed for changes (e.g. timeRange or live properties). Same for notifications. Having the same mechanisms for Letterbox is redundant and can lead to some events being lost (see #181).

Of course this needs to be properly documented so that people only use the controller for intended purposes. But I don't see API risks, at least not in the same way I saw them in the past. It is clear that if you are using LB all playback methods are on the controller anyway.

It is also likely we should then remove LB notifications (e.g. SRGLetterboxPlaybackStateDidChangeNotification). This chpotange would be breaking, but it is probably clearer and safer than keeping both MP- and LB-level notifications. This must be investigated and discussed further.