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

Audio 如何通过RTP流发送G722编码音频?,audio,sip,rtp,Audio,Sip,Rtp,我有一个小的SIP应用程序,它基本上是。我可以设置带有ulaw编码音频的RTP流,然后由我的软电话毫无问题地接收 现在我已经使用ffmepg创建了一个带有g722编码音频的文件,使用:ffmpeg-I sample.wav-ar 16000-acodec g722 sample.g722。我可以通过ffplay sample.g722播放这个音频,文件大小大约为每秒8000字节 我以以下方式回答邀请请求: v=0 o=- 55811 0 IN IP4 192.168.1.36 s=sipsorc

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

现在我已经使用ffmepg创建了一个带有g722编码音频的文件,使用:
ffmpeg-I sample.wav-ar 16000-acodec g722 sample.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流仍然缺少一些信息

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

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甚至无法了解有关流的任何信息。

我怀疑您需要做的就是设置RTP数据包有效负载类型,以匹配您的SDP服务

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

var rtpSession=new rtpSession(RTPPayloadTypesEnum.PCMU,null,null);
您的问题是,您的SDP报价告诉接收方在RTP数据包报头中预期有效负载类型为
9

修复应简单到将枚举更改为:

public enum RTPPayloadTypesEnum
{
PCMU=0,
PCMA=1,
G722=9,
动态=96,
}
然后

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

谢谢,这确实是答案。实际上,我在SipSorcery中使用了一个现有函数,它没有将9/G722作为一个值。所以我不得不做一个黑演员。但它现在工作得很好。G722也被添加到了一个sipsorcery代码示例()。啊,太好了。我说的cast是
rtpSession=newrtpsession((int)RTPPayloadTypesEnum.G722,null,null)用于中的第158行