国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【多人會議功能】uniapp - 微信小程序 - 騰訊云

這篇具有很好參考價值的文章主要介紹了【多人會議功能】uniapp - 微信小程序 - 騰訊云。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

目的:uniapp微信小程序通過騰訊云實現(xiàn)多人會議功能。

源碼下載地址:https://download.csdn.net/download/qq_39891453/86790793

效果展示:

【多人會議功能】uniapp - 微信小程序 - 騰訊云【多人會議功能】uniapp - 微信小程序 - 騰訊云【多人會議功能】uniapp - 微信小程序 - 騰訊云

功能實現(xiàn):

前提條件:?注冊騰訊云 賬號,并完成 實名認證。

推拉流標簽不支持個人小程序,要求申請的企業(yè)類微信小程序。

步驟一:開通微信小程序權(quán)限

推拉流標簽不支持個人小程序,要求申請的企業(yè)類微信小程序,登錄微信公眾平臺 =》開發(fā)?=》開發(fā)管理 =》接口設置,在其他接口中打開實時播放音視頻流實時播放音視頻流。如圖:

【多人會議功能】uniapp - 微信小程序 - 騰訊云

步驟二:在微信小程序控制臺配置域名

微信公眾平臺?=》?開發(fā)?=》?開發(fā)管理?=》?開發(fā)設置?=》?服務器域名中設置 request合法域名socket合法域名,如下圖所示:

【多人會議功能】uniapp - 微信小程序 - 騰訊云

  • ?request 合法域名:
    https://official.opensso.tencent-cloud.com
    https://yun.tim.qq.com
    https://cloud.tencent.com
    https://webim.tim.qq.com
    https://query.tencent-cloud.com
    https://web.sdk.qcloud.com
  • socket 合法域名:
    wss://wss.im.qcloud.com
    wss://wss.tim.qq.com

步驟三:下載多人會議功能源碼??源碼下載地址:https://download.csdn.net/download/qq_39891453/86790793

?項目結(jié)構(gòu)如圖所示:【多人會議功能】uniapp - 微信小程序 - 騰訊云

步驟四:?開通騰訊云服務?

  1. 登錄到 即時通信 IM 控制臺,單擊創(chuàng)建新應用,在彈出的對話框中輸入您的應用名稱,并單擊確定。

    【多人會議功能】uniapp - 微信小程序 - 騰訊云

  2. 單擊剛剛創(chuàng)建出的應用,進入基本配置頁面,并在頁面的右下角找到開通騰訊實時音視頻服務功能區(qū),單擊免費體驗即可開通 TUICallKit 的 7 天免費試用服務。【多人會議功能】uniapp - 微信小程序 - 騰訊云
  3. 在同一頁面找到 SDKAppID密鑰并記錄下來。【多人會議功能】uniapp - 微信小程序 - 騰訊云

步驟四:?配置 meeting =》debug =》GenerateTestUserSig.js 工程文件

設置 GenerateTestUserSig.js 文件中的相關(guān)參數(shù):

  • SDKAPPID:默認為0,請設置為實際的 SDKAppID。
  • SECRETKEY:默認為空字符串,請設置為實際的密鑰信息。【多人會議功能】uniapp - 微信小程序 - 騰訊云

步驟五:calling.vue為入口頁。

<template>
	<view class="container">
		<view class="trtc-demo-container">
		  <!-- <view class='title'  >
		    <view>多人會議</view>
		  </view> -->
		  <view class="input-box">
		    <input type="number" v-model="roomID" maxlength="10"  placeholder="請輸入房間號" placeholder-style="opacity: 0.55;"/>
		  </view>
		  <view class="choice-content">
		    <view class="label" >
		      <text>開啟攝像頭</text>
		      <u-switch inactiveColor="#999999" activeColor="#00B38A" v-model="localVideo"  @change="switchHandler"/>
		    </view>
		    <view class="label">
		      <text>開啟麥克風</text>
		      <u-switch  inactiveColor="#999999" activeColor="#00B38A" v-model="localAudio"  @change="switchHandler2"/>
		    </view>
		  </view>
		</view>
		
		<view class='bottom-btn'>
		  <button class="btn" @click="enterRoom" hover-class="none">進入房間</button>
		</view>
	</view>
</template>
<script>

