Cth*_*utu 10 objective-c avfoundation ios
我试图哄骗AVFoundation从自定义URL读取.自定义网址的工作原理.下面的代码创建一个带有电影文件的NSData:
NSData* movieData = [NSData dataWithContentsOfURL:@"memory://video"];
Run Code Online (Sandbox Code Playgroud)
我使用以下代码设置了一个AVAssetResourceLoader对象:
NSURL* url = [NSURL URLWithString:@"memory://video"];
AVURLAsset* asset = [[AVURLAsset alloc] initWithURL:url options:nil];
AVAssetResourceLoader* loader = [asset resourceLoader];
[loader setDelegate:self queue:mDispatchQueue];
Run Code Online (Sandbox Code Playgroud)
调度队列是并发的.
然后我尝试从电影中提取第一帧:
AVAssetImageGenerator* imageGen = [AVAssetImageGenerator assetImageGeneratorWithAsset:asset];
CMTime time = CMTimeMakeWithSeconds(0, 600);
NSError* error = nil;
CMTime actualTime;
CGImageRef image = [imageGen copyCGImageAtTime:time
actualTime:&actualTime
error:&error];
if (error) NSLog(@"%@", error);
Run Code Online (Sandbox Code Playgroud)
但是,当我运行此代码时,我会得到:
2013-02-21 10:02:22.197 VideoPlayer[501:907] Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo=0x1f863090 {NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x1e575a90 "The operation couldn’t be completed. (OSStatus error 268451843.)", NSLocalizedFailureReason=An unknown error occurred (268451843)}
Run Code Online (Sandbox Code Playgroud)
委托方法的实现是:
- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest
{
NSData* data = [NSData dataWithContentsOfURL:loadingRequest.request.URL];
[loadingRequest finishLoadingWithResponse:nil data:data redirect:nil];
return YES;
}
Run Code Online (Sandbox Code Playgroud)
现在,我的问题是,我是否正确实施了该方法?有谁知道我做的正确吗?
谢谢.
编辑:我正在拍摄的电影是一部单帧电影.
我已经实现了这个方法的工作版本.我花了一段时间才弄明白.但现在的应用程序正常运行.这表明代码没问题.
我的应用程序包含一个媒体文件,我不想在未加密的包中发送.我想动态解密文件.(一次一块).
该方法必须响应内容请求(告诉玩家它正在加载什么)和数据请求(给玩家一些数据).第一次调用该方法时,始终存在内容请求.然后会有一系列数据请求.
玩家很贪心.它总是要求整个文件.您没有义务提供.它要求整个蛋糕.你可以给它一片.
我交出媒体播放器的数据块.通常一次1 MB.用特殊情况处理较小的最终块.通常会按顺序询问块.但是你也需要能够处理无序请求.
- (BOOL) resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest
{
NSURLRequest* request = loadingRequest.request;
AVAssetResourceLoadingDataRequest* dataRequest = loadingRequest.dataRequest;
AVAssetResourceLoadingContentInformationRequest* contentRequest = loadingRequest.contentInformationRequest;
//handle content request
if (contentRequest)
{
NSError* attributesError;
NSString* path = request.URL.path;
_fileURL = request.URL;
if (_fileHandle == nil)
{
_fileHandle = [NSFileHandle fileHandleForReadingAtPath:path];
}
// fire up the decryption here..
// for example ...
if (_decryptedData == nil)
{
_cacheStart = 1000000000;
_decryptedData = [NSMutableData dataWithLength:BUFFER_LENGTH+16];
CCCryptorCreate(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, [sharedKey cStringUsingEncoding:NSISOLatin1StringEncoding], kCCKeySizeAES256, NULL, &cryptoRef);
}
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:&attributesError];
NSNumber *fileSizeNumber = [fileAttributes objectForKey:NSFileSize];
_fileSize = [fileSizeNumber longLongValue];
//provide information about the content
_mimeType = @"mp3";
contentRequest.contentType = _mimeType;
contentRequest.contentLength = _fileSize;
contentRequest.byteRangeAccessSupported = YES;
}
//handle data request
if (dataRequest)
{
//decrypt a block of data (can be any size you want)
//code omitted
NSData* decodedData = [NSData dataWithBytes:outBuffer length:reducedLen];
[dataRequest respondWithData:decodedData];
[loadingRequest finishLoading];
}
return YES;
}
Run Code Online (Sandbox Code Playgroud)
您需要创建一个 NSURLResponse 对象来传回。你正路过回来nil
。没有它,AVAssetResourceLoader 不知道如何处理您交给它的数据(也就是说,它不知道它是什么类型的数据 - 错误消息、jpeg 等)。在假设成功之前,您还应该真正使用-[NSData dataWithContentsOfURL:options:error:]
并检查错误。
归档时间: |
|
查看次数: |
8173 次 |
最近记录: |