webRtc及組件之間通信

應公司項目需求。 需要在原先完整項目的基礎上將音視頻通話部分與項目進行分離, 形成單獨的組件。 實現在項目中傳入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發佈事件.

結語

做完這些初步完成以項目爲基礎的組件抽離,代碼太次,正在優化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章