import { genTestUserSig } from './debug/GenerateTestUserSig'
import { mapState } from 'vuex';
	
	export default {
		data() {
			return {
				roomID: '',
				localVideo: true,
				localAudio: false,
			}
		},
		computed: {
			...mapState(['userInfo'])
		},
		onLaunch(){

		},
		onLoad() {

		},
		methods: {
			enterRoom() {
			    const nowTime = new Date()
			    if (nowTime - this.tapTime < 1000) {
			      return
			    }
			    if (!this.roomID) {
			      uni.showToast({
			        title: '請輸入房間號',
			        icon: 'none',
			        duration: 2000,
			      })
			      return
			    }
			    if (/^\d*$/.test(this.roomID) === false) {
			      uni.showToast({
			        title: '房間號只能為數(shù)字',
			        icon: 'none',
			        duration: 2000,
			      })
			      return
			    }
			    if (this.roomID > 4294967295 || this.roomID < 1) {
			      uni.showToast({
			        title: '房間號取值范圍為 1~4294967295',
			        icon: 'none',
			        duration: 2000,
			      })
			      return
			    }
			    const userID = this.userInfo.userId || '123'; //userID
			    const Signature = genTestUserSig(userID)
			    const url = `./room/room?roomID=${this.roomID}&localVideo=${this.localVideo}&localAudio=${this.localAudio}&userID=${userID}&sdkAppID=${Signature.sdkAppID}&userSig=${Signature.userSig}`
			    this.tapTime = nowTime
			    this.checkDeviceAuthorize().then((result) => {
			      console.log('授權(quán)成功', result)
			      wx.navigateTo({ url })
			    })
			      .catch((error) => {
			        console.log('沒有授權(quán)', error)
			      })
			  },
			  checkDeviceAuthorize() {
			    this.hasOpenDeviceAuthorizeModal = false
			    return new Promise((resolve, reject) => {
			      if (!wx.getSetting || !wx.getSetting()) {
			        // 微信測試版 獲取授權(quán)API異常,目前只能即使沒授權(quán)也可以通過
			        resolve()
			      }
			      wx.getSetting().then((result) => {
			        console.log('getSetting', result)
			        this.authorizeMic = result.authSetting['scope.record']
			        this.authorizeCamera = result.authSetting['scope.camera']
			        if (result.authSetting['scope.camera'] && result.authSetting['scope.record']) {
			          // 授權(quán)成功
			          resolve()
			        } else {
			          // 沒有授權(quán),彈出授權(quán)窗口
			          // 注意: wx.authorize 只有首次調(diào)用會彈框,之后調(diào)用只返回結(jié)果,如果沒有授權(quán)需要自行彈框提示處理
			          console.log('getSetting 沒有授權(quán),彈出授權(quán)窗口', result)
			          wx.authorize({
			            scope: 'scope.record',
			          }).then((res) => {
			            console.log('authorize mic', res)
			            this.authorizeMic = true
			            if (this.authorizeCamera) {
			              resolve()
			            }
			          })
			            .catch((error) => {
			              console.log('authorize mic error', error)
			              this.authorizeMic = false
			            })
			          wx.authorize({
			            scope: 'scope.camera',
			          }).then((res) => {
			            console.log('authorize camera', res)
			            this.authorizeCamera = true
			            if (this.authorizeMic) {
			              resolve()
			            } else {
			              this.openConfirm()
			              reject(new Error('authorize fail'))
			            }
			          })
			            .catch((error) => {
			              console.log('authorize camera error', error)
			              this.authorizeCamera = false
			              this.openConfirm()
			              reject(new Error('authorize fail'))
			            })
			        }
			      })
			    })
			  },
			  openConfirm() {
			    if (this.hasOpenDeviceAuthorizeModal) {
			      return
			    }
			    this.hasOpenDeviceAuthorizeModal = true
			    return uni.showModal({
			      content: '您沒有打開麥克風和攝像頭的權(quán)限,是否去設置打開?',
			      confirmText: '確認',
			      cancelText: '取消',
			      success: (res) => {
			        this.hasOpenDeviceAuthorizeModal = false
			        console.log(res)
			        // 點擊“確認”時打開設置頁面
			        if (res.confirm) {
			          console.log('用戶點擊確認')
			          wx.openSetting({
			            success: (res) => { },
			          })
			        } else {
			          console.log('用戶點擊取消')
			        }
			      },
			    })
			  },
			  switchHandler(e) {
				  this.localVideo = e;
			  },
			  switchHandler2(e) {
			  		this.localAudio = e;
			  },
			  onBack() {
			    wx.navigateBack({
			      delta: 1,
			    })
			  },
		}
		
	}
</script>
<style scoped>
	.container {
		width: 100vw;
		height: 100vh;
		background-color: #F5F5F5;
		position: fixed;
		top: 0;
		right: 0;
		left: 0;
		bottom: 0;
	}

	.trtc-demo-container {
	  /* background-image: url(https://mc.qcloudimg.com/static/img/7da57e0050d308e2e1b1e31afbc42929/bg.png); */
	  /* background-color: #333; */
	  /* background-repeat:no-repeat;
	  background-size: cover; */
	  width: 100vw;
	  height: 100vh;
	  display: flex;
	  flex-direction: column;
	  align-items: center;
	  box-sizing: border-box;
	}
	.trtc-demo-container .title{
	  color: #FFFFFF;
	  padding-top: 65rpx;
	  line-height: 60rpx;
	}
	.trtc-demo-container .input-box {
	  background-color: transparent;
	  color: #333;
	  padding: 2vw 5vw 1vw;
	  border-bottom: 1px solid #577785;
	  margin: 100rpx 0 40rpx 0;
	  text-align: center;
	  box-sizing: border-box;
	  width: 80vw;
	}
	.trtc-demo-container .input-box input{
	  font-size: 20px;
	}
	.choice-content {
	  margin-top: 20rpx;
	  width: 80vw;
	  display: flex;
	  flex-direction: column;
	  /* justify-content: space-between;
	  flex-wrap: wrap; */
	  font-size: 14px;
	  color: #333;
	}
	.label{
		display: flex;
		flex-direction: row;
		align-items: center;
		justify-content: space-between;
		padding: 24rpx 0;
	}
	.choice-content switch {
	  color: #00B38A;
	  transform:scale(0.8);
	}
	
	
	.bottom-btn {
	  position: fixed;
	  width: 100vw;
	  text-align: center;
	  bottom: 5vh;
	}
	.bottom-btn .btn{
	  width: 80%;
	  background-color: #00B38A;
	  border-radius: 50px;
	  color: #ffffff;
	}
	
	.close {
	  position:absolute;
	  padding-left:5vw;
	  padding-right:5vw;
	  width:50rpx;
	  height:60rpx;
	}
</style>

room.vue 會議頁面(樣式按自己需求調(diào)整):?實時音視頻 API 概覽-含 UI 集成方案-文檔中心-騰訊云 (tencent.com)文章來源地址http://www.zghlxwxcb.cn/news/detail-455479.html

