I would like to cache progressive-download videos using AVPlayer. How can I save an AVPlayer's item to disk? I'm trying to use AVAssetExportSession on the player's currentItem (which is fully loaded). This code is giving me "AVAssetExportSessionStatusFailed (The operation could not be completed)" :
AVAsset *mediaAsset = self.player.currentItem.asset;
AVAssetExportSession *es = [[AVAssetExportSession alloc] initWithAsset:mediaAsset presetName:AVAssetExportPresetLowQuality];
NSString *outPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"out.mp4"];
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager removeItemAtPath:outPath error:NULL];
es.outputFileType = @"com.apple.quicktime-movie";
es.outputURL = [[[NSURL alloc] initFileURLWithPath:outPath] autorelease];
NSLog(@"exporting to %@",outPath);
[es exportAsynchronouslyWithCompletionHandler:^{
NSString *status = @"";
if( es.status == AVAssetExportSessionStatusUnknown ) status = @"AVAssetExportSessionStatusUnknown";
else if( es.status == AVAssetExportSessionStatusWaiting ) status = @"AVAssetExportSessionStatusWaiting";
else if( es.status == AVAssetExportSessionStatusExporting ) status = @"AVAssetExportSessionStatusExporting";
else if( es.status == AVAssetExportSessionStatusCompleted ) status = @"AVAssetExportSessionStatusCompleted";
else if( es.status == AVAssetExportSessionStatusFailed ) status = @"AVAssetExportSessionStatusFailed";
else if( es.status == AVAssetExportSessionStatusCancelled ) status = @"AVAssetExportSess开发者_StackOverflowionStatusCancelled";
NSLog(@"done exporting to %@ status %d = %@ (%@)",outPath,es.status, status,[[es error] localizedDescription]);
}];
How can I export successfully? I'm looking into copying mediaAsset into an AVMutableComposition, but haven't had much luck with that either.
Thanks!
PS: Here are some questions from people trying to accomplish the same thing (but with MPMoviePlayerController):
Cache Progressive downloaded content in MPMoviePlayerController
Simultaneously stream and save a video?
Caching videos to disk after successful preload by MPMoviePlayerController
I'm not using the iOS 4.3 SDK yet, but I'd be curious to know the value of mediaAsset.exportable under 4.3, as described here:
http://developer.apple.com/library/ios/#releasenotes/AudioVideo/RN-AVFoundation/_index.html#//apple_ref/doc/uid/TP40010717-CH1-SW4
I've tried a number of modifications to your code, such as getting the preset name and file type from the list of those available, but I'm getting the same error you are.
So, I decided to try a lower-level framework, since the documentation states that you can connect an AVAssetReader and an AVAssetWriter to get the same effect as an AVAssetExportSession except with more control. However, the following code:
NSError *readerError = nil;
AVAssetReader *reader =
[AVAssetReader assetReaderWithAsset:mediaAsset error:&readerError];
if (readerError) NSLog(@"Error instantiating asset reader: %@",
[readerError localizedDescription]);
Gives the following output:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '*** -[AVAssetReader initWithAsset:error:] Cannot initialize an instance of
AVAssetReader with an asset at non-local URL 'http://example.com/test.mp3''
Note that I tested this with a working URL but have replaced it with a fake one above. This looks to me like iOS doesn't support the functionality we're looking for. For all I know AVAssetExportSession uses an AVAssetReader under the hood and just reports a much less descriptive error when it fails. It sure would be nice if they'd just document it as such. The docs for AVAssetExportSession don't mention anything about the asset needing to be local:
http://developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVAssetExportSession_Class/Reference/Reference.html#//apple_ref/occ/cl/AVAssetExportSession
I know this isn't much of an answer, but it moves the investigation down the road a little. I'm still really hoping there's some way to do this, because clearly we are not alone in wanting the feature.
For sure it doesn't work on iOS 4.X. Has any one tried make it working on iOS 5 Beta?
It seems to be a missing feture. There isn't stated anywhere in the documentation that it doesn't support data access for networked media. Even error messages and other stuff in API befeviour weird and seems to be incomplete, when trying to run it. Most likely it will be supported soon.
精彩评论