微信小程序TRTC使用custom自定义面板(实现篇)

2021-03-17 17:30:43 浏览数 (2)

本文主要是使用 custom 面板实现直播互动,上下麦操作。如有疑问可参考 微信小程序TRTC使用custom自定义面板(理解篇)。本文只是简单演示如何实现主播与观众进行连麦互动,在实际中,通常是有主播端发起与粉丝进行直播互动,通过粉丝来接受,进行连麦。发送这种消息可以使用IM(即时通讯)完成。

由于小程序在直播模式中没有特别指定主播和观众身份,所以在编写代码时需要自己进行区分,主播身份就进行视频流和音频流的推送;观众端则不进行推流,当需要连麦时,将观众的音频流推上去。

以下是实现代码:(代码中用到少量 iViewUI )

首先用一个页面进行数据的收集:

live.wxml中的简单代码

代码语言:html复制
<!--pages/live/live.wxml-->
<view>
  <van-field id="userID" label="userID" placeholder="请输入用户名" value="{{userID}}" bind:change="inputtext"></van-field>
  <van-field id="roomID" label="roomID" placeholder="请输入房间号" value="{{roomID}}" bind:change="inputtext"></van-field>
  <van-radio-group direction="horizontal" value="{{ radio }}" bind:change="onChange">
    <van-radio name="1">主播</van-radio>
    <van-radio name="2">观众</van-radio>
  </van-radio-group>
  <van-button type="primary" size='large' bind:click="toroom">确定</van-button>
</view>

live.js的代码

代码语言:javascript复制
// pages/live/live.js
Page({
  data: {
    roomID: null,
    userID: null,
    role: 'Anchor', // Audience观众
    radio: 1
  },
  // 点选框的选择
  onChange(e) {
    if (e.detail == 1) {
      this.setData({
        radio: e.detail,
        role: 'Anchor',
      })
    } else if (e.detail == 2) {
      this.setData({
        radio: e.detail,
        role: 'Audience',
      })
    }
  },
  // 输入框输入
  inputtext(e) {
    this.setData({
      [e.currentTarget.id]: e.detail
    })
  },
  // 进入liveroom页面,里面有<trtc-room>标签
  toroom() {
    wx.navigateTo({
      url: './liveroom?roomID=' this.data.roomID '&userID=' this.data.userID '&role=' this.data.role,
    })
  }
})

然后就是引入<trtc-room>标签的页面

liveroom.wxml的代码

代码语言:html复制
<!--pages/live/liveroom.wxml-->
<view class="win">
  <trtc-room id="trtcroom" config="{{trtcConfig}}"></trtc-room>
  <!-- 以下是观众的按键 -->
  <view wx:if="{{role=='Anchor'?false:true}}" class="content" bindtap="lianmai"
    style="color:{{lianmai?'#2db7f5':'#c5c8ce'}}">连麦</view>
  <view wx:if="{{role=='Anchor'?false:true}}" class="exit" bindtap="leave">退房</view>
</view>

liveroom.wxss的代码

代码语言:css复制
/* pages/live/liveroom.wxss */
.win {
  position: relative;
  height: 100vh;
  width: 100vw;
}

.content,
.exit {
  z-index: 100;
  position: absolute;
  width: 100px;
  height: 100px;
  border-radius: 50px;
  line-height: 100px;
  text-align: center;
}

.content {
  bottom: 0;
  right: 0;
  color: #c5c8ce;
  background: white;
}

.exit {
  bottom: 0;
  left: 0;
  color: #f8f8f9;
  background: red;
}

liveroom.js的代码,需要注意sdkAppID请填入自己的,关于UserSig可以参考 UserSig相关问题