<template>
	<view class="template-grid">
		<view class="column-1">
			<!-- :class="playerList.length !=0? 'fullscreen':'fullscreen2'" -->
			<view class="view-container fullscreen">
				<live-pusher class="pusher"
					:data-userid="pusher.userID"
					:data-streamid="pusher.streamID"
					:data-streamtype="pusher.streamType"
					: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" :beauty-style="pusher.beautyStyle" :filter="pusher.filter"
					@statechange="_pusherStateChangeHandler" @netstatus="_pusherNetStatusHandler"
					@error="_pusherErrorHandler" @bgmstart="_pusherBGMStartHandler"
					@bgmprogress="_pusherBGMProgressHandler" @bgmcomplete="_pusherBGMCompleteHandler"
					@audiovolumenotify="_pusherAudioVolumeNotify" />
				<view class="no-video" v-if="!pusher.enableCamera">
					<image class="image" :src="require('../static/images/mute-camera-white.png')"></image>
				</view>
				<view class="no-audio" v-if="!pusher.enableMic">
					<image class="image" :src="require('../static/images/mute-mic-white.png')"></image>
				</view>
				<view class="audio-volume" v-if="pusher.enableMic">
						<image class="image" :src="require('../static/images/micro-open.png')"></image>
						<view class="audio-active" :style="'height:' + pusher.volume + '%'">
							<image class="image" :src="require('../static/images/audio-active.png')"></image>
						</view>
					</view>
			</view>
		</view>
		<swiper v-show="show_memberList" class="swiper" :indicator-dots="true" indicatorActiveColor="#00B38A">
			<swiper-item class="swiper-item" v-for="(items, index) in playerList" :key="index">
					<view v-for="(item, streamID) in items" :key="streamID" class="player-container"
					:id="'player-' + item.streamID">
					<live-player class="player" :id="item.id"
						:data-userid="item.userID"
						:data-streamid="item.streamID"
						:data-streamtype="item.streamType"
						:src="item.src" mode="RTC"
						: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"
						@statechange="_playerStateChange" @fullscreenchange="_playerFullscreenChange"
						@netstatus="_playerNetStatus" @audiovolumenotify="_playerAudioVolumeNotify" />
					<view class="no-video" v-if="item.muteVideo">
						<image class="image" :src="require('../static/images/display-pause-white.png')"></image>
						<view class="text">
							<p>{{ item.userID }}</p>
						</view>
					</view>
					<view class="no-video" v-if="!item.hasVideo && !item.muteVideo">
						<image class="image" :src="require('../static/images/mute-camera-white.png')"></image>
						<view class="text">
							<p>{{ item.userID }}</p>
						</view>
						<view class="text">
							<p>對方攝像頭未打開</p>
						</view>
					</view>
					<view class="no-audio" v-if="!item.hasAudio">
						<image class="image" :src="require('../static/images/mute-mic-white.png')"></image>
					</view>
					<view class="audio-volume" v-if="item.hasAudio">
						<image class="image" :src="require('../static/images/micro-open.png')"></image>
						<view class="audio-active" :style="'height:' + item.volume + '%'">
							<image class="image" :src="require('../static/images/audio-active.png')"></image>
						</view>
					</view>
					<view class="sub-box">
						<image class="audio-image" @click="_mutePlayerAudio(item)" 
							:src="item.muteAudio? require('../static/images/mute-mic-white.png') : require('../static/images/micro-open.png')">
						</image>
						<image class="audio-image" @click="_mutePlayerVideo(item)" 
							:src="item.muteVideo? require('../static/images/mute-camera-white.png') : require('../static/images/camera.png')">
						</image>
					</view>
				</view>
			</swiper-item>
		</swiper>
	
		<view class="bottom-box">
			<view class="bottom-btns">
				<view class="btn-normal" @click="_pusherAudioHandler">
					<image class="btn-image"
						:src="pusher.enableMic? require('../static/images/audio-true.png') : require('../static/images/audio-false.png')">
					</image>
				</view>
				<view class="btn-normal" @click="_pusherVideoHandler">
					<image class="btn-image"
						:src="pusher.enableCamera? require('../static/images/camera-true.png') : require('../static/images/camera-false.png')">
					</image>
				</view>
				<view class="btn-hangup" @click="_hangUp">
					<image class="btn-image" :src="require('../static/images/hangup.png')"></image>
				</view>
				<view class="btn-normal"
					@click="_setPusherBeautyHandle">
					<image class="btn-image"
						:src="pusher.beautyLevel == 9? require('../static/images/beauty-true.png') : require('../static/images/beauty-false.png')">
					</image>
				</view>
				<view class="btn-normal" @click="_switchMemberListPanel">
					<image class="btn-image" :src="require('../static/images/list.png')"></image>
				</view>
				
			</view>
		</view>
	
		<!-- <view class="panel memberlist-panel" v-if="show_memberList">
			<view @click="_handleClose" class='close-btn'>X</view>
			<view class="panel-header">成員列表</view>
			<view class="panel-body">
				<view class="panel-tips" v-if="playerList.length == 0">暫無成員</view>
				<scroll-view class="scroll-container" scroll-y="true">
					<view v-for="(items, index) in playerList" :key="index">
						<view class="member-item" v-for="(item, streamID) in items" :key="streamID">
							<view class="member-id">{{ item.userID }}</view>
							<view class="member-btns">
								<view class="btn">
									<image class="audio-image" @click="_mutePlayerAudio(item)"
										:src="item.muteAudio? require('../static/images/mute-mic-white.png') : require('../static/images/micro-open.png')">
									</image>
								</view>
								<view class="btn">
									<image class="audio-image" @click="_mutePlayerVideo(item)"
										:src="item.muteVideo? require('../static/images/mute-camera-white.png') : require('../static/images/camera.png')">
									</image>
								</view>
							</view>
						</view>
					</view>
				</scroll-view>
			</view>
		</view> -->
		
	</view>
</template>
<script>
import TRTC from '../static/trtc-wx';
import { mapState } from 'vuex';

