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

PJSUA2 Python简易项目调用音频设备失败:无法设置单声道播放通道

PJSUA2 Python软电话Docker部署音频设备初始化失败问题

PJSUA2的Python示例应用pygui开箱即用存在问题,无法添加联系人且触发涉及C代码文件的异常,我不需要GUI功能,因此编写了一个仅满足PJSUA2库基础通话要求的简易无GUI软电话。我已在支持拨打POTS号码的SIP服务商完成注册(此前用PyVoIP测试过该服务商,功能正常),但发起呼叫时项目完全失败,报错信息如下:

20:59:26.067            pjsua_acc.c  ..Acc 0: Registration sent
20:59:26.067           pjsua_call.c  Making call with acc #0 to -redacted-
20:59:26.067            pjsua_aud.c  .Set sound device: capture=-1, playback=-2, mode=0, use_default_settings=0
20:59:26.067            pjsua_aud.c  ..Opening sound device (speaker + mic) PCM@16000/1/20ms
20:59:26.068             alsa_dev.c  ...Unable to set a channel count of 1 for playback device 'hw:CARD=PCH,DEV=0'
20:59:26.068            pjsua_aud.c  ..Opening sound device (speaker + mic) PCM@44100/1/20ms
20:59:26.068             alsa_dev.c  ...Unable to set a channel count of 1 for playback device 'hw:CARD=PCH,DEV=0'
20:59:26.068            pjsua_aud.c  ..Opening sound device (speaker + mic) PCM@48000/1/20ms
20:59:26.068             alsa_dev.c  ...Unable to set a channel count of 1 for playback device 'hw:CARD=PCH,DEV=0'
20:59:26.068            pjsua_aud.c  ..Opening sound device (speaker + mic) PCM@32000/1/20ms
20:59:26.069             alsa_dev.c  ...Unable to set a channel count of 1 for playback device 'hw:CARD=PCH,DEV=0'
20:59:26.069            pjsua_aud.c  ..Opening sound device (speaker + mic) PCM@16000/1/20ms
20:59:26.069             alsa_dev.c  ...Unable to set a channel count of 1 for playback device 'hw:CARD=PCH,DEV=0'
20:59:26.069            pjsua_aud.c  ..Opening sound device (speaker + mic) PCM@8000/1/20ms
20:59:26.069             alsa_dev.c  ...Unable to set a channel count of 1 for playback device 'hw:CARD=PCH,DEV=0'
20:59:26.069            pjsua_aud.c  ..Unable to open sound device: Unknown error from audio driver (PJMEDIA_EAUD_SYSERR) [status=420002]
20:59:26.069          pjsua_media.c  .Call 0: deinitializing media..

该项目部署在Docker镜像中,已安装libasound2并挂载/dev/snd设备,但仍出现上述错误。我列出了四种可能的问题:

  • 容器运行时音频硬件不可用,可能是设备挂载方式不正确
  • 端点初始化时使用了不符合音频硬件的配置
  • 库启动时使用了不符合音频硬件的配置
  • 音频硬件本身存在问题(可能性低,本机双系统均可正常使用音频)

由于我不熟悉C++,希望得到Python层面的解决方案。附完整项目代码、Dockerfile及启动脚本:

Python代码

import sys

import pjsua2 as pj


class Settings:
  def __init__(self, sip_user=None, sip_pass=None, sip_registrar_uri=None):
    self.sip_user = sip_user
    self.sip_pass = sip_pass
    self.sip_registrar_uri = sip_registrar_uri


# Subclass to extend the Account and get notifications etc.
class Account(pj.Account):
  def onRegState(self, prm):
      # print("***OnRegState: " + prm.reason)
      pass


