【发布时间】:2017-06-08 16:56:47
【问题描述】:
使用以下代码,我将视频从网络摄像头录制并保存到磁盘。但即使是 3 秒的视频,也可以保存大约 50 MB 的文件大小。我假设我在滥用 VideoWriter 类。有什么建议?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.CV.Structure;
namespace EmguCV_Webcam
{
public partial class Form1 : Form
{
#region Private variables
private Capture currentDevice;
private VideoWriter videoWriter;
private bool recording;
private int videoWidth;
private int videoHeight;
#endregion
#region Constructors
public Form1()
{
InitializeComponent();
InitializeVariables();
AttachButtonMacros();
StartVideoFeed();
}
#endregion
#region Methods
private void InitializeVariables()
{
currentDevice = new Capture(0);
recording = false;
videoWidth = currentDevice.Width;
videoHeight = currentDevice.Height;
}
private void StartVideoFeed()
{
currentDevice.Start();
currentDevice.ImageGrabbed += CurrentDevice_ImageGrabbed;
}
private void AttachButtonMacros()
{
StartRecordingButton.Click += StartRecordingButton_Click;
StopRecordingButton.Click += StopRecordingButton_Click;
}
private void CurrentDevice_ImageGrabbed(object sender, EventArgs e)
{
Mat m = new Mat();
currentDevice.Retrieve(m);
VideoPictureBox.Image = m.ToImage<Bgr, byte>().Bitmap;
if (recording && videoWriter != null)
{
videoWriter.Write(m);
}
}
private void StartRecordingButton_Click(object sender, EventArgs e)
{
recording = true;
SaveFileDialog dialog = new SaveFileDialog();
dialog.DefaultExt = ".avi";
dialog.AddExtension = true;
dialog.FileName = DateTime.Now.ToString();
DialogResult dialogResult = dialog.ShowDialog();
if(dialogResult != DialogResult.OK)
{
return;
}
videoWriter = new VideoWriter(dialog.FileName, 30, new Size(videoWidth, videoHeight), true);
}
private void StopRecordingButton_Click(object sender, EventArgs e)
{
recording = false;
if(videoWriter != null)
{
videoWriter.Dispose();
}
}
#endregion
}
}
【问题讨论】:
-
听起来您正在编写未压缩的视频。您需要选择一个编解码器来减小该尺寸。这是在 Linux 还是 Windows 上?我问的原因是因为docs state,您在代码中使用的构造函数应该在 Windows 上“打开编解码器选择对话框”,但在 Linux 中“将使用默认编解码器”。你试过this constructor吗?
-
谢谢,刚刚尝试过,但是现在它会导致更多问题。首先,除非我为 x86 配置 Visual Studio,否则它会使程序崩溃。当我使用提示用户选择编解码器的构造函数时,我得到以下选择:Radius 的 Cinepak 编解码器、Logitech Video (I420)、英特尔 IYUV 编解码器、Microsoft RLE、Microsoft Video 1 和全帧(未压缩)。有些,包括第一个,会导致错误:
-
System.AccessViolationException 发生 HResult=0x80004003 消息=尝试读取或写入受保护的内存。这通常表明其他内存已损坏。 Source=Emgu.CV.World StackTrace: 在 Emgu.CV.CvInvoke.cveVideoWriterWrite(IntPtr writer, IntPtr image) 在 Emgu.CV.VideoWriter.Write(Mat frame) 在 EmguCV_Webcam.Form1.CurrentDevice_ImageGrabbed(Object sender, EventArgs e) in c:\users\yoga 710\documents\visual studio 2017\Projects\EmguCV_Webcam\EmguCV_Webcam\Form1.cs:第 70 行在 Emgu.CV.Capture.Grab() 在 Emgu.CV.Capture.Run()
-
其余编解码器要么将视频保存到不可播放状态,要么根本不压缩视频。必须有一种方法可以在不崩溃的情况下压缩视频...
-
我建议研究一下 FFMPEG 可以带来什么。
标签: c# video-capture emgucv video-encoding webcam-capture