代码语言:javascript复制
// pages/live/liveroom.js
// 计算UserSig的函数
import {
  genTestUserSig
} from '../../utils/GenerateTestUserSig'
Page({
  data: {
    trtcConfig: {
      scene: 'live', // 通话场景'trc' 'live'
      sdkAppID: '', // SDKAppID,请填入自己的
      userID: '', // 用户ID
      userSig: '', // 身份签名
      template: 'custom', // 画面排版'1v1' 'grid' 'custom'
      enableCamera: false, // 开启摄像头
      enableMic: true, // 开启麦克风
      enableAgc: false, // 开启音频自动增益
      enableAns: false, // 开启音频噪声抑制
      enableEarMonitor: false, // 开启耳返(ios)
      enableAutoFocus: true, // 开启摄像头自动对焦
      enableZoom: false, // 支持双手滑动调整摄像头焦距
      minBitrate: '200', // 最小码率,不建议设置太低
      maxBitrate: '1000', // 最大码率,需要跟分辨率相匹配,建议参考 分辨率码率参照表。
      videoWidth: '360', // 视频宽,若设置视频宽高,会忽略 aspect
      videoHeight: '640', // 视频高,若设置视频宽高,会忽略 aspec
      beautyLevel: 0, // 美颜,取值范围 0-9,0表示关闭
      whitenessLevel: 0, // 美白,取值范围 0-9,0表示关闭。
      videoOrientation: 'vertical', // 设置本地画面方向,可选值:vertical 或 horizontal。
      videoAspect: '9:16', // 宽高比,可选值:3:4 或 9:16。
      frontCamera: 'front', // 设置前置还是后置摄像头,可选值:front 或 back。
      enableRemoteMirror: false, // 设置观众端看到的画面的镜像效果
      localMirror: 'auto', // 设置主播本地摄像头预览画面的镜像效果
      enableBackgroundMute: false, // 设置主播端小程序切入后台时是否暂停声音的采集
      audioQuality: 'high', // 高音质(48KHz)或低音质(16KHz),可选值:high 或 low。
      audioVolumeType: 'voicecall', // 系统音量类型'media' 'voicecall'
      audioReverbType: 0, // 音频混响类型,可选值为: 0:关闭,1:KTV,2:小房间,3:大会堂,4:低沉,5:洪亮,6:金属声,7:磁性。
      enableIM: false,
      debugMode: false,
    },
    roomID: '',
    trtcRoomContext: null,
    lianmai: false,
  },
  onLoad: function (options) {
    console.log(options)
    let trtcConfig = this.data.trtcConfig
    trtcConfig['userID'] = options.userID
    trtcConfig['enableCamera'] = options.role == 'Anchor' ? true : false
    trtcConfig['enableMic'] = options.role == 'Anchor' ? true : false
    trtcConfig['userSig'] = genTestUserSig(options.userID).userSig
    this.setData({
      trtcConfig,
      roomID: options.roomID,
      role: options.role
    })
  },
  onShow: function () {
    // 获取trtc-room实例
    let trtcRoomContext = this.selectComponent('#trtcroom')

    // 绑定事件监听
    const TRTC_EVENT = trtcRoomContext.EVENT
    trtcRoomContext.on(TRTC_EVENT.LOCAL_JOIN, (event) => {
      // 进房成功,触发该事件后可以对本地视频和音频进行设置
      if (this.data.role == 'Anchor') {
        trtcComponent.publishLocalVideo()
        trtcComponent.publishLocalAudio()
        trtcComponent.setViewRect({
          userID: event.userID,
          xAxis: '0rpx',
          yAxis: '0rpx',
          width: '100vw',
          height: '100vh',
        })

      }
    })
    // 远端用户推送视频
    trtcRoomContext.on(TRTC_EVENT.REMOTE_VIDEO_ADD, (event) => {
      // 订阅视频
      // const userList = trtcRoomContext.getRemoteUserList()
      const data = event.data
      trtcRoomContext.subscribeRemoteVideo({
        userID: data.userID,
        streamType: data.streamType,
      })
    })
    // 远端用户推送音频
    trtcRoomContext.on(TRTC_EVENT.REMOTE_AUDIO_ADD, (event) => {
      // 订阅音频
      const data = event.data
      trtcRoomContext.subscribeRemoteAudio({
        userID: data.userID,
      })
    })
    trtcRoomContext.enterRoom({
      roomID: parseInt(this.data.roomID)
    })
    this.setData({
      trtcRoomContext
    })
  },
  // 连麦操作
  lianmai() {
    if (this.data.role == 'Audience') {

      let trtcRoomContext = this.data.trtcRoomContext
      if (this.data.lianmai) {
        trtcRoomContext.unpublishLocalAudio()
        this.setData({
          lianmai: false
        })
      } else {
        trtcRoomContext.publishLocalAudio()
        this.setData({
          lianmai: true
        })
      }

    }
  },
  // 离开房间
  leave() {
    if (this.data.role == 'Audience') {
      let trtcRoomContext = this.data.trtcRoomContext
      trtcRoomContext.exitRoom()
      wx.navigateBack({
        delta: 1,
      })
    }
  }
})

编辑custom面板,找到custom自定义面板

