2013-04-10 13 views
24

Zastanawiam się, czy ktoś może mi powiedzieć, jak mogę to osiągnąć. Jeśli myślał od kilku rozwiązań:Jak dodać znak wodny w przechwyconym wideo na iOS

  1. Tworzenie pojedynczych obrazów z przechwyconego wideo, a następnie połączyć je na obrazie, a potem utworzyć nowy AVAsset ... Brzmi nieco skomplikowany, nie sądzisz?

  2. Scal 2 filmy, jeden jest przezroczysty (ten zawierający znak wodny), a drugi to materiał przechwycony aparatem.

Odpowiedz

15

Ten kod dodaje tekst lub ciąg znaków do wideo, a po zapisaniu wideo zostanie odtworzony na dowolnym odtwarzaczu. Największą zaletą tego kodu jest zapewnienie wideo z dźwiękiem. I wszystkie rzeczy w jednym kodzie (to jest tekst i obraz).

#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; 
    } 
    }]; 
} 

Pokazuje błąd, który wystąpi po zapisaniu wideo.

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

Zwróć uwagę na wiersz powyżej "videoComposition.frameDuration = CMTimeMake (1, 10);" prawdopodobnie powinien to być "videoComposition.frameDuration = CMTimeMake (1, 30);" Domyślna liczba klatek na sekundę to 30. Wygląda też lepiej. – etayluz

+0

czy możesz zaproponować mi, jak ustawić odpowiednią ramkę dla CATextLayer? zobacz moje pytanie http://stackoverflow.com/questions/31780060/how-to-set-catextlayer-in-video- recording- to- frame –

+2

To zapisuje wideo w niewłaściwej orientacji .. Jakieś poprawki do tego? – RJiryes

Powiązane problemy