Search code examples
c#wpfvideorecordmediaelement

Recording video in C# and WPF from mediaElement


My application applies custom HLSL shader effects to a mediaElement using decorators. How can I record and save the modified video using the application itself in realtime?


Solution

  • I have been using the RenderTargetBitmap object to render image sequences of animations like this:

    First you call:

    myStoryboard.CurrentTimeInvalidated += new EventHandler(onCurrentTimeInvalidated );
    

    where myStoryboard is the Storyboard driving the animation and then you have the following method:

    void onCurrentTimeInvalidated (object sender, EventArgs e)
            {
                prefix = "";
                if (counter < 10)
                {
                    prefix = "000";
                }
                else if (counter < 100)
                {
                    prefix = "00";
                }
                else if (counter < 1000)
                {
                    prefix = "0";
                }
    
                Size size = new Size(MainCanvas.ActualWidth, MainCanvas.ActualHeight);
                MainCanvas.Measure(size);
                MainCanvas.Arrange(new Rect(size));
    
    
                RenderTargetBitmap bmp = new RenderTargetBitmap(imgWidth, imgHeight, 96d, 96d, PixelFormats.Default);
                bmp.Render(MainCanvas);
    
                JpegBitmapEncoder encoder = new JpegBitmapEncoder();
                encoder.QualityLevel = 90;
                encoder.Frames.Add(BitmapFrame.Create(bmp));
                string file = basePath + prefix + counter.ToString() + "_testpic.jpg";
                using (Stream stm = File.Create(file))
                {
                    encoder.Save(stm);
                }
                counter++;
            }
    

    I am not sure how well this will work with the MediaElement but it may be worth a try. For this to work on the MediaElement though you need to drive the MediaElement from a MediaTimeline and call the onCurrentTimeInvalidated method from it's CurrentTimeInvalidated event.