【问题标题】:How to send G722 encoded audio over an RTP stream?如何通过 RTP 流发送 G722 编码的音频?
【发布时间】:2020-03-16 00:43:24
【问题描述】:

我有一个小型 SIP 应用程序,基本上是 UserAgentServer example from SipSorcery。我可以设置一个带有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 甚至无法弄清楚有关流的任何信息。

【问题讨论】:

    标签: audio sip rtp


    【解决方案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);
    

    【讨论】:

    猜你喜欢
    • 2013-06-07
    • 2016-04-03
    • 2012-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-03
    • 2012-05-20
    • 1970-01-01
    相关资源
    最近更新 更多