使用 Accord.NETC# 和 WPF录制时帧丢失

问题描述

我们在使用 .NETFramework 版本 v4.7.2 录制带有 Accord.NET 版本 3.8.2-alpha 的视频时遇到问题。我们使用这个旧版本的 Accord.NET 是因为有比最新版本更多的视频录制选项。
在使用以下代码的每个高分辨率记录中,视频丢失了一些帧并开始卡顿(似乎没有一致的滞后频率)。此外,我们使用 Windows 10 - 版本 20H2。我们在 Visual Studio 中的 “任何 cpu“x86” 调试模式下尝试了此代码
我们尝试以 30 fps 进行录制并发现 framesPerSecond_1 变量仅接收 24 帧。在此之后,我们尝试在 30 上手动设置此值,但遇到了同样的问题。此外,我们想要录制 10 秒,但录制的视频持续大约 15-20 秒(奇怪的是,资源管理器在属性显示它只能持续 10 秒)。所以视频也在慢动作播放。知道不存在性能问题也可能很有趣,因为即使我们同时使用两台摄像机进行录制,cpu 和 RAM 也永远不会达到它们的极限。
顺便说一下,代码不会抛出任何错误,如下所示:

using Accord.Video;
using Accord.Video.DirectShow;
using Accord.Video.FFMPEG;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace VideoRecord
{
    /// <summary>
    /// Interaction Logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private VideoCaptureDevice videoCaptureDevice;
        private VideoFileWriter videoFileWriter;
        private DateTime? _firstFrameTime = null;
        private bool recording = false;
        private readonly object balanceLock = new object();

        private void Button_Click(object sender,RoutedEventArgs e)
        {
            //Get connected video devices
            FilterInfoCollection devices = new FilterInfoCollection(FilterCategory.VideoInputDevice);

            //Our testing webcam
            videoCaptureDevice = new VideoCaptureDevice(devices[3].MonikerString);

            //Register new frame method
            videoCaptureDevice.NewFrame += new NewFrameEventHandler(showPreview);
            videoCaptureDevice.Start();

            //Setting properties for the file
            videoFileWriter = new VideoFileWriter();

            int width = 1920;
            int height = 1080;

            int temp_1 = videoCaptureDevice.FramesReceived;
            Thread.Sleep(1000);
            int framesPerSecond_1 = videoCaptureDevice.FramesReceived;

            int bitRate_1 = width*height*framesPerSecond_1;


            videoFileWriter.BitRate = bitRate_1;
            videoFileWriter.Width = width;
            videoFileWriter.Height = height;
            videoFileWriter.FrameRate = framesPerSecond_1;
            videoFileWriter.VideoCodec = VideoCodec.H264;

            //Tried to use the following lines because of an other forum
            //videoFileWriter.VideoOptions["preset"] = "ultrafast";
            //videoFileWriter.VideoOptions["tune"] = "zerolatency";
            videoFileWriter.VideoOptions["x264opts"] = "no-mbtree:sliced-threads:sync-lookahead=0";

            //Open the folder where the video should get stored and start recording
            videoFileWriter.Open("C:\\Storage\\videos\\"+DateTime.Now.Ticks+".mp4");
            recording = true;

            //Record for 10 seconds
            Thread.Sleep(10000);

            //Stop recording
            videoCaptureDevice.SignalToStop();
            videoCaptureDevice.WaitForStop();

            videoFileWriter.Close();
            videoFileWriter.Flush();
            videoFileWriter.dispose();

            recording = false;
            _firstFrameTime = DateTime.Now;
        }

        private void showPreview(object sender,Accord.Video.NewFrameEventArgs eventArgs)
        {

            try
            {
                //Get the image from the camera
                Bitmap img = eventArgs.Frame;

                //Get the timestamp between every frame
                var frameTimestamp = _firstFrameTime - DateTime.Now;
                if (recording)
                {
                    //We don't kNow if "lock" helps but we tried it
                    lock (balanceLock)
                    {
                        //Record the video if the button is clicked
                        videoFileWriter.WriteVideoFrame(img,(TimeSpan)frameTimestamp);
                    }
                }
            }
            catch (Exception ex)
            {
            }
        }
    }
}

有人知道解决办法吗?
提前致谢!

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)