# Subclass the Call class to define callbacks etc.
class Call(pj.Call):

  def __init__(self, acc, peer_uri='', chat=None, call_id=pj.PJSUA_INVALID_ID):
    pj.Call.__init__(self, acc, call_id)
  

  def onCallState(self, prm):
    call_info = self.getInfo()
    self.connected = call_info.state == pj.PJSIP_INV_STATE_CONFIRMED
    

  def onCallMediaState(self, prm):
    ep = pj.Endpoint()
    call_info = self.getInfo()
    print(f'call_info: {call_info}')
    # for media_item in call_info.media:
    #   if media_item.type == pj.PJMEDIA_TYPE_AUDIO and (
    #     media_item.status == pj.PJSUA_CALL_MEDIA_ACTIVE or
    #     media_item.status == pj.PJSUA_CALL_MEDIA_REMOTE_HOLD
    #   ):
    #     media = self.getMedia(media_item.index)
    #     audio_media = pj.AudioMedia.typecastFromMedia(media)
        # Connect ports.
        # LEFT OFF HERE


def read_settings() -> Settings:
  # TODO: SECURITY: Rip these out, pass in via env vars.
  return Settings(
    sip_user='-redacted-',
    sip_pass='-redacted-',
    sip_registrar_uri='seattle1.voip.ms',  # Seattle VoIP.ms PoP
  )


def main():
  # Retrieve required settings.
  settings = read_settings()
  # Set up endpoint.
  endpoint_config = pj.EpConfig()
  endpoint = pj.Endpoint()
  endpoint.libCreate()
  endpoint.libInit(endpoint_config)
  # Set up SIP transport.
  sip_transport_config = pj.TransportConfig()
  sip_transport_config.port = 5060
  endpoint.transportCreate(pj.PJSIP_TRANSPORT_UDP, sip_transport_config)
  # Start the library.
  endpoint.libStart()
  # Set up account.
  account_config = pj.AccountConfig()
  account_config.idUri = f'sip:{settings.sip_user}'
  account_config.regConfig.registrarUri = f'sip:{settings.sip_registrar_uri}'
  credentials = pj.AuthCredInfo('digest', '*', settings.sip_user, 0,
    settings.sip_pass)
  account_config.sipConfig.authCreds.append(credentials)
  # Create account.
  account = Account()
  account.create(account_config)
  # Create call.
  call = Call(account)
  call_param = pj.CallOpParam()
  call_param.opt.audioCount = 1  # Also tried 2 here, for stereo? Same error...
  call_param.opt.videoCount = 0
  # Dial.
  try:
    call.makeCall('-redacted-', call_param)
  except Exception as error:
    print(f'Dialing error: {error}')
    sys.exit(1)
  # Main event loop.
  while True:
    try:
      endpoint.libHandleEvents(50)
    except Exception as error:
      print(f'Error: {error}')
      break 
  endpoint.libDestroy()


if __name__ == "__main__":
  main()

Dockerfile

FROM python:3-slim AS build_pjsip
ENV PJSIP_VERSION="2.13.1"
WORKDIR /src
RUN apt-get update && apt-get install -y \
    wget \
    build-essential \
    swig \
    libasound2-dev
RUN wget https://github.com/pjsip/pjproject/archive/refs/tags/${PJSIP_VERSION}.tar.gz && \
    tar xfz ${PJSIP_VERSION}.tar.gz
RUN mv pjproject-${PJSIP_VERSION} pjproject && \
    cd pjproject && \
    ./configure CFLAGS="-fPIC" && \
    make dep && \
    make clean && \
    make
RUN cd pjproject/pjsip-apps/src/swig/python && \
    make && \
    make install


FROM python:3-slim as release
RUN apt-get update && apt-get install -y \
    libasound2
ADD . /opt/btm
WORKDIR /opt/btm
COPY --from=build_pjsip /root/.local/lib /root/.local/lib
CMD ["/bin/bash"]

启动脚本

#!/bin/bash

docker run \
    --rm \
    -it \
    -v .:/opt/btm \
    --device /dev/snd:/dev/snd \
    btm-make-a-call

内容的提问来源于stack exchange,提问作者Bruce Bradley

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 22:52:32