﻿# anyrtc-push

小程序自定义组件

> 使用此组件需要依赖小程序基础库 2.2.1 以上版本，同时依赖开发者工具的 npm 构建。具体详情可查阅[官方 npm 文档](https://developers.weixin.qq.com/miniprogram/dev/devtools/npm.html)。

# 使用说明

> 1.结合[anyrtc小程序会议SDK](https://www.npmjs.com/package/miniprogram-anyrtc-meet)使用  
> 2.结合[anyrtc小程序推流组件](https://www.npmjs.com/package/miniprogram-anyrtc-push)和[anyrtc小程序拉流组件](https://www.npmjs.com/package/miniprogram-anyrtc-play)使用

# 使用方法

1. 安装 anyrtc-push  

```
npm install --save miniprogram-anyrtc-push
```

2. 在需要使用 slide-view 的页面 page.json 中添加 anyrtc-push 自定义组件配置

```
{
  "usingComponents": {
    "anyrtc-push": "miniprogram-anyrtc-push"
  }
}
```

WXML 文件中引用 anyrtc-push

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

```
### anyrtc-push的属性介绍如下：

|属性名|类型|默认值|是否必须|说明|
|--|--|--|--|--|--|
|pushURL|String|-|是|anyrtc-push组件推流URL|
|id|String|-|是|用户获取组件的```LivePusherContext```来切换摄像头等[操作](https://developers.weixin.qq.com/miniprogram/dev/api/media/live/LivePusherContext.html)。|
|width|Number|显示屏幕的宽度|是|anyrtc-push组件的宽度|
|height|Number|0|是|anyrtc-push组件的高度|
|coverImg|String|-|否|anyrtc-push组件进入后台时推流的等待画面|
|enableAudio|Boolean|true|否|anyrtc-push组件是否静音|
|enableVideo|Boolean|true|否|anyrtc-push组件是否开启摄像头|
|bindRoomEvent|Functiong|-|是|anyrtc-push组件接收在线人员信息、推流等信息|


### anyrtc-push的方法介绍如下

**注意：    
当需要停止推流、回复推流、切换摄像头等操作时，需要获取到推流组件对象后，才可对其进行操作。    
打开/关闭摄像头、打开/关闭麦克风则改变推流组件对外属性```enableVideo```和```enableAudio```即可。  
具体看Demo**


1. 停止推流
```
//that为当前页面对象
that.selectComponent('#anyrtcpush').pause()

```
2. 恢复推流
```
//that为当前页面对象
that.selectComponent('#anyrtcpush').resume()
```
3. 切换前后置摄像头
```
//that为当前页面对象
that.selectComponent('#anyrtcpush').switchCamera()
```

4. 打开/关闭麦克风
```
//that为当前页面对象
that.setData({
  enableAudio: !this.data.enableAudio
});
```

5. 打开/关闭摄像头
```
//that为当前页面对象
that.setData({
  enableVideo: !this.data.enableVideo
});
```

# 完整代码

WXML

```
<!--pages/room/room.wxml-->

<!-- anyrtc发布，view包裹可自定义样式 -->
<view>
  <anyrtc-push 
  id="anyrtcpush"
  width="{{pushWidth}}"
  height="200"
  coverImg="123"
  enableAudio="{{enableAudio}}"
  enableVideo="{{enableVideo}}"
  pushURL="{{pushURL}}" 
  bindRoomEvent="handleRoomEvent"></anyrtc-push>
</view>

<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 type="button" bindtap="leaveRoom">退出房间</button>

```

JS

```
const _windowWidth = wx.getSystemInfoSync().windowWidth
const config = require('../../config.js');
let wxRTMeet = require('miniprogram-anyrtc-meet');

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

  /**
   * 页面的初始数据
   */
  data: {
    anyrtcPusherComponent: null,
    wxmeet: null,
    pushURL: '',
    pushWidth: _windowWidth,
    enableVideo: true,
    enableAudio: false,
    members: []
  },

  //停止推流
  pausePush () {
    this.data.anyrtcPusherComponent.pause();
  },
  //恢复推流
  resumePush () {
    this.data.anyrtcPusherComponent.resume();
  },
  //切换摄像头
  switchCamera () {
    this.data.anyrtcPusherComponent.switchCamera();
  },
  //打开/关闭摄像头
  enableCamera () {
    this.setData({
      enableVideo: !this.data.enableVideo
    });
  },
  //打开/关闭麦克风
  enableMicphone () {
    this.setData({
      enableAudio: !this.data.enableAudio
    });
  },
  //退出房间
  leaveRoom() {
    this.data.wxmeet.leaveRoom();
    wx.navigateBack();
  },

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

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

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

    that.onScreen();

    that.setData({
      wxmeet: wxmeet,
      anyrtcPusherComponent: that.selectComponent('#anyrtcpush')
    });

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

    let userid = '' + parseInt(Math.random() * 10000);
    let username = '' + parseInt(Math.random() * 1000000);

    wxmeet.joinRoom(roomId, userid, username,JSON.stringify({ userid }));

    wxmeet.on("onJoinRoomOK", () => {
      wx.showToast({
        title: '加入房间成功',
      });
    });
    
    wxmeet.on("onGetPushUrl", (code, data) => {
      console.log('onGetPushUrl', code, data);
      if (code === 0) {//成功
        that.setData({
          pushURL: data.pushURL
        });
      } else {
        wx.showToast({
          icon: 'none',
          title: '获取房间签名失败',
        });
      }
    });
  },

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

    console.log('handleRoomEvent', data);
    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}`);
  },

  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);
  },

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

  },

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

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
    //小程序后台，手机切到主页面
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
    //返回入口，关闭小程序
    this.data.wxmeet.leaveRoom();
    this.offScreen();
  },
})
```

> ## 技术支持 
> 加QQ技术咨询群：580477436 (一群) 554714720 (二群)     
> 欢迎加入[anyRTC社区](https://bbs.anyrtc.io) 和我们一起探讨WebRTC技术以及解决集成问题。