繁体   English   中英

在iOS中使用AVPlayer播放加密视频

[英]Playing Encrypted Videos using AVPlayer in iOS

所以,我正在尝试使用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;
}

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

我也坚持了几天这个任务。 这并不困难,但是没有足够的信息(或清楚信息)如何使用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您必须为contentInformationRequest提供loadingRequest 您可以找到视频格式AV基础常量参考列表。 另一件事是contentLength 必须将其设置为解密文件的大小,而不是您用于解密的文件。
  3. loadingRequest可以请求重叠数据或多次请求相同的数据。 这样您就无法简单地将数据解码并粘贴到dataRequest 您将需要另一个缓冲区来解码数据。 resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest ,检查是否有足够的数据要返回,或者您需要解码更多。 解码更多数据时,可以清理以前的缓冲区以保持较低的内存,但请记住复制前一个缓冲区中的任何未使用的数据。

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

在线

contentRequest.contentType = @"mov";

你必须设置有效的解密内容UTI

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM