2011-08-08 24 views
13

Tôi đang cố gắng nướng CALayer thành video chế độ dọc (khi xuất) bằng cách sử dụng AVMutableComposition, AVMutableVideoComposition và AVVideoCompositionCoreAnimationTool trên iOS 4.3. Điều này tất cả các công trình trong cảnh quan. Tuy nhiên, nếu tôi quay video theo chiều dọc, AVVideoCompositionCoreAnimationTool sẽ bỏ qua biến đổi trên đoạn video. Tức là, đối với video chế độ dọc, tôi đặt AVMutableCompositionTrack.preferredTransform thành giá trị ưa thíchTransform từ bản nhạc video gốc. Miễn là tôi không sử dụng AVVideoCompositionCoreAnimationTool, công cụ này hoạt động và video xuất hiện ở chế độ dọc. Tuy nhiên, ngay sau khi tôi thêm AVVideoCompositionCoreAnimationTool và CALayer, tệp sẽ xuất hiện ở chế độ ngang. (CALayer xuất hiện chính xác, nhưng video đằng sau nó ở bên cạnh nó và tỷ lệ khung hình của tệp bị tắt). Tôi đã thử áp dụng biến đổi cho CALayer, và thiết lập một biến đổi trong ACVideoComposition. Không thay đổi định hướng của tệp được tạo ra (nó vẫn là 480x369, không phải 360x480). Có cách nào để hiển thị video chế độ dọc với AVVideoCompositionCoreAnimationTool không?AVVideoCompositionCoreAnimationTool và CALayer ở chế độ dọc?

Trước tiên tôi thiết lập một AVMutableComposition và AVMutableVideoComposition

AVMutableComposition *composition = [AVMutableComposition composition]; 
AVMutableCompositionTrack *compositionVideoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 
AVURLAsset *videoAsset = [AVURLAsset URLAssetWithURL:url options:nil]; 
CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, [videoAsset duration]); 
AVAssetTrack *clipVideoTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; 

CGSize videoSize = CGSizeApplyAffineTransform(clipVideoTrack.naturalSize, clipVideoTrack.preferredTransform); 
videoSize.width = fabs(videoSize.width); 
videoSize.height = fabs(videoSize.height); 

CMTime titleDuration = CMTimeMakeWithSeconds(5, 600); 
CMTimeRange titleRange = CMTimeRangeMake(kCMTimeZero, titleDuration); 

[compositionVideoTrack insertTimeRange:titleRange ofTrack:nil atTime:kCMTimeZero error:nil]; 
[compositionVideoTrack insertTimeRange:timeRange ofTrack:clipVideoTrack atTime:titleDuration error:nil]; 
compositionVideoTrack.preferredTransform = clipVideoTrack.preferredTransform; 

AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition]; 
AVMutableVideoCompositionInstruction *passThroughInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 
passThroughInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, [composition duration]); 
AVAssetTrack *videoTrack = [[composition tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; 
AVMutableVideoCompositionLayerInstruction *passThroughLayer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];  
passThroughInstruction.layerInstructions = [NSArray arrayWithObject:passThroughLayer]; 
videoComposition.instructions = [NSArray arrayWithObject:passThroughInstruction];  
videoComposition.frameDuration = CMTimeMake(1, 30); 
videoComposition.renderSize = videoSize; 
videoComposition.renderScale = 1.0; 

Và một CALayer với một tiêu đề

CALayer *animationLayer = [CALayer layer]; 
animationLayer.bounds = CGRectMake(0, 0, videoSize.width, videoSize.height); 

CATextLayer *titleLayer = [CATextLayer layer]; 
titleLayer.string = [effect valueForKey:@"title"]; 
titleLayer.font = [effect valueForKey:@"font"]; 
titleLayer.fontSize = 30; 

titleLayer.alignmentMode = kCAAlignmentCenter; 
titleLayer.bounds = CGRectMake(0, 0, videoSize.width, videoSize.height/6); 

[animationLayer addSublayer:titleLayer]; 
titleLayer.anchorPoint = CGPointMake(0.5, 0.5); 
titleLayer.position = CGPointMake(CGRectGetMidX(layer.bounds), CGRectGetMidY(layer.bounds));  

CABasicAnimation *fadeAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; 
fadeAnimation.fromValue = [NSNumber numberWithFloat:1.0]; 
fadeAnimation.toValue = [NSNumber numberWithFloat:0.0]; 
fadeAnimation.additive = NO; 
fadeAnimation.removedOnCompletion = NO; 
fadeAnimation.beginTime = 3.5; 
fadeAnimation.duration = 1.0; 
fadeAnimation.fillMode = kCAFillModeBoth; 
[titleLayer addAnimation:fadeAnimation forKey:nil]; 

Cuối cùng tôi thêm các CALayer đến AVMutableVideoComposition

CALayer *parentLayer = [CALayer layer]; 
CALayer *videoLayer = [CALayer layer]; 

parentLayer.bounds = CGRectMake(0, 0, videoSize.width, videoSize.height); 
parentLayer.anchorPoint = CGPointMake(0, 0); 
parentLayer.position = CGPointMake(0, 0); 

videoLayer.bounds = CGRectMake(0, 0, videoSize.width, videoSize.height); 
[parentLayer addSublayer:videoLayer]; 
videoLayer.anchorPoint = CGPointMake(0.5, 0.5); 
videoLayer.position = CGPointMake(CGRectGetMidX(parentLayer.bounds), CGRectGetMidY(parentLayer.bounds)); 
[parentLayer addSublayer:layer];  
animationLayer.anchorPoint = CGPointMake(0.5, 0.5); 
animationLayer.position = CGPointMake(CGRectGetMidX(parentLayer.bounds), CGRectGetMidY(parentLayer.bounds)); 
videoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer]; 

