在视频上添加图像作为水印会导致倒置视频

时间:2017-06-19 07:21:26

标签: ios objective-c avfoundation

我使用以下代码在视频上添加图像水印,但结果视频的帧旋转了180度,我尝试了所有可能的解决方案来阻止它。我只想要与水印相同的视频作为源视频。请提出解决方案。

-(void)watermarkVideoAtURL:(NSURL *)url fb:(BOOL)fb withCompletionHandler:(void(^)(bool success, NSURL *assetsURL, NSError *error))completionHandler {

    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] lastObject];
    AVMutableCompositionTrack *compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];

    AVAssetTrack *clipAudioTrack = [[videoAsset tracksWithMediaType:AVMediaTypeAudio] lastObject];
    [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] lastObject] preferredTransform]];
    CGSize sizeOfVideo = [videoAsset naturalSize];

    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);

    // Image of watermark
    UIImage *myImage = [self imageByApplyingAlpha:watermarkOpacityFactor toImage:[UIImage imageNamed:@"iconbig"]];
    CALayer *layerCa = [CALayer layer];
    layerCa.contents = (id)myImage.CGImage;
    layerCa.frame = CGRectMake(10, sizeOfVideo.height - 50, 50, 50);
    layerCa.opacity = 1.0;

    CALayer *layerCa2 = [CALayer layer];
    layerCa2.contents = (id)myImage.CGImage;
    layerCa2.frame = CGRectMake(sizeOfVideo.width - 60, 10, 50, 50);
    layerCa2.opacity = 1.0;

    [parentLayer addSublayer:videoLayer];
    [parentLayer addSublayer:layerCa];
    [parentLayer addSublayer:layerCa2];

    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] lastObject];


    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:AVAssetExportPresetHighestQuality];
    exportSession.videoComposition = videoComposition;
    exportSession.outputURL = [NSURL fileURLWithPath:destinationPath];
    exportSession.outputFileType = AVFileTypeQuickTimeMovie;

    [exportSession exportAsynchronouslyWithCompletionHandler:^{
        switch (exportSession.status) {
            case AVAssetExportSessionStatusCompleted: {
                ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
                [library writeVideoAtPathToSavedPhotosAlbum:exportSession.outputURL completionBlock:^(NSURL *assetURL, NSError *error) {
                    if (!error) {
                        completionHandler(YES, assetURL, nil);
                    } else {
                        completionHandler(NO, nil, error);
                    }
                }];
            }
                break;

            case AVAssetExportSessionStatusFailed: {
               completionHandler(NO, nil, exportSession.error);
            }
                break;

            case AVAssetExportSessionStatusCancelled: {
               completionHandler(NO, nil, exportSession.error);
            }
                break;

            default:
                break;
        }
    }];
}

1 个答案:

答案 0 :(得分:0)

尝试将AVAssetTrack的{​​{1}}设置为图层指令

的setTransform:atTime:

  

设置固定变换以应用从指定时间到下一次设置变换的时间。[...]在设置变换的第一个指定时间之前,仿射变换保持不变为该值的   CGAffineTransformIdentity   ;在设置了变换的最后一次之后,仿射变换在最后一个值处保持不变。