前言:因为我所做的项目需求是,接到后端推送视频消息,APP端点击消息跳转到通话页面进行1对1通话,而后端已经进行账号好友等的处理,环信提供的demo很多功能前端暂时用不到了,以下就把我用到的罗列出来。

PS:本人并不是前端大神,第一次分享文章,有写不对的欢迎提出来哦,请大佬们多多包涵!

效果:

一、引入插件

  1. 首先,在插件市场https://ext.dcloud.net.cn/plugin?id=3507,按照官方文档集成参考说明,把所用到插件导入到你的项目中

  2. 下载环信demo,以下是需要直接复制粘贴到你的项目中的sdk和组件以及你所用到的图片,图片暂不展示

  3. 音视频SDK在emediaSDK/emedia_for_miniProgram.js里,引入SDK方法:在App.vue页面引入

let emedia = uni.emedia = require("./emediaSDK/emedia_for_miniProgram");emedia.config({useUniappPlugin: true}) // 设置使用uniapp插件

二、改造demo实现我的项目需求

  1. 项目只是单纯实现接听视频通话,所以思路大概如下:
    (1)项目需求直接用项目的账号进行登录,后端已处理环信的账号登录、好友绑定、创建群聊等,所以我这边登录项目的账号的时候已经跟后端的账号好友绑定了。现在展示一下环信登录的代码:
    (appKey是每个项目使用环信的唯一标识,就相当于微信小程序的appid)
// //接收环信多人视频
var options = {apiUrl: 'https://a1.easemob.com',user: XX,pwd: XX,appKey: XX
};
//环信登录
WebIM.conn.open(options);

(2)在App.vue入口页,通过onTextMessage()函数监听到后端传来的视频参数,接收到我的账号、发出视频邀请的账号、会议Id,接收到的参数直接传入groupChatRoom页面:
(这里只展示关键代码,后面附上groupChatRoom页面完整代码)

