AVAssetResourceLoaderDelegate方法不在设备上工作

时间:2014-10-30 09:55:51

标签: ios avfoundation

我一直在制作一个简单的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_asyncdispatch_get_main_queue区块中,但是解决我的问题没有运气。

目前,我的上述代码未被任何调度队列块包围。

对这个问题的任何想法?

3 个答案:

答案 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];