android sip视频聊天开发
采用的是linphone 5.0.0的版本:'org.linphone:linphone-sdk-android:5.0.0'
我已经实现视频通话,但是在获取当前来电是视频还是普通来电时候遇到问题;
目前是发送端的videoEnabled不论设置true还是false接收端都为默认值true;
自定义头也收不到
//发送端
params?.enableVideo(true)
//或者
params?.enableVideo(false)
//接收端始终是true:
val remoteParams = core.currentCall!!.remoteParams
if (remoteParams != null && remoteParams .videoEnabled()) {
showLog("视频来电")
//answer: video true
} else {
showLog("普通电话")
//answer: video false");
}
发送端自定义addCustomHeader
//发送端自定义头
val headerKey = "X-Custom-Header"
val headerValue = "Custom Information"
params!!.addCustomHeader(headerKey, headerValue)
//接收端
call.currentParams.getCustomHeader(headerKey) //始终为空
从您的描述来看,此Linphone视频通话实现中存在以下两个问题:
视频通话参数enableVideo设置不生效,接收端始终获取到的视频状态为true。
自定义头信息addCustomHeader添加成功,但接收端无法获取该信息。
这两个问题的可能原因有:
在使用Linphone SDK进行android视频聊天开发时,您需要在SIP消息头中携带信息来标记协商出的音视频策略,这样接收端才能正确识别当前通话是音频还是视频。
Linphone SDK 的默认SIP头部是不支持自定义的,如果您需要发送自定义数据,建议在sdphandler.c文件中进行修改。 在on_sip_request_outgoing()函数中,您可以手动添加 SIP头部:
linphone_sdp_add_custom_header(linphone_sdp, "X-VIDEO_ENABLED: false \r\n");
这里,X-VIDEO_ENABLED头是自定义的SIP头,包含双方是否启用视频的标志位信息。另外,在接收SIP消息时,相应的自定义头应该通过相应的API来读取。
代码示例:
CallParams callParams = mCore.createCallParams(mCore.getCurrentSelectedAddress());
callParams.enableVideo(true);
Call call = mCore.inviteAddressWithParams(mCore.getCurrentSelectedAddress(),callParams);
在发起呼叫时,使用enableVideo函数设置是否启用视频。在接收到SIP消息时,使用linphone_call_params_video_enabled获取视频是否启用标志。
if (call.getRemoteParams() != null && call.getRemoteParams().videoEnabled()) {
//视频来电
}else{
//普通来电
}
以上是基于Linphone SDK 5.0.0实现的示例,您可以根据自己的实际情况做出适当修改。
有可能是拨打电话段的参数没有设置好,设置是否是视频通话,通过 CallParams 参数指定, 并通过inviteAddressWithParams方法发起通话,大致代码如下:
CallParams params = core.createCallParams(null);
params.setMediaEncryption(MediaEncryption.None);
params.enableVideo(video);
// Finally we start the call
core.inviteAddressWithParams(remoteAddress, params);
关于来电是视频还是普通电话的问题,您需要在每次呼入时检查远程参数(remoteParams)中是否设置了 videoEnabled 的值。如果 remoteParams 为 null,则可能意味着您在接听之前就检查了这个值。
请尝试在接收到来电后开始监听远程参数,例如:
// 在接收到来电之后添加远程参数监听器
core.addListener(object : LinphoneCoreListenerBase() {
override fun callStateChanged(core: LinphoneCore?, call: LinphoneCall?, state: LinphoneCall.State?, message: String?) {
super.callStateChanged(core, call, state, message)
if (state == LinphoneCall.State.IncomingReceived && call?.remoteParams != null) {
val isVideoEnabled = call.remoteParams.videoEnabled()
if (isVideoEnabled) {
// 视频来电
showLog("视频来电")
} else {
// 普通电话
showLog("普通电话")
}
}
}
})
关于自定义头的问题,如果发送方未启用“加密信息头”(encrypt_information_headers),则自定义标题可能会被对端服务器或IDA授权中心拦截。请确保您在初始化时启用了加密信息头,并使用标准SIP header名称而不是像 "X-Custom-Header" 这样的自定义标题。例如:
// 初始化操作
LinphoneCore.setLogLevel(LogCollection.LogLevel.Debug)
factory = Factory.instance()
core = factory.createLinphoneCore(this, null)
// 启用加密信息头并添加自定义标题
core.iterate { // 等待核心启动完成
core.createProxyConfig()
val sipHeader = factory.createInfoMessage(null)
sipHeader.addHeader("Custom-Header", "Custom Information")
core.setDefaultProxyConfig(core.defaultProxyConfig)
}
接收方使用 currentCall.currentParams.getCustomHeader(headerName) 方法获取标准 SIP header 名称。例如:
// 在获取自定义头之前,确保至少有一个call存在
if (core.callsNb > 0 && core.currentCall != null) {
val callParams = core.currentCall!!.currentParams
val customHeaderValue = callParams.getCustomHeader("Custom-Header")?.value
if (customHeaderValue != null) {
showLog("Received Custom Header Value: $customHeaderValue")
}
}
请注意,在生产环境中,可能需要更多的配置和测试才能确保通用性、安全性和可靠性。
网络抓包,看看实际发送请求的数据情况,看下是否与发送端设置的一致