基于Node.js+FFmpeg向Yealink SIP-T42G推送RTP流的问题排查
解决Yealink SIP-T42G无法接收RTP音频的问题
我在Node.js中实现SIP功能,使用node.js-sip库。收到Yealink SIP-T42G发送的INVITE请求后,解析SDP为对象,发送100、180响应后用FFmpeg启动RTP流,但对方无法接收音频。用FFmpeg生成的SDP返回200时对方无法接通,改成Yealink风格SDP能接通但无音频,FFmpeg识别音频为pcm_alaw, 8000 Hz, mono, s16, 64 kb/s,怀疑格式不匹配。
收到的INVITE请求
Received INVITE INVITE sip:201@192.168.1.2:5060 SIP/2.0 Via: SIP/2.0/UDP 192.168.1.39:5062;branch=z9hG4bK1534941205 From: "Nik" <sip:Nik@192.168.1.2>;tag=564148403 To: <sip:201@192.168.1.2> Call-ID: 2068254636@192.168.1.39 CSeq: 2 INVITE Contact: <sip:Nik@192.168.1.39:5062> Authorization: Digest username="Nik", realm="NRegistrar", nonce="1234abcd", uri="sip:201@192.168.1.2:5060", response="7fba16dafe3d60c270b774bd5bba524c", algorithm=MD5 Content-Type: application/sdp Allow: INVITE, INFO, PRACK, ACK, BYE, CANCEL, OPTIONS, NOTIFY, REGISTER, SUBSCRIBE, REFER, PUBLISH, UPDATE, MESSAGE Max-Forwards: 70 User-Agent: Yealink SIP-T42G 29.71.0.120 Supported: replaces Allow-Events: talk,hold,conference,refer,check-sync Content-Length: 306 v=0 o=- 20083 20083 IN IP4 192.168.1.39 s=SDP data c=IN IP4 192.168.1.39 t=0 0 m=audio 11782 RTP/AVP 0 8 18 9 101 a=rtpmap:0 PCMU/8000 a=rtpmap:8 PCMA/8000 a=rtpmap:18 G729/8000 a=fmtp:18 annexb=no a=rtpmap:9 G722/8000 a=fmtp:101 0-15 a=rtpmap:101 telephone-event/8000 a=ptime:20 a=sendrecv
解析后的SDP对象
{ "session":{ "version":"0", "origin":"- 20084 20084 IN IP4 192.168.1.39", "sessionName":"SDP data" }, "media":[{ "media":"audio", "port":11784, "protocol":"RTP/AVP", "format":"0", "attributes":["rtpmap:0 PCMU/8000","rtpmap:8 PCMA/8000","rtpmap:18 G729/8000","fmtp:18 annexb=no","rtpmap:9 G722/8000","fmtp:101 0-15","rtpmap:101 telephone-event/8000","ptime:20","sendrecv"] }] }
启动RTP流的代码
var port = SDPParser.parse(res.message.body).media[0].port var s = new STREAMER('output.wav', '192.168.1.39', port)
STREAMER类实现
class Streamer{ constructor(inputFilePath, rtpAddress, rtpPort){ this.inputFilePath = 'output.wav'; this.rtpAddress = rtpAddress; this.rtpPort = rtpPort; } start(){ return new Promise((resolve) => { const ffmpegCommand = `ffmpeg -re -i ${this.inputFilePath} -ar 8000 -f mulaw -f rtp rtp://${this.rtpAddress}:${this.rtpPort}`; const ffmpegProcess = spawn(ffmpegCommand, { shell: true }); ffmpegProcess.stdout.on('data', (data) => { data = data.toString() data = data.replace(new RegExp('127.0.0.1', 'g'), '192.168.1.3'); resolve(data.toString()) }); ffmpegProcess.stderr.on('data', (data) => { console.log(data.toString()) }); ffmpegProcess.on('close', (code) => { console.log('close') console.log(code.toString()) }); ffmpegProcess.on('error', (error) => { console.log(error.toString()) }); }) } }
完整业务代码
Client.on('INVITE', (res) => { console.log("Received INVITE") var d = Client.Dialog(res).then(dialog => { dialog.send(res.CreateResponse(100)) dialog.send(res.CreateResponse(180)) var port = SDPParser.parse(res.message.body).media[0].port var s = new STREAMER('output.wav', '192.168.1.39', port) s.start().then(sdp => { console.log(sdp.split('SDP:')[1]) var ok = res.CreateResponse(200) ok.body = sdp.split('SDP:')[1] dialog.send(ok) }) dialog.on('BYE', (res) => { console.log("BYE") dialog.send(res.CreateResponse(200)) dialog.kill() }) }) })
解决方案
1. 对齐音频编码与SDP格式
从INVITE的SDP看,Yealink支持PCMU(payload 0)、PCMA(payload 8)等编码。当前FFmpeg命令用-f mulaw(对应PCMU),但输入音频被识别为PCMA,编码不匹配导致无声音。修改FFmpeg命令,明确指定编码:
# 使用PCMU编码(对应payload 0) ffmpeg -re -i ${this.inputFilePath} -ar 8000 -ac 1 -codec:a pcm_mulaw -f rtp rtp://${this.rtpAddress}:${this.rtpPort}
若要使用PCMA,替换为-codec:a pcm_alaw,同时在200响应的SDP里将m=audio的格式改为8。
2. 修正SDP中的IP与端口
- 确保SDP的
c=字段IP是Yealink能访问到的本地服务端IP,不要错误替换成无关IP。 - 确认解析后的RTP端口与INVITE中Yealink提供的接收端口一致(INVITE里是11782,当前解析结果为11784,需排查解析器逻辑)。
3. 构造兼容Yealink的SDP
手动生成符合Yealink风格的SDP,避免FFmpeg自动生成的字段不兼容:
v=0 o=- 20085 20085 IN IP4 192.168.1.3 s=SDP data c=IN IP4 192.168.1.3 t=0 0 m=audio 11782 RTP/AVP 0 a=rtpmap:0 PCMU/8000 a=ptime:20 a=sendonly
注意a=sendonly(仅发送音频),端口使用Yealink的接收端口。
4. 验证RTP流状态
- 查看FFmpeg的stderr输出,确认音频文件读取正常、转码参数生效。
- 用Wireshark抓包,检查RTP包是否发送到Yealink的IP和端口,以及负载类型是否匹配指定的编码(如PCMU对应payload 0)。
内容的提问来源于stack exchange,提问作者Nik Hendricks
相关产品推荐
相关产品推荐

