change camera

This commit is contained in:
zhangtao 2022-10-22 14:13:10 +08:00
parent d911a20419
commit b696b192ed
2 changed files with 44 additions and 24 deletions

View File

@ -13,7 +13,7 @@
<script> <script>
import TRTC from 'trtc-js-sdk' import TRTC from 'trtc-js-sdk'
import { reactive, toRefs, onMounted, defineComponent } from 'vue' import { defineComponent, reactive, toRefs, onMounted, onBeforeUnmount } from 'vue'
export default defineComponent({ export default defineComponent({
name: 'DeviceSelect', name: 'DeviceSelect',
props: { props: {
@ -26,7 +26,7 @@ export default defineComponent({
default: () => {} default: () => {}
} }
}, },
emits: ['update:value'], emits: ['update:value', 'switch'],
setup(props, { emit }) { setup(props, { emit }) {
const data = reactive({ const data = reactive({
deviceList: [], deviceList: [],
@ -35,10 +35,10 @@ export default defineComponent({
const getDeviceList = async() => { const getDeviceList = async() => {
switch (props.deviceType) { switch (props.deviceType) {
case 'camera': case 'video':
data.deviceList = await TRTC.getCameras() data.deviceList = await TRTC.getCameras()
break break
case 'microphone': case 'audio':
data.deviceList = await TRTC.getMicrophones() data.deviceList = await TRTC.getMicrophones()
break break
case 'speaker': case 'speaker':
@ -54,18 +54,21 @@ export default defineComponent({
const handleChange = (value) => { const handleChange = (value) => {
data.activeDeviceId = value data.activeDeviceId = value
emit('update:value', data.activeDeviceId) emit('update:value', data.activeDeviceId)
emit('switch', { type: props.deviceType, deviceId: data.activeDeviceId })
} }
const handleReverse = () => { const handleReverse = () => {
const index = data.deviceList.findIndex((item) => item.deviceId === data.activeDeviceId) const index = data.deviceList.findIndex((item) => item.deviceId === data.activeDeviceId)
if (data.deviceList.length === 1) { if (data.deviceList.length === 1) {
emit('update:value', data.activeDeviceId) return
} else if (index === data.deviceList.length - 1) { } else if (index === data.deviceList.length - 1) {
data.activeDeviceId = data.deviceList[index - 1].deviceId data.activeDeviceId = data.deviceList[index - 1].deviceId
emit('update:value', data.activeDeviceId) emit('update:value', data.activeDeviceId)
emit('switch', { type: props.deviceType, deviceId: data.activeDeviceId })
} else { } else {
data.activeDeviceId = data.deviceList[index + 1].deviceId data.activeDeviceId = data.deviceList[index + 1].deviceId
emit('update:value', data.activeDeviceId) emit('update:value', data.activeDeviceId)
emit('switch', { type: props.deviceType, deviceId: data.activeDeviceId })
} }
} }
@ -74,11 +77,11 @@ export default defineComponent({
.then(() => { .then(() => {
getDeviceList() getDeviceList()
}) })
// navigator.mediaDevices.addEventListener('devicechange', this.getDeviceList) navigator.mediaDevices.addEventListener('devicechange', getDeviceList)
})
onBeforeUnmount(() => {
navigator.mediaDevices.removeEventListener('devicechange', getDeviceList)
}) })
// beforeUnmount() {
// navigator.mediaDevices.removeEventListener('devicechange', this.getDeviceList)
// }
return { return {
...toRefs(data), ...toRefs(data),

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="room"> <div class="room">
<DeviceSelect ref="cameraRef" v-model:value="cameraId" device-type="camera" /> <DeviceSelect v-show="false" ref="cameraRef" v-model:value="cameraId" device-type="video" @switch="handleDeviceSwitch" />
<DeviceSelect v-show="false" v-model:value="microphoneId" device-type="microphone" /> <DeviceSelect v-show="false" v-model:value="microphoneId" device-type="audio" @switch="handleDeviceSwitch" />
<!-- 远端 --> <!-- 远端 -->
<div class="remote-container"> <div class="remote-container">
@ -53,7 +53,7 @@ import TRTC from 'trtc-js-sdk'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import DeviceSelect from './components/Device.vue' import DeviceSelect from './components/Device.vue'
import { ref, reactive, toRefs, onMounted, watch, nextTick } from 'vue' import { ref, reactive, toRefs, onMounted, watch, nextTick } from 'vue'
import { CameraOutline, CameraReverseOutline, VideocamOutline, VideocamOffOutline } from '@vicons/ionicons5' import { CameraReverseOutline, VideocamOutline, VideocamOffOutline } from '@vicons/ionicons5'
import { AudioOutlined, AudioMutedOutlined } from '@vicons/antd' import { AudioOutlined, AudioMutedOutlined } from '@vicons/antd'
import { isUndef } from '@/utils/is.js' import { isUndef } from '@/utils/is.js'
// import { Screen, ScreenOff } from '@vicons/carbon' // import { Screen, ScreenOff } from '@vicons/carbon'
@ -61,7 +61,6 @@ export default {
name: 'HomePage', name: 'HomePage',
components: { components: {
DeviceSelect, DeviceSelect,
CameraOutline,
CameraReverseOutline, CameraReverseOutline,
VideocamOutline, VideocamOutline,
VideocamOffOutline, VideocamOffOutline,
@ -72,6 +71,7 @@ export default {
const route = useRoute() const route = useRoute()
const cameraRef = ref() const cameraRef = ref()
const data = reactive({ const data = reactive({
hasInit: false,
client: null, client: null,
sdkAppId: 1400752641, sdkAppId: 1400752641,
sdkSecret: '9b5fc557f286d7e4d6eafd8023026da59f0674000f319754aa1ec4beefddcdd6', sdkSecret: '9b5fc557f286d7e4d6eafd8023026da59f0674000f319754aa1ec4beefddcdd6',
@ -204,37 +204,31 @@ export default {
/* 远端流更新 */ /* 远端流更新 */
data.client.on('stream-updated', (event) => { data.client.on('stream-updated', (event) => {
const { stream: remoteStream } = event const { stream: remoteStream } = event
alert('stream')
console.log(`type: ${remoteStream.getType()} stream-updated hasAudio: ${remoteStream.hasAudio()} hasVideo: ${remoteStream.hasVideo()}`) console.log(`type: ${remoteStream.getType()} stream-updated hasAudio: ${remoteStream.hasAudio()} hasVideo: ${remoteStream.hasVideo()}`)
}) })
/* 远端流禁用音频 */ /* 远端流禁用音频 */
data.client.on('mute-audio', (event) => { data.client.on('mute-audio', (event) => {
const { userId } = event const { userId } = event
alert('muteaudio')
console.log(`${userId} mute audio`) console.log(`${userId} mute audio`)
}) })
/* 远端流启用音频 */ /* 远端流启用音频 */
data.client.on('unmute-audio', (event) => { data.client.on('unmute-audio', (event) => {
const { userId } = event const { userId } = event
alert('unmuteaudio')
console.log(`${userId} unmute audio`) console.log(`${userId} unmute audio`)
}) })
/* 远端流禁用视频 */ /* 远端流禁用视频 */
data.client.on('mute-video', (event) => { data.client.on('mute-video', (event) => {
const { userId } = event const { userId } = event
alert('mutevideo')
console.log(`${userId} mute video`) console.log(`${userId} mute video`)
}) })
/* 远端流启用视频 */ /* 远端流启用视频 */
data.client.on('unmute-video', (event) => { data.client.on('unmute-video', (event) => {
const { userId } = event const { userId } = event
alert('unmutevideo')
console.log(`${userId} unmute video`) console.log(`${userId} unmute video`)
}) })
/* 本地 client 与腾讯云的连接状态变更 */ /* 本地 client 与腾讯云的连接状态变更 */
data.client.on('connection-state-changed', (event) => { data.client.on('connection-state-changed', (event) => {
alert('connection')
console.log(`RtcClient state changed to ${event.state} from ${event.prevState}`) console.log(`RtcClient state changed to ${event.state} from ${event.prevState}`)
}) })
@ -255,7 +249,6 @@ export default {
audio: isUndef(config.audio) ? true : config.audio, audio: isUndef(config.audio) ? true : config.audio,
video: isUndef(config.video) ? true : config.video video: isUndef(config.video) ? true : config.video
}) })
alert('subscribeStream')
} catch (error) { } catch (error) {
console.error(`subscribe ${remoteStream.getUserId()} with audio: ${config.audio} video: ${config.video} error`, error) console.error(`subscribe ${remoteStream.getUserId()} with audio: ${config.audio} video: ${config.video} error`, error)
} }
@ -268,7 +261,6 @@ export default {
const unsubscribeStream = async(remoteStream) => { const unsubscribeStream = async(remoteStream) => {
try { try {
await data.client.unsubscribe(remoteStream) await data.client.unsubscribe(remoteStream)
alert('unsubscribeStream')
} catch (error) { } catch (error) {
console.error(`unsubscribe ${remoteStream.getUserId()} error`, error) console.error(`unsubscribe ${remoteStream.getUserId()} error`, error)
} }
@ -312,7 +304,9 @@ export default {
* @return {*} * @return {*}
*/ */
const playLocalStream = async() => { const playLocalStream = async() => {
alert('playLocalStream') if (settings.localStream && settings.isPlayingLocalStream) {
settings.isPlayingLocalStream = false
}
settings.localStream.play('localStream') settings.localStream.play('localStream')
.then(() => { .then(() => {
settings.isPlayingLocalStream = true settings.isPlayingLocalStream = true
@ -425,6 +419,22 @@ export default {
data.client && data.client.enableAudioVolumeEvaluation(-1) data.client && data.client.enableAudioVolumeEvaluation(-1)
} }
/**
* @description: 切换音频
* @param {*} type
* @param {*} deviceId
* @return {*}
*/
const handleDeviceSwitch = ({ type, deviceId }) => {
try {
if (settings.localStream) {
settings.localStream.switchDevice(type, deviceId)
}
} catch (error) {
console.error('switchDevice failed', error)
}
}
/** /**
* @description: 退出直播间 * @description: 退出直播间
* @return {*} * @return {*}
@ -460,6 +470,12 @@ export default {
}) })
watch(() => [settings.cameraId, settings.microphoneId], async([cameraId, microphoneId]) => { watch(() => [settings.cameraId, settings.microphoneId], async([cameraId, microphoneId]) => {
if (cameraId && microphoneId) { if (cameraId && microphoneId) {
data.hasInit = true
}
})
watch(() => data.hasInit, async(val) => {
if (val) {
await createMeetingRoom() await createMeetingRoom()
await joinMeetingRoom() await joinMeetingRoom()
await initLocalStream() await initLocalStream()
@ -478,6 +494,7 @@ export default {
handleAudioMute, handleAudioMute,
handleAudioUnMute, handleAudioUnMute,
handelCameraReverse, handelCameraReverse,
handleDeviceSwitch,
leaveMeetingRoom leaveMeetingRoom
} }
} }
@ -491,9 +508,9 @@ export default {
position: relative; position: relative;
.local-stream-container{ .local-stream-container{
width: 100%; width: 100%;
height: 30%; height: 100%;
position: absolute; position: absolute;
top: 50px; top: 0;
.local-stream-content { .local-stream-content {
width: 100%; width: 100%;
height: 100%; height: 100%;