私はmp4ビデオに追加するオーバーレイ画像に適用したいアニメーションに関してあなたの助けが必要です。ビデオにオーバーレイを追加するには、私はここでRay Wenderlichのチュートリアルに従った:https://www.raywenderlich.com/30200/avfoundation-tutorial-adding-overlays-and-animations-to-videos。そのリンクの最後に、アニメーションがオーバーレイ上に作成されます。Xamarin.iosでAVAssetExportSessionを使用している場合、アニメーションをCALayerに正しく追加するにはどうすればよいですか?
レイWenderlichは、C#でコーディングされていませんが、私は私のアプリを作成するためにXamarinを使用するので、私はやります。 アニメーションを使用すると、ビデオの最初の1秒間にオーバーレイが消えてしまいます。しかし、何も起こりません。私はビデオを除いてアニメーション化されたものは何も起こらないことを意味します:オーバーレイはビデオの上に置かれますが、消えません。
はポストのほとんどは私がアニメーションについて読むと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;
}
});
}