Và xuất khẩu!

AVAssetExportSession *exportSession = [[[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetMediumQuality] autorelease]; 
exportSession.videoComposition = videoComposition; 

NSURL *segmentFileURL = //some local URL 
exportSession.outputFileType = @"com.apple.quicktime-movie"; 
exportSession.outputURL = segmentFileURL; 


[exportSession exportAsynchronouslyWithCompletionHandler:^{ 
    switch ([exportSession status]) { 
     case AVAssetExportSessionStatusFailed: 
      Log(@"Export failed: %@", [exportSession error]); 
      break; 
     case AVAssetExportSessionStatusCancelled: 
      Log(@"Export canceled"); 
      break; 
     case AVAssetExportSessionStatusCompleted: 
      Log(@"Export done"); 
      break; 
    } 
}]; 

Mã này hoạt động ở chế độ nằm ngang, và cũng có thể trong bức chân dung nếu tôi loại bỏ các dòng videoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];

+0

Tôi gặp vấn đề tương tự. bạn đã tìm thấy giải pháp chưa? –

+1

Có, mặc dù tôi cũng gặp phải một số vấn đề khác với bố cục chế độ dọc. Bí quyết IS để đặt biến đổi trên AVMutableVideoCompositionLayerInstruction. Tuy nhiên, biến đổi chính xác không phải là biến đổi được ưu tiên của nội dung. Bắt đầu với biến đổi được ưu tiên, và áp dụng các bản dịch bổ sung và flips. Bạn sẽ tìm thấy một cái gì đó hoạt động (như một chức năng của kích thước khung hình). Thật không may thay đổi chính xác là khác nhau cho mọi định hướng. Về cơ bản, có một lỗi trong bố cục, và chúng tôi đang làm việc xung quanh nó bằng cách định vị lớp xuất. Tôi đã làm cho nó hoạt động. – wombat57

Trả lời

2

Hãy thử điều này và thêm các hướng dẫn khác của bạn là tốt.

///turn video 90 degrees 
AVMutableVideoCompositionLayerInstruction *passThroughLayer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:clipVideoTrack]; 
CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(degreesToRadians(90.0)); 
CGAffineTransform rotateTranslate = CGAffineTransformTranslate(rotationTransform,320,0); 
[passThroughLayer setTransform:rotateTranslate atTime:kCMTimeZero]; 

Hãy cho tôi biết cách thực hiện!

MacMike

+0

Không tốt (Tôi đã thử điều này trước đây, chuyển thành phầnVideoTrack.preferredTransform thành passThroughLayer setTransform). Tỷ lệ khung hình vẫn là cảnh quan và không có khung hình video nào hiển thị (ngoài hoạt ảnh của CALayer). Dường như AVVideoCompositionCoreAnimationTool không xử lý ma trận. – wombat57

+0

Điều này có thể hoạt động trên một số video nhưng không hoạt động trên các video mà tôi đã thử nghiệm. Dù bằng cách nào, đó là sự giúp đỡ lớn đối với tôi, vì đây có vẻ là cách đi đúng đắn. Cảm ơn. –

Các vấn đề liên quan