WebIM.conn.listen({onTextMessage(message) {console.log("onTextMessage", message);if (message) {if (onMessageError(message)) {msgStorage.saveReceiveMsg(message, msgType.TEXT);}var my = uni.getStorageSync("myUsername");var nameList = {myName: my,your: message.from,groupId: message.ext.conferenceId};uni.navigateTo({url: "/pages/groupChatRoom/groupChatRoom?username=" + JSON.stringify(nameList)});calcUnReadSpot(message);ack(message);}
},

(3)groupChatRoom页面里展示的是接收群聊消息,因为后端已做好好友绑定、创建群聊,所以这里我只需列出后端传来的最新消息即可,以下是demo提供的处理数据的代码,有一些数据我的项目需求用不到,不过懒得整理了,处理最后得到的array数据,存入浏览器本地,之后需要调用到:

getChatList() {var array = [];var member = uni.getStorageSync("member");var myName = uni.getStorageSync("myUsername");var listGroups = uni.getStorageSync('listGroup') || [];for (let i = 0; i < member.length; i++) {let newChatMsgs = uni.getStorageSync(member[i].name + myName) || [];let historyChatMsgs = uni.getStorageSync("rendered_" + member[i].name + myName) || [];let curChatMsgs = historyChatMsgs.concat(newChatMsgs);if (curChatMsgs.length) {let lastChatMsg = curChatMsgs[curChatMsgs.length - 1];lastChatMsg.unReadCount = newChatMsgs.length;if (lastChatMsg.unReadCount > 99) {lastChatMsg.unReadCount = "99+";}let dateArr = lastChatMsg.time.split(' ')[0].split('-');let timeArr = lastChatMsg.time.split(' ')[1].split(':');let month = dateArr[2] < 10 ? '0' + dateArr[2] : dateArr[2];lastChatMsg.dateTimeNum = `${dateArr[1]}${month}${timeArr[0]}${timeArr[1]}${timeArr[2]}`;lastChatMsg.time = `${dateArr[1]}月${dateArr[2]}日 ${timeArr[0]}时${timeArr[1]}分`;array.push(lastChatMsg);}}for (let i = 0; i < listGroups.length; i++) {let newChatMsgs = uni.getStorageSync(listGroups[i].groupid + myName) || [];let historyChatMsgs = uni.getStorageSync("rendered_" + listGroups[i].groupid + myName) || [];let curChatMsgs = historyChatMsgs.concat(newChatMsgs);if (curChatMsgs.length) {let lastChatMsg = curChatMsgs[curChatMsgs.length - 1];lastChatMsg.unReadCount = newChatMsgs.length;if (lastChatMsg.unReadCount > 99) {lastChatMsg.unReadCount = "99+";}let dateArr = lastChatMsg.time.split(' ')[0].split('-') let timeArr = lastChatMsg.time.split(' ')[1].split(':') let month = dateArr[2] < 10 ? '0' + dateArr[2] : dateArr[2] lastChatMsg.time = `${dateArr[1]}月${dateArr[2]}日 ${timeArr[0]}时${timeArr[1]}分`lastChatMsg.dateTimeNum = `${dateArr[1]}${month}${timeArr[0]}${timeArr[1]}${timeArr[2]}`lastChatMsg.groupName = listGroups[i].groupname array.push(lastChatMsg);}}array.sort((a, b) = >{return b.dateTimeNum - a.dateTimeNum;});console.log('array:', array)//2021/02/01新加uni.setStorageSync("newChatMsg", array);return array;},

array得到的数据格式:

[{"info": {"from": "nzXXXXXXfk", //对方的账号"to": "lXXXXXX5" //你的账号},"username": "nzXXXXXXfk","yourname": "nzXXXXXXfk","msg": {"type": "txt","url": "","data": [{"data": "快来加入会议 - LBJ13H055XXXXXXXXXXXXXC65666","type": "txt"}],"ext": {"conferenceId": "LBJ13H05522QATI4O4DEXH00C65666", //会议id,后端每发一个视频流对应一个id"msg_extension": "{\"inviter\":\"nzXXXXXXfk\"}", //处理过的对方的账号"password": ""//会议密码}},"style": "","time": "2月1日 15时41分","mid": "txt835802715723401212","chatType": "chat","unReadCount": 10,"dateTimeNum": "201154124"
}]

上面的array将会传到comps/chat/chat.vue–comps/chat/msglist/msglist.vue组件里处理,这个组件放的就是群聊窗口,而msglist就是处理消息列表的。
chatMsg获取之前的array值,遍历出msgList消息列表值

let timer = setTimeout(function() {me.username = uni.username;let username = me.username;let myUsername = uni.getStorageSync("myUsername");let sessionKey = username.groupId ? username.groupId + myUsername: username.your + myUsername;// let chatMsg = uni.getStorageSync(sessionKey) || [];// 2021/02/01 新增  !!!!!let chatMsg = uni.getStorageSync("newChatMsg");  //更改了这里!!!console.log('chatMsg:', chatMsg) me.renderMsg(null, null, chatMsg, sessionKey);uni.setStorageSync(sessionKey, null);disp.on('em.error.sendMsgErr',function(err) {curMsgMid = err.data.mid;isFail = true;console.log('发送失败了');return;let msgList = me.chatMsg;msgList.map(item = >{if (item.mid.substring(item.mid.length - 10) == curMsgMid.substring(curMsgMid.length - 10)) {item.msg.data[0].isFail = true;item.isFail = true;me.setData({chatMsg: msgList});}});console.log('msgList:', msgList)if (me.curChatMsg[0].mid == curMsgMid) {me.curChatMsg[0].msg.data[0].isShow = false;me.curChatMsg[0].isShow = false;}uni.setStorageSync("rendered_" + sessionKey, msgList);});msgStorage.on("newChatMsg", this.dispMsg);
},
1000);

(4)comps/chat/chat.vue页面里点击消息列表,引用父级页面groupChatRoom的onClickInviteMsg方法,并跳转到视频通话页面:emedia页面

comps/chat/chat.vue页面

clickMsg(msg) {this.$emit('onClickInviteMsg', msg) console.log('点击消息上一级', msg)
},

groupChatRoom页面

<chat id="groupchat" ref="chat" :username="username" :groupId="groupId" chatType="chatRoom" @onMakeVideoCall="makeVideoCall" @onClickInviteMsg="onClickMsg">
</chat>
export default {methods: {onClickMsg(msg){msg.action = 'join'uni.navigateTo({url: "../emedia/index?srcData="+JSON.stringify(msg)});}}
}

(5)emedia页面
插件市场里所展示的代码就写在这个页面里边,此时效果已经出来了。

< emlive - player id = "livePlayer"ref = "livePlayer"objectFit = "fit"@bindstatechange = "playerStateChange"@bindnetstatus = "playerNetChange": data - streamId = "item.id": muted = "false": enableCamera = "true": openSpeaker = "openSpeaker"@callbackData = "onPlayerData"style = "width:170px;height:170px; margin: 5px" > </emlive-player>

三、附上groupChatRoom页面完整代码:

<template>
<chat id="groupchat" ref="chat" :username="username" :groupId="groupId" chatType="chatRoom" @onMakeVideoCall="makeVideoCall" @onClickInviteMsg="onClickMsg">
</chat>
</template><script>
let disp = require("../../utils/broadcast");
import chat from "../../comps/chat/chat.vue";
var WebIM = require("../../utils/WebIM")["default"];
export default {data() {return {username: {your: ""},search_btn: true,search_chats: false,show_mask: false,yourname: "",unReadSpotNum: 0,unReadNoticeNum: 0,messageNum: 0,unReadTotalNotNum: 0,arr: [],show_clear: false,member: "",isIPX: false,gotop: false,input_code: ""};},components: {chat},props: {groupId:{type:String,default:''}},// options = 系统传入的 url 参数onLoad(options) {let me = this; let username = JSON.parse(options.username);this.setData({username: username});uni.username = username;uni.setNavigationBarTitle({title: username.your});this.getRoster();},onShow: function () {this.setData({arr: this.getChatList()});if (getApp().globalData.isIPX) {this.setData({isIPX: true});}},onUnload() {disp.fire("em.chatroom.leave");},methods: {getRoster() {let me = this;let rosters = {success(roster) {var member = [];for (let i = 0; i < roster.length; i++) {if (roster[i].subscription == "both") {member.push(roster[i]);}}uni.setStorage({key: "member",data: member});me.setData({member: member});me.listGroups(); //if(!systemReady){disp.fire("em.main.ready"); //systemReady = true;//}// me.getChatList()me.setData({arr: me.getChatList(),unReadSpotNum: getApp().globalData.unReadMessageNum > 99 ? '99+' : getApp().globalData.unReadMessageNum});},error(err) {console.log(err);}};WebIM.conn.getRoster(rosters);},listGroups() {var me = this;return WebIM.conn.getGroup({limit: 50,success: function (res) {uni.setStorage({key: "listGroup",data: res.data});me.getChatList();},error: function (err) {console.log(err);}});},makeVideoCall(data){console.log('data:', data)if(false){uni.showToast({title: '请输入会议Id',duration: 2000});return}uni.navigateTo({url: "../emedia/index?srcData="+JSON.stringify(data)});},// 不包含陌生人版本getChatList() {var array = [];var member = uni.getStorageSync("member");var myName = uni.getStorageSync("myUsername");var listGroups = uni.getStorageSync('listGroup') || [];for (let i = 0; i < member.length; i++) {let newChatMsgs = uni.getStorageSync(member[i].name + myName) || [];let historyChatMsgs = uni.getStorageSync("rendered_" + member[i].name + myName) || [];let curChatMsgs = historyChatMsgs.concat(newChatMsgs);if (curChatMsgs.length) {let lastChatMsg = curChatMsgs[curChatMsgs.length - 1];lastChatMsg.unReadCount = newChatMsgs.length;if (lastChatMsg.unReadCount > 99) {lastChatMsg.unReadCount = "99+";}let dateArr = lastChatMsg.time.split(' ')[0].split('-');let timeArr = lastChatMsg.time.split(' ')[1].split(':');let month = dateArr[2] < 10 ? '0' + dateArr[2] : dateArr[2];lastChatMsg.dateTimeNum = `${dateArr[1]}${month}${timeArr[0]}${timeArr[1]}${timeArr[2]}`;lastChatMsg.time = `${dateArr[1]}月${dateArr[2]}日 ${timeArr[0]}时${timeArr[1]}分`;array.push(lastChatMsg);console.log('array1:', array)}}for(let i = 0; i < listGroups.length; i++){let newChatMsgs = uni.getStorageSync(listGroups[i].groupid + myName) || [];let historyChatMsgs = uni.getStorageSync("rendered_" + listGroups[i].groupid + myName) || [];let curChatMsgs = historyChatMsgs.concat(newChatMsgs);if(curChatMsgs.length){let lastChatMsg = curChatMsgs[curChatMsgs.length - 1];lastChatMsg.unReadCount = newChatMsgs.length;if(lastChatMsg.unReadCount > 99) {lastChatMsg.unReadCount = "99+";}let dateArr = lastChatMsg.time.split(' ')[0].split('-')let timeArr = lastChatMsg.time.split(' ')[1].split(':')let month = dateArr[2] < 10 ? '0' + dateArr[2] : dateArr[2]lastChatMsg.time = `${dateArr[1]}月${dateArr[2]}日 ${timeArr[0]}时${timeArr[1]}分`lastChatMsg.dateTimeNum = `${dateArr[1]}${month}${timeArr[0]}${timeArr[1]}${timeArr[2]}`lastChatMsg.groupName = listGroups[i].groupnamearray.push(lastChatMsg);console.log('array2:', array)}} array.sort((a, b) => {return b.dateTimeNum - a.dateTimeNum;});console.log('array3:', array)//2021/02/01新加uni.setStorageSync("newChatMsg" , array);return array;},onClickMsg(msg){msg.action = 'join'uni.navigateTo({url: "../emedia/index?srcData="+JSON.stringify(msg)});}}
};
</script>
<style>
@import "./groupChatRoom.css";
</style>

四、总结与遇到的问题

  1. 重点!:遇到视频出不来或黑屏,很有可能是因为emedia/index.nvue文件里的getName方法没改成自己的appkey 的appname。
    如你的appkey为:1101246581426371#chatdemoui,以下红框改成相应内容

    (这里真的很坑,是问了环信客服才知道)
  2. 注意:groupChatRoom模块、emedia模块等建议不要放在自己新建的子目录里,而直接放在pages目录下,要不然会出现路径错误而无法正常运行。
  3. 要用自定义基座运行,公共测试证书就行,要不然视频会黑屏。
  4. 整理demo时因为很多参数被封装了,单独引入很容易出错,建议直接复制,然后再把不需要的代码删掉。

uniapp使用环信插件实现视频通话相关推荐

  1. uni-app 接入环信sdk

    官方文档: 一个接入的采坑之路终于完结了,送给需要的人们 项目不需要做太多的其他处理,只做发送消息,有提示音.振动即可,多余不处理咯.给大家做个接入参考. 环信sdk :3.x.x版本 接入方式:直接 ...

  2. uni-app接入环信客服云 easemobim

    需求:点击商品详情里的客服按钮,跳转(注意:不是拉起)页面,页面为客服窗口 尝试: uni-app webview直接集成网页链接(https://106280.kefu.easemob.com/we ...

  3. android 环信录音,环信音视频插件

    更新记录 1.0.1(2020-12-13) 解决插件和微信小程序不通的问题 Android端增加日志文件输出 1.0.0(2020-11-26) 1.0.0 发布原生的推流 拉流组件 ,配合环信We ...

  4. 【2021环信IM快速集成指南】PC Web、Uni-App、小程序集成都在这里了

    本文将直白且详细的描述一下如何集成环信web端的IM SDK,(小程序.Uni-app通用).这是一篇快速集成攻略,其中更多的是对于官网文档的一篇注释说明,相信很多的小伙伴在准备将环信的IM即时通讯能 ...

  5. 使用环信提供的uni-app Demo,快速实现一对一单聊

    如何利用环信提供的uni-app Demo,快速实现一对一单聊?真真保姆级别教程! 写在前面: 1)因为初期直接下载环信的uni-app的demo源码直接看可能一头雾水,因此写下这篇文档帮助项目周期较 ...

  6. 根据环信3.0集成的视频通话

    本项目中我用到的第三方框架:evenbus,和ButterKnife ButterKnife: @BindView(R.id.tv_call_state)TextView callStateTextV ...

  7. 基于环信sdk在uni-app框架中快速开发一款多平台社交Demo

    说在前面:此款 demo 是基于 环信sdk 开发的一款具有单聊.群聊.聊天室.音视频等功能的应用.在此之前我们已经开发完 Vue.react(web端).微信小程序.这三个热门领域的版本,如有需要源 ...

  8. uniapp H5接入使用环信聊天

    准备工作 官网下载WebIM.js以及WebIMConfig.js两个文件 然后main.js中引入并配置(appKey就是申请使用的环信APPKEY本文是在WebIMConfig.js配置) 在Ap ...

  9. Android环信爬坑指北(二)头像昵称好友备注显示

      在上一篇文章中提到了要在初始化的时候,设置用户信息提供者类--EaseUserProfileProvider,用以获取用户信息.下面我们来看一下 EaseUserProfileProvider 是 ...

最新文章

  1. US News 2021年世界大学排行榜发布,清华大学首登亚洲第一
  2. sap服务器应用webservice加载spring的机制问题
  3. 41 Ansible安装
  4. 静态反调试技术(1)
  5. C#:对txt文件的读写
  6. idea 查看jsp是否被引用_IDEA集成Java性能分析神器JProfiler
  7. Silverlight4.0教程之与摄像头与迈克风设备交互
  8. Http client to POST using multipart/form-data
  9. wps页眉怎么设置不同页码_wps版word怎么从第二页设置页眉页脚
  10. python所需各种库(.whl)文件网址,不用下载其它运行库,直接pip install .....whl
  11. linux内核热插拔,Linux热插拔机制的介绍和应用
  12. hdu 4899 Hero meet devil
  13. 超 82% 的 GitHub 代码是重复的,还不是 Forked 而来。
  14. URP关于多个摄相机的性能优化
  15. 沙尔克04和ajax,昔日德甲劲旅沦为保级球队,沙尔克04和云达不来梅到底怎么了?...
  16. ZBlog采集插件无需授权远离ZBlog破解版
  17. 大连理工计算机应用基础作业,2014秋大连理工大学《计算机应用基础》在线测试1...
  18. utf8mb4_unicode_ci、utf8mb4_general_ci的区别总结
  19. WPF基础之XAML----(XAML 根元素和 xmlns,事件和 XAML 代码隐藏)
  20. Authorization

热门文章

  1. [易水寒]大一实训笔记 第二篇
  2. 【NOIP2016普及组】复赛——海港
  3. AWS S3 挂载到EC2
  4. 需要证件照怎么办?教你如何自己在线做照片
  5. web项目引入PDF.js并添加水印禁止下载
  6. 达人评测 i5 12500h和r7 6800h 选哪个好
  7. 【C语言】输入一个年份和月份,输出该月的天数
  8. ubuntu修改默认python为python3
  9. UVALive 5739|User Names|模拟
  10. iOS6和iOS7环境下微信登录未显示问题微信IOS的SDK:isWXAppInstalled总是返回NO和nil...