I use AVQueuePlayerto play a list of videos in our application. I am trying to cache videos that play AVQueuePlayerso that the video does not need to be downloaded every time.
So, after the video has finished playing, I try to save the AVPlayerItem to disk so that the next time it is initialized with a local URL.
I tried to achieve this in two ways:
- Use AVAssetExportSession
- Use AVAssetReader and AVAssetWriter.
1) AVAssetExportSession approach
This approach works as follows:
- Pay attention when it
AVPlayerItemfinishes playing with AVPlayerItemDidPlayToEndTimeNotification. - When you receive the above notification (video playback is completed, therefore it is fully downloaded), use
AVAssetExportSessionto export this video to a file on disk.
The code:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(videoDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
then
- (void)videoDidFinishPlaying:(NSNotification*)note
{
AVPlayerItem *itemToSave = [note object];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:itemToSave.asset presetName:AVAssetExportPresetHighestQuality];
exportSession.outputFileType = AVFileTypeMPEG4;
exportSession.outputURL = [NSURL fileURLWithPath:@"/path/to/Documents/video.mp4"];
[exportSession exportAsynchronouslyWithCompletionHandler:^{
switch(exportSession.status){
case AVAssetExportSessionStatusExporting:
NSLog(@"Exporting...");
break;
case AVAssetExportSessionStatusCompleted:
NSLog(@"Export completed, wohooo!!");
break;
case AVAssetExportSessionStatusWaiting:
NSLog(@"Waiting...");
break;
case AVAssetExportSessionStatusFailed:
NSLog(@"Failed with error: %@", exportSession.error);
break;
}
}
The result in the console of this code:
Failed with error: Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo=0x98916a0 {NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x99ddd10 "The operation couldn’t be completed. (OSStatus error -12109.)", NSLocalizedFailureReason=An unknown error occurred (-12109)}
2) AVAssetReader, AVAssetWriter approach
The code:
- (void)savePlayerItem:(AVPlayerItem*)item
{
NSError *assetReaderError = nil;
AVAssetReader *assetReader = [[AVAssetReader alloc] initWithAsset:assetToCache error:&assetReaderError];
//(algorithm continues)
}
This code throws an exception when trying to allocate / init AVAssetReaderwith the following information:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[AVAssetReader initWithAsset:error:] Cannot initialize an instance of AVAssetReader with an asset at non-local URL 'https://someserver.com/video1.mp4''
***
Any help is greatly appreciated.