本次捣鼓了PJSUA2和PJSIP,用于测试VoIP 软电话功能。

PJSUA2 API 是一个基于 PJSUA-LIB API 的 C++ 库,它提供了高层次的 API,用于构建会话初始协议(SIP)多媒体用户代理应用程序(也称为 VoIP 软电话)。

折腾过程参考了下面的教程:

Ubuntu 18.04 下编译 Pjsua2

用arm-none-linux-gnueabi-gcc交叉编译pjsip源码_pjsip移植arm-CSDN博客

linux环境下编译pjsip库_libpjproject.pc-CSDN博客

主要推荐看这个:Ubuntu 之 Python3.12安装PJSUA2-CSDN博客

Building PJSUA2 — PJSIP Project 2.15-dev documentation

PJSIP 编译安装

PJSUA2虽然是Python下的一个包,但是底层是依赖的C的PJSIP项目,所以我们使用前需要先编译,PJSIP的官方项目在:pjsip/pjproject: PJSIP project

PJSIP 是一个用 C 语言编写的免费开源多媒体通信库,提供了 C、C++、Java、C# 和 Python 等高级语言的高层次 API。它实现了基于标准的协议,如 SIP、SDP、RTP、STUN、TURN 和 ICE。它将信令协议(SIP)与丰富的多媒体框架和 NAT 穿透功能结合成高层次的 API,具有可移植性,适用于从桌面系统、嵌入式系统到移动手机的几乎任何类型的系统。
./configure --enable-shared

image-20250511175754688.webp

make dep

image-20250511175831584.webp

make

image-20250511175857401.webp

sudo make install

image-20250511175918851.webp

image-20250511172023336.webp

如果提示缺少python,记得装python3。(测试环境是在docker中的,是最小系统)

image-20250511172037961.webp

image-20250511171938654.webp

image-20250511171927531.webp

如果遇到如下问题,手动指定缺少的依赖文件地址:

ImportError: libpjsip-ua.so.2: cannot open shared object file: No such file or directory

export PATH=/home/cyqsd/Workspace/pjsip_test/pjproject-2.15.1/pjsip/lib:$PATH

image-20250511180839600.webp

ImportError: libpjmedia-audiodev.so.2: cannot open shared object file: No such file or directory

image-20250511181555558.webp

[root@localhost python]# make install
python3 setup.py install --user
running install
running bdist_egg
running egg_info
writing pjsua2.egg-info/PKG-INFO
writing dependency_links to pjsua2.egg-info/dependency_links.txt
writing top-level names to pjsua2.egg-info/top_level.txt
reading manifest file 'pjsua2.egg-info/SOURCES.txt'
writing manifest file 'pjsua2.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-x86_64/egg
running install_lib
running build_py
running build_ext
creating build/bdist.linux-x86_64
creating build/bdist.linux-x86_64/egg
copying build/lib.linux-x86_64-3.9/pjsua2.py -> build/bdist.linux-x86_64/egg
copying build/lib.linux-x86_64-3.9/_pjsua2.cpython-39-x86_64-linux-gnu.so -> build/bdist.linux-x86_64/egg
byte-compiling build/bdist.linux-x86_64/egg/pjsua2.py to pjsua2.cpython-39.pyc
creating stub loader for _pjsua2.cpython-39-x86_64-linux-gnu.so
byte-compiling build/bdist.linux-x86_64/egg/_pjsua2.py to _pjsua2.cpython-39.pyc
creating build/bdist.linux-x86_64/egg/EGG-INFO
copying pjsua2.egg-info/PKG-INFO -> build/bdist.linux-x86_64/egg/EGG-INFO
copying pjsua2.egg-info/SOURCES.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying pjsua2.egg-info/dependency_links.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying pjsua2.egg-info/top_level.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
writing build/bdist.linux-x86_64/egg/EGG-INFO/native_libs.txt
zip_safe flag not set; analyzing archive contents...
__pycache__._pjsua2.cpython-39: module references __file__
creating 'dist/pjsua2-2.15.1-py3.9-linux-x86_64.egg' and adding 'build/bdist.linux-x86_64/egg' to it
removing 'build/bdist.linux-x86_64/egg' (and everything under it)
Processing pjsua2-2.15.1-py3.9-linux-x86_64.egg
removing '/root/.local/lib/python3.9/site-packages/pjsua2-2.15.1-py3.9-linux-x86_64.egg' (and everything under it)
creating /root/.local/lib/python3.9/site-packages/pjsua2-2.15.1-py3.9-linux-x86_64.egg
Extracting pjsua2-2.15.1-py3.9-linux-x86_64.egg to /root/.local/lib/python3.9/site-packages
pjsua2 2.15.1 is already the active version in easy-install.pth

Installed /root/.local/lib/python3.9/site-packages/pjsua2-2.15.1-py3.9-linux-x86_64.egg
Processing dependencies for pjsua2==2.15.1
Finished processing dependencies for pjsua2==2.15.1

PJSUA2_Python测试

我们使用PJSIP在Python下进行调试,有关更多信息可以查看官方文档页面:Overview — PJSIP Project 2.15-dev documentation

PJSIP 是一个用 C 语言编写的免费开源多媒体通信库,实现了基于标准的协议,如 SIP、SDP、RTP、STUN、TURN 和 ICE。它将信令协议(SIP)与丰富的多媒体框架和 NAT 穿透功能结合成高层次的 API,具有可移植性,适用于从桌面系统、嵌入式系统到移动手机的几乎任何类型的系统。

image-20250511182734388.webp

经过前面的安装,到此步骤时,直接import是可用的了。

官方提供了最小化的测试代码:Hello World! — PJSIP Project 2.15-dev documentation

根据我们本地测试地址修改了一下:

ep_cfg = pj.EpConfig()
ep = pj.Endpoint()
ep.libCreate()
ep.libInit(ep_cfg)

# 单独设置日志配置
# log_cfg = pj.LogConfig()
# log_cfg.level = 3
# ep.setLogConfig(log_cfg)  # 调用 setLogConfig() 方法

# 设置日志级别(通过其他方式,如环境变量或默认配置)

# 创建 UDP 传输(监听 5060)
sipTpConfig = pj.TransportConfig()
sipTpConfig.port = 5060
transport = ep.transportCreate(pj.PJSIP_TRANSPORT_UDP, sipTpConfig)

# 启动事件调度线程
ep.libStart()

# 注册 SIP 账号(可选)
acc = MyAccount(ep)
acc_cfg = pj.AccountConfig()
acc_cfg.idUri = "sip:1002@192.168.2.60"
acc_cfg.regConfig.registrarUri = "sip:192.168.2.60"
acc_cfg.sipConfig.authCreds.append(pj.AuthCredInfo("digest", "*", "1002", 0, "1234"))
acc.create(acc_cfg)

print("正在监听 SIP 呼叫...")

然后运行,则可以看到报文。

image-20250511184743080.webp

如果你在GUI的系统中,那可以开源测试带界面的程序会很多,在此就不多写了。

PJSUA2也提供了不同系统平台下的例子:

PJSUA2 Samples — PJSIP Project 2.15-dev documentation

image-20250805162022077.webp

文章目录