这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

记录--uniapp开发安卓APP视频通话模块初实践

视频通话SDK用的即构的,uniapp插件市场地址

推送用的极光的,uniapp插件市场地址

即构音视频SDK

uniapp插件市场的貌似是有些问题,导入不进项目,直接去官网下载,然后放到项目下的 nativeplugins 目录下,在配置文件中填入即构后台的appID和AppSign,接下来就可以开干了

准备两个页面

首页:/pages/index/index

// 新建一个按钮
<button @click="sendVideo">发送视频邀请</button>
// 发送事件,主动发送直接进入下一个页面即可
sendVideo(){
uni.navigateTo({
url: '/pages/call/call'
})
}

通话页:pages/call/call这个页面会复杂一点

注意这个页面为nvue页面

先把所有代码都列出来,再一一做说明

<template>
<view>
<view v-if="status === 1" class="switch-bg" :style="{'height': pageH + 'px'}">
<view class="top-info u-flex">
<image src="https://cdn.yuucn.cn/wp-content/uploads/2022/11/1668749350-6c49bb0403761c1.jpeg" class="avatar">
</image>
<view class="info u-flex u-flex-col u-col-top">
<text class="text">值班中心</text>
<text class="text">正在呼叫</text>
</view>
</view>
<view class="switch-handle u-flex u-row-center">
<image src="" class="img" @click="hangUp"></image>
</view>
</view>
<view v-if="status === 2" class="switch-bg" :style="{'height': pageH + 'px'}">
<view class="top-info u-flex">
<image src="https://cdn.yuucn.cn/wp-content/uploads/2022/11/1668749350-6c49bb0403761c1.jpeg" class="avatar">
</image>
<view class="info u-flex u-flex-col u-col-top">
<text class="text">值班中心</text>
<text class="text">邀请您视频聊天</text>
</view>
</view>
<view class="switch-handle">
<view class="u-flex">
<text>切到语音接听</text>
<image src=""></image>
</view>
<view class="u-flex u-row-center u-row-between">
<image src="" class="img" @click="hangUp"></image>
<image src="" class="img" @click="switchOn"></image>
</view>
</view>
</view>
<view v-if="status === 3" :style="{'height': pageH + 'px'}">
<view>
<zego-preview-view class="face"></zego-preview-view>
<view v-for="(stream, index) in streamList" :key="index">
<zego-view :streamID="stream.streamID"></zego-view>
</view>
</view>
<view class="switch-handle">
<view>
<text>{{minute}}:{{seconds}}</text>
</view>
<view>
<view>
<view class="icon-round">
<image src="" class="icon1" mode=""></image>
</view>
<text class="h-text">切到语音通话</text>
</view>
<view>
<image src="" class="img" @click="hangUp"></image>
<text class="h-text">挂断</text>
</view>
<view>
<view class="icon-round" @click="changeCamera">
<image src="" class="icon2" mode=""></image>
</view>
<text class="h-text">转换摄像头</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
// #ifdef APP-PLUS
var jpushModule = uni.requireNativePlugin("JG-JPush")
import ZegoExpressEngine from '../../zego-express-video-uniapp/ZegoExpressEngine';
import {ZegoScenario} from '../../zego-express-video-uniapp/impl/ZegoExpressDefines'
import {AppID,AppSign} from '../../zegoKey.js'
var instance = ZegoExpressEngine.createEngine(AppID, AppSign, true, 0);
// #endif
export default {
data() {
return {
status: 1, // 1: 主动呼叫;2: 被呼叫
pageH: '',	// 页面高度
innerAudioContext: null, //	音乐对象
streamList: [],
msg_id: '',		// 推送消息id
msg_cid: '',		// 推送cid
roomID: 'dfmily110001',
publishStreamID: uni.getStorageSync('userinfo').nickname,
userID: uni.getStorageSync('userinfo').nickname,
userName: uni.getStorageSync('userinfo').nickname,
camera_dir: 'before', // 摄像头 before 前置,after 后置
};
},
destroyed: () => {
console.log('destroyed');
ZegoExpressEngine.destroyEngine();
},
mounted() {
var client = uni.getSystemInfoSync()
if (client.platform == 'android') {
//安卓事先请求摄像头、麦克风权限
var nativeEngine = uni.requireNativePlugin('zego-ZegoExpressUniAppSDK_ZegoExpressUniAppEngine');
nativeEngine.requestCameraAndAudioPermission();
}
},
onLoad(opt) {
this.getSysInfo();
this.playAudio();
if(opt.status == 2){		// 带参数 status=2时代表被呼叫
this.status = parseInt(opt.status)
}
if(!opt.status){			// 主动呼叫、需要发推送消息
this.getPushCid();
}
this.initZegoExpress();
},
onBackPress() {
// return true;
this.innerAudioContext.stop();
this.logout();
},
methods: {
getSysInfo() { // 获取手机信息
let sys = uni.getSystemInfoSync()
this.pageH = sys.windowHeight
},
playAudio() { // 播放音乐
this.innerAudioContext = uni.createInnerAudioContext();
this.innerAudioContext.autoplay = true;
this.innerAudioContext.src = '/static/message.mp3';
this.innerAudioContext.onPlay(() => {
console.log('开始播放');
});
},
stopAudio(){		// 停止播放音乐
if (this.innerAudioContext) {
this.innerAudioContext.stop()
}
},
hangUp() { // 挂断
this.stopAudio();
this.sendCustomCommand(500)
this.revocationPushMsg();
this.logout();
uni.navigateBack({
delta:1
})
},
switchOn() { // 接通
this.stopAudio();
this.status = 3
this.sendCustomCommand(200)
},
changeCamera() { // 切换摄像头
var instance = ZegoExpressEngine.getInstance();
if (this.camera_dir == 'before') {
instance.useFrontCamera(false)
this.camera_dir = 'after'
} else if (this.camera_dir == 'after') {
instance.useFrontCamera(true)
this.camera_dir = 'before'
}
},
sendCustomCommand(msg){		// 发送自定义信令
var instance = ZegoExpressEngine.getInstance();
instance.sendCustomCommand(this.roomID, msg, [{
"userID": this.userID,
"userName": this.userName
}], res => {
console.log(res)
});
},
getPushCid(){			// 极光推送cid获取
uni.request({
url: 'n-round {
align-items: center;
justify-content: center;
width: 136rpx;
height: 136rpx;
border: 1rpx solid #fff;
border-radius: 50%;
.icon1 {
width: 64rpx;
height: 52rpx;
}
.icon2 {
width: 60rpx;
height: 60rpx;
}
}
.h-text {
margin-top: 10rpx;
font-size: 26rpx;
color: #fff;
}
}
</style>

说明:

代码中的masterSecret需要修改为极光后台的masterSecretappKey需要修改为极光后台的appKey

view 部分:

status=1 中的为主动呼叫方进入页面是初始显示内容,最重要的是 hangUp 方法,用来挂断当前邀请

status=2 中的为被邀请者进入页面初始显示的内容,有两个按钮,一个hangUp挂断,一个switchOn 接听

status=3中为接听后显示的内容(显示自己与对方视频画面)

script 部分:

最开始五行是引入相关SDK的。极光推送、即构音视频

onLoad 中有一个判断语句,这个就是用于判断进入页面时是主动呼叫方还是被动答应方的,显示不同内容

if(opt.status == 2){		// 带参数 status=2时代表被呼叫
this.status = parseInt(opt.status)
}
if(!opt.status){			// 主动呼叫、需要发推送消息
this.getPushCid();
}

sendCustomCommand 是用来在房间内发送自定义信令的,用于通知另一个人是接听了还是挂断了通话

getPushCid 是获取极光推送的cid,避免重复发送推送消息(极光推送)

changeCamera 切换摄像头

revocationPushMsg 撤销推送(主动呼叫方挂断通话)

sendPushMsg 发推送消息

initZegoExpress 初始化即构音视频SDK相关,与官网demo,此处我做了小改动

login 登录即构房间

logout 退出即构房间

publish 推流

destroyEngine 销毁音视频实例

removeStreams 删除流

encode base64转码

在App.vue中进行极光推送的初始化

onLaunch: function() {
console.log('App Launch')
// #ifdef APP-PLUS
if (uni.getSystemInfoSync().platform == "ios") {
// 请求定位权限
let locationServicesEnabled = jpushModule.locationServicesEnabled()
let locationAuthorizationStatus = jpushModule.getLocationAuthorizationStatus()
console.log('locationAuthorizationStatus', locationAuthorizationStatus)
if (locationServicesEnabled == true && locationAuthorizationStatus < 3) {
jpushModule.requestLocationAuthorization((result) => {
console.log('定位权限', result.status)
})
}
jpushModule.requestNotificationAuthorization((result) => {
let status = result.status
if (status < 2) {
uni.showToast({
icon: 'none',
title: '您还没有打开通知权限',
duration: 3000
})
}
})
jpushModule.addGeofenceListener(result => {
let code = result.code
let type = result.type
let geofenceId = result.geofenceId
let userInfo = result.userInfo
uni.showToast({
icon: 'none',
title: '触发地理围栏',
duration: 3000
})
})
jpushModule.setIsAllowedInMessagePop(true)
jpushModule.pullInMessage(result => {
let code = result.code
console.log(code)
})
jpushModule.addInMessageListener(result => {
let eventType = result.eventType
let messageType = result.messageType
let content = result.content
console.log('inMessageListener', eventType, messageType, content)
uni.showToast({
icon: 'none',
title: JSON.stringify(result),
duration: 3000
})
})
}
jpushModule.initJPushService();
jpushModule.setLoggerEnable(true);
jpushModule.addConnectEventListener(result => {
let connectEnable = result.connectEnable
uni.$emit('connectStatusChange', connectEnable)
});
jpushModule.addNotificationListener(result => {
let notificationEventType = result.notificationEventType
let messageID = result.messageID
let title = result.title
let content = result.content
let extras = result.extras
console.log(result)
this.$util.router(`/pages/public/answer?status=2`)
});
jpushModule.addCustomMessageListener(result => {
let type = result.type
let messageType = result.messageType
let content = result.content
console.log(result)
uni.showToast({
icon: 'none',
title: JSON.stringify(result),
duration: 3000
})
})
jpushModule.addLocalNotificationListener(result => {
let messageID = result.messageID
let title = result.title
let content = result.content
let extras = result.extras
console.log(result)
uni.showToast({
icon: 'none',
title: JSON.stringify(result),
duration: 3000
})
})
// #endif
},

不要忘了在最开始引入极光推送的插件

var jpushModule = uni.requireNativePlugin("JG-JPush")

官方demo的代码,直接拿过来了。。

其中最重要的就是下面这段,用来监听获取推送消息的,这里如果收到推送消息自动跳转至通话页面,也就是上面status=2的状态下

jpushModule.addNotificationListener(result => {
let notificationEventType = result.notificationEventType
let messageID = result.messageID
let title = result.title
let content = result.content
let extras = result.extras
console.log(result)
this.$util.router(`/pages/call/call?status=2`)
});

https://juejin.cn/post/6954172658195906567

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

记录--uniapp开发安卓APP视频通话模块初实践

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。