AVAsset
Facts about AVAsset
- Made up of “Tracks” : Could be audio or video track.
- Provides information about the collection of audio tracks and video tracks as a whole, including title, duration, size, etc.
- Not tied to any file format
- Initializaing an asset doesn’t mean it’s ready to use. Therefore use a block for asynchronous usage.
A. Preparing AVAsset
1. Typical Scenario
// 1. Get File Manager
NSFileManager *filemgr = [NSFileManager defaultManager];
// 2. Get vid.mov inside tmp directory
NSString *fileName = [NSTemporaryDirectory() stringByAppendingPathComponent:@"vid.mov"];
// 3. Get a NSURL version of the filename
NSURL *url = [NSURL fileURLWithPath: fileName];
// 4. Create an asset with the URL
AVURLAsset *anAsset = [[AVURLAsset alloc] initWithURL:url options:nil];
2. Initialize for precise timing
For just playing, probably no need for passing the option. However if I want to add the asset to an AVMutableComposition, I may need to.
NSDictionary *options = @{ AVURLAssetPreferPreciseDurationAndTimingKey : @YES };
AVURLAsset *anAssetToUseInAComposition = [[AVURLAsset alloc] initWithURL:url options:options];
B. Using AVAsset
Running initWithURL:options:
does not mean that the asset is prepared to be accessed. Therefore must use loadValuesAsynchronouslyForKeys:completionHandler:
to access the asset asynchronously.
1. Accessing the Asset’s duration
// ..
// Continued from above...
AVURLAsset *anAsset = [[AVURLAsset alloc] initWithURL:url options:nil];
NSArray *keys = @[@"duration"];
[asset loadValuesAsynchronouslyForKeys:keys completionHandler:^() {
// This block is run after the "duration" value is loaded
NSError *error = nil;
AVKeyValueStatus tracksStatus = [asset statusOfValueForKey:@"duration" error:&error];
switch (tracksStatus) {
case AVKeyValueStatusLoaded:
[self updateUserInterfaceForDuration];
break;
case AVKeyValueStatusFailed:
[self reportError:error forAsset:asset];
break;
case AVKeyValueStatusCancelled:
// Do whatever is appropriate for cancelation.
break;
}
}];
2. Getting an image capture
AVAsset anAsset = <#Get an asset#>;
if ([[anAsset tracksWithMediaType:AVMediaTypeVideo] count] > 0) {
AVAssetImageGenerator *imageGenerator = [AVAssetImageGenerator assetImageGeneratorWithAsset:anAsset];
// Implementation continues...
}