【问题标题】:Playing Encrypted Videos using AVPlayer in iOS在 iOS 中使用 AVPlayer 播放加密视频
【发布时间】:2015-07-26 11:05:01
【问题描述】:

所以,我正在尝试使用 AVplayer 播放加密视频,但播放器中没有显示任何内容。

所以我对该项目的进展如下:

1.实现了一个 AVPlayer,它将有一个 UIView 来播放 AV 内容(这对于播放非加密文件很好。)

AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:fileURL options:nil]; //local file url with custom scheme         
AVAssetResourceLoader *loader = [asset resourceLoader];
[loader setDelegate:self queue:dispatch_get_main_queue()];
self.playerItem = [AVPlayerItem playerItemWithAsset:asset];
self.player = [AVPlayer playerWithPlayerItem:self.playerItem];
[self.playerView setPlayer:self.player];

从上面的代码中,我知道我下面的资源加载器方法正在被调用:

2.实现了AVAssetResourceLoaderDelegate协议,我实现了资源加载器方法如下。

- (BOOL) resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest 
{
    NSURLRequest* request = loadingRequest.request;
    AVAssetResourceLoadingDataRequest* dataRequest = loadingRequest.dataRequest;
    AVAssetResourceLoadingContentInformationRequest* contentRequest = loadingRequest.contentInformationRequest;
    NSMutableData *data;
    //handle content request
    if (contentRequest)
    {
        contentRequest.contentType = @"mov";
        contentRequest.contentLength = movieFileLengthInBytes
        contentRequest.byteRangeAccessSupported = YES;
    }
    if (dataRequest)
    {
        DecryptedStream* readStream = [FS getReadStream:filename error:nil];
        if (readStream)
        {
            while ([readStream hasBytesAvailable])
            {
                NSInteger nRead;
                uint8_t buffer[kBufferReadSize];
                nRead = [readStream read:buffer maxLength:kBufferReadSize];
                NSMutableData *data = [NSMutableData data];
                [data appendBytes:buffer length:nRead];
                [dataRequest respondWithData:data];
            }
        }
        [loadingRequest finishLoading];
    }
    return YES;
}

基于上面的代码,以及从其他对resourceloader的Apple文档的进一步阅读:“在加载过程中,可能会要求资源加载器对象协助加载资源。例如,可能会导致需要解密的资源在资源加载器中被要求提供适当的解密密钥。您可以将委托对象分配给资源加载器对象并使用您的委托来拦截这些请求并提供适当的响应“这基本上就是我正在做的。但是,我无法播放我的视频。我确保我解密的数据是正确的(即,我可以将其写入 tmp 文件并可以播放我的 mov)。

【问题讨论】:

  • 您是否在资源加载器方法中设置了断点并逐步查看设置了哪些值,尤其是对于data
  • 是的,通过将其写入临时文件验证它是正确的数据,我可以播放我的文件。
  • 您可能想查看示例应用程序AVARLDelegateDemo
  • A-Live,我以前去过这个,我相信操作顺序几乎相同,他们使用的是一堆调度队列,而我不是。跨度>
  • 你有没有想过这个问题?

标签: ios objective-c avplayer


【解决方案1】:

我也被困在这个任务上好几天了。这并不难,但是没有足够的信息(或明确的信息)来说明如何使用AVAssetResourceLoaderAVAssetResourceLoaderDelegate。这是我在执行此任务时得到的:

  1. 如果您正在加载本地视频文件,则必须为您的fileURL 提供自定义方案才能使用AVAssetResourceLoaderDelegate

    let urlComponents = NSURLComponents(URL: fileURL, resolvingAgainstBaseURL: false)
    urlComponents?.scheme = "enc"
    let asset = AVURLAsset(URL: urlComponents!.URL!, options: nil)
    

    简单使用let asset = AVURLAsset(URL: fileURL, options: nil) 不会触发任何AVAssetResourceLoaderDelegate

  2. 在使用resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest 时,您必须为loadingRequest 提供contentInformationRequest。您可以找到视频格式列表AV Foundation Constants Reference。另一件事是contentLength。它必须设置为解密文件的大小,而不是您用来解密的文件的大小。
  3. loadingRequest 可以请求重叠数据或多次请求相同的数据。这样您就不能简单地将数据解码并粘贴到dataRequest。您将需要另一个缓冲区来解码数据。在resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest 中,检查是否有足够的数据返回或者需要解码更多。当您解码更多数据时,您可以清理之前的缓冲区以保持低内存,但请记住复制之前缓冲区中所有未使用的数据。

而且,我建议您先尝试播放未加密的文件。在跳转到加密文件之前,请确保您为 loadingRequest 加载数据的方法正常工作。最后你会发现做这样的任务非常有趣和有趣。快乐编码:)

【讨论】:

  • 嗨撒哈拉,感谢您的评论。你有代码库的链接吗?
  • 我也需要那个:)
  • @sahara108 除了第 3 点之外,我已经尝试了您的建议,因为我首先尝试使用一个小的未加密文件。我仍然无法播放视频。我的代码与添加了前两个建议的问题相同。你能帮我解决吗
  • @prabhu 你能分享你的代码吗?我去看看能不能帮上忙。
【解决方案2】:

排队

contentRequest.contentType = @"mov";

您必须设置解密内容的有效 UTI,例如

contentRequest.contentType = @"public.mpeg-4";

【讨论】:

    猜你喜欢
    • 2012-04-02
    • 2017-02-23
    • 1970-01-01
    • 1970-01-01
    • 2015-10-16
    • 2014-11-02
    • 1970-01-01
    • 2018-09-13
    • 1970-01-01
    相关资源
    最近更新 更多