I'm using AVQueuePlayer
to do playback of a list of videos in our app. I'm trying to cache the videos that are played by AVQueuePlayer
so that the video doesn't have to be downloaded each time.
So, after the video finishes playing, I attempt to save the AVPlayerItem into disk so next time it's initialized with a local URL.
I've tried to achieve this through two approaches:
- Use AVAssetExportSession
- Use AVAssetReader and AVAssetWriter.
1) AVAssetExportSession approach
This approach works like this:
- Observe when an
AVPlayerItem
finishes playing usingAVPlayerItemDidPlayToEndTimeNotification
. - When the above notification is received (a video finished playing, so it's fully downloaded), use
AVAssetExportSession
to export that video into a file in 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 console of that code is:
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)
}
That code throws an exception when trying to alloc/init the AVAssetReader
with 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 much appreciated.