- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
目标是控制 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();
}
}
它工作正常但速度太快。我想使用计时器,或允许我控制帧提取速度的东西。
最佳答案
我建议对当前代码进行一些更改(实际上相当多:)。
要点:
Progress<Bitmap>
类型,在此处命名为 videoProgress
)将新数据编码到 UI 线程,用于更新 PictureBox 控件。委托(delegate)方法名为 Updater
Image
图片框的属性重要提示:
VideoFileReader
的位图返回必须处理。如果不这样做,您将看到图形资源消耗的增加,而且这种情况不会停止SizeMode = Zoom
并最大化表单(设置 PictureBox 的 Zoom
模式会影响性能,您应该改为调整位图的大小) buttonStart_Click
, buttonStop_Click
和 buttonPause_Click
是用于开始、停止和暂停播放的按钮的点击处理程序。syncRoot
object 在这里不是严格要求的,但保留在那里,它可能在某些时候有用
using System.Drawing;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Accord.Video.FFMPEG;
public partial class Form1 : Form
{
Bitmap frame = null;
Graphics frameGraphics = null;
bool isVideoRunning = false;
IProgress<Bitmap> videoProgress = null;
private CancellationTokenSource cts = null;
private readonly object syncRoot = new object();
private static long pause = 0;
public Form1() => InitializeComponent();
private async void buttonStart_Click(object sender, EventArgs e) {
string fileName = "[The Video File Path]";
if (isVideoRunning) return;
isVideoRunning = true;
using (var videoReader = new VideoFileReader()) {
videoReader.Open(fileName);
frame = new Bitmap(videoReader.Width + 2, videoReader.Height + 2);
trackBar1.Maximum = (int)videoReader.FrameCount;
}
videoProgress = new Progress<Bitmap>(Updater);
cts = new CancellationTokenSource();
pictureBox1.Image = frame;
try {
frameGraphics = Graphics.FromImage(frame);
// Set the frame rate to 25 frames per second
int frameRate = 1000 / 25;
await GetVideoFramesAsync(videoProgress, fileName, frameRate, cts.Token);
}
finally {
StopPlayback(false);
frameGraphics?.Dispose();
pictureBox1.Image?.Dispose();
pictureBox1.Image = null;
buttonPause.Text = "Pause";
pause = 0;
isVideoRunning = false;
}
}
private void buttonStop_Click(object sender, EventArgs e) => StopPlayback(true);
private void buttonPause_Click(object sender, EventArgs e)
{
if (pause == 0) {
buttonPause.Text = "Resume";
Interlocked.Increment(ref pause);
}
else {
Interlocked.Decrement(ref pause);
buttonPause.Text = "Pause";
}
}
private void StopPlayback(bool cancel) {
lock (syncRoot) {
if (cancel) cts?.Cancel();
cts?.Dispose();
cts = null;
}
}
private void Updater(Bitmap videoFrame) {
using (videoFrame) frameGraphics.DrawImage(videoFrame, Point.Empty);
pictureBox1.Invalidate();
}
private async Task GetVideoFramesAsync(IProgress<Bitmap> updater, string fileName, int intervalMs, CancellationToken token = default) {
using (var videoReader = new VideoFileReader()) {
if (token.IsCancellationRequested) return;
videoReader.Open(fileName);
while (true) {
if (token.IsCancellationRequested) break;
// Resumes on a ThreadPool Thread
await Task.Delay(intervalMs).ConfigureAwait(false);
if (Interlocked.Read(ref pause) == 0) {
var frame = videoReader.ReadVideoFrame();
if (frame is null) break;
updater.Report(frame);
}
}
}
}
protected override void OnFormClosing(FormClosingEventArgs e) {
if (isVideoRunning) StopPlayback(true);
base.OnFormClosing(e);
}
}
关于c# - 如何计时从视频文件中显示和提取帧?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74157315/
我正在做一个业余爱好项目,使用 Ruby、PHP 或 Java 来抓取 ASP.net 网站的内容。例如,如果网站 url“www.myaspnet.com/home.aspx”。我想从 home.a
如果我有这些字符串: mystrings <- c("X2/D2/F4", "X10/D9/F4", "X3/D22/F4",
我有以下数据集 > head(names$SAMPLE_ID) [1] "Bacteria|Proteobacteria|Gammaproteobacteria|Pseudomonadales|Mor
设置: 3个域类A,B和C。A和B在插件中。 C在依赖于此插件的应用程序中。 class A{ B b static mapping = { b fetch: 'joi
我不知道如何提取 XML 文件中的开始标记元素名称。我很接近〜意味着没有错误,我正在获取标签名称,但我正在获取标签名称加上信息。我得到的是: {http://www.publishing.org}au
我有一个字符串 x <- "Name of the Student? Michael Sneider" 我想从中提取“Michael Sneider”。 我用过: str_extract_all(x,
我有一个如下所示的文本文件: [* content I want *] [ more content ] 我想读取该文件并能够提取我想要的内容。我能做的最好的事情如下,但它会返回 [更多内容] 请注意
假设我有一个项目集合 $collection = array( 'item1' => array( 'post' => $post, 'ca
我正在寻找一种过滤文本文件的方法。我有许多文件夹名称,其中包含许多文本文件,文本文件有几个没有人员,每个人员有 10 个群集/组(我在这里只显示了 3 个)。但是每个组/簇可能包含几个原语(我在这里展
我已经编写了一个从某个网页中提取网址的代码,我面临的问题是它不会以网页上相同的方式提取网址,我的意思是如果该网址位于某些网页中法语,它不会按原样提取它。我该如何解决这个问题? import reque
如何在 C# 中提取 ZipFile?(ZipFile 是包含文件和目录) 最佳答案 为此使用工具。类似于 SharpZip .据我所知 - .NET 不支持开箱即用的 ZIP 文件。 来自 here
我有一个表达: [training_width]:lofmimics 我要提取[]之间的内容,在上面的例子中我要 training_width 我试过以下方法: QRegularExpression
我正在尝试创建一个 Bash 脚本,该脚本将从命令行给出的最后一个参数提取到一个变量中以供其他地方使用。这是我正在处理的脚本: #!/bin/bash # compact - archive and
我正在寻找一个 JavaScript 函数/正则表达式来从 URI 中提取 *.com...(在客户端完成) 它应该适用于以下情况: siphone.com = siphone.com qwr.sip
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 8 年前。 Improve this qu
编辑:添加了实际的 JSON 对象和代码以供审查 我有这种格式的 JSON(只是这种层次结构,假设 JSON 正常工作) {u'kind': u'calendar#events', u'default
我已经编写了代码来使用 BeautifulSoup 提取一本书的 url 和标题来自页面。 但它并没有在 > 之间提取惊人的 super 科学故事 1930 年 4 月这本书的名字。和 标签。 如何提
使用 Java,我想提取美元符号 $ 之间的单词。 例如: String = " this is first attribute $color$. this is the second attribu
您好,我正在尝试找到一种方法来确定字符串中的常量,然后提取该常量左侧的一定数量的字符。 例如-我有一个 .txt 文件,在那个文件的某处有数字 00nnn 数字的例子是 00234 00765 ...
php读取zip文件(删除文件,提取文件,增加文件)实例 从zip压缩文件中提取文件 复制代码 代码如下: <?php /* php 从zip压缩文件
我是一名优秀的程序员,十分优秀!