【问题标题】:Recording Video from Webcam with OpenCvSharp - Resulting File playback to fast使用 OpenCvSharp 从网络摄像头录制视频 - 使文件播放速度加快
【发布时间】:2021-09-18 06:22:42
【问题描述】:

我正在尝试使用 OpenCvSharp 从网络摄像头录制视频

我已经可以使用下面的代码录制视频,但生成的 .mp4 文件播放速度很快(例如,我录制了 5 秒,结果甚至不到一秒)。

我已经在AddCameraFrameToRecordingThread 中玩过延迟但无济于事

可能是什么问题?或者我可以使用其他什么库来从网络摄像头录制视频?

namespace BlackBears.Recording
{
    using System;
    using System.Drawing;
    using System.Threading;

    using OpenCvSharp;
    using OpenCvSharp.Extensions;

    using Size = OpenCvSharp.Size;

    public class Recorder : IDisposable
    {
        private readonly VideoCaptureAPIs _videoCaptureApi = VideoCaptureAPIs.DSHOW;
        private readonly ManualResetEventSlim _writerReset = new(false);
        private readonly VideoCapture _videoCapture;
        private VideoWriter _videoWriter;
        private Thread _writerThread;

        private bool IsVideoCaptureValid => _videoCapture is not null && _videoCapture.IsOpened();

        public Recorder(int deviceIndex, int frameWidth, int frameHeight, double fps)
        {
            _videoCapture = VideoCapture.FromCamera(deviceIndex, _videoCaptureApi);
            _videoCapture.Open(deviceIndex, _videoCaptureApi);

            _videoCapture.FrameWidth = frameWidth;
            _videoCapture.FrameHeight = frameHeight;
            _videoCapture.Fps = fps;
        }

        /// <inheritdoc />
        public void Dispose()
        {
            GC.SuppressFinalize(this);
            Dispose(true);
        }

        ~Recorder()
        {
            Dispose(false);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                StopRecording();

                _videoCapture?.Release();
                _videoCapture?.Dispose();
            }
        }

        public void StartRecording(string path)
        {
            if (_writerThread is not null)
                return;

            if (!IsVideoCaptureValid)
                ThrowHelper.ThrowVideoCaptureNotReadyException();

            _videoWriter = new VideoWriter(path, FourCC.XVID, _videoCapture.Fps, new Size(_videoCapture.FrameWidth, _videoCapture.FrameHeight));

            _writerReset.Reset();
            _writerThread = new Thread(AddCameraFrameToRecordingThread);
            _writerThread.Start();
        }

        public void StopRecording()
        {
            if (_writerThread is not null)
            {
                _writerReset.Set();
                _writerThread.Join();
                _writerThread = null;
                _writerReset.Reset();
            }

            _videoWriter?.Release();
            _videoWriter?.Dispose();
            _videoWriter = null;
        }

        private void AddCameraFrameToRecordingThread()
        {
            var waitTimeBetweenFrames = (int)(1_000 / _videoCapture.Fps);
            using var frame = new Mat();
            while (!_writerReset.Wait(waitTimeBetweenFrames))
            {
                if (!_videoCapture.Read(frame))
                    return;
                _videoWriter.Write(frame);
            }
        }
    }
}

【问题讨论】:

    标签: c# .net opencv


    【解决方案1】:

    在玩了很多之后,我自己找到了解决方案。

    单个线程来捕获帧并写入它们是不够的。 我现在创建了两个线程,一个从相机捕获帧,一个写入它们。要在生成的文件中获得正确的时序,必须考虑写入产生的延迟。

    我最终得到了以下两个在不同线程中运行的函数:

    private void CaptureFrameLoop()
    {
        while (!_threadStopEvent.Wait(0))
        {
            _videoCapture.Read(_capturedFrame);
        }
    }
    
    private void AddCameraFrameToRecordingThread()
    {
        var waitTimeBetweenFrames = 1_000 / _videoCapture.Fps;
        var lastWrite = DateTime.Now;
    
        while (!_threadStopEvent.Wait(0))
        {
            if (DateTime.Now.Subtract(lastWrite).TotalMilliseconds < waitTimeBetweenFrames)
                continue;
            lastWrite = DateTime.Now;
            _videoWriter.Write(_capturedFrame);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-10
      • 1970-01-01
      • 1970-01-01
      • 2017-09-16
      • 2020-11-24
      • 2021-06-30
      • 1970-01-01
      • 2012-05-25
      相关资源
      最近更新 更多