Reputation: 1489
While initializing AVAssetReader I noticed that about 20% of the time it fails to start reading. Below is the code snippet which ends where the code stops 20% of time. The 'startReading' call returns NO.
Anybody know why that may be happening? Am I missing anything here? I should also note that this code gets executed quite often. It could be about 10 videos that are being processed sequentially one after another. So about 2 or 3 videos would fail to process because of the 'startReading' call would return NO.
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;
}
Upvotes: 3
Views: 1316
Reputation: 3216
You can request time to run in the background. (confirmed on iOS8, and might work on earlier iOS as well.)
Add a property for a UIBackgroundTaskIdentifier
.
@property (nonatomic) UIBackgroundTaskIdentifier bgIdentifier;
When your app will enter the background, begin a background task.
self.bgIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler: ^ {
NSLog(@"background task expired.");
[[UIApplication sharedApplication] endBackgroundTask:self.bgIdentifier];
self.bgIdentifier = UIBackgroundTaskInvalid;
}];
Do some work. (Your asset reader should now be reading in the background).
End the task when you've finished, so that the system can suspend your app.
[[UIApplication sharedApplication] endBackgroundTask:self.bgIdentifier];
self.bgIdentifier = UIBackgroundTaskInvalid;
Keep in mind you will only get a few minutes' time using this method.
Upvotes: 1