Reputation: 11319
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 System.IO;
using System.Threading;
using System.Diagnostics;
namespace ConvertVideo
{
public partial class Form1 : Form
{
string InputFile = @"C:\temp\video\new.avi";
string OutputFile = @"C:\temp\video\new.wmv";
string cmd;
string exepath = @"E:\myffmpegstatic\ffmpeg-20151217-git-9d1fb9e-win64-static\bin\ffmpeg.exe";
FileInfo fi;
public Form1()
{
InitializeComponent();
backgroundWorker1.WorkerReportsProgress = true;
fi = new FileInfo(InputFile);
label2.Text = InputFile;
cmd = " -i \"" + InputFile + "\" \"" + OutputFile + "\"";
backgroundWorker1.RunWorkerAsync();
}
private void ConvertNow(string cmd)
{
try
{
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = exepath;
proc.StartInfo.Arguments = cmd;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.RedirectStandardOutput = true;
// use this event
proc.OutputDataReceived += (sender, e) => backgroundWorker1.ReportProgress(0, e.Data); // use this for synchronization
proc.Start();
// and start asynchronous read
proc.BeginOutputReadLine();
// wait until it's finished in your background worker thread
proc.WaitForExit();
}
catch(Exception err)
{
string myerr = err.ToString();
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
ConvertNow(cmd);
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
textBox1.Text = e.ProgressPercentage.ToString();
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
}
}
What i want is to report both the progress and the data to the progresschanged event and updating the textbox1 and a progressBar(i have in the designer a progressBar1).
In the progressBar i want to report the convertion progress in percentages to 100%
Not sure how to make this reports but i'm sure it's not getting to the progresschanged event. Using a break point i see it's getting to the line:
backgroundWorker1.ReportProgress(0, e.Data);
In the deisgner in the backgroundworker properties WorkerReportsProgress is set to true.
Upvotes: 1
Views: 203
Reputation: 31393
Here you have said :
proc.OutputDataReceived += (sender, e) => backgroundWorker1.ReportProgress(0, e.Data);
So, you're sending the string
content of each line output by ffmpeg in the UserState
parameter of the event and you are sending 0
in the progress percentage. But in your ProgressChanged
handler you are only examining the ProgressPercentage
argument - the one to which you are only sending zeroes.
textBox1.Text = e.ProgressPercentage.ToString();
So...naturally you're not going to see anything in your textbox except for a zero.
If you drop a listbox on your form and try, for example :
private void backgroundWorker1_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
if (e.UserState != null)
{
listBox1.Items.Add(e.UserState.ToString());
}
}
You should find your listbox populates with the console output from ffmpeg
as it works. If you want to extract a percentage from this you'll have to parse the output and estimate based on the frame number or time index how far along you are.
For alternative ways to get progress from ffmpeg, see perhaps :
The answer above in in PHP, but it should give you some better ideas.
For a full working example that demonstrates your approach is otherwise sound, this uses ipconfig
(which everyone should have) and requires that Form1
have a backgroundworker with the ProgressChanged
and DoWork
events hooked up, as well as a listbox added to the form.
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.RunWorkerAsync();
}
private void GetIPInfo()
{
try
{
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = "ipconfig.exe";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.OutputDataReceived += (sender, e) =>
backgroundWorker1.ReportProgress(0, e.Data);
proc.Start();
proc.BeginOutputReadLine();
proc.WaitForExit();
}
catch (Exception err)
{
string myerr = err.ToString();
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
GetIPInfo();
}
private void backgroundWorker1_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
if (!(e.UserState == null))
{
listBox1.Items.Add(e.UserState.ToString());
}
}
}
}
Upvotes: 1