webRtc及组件之间通信

zhuiyuanqingya 2019-06-29

应公司项目需求。 需要在原先完整项目的基础上将音视频通话部分与项目进行分离, 形成单独的组件。 实现在项目中传入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发布事件.

结语

做完这些初步完成以项目为基础的组件抽离,代码太次,正在优化。

相关推荐