如何通过RTP流发送G722编码的音频?

时间:2019-11-20 10:21:00

标签: audio sip rtp

我有一个小的SIP应用程序,基本上是UserAgentServer example from SipSorcery。我可以用ulaw编码的音频设置RTP流,然后由我的软件电话毫无问题地接收。

现在,我已经使用ffmepg使用ffmpeg -i sample.wav -ar 16000 -acodec g722 sample.g722创建具有g722编码音频的文件。我可以通过ffplay sample.g722很好地播放此音频,文件大小约为每秒8000字节。

我通过以下方式回答邀请请求

v=0
o=- 55811 0 IN IP4 192.168.1.36
s=sipsorcery
c=IN IP4 192.168.1.36
t=0 0
m=audio 49000 RTP/AVP 9
a=rtpmap:9 G722/8000
a=sendrecv

但是随后出了点问题。因为在wireshark中,我看到我的RTP流的有效负载为“ RTPType-96”,而软件电话的RTP流显示为g722。因此看来编解码器类型已正确协商,但是以某种方式我的实际RTP流仍然缺少一些信息。

我通过g722编码文件通过RPT流发送字节,如下所示:

private async Task SendG722()
{
    uint timestamp = 0;
    using (StreamReader sr = new StreamReader(this.AudioFileName))
    {
        var interval = 20;
        var bytesPerSecond = 8000;
        var packetsPerSecond = 1000 / interval;
        var bufferSize = bytesPerSecond / packetsPerSecond;

        byte[] buffer = new byte[bufferSize];
        int bytesRead = sr.BaseStream.Read(buffer, 0, buffer.Length);

        while (bytesRead > 0 && !this.CancellationTokenSource.IsCancellationRequested)
        {                
            this.Session.SendAudioFrame(this.RtpSocket, this.DestinationRtpEndPoint, timestamp, buffer);
            timestamp += (uint)buffer.Length;                    

            await Task.Delay(interval, this.CancellationTokenSource.Token);
            bytesRead = sr.BaseStream.Read(buffer, 0, buffer.Length);
        }
    }
}

但是当字节发送到某个地方时,RTP流和数据包显示在Wireshark中。我无法从软件电话听到任何音频。 Wireshark甚至无法弄清流中的任何内容。

1 个答案:

答案 0 :(得分:1)

我怀疑您所要做的就是将RTP数据包有效负载类型设置为与您的SDP提供的内容相匹配。

下面的行将RTP数据包头中的有效负载类型设置为0。

var rtpSession = new RTPSession(RTPPayloadTypesEnum.PCMU, null, null);

您的问题是您的SDP报价告诉接收方期望RTP数据包头中的有效载荷类型为9

此修复应简单到将ENUM更改为:

public enum RTPPayloadTypesEnum
{
    PCMU = 0,
    PCMA = 1,
    G722 = 9,
    Dynamic = 96,
}

然后

var rtpSession = new RTPSession(RTPPayloadTypesEnum.G722, null, null);