Hi,
I am running 3 threads that each start an ffmpeg process to extract 3 snapshots form a video file.
I need to be able to call this method multiple times, with different video files.
It writes the three snapshots to the system.
However If I try to delete these files using File.Delete, it throws an exception.
Here is the code:
namespace runFFmpeg
{
public struct ThreadData
{
public string time;
public string inputFilename;
public string outputFilename;
}
/// <summary>
/// Description of MyClass.
/// </summary>
public class FfmpegBitmapCapture
{
private string output1;
private string output2;
private string pathToFfmpg = "..\\..\\lib\\ffmpeg.exe";
private SnapshotItem[] snapshotItems = new SnapshotItem[3];
private TimeSpan executionTime;
public SnapshotItem[] SnapshotItems
{
get { return snapshotItems; }
}
public TimeSpan ExecutionTime
{
get { return this.executionTime;}
}
public FfmpegBitmapCapture(string filename, int percentFirst, int percentSecond, int percentThird)
{
GetSnapshotTimes(percentFirst,percentSecond,percentThird,filename);
SmallLogger.SmallLogger.LogMessageToFile("ffmpeg: filename " + filename);
ThreadData tdStart = new ThreadData();
tdStart.inputFilename = filename;
tdStart.outputFilename = this.GetTempPath() + "vidLib_snapshot[1].jpg";
tdStart.time = snapshotItems[0].Time.ToString();
Thread startThread = new Thread(new ParameterizedThreadStart(ExtractSnapshot));
ThreadData tdMiddle = new ThreadData();
tdMiddle.inputFilename = filename;
tdMiddle.outputFilename = this.GetTempPath() + "vidLib_snapshot[2].jpg";
tdMiddle.time = snapshotItems[1].Time.ToString();
Thread middleThread = new Thread(new ParameterizedThreadStart(ExtractSnapshot));
ThreadData tdEnd = new ThreadData();
tdEnd.inputFilename = filename;
tdEnd.outputFilename = this.GetTempPath() + "vidLib_snapshot[3].jpg";
tdEnd.time = snapshotItems[2].Time.ToString();
Thread endThread = new Thread(new ParameterizedThreadStart(ExtractSnapshot));
DateTime startTime = DateTime.Now;
startThread.Start(tdStart);
middleThread.Start(tdMiddle);
endThread.Start(tdEnd);
startThread.Join();
middleThread.Join();
endThread.Join();
this.snapshotItems[0].Thumbnail = new Bitmap(tdStart.outputFilename);
this.snapshotItems[1].Thumbnail = new Bitmap(tdMiddle.outputFilename);
this.snapshotItems[2].Thumbnail = new Bitmap(tdEnd.outputFilename);
try
{
File.Delete(tdStart.outputFilename);
File.Delete(tdMiddle.outputFilename);
File.Delete(tdEnd.outputFilename);
}
catch(Exception ex)
{
System.Console.Out.WriteLine(ex);
}
DateTime stopTime = DateTime.Now;
this.executionTime = stopTime - startTime;
}
void ExtractSnapshot(object threadData)
{
ThreadData td = (ThreadData)threadData;
string outFileName = td.outputFilename;
//from http://dotnetperls.com/process-redirect-standard-output
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = this.pathToFfmpg;
start.Arguments = "-i \"" + td.inputFilename + "\" -r 1 -f mjpeg -vframes 1 -ss " + td.time + " -y " + outFileName;
//start.Arguments = "-h";
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
start.RedirectStandardError = true;
start.CreateNoWindow = true;
//using(Process process = Process.Start(start))
//{
Process process = new Process();
process.StartInfo = start;
process.Start();
using(StreamReader reader = process.StandardOutput)
{
output1 = reader.ReadToEnd();
}
using (StreamReader reader2 = process.StandardError)
{
output2 = reader2.ReadToEnd();
}
process.WaitForExit();
process.Close();
//}
}
private string GetTempPath()
{
string path = System.Environment.GetEnvironmentVariable("TEMP");
if (!path.EndsWith("\\")) path += "\\";
return path;
}
private void GetSnapshotTimes(int percentFirst,
int percentMiddle,
int percentLast,
string filename)
{
string outputList;
TimeSpan middle;
TimeSpan end;
TimeSpan begin;
ProcessStartInfo start = new ProcessStartInfo();
//start.FileName = "C:\\Users\\daddy\\Downloads\\ffmpeg-latest\\bin\\ffmpeg.exe";
start.FileName = this.pathToFfmpg;
start.Arguments = "-i \"" + filename + "\"";
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
start.RedirectStandardError = true;
start.CreateNoWindow = true;
using(Process process = Process.Start(start))
{
using (StreamReader reader2 = process.StandardError)
{
outputList = reader2.ReadToEnd();
}
process.WaitForExit();
}
Regex regex = new Regex("Duration: +(?<dur>\\d\\d:\\d\\d:\\d\\d.\\d+)");
Match m = regex.Match(outputList);
if(m.Success)
{
TimeSpan OneSecond = TimeSpan.Parse("00:00:01.00");
long OneseconTicks = OneSecond.Ticks;
string duration = m.Groups["dur"].Value;
TimeSpan ts = TimeSpan.Parse(duration);
long durTicks = ts.Ticks;
if(durTicks <= OneseconTicks){
begin = TimeSpan.FromTicks((long)((double)durTicks * 0.05));
end = begin;
middle = begin;
}
else
{
middle = TimeSpan.FromTicks((long)((double)durTicks * ((double)percentMiddle)/100.0));
end = TimeSpan.FromTicks((long)((double)durTicks * ((double)percentLast)/100.0));
begin = TimeSpan.FromTicks((long)((double)durTicks * ((double)percentFirst)/100.0));
}
this.snapshotItems[0].Time = begin;
this.snapshotItems[1].Time = middle;
this.snapshotItems[2].Time = end;
}
}
}
}
Regards,
John