Я предполагаю, что это как-то связано с воспроизведением скорость или буферизация, но я уже пару недель пытаюсь это исправить и не могу найти решение.
Я пробовал искать публичные репозитории, делающие что-то подобное, но я недостаточно техничен, чтобы понять их процесс.
Вот как инициализируется воспроизведение при запуске приложения:
Код: Выделить всё
public static void Initialize()
{
waveProvider = new BufferedWaveProvider(new WaveFormat(48000, 1))
{
BufferDuration = TimeSpan.FromSeconds(5),
DiscardOnBufferOverflow = false
};
waveOut = new WaveOutEvent();
waveOut.Init(waveProvider);
}
Код: Выделить всё
public class JitterBuffer(int maxBufferSize)
{
private readonly SortedDictionary buffer = [];
private readonly int maxBufferSize = maxBufferSize;
public void AddFrame(short[] frame, int sequenceNumber)
{
if (buffer.Count >= maxBufferSize)
{
buffer.Remove(buffer.Keys.First()); // Remove the oldest frame if the buffer is full
}
buffer[sequenceNumber] = frame;
}
public short[]? GetFrame()
{
if (buffer.Count > 0)
{
var firstKey = buffer.Keys.First();
var firstValue = buffer[firstKey];
buffer.Remove(firstKey);
return firstValue;
}
// Return null if the buffer is empty
return null;
}
public int BufferSize => buffer.Count;
}
И вот как я получаю кадры из этого JitterBuffer для добавления в BufferedWaveProvider:
Код: Выделить всё
public static void PlayFromBuffer(object? state)
{
short[]? frame = jitterBuffer.GetFrame();
if (frame != null)
{
byte[] byteBuffer = new byte[frame.Length * sizeof(short)];
Buffer.BlockCopy(frame, 0, byteBuffer, 0, byteBuffer.Length);
waveProvider.AddSamples(byteBuffer, 0, byteBuffer.Length);
}
}
Кроме того, если это актуально, вот как я записываю звук:
Код: Выделить всё
public static void Initialize()
{
waveIn = new WaveInEvent
{
DeviceNumber = 0, // Use default recording device
WaveFormat = new WaveFormat(48000, 1)
};
waveIn.DataAvailable += OnDataAvailable;
waveIn.RecordingStopped += WaveIn_RecordingStopped;
}
// waveIn.StartRecording is called in a separate method
private static void OnDataAvailable(object? sender, WaveInEventArgs a)
{
// Convert buffer to short PCM samples and accumulate
short[] pcmBuffer = new short[a.BytesRecorded / 2];
Buffer.BlockCopy(a.Buffer, 0, pcmBuffer, 0, a.BytesRecorded);
pcmAccumulationBuffer.AddRange(pcmBuffer);
// This method calls Opus to encode then packages it into a packet and is sent to the server
AudioCodec.Process(pcmAccumulationBuffer);
}
Подробнее здесь: https://stackoverflow.com/questions/793 ... gh-network