Воспроизведение потока RTP на динамики компьютера
Я использую UdpClient для получения потока RTP от телефонных звонков через Avaya DMCC SDK. Я хотел бы воспроизвести этот поток через динамики компьютера. После долгих поисков мне удалось найти решения, которые требуют сохранения в файл и последующего воспроизведения файла, но мне нужно воспроизвести поток через динамики без сохранения в файл. Я хотел бы отправить аудио на динамики, как я его получаю.
public void StartClient()
{
// Create new UDP client. The IP end point tells us which IP is sending the data
client = new UdpClient(port);
endPoint = new IPEndPoint(System.Net.IPAddress.Any, port);
selectedCodec = new MuLawChatCodec();
waveOut = new WaveOut();
waveProvider = new BufferedWaveProvider(selectedCodec.RecordFormat);
waveOut.Init(waveProvider);
waveOut.Play();
listening = true;
listenerThread = new Thread(ReceiveCallback);
listenerThread.Start();
}
private void ReceiveCallback()
{
// Begin looking for the next packet
while (listening)
{
// Receive packet
byte[] packet = client.Receive(ref endPoint);
// Packet header
int version = GetRTPValue(packet, 0, 1);
int padding = GetRTPValue(packet, 2, 2);
int extension = GetRTPValue(packet, 3, 3);
int csrcCount = GetRTPValue(packet, 4, 7);
int marker = GetRTPValue(packet, 8, 8);
int payloadType = GetRTPValue(packet, 9, 15);
int sequenceNum = GetRTPValue(packet, 16, 31);
int timestamp = GetRTPValue(packet, 32, 63);
int ssrcId = GetRTPValue(packet, 64, 95);
int csrcid = (csrcCount == 0) ? -1 : GetRTPValue(packet, 96, 95 + 32 * (csrcCount));
int extHeader = (csrcCount == 0) ? -1 : GetRTPValue(packet, 128 + (32 * csrcCount), 127 + (32 * csrcCount));
int payloadIndex = csrcCount == 0 ? 96 : 128 + 32 * csrcCount;
int payload = GetRTPValue(packet, payloadIndex, packet.Length);
byte[] Payload = new byte[packet.Length - payloadIndex];
Buffer.BlockCopy(packet, payloadIndex, Payload, 0, packet.Length - payloadIndex);
byte[] decoded = selectedCodec.Decode(Payload, 0, Payload.Length);
}
}
private int GetRTPValue(byte[] packet, int startBit, int endBit)
{
int result = 0;
// Number of bits in value
int length = endBit - startBit + 1;
// Values in RTP header are big endian, so need to do these conversions
for (int i = startBit; i <= endBit; i++)
{
int byteIndex = i / 8;
int bitShift = 7 - (i % 8);
result += ((packet[byteIndex] >> bitShift) & 1) * (int)Math.Pow(2, length - i + startBit - 1);
}
return result;
}
Теперь я успешно получаю звук от разговора, воспроизводимого через динамики, добавив byte[]
содержащий только полезную нагрузку для NAudio BufferedWaveProvider
1 ответ
Существует демонстрация того, как воспроизводить звук, полученный по сети, включенный в исходный код NAudio (см. Демонстрацию сетевого чата в проекте NAudioDemo). В основном используйте AcmStream
декодировать аудио, а затем поместить его в BufferedWaveProvider
с которого воспроизводится звуковая карта.