Domanda

I'm trying to crop and merge several videos in app. I'm having an issue in the final part of the steps where I need to save the video to camera reel and UIVideoAtPathIsCompatibleWithSavedPhotosAlbum is returning NO. Any idea what's going wrong?

- (void)video {
    self.shouldRotate = NO;
    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
    imagePicker.delegate = self;
    imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    imagePicker.mediaTypes = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeMovie,      nil];

    [self presentViewController:imagePicker animated:YES completion:nil];
}


- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];
    NSString* moviePath = nil;
    if (CFStringCompare ((__bridge CFStringRef) mediaType, kUTTypeMovie, 0) == kCFCompareEqualTo) {
        moviePath = [[info objectForKey:UIImagePickerControllerMediaURL] path];
        // NSLog(@"%@",moviePath);
        //NSURL *videoUrl=(NSURL*)[info objectForKey:UIImagePickerControllerMediaURL];

    }

    NSURL* sourceMovieURL = [NSURL fileURLWithPath:moviePath];
    NSURL* outputPath = [sourceMovieURL URLByDeletingPathExtension];
    outputPath = [outputPath URLByDeletingLastPathComponent];
    NSMutableString* last_path_component =
            [[NSMutableString alloc] initWithString:[[sourceMovieURL URLByDeletingPathExtension] lastPathComponent]];
    [last_path_component appendString:@"~SQUARE"];
    outputPath = [outputPath URLByAppendingPathComponent:last_path_component];
    outputPath = [outputPath URLByAppendingPathExtension:@"MOV"];
    AVURLAsset* asset = [AVURLAsset URLAssetWithURL:sourceMovieURL options:nil];

    AVMutableComposition *composition = [AVMutableComposition composition];
    [composition  addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];

    // input clip
    AVAssetTrack *clipVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];

    // make it square
    AVMutableVideoComposition* videoComposition = [AVMutableVideoComposition videoComposition];
    videoComposition.renderSize = CGSizeMake(clipVideoTrack.naturalSize.height, clipVideoTrack.naturalSize.height);
    videoComposition.frameDuration = CMTimeMake(1, 30);

    AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
    instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(60, 30) );

    // rotate to portrait
    AVMutableVideoCompositionLayerInstruction* transformer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:clipVideoTrack];
    CGAffineTransform t1 = CGAffineTransformMakeTranslation(clipVideoTrack.naturalSize.height, -(clipVideoTrack.naturalSize.width - clipVideoTrack.naturalSize.height) /2 );
    CGAffineTransform t2 = CGAffineTransformRotate(t1, M_PI_2);

    CGAffineTransform finalTransform = t2;
    [transformer setTransform:finalTransform atTime:kCMTimeZero];
    instruction.layerInstructions = [NSArray arrayWithObject:transformer];
    videoComposition.instructions = [NSArray arrayWithObject: instruction];

    // export


    AVAssetExportSession* exporter = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetHighestQuality] ;
    exporter.videoComposition = videoComposition;
    exporter.outputURL=outputPath;
    exporter.outputFileType=AVFileTypeQuickTimeMovie;

    VideoButtonView* button = [self.scrollView buttonAdded];
    [exporter exportAsynchronouslyWithCompletionHandler:^(void){
        AVURLAsset* new_asset = [AVURLAsset URLAssetWithURL:outputPath options:nil];
        [button addVideoAsset:new_asset];
        if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum (outputPath.absoluteString)) {
            UISaveVideoAtPathToSavedPhotosAlbum (outputPath.absoluteString, self, nil, nil);
        }

    }];

    [self dismissViewControllerAnimated:YES completion:nil];
    //[picker release];
}
È stato utile?

Soluzione

I solved it. Using assetlibrary seems to have fixed the problem.

[exporter exportAsynchronouslyWithCompletionHandler:^{
    BOOL success = false;
    switch ([exporter status]) {
        case AVAssetExportSessionStatusCompleted:
            success = true;
            NSLog(@"Export Completed");
            break;
        case AVAssetExportSessionStatusWaiting:
            NSLog(@"Export Waiting");
            break;
        case AVAssetExportSessionStatusExporting:
            NSLog(@"Export Exporting");
            break;
        case AVAssetExportSessionStatusFailed:
        {
            NSError *error = [exporter error];
            NSLog(@"Export failed: %@", [error localizedDescription]);

            break;
        }
        case AVAssetExportSessionStatusCancelled:
            NSLog(@"Export canceled");

            break;
        default:
            break;
    }

    if (success == true) {

     ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init];
     [assetLibrary writeVideoAtPathToSavedPhotosAlbum:url completionBlock:^(NSURL *assetURL, NSError *error){
     NSError *removeError = nil;
     [[NSFileManager defaultManager] removeItemAtURL:url error:&removeError];
     }];

     }
}];
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top