Der FFMPEG -Rohrprozess endet gleich nach dem Schreiben von ersten Pufferdaten in den EingabebröstC#

Ein Treffpunkt für C#-Programmierer
Anonymous
 Der FFMPEG -Rohrprozess endet gleich nach dem Schreiben von ersten Pufferdaten in den Eingabebröst

Post by Anonymous »

Ich habe versucht, 16 -Bit -PCM (S16LE) Audiodaten in WebM mit FFMPEG in C#zu konvertieren. Aber wissen Sie nicht, warum ....
Könnte mir jemand sagen, warum? < /P>
Ich schätze es, wenn Sie mich unterstützen könnten. public class SpeechService : ISpeechService
{

///
/// Defines the _audioInputStream
///
private readonly MemoryStream _audioInputStream = new MemoryStream();

public async Task SendPcmAsWebmViaWebSocketAsync(
MemoryStream pcmAudioStream,
int sampleRate,
int channels)
{
string inputFormat = "s16le";

var ffmpegProcessInfo = new ProcessStartInfo
{
FileName = _ffmpegPath,
Arguments =
$"-f {inputFormat} -ar {sampleRate} -ac {channels} -i pipe:0 " +
$"-f webm pipe:1",
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true,
};

_ffmpegProcess = new Process { StartInfo = ffmpegProcessInfo };

Console.WriteLine("Starting FFmpeg process...");
try
{

if (!await Task.Run(() => _ffmpegProcess.Start()))
{
Console.Error.WriteLine("Failed to start FFmpeg process.");
return;
}
Console.WriteLine("FFmpeg process started.");

}
catch (Exception ex)
{
Console.Error.WriteLine($"Error starting FFmpeg process: {ex.Message}");
throw;
}

var encodeAndSendTask = Task.Run(async () =>
{
try
{
using var ffmpegOutputStream = _ffmpegProcess.StandardOutput.BaseStream;
byte[] buffer = new byte[8192]; // Temporary buffer to read data
byte[] sendBuffer = new byte[8192]; // Buffer to accumulate data for sending
int sendBufferIndex = 0; // Tracks the current size of sendBuffer
int bytesRead;

Console.WriteLine("Reading WebM output from FFmpeg and sending via WebSocket...");
while (true)
{
if ((bytesRead = await ffmpegOutputStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
// Copy data to sendBuffer
Array.Copy(buffer, 0, sendBuffer, sendBufferIndex, bytesRead);
sendBufferIndex += bytesRead;

// If sendBuffer is full, send it via WebSocket
if (sendBufferIndex >= sendBuffer.Length)
{
var segment = new ArraySegment(sendBuffer, 0, sendBuffer.Length);
_ws.SendMessage(segment);
sendBufferIndex = 0; // Reset the index after sending
}
}
}
}
catch (OperationCanceledException)
{
Console.WriteLine("Encode/Send operation cancelled.");
}
catch (IOException ex) when (ex.InnerException is ObjectDisposedException)
{
Console.WriteLine("Stream was closed, likely due to process exit or cancellation.");
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error during encoding/sending: {ex}");
}
});

var errorReadTask = Task.Run(async () =>
{
Console.WriteLine("Starting to read FFmpeg stderr...");
using var errorReader = _ffmpegProcess.StandardError;
try
{
string? line;
while ((line = await errorReader.ReadLineAsync()) != null)
{
Console.WriteLine($"[FFmpeg stderr] {line}");
}
}
catch (OperationCanceledException) { Console.WriteLine("FFmpeg stderr reading cancelled."); }
catch (TimeoutException) { Console.WriteLine("FFmpeg stderr reading timed out (due to cancellation)."); }
catch (Exception ex) { Console.Error.WriteLine($"Error reading FFmpeg stderr: {ex.Message}"); }
Console.WriteLine("Finished reading FFmpeg stderr.");
});

}

public async Task AppendAudioBuffer(AudioMediaBuffer audioBuffer)
{
try
{
// audio for a 1:1 call
var bufferLength = audioBuffer.Length;
if (bufferLength > 0)
{
var buffer = new byte[bufferLength];
Marshal.Copy(audioBuffer.Data, buffer, 0, (int)bufferLength);

_logger.Info("_ffmpegProcess.HasExited:" + _ffmpegProcess.HasExited);
using var ffmpegInputStream = _ffmpegProcess.StandardInput.BaseStream;
await ffmpegInputStream.WriteAsync(buffer, 0, buffer.Length);
await ffmpegInputStream.FlushAsync(); // バッファをフラッシュ
_logger.Info("Wrote buffer data.");

}
}
catch (Exception e)
{
_logger.Error(e, "Exception happend writing to input stream");
}
}

< /code>
Starting FFmpeg process...
FFmpeg process started.
Starting to read FFmpeg stderr...
Reading WebM output from FFmpeg and sending via WebSocket...
[FFmpeg stderr] ffmpeg version 7.1.1-essentials_build-www.gyan.dev Copyright (c) 2000-2025 the FFmpeg developers
[FFmpeg stderr] built with gcc 14.2.0 (Rev1, Built by MSYS2 project)
[FFmpeg stderr] configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-zlib --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-sdl2 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --enable-mediafoundation --enable-libass --enable-libfreetype --enable-libfribidi --enable-libharfbuzz --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-dxva2 --enable-d3d11va --enable-d3d12va --enable-ffnvcodec --enable-libvpl --enable-nvdec --enable-nvenc --enable-vaapi --enable-libgme --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libtheora --enable-libvo-amrwbenc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-librubberband
[FFmpeg stderr] libavutil 59. 39.100 / 59. 39.100
[FFmpeg stderr] libavcodec 61. 19.101 / 61. 19.101
[FFmpeg stderr] libavformat 61. 7.100 / 61. 7.100
[FFmpeg stderr] libavdevice 61. 3.100 / 61. 3.100
[FFmpeg stderr] libavfilter 10. 4.100 / 10. 4.100
[FFmpeg stderr] libswscale 8. 3.100 / 8. 3.100
[FFmpeg stderr] libswresample 5. 3.100 / 5. 3.100
[FFmpeg stderr] libpostproc 58. 3.100 / 58. 3.100

[2025-05-06 15:44:43,598][INFO][XbLogger.cs:85] _ffmpegProcess.HasExited:False
[2025-05-06 15:44:43,613][INFO][XbLogger.cs:85] Wrote buffer data.
[2025-05-06 15:44:43,613][INFO][XbLogger.cs:85] Wrote buffer data.
[FFmpeg stderr] [aist#0:0/pcm_s16le @ 0000025ec8d36040] Guessed Channel Layout: mono
[FFmpeg stderr] Input #0, s16le, from 'pipe:0':
[FFmpeg stderr] Duration: N/A, bitrate: 256 kb/s
[FFmpeg stderr] Stream #0:0: Audio: pcm_s16le, 16000 Hz, mono, s16, 256 kb/s
[FFmpeg stderr] Stream mapping:
[FFmpeg stderr] Stream #0:0 -> #0:0 (pcm_s16le (native) -> opus (libopus))
[FFmpeg stderr] [libopus @ 0000025ec8d317c0] No bit rate set. Defaulting to 64000 bps.
[FFmpeg stderr] Output #0, webm, to 'pipe:1':
[FFmpeg stderr] Metadata:
[FFmpeg stderr] encoder : Lavf61.7.100
[FFmpeg stderr] Stream #0:0: Audio: opus, 16000 Hz, mono, s16, 64 kb/s
[FFmpeg stderr] Metadata:
[FFmpeg stderr] encoder : Lavc61.19.101 libopus
[FFmpeg stderr] [out#0/webm @ 0000025ec8d36200] video:0KiB audio:1KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: 67.493113%
[FFmpeg stderr] size= 1KiB time=00:00:00.04 bitrate= 243.2kbits/s speed=2.81x
Finished reading FFmpeg stderr.
[2025-05-06 15:44:44,101][INFO][XbLogger.cs:85] _ffmpegProcess.HasExited:True
[2025-05-06 15:44:44,132][ERROR][XbLogger.cs:67] Exception happend writing to input stream
System.ObjectDisposedException: Cannot access a closed file.
at System.IO.FileStream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
at System.IO.Stream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count)
at EchoBot.Media.SpeechService.AppendAudioBuffer(AudioMediaBuffer audioBuffer) in C:\Users\tm068\Documents\workspace\myprj\xbridge-teams-bot\src\EchoBot\Media\SpeechService.cs:line 242
< /code>
I am expecting the ffmpeg process keep running.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post