export default {
	data() {
		return {
			RtcConfig: {
				sdkAppID: '', // 必要參數(shù) 開通實時音視頻服務創(chuàng)建應用后分配的 sdkAppID
				userID: '', // 必要參數(shù) 用戶 ID 可以由您的帳號系統(tǒng)指定
				userSig: '', // 必要參數(shù) 身份簽名,相當于登錄密碼的作用
			},
			pusher: {
				enableCamera: false,
			},
			//切換后的主頻
			pushed: {
				enableCamera: false,
			},
			playerList: [
				// {"sre":"room://cloud.tencent.com/rtc?userid=654&streamtype=main",
				//  "mode":"RTC", 
				//  "autoplay":true, 
				//  "muteAudio" :false, 
				//  "mute Video" :true, 
				//  " orientation": "vertical",
				// "objectFit":"fillCrop",
				// "enableBackgroundMute":false,
				// "minCache":1," maxCache":2, "soundMode":"speaker", 
				// "enableRecMessage":false, "autoPauselfNavigate":true,
				// "autoPauselfOpenNative":true,"isVisible":true,
				// "_definitionType": "main", "netStatus":
				// {"videoBitrate":0, " audioBitrate":42, "videoFPS":0, "netSpeed"
				// :42, "netQualityLevel":1, " videoWidth":640, " videoHeight":480
				// }, "userID": "654","streamType": "main","streamID": "654_main", id: "654_main","hasVideo" :false, "hasAudio" :false, "volume":54},
				// {"sre":"room://cloud.tencent.com/rtc?userid=654&streamtype=main",
				//  "mode":"RTC", 
				//  "autoplay":true, 
				//  "muteAudio" :false, 
				//  "mute Video" :true, 
				//  " orientation": "vertical",
				// "objectFit":"fillCrop",
				// "enableBackgroundMute":false,
				// "minCache":1," maxCache":2, "soundMode":"speaker", 
				// "enableRecMessage":false, "autoPauselfNavigate":true,
				// "autoPauselfOpenNative":true,"isVisible":true,
				// "_definitionType": "main", "netStatus":
				// {"videoBitrate":0, " audioBitrate":42, "videoFPS":0, "netSpeed"
				// :42, "netQualityLevel":1, " videoWidth":640, " videoHeight":480
				// }, "userID": "654","streamType": "main","streamID": "654_main", id: "654_main","hasVideo" :false, "hasAudio" :false, "volume":54},
				// {"sre":"room://cloud.tencent.com/rtc?userid=654&streamtype=main",
				//  "mode":"RTC", 
				//  "autoplay":true, 
				//  "muteAudio" :false, 
				//  "mute Video" :true, 
				//  " orientation": "vertical",
				// "objectFit":"fillCrop",
				// "enableBackgroundMute":false,
				// "minCache":1," maxCache":2, "soundMode":"speaker", 
				// "enableRecMessage":false, "autoPauselfNavigate":true,
				// "autoPauselfOpenNative":true,"isVisible":true,
				// "_definitionType": "main", "netStatus":
				// {"videoBitrate":0, " audioBitrate":42, "videoFPS":0, "netSpeed"
				// :42, "netQualityLevel":1, " videoWidth":640, " videoHeight":480
				// }, "userID": "654","streamType": "main","streamID": "654_main", id: "654_main","hasVideo" :true, "hasAudio" :true, "volume":54},
				// {"sre":"room://cloud.tencent.com/rtc?userid=654&streamtype=main",
				//  "mode":"RTC", 
				//  "autoplay":true, 
				//  "muteAudio" :false, 
				//  "mute Video" :true, 
				//  " orientation": "vertical",
				// "objectFit":"fillCrop",
				// "enableBackgroundMute":false,
				// "minCache":1," maxCache":2, "soundMode":"speaker", 
				// "enableRecMessage":false, "autoPauselfNavigate":true,
				// "autoPauselfOpenNative":true,"isVisible":true,
				// "_definitionType": "main", "netStatus":
				// {"videoBitrate":0, " audioBitrate":42, "videoFPS":0, "netSpeed"
				// :42, "netQualityLevel":1, " videoWidth":640, " videoHeight":480
				// }, "userID": "654","streamType": "main","streamID": "654_main", id: "654_main","hasVideo" :true, "hasAudio" :true, "volume":54},
				// {"sre":"room://cloud.tencent.com/rtc?userid=654&streamtype=main",
				//  "mode":"RTC", 
				//  "autoplay":true, 
				//  "muteAudio" :false, 
				//  "mute Video" :true, 
				//  " orientation": "vertical",
				// "objectFit":"fillCrop",
				// "enableBackgroundMute":false,
				// "minCache":1," maxCache":2, "soundMode":"speaker", 
				// "enableRecMessage":false, "autoPauselfNavigate":true,
				// "autoPauselfOpenNative":true,"isVisible":true,
				// "_definitionType": "main", "netStatus":
				// {"videoBitrate":0, " audioBitrate":42, "videoFPS":0, "netSpeed"
				// :42, "netQualityLevel":1, " videoWidth":640, " videoHeight":480
				// }, "userID": "654","streamType": "main","streamID": "654_main", id: "654_main","hasVideo" :true, "hasAudio" :true, "volume":54}
			],
			show_memberList: false,
			localAudio: false,
			localVideo: false,
			myshow:true,
			shownum:true,
		}
	},
	/**
	* 生命周期函數(shù)--監(jiān)聽頁面加載
	*/

	computed: {
		...mapState(['userInfo'])
	},
	onLoad(options) {
		console.log('room onload', options)
		wx.setKeepScreenOn({
			keepScreenOn: true,
		})
		this.TRTC = new TRTC(this)
		// 將String 類型的 true false 轉(zhuǎn)換成 boolean
		Object.getOwnPropertyNames(options).forEach((key) => {
			if (options[key] === 'true') {
				options[key] = true
			}
			if (options[key] === 'false') {
				options[key] = false
			}
		})
		 // this.playerList = this.sliceIntoChunks(this.playerList,2)//測試
		this.init(options)
		this.bindTRTCRoomEvent()
		this.enterRoom({ roomID: options.roomID })
	},
	onReady() {
		console.log('room ready')
	},
	onUnload() {
		console.log('room unload')
	},
	methods: {
		init(options) {

			console.log("options", options)
			// pusher 初始化參數(shù)
			const pusherConfig = {
				beautyLevel: 9,
			}
			const pusher = this.TRTC.createPusher(pusherConfig)
			console.log("pusher", pusher)
			console.log('userID', this.RtcConfig)
			this.RtcConfig.userID = options.userID;
			this.RtcConfig.sdkAppID = options.sdkAppID;
			this.RtcConfig.userSig = options.userSig;
			this.pusher = pusher.pusherAttributes;
			this.localAudio = options.localAudio;
			this.localVideo = options.localVideo;
			console.log(this.localAudio, this.localVideo)
			console.log("000000000000000")
		},

		enterRoom(options) {
			const roomID = options.roomID
			const config = Object.assign(this.RtcConfig, { roomID })
			this.pusher = this.TRTC.enterRoom(config);
			console.log("this.pusher", this.pusher)
			if (this.pusher) {
				this.TRTC.getPusherInstance().start() // 開始推流
			}
		},

		exitRoom() {
			const result = this.TRTC.exitRoom();
			this.pusher = result.pusher;
			this.playerList = this.sliceIntoChunks(result.playerList,2);
		},

		// 設置 pusher 屬性
		setPusherAttributesHandler(options) {
			this.pusher = this.TRTC.setPusherAttributes(options);
		},

		// 設置某個 player 屬性
		setPlayerAttributesHandler(player, options) {
			console.log("123",player, options,)
			//this.playerList = this.TRTC.setPlayerAttributes(player.streamID, options);
			let playerList = this.TRTC.setPlayerAttributes(player.streamID, options)
			this.playerList = this.sliceIntoChunks(playerList,2);
			console.log("12345678:",this.playerList)
		},
		// 事件監(jiān)聽
		bindTRTCRoomEvent() {
			const TRTC_EVENT = this.TRTC.EVENT
			console.log("xxxxxxxxxxxx", TRTC_EVENT)
			// 初始化事件訂閱
			this.TRTC.on(TRTC_EVENT.LOCAL_JOIN, (event) => {
				console.log('* room LOCAL_JOIN', event)
				if (this.localVideo) {
					this.setPusherAttributesHandler({ enableCamera: true })
				}
				if (this.localAudio) {
					this.setPusherAttributesHandler({ enableMic: true })
				}
			})
			this.TRTC.on(TRTC_EVENT.LOCAL_LEAVE, (event) => {
				console.log('* room LOCAL_LEAVE', event)
			})
			this.TRTC.on(TRTC_EVENT.ERROR, (event) => {
				console.log('* room ERROR', event)
			})
			this.TRTC.on(TRTC_EVENT.REMOTE_USER_JOIN, (event) => {
				console.log('* room REMOTE_USER_JOIN', event)
				const { userID } = event.data;
				uni.showToast({
					title: `${userID} 進入了房間`,
					icon: 'none',
					duration: 2000,
				})
			})
			// 遠端用戶退出
			this.TRTC.on(TRTC_EVENT.REMOTE_USER_LEAVE, (event) => {
				console.log('* room REMOTE_USER_LEAVE', event)
				const { userID, playerList } = event.data
				this.playerList = this.sliceIntoChunks(playerList,2);
				uni.showToast({
					title: `${userID} 離開了房間`,
					icon: 'none',
					duration: 2000,
				})
			})
			// 遠端用戶推送視頻
			this.TRTC.on(TRTC_EVENT.REMOTE_VIDEO_ADD, (event) => {
				console.log('* room REMOTE_VIDEO_ADD', event)
				const { player } = event.data
				// 開始播放遠端的視頻流,默認是不播放的
				this.setPlayerAttributesHandler(player, { muteVideo: false })
			})
			// 遠端用戶取消推送視頻
			this.TRTC.on(TRTC_EVENT.REMOTE_VIDEO_REMOVE, (event) => {
				console.log('* room REMOTE_VIDEO_REMOVE', event)
				const { player } = event.data
				console.log("234",player)
				this.setPlayerAttributesHandler(player, { muteVideo: true })
			})
			// 遠端用戶推送音頻
			this.TRTC.on(TRTC_EVENT.REMOTE_AUDIO_ADD, (event) => {
				console.log('* room REMOTE_AUDIO_ADD', event)
				const { player } = event.data
				console.log("345",player)
				this.setPlayerAttributesHandler(player, { muteAudio: false })
			})
			// 遠端用戶取消推送音頻
			this.TRTC.on(TRTC_EVENT.REMOTE_AUDIO_REMOVE, (event) => {
				console.log('* room REMOTE_AUDIO_REMOVE', event)
				const { player } = event.data
				this.setPlayerAttributesHandler(player, { muteAudio: true })
			})
			this.TRTC.on(TRTC_EVENT.REMOTE_AUDIO_VOLUME_UPDATE, (event) => {
				console.log('* room REMOTE_AUDIO_VOLUME_UPDATE', event)
				const { playerList } = event.data;
				this.playerList = this.sliceIntoChunks(playerList,2);
				console.log("@@@@", this.playerList)
			})
			this.TRTC.on(TRTC_EVENT.LOCAL_AUDIO_VOLUME_UPDATE, (event) => {
				// console.log('* room LOCAL_AUDIO_VOLUME_UPDATE', event)
				const { pusher } = event.data
				this.pusher = pusher;
			})
		},

		// 是否訂閱某一個player Audio
		_mutePlayerAudio(player) {
			console.log('22222',player)
			//const player = event.currentTarget.dataset.value
			if (player.hasAudio && player.muteAudio) {
				this.setPlayerAttributesHandler(player, { muteAudio: false })
				return
			}
			if (player.hasAudio && !player.muteAudio) {
				this.setPlayerAttributesHandler(player, { muteAudio: true })
				return
			}
		},

		// 訂閱 / 取消訂閱某一個player Audio
		_mutePlayerVideo(player) {
			console.log("1111")
			console.log(player)
			//const player = event.currentTarget.dataset.value
			if (player.hasVideo && player.muteVideo) {
				this.setPlayerAttributesHandler(player, { muteVideo: false })
				return
			}
			if (player.hasVideo && !player.muteVideo) {
				this.setPlayerAttributesHandler(player, { muteVideo: true })
				return
			}
		},

		// 掛斷退出房間
		_hangUp() {
			this.exitRoom()
			wx.navigateBack({
				delta: 1,
			})
		},

		// 設置美顏
		_setPusherBeautyHandle() {
			const beautyLevel = this.pusher.beautyLevel === 0 ? 9 : 0
			this.setPusherAttributesHandler({ beautyLevel })
		},

		// 訂閱 / 取消訂閱 Audio
		_pusherAudioHandler() {
			if (this.pusher.enableMic) {
				this.setPusherAttributesHandler({ enableMic: false })
			} else {
				this.setPusherAttributesHandler({ enableMic: true })
			}
		},

		// 訂閱 / 取消訂閱 Video
		_pusherVideoHandler() {
			if (this.pusher.enableCamera) {
				this.setPusherAttributesHandler({ enableCamera: false })
			} else {
				this.setPusherAttributesHandler({ enableCamera: true })
			}
		},

		_switchMemberListPanel() {
			if(this.playerList.length == 0){
				uni.showToast({
					title: "暫無成員",
					icon: 'none',
					duration: 2000,
				})
			}else{
				this.show_memberList = !this.show_memberList;
			}
			// this.setData({
			//   show_memberList: true
			// })
		},
		_handleClose() {
			this.show_memberList = false;
			// this.setData({
			//   show_memberList: false
			// })
		},
		// 請保持跟 wxml 中綁定的事件名稱一致
		_pusherStateChangeHandler(event) {
			this.TRTC.pusherEventHandler(event)
		},
		_pusherNetStatusHandler(event) {
			this.TRTC.pusherNetStatusHandler(event)
		},
		_pusherErrorHandler(event) {
			this.TRTC.pusherErrorHandler(event)
		},
		_pusherBGMStartHandler(event) {
			this.TRTC.pusherBGMStartHandler(event)
		},
		_pusherBGMProgressHandler(event) {
			this.TRTC.pusherBGMProgressHandler(event)
		},
		_pusherBGMCompleteHandler(event) {
			this.TRTC.pusherBGMCompleteHandler(event)
		},
		_pusherAudioVolumeNotify(event) {
			this.TRTC.pusherAudioVolumeNotify(event)
		},
		_playerStateChange(event) {
			this.TRTC.playerEventHandler(event)
		},
		_playerFullscreenChange(event) {
			this.TRTC.playerFullscreenChange(event)
		},
		_playerNetStatus(event) {
			this.TRTC.playerNetStatus(event)
		},
		_playerAudioVolumeNotify(event) {
			this.TRTC.playerAudioVolumeNotify(event)
		},

		//數(shù)組重構(gòu)
		sliceIntoChunks(arr, chunkSize) {
				const res = [];
				console.log(arr.length)
				for (let i = 0; i < arr.length; i += chunkSize) {
					const chunk = arr.slice(i, i + chunkSize);
					console.log(chunk)
					res.push(chunk);
			}
				return res;
		},
		//切換為主頻
		toggle(e,i,j){
			// this.setPlayerAttributesHandler(e, { muteVideo: false })
			// console.log(this.shownum)
			// console.log('######',e,i,j)
			// console.log('zhu:',this.pusher,this.pusher.muteVideo,e.muteVideo)
			// if(e.userID == this.userInfo.userId){
			// 	this.setPlayerAttributesHandler(this.pushed, { muteVideo: false })
			// 	this.playerList[i].splice(j,1,this.pushed);
			// 	this.myshow = true;
			// 	this.shownum = true
			// }else{
			// 	this.myshow = false;
			// 	if(this.shownum){
			// 		this.playerList[i].splice(j,1,this.pusher);
			// 		this.pushed = e;
			// 		this.shownum = false
			// 	}else{
			// 		this.shownum = false
			// 		 //this.setPlayerAttributesHandler(this.pushed, { muteVideo: false })
			// 		this.playerList[i].splice(j,1,this.pushed);
			// 		this.pushed = e;
			// 	}
			// }
			
			// this.setPlayerAttributesHandler(e, { muteVideo: false })
			// console.log('######',e,i,j)
			// console.log('zhu:',this.pusher,this.pusher.muteVideo,e.muteVideo)
			if(e.userID == this.userInfo.userId){
					this.playerList[i].splice(j,1,this.pushed);
					this.myshow = true;
			}else{
					this.playerList[i].splice(j,1,this.pusher);
					this.pushed = e;
					this.myshow = false;
			}
			// this.setPlayerAttributesHandler(this.playerList, { muteVideo: false })
			console.log('$$$$$$$$$$$',this.playerList)
		},
		/**
			 * 切換前后攝像頭
			 */
			switchCamera() {
				if (!this.cameraPosition) {
					// this.data.pusher.cameraPosition 是初始值,不支持動態(tài)設置
					this.cameraPosition = this.pusher.frontCamera;
				}

				console.log(TAG_NAME, 'switchCamera', this.cameraPosition);
				this.cameraPosition = this.cameraPosition === 'front' ? 'back' : 'front';
				this.setData({
					cameraPosition: this.cameraPosition
				}, () => {
					console.log(TAG_NAME, 'switchCamera success', this.cameraPosition);
				}); // wx 7.0.9 不支持動態(tài)設置 pusher.frontCamera ,只支持調(diào)用 API switchCamer() 設置,這里修改 cameraPosition 是為了記錄狀態(tài)

				this.pusher.getPusherContext().switchCamera();
			},
	}
}
</script>
<style lang="less" scoped>
/* 9人 會議模版 */
.template-grid{
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  background-color: #F5F5F5;
  /* background-image: url(https://mc.qcloudimg.com/static/img/7da57e0050d308e2e1b1e31afbc42929/bg.png); */
  /* display: flex;
  flex-direction: row;
  flex-wrap: wrap; */
}
.pusher {
  height: 100%;
}
.player{
  height: 100%;
}

