更新记录

1.6.14(2023-11-02)

添加静音功能

1.6.13(2023-10-25)

 新增静音功能

1.6.12(2023-10-11)

1、新增可自定义头部数据包中user-agent标识 2、自定义注册过期时间

查看更多

平台兼容性

Android Android CPU类型 iOS
适用版本区间:6.0 - 12.0 armeabi-v7a:未测试,arm64-v8a:未测试,x86:未测试 适用版本区间:11 - 15

原生插件通用使用流程:

  1. 购买插件,选择该插件绑定的项目。
  2. 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
  3. 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
  4. 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
  5. 开发完毕后正式云打包

付费原生插件目前不支持离线打包。
Android 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/android
iOS 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/ios

注意事项:使用HBuilderX2.7.14以下版本,如果同一插件且同一appid下购买并绑定了多个包名,提交云打包界面提示包名绑定不一致时,需要在HBuilderX项目中manifest.json->“App原生插件配置”->”云端插件“列表中删除该插件重新选择


于linphone封装SIP电话uniapp插件

重要的事情说在前面

  1. 如果没有声音请先确认是否有录音和蓝牙权限
  2. uni把基础权限独立分离了,云打包或打基座在manifest.json需勾选蓝牙和record模块

拨打和接听流程

  • 拨打:插件引入 → SIP用户注册→onRegistrationStateChanged监听注册结果→拨打电话

  • 接听:插件引入 →SIP用户注册→onRegistrationStateChanged监听注册结果→onCallStateChanged事件监听

方法

模块引入

const uniLinphone = uni.requireNativePlugin('crc-linphone');  // 模块方法
const globalEvent = uni.requireNativePlugin('globalEvent');   // 事件监听

SIP注册

可通过onRegistrationStateChanged事件监听是否注册成功或失败状态,回调e为json,result空为正常,异常为异常信息

最后一个回调只是返回register的执行结果有异常会在此抛出,并不是真正注册成功失败事件

/**
 * 参数dommain:服务端IP或域名
 * 参数username:账号
 * 参数passwd:密码
 * 参数transportType: 传输协议,默认UDP协议,枚举值 0:Udp 1:Tcp 2:Tls 3:Dtls  
 * 参数ringStoneUrl: 铃声URL(目前只对ios有用)
 * 参数options: (暂不支持ios)没有用到请删除这个字段,不然会有概率注册不成功,里面的字段没有也删除保留要用的非必要不设置
 * 参数4:回调方法,回调参数方法是否执行成功,注册成功或失败在onRegistrationStateChanged监听
 */
uniLinphone.register({
  "domain":"xxx.xxx.com",
  "username":"02010020",
  "passwd":"xxxx",
  "transportType": "0",  
  "ringStoneUrl":"https://www.cambridgeenglish.org/images/153149-movers-sample-listening-test-vol2.mp3",
  "options": {
    "echoCancellationEnabled": true,  // 消除回声
    "adaptiveRateControlEnabled": true, // 自适应速率
    "pushNotificationEnabled": false, // 推送通知
    "accountParamsExpires": 3600,  // 注册过期时间
    "coreUserAgent": "", // 数据包中user-agent标识
  }
  },(e)=>{
  // e: { result: ""}
});

// 注销
uniLinphone.unregister();

呼叫

两个参数,第一个参数为对应SIP账号或具体手机号码,第二个回调e为json,result空为正常,异常为异常信息,可以在onCallStateChanged事件中监听当前通话的状态,安卓可直接使用10003进去拨打,IOS需要完整的SIP地址

// 拨打sip电话
uniLinphone.callPhone("sip:10003@xxx.xxx.com", (e)=>{
 // e: { result: ""}
});

// 拨打真实号码
uniLinphone.callPhone("sip:158xxxx1363@xxx.xxx.com", (e)=>{
 // e: { result: ""}
});

接听

参数回调,成功或失败结果也可以在onCallStateChanged事件中监听当前通话的状态,回调e为json,result空为正常,异常为异常信息

uniLinphone.acceptCall((e)=>{
  // e: { result: ""}
});

挂断

参数回调,成功或失败结果也可以在onCallStateChanged事件中监听当前通话的状态,回调e为json,result空为正常,异常为异常信息

uniLinphone.handUp((e)=>{
  // e: { result: ""}
});

扬声器、听筒、蓝牙、耳机播放

会自动监听是否有蓝牙或耳机插入,顺序:蓝牙耳机->有线耳机->默认(听筒或扬声器)

// 听筒播放
uniLinphone.toggleMicrophone();

// 扬声器播放
uniLinphone.toggleSpeaker();

// 指定蓝牙播放:IOS系统限制可能无效
uniLinphone.toggleBluetooth();

