2013-12-09 13 views
2

當我創建使用this tutorial一個視頻,我嘗試移動AVAssetTrack* firstTrack使用AVMutableVideoCompositionInstruction爲包含一些CGAffineTransformAVMutableVideoCompositionLayerInstruction(不包括動畫,所以我不能使用CAAnimation S),在變換一下就忽略忽略。AVMutableVideoCompositionInstruction是在AVMutableVideoComposition

有誰知道這個問題,並知道如何解決它?

在此先感謝!

此信息可能有所幫助:在導出時,我使用AVAssetExportPreset1280x720作爲預設。所以我認爲(可能是錯誤的)this不是問題。

編輯:代碼被分割成各種函數,但我試圖把所有東西都合併到一個代碼中。我希望沒有忘記任何東西或弄亂了某些東西。

// The layer I want to move 
CALayer* layerToMove = nil; 
// A layer containing just the black background 
CALayer* backgroundLayer = nil; 
// The videos duration 
double duration = 12.0; 

AVMutableComposition *exportAsset = [[AVMutableComposition alloc] init]; 
[exportAsset setNaturalSize:layerToMove.frame.size]; 

AVMutableCompositionTrack* dstTrack = [self addBlackVideoTrackOfDuration:duration toComposition:exportAsset]; 

AVMutableVideoCompositionInstruction * MainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 

MainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, exportAsset.duration); 

CGAffineTransform Scale = CGAffineTransformMakeScale(0.1f,0.1f); 
CGAffineTransform Move = CGAffineTransformMakeTranslation(230,230); 
AVMutableVideoCompositionLayerInstruction *FirstlayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:dstTrack]; 

[FirstlayerInstruction setTransform:CGAffineTransformConcat(Scale,Move) atTime:kCMTimeZero]; 
[MainInstruction setLayerInstructions:@[FirstlayerInstruction]]; 

CALayer* compositionLayer = [CALayer layer]; 

compositionLayer.bounds = layerToMove.frame; 
compositionLayer.anchorPoint = CGPointMake(0, 0); 
compositionLayer.position = CGPointMake(0, 0); 

[compositionLayer setFrame:layerToMove.frame]; 
[compositionLayer setBounds:layerToMove.frame]; 

[compositionLayer addSublayer:backgroundLayer]; 
[compositionLayer addSublayer:layerToMove]; 

AVVideoCompositionCoreAnimationTool *animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:layerToMove inLayer:compositionLayer]; 

CMTime frameDuration = CMTimeMakeWithSeconds(1.0/25, 
              1000); 

AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition]; 
[videoComposition setFrameDuration:frameDuration]; 
[videoComposition setInstructions:@[MainInstruction]]; 
[videoComposition setAnimationTool:animationTool]; 
[videoComposition setRenderSize:layerToMove.frame.size]; 
[videoComposition setRenderScale:1.0]; 

AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:exportAsset presetName:AVAssetExportPreset1280x720]; 

[exportSession setOutputFileType:AVFileTypeQuickTimeMovie]; 
[exportSession setOutputURL:nil/*Any url*/]; 
[exportSession setVideoComposition:videoComposition]; 
// The export is complete 
[exportSession exportAsynchronouslyWithCompletionHandler:^ 
{ 
    /*Whatever*/ 
}]; 
+1

你可以發佈你現有的代碼? –

+0

這是非常多的代碼分裂在各種功能,但我會盡力把它發佈每一個重要的行。給我幾分鐘。 – 0x6368

+1

我在視頻拼貼應用程序中有CGAffineTransform。它工作正常。你也可以使用CoreAnimationTool來改變AVExportSession的視頻層的位置。你能告訴我你的代碼嗎? –

回答

0

我發現,我能得到變換,每次工作的唯一方法是使用preferredTransform從AVAssetTrack對象爲出發點,然後CONCAT您所需的變換(S)與:

AVAsset *asset = [AVAsset assetWithURL:videoURL]; 
AVAssetTrack *track = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; 

[mutableCompositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero,asset.duration) ofTrack:track atTime:kCMTimeZero error:nil]; 
AVMutableVideoCompositionLayerInstruction* layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:track]; 
AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 

CGAffineTransform transform = track.preferredTransform; 

CGAffineTransform scale = CGAffineTransformMakeScale(0.1f,0.1f); 
transform = CGAffineTransformConcat(transform, scale); 
[layerInstruction setTransform:transform atTime:kCMTimeZero]; 

我有一些代碼重新定位在視頻中的圖像。這似乎對我有用。我將持續時間設置爲0.01,並立即生成動畫。模擬器中存在一個錯誤,使得它看起來好像動畫不起作用(有時)。如果你在設備上運行它,它將工作:

//animate from the start to end bounds 
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"bounds"]; 
animation.fromValue = [NSValue valueWithCGRect:layerToMove.bounds]; 
animation.toValue = [NSValue valueWithCGRect:CGRectOffset(layerToMove.bounds, 100, 100)]; //change to the desired new position 
animation.duration = 0.01; 
animation.beginTime = 1e-100; 
animation.removedOnCompletion = NO; 
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 

//animate from the start to end center points. 
CABasicAnimation *animation2 = [CABasicAnimation animationWithKeyPath:@"position"]; 
animation2.fromValue = [NSValue valueWithCGPoint:CGPointMake(CGRectGetMidX(layerToMove.bounds), CGRectGetMidY(layerToMove.bounds))]; 
animation2.toValue = [NSValue valueWithCGPoint:CGPointMake(CGRectGetMidX(layerToMove.bounds) + 50, CGRectGetMidY(layerToMove.bounds) + 50)]; 
animation2.duration = 0.01; 
animation2.beginTime = 1e-100; 
animation2.removedOnCompletion = NO; 
animation2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 

//Create an animation group 
CAAnimationGroup *group = [[CAAnimationGroup alloc] init]; 
group.duration = 0.01; 
group.beginTime = 2.0; 
group.removedOnCompletion = NO; 
group.fillMode = kCAFillModeForwards; //causes the values that were animated to remain at their end values 
group.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 
group.animations = @[animation, animation2]; 

//Add the animation group to the layer 
[layerToMove addAnimation:group forKey:@"reposition"]; 
+0

首先,感謝您的回答!但這似乎不適合我。在我的情況下,track.preferredTransform似乎等於'CGAffineTransformIdentity'。 – 0x6368

+1

我仔細研究了你的代碼,看起來你試圖從背景圖層和其他內容層(沒有視頻)創建視頻並移動圖層。那是對的嗎?我假設這是因爲方法'addBlackVideoTrackOfDuration'。您是否嘗試在視頻的過程中對圖層進行動畫製作,或者將其定位在靜態位置? –

+0

是的,這是正確的。 我嘗試在視頻中移動圖層,但沒有動畫。我用CAAnimations試了這個,但是這樣一個動畫的最小持續時間是0.25s =>它是動畫的。 – 0x6368

相關問題