2013-04-10 33 views
24

Tôi đã tự hỏi liệu có ai có thể cho tôi biết cách tôi có thể đạt được điều này không. Nếu được suy nghĩ của một vài giải pháp:Làm cách nào để thêm hình mờ trong video đã quay trên iOS

  1. Tạo hình ảnh cá nhân từ video chụp và sau đó kết hợp chúng cho mỗi hình ảnh và sau đó tạo ra một AVAsset mới ... Nghe có vẻ hơi phức tạp không bạn nghĩ?

  2. Hợp nhất 2 video, một video trong suốt (hình ảnh đang giữ hình mờ) và hình kia là nội dung được chụp bằng máy ảnh.

Trả lời

15

Mã này thêm văn bản hoặc chuỗi TRÊN video và sau khi lưu video bạn sẽ phát trên trình phát bất kỳ. Đa số Ưu điểm của mã này là Cung cấp video có âm thanh. Và tất cả mọi thứ trong một mã (đó là văn bản và hình ảnh).

#import <AVFoundation/AVFoundation.h> 

-(void)MixVideoWithText 
{ 
    AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:url options:nil]; 
    AVMutableComposition* mixComposition = [AVMutableComposition composition]; 

    AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 
    AVAssetTrack *clipVideoTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; 
    AVMutableCompositionTrack *compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 
    AVAssetTrack *clipAudioTrack = [[videoAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; 
    //If you need audio as well add the Asset Track for audio here 

    [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:clipVideoTrack atTime:kCMTimeZero error:nil]; 
    [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:clipAudioTrack atTime:kCMTimeZero error:nil]; 

    [compositionVideoTrack setPreferredTransform:[[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] preferredTransform]]; 

    CGSize sizeOfVideo=[videoAsset naturalSize]; 

    //TextLayer defines the text they want to add in Video 
    //Text of watermark 
    CATextLayer *textOfvideo=[[CATextLayer alloc] init]; 
    textOfvideo.string=[NSString stringWithFormat:@"%@",text];//text is shows the text that you want add in video. 
    [textOfvideo setFont:(__bridge CFTypeRef)([UIFont fontWithName:[NSString stringWithFormat:@"%@",fontUsed] size:13])];//fontUsed is the name of font 
    [textOfvideo setFrame:CGRectMake(0, 0, sizeOfVideo.width, sizeOfVideo.height/6)]; 
    [textOfvideo setAlignmentMode:kCAAlignmentCenter]; 
    [textOfvideo setForegroundColor:[selectedColour CGColor]]; 

    //Image of watermark 
    UIImage *myImage=[UIImage imageNamed:@"one.png"]; 
    CALayer layerCa = [CALayer layer]; 
    layerCa.contents = (id)myImage.CGImage; 
    layerCa.frame = CGRectMake(0, 0, sizeOfVideo.width, sizeOfVideo.height); 
    layerCa.opacity = 1.0; 

    CALayer *optionalLayer=[CALayer layer]; 
    [optionalL addSublayer:textOfvideo]; 
    optionalL.frame=CGRectMake(0, 0, sizeOfVideo.width, sizeOfVideo.height); 
    [optionalL setMasksToBounds:YES]; 

    CALayer *parentLayer=[CALayer layer]; 
    CALayer *videoLayer=[CALayer layer]; 
    parentLayer.frame=CGRectMake(0, 0, sizeOfVideo.width, sizeOfVideo.height); 
    videoLayer.frame=CGRectMake(0, 0, sizeOfVideo.width, sizeOfVideo.height); 
    [parentLayer addSublayer:videoLayer]; 
    [parentLayer addSublayer:optionalLayer]; 
    [parentLayer addSublayer:layerCa]; 

    AVMutableVideoComposition *videoComposition=[AVMutableVideoComposition videoComposition] ; 
    videoComposition.frameDuration=CMTimeMake(1, 30); 
    videoComposition.renderSize=sizeOfVideo; 
    videoComposition.animationTool=[AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer]; 

    AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 
    instruction.timeRange = CMTimeRangeMake(kCMTimeZero, [mixComposition duration]); 
    AVAssetTrack *videoTrack = [[mixComposition tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; 
    AVMutableVideoCompositionLayerInstruction* layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack]; 
    instruction.layerInstructions = [NSArray arrayWithObject:layerInstruction]; 
    videoComposition.instructions = [NSArray arrayWithObject: instruction]; 

    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]; 
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
    [dateFormatter setDateFormat:@"yyyy-MM-dd_HH-mm-ss"]; 
    NSString *destinationPath = [documentsDirectory stringByAppendingFormat:@"/utput_%@.mov", [dateFormatter stringFromDate:[NSDate date]]]; 

    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetMediumQuality]; 
    exportSession.videoComposition=videoComposition; 

    exportSession.outputURL = [NSURL fileURLWithPath:destinationPath]; 
    exportSession.outputFileType = AVFileTypeQuickTimeMovie; 
    [exportSession exportAsynchronouslyWithCompletionHandler:^{ 
    switch (exportSession.status) 
    { 
     case AVAssetExportSessionStatusCompleted: 
      NSLog(@"Export OK"); 
      if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(destinationPath)) { 
       UISaveVideoAtPathToSavedPhotosAlbum(destinationPath, self, @selector(video:didFinishSavingWithError:contextInfo:), nil); 
      } 
      break; 
     case AVAssetExportSessionStatusFailed: 
      NSLog (@"AVAssetExportSessionStatusFailed: %@", exportSession.error); 
      break; 
     case AVAssetExportSessionStatusCancelled: 
      NSLog(@"Export Cancelled"); 
      break; 
    } 
    }]; 
} 

Hiển thị lỗi họ sẽ đến sau khi lưu video.

-(void) video: (NSString *) videoPath didFinishSavingWithError: (NSError *) error contextInfo: (void *) contextInfo 
{ 
    if(error) 
     NSLog(@"Finished saving video with error: %@", error); 
} 
+2

Lưu ý dòng ở trên "videoComposition.frameDuration = CMTimeMake (1, 10);" có lẽ nên là "videoComposition.frameDuration = CMTimeMake (1, 30);" Tốc độ khung hình mặc định là 30. Có vẻ tốt hơn. – etayluz

+0

bạn có thể gợi ý cho tôi cách đặt khung thích hợp cho CATextLayer không? xem câu hỏi của tôi http://stackoverflow.com/questions/31780060/how-to-set-catextlayer-in-video-according-to-frame –

+2

Thao tác này sẽ lưu video theo hướng sai. Mọi sửa lỗi cho điều đó? – RJiryes