dotnet / wpf

WPF is a .NET Core UI framework for building Windows desktop applications.
MIT License
7.05k stars 1.17k forks source link

Create a video from WPF animation. #6453

Open zydjohnHotmail opened 2 years ago

zydjohnHotmail commented 2 years ago

Hello: I am using WPF for C# target .NET 6.0; I have Visual Studio 2022 (Version 17.1.4) and also VS 2022 Preview (Preview Version 17.2.0 Preview 3.0) on Windows 10 (Version 21H2). I can write some C# code to generate animation, like the following code:

using System; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Shapes; using System.Windows.Media.Animation;

namespace WpfApplication1 { public partial class MainWindow : Window { private Storyboard myStoryboard;

    public MainWindow()
    {
        InitializeComponent();

        StackPanel myPanel = new StackPanel();
        myPanel.Margin = new Thickness(10);

        Rectangle myRectangle = new Rectangle();
        myRectangle.Name = "myRectangle";
        this.RegisterName(myRectangle.Name, myRectangle);
        myRectangle.Width = 100;
        myRectangle.Height = 100;
        myRectangle.Fill = Brushes.Blue;

        DoubleAnimation myDoubleAnimation = new DoubleAnimation();
        myDoubleAnimation.From = 1.0;
        myDoubleAnimation.To = 0.0;
        myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(5));
        myDoubleAnimation.AutoReverse = true;
        myDoubleAnimation.RepeatBehavior = RepeatBehavior.Forever;

        myStoryboard = new Storyboard();
        myStoryboard.Children.Add(myDoubleAnimation);
        Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);
        Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(Rectangle.OpacityProperty));

        // Use the Loaded event to start the Storyboard.
        myRectangle.Loaded += new RoutedEventHandler(myRectangleLoaded);
        myPanel.Children.Add(myRectangle);
        this.Content = myPanel;
    }

    private void myRectangleLoaded(object sender, RoutedEventArgs e)
    {
        myStoryboard.Begin(this);
    }
}

}

I want to know if there is any built-in or other “decent” way to create a MP4 format video to save the animation. So, I can play it with Windows Media Player or any other MP4 player, like VLC player. I know this way will work: using a 3rd party screen recording software to record the screen area where the animation took place. However, this seems not a “decent” way. I want to be able to control the frame rate like: either 25 or 30 FPS or other custom FPS, and I want to be able to control the resolution of the image/video for 720P or 1080P. For rotating animation, I want to save each 10 degree rotation as one frame, so for 360 degree rotation, the FPS will be 36. Using a 3rd party screen recording software is not so “decent”. I hope there is some built-in feature in WPF, but since there is documents for WPF in .NET 6.0 yet, I can only read WPF for .NET Framework 4.x; or if there is such feature in .NET MAUI in preview version can do this. Then, please share some code or provide some URL where I can find useful information for this topic. I believe this should be a built-in feature in WPF, otherwise, how you can save your visual effect using a publicly accessible format? Do you want all the people to install WPF with Visual Studio to view your WPF program in source code format? Thanks,

lindexi commented 2 years ago

I know this way will work: using a 3rd party screen recording software to record the screen area where the animation took place. However, this seems not a “decent” way.

This is the recommended way. It hard to make everyone happy when we try add this "feature" to framework.

ThomasGoulet73 commented 2 years ago

I don't think this should be a built-in feature in WPF. I think it would be very complicated to do because of the complexity of creating a video (Video codecs, container types, hardware acceleration, etc). Also, I don't think the need to create a video from a specific animation is very common.

That being said, another way to do what you want would be to render the control to images frame by frame and then merge the images to a video using separate tool (E.g. ffmpeg). You can look at this post on stackoverflow to see how to render the control to images frame by frame.

Using 3rd party screen recording software remains the easiest way to do this.

miloush commented 2 years ago

I did this in my life. :-) Basically, I was going through the animation frame by frame and using RenderTargetBitmap to render the visual. I was writing it out directly as an uncompressed AVI file (and then used external tools to add audio and encode it to mp4). More recently I used Media Foundation directly to encode camera stream into mp4.

As surprising it may be, I would actually support WPF adding bult-in support for MF, like it did for WIC.