前言
Telegram 的研究先放一放桑驱,在 Telegram 源碼中看到了 VOIP
相關(guān)功能牙躺,不禁想到自己上家公司的業(yè)務(wù)就是做 VOIP 通訊
佩迟,趁著現(xiàn)在自己這段時間勤奮勁還沒過酬诀,特地記錄下磺芭。
PJSIP 是什么?
PJSIP 是一個用 C 語言
編寫的開源嵌入式 SIP 協(xié)議庫是尖,實現(xiàn)了基于標(biāo)準(zhǔn)的協(xié)議(如SIP意系、SDP、RTP饺汹,STUN蛔添、TURN 和 ICE);把基于信令協(xié)議 SIP 的多媒體框架和 NAT 穿透功能整合成高層次、抽象的多媒體通信 API作郭。
PJSIP 具有非常好的移植性,幾乎支持現(xiàn)今所有系統(tǒng):從桌面系統(tǒng)弦疮、嵌入式系統(tǒng)到智能手機(jī)夹攒。
PJSIP 同時支持語音、視頻胁塞、狀態(tài)呈現(xiàn)和即時通訊咏尝;PJSIP 具有非常完善的文檔,對開發(fā)者非常友好啸罢。
PJSIP 基本框架
PJSIP 庫主要包括:
- SIP 協(xié)議棧:處理 SIP 消息
- 流媒體處理模塊:RTP / RTCP 等媒體包處理
SIP 協(xié)議部分
SIP 協(xié)議由下往上進(jìn)行了多層封裝:
- PJSIP -開源的 SIP 協(xié)議棧(Open Source SIP stack)
- PJMEDIA - 開源的媒體棧(Open Source Media Stack)
- PJNATH - 開源的 NAT-T 輔助庫(Open Source NAT Traversal Helper Library)
- PJLIB-UTIL - 輔助工具庫(Auxiliary Library)
- PJLIB - 基礎(chǔ)框架庫(Ultra Portable Base Framework Library)
對于 PJSIP 有以上基本了解就行编检,畢竟目前我們主要目的是編譯出 iOS 多架構(gòu)靜態(tài)庫,并導(dǎo)入到我們項目中進(jìn)行功能開發(fā)~
PJSIP 自動化導(dǎo)入
pod 'pjsip'
懶人必備方式扰才,已經(jīng)有先驅(qū)們因為個人需要編譯了這個版本:
- 優(yōu)點:不需要繁瑣的手動編譯允懂,伸手即得。
- 缺點:并不是官方存儲庫衩匣,且人家已經(jīng)完成了自己的開發(fā)任務(wù)蕾总,目前停留在了
2.9.1
版本,放棄了維護(hù)琅捏。
如果需要擴(kuò)展某些功能生百,他人編譯出來的版本未必會支持,到頭來柄延,還是得自己重新編譯~
PJSIP 手動編譯
截至目前(2023/01/28
)為止蚀浆,官方能下載的最新版本是 2.13
,因此搜吧,我將在這個版本上編譯市俊。
一、下載并解壓縮
首先滤奈,我們?nèi)?a target="_blank">官方下載源代碼秕衙,推薦下載 .tar.gz
的壓縮包。
下載完畢僵刮,我們可以將其放到一個合適的目錄下(最好路徑不包含中文)据忘,我這里就是將其放在桌面上;
若你電腦上已經(jīng)安裝了解壓縮軟件搞糕,就可以雙擊解壓縮勇吊;沒有的話也沒關(guān)系,我們打開終端
窍仰,用命令解壓縮:
tar -jxvf pjproject-2.13.tar.gz
這樣我們就能得到一個名為 pjproject-2.13
的文件夾汉规。
二、編譯
這里我已經(jīng)寫好了一個腳本:
#!/bin/sh
touch pjlib/include/pj/config_site.h
echo "#define PJ_CONFIG_IPHONE 1
#define PJ_HAS_IPV6 1
#include <pj/config_site_sample.h>
" > pjlib/include/pj/config_site.h
mkdir -p ./lib
export MIN_IOS="-miphoneos-version-min=8.0"
export DEVPATH=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer
#編譯 i386、x86_64针史、arm64 3種CPU架構(gòu)
export ARCH="-arch i386" CFLAGS="-O2 -m32 -mios-simulator-version-min=8.0" LDFLAGS="-O2 -m32 -mios-simulator-version-min=8.0"
./configure-iphone
make dep && make clean && make
export ARCH="-arch x86_64" CFLAGS="-O2 -m64 -mios-simulator-version-min=8.0" LDFLAGS="-O2 -m64 -mios-simulator-version-min=8.0"
./configure-iphone
make dep && make clean && make
export ARCH="-arch arm64"
./configure-iphone
make dep && make clean && make
#合并3種CPU架構(gòu)的.a庫
lipo -arch i386 third_party/lib/libg7221codec-i386-apple-darwin_ios.a -arch x86_64 third_party/lib/libg7221codec-x86_64-apple-darwin_ios.a -arch arm64 third_party/lib/libg7221codec-arm64-apple-darwin_ios.a -create -output lib/libg7221codec.a
lipo -arch i386 third_party/lib/libgsmcodec-i386-apple-darwin_ios.a -arch x86_64 third_party/lib/libgsmcodec-x86_64-apple-darwin_ios.a -arch arm64 third_party/lib/libgsmcodec-arm64-apple-darwin_ios.a -create -output lib/libgsmcodec.a
lipo -arch i386 third_party/lib/libilbccodec-i386-apple-darwin_ios.a -arch x86_64 third_party/lib/libilbccodec-x86_64-apple-darwin_ios.a -arch arm64 third_party/lib/libilbccodec-arm64-apple-darwin_ios.a -create -output lib/libilbccodec.a
lipo -arch i386 pjlib/lib/libpj-i386-apple-darwin_ios.a -arch x86_64 pjlib/lib/libpj-x86_64-apple-darwin_ios.a -arch arm64 pjlib/lib/libpj-arm64-apple-darwin_ios.a -create -output lib/libpj.a
lipo -arch i386 pjlib-util/lib/libpjlib-util-i386-apple-darwin_ios.a -arch x86_64 pjlib-util/lib/libpjlib-util-x86_64-apple-darwin_ios.a -arch arm64 pjlib-util/lib/libpjlib-util-arm64-apple-darwin_ios.a -create -output lib/libpjlib-util.a
lipo -arch i386 pjmedia/lib/libpjmedia-audiodev-i386-apple-darwin_ios.a -arch x86_64 pjmedia/lib/libpjmedia-audiodev-x86_64-apple-darwin_ios.a -arch arm64 pjmedia/lib/libpjmedia-audiodev-arm64-apple-darwin_ios.a -create -output lib/libpjmedia-audiodev.a
lipo -arch i386 pjmedia/lib/libpjmedia-codec-i386-apple-darwin_ios.a -arch x86_64 pjmedia/lib/libpjmedia-codec-x86_64-apple-darwin_ios.a -arch arm64 pjmedia/lib/libpjmedia-codec-arm64-apple-darwin_ios.a -create -output lib/libpjmedia-codec.a
lipo -arch i386 pjmedia/lib/libpjmedia-videodev-i386-apple-darwin_ios.a -arch x86_64 pjmedia/lib/libpjmedia-videodev-x86_64-apple-darwin_ios.a -arch arm64 pjmedia/lib/libpjmedia-videodev-arm64-apple-darwin_ios.a -create -output lib/libpjmedia-videodev.a
lipo -arch i386 pjmedia/lib/libpjmedia-i386-apple-darwin_ios.a -arch x86_64 pjmedia/lib/libpjmedia-x86_64-apple-darwin_ios.a -arch arm64 pjmedia/lib/libpjmedia-arm64-apple-darwin_ios.a -create -output lib/libpjmedia.a
lipo -arch i386 pjnath/lib/libpjnath-i386-apple-darwin_ios.a -arch x86_64 pjnath/lib/libpjnath-x86_64-apple-darwin_ios.a -arch arm64 pjnath/lib/libpjnath-arm64-apple-darwin_ios.a -create -output lib/libpjnath.a
lipo -arch i386 pjsip/lib/libpjsip-simple-i386-apple-darwin_ios.a -arch x86_64 pjsip/lib/libpjsip-simple-x86_64-apple-darwin_ios.a -arch arm64 pjsip/lib/libpjsip-simple-arm64-apple-darwin_ios.a -create -output lib/libpjsip-simple.a
lipo -arch i386 pjsip/lib/libpjsip-ua-i386-apple-darwin_ios.a -arch x86_64 pjsip/lib/libpjsip-ua-x86_64-apple-darwin_ios.a -arch arm64 pjsip/lib/libpjsip-ua-arm64-apple-darwin_ios.a -create -output lib/libpjsip-ua.a
lipo -arch i386 pjsip/lib/libpjsip-i386-apple-darwin_ios.a -arch x86_64 pjsip/lib/libpjsip-x86_64-apple-darwin_ios.a -arch arm64 pjsip/lib/libpjsip-arm64-apple-darwin_ios.a -create -output lib/libpjsip.a
lipo -arch i386 pjsip/lib/libpjsua-i386-apple-darwin_ios.a -arch x86_64 pjsip/lib/libpjsua-x86_64-apple-darwin_ios.a -arch arm64 pjsip/lib/libpjsua-arm64-apple-darwin_ios.a -create -output lib/libpjsua.a
lipo -arch i386 pjsip/lib/libpjsua2-i386-apple-darwin_ios.a -arch x86_64 pjsip/lib/libpjsua2-x86_64-apple-darwin_ios.a -arch arm64 pjsip/lib/libpjsua2-arm64-apple-darwin_ios.a -create -output lib/libpjsua2.a
lipo -arch i386 third_party/lib/libresample-i386-apple-darwin_ios.a -arch x86_64 third_party/lib/libresample-x86_64-apple-darwin_ios.a -arch arm64 third_party/lib/libresample-arm64-apple-darwin_ios.a -create -output lib/libresample.a
lipo -arch i386 third_party/lib/libspeex-i386-apple-darwin_ios.a -arch x86_64 third_party/lib/libspeex-x86_64-apple-darwin_ios.a -arch arm64 third_party/lib/libspeex-arm64-apple-darwin_ios.a -create -output lib/libspeex.a
lipo -arch i386 third_party/lib/libsrtp-i386-apple-darwin_ios.a -arch x86_64 third_party/lib/libsrtp-x86_64-apple-darwin_ios.a -arch arm64 third_party/lib/libsrtp-arm64-apple-darwin_ios.a -create -output lib/libsrtp.a
lipo -arch i386 third_party/lib/libwebrtc-i386-apple-darwin_ios.a -arch x86_64 third_party/lib/libwebrtc-x86_64-apple-darwin_ios.a -arch arm64 third_party/lib/libwebrtc-arm64-apple-darwin_ios.a -create -output lib/libwebrtc.a
lipo -arch i386 third_party/lib/libyuv-i386-apple-darwin_ios.a -arch x86_64 third_party/lib/libyuv-x86_64-apple-darwin_ios.a -arch arm64 third_party/lib/libyuv-arm64-apple-darwin_ios.a -create -output lib/libyuv.a
將該腳本保存為 build-iphone.sh
存放到剛解壓完成的 pjproject-2.13
文件夾下晶伦,然后執(zhí)行:
cd pjproject-2.13
進(jìn)入到 pjproject-2.13
文件夾,接著執(zhí)行
./build-iphone.sh
如果提示權(quán)限不夠啄枕,那么使用:
chmod 777 build-iphone.sh
來賦予該文件最大的訪問權(quán)限婚陪,接著再次執(zhí)行:
./build-iphone.sh
執(zhí)行完后,所有生成的不同架構(gòu)的靜態(tài)庫都會被合并频祝,且存放在 pjproject-2.13/lib 目錄下:
三泌参、集成
在桌面上新建一個文件夾,名為 PJSIP
常空,將上一步 編譯 完成的 lib
文件夾復(fù)制到 PJSIP
目錄下沽一,并在 PJSIP
文件夾目錄下新建一個 includes
文件夾,存放對應(yīng)的頭文件漓糙。
includes
下新建的文件夾铣缠,分別存放對應(yīng) pjproject-2.13
里相同名字文件夾下的 include
文件。
然后昆禽,我們新建一個 iOS 的項目 testPJSIPDemo
攘残,將 PJSIP
拖入到項目根目錄下,項目結(jié)構(gòu)如圖:
注意:includes 文件夾不要添加到項目中來为狸,只需添加 lib 文件夾歼郭,但我們?nèi)孕璞WC上圖中的目錄結(jié)構(gòu)
在項目工程配置中,在 targets
為 testPJSIPDemo
的 Build Settings
設(shè)置以下配置:
- Header Search Path:
$(PROJECT_DIR)/testPJSIPDemo/PJSIP/includes/pjlib
$(PROJECT_DIR)/testPJSIPDemo/PJSIP/includes/pjlib-util
$(PROJECT_DIR)/testPJSIPDemo/PJSIP/includes/pjmedia
$(PROJECT_DIR)/testPJSIPDemo/PJSIP/includes/pjnath
$(PROJECT_DIR)/testPJSIPDemo/PJSIP/includes/pjsip
- Other Linker Flags 添加 -ObjC
- Preprocessor Macros 添加 PJ_AUTOCONF=1
- Enable Bitcode 設(shè)置為 NO
在 Build Phases
中的 Link Binary With Libraries
中添加下面幾個 Framework
:
- Security
- SystemConfiguration
- VideoToolbox
- AudioToolbox
- AVFoundation
- CFNetwork
- CoreAudio
- CoreFoundation
- CoreImage
- CoreMedia
- CoreVideo
- OpenGLES
- QuartzCore
- Foundation
- CoreGraphics
- UIKit
在 info.plist
添加相機(jī)(如果需要視頻通話)和使用麥克風(fēng)所需的權(quán)限:
Privacy - Microphone Usage Description
Privacy - Camera Usage Description
走完上面的步驟辐棒,我們就可以正常的使用 pjsip
庫了病曾,Command + B
編譯下你的工程,如果有警告或錯誤漾根,那就說明你的配置可能出現(xiàn)了問題泰涂。