SRGSSR / srgmediaplayer-apple

An advanced media player library, simple and reliable
MIT License
158 stars 33 forks source link

Play method using AVPlayerItem #42

Closed tooolbox closed 6 years ago

tooolbox commented 6 years ago

Issue overview

Description of the problem

Using SRG Media Player, there is no way to handle authentication issues on a stream. Because the API only exposes playing URLs, options like this one for setting auth headers on the AVURLAsset are unavailable.

Environment information

Reproducibility

Code sample

All of the playing methods seem to trace down to this:

- (void)prepareToPlayURL:(NSURL *)URL
                  atTime:(CMTime)time
            withSegments:(NSArray<id<SRGSegment>> *)segments
           targetSegment:(id<SRGSegment>)targetSegment
                userInfo:(NSDictionary *)userInfo
       completionHandler:(void (^)(void))completionHandler
{
    ...
    AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithURL:URL];
    self.player = [AVPlayer playerWithPlayerItem:playerItem];
    ...
}

Suggestions

Refactor the API to expose play methods that deal directly with the AVPlayerItem, giving users of the library a way to controls headers on requests.

...I would probably attempt a PR but my Objective-C is rusty, and for the moment, all I need is HTTP Basic Auth so I can hack it into the URL, so to speak.

defagos commented 6 years ago

I would rather investigate the possibility to do this with a custom AVAssetResourceLoader instead.

In fact, custom resource loader support is something we have planned for this year (and internally already implemented as a proof-of-concept). We should check whether request headers, for example, can be customized using a resource loader, and without using private stuff (which AVURLAssetHTTPHeaderFieldsKey seems to be) . If the answer is positive, I think this is the proper way to go.

In the meantime, I would suggest you use another approach if you can. An NSURLProtocol subclass might be a possibility as well.

tooolbox commented 6 years ago

I get what you're saying, and I get how you would want to avoid private stuff.

However, the specific example I give is not the only reason to expose an AVPlayerItem-based play method. I am sure I could spend a couple of hours searching the docs and give you a dozen useful things that you could do by exposing this, and they would all be much easier than messing with AVAssetResourceLoader or NSURLProtocol.

Here's an example: blocking your HLS streams from loading over a cell connection. Per apple's docs you can do this by setting the AVURLAssetAllowsCellularAccessKey on your AVURLAsset. I would much rather do that than implement my own NSURLProtocol.

Can you tell me a reason why you shouldn't expose the AVPlayerItem (and thereby the AVAsset) to consumers of your library? This seems like an unnecessary limitation, unlike controlling access to the AVPlayer.

defagos commented 6 years ago

The limitation initially existed for API simplicity, but providing an additional playback method expecting an AVPlayerItem should not be a problem. Your AVURLAssetAllowsCellularAccessKey example proves this is enables legitimate uses of public APIs we should allow.

Thanks for your input.

defagos commented 6 years ago

I implemented AVPlayerItem-based methods on the feature/player-item-playback branch.

I'll need to review and discuss it with the team first, then hopefully merge it back into develop.

tooolbox commented 6 years ago

Awesome @defagos thank you!

I appreciate a lot that your team has open-sourced your work on this player; it's the only one I was able to find that was customizable and yet fully-featured, and it saved me a lot of time on a recent project.

defagos commented 6 years ago

The new AVPlayerItem-based playback APIs are readily available on develop, and will be officially delivered in version 2.3.

Glad our player was helpful, and thanks again for your help and suggestions!