2011-08-08 15 views
13

Bir CALayer'ı AVMutableComposition, AVMutableVideoComposition ve iOS 4.3'teki AVVideoCompositionCoreAnimationTool kullanarak portre modu videosu (dışa aktarma) içine pişirmeye çalışıyorum. Bu manzarada çalışıyor. Ancak, videoyu portre halinde yakalarsam, AVVideoCompositionCoreAnimationTool video parçasındaki dönüşümü göz ardı ediyor. Yani, portre modu videosu için, AVMutableCompositionTrack.preferredTransform öğesini orijinal varlık video parçasından tercih edilenTransform değerine ayarlıyorum. Bir AVVideoCompositionCoreAnimationTool kullanmadığım sürece, bu çalışır ve video portre modunda çıkar. Ancak bir AVVideoCompositionCoreAnimationTool ve CALayer ekledikten sonra, dosya manzarada çıkar. (CALayer düzgün görünüyor, ancak arkasındaki video kendi tarafında ve dosyanın en boy oranı kapalı). Dönüşümün CALayer'a uygulanmasını denedim ve ACVideoComposition'da bir dönüşüm ayarlamayı denedim. Bunların hiçbiri üretilen dosyanın yönünü değiştirmez (hala 480x369, 360x480 değil). AVVideoCompositionCoreAnimationTool ile portre modu videosu oluşturmanın bir yolu var mı?AVVideoCompositionCoreAnimationTool ve CALayer dikey modda mı?

Önce

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

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

Ve ihracat için CALayer eklemek bir başlık ile AVMutableComposition ve 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; 

Ve bir CALayer kurmak!

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

Bu kod manzara modunda çalışır ve aynı zamanda portrede çizgiyi videoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];

+0

Aynı sorunu yaşıyorum. Buna bir çözüm buldunuz mu? –

+1

Evet, ayrıca portre modu besteleriyle de bir sürü başka problemle karşılaştım. Hile AVMutableVideoCompositionLayerInstruction üzerinde dönüşüm ayarlamak IS. Ancak, doğru dönüşüm, varlığın tercih edilen dönüşümü değildir. Tercih edilen dönüşümle başlayın ve ek çeviriler ve çevirmeler uygulayın. İşleyen bir şey bulacaksınız (çerçeve boyutunun bir işlevi olarak). Ne yazık ki her yönelim için doğru dönüşüm farklıdır. Temel olarak, kompozisyonda bir hata var ve biz ihracat katmanını konumlandırarak etrafta çalışıyoruz. Onu işe aldım. – wombat57

cevap

2

bu deneyin ve yanı sıra diğer talimatları eklemek kaldırırsanız.

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

Nasıl gideceğini bana bildirin!

MacMike

+0

İyi değil (Daha önce bunu denedim, compositionVideoTrack.preferredTransform öğesini passThroughLayer setTransform'a geçirdim). En boy oranı hala manzaradır ve video kareleri gösterilmez (CALayer animasyonunun yanı sıra). AVVideoCompositionCoreAnimationTool'un matrisi işlemediği gözüküyor. – wombat57

+0

Bu, muhtemelen bazı videolarda çalışır, ancak test ettiğim gibi değil. Her iki durumda da benim için büyük bir yardım, çünkü bu gitmek için doğru bir yol gibi görünüyor. Teşekkürler. –