我一直在制作一个简单的AVPlayer
来播放加密的HLS
媒体。
我正在使用AVAssetResourceLoaderDelegate
来处理密钥检索过程,因此可以使用有效密钥播放加密媒体。
该程序在模拟器上运行良好,但在设备上根本不起作用。
以下是代码:
- (void) playUrlByAVPlayer:(NSString *) videoUrl
{
NSURL *streamURL = [NSURL URLWithString:videoUrl];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:streamURL options:nil];
[asset.resourceLoader setDelegate:self queue:dispatch_get_main_queue()];
self.playerItem = [AVPlayerItem playerItemWithAsset:asset];
self.player = [AVPlayer playerWithPlayerItem:self.playerItem];
self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
[self.playerLayer setFrame:self.view.frame];
[self.view.layer addSublayer:self.playerLayer];
[self.player play];
}
经过一些调试后,我意识到委托方法shouldWaitForLoadingOfRequestedResource
从未在设备上调用过。
我已阅读其他相关问题:
AVAssetResourceLoaderDelegate not being called
AVAssetResourceLoaderDelegate - Only requests first two bytes?
我尝试将所有代码括在dispatch_async
,dispatch_get_main_queue
区块中,但是解决我的问题没有运气。
目前,我的上述代码未被任何调度队列块包围。
对这个问题的任何想法?
答案 0 :(得分:5)
如果你看一下他们展示bipbop.m3u8 HLS播放的Apple示例代码,你会发现他们正在使用掩码来实现真正的http请求:" http:/host/bipbop.m3u8" => " custom_scheme:/host/bipbop.m3u8" 应该使用播放列表子资源进行相同的操作。
否则,avplayer会忽略AVAssetResourceLoaderDelegate并直接加载数据。
您需要实现某种映射:
NSString* videoUrl = @"fake_scheme://host/video.m3u8";
NSURL *streamURL = [NSURL URLWithString:videoUrl];
答案 1 :(得分:3)
正如我在其他线程中提到的,AVAssetResourceLoaderDelegate仅在我们使用“非标准/非保留”url方案时才有效。 HTTP,HTTPS等被视为保留URL方案,如果URL具有其中一种方案,iOS将不会进行委托调用。我最终做的是使用my_own_http作为http urls,使用my_own_https作为https网址。在我做出改变后,它运作良好。如您所知,这会使您的播放列表无法在其他设备上使用。
答案 2 :(得分:2)
在您的委托shouldWaitForLoadingOfRequestedResource
中,将网址方案更改回http:
NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:loadingRequest.request.URL resolvingAgainstBaseURL:NO];
urlComponents.scheme = @"http";
NSMutableURLRequest *mutableLoadingRequest = [loadingRequest.request mutableCopy];
[mutableLoadingRequest setURL:urlComponents.URL];