有谁知道如何正确实现AVAssetResourceLoaderDelegate方法? [英] Does anyone know how to implement the AVAssetResourceLoaderDelegate methods correctly?

查看:295
本文介绍了有谁知道如何正确实现AVAssetResourceLoaderDelegate方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图哄骗AVFoundation从自定义URL读取。自定义网址的工作原理。下面的代码创建一个带有电影文件的NSData:

I am trying to coax AVFoundation to read from a custom URL. The custom URL stuff works. The code below creates a NSData with a movie file:

NSData* movieData = [NSData dataWithContentsOfURL:@"memory://video"];

我使用以下代码设置了AVAssetResourceLoader对象:

I've set up a AVAssetResourceLoader object using the following code:

NSURL* url = [NSURL URLWithString:@"memory://video"];
AVURLAsset* asset = [[AVURLAsset alloc] initWithURL:url options:nil];
AVAssetResourceLoader* loader = [asset resourceLoader];
[loader setDelegate:self queue:mDispatchQueue];

调度队列是并发的。

然后我尝试从电影中提取第一帧:

I then try to extract the first frame from the movie:

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);

但当我运行此代码时,我得到的代码:

But when I run this but of code I get:

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)}

委托方法的实现是:

- (BOOL)resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(AVAssetResourceLoadingRequest *)loadingRequest
{
    NSData* data = [NSData dataWithContentsOfURL:loadingRequest.request.URL];
    [loadingRequest finishLoadingWithResponse:nil data:data redirect:nil];
    return YES;
}

现在,我的问题是,我是否正确实施了该方法?有谁知道我做的是否正确?

Now, my question is, am I implementing the method correctly? Does anyone know if what I am doing correct?

谢谢。

编辑:我正在拍摄的电影它的整体是单帧电影。

The movie I am fetching in its entirety is a single frame movie.

推荐答案

我已经实现了这种方法的工作版本。我花了一段时间才弄明白。但现在的应用程序正常工作。这表明代码没问题。

I have implemented a working version of this method. It took me a while to figure out. But the resulting app now works. Which suggests that the code is okay.

我的应用程序包含一个媒体文件,我不想在未加密的软件包中发送。我想动态解密文件。 (一次一块)。

My app includes a media file which I did not want to ship in the package unencrypted. I wanted to dynamically decrypt the file. (a block at a time).

该方法必须响应内容请求(告诉玩家它正在加载什么)
和数据请求(给玩家一些数据)。第一次调用该方法时,始终存在内容请求。然后会有一系列数据请求。

The method has to respond both to the content request (tell the player what it is loading) And to data requests (give the player some data). The first time the method is called, there is always a content request. Then there will be a series of data requests.

玩家贪婪。它总是要求整个文件。您没有义务提供。它要求整个蛋糕。你可以给它一片。

The player is greedy. It always asks for the entire file. You are not obliged to provide that. It asks for the whole cake. You can give it one slice.

我交出媒体播放器的数据块。通常一次1 MB。用特殊情况处理较小的最终块。通常会按顺序询问块。但是你也需要能够处理无序请求。

I hand the media player blocks of data. Usually 1 MB at a time. With a special case to handle the smaller final block. Blocks are usually asked for in sequence. But you need to be able to cope with out-of-sequence requests too.

- (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;
}

这篇关于有谁知道如何正确实现AVAssetResourceLoaderDelegate方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