loadValuesAsynchronouslyForKeys和多个值加载

Pet*_*ich 6 iphone objective-c avfoundation ios4

我想异步加载持续时间,时间(创建视频的时间戳)和资产的区域设置.

Apple显示的所有示例代码'loadValuesAsynchronouslyForKeys:keys'始终只显示一个密钥.即:

NSURL *url = aUrl; 
AVAsset asset = [[AVURLAsset alloc] initWithURL:url options:nil];

NSArray *keys = [NSArray arrayWithObject:@"duration"];
[asset loadValuesAsynchronouslyForKeys:keys completionHandler:^() {

NSError *error = nil;
AVKeyValueStatus durationStatus = [asset statusOfValueForKey:@"duration" error:&error];

switch (durationSatus) {
    case AVKeyValueStatusLoaded:
            // Read duration from asset
            CMTime assetDurationInCMTime = [asset duration];            
        break;

        case AVKeyValueStatusFailed:
            // Report error
        break; 

        case AVKeyValueStatusCancelled:
        // Do whatever is appropriate for cancelation   
    }
}];
Run Code Online (Sandbox Code Playgroud)

我可以假设如果一个项的状态是'AVKeyValueStatusLoaded',那么在完成块中可以同时读取其他值吗?即:

[asset tracks]
[asset commonMetadata];
[asset duration]
Run Code Online (Sandbox Code Playgroud)

Eli*_*oij 6

不,你不能这么认为.我的一种方法看了两个键,可玩和持续时间,我发现可玩性通常可用,而持续时间尚未.我因此将loadValuesAsynchronouslyForKeys:代码移动到一个单独的方法shouldSave:.我在一个叫做save​​WithDuration:的方法中从一个计时器调用的shouldSave:方法.一旦saveWithDuration:收到非零持续时间,它就会继续并保存东西.为了避免等待太久,我现在使用了一个尝试计数器 - 将来,我将对此进行优化(您会注意到此时并未真正使用错误实例)

- (void)shouldSave:(NSTimer*)theTimer {
NSString * const TBDuration = @"duration";
NSString * const TBPlayable = @"playable";

__block float theDuration = TBZeroDuration;
__block NSError *error = nil;
NSArray *assetKeys = [NSArray arrayWithObjects:TBDuration, TBPlayable, nil];

[_audioAsset loadValuesAsynchronouslyForKeys:assetKeys completionHandler:^() {

    AVKeyValueStatus playableStatus = [_audioAsset statusOfValueForKey:TBPlayable error:&error];
    switch (playableStatus) {
        case AVKeyValueStatusLoaded:
            //go on
            break;
        default:
            return; 
    }

    AVKeyValueStatus durationStatus = [_audioAsset statusOfValueForKey:TBDuration error:&error];
    switch (durationStatus) {
        case AVKeyValueStatusLoaded:
            theDuration = CMTimeGetSeconds(_audioAsset.duration);
            break;
        default:
            return;
    }
}];

NSUInteger attempt = [[[theTimer userInfo] objectForKey:TBAttemptKey] integerValue];
attempt++;
[self saveWithDuration:theDuration attempt:attempt error:&error];
Run Code Online (Sandbox Code Playgroud)

}


tba*_*tba 2

从技术上讲你不能。loadValuesAsynchronouslyForKeys:completionHandler:的文档说

\n\n
\n

您在键中指定的键的完成状态不一定相同\xe2\x80\x94,某些可能已加载,而其他可能已失败。您必须单独检查每个键的状态。

\n
\n\n

在实践中,我认为这通常是一个安全的假设 - 正如您所指出的,Apple 的 StitchedStreamPlayer 示例项目仅查看第一个密钥的状态。

\n