Search code examples
iosvideoavfoundationuiimagepickercontroller

UIImagePickerControllerSourceTypePhotoLibrary "decoder busy" error when picking video


I encountered the problem that after picking several videos from the library (one after each other), the preview bar of the video player (UIImagePickerController) is black (but can be played back).enter image description here

After choosing the file imagePickerController:didFinishPickingMediaWithInfo: is called without UIImagePickerControllerMediaURL. After this happend once it will happen every next time the UIImagePickerController is opend. To be able to pick a new movie again, sometimes it is enough to restart the app. Sometimes the phone even has to be restarted (or maybe I am just to impatient).

I found this issue: AVPlayerItem fails with AVStatusFailed and error code "Cannot Decode". I believe it has the same background, but I have no idea how to solve the problem in this case. Further inside the app the video playback works perfectly.

The code for presenting and dismissing the UIImagePickerController is as followed.

- (IBAction)openVideoLibrary:(id)sender {
    if (_allowVideoSelection) {

        if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary] == NO || ![[UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypePhotoLibrary] containsObject:(NSString*)kUTTypeMovie]) {
            return;
        }

        UIImagePickerController *pickerController = [[UIImagePickerController alloc] init];
        [pickerController setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
        pickerController.mediaTypes = [[NSArray alloc] initWithObjects:(NSString*)kUTTypeMovie, nil];
        [pickerController setEditing:NO];
        [pickerController setDelegate:self];
        [self presentViewController:pickerController animated:YES completion:nil];
    }
}


- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    NSLog(@"info: %@", info);

    if (picker.sourceType == UIImagePickerControllerSourceTypePhotoLibrary) {
        [picker dismissViewControllerAnimated:YES completion:^{
            if (![info valueForKey:UIImagePickerControllerMediaURL]) {
                NSLog(@"Error: No media URL");
                return;
            }
            else {
                NSLog(@"Yey media");
            }
        }];
    }
}

Any ideas of a better/cleaner way to pick multiple media files after each other? The picking option is integrated in the workflow at several stages, so the images can't be picked all together.


Solution

  • Only a certain amount of AVPlayers can be running in parallel. If a UIViewController containing with a AVPlayer property is dismissed the AVPlayer is not automatically deallocated and remains alive until iOS kills it in the background. If repeatedly allocating AVPlayer without setting AVPlayerLayer.player = nil, at one point iOS doesn't allow to instantiate another AVPlayer. The error: "AVPlayerItem fails with AVStatusFailed and error code "Cannot Decode" arrises.