ProgressBar added to WPF

<ProgressBar x:Name="progressBar1" HorizontalAlignment="Left" Height="10" Margin="80,160,0,0" VerticalAlignment="Top" Width="400" Minimum="0" Maximum="100"/> 

This function normally recodes video. But does not use ProgressBar

 public void StartConvert() { var waitFlag = true; var path_ffmpeg = @"ffmpeg-20161107-34aeb5d-win32-static\bin\ffmpeg.exe"; var i = @"..\..\"; var dir_data = new DirectoryInfo(i + @"_data\"); var fullpath_ffmpeg = dir_data + path_ffmpeg; string outfile = " -i \"" + filefullname1 + "\" -codec:v libvpx -crf 10 -b:v 1M -f webm " + filefullname2; System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(); psi.FileName = filefullname1; psi.Arguments = outfile; psi.UseShellExecute = true; psi.CreateNoWindow = false; // System.Diagnostics.Process p = System.Diagnostics.Process.Start(psi); Thread.Sleep(1000);// utput.webm // p.WaitForExit(); if (waitFlag) { p.WaitForExit(); // wait for exit of called application } } 

This is taken from the Internet. http://www.freesmartsoft.com/Blog/Review?id=4

  private void button_Click(object sender, RoutedEventArgs e) { //StartConvert2(); StartConvert(); } 

Updated

  double duration = 0; string outString = null; while (!m_streamReader.EndOfStream) { outString = m_streamReader.ReadLine(); if ((duration == 0) && outString.Contains("Duration: ")) { //progress.Report(10); int index = outString.IndexOf(","); TimeSpan span = TimeSpan.Parse(outString.Remove(index).Remove(0, 10).Trim(new char[] { Convert.ToChar(":") }).Trim()); duration = span.TotalSeconds; } // Progress if ((duration > 0) && outString.Contains("time=")) { //progress.Report(50); string startStr = " time="; string stopStr = " bitrate="; int startIndex = outString.IndexOf(startStr); if (startIndex > 0) { int stopIndex = outString.IndexOf(stopStr); string time = outString.Substring(startIndex + startStr.Length, stopIndex - startIndex - startStr.Length); //double progress = 100.0 * double.Parse(time, m_culture.NumberFormat) / progressBar1.Value; var progress2 = 100.0 * double.Parse(time, m_culture.NumberFormat) / duration; m_progress = (int)progress2; } } progress.Report(m_progress); // progress.Report(80); } 
  • Judging by the code, it is executed in the GUI thread. It is necessary to take it to a separate thread. - Alexander Petrov
  • And in general, instead of calling the console ffmpeg, I would try to search the nuget for a ready-made managed wrapper. - Alexander Petrov

1 answer 1

Tasks that require a long wait, for example, some kind of complex calculation, or here's how video transcoding is done, should be run in a separate Thread from the UI thread. This avoids freezing the interface, i.e. the impression that the application is frozen, and also allows you to display the progress and the result of this complex and lengthy calculation by referring to the special object Dispatcher .

Specifically for your case you can do the following: 1) in the button_Click method you need to use a special class class Progress<T> : IProgress<T>

  var progress = new Progress<int>((p) => { progessBar1.Value = p; }); 

and the video transcoding method should be run asynchronously from the UI and pass the Progress instance to it, so

  try { //Запускаем асинхронно задачу await Task.Run(() => StartConvert2(progress)); // допишите async перед void у button_Click } catch (Exception ex) { MessageBox.Show(ex.Message, "Ошибка!"); } 

2) in the StartConvert2 conversion method itself, you can change the value of the progress bar like this progress.Report(i) where i is an integer value expressing the percentage of the done.

public void StartConvert2(IProgress<int> progress) as an interface parameter must be specified, this is important!

  • public void StartConvert2(Progress<int> progress) ... progress.Report(i) - Progress <int> does not contain a definition for Report - codename0082016
  • one
    @ codename0082016 Must be public void StartConvert2(IProgress<int> progress) i.e. The type of parameter is interface, not class - Bulson
  • one
    Turn off @ codename0082016 and the launch button, and after completing the task, turn on (in the finally block) to avoid double-triple launch of the same task for video transcoding. - Bulson
  • progress2 = 100.0 * double.Parse(time, m_culture.NumberFormat) / progress2; An exception of the type "System.FormatException" occurred in mscorlib.dll, but was not processed in user code Additional information: The input string had the wrong format. - codename0082016
  • what is progress2? You cannot directly access interface elements from an asynchronous task, so if you attempt to divide by the value of the progress bar, there will indeed be an error. You should only transfer to progress in the progress, but not try to get something from there, save the past solution to the temporary variable and then divide it into it. - Bulson