.column-1{
  // max-height: calc(100vh - 170rpx);
  // min-height: calc(100vh - 170rpx);
  display: flex;
  flex-direction: column;
  /*flex: 1;*/
}


.view-container {
  position: relative;
	width: 100vh;
}
.no-video{
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	box-sizing: border-box;
	color:#fff;
	background-color: rgba(0, 0, 0, 0.4);
	font-size: 24rpx;
	border-radius: 16rpx;
	.image{
		width: 60rpx;
		height: 60rpx;
	}
}


.fullscreen{
	width: 100vw;
	height: calc(100vh - 196rpx);
}

live-player {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  border-radius: 16rpx;
}


.template-grid .btn-normal {
  width: 64rpx;
  height: 64rpx;
  margin: 0 6rpx;
  box-sizing: border-box;
  display: flex;
  background: rgba(255, 255, 255, 1);
  justify-content: center;
  align-items: center;
  border-radius: 50%;
}

.template-grid .btn-normal .btn-image{
  width: 36rpx;
  height: 36rpx;
}

.template-grid .btn-hangup {
  background: #f75c45;
}

.template-grid .panel{
  position: absolute;
  background: rgba(0, 0, 0, 0.8);
  width: 90vw;
  height: auto;
  z-index: 999;
  top: 50vh;
  left: 50vw;
  transform: translate(-50%, -50%);
  color: white;
  display: flex;
  flex-direction: column;
  padding: 20rpx 0;
  border-radius: 10rpx;
  box-sizing: border-box;
  font-size: 24rpx;
}
.panel .close-btn {
  position: absolute;
  top: 0;
  right: 0;
  padding: 10rpx 20rpx;
}
.panel .panel-header{
  text-align: center;
  padding-bottom: 20rpx;
}
.panel .panel-tips {
  color: #999;
  text-align: center;
}
.panel .panel-body{
  flex: 1;
  max-height: 50vh;
}
.panel .panel-body .scroll-container{
  width: 100%;
  height: 100%;
  box-sizing: border-box;
}

