如何在iOS上捕获的video中添加水印

我想知道是否有人可以告诉我如何能做到这一点。 如果一直在考虑一些解决scheme:

  1. 从捕获的video中创build单个图像,然后将其合并到每个图像,然后创build一个新的AVAsset …听起来有点复杂,你不觉得吗?

  2. 合并2个video,其中一个是透明的(持有水印的那个),另一个是用相机捕获的资产。

此代码是在video上添加文本或string,保存video后,您将在任何播放器上播放。 这个代码的最大优点是提供有声video。 而所有的东西在一个代码(即文本和图像)。

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

显示保存video后会出现的错误。

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