【问题标题】:AVMutableVideoCompositionInstruction is ignored in a AVMutableVideoCompositionAVMutableVideoCompositionInstruction 在 AVMutableVideoComposition 中被忽略
【发布时间】:2013-12-09 18:59:18
【问题描述】:

当我使用this tutorial 创建视频并尝试使用AVMutableVideoCompositionInstruction 移动AVAssetTrack* firstTrack(没有动画,因此我不能使用CAAnimations)和包含一些AVMutableVideoCompositionLayerInstructionCGAffineTransforms ,转换就会被忽略。

有谁知道这个问题并知道如何解决?

提前致谢!

此信息可能会有所帮助:我在导出时使用 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*/
 }];

【问题讨论】:

  • 你能发布你现有的代码吗?
  • 这几乎是在各种功能中拆分的代码,但我会尝试将它放在每个重要的行之后。请给我几分钟。
  • 我在视频拼贴应用中有 CGAffineTransform。它工作正常。您也可以使用 CoreAnimationTool 更改 AVExportSession 的视频层位置。你能告诉我你的代码吗?
  • 我在上面添加了代码

标签: ios objective-c avfoundation cgaffinetransform


【解决方案1】:

我发现每次都能使转换工作的唯一方法是使用 AVAssetTrack 对象中的 preferredTransform 作为起点,然后将所需的转换与它连接:

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

【讨论】:

  • 首先,感谢您的回答!但这似乎对我不起作用。在我的情况下,track.preferredTransform 似乎等于 CGAffineTransformIdentity
  • 我仔细查看了您的代码,您似乎正在尝试从背景层和其他内容层(无视频)创建视频并移动该层。那是对的吗?我假设这是因为addBlackVideoTrackOfDuration 方法。您是在尝试在视频过程中为图层设置动画,还是只是将其放置在静态位置以进行渲染?
  • 是的,没错。我尝试在视频期间移动图层,但没有动画。我用 CAAnimations 试过这个,但是这种动画的最短持续时间是 0.25s => 它是动画的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多