.memberlist-panel .panel-body{
  height: 30vh;
  .audio-image {
  	padding: 0 12rpx;
  	width: 40rpx;
  	height: 40rpx;
  }
}
.memberlist-panel .member-item {
  display: flex;
  /* border-bottom: 1px solid #999; */
  margin: 16rpx 16rpx 16rpx 32rpx;
}
.memberlist-panel .member-id {
  width: 60%;
  font-size: 24rpx;
  line-height: 64rpx;
}
.memberlist-panel .member-btns{
  width: 70%;
  display: flex;
  justify-content: flex-end;
}
.memberlist-panel .member-btns .btn-normal{
  margin-left: 0;
}
.memberlist-panel .member-btns .btn{
  margin-right: 0;
}
 .sub-box{
  position: absolute;
  right: 10rpx;
  bottom: 24rpx;
  width: 80rpx;
  height: 172rpx;
  background-color: rgba(0,0,0,0.7);
  border-radius: 8rpx;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
	.audio-image {
		padding: 0 14rpx;
		width: 48rpx;
		height: 48rpx;
	}
}

.no-audio , .audio-volume{
  position: absolute;
  bottom: 20rpx;
  left: 20rpx;
  width: 36rpx;
  height: 36rpx;
	.image{
		width: 36rpx;
		height: 36rpx;
		position: absolute; /*android 的bug ,image absolute后會向上漂移幾個像素,如果要對其必須都設置absolute*/
	}
}