// 指定耳机播放:IOS系统限制可能无效
uniLinphone.toggleHeadset();

静音和恢复

方法会自动判断当前是静音还是通话中

// 静音和恢复
uniLinphone.pauseOrResume();

获取来电的通话信息

前提:当有来电时

可以通过此方法获取来电人信息,参数返回电SIP账号/手机号码

uniLinphone.getCurrentCall((e)=>{
    // { remoteAddress : '158xxxx1363' }
});

获取通话记录

先登录

可以通过此方法获取通话记录,参数为当前登录账号的通话记录数组。

uniLinphone.getCallLog((e)=>{
    // [{callId:"",dir:"",duration:"",errorInfo:"",...}] 还有很多参数
});

事件

onCallStateChanged

模块引入与使用:

const globalEvent = uni.requireNativePlugin('globalEvent');   
globalEvent.addEventListener('onCallStateChanged', function(e) {
  // e 通话状态
});

可通过此事件监听当前通话的所有状态,枚举值如下:

/// Initial state. 
case Idle = 0
/// Incoming call received. 
case IncomingReceived = 1
/// PushIncoming call received. 
case PushIncomingReceived = 2
/// Outgoing call initialized. 
case OutgoingInit = 3
/// Outgoing call in progress. 
case OutgoingProgress = 4
/// Outgoing call ringing. 
case OutgoingRinging = 5
/// Outgoing call early media. 
case OutgoingEarlyMedia = 6
/// Connected. 
case Connected = 7
/// Streams running. 
case StreamsRunning = 8
/// Pausing. 
case Pausing = 9
/// Paused. 
case Paused = 10
/// Resuming. 
case Resuming = 11
/// Referred. 
case Referred = 12
/// Error. 
case Error = 13
/// Call end. 
case End = 14
/// Paused by remote. 
case PausedByRemote = 15
/// The call's parameters are updated for example when video is asked by remote. 
case UpdatedByRemote = 16
/// We are proposing early media to an incoming call. 
case IncomingEarlyMedia = 17
/// We have initiated a call update. 
case Updating = 18
/// The call object is now released. 
case Released = 19
/// The call is updated by remote while not yet answered (SIP UPDATE in early
/// dialog received) 
case EarlyUpdatedByRemote = 20
/// We are updating the call while not yet answered (SIP UPDATE in early dialog
/// sent) 
case EarlyUpdating = 21

onRegistrationStateChanged

模块引入使用:

const globalEvent = uni.requireNativePlugin('globalEvent');   
globalEvent.addEventListener('onRegistrationStateChanged', function(e) {
  // e 注册状态
});

可通过此事件监听注册状态,枚举值如下:

/// Initial state for registrations. 
case None = 0
/// Registration is in progress. 
case Progress = 1
/// Registration is successful. 
case Ok = 2
/// Unregistration succeeded. 
case Cleared = 3
/// Registration failed. 
case Failed = 4

编码

语音编码

获取语音编码

uniLinphone.getAudioPayloadTypes(res=>{
  this.info = JSON.stringify(res); 
});

启用语音编码

res返回为空则设置成功,可通过再次调用getAudioPayloadTypes查看是否启用成功,参数params是数组,可通过getAudioPayloadTypes获取

uniLinphone.enableAudioPayloadTypes(params, res=>{
  // res 返回为空则设置成功
});

DTMF

发送DTMF

通话过程中会有发送数字或字符需求,可以过该方法发送

/**
* 发送DTMF
* @dtmft 需要发送的字符
* @res 回调结果,result为空,执行功能不然为错误信息
*/
uniLinphone.sendDTMF({
  "dtmfs": "#"
},(res) => {
  this.info  = JSON.stringify(e);
});

注意事项

权限

云打包(打基座或正式包)

模块配置勾选: Bluetooth、Record

权限配置勾选:

"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",

APP原生插件配置:

根据自个情况选择本地或云端插件,不能都选

其他配置

ios需添加UIBackgroundModes

"distribute" : {
    /* ios打包配置 */
    "ios" : {
      "UIBackgroundModes" : [ "audio" ]
    }
}

常见问题

互助QQ群:530326661

  1. 通话没声音

打开APP看下录音权限是否已获取了录音权限

  1. 视频没画面

打开APP看下录音权限是否已获取了录音权限

  1. 息屏后没反应

安卓需做保活处理允许后台运行、ios需要添加UIBackgroundModes后台权限

  1. 注册没反应

注册执行方法与回调是分离的,注意回调是否在函数生命周期内,网络不通等待的时间会相对时间长点

隐私、权限声明

1. 本插件需要申请的系统权限列表:

"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>", "<uses-permission android:name=\"android.permission.BLUETOOTH\"/>",

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问