鸿蒙Next中使用pjsip库
本文详细介绍了在HarmonyOS Next系统中交叉编译pjsip-2.13.1库的完整流程。主要内容包括:编译环境要求(HarmonyNext命令行工具5.0.3.800、gcc-9.3.0等)、版本检查方法、配置编译环境变量的具体命令、生成MakeFile的配置步骤、以及完整的编译安装过程。同时提供了将编译好的静态库集成到Native C++工程的方法,包括目录结构设置、CMakeLists
鸿蒙Next中使用pjsip库
简介
集成pjsip的HarmonyOS Next话机,不含额外编码工具和插件

交叉编译 pjsip-2.13.1 到HarmonyOSNext
编译环境要求
HarmonyNext命令行工具 commandline-tools-linux-x64-5.0.3.800
gcc-9.3.0
glibc-2.31
make-4.3
pjproject-2.13.1
版本检查
# 检查gcc >= 9.3.0
gcc -v
# 检查make >= 4.3
make -v
# 检查GLIBC,>= 2.31
strings /lib64/libc.so.6 |grep GLIBC
编译
# 准备编译时的环境变量,将C/C++编译路径指向HarmonyOSNext提供的工具
export OHOS_SDK=/你的命令行工具路径/command-line-tools/sdk/default/openharmony
export AS=${OHOS_SDK}/native/llvm/bin/llvm-as
export CC="${OHOS_SDK}/native/llvm/bin/clang --target=aarch64-linux-ohos -march=armv8-a --sysroot=/home/HarmonyOS_NEXT/ohos-sdk/linux/native/sysroot"
export CXX="${OHOS_SDK}/native/llvm/bin/clang++ --target=aarch64-linux-ohos --sysroot=/home/HarmonyOS_NEXT/ohos-sdk/linux/native/sysroot"
export LD="${OHOS_SDK}/native/llvm/bin/ld.lld"
export STRIP=${OHOS_SDK}/native/llvm/bin/llvm-strip
export RANLIB=${OHOS_SDK}/native/llvm/bin/llvm-ranlib
export OBJDUMP=${OHOS_SDK}/native/llvm/bin/llvm-objdump
export OBJCOPY=${OHOS_SDK}/native/llvm/bin/llvm-objcopy
export NM=${OHOS_SDK}/native/llvm/bin/llvm-nm
export AR=${OHOS_SDK}/native/llvm/bin/llvm-ar
export CFLAGS="-fPIC -D__MUSL__=1"
export CXXFLAGS="-fPIC -D__MUSL__=1"
进入pjsip目录
cd pjproject-2.13.1
开始配置,生成 MakeFile,中间如有错误查看 pjproject-2.13.1/config.log
./configure --prefix=/编译完成后静态库生成路径/pjsip --host=aarch64-linux --disable-libwebrtc LD="$CXX"
开始编译
make dep
make
make install
编译完成之后结束之后,进入/编译完成后静态库生成路径/pjsip目录查看编译结果, include是头文件, lib是静态库
[root@localhost pjsip]> ls
include lib
运行环境要求
编辑器版本DevEco Studio for Windows 5.0.3.810
编辑器内置SDK版本API Version 10 (4.0.10.16), 该SDK主要用于调试,不确定是否必须
真机系统HarmonyOS Next 0.0.66,因为上面pjsip只编译了aarch64架构的静态库,所以模拟器,预览(都是x86的)无法运行,必须真机,如果需要模拟器查看,需要编译对应的x86架构的pjsip
运行环境配置
使用编辑器创建一个全新的Native C++工程
在项目/lib/arm64-v8a/中新建目录libpjsip,将编译好的lib下静态库放入libpjsip
将编译好的include文件夹,包括头文件放到项目src/main/cpp目录下
修改CMakeLists.txt,参考下面
PJSIP宏
add_definitions(-DPJ_AUTOCONF=1)
add_definitions(-DPJ_IS_BIG_ENDIAN=0)
add_definitions(-DPJ_IS_LITTLE_ENDIAN=1)
add_definitions(-DPJ_LOG_MAX_LEVEL=6) # 设置最大日志等级
add_definitions(-DPJSUA2_ERROR_HAS_EXTRA_INFO=1)
add_definitions(-D__MUSL__=1)
# 在 add_library(entry SHARED napi_init.cpp) 之后链接PJSIP静态库到 entry, 如果你的不叫entry,请修改为对应名称
target_link_libraries(entry PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/libpjsip/libg7221codec-aarch64-unknown-linux-gnu.a)
target_link_libraries(entry PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/libpjsip/libpjmedia-codec-aarch64-unknown-linux-gnu.a)
target_link_libraries(entry PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/libpjsip/libpjsua2-aarch64-unknown-linux-gnu.a)
target_link_libraries(entry PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/libpjsip/libgsmcodec-aarch64-unknown-linux-gnu.a)
target_link_libraries(entry PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/libpjsip/libpjmedia-videodev-aarch64-unknown-linux-gnu.a)
target_link_libraries(entry PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/libpjsip/libresample-aarch64-unknown-linux-gnu.a)
target_link_libraries(entry PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/libpjsip/libilbccodec-aarch64-unknown-linux-gnu.a)
target_link_libraries(entry PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/libpjsip/libpjnath-aarch64-unknown-linux-gnu.a)
target_link_libraries(entry PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/libpjsip/libspeex-aarch64-unknown-linux-gnu.a)
target_link_libraries(entry PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/libpjsip/libpj-aarch64-unknown-linux-gnu.a)
target_link_libraries(entry PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/libpjsip/libpjsip-aarch64-unknown-linux-gnu.a)
target_link_libraries(entry PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/libpjsip/libsrtp-aarch64-unknown-linux-gnu.a)
target_link_libraries(entry PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/libpjsip/libpjlib-util-aarch64-unknown-linux-gnu.a)
target_link_libraries(entry PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/libpjsip/libpjsip-simple-aarch64-unknown-linux-gnu.a)
target_link_libraries(entry PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/libpjsip/libyuv-aarch64-unknown-linux-gnu.a)
target_link_libraries(entry PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/libpjsip/libpjmedia-aarch64-unknown-linux-gnu.a)
target_link_libraries(entry PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/libpjsip/libpjsip-ua-aarch64-unknown-linux-gnu.a)
target_link_libraries(entry PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/libpjsip/libpjmedia-audiodev-aarch64-unknown-linux-gnu.a)
target_link_libraries(entry PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/libpjsip/libpjsua-aarch64-unknown-linux-gnu.a)
点击编辑器右上角Sync Now同步CMakeLists.txt到编辑器
运行查看
修改napi_init.cpp在文件中使用pjsip提供的api
运行debug查看效果
测试使用的是pjsip官方的C++例子,进行话机注册,有一点需要注意,在HarmonyOS Next中运行C++,std::cout 输出日志是看不到的,必须使用HarmonyOS Next的hilog库提供的OH_LOG_Print方法进行日志输出,在pjsip中需要对日志方法进行重写
在napi_init.cpp中写的测试方法
// 自定义日志类
class MyLogWriter : public pj::LogWriter {
public:
// 使用 OH_LOG_Print 代理打印pjsip日志,这里使用的是pjsua2,所以代理方式采用了pjsua2的代理方式,如果你用的普通的pjsip,需要使用另外一种代理方式,两种是分开的
virtual void write(const pj::LogEntry &entry) {
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "PJSIP", "%{public}s", entry.msg.c_str());
}
};
// 测试方法
void test_pjsip()
{
// ...其他代码
pj::EpConfig ep_cfg;
pj::LogConfig log_config;
MyLogWriter *mw = new MyLogWriter;
log_config.writer = mw;
// 把日志配置添加到EpConfig
ep_cfg.logConfig = log_config;
// 初始化前端配置
ep.libInit( ep_cfg );
// ...其他代码
}
查看控制台有发起注册的信令,不知道为什么官方的例子注册始终401,注册到我自己的sip服务就是正常的
pjsip发起注册
已经验证的系统
HarmonyOS Next 0.0.66
HarmonyOS Next 0.0.68 (目前最新版本)
鸿蒙Next(HarmonyOS NEXT)集成PJSIP库
在鸿蒙Next(HarmonyOS NEXT)中集成PJSIP库,可以通过以下步骤实现。PJSIP是一个开源的SIP协议栈,适用于嵌入式设备和移动平台。
步骤概述:
获取PJSIP源码:从官方仓库(https://github.com/pjsip/pjproject)下载或克隆源码。
配置交叉编译环境:鸿蒙Next使用ArkTS/JS开发,但PJSIP是C库,需通过NDK(Native Development Kit)编译为共享库(.so)。
编写Native C代码:创建C/C++文件调用PJSIP API。
使用NAPI桥接:通过HarmonyOS NAPI将C代码暴露给ArkTS层。
在ArkTS中调用:在UI或服务中集成SIP功能。
详细步骤及代码示例:
-
下载并编译PJSIP
下载PJSIP源码,解压到项目目录(如third_party/pjproject)。
配置编译脚本(如config_site.h),针对鸿蒙架构(arm64-v8a)进行交叉编译。示例配置:
// config_site.h
#define PJ_CONFIG_ANDROID 1
#include <pj/config_site_sample.h>
注意:需根据鸿蒙NDK调整配置,参考鸿蒙NDK文档设置工具链路径。
使用CMake或Makefile编译,生成libpjsip2.so等库文件。
- 创建Native C模块
在HarmonyOS Native层创建C文件(如sip_native.c),实现PJSIP初始化和基本调用:
#include <pjlib.h>
#include <pjsip.h>
#include <napi/native_api.h>
static napi_value InitPJSIP(napi_env env, napi_callback_info info) {
pj_status_t status;
pj_caching_pool cp;
pj_pool_t *pool;
// 初始化PJ库
status = pj_init();
if (status != PJ_SUCCESS) {
napi_throw_error(env, NULL, "PJSIP初始化失败");
return NULL;
}
// 创建内存池
pj_caching_pool_init(&cp, NULL, 1024);
pool = pj_pool_create(&cp.factory, "sip_pool", 4000, 4000, NULL);
// 其他SIP初始化代码(如传输层、UA等)
// ...
napi_value result;
napi_create_int32(env, status, &result);
return result;
}
// NAPI模块注册
EXTERN_C_START
static napi_module sip_module = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = NULL,
.nm_register_func = InitPJSIP,
.nm_modname = "pjsip",
.nm_priv = NULL,
};
EXTERN_C_END
-
配置NAPI和构建
在build-profile.json5中配置Native依赖:
"native": {
"name": "sipnative",
"sourceDir": "./src/main/cpp",
"systemLibs": ["log"]
}
将编译的PJSIP库(.so)放入libs/arm64-v8a/目录,并在CMakeLists.txt中链接:
target_link_libraries(sipnative PUBLIC pjsip2 pjlib-util)

- ArkTS调用示例
在ArkTS中通过NAPI接口调用Native函数:
import native from 'libsipnative.so'; // 根据实际库名调整
let status = native.initPJSIP();
if (status === 0) {
console.log('PJSIP初始化成功');
} else {
console.error('PJSIP初始化失败');
}
注意事项:
权限配置:在module.json5中添加网络权限:
"requestPermissions": [
{ "name": "ohos.permission.INTERNET" }
]
线程安全:PJSIP需在独立线程运行,避免阻塞UI。
错误处理:检查PJSIP API返回状态,确保资源释放。
测试验证:使用SIP服务器(如Asterisk)测试注册和呼叫功能。
通过以上步骤,可在鸿蒙Next中集成PJSIP实现SIP通信。具体API调用参考PJSIP文档(https://www.pjsip.org)。
更多推荐



所有评论(0)