41

I'm trying to load a video file into my iPad app as an AVURLAsset, using the asynchronous-loading stuff to wait for it to be ready. Problem is, when I run it, I get a completely generic "failure" error message that I have no idea what to do with. The video works if I hand it to an MPMoviePlayerController, but AVURLAsset seems to refuse to have anything to do with it.

Code:

asset = [[AVURLAsset alloc] initWithURL:[NSURL URLWithString:[docPath stringByAppendingPathComponent:@"video.mov"]] options:nil];
[asset loadValuesAsynchronouslyForKeys:[NSArray arrayWithObject:@"tracks"] completionHandler:^{
    dispatch_async(dispatch_get_main_queue(), ^{
        [self composeIfReady];
    });
}];

...

- (void)composeIfReady
{
    NSError *error = nil;
    if([asset statusOfValueForKey:@"tracks" error:&error] == AVKeyValueStatusFailed)
        NSLog(@"error loading: %@", [error description]);
    if(error == nil)
        NSLog(@"okay awesome");
}

The output:

error loading: Error Domain=AVFoundationErrorDomain Code=-11800 "The operation couldn’t be completed. (AVFoundationErrorDomain error -11800.)" UserInfo=0x1696f0 {NSUnderlyingError=0x169a40 "The operation couldn’t be completed. (OSStatus error -12936.)"}

-11800, by the way, is the error code for "unknown error". Kind of a dead end. Any ideas? Is there something I should be setting up before I try to load the asset?

Noah Witherspoon
  • 57,021
  • 16
  • 130
  • 131

3 Answers3

116

Solved. The trick: use fileURLWithPath:, not URLWithString:. Apparently the difference is really, really significant.

Noah Witherspoon
  • 57,021
  • 16
  • 130
  • 131
  • 1
    Thank you verryy much!!! I do realize now that the difference is significant because it needs an absolute URL to the file and so the relative URL (/var/mobile/...) given by URLWithString does not work. – Chintan Patel May 22 '12 at 10:08
  • For me the callback just never got called when using `URLWithString`—not even for telling me an error. With `fileURLWithPath` it works, though. This is seriously flawed... -.- – Frank Rupprecht Feb 10 '15 at 16:29
  • fileURLWithPath is for play the audio from the bundle but i am not able to play the audio from the url. – Deepak Saki Feb 21 '17 at 11:01
  • I am also getting one issue, please look into this and advise: https://stackoverflow.com/questions/51239586/error-domain-avfoundationerrordomain-code-11800-the-operation-could-not-be-com – user2786 Jul 09 '18 at 12:52
6

If anyone is still having issues with this even after using fileURLWithPath, try requesting NSTimeIntervals in the time array if you are using int(s).

This does not work:

    NSMutableArray *playbackTimes = [NSMutableArray array];
    for (int i = 0; i <= 10; i ++) {
        [playbackTimes addObject:@(i)];
    }

    [self.videoPlayer requestThumbnailImagesAtTimes:playbackTimes timeOption:MPMovieTimeOptionNearestKeyFrame];

This works:

    NSMutableArray *playbackTimes = [NSMutableArray array];
    for (int i = 0; i <= 10; i ++) {
         [playbackTimes addObject:@((NSTimeInterval)i)];
     }

     [self.videoPlayer requestThumbnailImagesAtTimes:playbackTimes timeOption:MPMovieTimeOptionNearestKeyFrame];
Edwin Iskandar
  • 4,119
  • 1
  • 23
  • 24
6

If you are using -[NSURL fileURLWithPath:] to create the URL and still get the same error.

Check the AVURLAssetReferenceRestrictionsKey, Your local m3u8 may failed to play if it contains remote resource.

Set the value to @(AVAssetReferenceRestrictionForbidNone) should solve the problem.

naituw
  • 1,087
  • 10
  • 14