Пока я извлекаю кадры из видео, я заметил, что ffmpeg
закончит рендеринг определенных изображений. Проблема закончилась тем, что была "заполнением" байта между двумя jpeg
изображениями. Если размер моего буфера равен 4096
и если в этом буфере расположены байты от предыдущего изображения и следующего изображения, и если они не разделены никаким количеством байтов, тогда следующее изображение не будет отображаться должным образом. Это почему?
-i path -f image2pipe -c:v mjpeg -q:v 2 -vf fps=25 pipe:1
Представленный кадр:
Пример кода:
public void ExtractFrames()
{
string FFmpegPath = "Path...";
string Arguments = $"-i { VideoPath } -f image2pipe -c:v mjpeg -q:v 2 -vf fps=25/1 pipe:1";
using (Process cmd = GetProcess(FFmpegPath, Arguments))
{
cmd.Start();
FileStream fStream = cmd.StandardOutput.BaseStream as FileStream;
bool Add = false;
int i = 0, n = 0, BufferSize = 4096;
byte[] buffer = new byte[BufferSize + 1];
MemoryStream mStream = new MemoryStream();
while (true)
{
if (i.Equals(BufferSize))
{
i = 0;
buffer[0] = buffer[BufferSize];
if (fStream.Read(buffer, 1, BufferSize) == 0)
break;
}
if (buffer[i].Equals(255) && buffer[i + 1].Equals(216))
{
Add = true;
}
if (buffer[i].Equals(255) && buffer[i + 1].Equals(217))
{
n++;
Add = false;
mStream.Write(new byte[] { 255, 217 }, 0, 2);
File.WriteAllBytes([email protected]"C:\Path...\{n}.jpg", mStream.ToArray());
mStream = new MemoryStream();
}
if (Add)
mStream.WriteByte(buffer[i]);
i++;
}
cmd.WaitForExit();
cmd.Close();
}
}
private Process GetProcess(string FileName, string Arguments)
{
return new Process
{
StartInfo = new ProcessStartInfo
{
FileName = FileName,
Arguments = Arguments,
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = false,
}
};
}
Для тестирования следует использовать образец видео (> 480p) длиной 60 секунд или выше.