如何为将添加到AVMutableVideoComposition的CALayers设置动画

时间:2016-07-26 12:53:44

标签: ios objective-c swift xamarin core-animation

我已经在iPhone上的现有视频中加入CATextLayer并将其保存到另一个mp4文件中(如此处所示:How can I add a watermark in a captured video on iOS)。

AVAsset videoAsset = AVAsset.FromUrl(NSUrl.CreateFileUrl(urlpath, false, null));
AVMutableComposition mixComposition = AVMutableComposition.Create();
AVMutableCompositionTrack compositionVideoTrack = mixComposition.AddMutableTrack(AVMediaType.Video, 0);
AVAssetTrack clipVideoTrack = videoAsset.TracksWithMediaType(AVMediaType.Video).First();

CMTimeRange timeRange = new CMTimeRange(){
    Start = CMTime.Zero,
    Duration = videoAsset.Duration
};

NSError error;
compositionVideoTrack.InsertTimeRange(timeRange, clipVideoTrack, CMTime.Zero, out error);
compositionVideoTrack.PreferredTransform = videoAsset.TracksWithMediaType(AVMediaType.Video).First().PreferredTransform;


// Create overlay layer
CGSize naturalSize = videoAsset.NaturalSize;

CATextLayer overLayer = new CATextLayer(){
    Frame = new CGRect(new CGPoint(0, 0), naturalSize),
    String = "text layer on my video",
    ForegroundColor = UIColor.White.CGColor
};

// Sort the layers
CALayer parentLayer = new CALayer() {
    Frame = new CGRect(new CGPoint(0, 0), naturalSize)
};
CALayer videoLayer = new CALayer(){
    Frame = new CGRect(new CGPoint(0,0), naturalSize)
};

parentLayer.AddSublayer(videoLayer);
parentLayer.AddSublayer(overLayer);

// Create composition
AVMutableVideoComposition videoComposition = AVMutableVideoComposition.Create();
videoComposition.RenderSize = naturalSize;
videoComposition.FrameDuration = new CMTime(1, 30);
videoComposition.AnimationTool = AVVideoCompositionCoreAnimationTool.FromLayer(videoLayer, parentLayer);

// Instruction
AVMutableVideoCompositionInstruction instruction = new AVMutableVideoCompositionInstruction();

CMTimeRange timeRangeMixComposition = new CMTimeRange(){
    Start = CMTime.Zero,
    Duration = mixComposition.Duration
};

instruction.TimeRange = timeRangeMixComposition;
AVAssetTrack videoTrack = mixComposition.TracksWithMediaType(AVMediaType.Video).First();
AVMutableVideoCompositionLayerInstruction layerInstruction = AVMutableVideoCompositionLayerInstruction.FromAssetTrack(videoTrack);
instruction.LayerInstructions = new AVVideoCompositionLayerInstruction[] {layerInstruction};
videoComposition.Instructions = new AVVideoCompositionInstruction[] {instruction};

// Export
AVAssetExportSession exporterSession = new AVAssetExportSession(mixComposition, AVAssetExportSession.PresetHighestQuality){
    OutputUrl = m_outputUrl,
    OutputFileType = AVFileType.QuickTimeMovie,
    ShouldOptimizeForNetworkUse = true,
    VideoComposition = videoComposition
};

exporterSession.ExportAsynchronously((() => {
    if (exporterSession.Status == AVAssetExportSessionStatus.Completed){
        NSUrl outputUrl = exporterSession.OutputUrl;
        ALAssetsLibrary library = new ALAssetsLibrary();
        if (library.VideoAtPathIsIsCompatibleWithSavedPhotosAlbum(outputUrl)){
            library.WriteVideoToSavedPhotosAlbumAsync(outputUrl);
        }
    })
    );
}

这会创建另一个视频文件,并在视频中显示我的文字整个持续时间。但是,我需要每秒多次更改overLayer的String属性。

  

overLayer.String

应显示当前的播放时间。

我查看了几个不同的选项,但无法实现更改视频中间的文字:

  • 我尝试添加不同的指令,但没有找到将指令直接与我的图层连接的方法(它与整个构图相关联)
  • 我查看了CATransaction:这允许我更改String属性,但它只是覆盖了初始值

    CATransaction.Begin();
    CATransaction.AnimationDuration = 2;
    overLayer.String = "Changed string on my video";
    CATransaction.AnimationTimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.Linear);
    CATransaction.Commit();
    
  • 我尝试将自定义选择器直接注册到overLayer,但无法运行。

我很感激任何帮助,Objective-C或Swift解决方案也会有所帮助。

编辑:上面的代码在C# - Xamarin.iOS

0 个答案:

没有答案