Failed to export AVPlayerItem

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.

+1
source share
1 answer

How I managed to do this is to usually create an array AVPlayer> AVPlayerItem> AVURLAsset. But at the same time, create an AVExportSession immediately before AVPlayer fully downloads the video from the remote URL.

AVExportSession , AVPlayer URL-. , AVPlayer . , URL- . AVExportSession . , .

, AVPlayer/AVExportSession ,

- 2018-01-10 -

, . , , , .

( AVPlayer AVPlayerItem/AVAsset). AVFoundation . . , , AVPlayer/AVAsset. AVPlayer, , AVURLAsset .

+1

All Articles