Как последовательно запускать кодирование и декодирование с помощью ffmpegC#

Место общения программистов C#
Ответить
Anonymous
 Как последовательно запускать кодирование и декодирование с помощью ffmpeg

Сообщение Anonymous »

После создания процессов FFmpeg для кодирования и декодирования на C# я попытался обработать следующий процесс. Я также применил Thread.Sleep(1000/30), потому что хотел делать это с интервалом 1/30 секунды вместо 1 секунды.
  • Получить фиктивные необработанные данные.
  • Передать их в процесс ffmpeg для кодирования.
  • Считать закодированные данные и передать их в процесс ffmpeg для декодирования.
  • Вывод байта размер консоли
Вот мой код, почему он не работает?

Код: Выделить всё

internal byte[] GetFrame(int width, int height)
{
int frameSize = width * height * 3;

byte[] frameData = new byte[frameSize];

Random random = new Random();

for(int i = 0; i < frameData.Length; i++)
{
frameData[i] = (byte)random.Next(256);
}

return frameData;
}

internal void EncodeAndDecode(int width, int height, int fps, int bitrate, string codec, string preset, string tune)
{
Process ffmpegEncodeProcess = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "ffmpeg",
Arguments = $"-f rawvideo -pixel_format rgb24 -s 540x720 -r 30 " +
$"-i - -c:v libx264 -preset ultrafast -tune zerolatency -maxrate 1500k -b:v 1500k " +
$"-f h264 pipe:1",
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
}
};

Process ffmpegDecodeProcess = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "ffmpeg",
Arguments = $"-f h264 -i pipe:0 " +
$"-f rawvideo -pixel_format rgb24 -s 540x720 pipe:1",
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
}
};

//start process
ffmpegEncodeProcess.Start();
ffmpegDecodeProcess.Start();

//input stream
var ffmpegEncodeInput = ffmpegEncodeProcess.StandardInput.BaseStream;
var ffmpegDecodeInput = ffmpegDecodeProcess.StandardInput.BaseStream;

//output stream
var ffmpegEncodeOutput = ffmpegEncodeProcess.StandardOutput.BaseStream;
var ffmpegDecodeOutput = ffmpegDecodeProcess.StandardOutput.BaseStream;

new Thread(async () =>
{
try
{
while(true)
{
byte[] encodedChunk = new byte[width * height * 3];
byte[] decodedChunk = new byte[width * height * 3];

byte[] frameData = GetFrame(width, height);

Console.WriteLine($"[INFO] Original frame size: {frameData.Length}bytes.");

if(frameData.Length == 0)
{
break;
}

await ffmpegEncodeInput.WriteAsync(frameData, 0, frameData.Length);
await ffmpegEncodeInput.FlushAsync();

int encodedBytesRead = await ffmpegEncodeOutput.ReadAsync(encodedChunk, 0, encodedChunk.Length);

Console.WriteLine($"[INFO] Encoded frame size: {encodedBytesRead}bytes.");

if(encodedBytesRead > 0)
{
await ffmpegDecodeInput.WriteAsync(encodedChunk, 0, encodedBytesRead);
await ffmpegDecodeInput.FlushAsync();

int decodedBytesRead = await ffmpegDecodeOutput.ReadAsync(decodedChunk, 0, decodedChunk.Length);

Console.WriteLine($"[INFO] Decoded frame size: {decodedBytesRead}bytes.");

if(decodedBytesRead >  0)
{
//do something...
}
}

Thread.Sleep(1000 / fps); //1/30s
}
}
catch(Exception e)
{
Console.WriteLine(e);
}
finally
{
ffmpegEncodeInput.Close();
ffmpegDecodeInput.Close();

if(!ffmpegEncodeProcess.HasExited)
{
ffmpegEncodeProcess.Kill();
}

if(!ffmpegDecodeProcess.HasExited)
{
ffmpegDecodeProcess.Kill();
}

Console.WriteLine("[INFO]: FFmpeg process clean up.");
}
}).Start();
}
Если быть точным, он выводит на консоль размеры «Исходный» и «Закодированный» только один раз, а затем ничего не делает. Что я делаю не так?


Подробнее здесь: https://stackoverflow.com/questions/793 ... ith-ffmpeg
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»