내가 mp4 비디오에 추가하는 오버레이 이미지에 적용하려는 애니메이션과 관련하여 도움이 필요합니다. 비디오에 오버레이를 추가하려면 여기에서 Ray Wenderlich 자습서 (https://www.raywenderlich.com/30200/avfoundation-tutorial-adding-overlays-and-animations-to-videos)를 따랐습니다. 해당 링크가 끝나면 오버레이에서 애니메이션이 만들어집니다.Xamarin.ios에서 AVAssetExportSession을 사용할 때 어떻게 CALayer에 애니메이션을 추가 할 수 있습니까?
Ray Wenderlich는 C#으로 코딩하지 않지만 Xamarin을 사용하여 내 응용 프로그램을 만든 이후로 사용합니다. 애니메이션을 사용하면 오버레이가 비디오 초반부에 사라집니다. 그러나 아무 일도 일어나지 않습니다. 동영상을 제외하고는 애니메이션이 적용되지 않습니다. 오버레이는 동영상 상단에 잘 표시되지만 사라지지 않습니다.
내가 애니메이션과 CALayer에 대해 읽은 대부분의 게시물은 UIView 내에서 애니메이션을 만듭니다.
나는 스스로에게 묻습니다. 애니메이션을 사용하고 있지 않기 때문에 C#을 사용했거나 잘못된 것을 작성 했습니까?
누군가 제발 도와 줄 수 있습니까?
public static void addFadeOverlayAtTheBeginning (NSUrl source, String overlay, long secondsToFade, NSUrl destination)
{
AVUrlAsset videoAsset = new AVUrlAsset(source);
if (secondsToFade > videoAsset.Duration.Seconds)
secondsToFade = (long)videoAsset.Duration.Seconds;
CALayer overlayLayer = CALayer.Create();
UIImage image = new UIImage(overlay);
image.CreateResizableImage(new UIEdgeInsets(0, 0, videoAsset.NaturalSize.Width, videoAsset.NaturalSize.Height));
overlayLayer.Contents = image.CGImage;
overlayLayer.Frame = new CGRect(0, 0, videoAsset.NaturalSize.Width, videoAsset.NaturalSize.Height);
overlayLayer.MasksToBounds = true;
CABasicAnimation animation = CABasicAnimation.FromKeyPath(@"opacity");
animation.BeginTime = 0; // GetSeconds(image.CGImage.StartTime);
animation.Duration = secondsToFade;
animation.SetFrom (NSNumber.FromFloat (1));
animation.SetTo (NSNumber.FromFloat(0));
overlayLayer.AddAnimation(animation, @"opacity");
AVMutableComposition videoComposition = AVMutableComposition.Create();
AVMutableCompositionTrack track = videoComposition.AddMutableTrack(AVMediaType.Video, 0);
AVAssetTrack sourceVideoTrack = videoAsset.TracksWithMediaType(AVMediaType.Video)[0];
CMTimeRange timeRangeInAsset = new CMTimeRange();
timeRangeInAsset.Start = CMTime.Zero;
timeRangeInAsset.Duration = videoAsset.Duration;
NSError videoInsertError = null;
track.InsertTimeRange(timeRangeInAsset, sourceVideoTrack, CMTime.Zero, out videoInsertError);
track.PreferredTransform = sourceVideoTrack.PreferredTransform;
CALayer parentLayer = CALayer.Create();
CALayer videoLayer = CALayer.Create();
parentLayer.Frame = new CGRect(0, 0, videoAsset.NaturalSize.Width, videoAsset.NaturalSize.Height);
videoLayer.Frame = new CGRect(0, 0, videoAsset.NaturalSize.Width, videoAsset.NaturalSize.Height);
parentLayer.AddSublayer(videoLayer);
parentLayer.AddSublayer(overlayLayer);
//parentLayer.AddAnimation(animation, "opacity");
AVMutableVideoComposition animationComposition = AVMutableVideoComposition.Create(); //videoComposition
animationComposition.AnimationTool = AVVideoCompositionCoreAnimationTool.FromLayer(videoLayer, parentLayer);
animationComposition.RenderSize = videoAsset.NaturalSize;
animationComposition.FrameDuration = new CMTime(1, 30);
AVMutableVideoCompositionInstruction instruction = AVMutableVideoCompositionInstruction.Create() as AVMutableVideoCompositionInstruction;
CMTimeRange timeRangeInstruction = new CMTimeRange();
timeRangeInstruction.Start = CMTime.Zero;
timeRangeInstruction.Duration = videoComposition.Duration;
instruction.TimeRange = timeRangeInstruction;
AVMutableVideoCompositionLayerInstruction layerInstruction = AVMutableVideoCompositionLayerInstruction.FromAssetTrack(track);
CMTimeRange timeRangeFading = new CMTimeRange();
timeRangeFading.Start = CMTime.Zero;
timeRangeFading.Duration = new CMTime(secondsToFade, 1);
//layerInstruction.SetOpacityRamp(1, 0, timeRangeFading);
instruction.LayerInstructions = new AVVideoCompositionLayerInstruction[] { layerInstruction };
List<AVVideoCompositionInstruction> instructions = new List<AVVideoCompositionInstruction>();
instructions.Add(instruction);
animationComposition.Instructions = instructions.ToArray();
if (File.Exists(destination.Path))
File.Delete(destination.Path);
AVAssetExportSession exporter = new AVAssetExportSession(videoComposition, AVAssetExportSession.PresetHighestQuality);
exporter.OutputUrl = destination;
exporter.VideoComposition = animationComposition;
exporter.OutputFileType = AVFileType.Mpeg4;
exporter.ExportAsynchronously(() => {
VideoManagement.state ++;
AVAssetExportSessionStatus status = exporter.Status;
Console.WriteLine("addFadeOverlayAtTheBeginning Done. Status: " + status.ToString());
switch (status)
{
case AVAssetExportSessionStatus.Completed:
Console.WriteLine("Sucessfully Completed");
if (File.Exists(destination.Path))
{
Console.WriteLine(String.Format("Saved to {0}", destination.Path));
}
else
Console.WriteLine("Failed");
break;
case AVAssetExportSessionStatus.Cancelled:
break;
case AVAssetExportSessionStatus.Exporting:
break;
case AVAssetExportSessionStatus.Failed:
Console.WriteLine("Task failed => {0}", exporter.Error);
Console.WriteLine(exporter.Error.Description);
break;
case AVAssetExportSessionStatus.Unknown:
break;
case AVAssetExportSessionStatus.Waiting:
break;
default:
break;
}
});
}