I am building an application that imports numerous video files from a file picker and runs them all through EXIFTOOL to get the metadata of each file. A list of VideoFileModel is returned after all of the videos have been processed. This all works great 99.99% of the time; however, I have come across one video file that halts execution of my application. I am not sure if the video is corrupted or what. It is the only one I have come across that provides this error but surely this will happen again one day so I need a fix.
When my application launches the process for EXIFTOOL for this video, the process window stays open and execution stops. If I physical close the process window, the data is processed and execution continues with no errors. It seems that the process is stuck. Execution is halted because of the following await:
var metaDataResults = await System.Threading.Tasks.Task.WhenAll(metaTasks);
My code after this relies of the data that is being returned to metaDataResults. I have tried to kill the process manually with process.Kill() and process.Close() but the window stays open until I physically close it. I have heard that there can result a “Dead Lock” in EXIFTOOL if standard output and standard error are both redirecting. I am not redirecting standard error only output. I have tested with standard error and is returns nothing.
Below is the code from initial button click:
private async void ImportVideoButton_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Multiselect = true;
if (openFileDialog.ShowDialog() == true)
{
List<Task<Models.VideoFileModel>> metaTasks = new List<Task<VideoFileModel>>();
foreach (string file in openFileDialog.FileNames)
{
foreach (var video in _viewModel.AllLightningVideos)
{
if (file == video.VideoPath)
{
video.VideoName = video.VideoName + "_";
}
}
metaTasks.Add(System.Threading.Tasks.Task.Run(() => _viewModel.ProcessMetaData(file)));
}
// EXECUTION STOPS AT THE CODE BELOW PRESUMMINGLY BECUASE THE PROCESS WILL NOT FINISH
var metaDataResults = await System.Threading.Tasks.Task.WhenAll(metaTasks);
ProcessMetaData returns a VideoFileModel after calling the method getExifDataViaTool. Below is the code for that method:
public static Dictionary<string, string> getExifDataViaTool(string sourceFile, string parameters = "-a -api largefilesupport=1")
{
var result = new Dictionary<string, string>();
sourceFile = Regex.Replace(sourceFile, @"(\\*)" + "\"", @"$1\$0");
sourceFile = Regex.Replace(sourceFile, @"^(.*\s.*?)(\\*)$", "\"$1$2$2\"");
var argumentsString = parameters + " " + sourceFile;
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
string ExifToolPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "FFMPEG\\exiftool.exe");
startInfo.FileName = ExifToolPath;
startInfo.Arguments = argumentsString;
startInfo.RedirectStandardOutput = true;
//startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = false;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo = startInfo;
process.Start();
string output = process.StandardOutput.ReadToEnd();
process.WaitForExit(1000);
string[] lines = output.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
foreach (var line in lines)
{
var pair = line.Split(new char[] { ':' }, 2);
if (pair.Length >= 2)
{
var key = pair[0].TrimEnd();
var value = pair[1].TrimStart();
result[key] = value;
Debug.WriteLine(key + " : :" + value);
}
}
return result;
}
Any help would be appreciated!