.audio-active {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 0;
  overflow: hidden;
}
.audio-active .image{
  bottom: 0;
}

.slide-up-tips {
  position: absolute;
  bottom: -100rpx;
  left: 50%;
  transform: translate(-50%, 0);
  width: 200rpx;
  height: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  font-size: 24rpx;
  color: #fff;
  background-color: rgba(0, 0, 0, 0.4);
  box-sizing: border-box;
  padding: 20rpx;
  border-radius: 10rpx;
  opacity: 0;
}
.slide-up-tips .image {
  width: 100rpx;
  height: 100rpx;
}
.player-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.player-placeholder .image {
  width: 100rpx;
  height: 100rpx;
}

.bottom-box {
	width: 100vw;
	height: 196rpx;
	background-color: rgba(0,0,0,0.7);
  
  .bottom-btns {
    z-index: 3;
	width: 100vw;
	height: 100%;
    display: flex;
    flex-direction: row;
	align-items: center;
    justify-content: space-around;
	.btn-hangup  {
	  width: 100rpx;
	  height: 100rpx;
	  background: #f75c45;
	  box-sizing: border-box;
	  display: flex;
	  justify-content: center;
	  align-items: center;
	  border-radius: 50%;
	}
  }
}
.btn-normal {
  width: 72rpx;
  height: 72rpx;
  box-sizing: border-box;
  display: flex;
  background: white;
  justify-content: center;
  align-items: center;
  border-radius: 50%;
}
.btn-hangup .btn-image,
.btn-normal .btn-image{
  width: 48rpx;
  height: 48rpx;
}
.swiper{
	position: absolute;
	top: 40%;
	width: 100vw;
	height: 48vh;
	padding: 0 12rpx;
	background-color: #F5F5F5;
	.swiper-item{
		position: relative;
		background-color: #F5F5F5;
		display: flex;
		flex-direction: row;
		// flex-wrap: wrap;
		height: 95% !important;
		.player-container {
			border-radius: 16rpx;
			position: relative;
			margin: 24rpx 12rpx 12rpx 12rpx;
			width: 45%;
			height: 93%;
		}
	}
}
</style>

