共计 2019 个字符,预计需要花费 6 分钟才能阅读完成。
应公司项目需求。需要在原先完整项目的基础上将音视频通话部分与项目进行分离,形成单独的组件。实现在项目中传入 url,后弹出 model 框进行两端音视频通话。
通话功能
通话功能的流程是通过页面上的某个按钮执行 init() 方法。因为用了腾讯云的音视频技术。所以需要在腾讯云服务器创建房间,还有公司本地服务器创建房间做通话两端的中间人角色。
import rtc from ‘path’;
rtc.init(
obj, // 创建房间基本信息字段
‘p1’, // 获取腾讯云信息
‘p2’, // 本地服务器创建房间
‘p3’, // 心跳接口
‘p4’, // 退出本地服务器房间
heart, // 心跳回调 根据返回值查看视频过程
eventcb, // 腾讯云服务器 发生事件回调 可不传
1, // 是否需要混流 可不传
‘p5’, // 混流接口 可不传
);
在页面中引入 rtc 组件并执行 init() 方法,传入路径,监听通话过程的回调等。
在 rtc 组件中:
const rtc = {
… // 保存信息变量
init(obj, u1, u2, u3, u4, heart, eventcb, isMixed = 0, u5 = ”) {
… // 全局保存传入字段
axios.post(u1, Qs.stringify(params)).then((res) => {
const opt = {
… // 房间信息
};
const RTC = that.create(opt);
Object.keys(that.events).forEach((key) => {
if (!eventcb) {
that.eventcb = function (rs) {
return rs.tip;
};
} else {
that.eventcb = eventcb;
}
RTC.on(key, that.events[key]);
});
});
}
}
init() 方法中通过传入的路径,首先调用后台初始化接口,获取创建房间必要的参数信息。同时将信息存入全局变量中。执行 create()。开始在服务器及腾讯云服务器创建房间。在 create 中 return RTC; 说明房间创建成功。events 定义了腾讯云事件通知,遍历 key,value, RTC.on 进行监听. eventcb 为传入的事件回调。
create(opt) {
const self = this;
const RTC = new WebRTCAPI(opt, function () {
const params = {
… // 创建本地服务器房间
};
axios.post(self.u2, Qs.stringify(params)).then((res) => {
const createOpt = {
… // 创建腾讯服务器房间
};
RTC.createRoom(createOpt, function() {
console.log(‘ 创建房间 ’);
self.heartbeat();
})
});
});
return RTC;
},
heartbeat() 递归调用心跳函数,对通话过程进行监听,比如一端退出房间通过与后台商定的 code 值,即使在本地服务器退出房间等。
events: {
onRemoteStreamUpdate(data) {
… // 远端流 新增 / 更新
if (!rtc.connect) {
rtc.connect = 1; // 开始通话
rtc.instance.$emit(‘connection’, rtc.connect);
}
rtc.eventcb(….); 回调返回信息
},
onRemoteStreamRemove(data) {
… // 远端流断开
rtc.eventcb(….);
},
onRelayTimeout(data) {
… // server 超时断开
rtc.eventcb(….);
}
},
eventcb 如果传入能确保在执行 init() 方法的页面得到通话过程中的事件执行信息。
组件通信
init() 与 rtc.js 可以通过回调传参的方式进行通信,但 rtc.js 与 通话面板之间无法通过这种方式进行信息传递。比如需要在 rtc.js 通知 model 通话开始, 这时需要开始计时等。vuex, bus 无法在这种情况下使用. 所以通过 Vue.extend(),在 Vue 构造器上创建子类。注册到全局。使用 vm.$emit 及 vm.$om 发布订阅事件
import rtcContainer from ‘./view.rtc’;
init(…) {
…
const callPanel = Vue.extend(rtcContainer);
this.instance = new callPanel({
propsData: {
// 传值
}
}).$mount();
document.body.appendChild(this.instance.$el);
}
如果 $mount() 不传值,没有挂载节点,也会生成 callpanel 实例。这是一个坑,而后将其挂载到 body 上。在需要的地方 $emit 发布事件.
结语
做完这些初步完成以项目为基础的组件抽离,代码太次,正在优化。