目标是控制BackGroundWorker的DoWork
事件中的帧提取速度。
我尝试了Thread.Sleep()
,但它抛出了异常。
这就是我想做的。上面和下面都有描述。
using Accord.Video;
using Accord.Video.FFMPEG;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
using (var vFReader = new VideoFileReader())
{
vFReader.Open(@"C:\Users\Chocolade 1972\Downloads\MyVid.mp4");
trackBar1.Maximum = (int)vFReader.FrameCount;
}
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
using (var vFReader = new VideoFileReader())
{
vFReader.Open(@"C:\Users\Chocolade 1972\Downloads\MyVid.mp4");
for (var i = 0; i < vFReader.FrameCount; i++)
{
backgroundWorker1.ReportProgress(0, vFReader.ReadVideoFrame());
}
// Not sure that this would be required as it might happen implicitly at the end of the 'using' block.
vFReader.Close();
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
pictureBox1.Image?.Dispose();
pictureBox1.Image = (Image)e.UserState;
}
private void Form1_Resize(object sender, EventArgs e)
{
label1.Text = this.Size.ToString();
}
}
我想使用一个计时器,或者其他可以控制帧提取速度的东西。
1条答案
按热度按时间raogr8fs1#
我建议对当前代码进行一些修改(实际上很多修改:)。
要点:
1.创建一个异步方法来执行视频播放。VideoFileReader在ThreadPool线程(实际上是2个)上工作,它不会导致窗体冻结
1.使用IProgress委托(类型为
Progress<Bitmap>
,此处名为videoProgress
),该委托将用于更新PictureBox控件的新数据封送到UI线程。该委托方法名为Updater
1.使用单个Bitmap对象,设置为PictureBox的
Image
属性1.使用从此Bitmap派生的Graphics对象绘制视频帧。这允许包含所使用的资源。PictureBox只是无效,以显示Bitmap的当前内容
1.允许视频播放方法接受一个帧速率值,这里设置为每秒25帧。当然,它可以适应于减慢或加快播放(注意,设置超过每秒32~35帧,你开始丢失一些帧)
1.使用CancellationTokenSource向视频播放方法发出信号,以在播放处于活动状态时按下“停止”按钮或关闭窗体时停止播放并终止
重要提示:
VideoFileReader
返回的位图必须被释放。如果你不这样做,你将看到图形资源消耗的增加,这是不会停止的当然,当您打开此窗体并创建容器Bitmap时,资源会略有增加,但当窗体关闭时,会回收少量资源
SizeMode = Zoom
并最大化窗体(设置PictureBox的Zoom
模式会影响性能,您应该改为调整位图的大小)buttonStart_Click
、buttonStop_Click
和buttonPause_Click
是用于开始、停止和暂停播放的Button的Click处理程序。syncRoot
对象在这里并不是严格必需的,但请将其保留在那里,它在某些时候可能会变得有用