我已经在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
中