必须使用Linux编译,不要在Windows上浪费时间,编译好了再把so拷贝出来Windows即可。没有Linux?virtualbox搞一个Ubuntu不是什么难事,网速快的话半小时搞定。
源码目录说明
目录: lib: [PJPROJECT的lib库] pjlib:[基础框架库] pjlib-util:[辅助工具库] pjmedia:[开源的媒体栈] pjnath:[开源的NAT-T辅助库] pjsip:[开源的SIP协议栈] pjsip-apps[demo]
配置准备
VirtualBox6.1 Ubuntu 16.0.4桌面版(编译期间最好不用让Ubuntu息屏或锁屏,否则可能会导致失败)
安装vim,方便编辑
以下软件全部放到/home/itant/Documents/下: ①先卸载原有的openjdk,再安装jdk 1.8(arch命令查看系统架构,然后下载对应的版本,这里是x86_64,即下载x64对应的即可) 对应文件夹:/home/itant/Documents/jdk1.8
②Android Studio Bumblebee | 2021.1.1 对应文件夹:/home/itant/Documents/android-studio 打开AndroidStudio,在Android Studio的Setting修改Android SDK Location:/home/itan/Documents/sdk 应用并等待完成… 对应文件夹:/home/itant/Documents/sdk 然后再次点击Setting,设置: -Android SDK:Android 25(根据测试机的安卓版本确定,对应Android 7.1.1,可酌情修改,可以安装Android Studio后在SDK Manager里下载) -Android SDK Build-Tools 24(build-tools;24.0.0) -Android SDK Command-line Tools (cmdline-tools;1.0) -CMake 3.6.4111459(cmake;3.6.4111459) Setting里cmake和command line勾选最旧的
③Android SDK Tools http://dl.google.com/android/android-sdk_r24.4.1-linux.tgz 。(必需等于或小于该版本,之后的版本弃用android命令,导致编译失败) 将android-sdk_r24.4.1-linux.tgz解压后的tools文件夹覆盖Android Studio默认SDK里的tools文件夹。
④android-ndk-r13b 对应文件夹:/home/itant/Documents/ndk-r13b
⑤Openh264版本:1.6.0 下载地址https://github.com/cisco/openh264/archive/v1.6.0.zip 说明:没有使用最新版本,在https://trac.pjsip.org/repos/ticket/1947明确说明了使用1.6.0版本 对应文件夹:/home/itant/Documents/openh264-1.6.0
⑥pjproject-2.11 下载链接:https://github.com/pjsip/pjproject/archive/refs/tags/2.11.zip 对应文件夹:/home/itant/Documents/pjproject-2.11
因为项目需求,需要保证SIP通话过程中服务器不对音频数据包进行转码,因此需要减少PJSIP默认支持的音频编码格式,同时也可以减小编译出来的链接库大小。 在pjlib/include/pj/中新建config_site.h文件,内容如下:
/* Activate Android specific settings in the 'config_site_sample.h' */
#define PJ_CONFIG_ANDROID 1
//To enable video
#define PJMEDIA_HAS_VIDEO 1
//To enable libyuv
#define PJMEDIA_HAS_LIBYUV 1
//To enable TCP transport
#define PJ_HAS_TCP 1
#include <pj/config_site_sample.h>
此时,config_site.h也是有一个锁的标志的,直接chmod 777 config_site.h
(可选)修改config_site_sample.h中针对Android的配置如下:
······
/*
* Android sample settings.
*/
#if PJ_CONFIG_ANDROID
······
/* Disable some codecs */
#define PJMEDIA_HAS_L16_CODEC 0
#define PJMEDIA_HAS_GSM_CODEC 1
#define PJMEDIA_HAS_SPEEX_CODEC 0
#define PJMEDIA_HAS_ILBC_CODEC 0
#define PJMEDIA_HAS_PCMU_CODEC 1
#define PJMEDIA_HAS_PCMA_CODEC 1
#define PJMEDIA_HAS_G722_CODEC 0
#define PJMEDIA_RTP_PT_TELEPHONE_EVENTS 0
#define PJMEDIA_RTP_PT_TELEPHONE_EVENTS_STR 0
#define PJMEDIA_ADVERTISE_RTCP 0
······
上述修改主要是保留了GSM、PCMU、PCMA音频编码,取消了其余的静态编码方式和动态编码方式,可以根据需要酌情修改。
配置环境
①配置Java环境变量 执行vim /etc/profile ,在最后一行添加:
export JAVA_HOME=/home/itant/Documents/jdk1.8
export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin
②配置SDK 可以安装Android Studio后在SDK Manager里下载相应SDK版本,然后将android-sdk_r24.4.1-linux.tgz解压后的tools文件夹覆盖Android Studio默认SDK里的tools文件夹。 编辑/etc/profile配置文件,添加:
export ANDROID_SDK_ROOT=/home/itant/Documents/sdk
export PATH=$PATH:$ANDROID_SDK_ROOT/tools:$ANDROID_SDK_ROOT/platform-tools
③配置NDK 将NDK解压,编辑/etc/profile配置文件,添加:
export ANDROID_NDK_ROOT=/home/itant/Documents/ndk-r13b
export PATH=$PATH:$ANDROID_NDK_ROOT
④更新环境变量 临时:执行source /etc/profile,更新本次终端的环境变量; 长期:重启,/etc/profile文件在每次启动时均会加载 这里最好重启一下
开始编译
①编译说明 编译过程中所有Android版本均使用android 25(根据目标机的安卓版本确定,对应Android 7.1.1,可酌情修改); CPU架构均使用arm64-v8a
②编译openh264 进入openh264目录,可以先建立androidlib目录,然后执行
make OS=android NDKROOT=/home/itant/Documents/ndk-r13b TARGET=android-25 PREFIX=./androidlib install-shared ARCH=arm64-v8a
注意,NDKROOT赋值为前述NDK的路径,PREFIX为编译后生成的头文件和链接库的位置,这里是openh264目录下的androidlib文件夹,这个路径在编译PJSIP还要用于指明openh264位置。 Opneh264默认采用armeabi-v7a架构。如ARCH=arm可以指定编译架构。
③安装swig用于编译java接口文件:
sudo apt install swig
建议手动安装: 下载安装swig4.0.2(http://www.swig.org/download.html),下载完成后解压。 下载pcre-8.40.tar.bz2(https://sourceforge.net/projects/pcre/files/),放到解压后的swig目录里 依次执行:
./Tools/pcre-build.sh
./autogen.sh
./configure
make
make install
④编译PJSIP配置: 进入PJSIP目录,执行配置:
NDK_TOOLCHAIN_VERSION=clang TARGET_ABI=arm64-v8a APP_PLATFORM=android-25 ./configure-android --use-ndk-cflags --with-openh264=/home/itant/Documents/openh264-1.6.0/androidlib
如果有权限问题,chmod 777
注意:NDK_TOOLCHAIN_VERSION=4.9 这个必须设置,如果没有设置这个,configure-android无法配置成功,亲测还是会报错“This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.”,于是换成NDK_TOOLCHAIN_VERSION=clang;
APP_PLATFORM=android-25设置成自己需要运行的android版本;
–use-ndk-cflags 为系统选项,必须跟上;
–with-openh264=xxx/androidlib/ 设置成openh264编译成功后,生成的androidlib目录的绝对路径,参考openh264编译中PREFIX的目录名称。编译时可能报错’wels/codec_api.h’ file not found,可能是因为没有权限,仔细观察发现androidlib文件夹上有个锁的标志,chmod 777 androidlib ,再次运行还是不行,原来openh264的路径写的是相对路径,替换成全路径重试成功。
⑤编译PJSIP:
make dep && make clean && make
⑥如果要编译其他架构,必须先清除
$ cd /path/to/your/pjsip/dir
$ make clean
# cleanup pjsua sample app
$ cd pjsip-apps/src/pjsua/android/jni
$ make clean
# also cleanup pjsua2 sample app (SWIG)
$ cd /path/to/your/pjsip/dir
$ cd pjsip-apps/src/swig
$ make clean
然后再执行⑤
⑦使用swig编译demo 编译之前也要先执行⑥
cd /path/to/your/pjsip/dir
cd pjsip-apps/src/swig
make
demo源码:pjsip-apps/src/swig/java/android,拷贝出来导入AndroidStudio运行,记得把生成的其他so,如libopenh264.so也拷贝到android/pjsua2/src/main/jniLibs/对应架构文件夹下。
⑧创建自己的项目 导入pjsua2使用 如果不使用module,则拷贝在pjsip-apps/src/swig/java/android/app/src/main/java/org/pjsip/pjsua2生成的pjsua2 Java接口文件,这些文件是给apk开发使用的,so文件也要拷贝全。
刚开始使用armeabi-v7a没有成功,提示Failed to load native library pjsua2,后来不使用openh264,且改用arm64-v8a成功了(部分支持arm64-v8a架构的手机可用)
局域网拨打
我们的开发环境大多都是局域网,而sip如果要跨网段打电话,就需要sip服务器和stun服务器。其实,如果我们的手机都在同一个网段的局域网,而且只是测试PjSip的功能,是没有必要使用sip服务器和stun服务器的。
下面说下,不需要sip服务器和stun服务器,只在局域网内测试PjSip功能,A、B在同一个网段的局域网中。。
1、打开pjsip-apps\src\swig\java\android\app\src\main\java\org\pjsip\pjsua2\app目录下的MyApp.java,注释掉 public void init(MyAppObserver obs, String app_dir, boolean own_worker_thread)接口中的:
//ua_cfg.setStunServer(stun_servers); //局域网测试中,不需要设置stun服务器。
//不需要TCP和TLS transport连接,特别是TLS,在apk运行是报错,TCP可以参考保留
// try {
// ep.transportCreate(pjsip_transport_type_e.PJSIP_TRANSPORT_TCP,
// sipTpConfig);
// } catch (Exception e) {
// System.out.println(e);
// }
// try {
// sipTpConfig.setPort(SIP_PORT+1);
// ep.transportCreate(pjsip_transport_type_e.PJSIP_TRANSPORT_TLS,
// sipTpConfig);
// } catch (Exception e) {
// System.out.println(e);
// }
2、设置sip账号 点击扳手图标,设置Pjsip中自己的sip账号地址(可填写当前设备的局域网IP,留空则对方看到empty):sip:IP地址,如:sip:192.168.1.100
3、点击加号图标增加一个联系人,联系人设置成:sip:对方局域网IP地址:6000,如:sip:192.168.1.100:6000 6000是端口号,example指定了端口号为6000
4、拨打 选中添加的联系人,点击拨号按钮。
实例设置: A的ID设置成sip:192.168.1.100,增加一个联系人B,B的地址设置成:sip:192.168.1.106:6000 B的ID设置成sip:192.168.1.106,增加一个联系人A,A的地址设置成:sip:192.168.1.100:6000
可以A拨打B或者B拨打A
跨网段打电话测试
1、需要搭建自己的公网sip服务器 2、需要搭建自己的stun服务器或者使用公网的stun服务器 3、设置自己的ID:sip:电话@IP地址,如:sip:101@192.168.1.1 4、设置注册服务器地址registrar:sip:192.168.1.1 5、设置用户名和密码
转换为AndroidStudio编译
1、新建native module,拷贝整个pjproject开源库到cpp目录,拷贝编译好的pjsua java文件到java文件夹。 2、复制可能用到的其他so到cpp目录,如openh264.so 3、自行编写CMakeLists.txt文件,链接所有C/C++文件(重点)
官方文档:https://trac.pjsip.org/repos/wiki/Getting-Started/Android 参考文档:https://www.freesion.com/article/9552413705/ 仓库地址:https://github.com/pjsip/pjproject
|