到了這里,關(guān)于【多人會議功能】uniapp - 微信小程序 - 騰訊云的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務器費用

相關(guān)文章

  • uniapp微信小程序vue企業(yè)會議室預約系統(tǒng)python+python+nodejs+php

    uniapp微信小程序vue企業(yè)會議室預約系統(tǒng)python+python+nodejs+php

    該系統(tǒng)游客可以通過注冊成為注冊員工,之后就能夠?qū)h室、車輛信息瀏覽與預約。員工登錄后可以修改個人密碼,這個主要是微信端登錄的。服務端登錄管理員;管理員在登錄前選擇自己的角色,然后登錄該系統(tǒng)進行相應的操作。主要編輯上傳、會議室、會議室預約、車

    2024年04月29日
    瀏覽(23)
  • uniapp&&微信小程序中打開騰訊地圖獲取用戶位置信息

    uniapp&&微信小程序中打開騰訊地圖獲取用戶位置信息

    個人項目地址:?SubTopH前端開發(fā)個人站 (自己開發(fā)的前端功能和UI組件,一些有趣的小功能,感興趣的伙伴可以訪問,歡迎提出更好的想法,私信溝通,網(wǎng)站屬于靜態(tài)頁面) SubTopH前端開發(fā)個人站 https://subtop.gitee.io/subtoph.github.io/#/home 實現(xiàn)的效果 第一步:首先登錄微信公眾平

    2024年02月13日
    瀏覽(95)
  • 【uniapp】 微信小程序使用騰訊API地圖、路線軌跡、marker標記點

    【uniapp】 微信小程序使用騰訊API地圖、路線軌跡、marker標記點

    引入js import amap from \\\'@/common/qqmap-wx-jssdk.js\\\'; var qqmapsdk; qqmapsdk = new amap({ key: \\\'騰訊地圖API key\\\' // 必填 }); 小程序配置合法域名 :https://apis.map.qq.com 下載地址 :請前往【小程序地圖、騰訊API、商業(yè)圈、路線軌跡、地圖選點】 示例圖 請前往小程序查詢

    2024年02月16日
    瀏覽(107)
  • 【微信小程序支付功能】uniapp實現(xiàn)微信小程序支付功能

    【微信小程序支付功能】uniapp實現(xiàn)微信小程序支付功能

    場景 :要實現(xiàn)公司微信小程序的電商模塊微信支付功能 一.實現(xiàn)步驟和思路 在登錄狀態(tài),登錄的時候獲取到code,利用code獲取到 openid: https://blog.csdn.net/weixin_45308405/article/details/128868377?spm=1001.2014.3001.5501 在manifest.json文件“App模塊配置”項的“Payment(支付)”下,勾選“微信支付

    2024年02月11日
    瀏覽(104)
  • uniapp微信小程序使用分享功能

    uniapp微信小程序使用分享功能

    實現(xiàn)效果為如下所示的小程序分享功能: 本項目是一個使用uniapp搭建的微信小程序,上線后點擊右上角的…,發(fā)現(xiàn)其中的發(fā)送給朋友和分享到朋友圈是如下圖所示的灰色不能點擊: 那么,如何設置微信小程序的分享功能呢? 第一步:在onLoad方法中寫wx.showShareMenu方法,設置

    2024年02月11日
    瀏覽(96)
  • UNIAPP 微信小程序?qū)崿F(xiàn)分享功能

    UNIAPP 微信小程序?qū)崿F(xiàn)分享功能

    默認情況下點擊微信小程序調(diào)試器無法實現(xiàn)分享功能,如下圖 ?此時需要設置如下操作,個人默認習慣是在 utils文件下 創(chuàng)建 share.js 文件 并寫入代碼 內(nèi)容如下 然后打開main.js 修改如下 設置完成后再點擊右上角的分享就打開了 回到組件內(nèi) 如果需要通過按鈕實現(xiàn)分享功能? 參考

    2024年02月04日
    瀏覽(88)
  • uniapp微信小程序地圖功能實現(xiàn)教程

    本篇文章將介紹如何在uniapp中實現(xiàn)微信小程序的地圖功能,包括獲取appid和地圖授權(quán)的key,以及具體的功能實現(xiàn)步驟。

    2024年02月05日
    瀏覽(110)
  • uniapp 微信小程序?qū)Ш焦δ埽▎蝹€地址)

    uniapp 微信小程序?qū)Ш焦δ埽▎蝹€地址)

    獲取終點的坐標,根據(jù)終點的坐標,終點名稱,終點詳細地址,調(diào)起地圖導航到第三方APP 1、針對單個地址導航

    2024年02月12日
    瀏覽(27)
  • uniapp 微信小程序分享、分享朋友圈功能

    uniapp 微信小程序分享、分享朋友圈功能

    頁內(nèi)自定義分享按鈕 當頁面js上沒有添加事件“onShareAppMessage”,右上角‘…’不會出現(xiàn)“轉(zhuǎn)發(fā)”事件。 如果有事件,但是沒有定義事件內(nèi)容的話,轉(zhuǎn)發(fā)的卡片則是當前頁面的截屏信息。 官方文檔:https://uniapp.dcloud.io/api/plugins/share?id=onshareappmessage 方式1:小程序右上角原生菜

    2024年02月16日
    瀏覽(95)
  • uniapp 微信小程序?qū)С鰁xcel功能實現(xiàn)

    需要用到xlsx.core.min.js的js庫,以實現(xiàn)導出excel。 下載鏈接: SheetJS:?https://github.com/SheetJS/sheetjs 找到dist目錄下,xlsx.core.min.js文件,將它復制到你項目的/common/js/目錄下。 1、導入js庫; 2、編輯導出數(shù)據(jù)。 ?3、利用js庫導出excel。 這樣就可以了。

    2024年03月21日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包