Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 有人知道如何正确实现AVAssetResourceLoaderDelegate方法吗?_Ios_Objective C_Avfoundation - Fatal编程技术网

Ios 有人知道如何正确实现AVAssetResourceLoaderDelegate方法吗?

Ios 有人知道如何正确实现AVAssetResourceLoaderDelegate方法吗?,ios,objective-c,avfoundation,Ios,Objective C,Avfoundation,我试图哄骗AVFoundation从自定义URL读取。自定义URL的东西工作。下面的代码使用电影文件创建NSData: NSData* movieData = [NSData dataWithContentsOfURL:@"memory://video"]; 我使用以下代码设置了AVAssetResourceLoader对象: NSURL* url = [NSURL URLWithString:@"memory://video"]; AVURLAsset* asset = [[AVURLAss

我试图哄骗AVFoundation从自定义URL读取。自定义URL的东西工作。下面的代码使用电影文件创建NSData:

NSData* movieData = [NSData dataWithContentsOfURL:@"memory://video"];
我使用以下代码设置了AVAssetResourceLoader对象:

NSURL* url = [NSURL URLWithString:@"memory://video"];
AVURLAsset* asset = [[AVURLAsset alloc] initWithURL:url options:nil];
AVAssetResourceLoader* loader = [asset resourceLoader];
[loader setDelegate:self queue:mDispatchQueue];
调度队列是并发的

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

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);
但当我运行这段代码时,我得到:

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;
}
现在,我的问题是,我是否正确地实现了该方法?有人知道我所做的是否正确吗

谢谢


编辑:我正在获取的电影全部是单帧电影。

您需要传回。您正在传回
nil
。没有它,AVAssetResourceLoader就不知道如何处理您传递的数据(也就是说,它不知道它是什么类型的数据—错误消息、jpeg等)。您还应该使用
-[NSData DATA WITH CONTENTS OFURL:options:error://code>并在假设成功之前检查错误。

我只是浪费了两个小时尝试做一些非常类似的事情

原来它只在设备上工作,在iOS模拟器上不工作


我猜模拟器中的AVFoundation某种程度上与主机Mac的AVFoundation“桥接”。不幸的是,此API在OS X 10.8上不可用(根据WebCore上的一些提交,它将在OS X 10.9中可用),因此目前它在模拟器中不起作用。

我已经实现了此方法的工作版本。我花了一段时间才弄明白。但最终的应用程序现在可以运行了。这表明代码是正确的

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

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

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

我将数据块交给媒体播放器。通常一次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;
}

用户NSURLComponent和scheme=“enc”一起调用AVAssetResourceLoaderDelegate方法

let urlComponents = NSURLComponents(url: video_url, resolvingAgainstBaseURL: false)
    urlComponents?.scheme = "enc"
let avAsset = AVURLAsset(url: (urlComponents?.url)!, options: ["AVURLAssetHTTPHeaderFieldsKey": headers])
    avAsset.resourceLoader.setDelegate(self, queue: DispatchQueue(label: "AVARLDelegateDemo loader"))

现在,copyCGImageAtTime:actualTime:error:call似乎没有等待委托方法完成(委托方法正在调度队列中运行)。因此,问题变成了如何确保在进行copyCGImageAtTime:actualTime:error调用之前加载数据?请参阅上的“准备资产以供使用”-您的缩略图生成代码应位于完成处理程序块中。感谢您的评论,但当我不需要更改AVAssetResourceLoader对象时,我的代码是正确的,当我从HTTP或文件类型URL获取时。我可以得到视频帧。我试图解决的问题是如何从自定义URL获取它。我被告知AVAssetResourceLoader是密钥,但我在使用它时遇到问题。loadingRequest.request.URL是否等于@”memory://video"? 如果NSData对象是您想要的对象,您可以通过使用NSURLConnection下载数据,将其写入磁盘,然后使用
-[AVURLAsset initWithURL:options:][/code>。。。虽然这似乎是一个不完美的解决方案。URL是正确的。问题似乎是resourceLoader:shouldWaitForLoadingFrequestedResource:和copyCGImageAtTime:actualTime:error:之间的竞争条件。后者在前者完成之前完成。我希望委托方法在后者结束之前完全完成。所以我一定是用错了。我试过了,但也没用。也许这仍然是我需要的东西。但实际情况是,在委托方法完成之前,帧的获取以错误结束。委托方法的结果没有任何阻塞。要创建响应,我使用:[[NSURLResponse alloc]initWithURL:loadingRequest.request.URL MIMETYPE:@“video/mp4”ExpectedContentLength:data.length textEncodingName:nil]我认为问题不在于委托方法(至少不是我必须解决的直接问题)因为在copyCGImageAtTime:actualTime:error:call返回之前它还没有完成。两个线程之间出现了一个同步问题,我不知道如何解决。~Cthutu,你找到解决方法了吗。我被代理卡住了。我实现了它,但由于某种原因,我收到了“失败”状态。你知道吗?我这样实现了我的委托:-(BOOL)resourceLoader:。。。{NSData*data=[NSData dataWithContentsOfURL:[[NSBundle mainBundle]URLForResource:@“sample.m4v”带扩展名:@”“];nsurresponse*response=[[nsurresponse alloc]initWithURL:self.url MIMEType:@“video/x-m4v”预期内容长度:[数据长度]textcencodingname:nil];[loadingRequest finishLoadingWithResponse:响应数据:数据重定向:nil];返回YES;}您好,我有类似的实现方式,但我在擦洗视频时有时会遇到问题。有时我们来回擦洗视频时,视频像素化或显示为绿色。您是否遇到过类似问题?我让我的应用程序保持稳定。但应用程序不需要擦洗。我有点不确定如何驱动CCCrypto代码。