miniprogram-anyrtc-rtmpc

anyRTC实时连麦小程序SDK

Usage no npm install needed!

<script type="module">
  import miniprogramAnyrtcRtmpc from 'https://cdn.skypack.dev/miniprogram-anyrtc-rtmpc';
</script>

README

# anyRTC实时连麦小程序SDK

使用此组件需要依赖小程序基础库 2.2.1 以上版本,同时依赖开发者工具的 npm 构建。具体详情可查阅官方 npm 文档

准备工作

  1. 注册微信小程序,登录小程序后台获取微信小程序appid,appSecrert,修改类目审核(社交、教育、医疗、政务民生、金融,目前只有这些支持),配置socket合法域名wss://teameeting.anyrtc.io:9095
  2. 前往anyRTC平台注册账号和创建应用并开通小程序服务
  3. 开发-配置中开启“使用npm模块”,基础库选择2.4.0及以上,打开“不校验合法域名”、真机调试打开“调试”。集成moniprogram-anyrtc-meet、moniprogram-anyrtc-push、moniprogram-anyrtc-play

使用说明

1.结合anyrtc小程序实时连麦SDK使用
2.结合anyrtc小程序推流组件anyrtc小程序拉流组件使用

使用方法

  1. 安装 anyrtc-rtmpc
npm install --save miniprogram-anyrtc-rtmpc
  1. 会议初始化
//创建实例
let wxrtmpc = new wxRTMPC();
that.setData({
  wxrtmpc: wxrtmpc
});
//初始化
wxrtmpc.initEngineWithAnyRTCInfo(config.DEV_ID, config.APP_ID, config.APP_KEY, config.APP_TOKEN, config.APP_DOMAIN);

  1. 加入房间
//加入房间
wxrtmpc.joinRoom(roomId, userid, username,JSON.stringify({ userid }));
//加入房间成功回调
wxrtmpc.on("onJoinRoomOK", () => {
  wx.showToast({
    title: '加入房间成功',
  });
});
  1. 收到推流地址
//收到推流URL回调,将URL绑定到anyrtc-push组件中,其他人将收到自己的视频
wxrtmpc.on("onGetPushUrl", (code, data) => {
  console.log('onGetPushUrl', code, data);
  if (code === 0) {//成功
    that.setData({
      pushURL: data.pushURL
    });
  } else {
    wx.showToast({
      icon: 'none',
      title: '获取房间签名失败',
    });
  }
});

  1. 退出房间
wxrtmpc.leaveRoom();
//自行路由跳转

完整代码

WXML

<!--pages/room/room.wxml-->
<live-player wx:if="{{watchUrl && !onLine}}" style="width:100%;height:210px" id="rtcwatcher" src="{{watchUrl}}" autoplay binderror="onPlayError" bindstatechange="onPlay"></live-player>
<button wx:if="{{!onLine}}" type="button" bindtap="apply">连麦</button>

<anyrtc-push 
  id="anyrtcpush"
  width="{{pushWidth}}"
  height="200"
  coverImg="123"
  enableAudio="{{enableAudio}}"
  enableVideo="{{enableVideo}}"
  pushURL="{{pushURL}}" 
  bindRoomEvent="handleRoomEvent">
</anyrtc-push>

<button class="meet_btn" bindtap="pausePush">暂停推流</button>
<button class="meet_btn" bindtap="resumePush">恢复推流</button>
<button class="meet_btn" bindtap="switchCamera">切换前后摄像头</button>
<button class="" bindtap="enableCamera">开关摄像头 :: 当前状态{{enableVideo ? '开' : '关'}}</button>
<button class="" bindtap="enableMicphone">开关麦克风 :: 当前状态{{enableAudio ? '开' : '关'}}</button>

<!-- anyrtc订阅,view包裹可自定义样式-->
<view wx:for="{{members}}" wx:key="index">
  <anyrtc-play 
    id="{{item.pubID}}-play"
    pubID="{{item.pubID}}" 
    width="{{item.width}}" 
    height="{{item.height}}" 
    playURL="{{item.playURL}}" 
    bindPlayStatus="handlePlayStatus">
  </anyrtc-play>
  <button class="meet_btn" data-id="{{item.pubID}}" bindtap="pause">暂停</button>
  <button class="meet_btn" data-id="{{item.pubID}}" bindtap="play">播放</button>
  <button class="meet_btn" data-id="{{item.pubID}}" bindtap="full">全屏</button>
</view>

<button wx:if="{{onLine}}" type="button" bindtap="hangup">挂断</button>

JS

var wxRTMPC = require('../../lib/RTMPCXcxKit.js').default;
const config = require('../../config.js');
const _windowWidth = wx.getSystemInfoSync().windowWidth;

