Web语音对讲示例

PCM文件生成
1. 在线语音合成 https://ttsmaker.cn/
2. 音频转码

小端模式 ffmpeg.exe -i test.mp3 -f s16le -ar 8000 -ac 1 -vn output.pcm

大端模式 ffmpeg.exe -i test.mp3 -f s16be -ar 8000 -ac 1 -vn story.pcm

3. 播放测试

ffplay -f s16be -ar 8000 -ac 1 story.pcm
vlc story.pcm :demux=rawaud :rawaud-channels=1 :rawaud-samplerate=8000 :rawaud-fourcc=s16b

 

RTP播放测试
新建stream.sdp文件,使用vlc打开该文件,如8kHz 单声道 16-bit:

v=0
o=- 0 0 IN IP4 127.0.0.1
s=PCM Audio Stream
c=IN IP4 127.0.0.1
t=0 0
m=audio 5004 RTP/AVP 96
a=rtpmap:96 L16/8000/1

 

技术实现

流媒体:SDP流媒体信息、RTP打包、RTP解包

通信层:websocket

界面层:Html获取麦克风音频数据,播放PCM音频

 

代码结构

image

image

media.sdp

v=0
o=- 0 0 IN IP4 127.0.0.1
s=RTP PCM Audio Stream
c=IN IP4 127.0.0.1
t=0 0
m=audio 5504 RTP/AVP 96
a=rtpmap:96 L16/8000/1

talk_G711Alaw.sdp

v=0
o=- 0 0 IN IP4 127.0.0.1
s=s=RTP G711 Audio Stream
c=IN IP4 127.0.0.1
t=0 0
m=audio 5004 RTP/AVP 8
a=rtpmap:8 PCMA/8000

talk_PCM.sdp

v=0
o=- 0 0 IN IP4 127.0.0.1
s=s=RTP G711 Audio Stream
c=IN IP4 127.0.0.1
t=0 0
m=audio 5004 RTP/AVP 96
a=rtpmap:96 L16/8000/1
using System.Net;
using System.Net.Sockets;

namespace RTPService.rtp
{
    public class RtpStreamer
    {
        private UdpClient udpClient;
        private IPEndPoint remoteEndPoint;
        private RtpPacketizer packetizer;
        private int frameSize;
        private int sampleRate;
        private int channel;
        private int bytesPerSample;

        public RtpStreamer(string remoteAddress, int remotePort, uint ssrc, int sampleRate = 8000, int bitDepth = 16, int channel = 1, byte payloadType = 96, bool isBigEndian = false)
        {
            udpClient = new UdpClient();
            remoteEndPoint = new IPEndPoint(IPAddress.Parse(remoteAddress), remotePort);

            this.sampleRate = sampleRate;
            this.channel = channel;
            this.bytesPerSample = bitDepth / 8;

            packetizer = new RtpPacketizer(ssrc, sampleRate, channel, bytesPerSample, payloadType, isBigEndian);

            // 计算适当的帧大小 (20ms 的数据)
            frameSize = (sampleRate * channel * bytesPerSample * 20) / 1000;
            // 确保帧大小是样本大小的倍数
            int sampleSize = channel * bytesPerSample;
            frameSize = (frameSize / sampleSize) * sampleSize;

            Console.WriteLine($"Streaming parameters: SSRC={ssrc},SampleRate={sampleRate}, bitDepth={bitDepth}, Channels={channel}, PayloadType={payloadType}, isBigEndian={isBigEndian}, FrameSize={frameSize}");
        }

        public void StreamPcmFile(string filePath)
        {
            using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                byte[] buffer = new byte[frameSize];
                int bytesRead;

                while ((bytesRead = fileStream.Read(buffer, 0, frameSize)) > 0)
                {
                    SendRtp(buffer, bytesRead);

                    // 等待适当的时间以保持正确的速率
                    int samples = bytesRead / (channel * bytesPerSample);
                    int delayMs = (samples * 1000) / sampleRate;
                    Thread.Sleep(delayMs);
                }
            }
        }

        public byte[] CreateRtpPacket(byte[] buffer, int bytesRead)
        {
            return packetizer.CreateRtpPacket(buffer, 0, bytesRead);
        }

        public byte[] DepacketizeRtpPacket(byte[] rtp)
        {
            return packetizer.DepacketizeRtpPacket(rtp);
        }

        public void SendRtp(byte[] buffer, int bytesRead)
        {
            // 创建RTP包
            byte[] rtpPacket = CreateRtpPacket(buffer, bytesRead);

            // 发送RTP包
            udpClient.Send(rtpPacket, rtpPacket.Length, remoteEndPoint);

            // 发送RTSP over UDP
            //byte[] rtspPacket = packetizer.CreateRtspPacket(rtpPacket);
            //udpClient.Send(rtspPacket, rtspPacket.Length, remoteEndPoint);
        }

        public void Close()
        {
            //udpClient?.Close();
        }
    }
}

 

功能

1. 播放本地音频文件

2. 音频播放:服务端推送音频文件并播放

3. 音频回调:RTP解包并进行音频播放

4. 开始对讲:测试流程:html将麦克风数据转base64,websocket发送中间件,转成音频编码:G.711alaw,进行rtp打包,udp发送到5004,vlc播放sdp文件测试

5. 结束对讲

6. 摄像头播放:测试流程:读取pcm文件,进行rtp打包,udp发送到5504,vlc播放sdp文件,播放服务端音频

image

image

 

posted @ 2025-08-22 15:33  CHHC  阅读(25)  评论(0)    收藏  举报