0

私は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; 
      } 
     }); 

    } 

答えて

0

OK:

これは私が書いた関数です。それを見つけた。明らかに、animation.BeginTime = 0;はサポートされていません。私は0.01に変更し、すべて正常に動作します。

double Epsilon = 0.01; 

     if (secondsToFade > videoAsset.Duration.Seconds - Epsilon) 
      secondsToFade = videoAsset.Duration.Seconds - Epsilon; 

     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; 

     //On crée l'animation pour le CAlayer 
     CABasicAnimation animation = CABasicAnimation.FromKeyPath(@"opacity"); 
     animation.BeginTime = Epsilon; 
     animation.Duration = secondsToFade; 
     animation.SetFrom (NSNumber.FromFloat (1)); 
     animation.SetTo (NSNumber.FromFloat(0)); 
     animation.FillMode = CAFillMode.Forwards; 
     animation.RemovedOnCompletion = false; 
関連する問題