// pages/room/room.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    onLine: false,
    watchUrl: '',//游客默认观看主播流
    userID: '',
    anyrtcPusherComponent: null,
    wxrtmpc: null,

    pushURL: '',
    pushWidth: _windowWidth,
    enableAudio: false,
    enableVideo: true,
    
    members: [],
  },

  onScreen () {
    wx.setKeepScreenOn({
      keepScreenOn: true
    })
  },

  offScreen () {
    wx.setKeepScreenOn({
      keepScreenOn: false
    })
  },

  //停止推流
  pausePush() {
    anyrtcPusherComponent: this.selectComponent('#anyrtcpush') && this.data.anyrtcPusherComponent.pause();
  },

  //恢复推流
  resumePush() {
    anyrtcPusherComponent: this.selectComponent('#anyrtcpush') && this.data.anyrtcPusherComponent.resume();
  },

  //切换摄像头
  switchCamera() {
    anyrtcPusherComponent: this.selectComponent('#anyrtcpush') && this.data.anyrtcPusherComponent.switchCamera();
  },

  //打开/关闭摄像头
  enableCamera() {
    this.setData({
      enableVideo: !this.data.enableVideo
    });
  },

  //打开/关闭麦克风
  enableMicphone() {
    this.setData({
      enableAudio: !this.data.enableAudio
    });
  },
  
  //暂停远程人员音视频流
  pause(e) {
    let that = this;
    let data = e.currentTarget.dataset;

    //参考 https://developers.weixin.qq.com/miniprogram/dev/api/media/live/LivePlayerContext.pause.html
    that.selectComponent(`#${data.id}-play`).pause({
      complete: res => {
        console.log('selectComponent pause', res);
      }
    });
  },

  //播放远程人员音视频流
  play(e) {
    let that = this;
    let data = e.currentTarget.dataset;

    //参考 https://developers.weixin.qq.com/miniprogram/dev/api/media/live/LivePlayerContext.play.html
    that.selectComponent(`#${data.id}-play`).play({
      complete: res => {
        console.log('selectComponent pause', res);
      }
    });
  },

  //使远程人员音视频流全屏
  full(e) {
    let that = this;
    let data = e.currentTarget.dataset;

    //参考 https://developers.weixin.qq.com/miniprogram/dev/api/media/live/LivePlayerContext.requestFullScreen.html
    that.selectComponent(`#${data.id}-play`).requestFullScreen({
      direction: 90,
      complete: res => {
        console.log('selectComponent pause', res);
      }
    });
    //此处由于只做演示,所以2秒之后结束全屏
    setTimeout(() => {
      that.selectComponent(`#${data.id}-play`).exitFullScreen({
        complete: res => {
          console.log('selectComponent pause', res);
        }
      });
    }, 2000);
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    let that = this;
    let roomId = '' + options.roomid;
    let wxrtmpc = new wxRTMPC();

    that.onScreen();

    that.setData({
      watchUrl: options.rtmpUrl,
      wxrtmpc: wxrtmpc,
      anyrtcPusherComponent: that.selectComponent('#anyrtcpush')
    });

    wxrtmpc.initEngineWithAnyRTCInfo(config.DEV_ID, config.APP_ID, config.APP_KEY, config.APP_TOKEN, config.APP_DOMAIN);

    let userid = '' + parseInt(Math.random() * 10000);
    wxrtmpc.joinRTCLine(roomId, userid, JSON.stringify({ userid }));
    
    //连接RTC结果回调
    wxrtmpc.on("onRTCJoinLineResult", (code, data) => {
      console.log('onRTCJoinLineResult', code, data);
    });
    //申请连线结果
    wxrtmpc.on("onRTCApplyLineResult", (code, id) => {
      console.log('onRTCApplyLineResult', code, id);
      if (code === 0) {
        that.setData({
          onLine: true
        });
      }
    });
    //连线被挂断
    wxrtmpc.on("onRTCHangupLine", () => {
      console.log('onRTCHangupLine');
      that.setData({
        onLine: false
      });
    });
    wxrtmpc.on("onGetPushUrl", (code, data) => {
      if (code === 0) {//成功
        that.setData({
          pushURL: data.pushURL
        });
      } else {
        wx.showToast({
          icon: 'none',
          title: '获取房间签名失败',
        });
      }
    });
    //直播人员列表
    wxrtmpc.on("onRTCMemberListNotify", (nTotal, RoomID, RoomSvrID) => {
      console.log('onRTCMemberListNotify', nTotal, RoomID, RoomSvrID);
    });
    //直播开始
    wxrtmpc.on("onRTCLiveStart", () => {
      console.log('onRTCLiveStart');
    });
    //直播暂时停止
    wxrtmpc.on("onRTCLiveStop", () => {
      console.log('onRTCLiveStop');
      that.backIndex();
    });
    //直播结束
    wxrtmpc.on("onRTCLineLeave", () => {
      console.log('onRTCLineLeave');
    });
  },

  backIndex () {
    wx.navigateBack();
  },
  
  //申请连线
  apply() {
    this.data.wxrtmpc.applyRTCLine(JSON.stringify({ nickName: 'hello' }));
  },

  //挂断连线
  hangup () {
    this.data.wxrtmpc.hangupRTCLine();
    this.backIndex();
  },

  //监听房间事件
  handleRoomEvent (e) {
    let that = this;
    let data = e.detail;

    console.log('handleRoomEvent', data);
    let members = that.data.members;
    
    switch (data.tag) {
      case "MemberJoin":
        let newMember = data.detail;

        newMember.map(item => {
          let nitem = Object.assign({}, item, {
            width: 100,
            height: 100
          });
          members.push(nitem);
        });

        that.setData({
          members: members
        });
        break;
      case "MemberLeave":
        let leaveUsers = data.detail;

        members.map((item, index) => {
          leaveUsers.map((i, n) => {
            if (i.pubID === item.pubID) {
              members.splice(index, 1);
            }
          });
        });

        that.setData({
          members: members
        });
        break;
      case "PushError":
        //重新进会
        break;
    }
  },

  //监听播放状态
  handlePlayStatus (e) {
    let that = this;
    let data = e.detail;

    //错误码参考 https://developers.weixin.qq.com/miniprogram/dev/component/live-player.html
    console.log('handlePlayStatus', `pubID为 ${data.pubID} 的播放状态为 ${data.code}`);
  },

  //未连线时播放主播rtmp流状态
  onPlay (e) {
    console.log('onPlay', e);
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
    
  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
    console.log('onHide');
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
    console.log('onUnload');
    this.onScreen();
    //断开RTC连接并释放资源
    this.data.wxrtmpc.clear();
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})

技术支持

加QQ技术咨询群:580477436 (一群) 554714720 (二群)
欢迎加入anyRTC社区 和我们一起探讨WebRTC技术以及解决集成问题。