You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何查询VoIP提供商的音频流格式与采样率?附工具实现需求

查询VoIP提供商的音频格式与采样率方法

要确定VoIP提供商使用的音频编码格式和采样率,核心是查看SIP呼叫过程中SDP(会话描述协议)的协商结果——这是VoIP设备/客户端与提供商交换媒体能力的关键信息。下面是你提到的工具的具体实现方案:


一、使用linphone-cli查询

linphone-cli可以通过呼叫时的调试日志或交互命令直接获取协商后的编码信息。

命令示例

  1. 启动带调试日志的linphone-cli,查看SDP交换细节:

    linphone-cli -d 6
    

    日志中会包含m=audio开头的行,比如:m=audio 5004 RTP/AVP 0 8,其中:

    • 0对应PCMU(MuLaw,8kHz)
    • 8对应PCMA(ALaw,8kHz)
      其他RTP payload类型可参考标准映射表。
  2. 呼叫建立后,在交互模式下查看当前编码:
    先发起呼叫:

    call sip:test@your-provider-domain.com
    

    呼叫接通后输入:

    codec list
    

    或更详细的呼叫信息:

    info
    

    输出会明确显示当前使用的音频编码名称和采样率。


二、使用pjsip查询(Python示例)

利用pjsua2库的回调事件,在呼叫建立后获取媒体流编码信息。

代码示例

import pjsua2 as pj
import time

class CallHandler(pj.Call):
    def onCallState(self, prm):
        call_info = self.getInfo()
        if call_info.state == pj.PJSIP_INV_STATE_CONFIRMED:
            # 遍历音频媒体流
            for media_info in call_info.media:
                if media_info.type == pj.PJMEDIA_TYPE_AUDIO:
                    print(f"当前音频编码: {media_info.codecInfo.name}")
                    print(f"采样率: {media_info.codecInfo.clockRate} Hz")

# 初始化pjsip端点
ep = pj.Endpoint()
ep.libCreate()
ep.libInit(pj.EpConfig())

# 配置VoIP账户(替换为你的提供商信息)
acc_cfg = pj.AccountConfig()
acc_cfg.idUri = "sip:your-username@your-provider-domain.com"
acc_cfg.regConfig.registrarUri = "sip:your-provider-domain.com"
acc_cfg.sipConfig.authCreds.append(pj.AuthCredInfo("digest", "*", "your-username", 0, "your-password"))

acc = pj.Account()
acc.create(acc_cfg)

# 等待注册完成
time.sleep(2)

# 发起测试呼叫
call = CallHandler(acc, pj.CallOpParam())
call.makeCall("sip:test@your-provider-domain.com", pj.CallOpParam())

# 保持运行直到手动中断
try:
    while True:
        time.sleep(1)
except KeyboardInterrupt:
    call.hangup()
    ep.libDestroy()
    ep.libClose()

三、使用SIP.js查询(浏览器环境)

通过监听会话事件,获取协商后的媒体编码信息或直接解析SDP。

代码示例

// 初始化SIP用户代理
const userAgent = new SIP.UA({
  uri: 'sip:your-username@your-provider-domain.com',
  authorizationUser: 'your-username',
  password: 'your-password',
  transportOptions: {
    wsServers: 'wss://your-provider-ws-endpoint.com'
  }
});

userAgent.on('registered', () => {
  // 发起测试呼叫
  const session = userAgent.invite('sip:test@your-provider-domain.com', {
    media: { audio: true }
  });

  // 呼叫接通后解析SDP
  session.on('accepted', () => {
    const remoteSDP = session.sessionDescriptionHandler.remoteDescription.sdp;
    // 提取音频编码行
    const audioLine = remoteSDP.split('\n').find(line => line.startsWith('m=audio'));
    if (audioLine) {
      const payloadTypes = audioLine.split(' ')[3].split(' ');
      console.log("协商的RTP payload类型:", payloadTypes);
      // 映射到编码名称和采样率,示例:0=MuLaw(8kHz), 8=ALaw(8kHz), 111=Opus(48kHz)
      const payloadMap = {
        '0': ['MuLaw', 8000],
        '8': ['ALaw', 8000],
        '111': ['Opus', 48000]
      };
      payloadTypes.forEach(type => {
        if (payloadMap[type]) {
          console.log(`编码: ${payloadMap[type][0]}, 采样率: ${payloadMap[type][1]}Hz`);
        }
      });
    }
  });
});

四、使用pyVOIP查询

通过监听呼叫状态变化,解析远程SDP获取编码信息。

代码示例

from pyVOIP.VOIP import VoIPPhone, CallState
import time

def on_call_update(call):
    if call.state == CallState.CONNECTED:
        remote_sdp = call.remote_sdp
        if remote_sdp:
            for media in remote_sdp.media:
                if media.media_type == 'audio':
                    print("音频RTP payload类型:", media.rtp_payloads)
                    # 映射编码与采样率
                    payload_map = {
                        '0': ('MuLaw', 8000),
                        '8': ('ALaw', 8000),
                        '111': ('Opus', 48000),
                        '101': ('Linear16', 16000)
                    }
                    for payload in media.rtp_payloads:
                        if payload in payload_map:
                            codec, rate = payload_map[payload]
                            print(f"匹配编码: {codec}, 采样率: {rate}Hz")

# 初始化VoIP电话
phone = VoIPPhone(
    username='your-username',
    password='your-password',
    domain='your-provider-domain.com',
    port=5060,
    call_callback=on_call_update
)

phone.start()
# 发起测试呼叫
phone.call('test@your-provider-domain.com')

# 保持运行
try:
    input("按回车键结束测试...\n")
finally:
    phone.stop()

关键说明

  • SDP中的RTP payload类型是核心依据,不同类型对应固定的编码格式和采样率,可通过标准RTP payload表查询完整映射。
  • 若提供商支持多种编码,最终使用的是双方(客户端与提供商)协商后的最优编码,这也是你需要适配STT服务的格式。

内容的提问来源于stack exchange,提问作者Paul Serikov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 12:05:44