我想在下载的视频的左下角添加水印图片,我发现下面的代码在视频的视频轨道的preferredTransform
属性为CGAffineTransformIdentity
时有效(这意味着没有真正的转换),而对于那些视频进行转换,代码失败了。如何解决?
示例视频(已转换)网址为here
BTW,AVFoundations报告的错误代码是-11841
+(void) addWatermarkWithInputFile:(NSString *)inputFile outputFile:(NSString *)outputFile completion:(void (^)(BOOL))completion{
[[NSFileManager defaultManager] removeItemAtPath:outputFile error:nil];
AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:[NSURL fileURLWithPath:inputFile] options:nil];
AVMutableComposition* composition = [AVMutableComposition composition];
CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, videoAsset.duration);
AVAssetTrack *track = [videoAsset tracksWithMediaType:AVMediaTypeVideo].firstObject;
{
AVMutableCompositionTrack * composedTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo
preferredTrackID:kCMPersistentTrackID_Invalid];
composedTrack.preferredTransform = track.preferredTransform;
[composedTrack insertTimeRange:timeRange
ofTrack:[videoAsset tracksWithMediaType:AVMediaTypeVideo].firstObject
atTime:kCMTimeZero
error:nil];
}
{
AVMutableCompositionTrack * composedTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio
preferredTrackID:kCMPersistentTrackID_Invalid];
composedTrack.preferredTransform = track.preferredTransform;
[composedTrack insertTimeRange:timeRange
ofTrack:[videoAsset tracksWithMediaType:AVMediaTypeAudio].firstObject
atTime:kCMTimeZero
error:nil];
}
AVAssetTrack *clipVideoTrack = [videoAsset tracksWithMediaType:AVMediaTypeVideo].firstObject;
CGSize videoSize = clipVideoTrack.naturalSize;
AVMutableVideoComposition* videoComp = [AVMutableVideoComposition videoComposition];
videoComp.renderSize = videoSize;
videoComp.frameDuration = CMTimeMake(1, 30);
{
UIImage *myImage = [UIImage imageNamed:@"video-watermark"];
CALayer *aLayer = [CALayer layer];
aLayer.contents = (id)myImage.CGImage;
aLayer.frame = CGRectMake(10, 10, myImage.size.width * myImage.scale, myImage.size.height * myImage.scale);
CALayer *parentLayer = [CALayer layer];
CALayer *videoLayer = [CALayer layer];
parentLayer.frame = CGRectMake(0, 0, videoSize.width, videoSize.height);
videoLayer.frame = CGRectMake(0, 0, videoSize.width, videoSize.height);
[parentLayer addSublayer:videoLayer];
[parentLayer addSublayer:aLayer];
videoComp.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
}
/// instruction
AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instruction.timeRange = timeRange;
AVMutableVideoCompositionLayerInstruction* layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:clipVideoTrack];
instruction.layerInstructions = @[layerInstruction];
videoComp.instructions = @[instruction];
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:composition
presetName:AVAssetExportPresetHighestQuality];
exporter.outputURL = [NSURL fileURLWithPath:outputFile];
exporter.outputFileType = AVFileTypeMPEG4;
exporter.shouldOptimizeForNetworkUse = YES;
exporter.videoComposition = videoComp;
exporter.timeRange = timeRange;
[exporter exportAsynchronouslyWithCompletionHandler:^{
completion(exporter.status == AVAssetExportSessionStatusCompleted);
}];
}