3

在初始化 AVAssetReader 时,我注意到大约 20% 的时间它无法开始读取。下面是代码片段,它在代码停止 20% 的时间处结束。'startReading' 调用返回 NO。

有人知道为什么会这样吗?我在这里错过了什么吗?我还应该注意到,这段代码经常被执行。可能是大约 10 个视频正在一个接一个地依次处理。因此,大约 2 或 3 个视频将无法处理,因为“startReading”调用将返回 NO。


更新:经过更多测试,我发现当应用程序进入后台时它总是失败。因此,当应用程序处于后台时,AVAssetReader 无法“开始阅读”。有没有办法让它在应用程序在后台运行时工作?

NSError *error = nil;
NSURL *srcVideo = [NSURL fileURLWithPath:[video getVideoLocation]];

NSDictionary *opts =
    [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:yes]
                                forKey:@"AVURLAssetPreferPreciseDurationAndTimingKey"];

AVAsset *avAsset = [[AVURLAsset alloc] initWithURL:srcVideo options:opts];

// Get the video track but first check for existence of track
if( [[avAsset tracksWithMediaType:AVMediaTypeVideo] count] == 0 ) {
    DLog(@"Error - no video tracks in asset");
    return;
}

AVAssetTrack *videoTrack = [[avAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];

// Set up the reading of the video track
AVAssetReader *reader = [[AVAssetReader alloc] initWithAsset:avAsset
                                                       error:&error];
NSDictionary *videoOptions =
    [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA]
                                forKey:(id)kCVPixelBufferPixelFormatTypeKey];

AVAssetReaderTrackOutput *assetReaderVideoOutput =
    [[AVAssetReaderTrackOutput alloc] initWithTrack:videoTrack
                                     outputSettings:videoOptions];

[reader addOutput:assetReaderVideoOutput];

if( ![reader startReading] ) {
    DLog(@"Error - failed to start reading video");

    DLog(@"Happens about 20% of time...");

    return;
}
4

1 回答 1

1

您可以请求时间在后台运行。(在 iOS8 上确认,并且可能也适用于早期的 iO​​S。)

为 a 添加属性UIBackgroundTaskIdentifier

@property (nonatomic) UIBackgroundTaskIdentifier bgIdentifier;

当您的应用程序将进入后台时,开始一个后台任务。

self.bgIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler: ^ {
      NSLog(@"background task expired.");
      [[UIApplication sharedApplication] endBackgroundTask:self.bgIdentifier];
      self.bgIdentifier = UIBackgroundTaskInvalid;
}];

做一些工作。(您的资产阅读器现在应该在后台阅读)。

完成后结束任务,以便系统暂停您的应用程序。

[[UIApplication sharedApplication] endBackgroundTask:self.bgIdentifier];
self.bgIdentifier = UIBackgroundTaskInvalid;

请记住,使用此方法您只会得到几分钟的时间。

于 2014-09-26T18:39:56.483 回答