2017-06-16 89 views
4

我拍攝了一張png圖像和一個水印視頻,兩者都是肖像。我在視頻中做了水印和圖片。試圖在視頻上使用AVFoundation對水印圖像進行水印

加水印後,在橫向模式下獲得合併視頻,並在反時鐘方向翻轉90度。 我無法找出視頻從縱向翻到橫向模式的確切原因。圖像顯示的是拉伸人像。 請幫忙。提前致謝。

使用下面的代碼: -

- (void)addWatermarkAtVideoFile:(NSURL *)videoURL image:(UIImage *)image withConvertedVideoUUID:(NSString *)convertedVideoUUID response:(void(^)(BOOL success, NSString *videoUUID, NSURL *videoPath))responseBlock { 

    AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:videoURL options:nil]; 
    AVMutableComposition* mixComposition = [AVMutableComposition composition]; 


    AVAssetTrack *clipVideoTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; 
    if(clipVideoTrack) { 
     AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 
     [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:clipVideoTrack atTime:kCMTimeZero error:nil]; 
     [compositionVideoTrack setPreferredTransform:[[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] preferredTransform]]; 
    } 

    AVAssetTrack *clipAudioTrack = [[videoAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]; 
    if(clipAudioTrack) { 
     AVMutableCompositionTrack *compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 
     [compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:clipAudioTrack atTime:kCMTimeZero error:nil]; 
    } 

    CGSize sizeOfVideo=[videoAsset naturalSize]; 

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

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

    //Creating temp path to save the converted video 
    NSString* myDocumentPath = [self getDocumentDirectoryPathWithFileName:convertedVideoUUID]; 
    NSURL *outputFileURL = [[NSURL alloc] initFileURLWithPath:myDocumentPath]; 

    //Check if the file already exists then remove the previous file 
    [self removeFileIfExistAtPAth:myDocumentPath]; 

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

    exportSession.outputURL = outputFileURL; 
    exportSession.outputFileType = AVFileTypeQuickTimeMovie; 
    [exportSession exportAsynchronouslyWithCompletionHandler:^{ 
     switch (exportSession.status) 
     { 
      case AVAssetExportSessionStatusCompleted: 

       NSLog(@"Export OK"); 
       [self saveInPhotoAlbum:myDocumentPath]; 

       break; 
      case AVAssetExportSessionStatusFailed: 
       NSLog (@"AVAssetExportSessionStatusFailed: %@", exportSession.error); 
       break; 
      case AVAssetExportSessionStatusCancelled: 
       NSLog(@"Export Cancelled"); 
       break; 
     } 

     BOOL statusSuccess = [exportSession status] == AVAssetExportSessionStatusCompleted; 
     responseBlock(statusSuccess ? YES : NO, statusSuccess ? convertedVideoUUID : nil, statusSuccess ? outputFileURL : nil); 
    }]; 
} 

回答

0

我認爲這是與AVFoundation的默認行爲,它可能沒有鏈接到水印功能。

你可以使用CGAffineTransform:

if(height > width) { 
    CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(M_PI_2); 
    [layerInstruction setTransform:rotationTransform atTime:kCMTimeZero]; 
} 
0

AVAsset的naturalSize不考慮視頻的最終旋轉。
如果您想正確放置遊覽水印,請考慮使用AVMutableVideoCompositionrenderSize或應用一些轉換。 這段代碼給你的資產的實際方向:

func orientationForAsset(_ asset: AVAsset) -> (orientation: UIImageOrientation, isPortrait: Bool) { 
     let videoTrack = asset.tracks(withMediaType: AVMediaTypeVideo).first! 
     let transformMatrix = videoTrack.preferredTransform 
     return orientationFromTransform(transformMatrix) 
    } 

    func orientationFromTransform(_ transform: CGAffineTransform) -> (orientation: UIImageOrientation, isPortrait: Bool) { 
     var assetOrientation = UIImageOrientation.up 
     var isPortrait = false 
     if transform.a == 0 && transform.b == 1.0 && transform.c == -1.0 && transform.d == 0 { 
      assetOrientation = .right 
      isPortrait = true 
     } else if transform.a == 0 && transform.b == -1.0 && transform.c == 1.0 && transform.d == 0 { 
      assetOrientation = .left 
      isPortrait = true 
     } else if transform.a == 1.0 && transform.b == 0 && transform.c == 0 && transform.d == 1.0 { 
      assetOrientation = .up 
     } else if transform.a == -1.0 && transform.b == 0 && transform.c == 0 && transform.d == -1.0 { 
      assetOrientation = .down 
     } 
     return (assetOrientation, isPortrait) 
    } 

有了這一個你可以得到的實際大小考慮旋轉。

func resolutionSizeForAsset(_ asset: AVAsset) -> CGSize? { 
     guard let track = asset.tracks(withMediaType: AVMediaTypeVideo).first else { return nil } 
     let size = track.naturalSize.applying(track.preferredTransform) 
     return CGSize(width: fabs(size.width), height: fabs(size.height)) 
    } 
+0

謝謝安德烈。我知道了。 –