custom面板所在的位置custom面板所在的位置

custom.wxml的代码:

代码语言:html复制
<!-- template custom -->
<template name='custom'>
  <view class="win">
    <view wx:for="{{streamList}}" wx:key="streamID" class="player">
      <live-player class="player" id="{{item.streamID}}" data-userid="{{item.userID}}" data-streamid="{{item.streamID}}"
        data-streamtype="{{item.streamType}}" src="{{item.src}}" mode="{{item.mode}}" autoplay="{{item.autoplay}}"
        mute-audio="{{item.muteAudio}}" mute-video="{{item.muteVideo}}" orientation="{{item.orientation}}"
        object-fit="{{item.objectFit}}" background-mute="{{item.enableBackgroundMute}}" min-cache="{{item.minCache}}"
        max-cache="{{item.maxCache}}" sound-mode="{{item.soundMode}}" enable-recv-message="{{item.enableRecvMessage}}"
        auto-pause-if-navigate="{{item.autoPauseIfNavigate}}" auto-pause-if-open-native="{{item.autoPauseIfOpenNative}}"
        debug="{{debug}}" bindstatechange="_playerStateChange" bindfullscreenchange="_playerFullscreenChange"
        bindnetstatus="_playerNetStatus" bindaudiovolumenotify="_playerAudioVolumeNotify" />
    </view>
    <live-pusher class="pusher" url="{{pusher.url}}" mode="{{pusher.mode}}" autopush="{{pusher.autopush}}"
      enable-camera="{{pusher.enableCamera}}" enable-mic="{{pusher.enableMic}}" muted="{{!pusher.enableMic}}"
      enable-agc="{{pusher.enableAgc}}" enable-ans="{{pusher.enableAns}}"
      enable-ear-monitor="{{pusher.enableEarMonitor}}" auto-focus="{{pusher.enableAutoFocus}}"
      zoom="{{pusher.enableZoom}}" min-bitrate="{{pusher.minBitrate}}" max-bitrate="{{pusher.maxBitrate}}"
      video-width="{{pusher.videoWidth}}" video-height="{{pusher.videoHeight}}" beauty="{{pusher.beautyLevel}}"
      whiteness="{{pusher.whitenessLevel}}" orientation="{{pusher.videoOrientation}}" aspect="{{pusher.videoAspect}}"
      device-position="{{pusher.frontCamera}}" remote-mirror="{{pusher.enableRemoteMirror}}"
      local-mirror="{{pusher.localMirror}}" background-mute="{{pusher.enableBackgroundMute}}"
      audio-quality="{{pusher.audioQuality}}" audio-volume-type="{{pusher.audioVolumeType}}"
      audio-reverb-type="{{pusher.audioReverbType}}" waiting-image="{{pusher.waitingImage}}" debug="{{debug}}"
      bindstatechange="_pusherStateChangeHandler" bindnetstatus="_pusherNetStatusHandler"
      binderror="_pusherErrorHandler" bindbgmstart="_pusherBGMStartHandler" bindbgmprogress="_pusherBGMProgressHandler"
      bindbgmcomplete="_pusherBGMCompleteHandler" bindaudiovolumenotify="_pusherAudioVolumeNotify" />
    <!-- 以下是主播的按钮,具体可以更具业务需要自己编写,其中引用的函数可以参考 https://cloud.tencent.com/developer/article/1801901 -->
    <view class="buttonbox" wx:if="{{streamList.length < 2}}">
      <Button type="error" shape="circle" bindtap="_hangUp">退出</Button>
      <Button type="{{pusher.enableMic?'primary':'default'}}" shape="circle" bindtap="_toggleAudio">话筒</Button>
      <Button type="{{pusher.enableCamera?'primary':'default'}}" shape="circle" bindtap="_toggleVideo">镜头</Button>
      <Button type="{{pusher.beautyLevel==9?'primary':'default'}}" shape="circle" bindtap="_setPuserProperty" data-key="beautyLevel" data-value="9|0"
        data-value-type="number">美颜</Button>
      <Button type="primary" shape="circle" bindtap="switchCamera">切换</Button>
    </view>
  </view>
</template>

custom.wxss的代码:

代码语言:css复制
/* 通过方法自定义模式 */
.win {
  height: 100vh;
  width: 100vw;
  position: relative;
}
.buttonbox {
  position: absolute;
  width: 100vw;
  height: 100px;
  bottom: 0;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-content: center;
}

0 人点赞