Search code examples
iosios8video-capturecmsamplebufferref

Creating `CMSampleBufferRef` from a .mov file


My app captures a video clip for 3 seconds, and programmatically I want to create a 15 sec clip from recorded 3 sec clip by looping it 5 times. And finally have to save 15 sec clip in CameraRoll.

I have got my 3 sec video clip via AVCaptureMovieFileOutput and I have its NSURL from delegate which is currently in NSTemporaryDirectory().

I am using AVAssetWriterInput for looping it. But it ask for CMSampleBufferRef like :

[writerInput appendSampleBuffer:sampleBuffer];

How will I gee this CMSampleBufferRef from video in NSTemporaryDirectory() ?

I have seen code for converting UIImage to CMSampleBufferRef, but I can find any for video file.

Any suggestion will be helpful. :)


Solution

  • Finally, I fixed my problem using AVMutableComposition. Here is my code :

    AVMutableComposition *mixComposition = [AVMutableComposition new];
    AVMutableCompositionTrack *mutableCompVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
    
    AVURLAsset *videoAsset = [[AVURLAsset alloc]initWithURL:3SecFileURL options:nil];
    CMTimeRange video_timeRange = CMTimeRangeMake(kCMTimeZero, [videoAsset duration]);
    
    CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(M_PI_2);
    [mutableCompVideoTrack setPreferredTransform:rotationTransform];
    
    CMTime currentCMTime = kCMTimeZero;
    
    for (NSInteger count = 0 ; count < 5 ; count++)
    {
        [mutableCompVideoTrack insertTimeRange:video_timeRange ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:currentCMTime error:nil];
        currentCMTime = CMTimeAdd(currentCMTime, [videoAsset duration]);
    }
    
    NSString *fullMoviePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[@"moviefull" stringByAppendingPathExtension:@"mov"]];
    NSURL *finalVideoFileURL = [NSURL fileURLWithPath:fullMoviePath];
    
    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetPassthrough];
    [exportSession setOutputFileType:AVFileTypeQuickTimeMovie];
    [exportSession setOutputURL:finalVideoFileURL];
    
    CMTimeValue val = [mixComposition duration].value;
    CMTime start = CMTimeMake(0, 1);
    CMTime duration = CMTimeMake(val, 1);
    CMTimeRange range = CMTimeRangeMake(start, duration);
    [exportSession setTimeRange:range];
    
    [exportSession exportAsynchronouslyWithCompletionHandler:^{
    
        switch ([exportSession status])
        {
            case AVAssetExportSessionStatusFailed:
            {
                NSLog(@"Export failed: %@ %@", [[exportSession error] localizedDescription], [[exportSession error]debugDescription]);
            }
            case AVAssetExportSessionStatusCancelled:
            {
                NSLog(@"Export canceled");
                break;
            }
            case AVAssetExportSessionStatusCompleted:
            {
                NSLog(@"Export complete!");
            }
    
            default:    NSLog(@"default");
        }
    }];