There are two process I am handling. Ffmpeg and fpcalc.
I have completed my appplication by encoding a wav file with ffmpeg, and reading it for purposes of chromaprinting with fpcalc.
However, I think the next step is to skip the saving of a wav file, and pipe the data directly into the fpcalc process.
I've been trying to understand how to pipe the stream data from ffpmeg stdout into the fpcalc process stdin.
Some of the code I've been testing and reading (below) has come from other answers, with regards to piping data out of a Process object in c#, specifically with ffmpeg, found here on Stack
private static void ExtractPCMAudio(string input, int duration)
{
Process proc = new Process();
proc.StartInfo.FileName = @"ffmpeg.exe";
proc.StartInfo.Arguments = $"-t 00:3:00 -i \"{input}\" -f wav -ac 1 -acodec pcm_s16le -ar 16000 -"; //"-" Dash pipes the stream
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();
FileStream baseStream = proc.StandardOutput.BaseStream as FileStream;
byte[] audioBytes = null;
int lastRead = 0;
using (MemoryStream ms = new MemoryStream())
{
byte[] buffer = new byte[4096];
do
{
lastRead = baseStream.Read(buffer, 0, buffer.Length);
ms.Write(buffer, 0, lastRead);
} while (lastRead > 0);
audioBytes = ms.ToArray();
}
proc.StandardInput.BaseStream.Close();
baseStream.Close();
FingerPrintAudio(audioBytes);
Console.WriteLine("Done!");
}
private static void FingerPrintAudio(byte[] audioBytes)
{
var fpcalc = "fpcalc.exe";
var procStartInfo =
new ProcessStartInfo(fpcalc, $" -raw -length 600 -json")
{
RedirectStandardOutput = true,
RedirectStandardInput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true,
};
var process = new Process {StartInfo = procStartInfo};
process.Start();
process.StandardInput.BaseStream.Write(audioBytes, 0, audioBytes.Length); //<--This is where the piping error happens.
string processOutput = null;
using (var sr = new StreamWriter("Test.json"))
{
while ((processOutput = process.StandardOutput.ReadLine()) != null)
{
sr.WriteLine(processOutput);
Console.WriteLine(processOutput);
}
sr.Close();
}
}
Throughout many variations of the code, posted above, I seem to encounter an error: 'the pipe has ended'. I think it is a buffering error, where the process handling fpcalc is expecting more byte data, but is cut short?
Perhaps there is a better way to send stream data from one process and use it in a second process?