[*] 踢人 拉人 切换视频媒体

This commit is contained in:
acgist
2023-03-12 12:29:53 +08:00
parent 1bf8fbe415
commit ab8646a21f
39 changed files with 1779 additions and 352 deletions

View File

@@ -3,7 +3,7 @@
<div id="taoyao">
<!-- 信令 -->
<el-dialog center width="30%" title="终端设置" :show-close="false" v-model="signalVisible">
<el-form ref="SignalSetting" :model="config">
<el-form ref="SignalSetting">
<el-form-item label="终端标识">
<el-input v-model="config.clientId" placeholder="终端标识" />
</el-form-item>
@@ -29,7 +29,7 @@
</el-dialog>
<!-- 房间 -->
<el-dialog center width="30%" title="房间设置" :show-close="false" v-model="roomVisible" @open="loadList">
<el-form ref="RoomSetting" :model="room">
<el-form ref="RoomSetting">
<el-tabs v-model="roomActive">
<el-tab-pane label="进入房间" name="enter">
<el-form-item label="房间标识">
@@ -48,6 +48,13 @@
<el-input v-model="room.name" placeholder="房间名称" />
</el-form-item>
</el-tab-pane>
<el-tab-pane label="邀请终端" name="invite">
<el-form-item label="终端标识">
<el-select v-model="room.inviteClientId" placeholder="终端标识">
<el-option v-for="value in clients" :key="value.clientId" :label="value.name || value.clientId" :value="value.clientId" />
</el-select>
</el-form-item>
</el-tab-pane>
</el-tabs>
<el-form-item label="房间密码">
<el-input v-model="room.password" placeholder="房间密码" />
@@ -56,23 +63,24 @@
<template #footer>
<el-button type="primary" @click="roomEnter" v-if="roomActive === 'enter'">进入</el-button>
<el-button type="primary" @click="roomCreate" v-if="roomActive === 'create'">创建</el-button>
<el-button type="primary" @click="roomInvite" v-if="roomActive === 'invite'">邀请</el-button>
</template>
</el-dialog>
<!-- 菜单 -->
<div class="menus">
<el-button type="primary" :disabled="taoyao && taoyao.connect" @click="signalVisible = true">连接信令</el-button>
<el-button type="primary" :disabled="!taoyao" @click="roomActive = 'enter';roomVisible = true;">选择房间</el-button>
<el-button type="primary" :disabled="!taoyao" @click="roomActive = 'create';roomVisible = true;">创建房间</el-button>
<el-button :disabled="!taoyao || !room.roomId">邀请终端</el-button>
<el-button :disabled="!taoyao || !room.roomId">离开房间</el-button>
<el-button :disabled="!taoyao || !room.roomId" @click="roomClose()" type="danger">关闭房间</el-button>
<el-button @click="signalVisible = true" type="primary" :disabled="taoyao && taoyao.connect">连接信令</el-button>
<el-button @click="roomActive = 'enter'; roomVisible = true;" type="primary" :disabled="!taoyao">选择房间</el-button>
<el-button @click="roomActive = 'create'; roomVisible = true;" type="primary" :disabled="!taoyao">创建房间</el-button>
<el-button @click="roomActive = 'invite'; roomVisible = true;" :disabled="!taoyao || !taoyao.roomId">邀请终端</el-button>
<el-button @click="roomLeave" :disabled="!taoyao || !taoyao.roomId">离开房间</el-button>
<el-button @click="roomClose" :disabled="!taoyao || !taoyao.roomId" type="danger">关闭房间</el-button>
</div>
<!-- 终端 -->
<div class="clients">
<!-- 本地终端 -->
<LocalClient v-if="taoyao" ref="local-client" :client="taoyao" :taoyao="taoyao"></LocalClient>
<LocalClient v-if="taoyao && taoyao.roomId" ref="local-client" :client="taoyao" :taoyao="taoyao"></LocalClient>
<!-- 远程终端 -->
<RemoteClient v-for="(kv, index) in remoteClients" :key="index" :ref="'remote-client-' + kv[0]" :client="kv[1]" :taoyao="taoyao"></RemoteClient>
</div>
@@ -92,6 +100,7 @@ export default {
room: {},
rooms: null,
medias: null,
clients: null,
config: {
clientId: "taoyao",
name: "taoyao",
@@ -111,6 +120,8 @@ export default {
console.info(`
中庭地白树栖鸦,冷露无声湿桂花。
今夜月明人尽望,不知秋思落谁家。
:: https://gitee.com/acgist/taoyao
`);
},
methods: {
@@ -126,22 +137,27 @@ export default {
async loadList() {
this.rooms = await this.taoyao.roomList();
this.medias = await this.taoyao.mediaList();
this.clients = await this.taoyao.clientList();
},
async roomLeave() {
this.taoyao.roomLeave();
},
async roomClose() {
this.taoyao.roomClose();
},
async roomCreate() {
const room = await this.taoyao.roomCreate(this.room);
this.room.roomId = room.roomId;
await this.roomEnter();
},
async roomEnter() {
await this.taoyao.roomEnter(this.room.roomId, this.room.password);
await this.taoyao.produceMedia();
this.roomVisible = false;
},
audioVolume(message) {
async roomCreate() {
const room = await this.taoyao.roomCreate(this.room);
this.room.roomId = room.roomId;
await this.roomEnter();
},
async roomInvite() {
this.taoyao.roomInvite(this.room.inviteClientId);
this.roomVisible = false;
},
/**
* 信令回调
@@ -157,9 +173,6 @@ export default {
case "client::config":
me.roomVisible = true;
break;
case "media::audio::active::speaker":
me.audioVolume(message);
break;
case "platform::error":
if (error) {
console.error("发生异常:", message, error);

View File

@@ -5,11 +5,11 @@
<video ref="video"></video>
<p class="title">{{ client?.name || "" }}</p>
<div class="buttons" :style="{'--volume': client?.volume}">
<el-button v-show="!client.audioActive" type="primary" title="打开麦克风" :icon="Microphone" circle />
<el-button v-show="client.audioActive" type="danger" title="关闭麦克风" :icon="Mute" circle />
<el-button v-show="!client.videoActive" type="primary" title="打开摄像头" :icon="VideoPlay" circle />
<el-button v-show="client.videoActive" type="danger" title="关闭摄像头" :icon="VideoPause" circle />
<el-button title="交换媒体" :icon="Refresh" circle />
<el-button @click="taoyao.mediaProducerResume(audioProducer.id)" v-show="audioProducer && audioProducer.paused" type="primary" title="打开麦克风" :icon="Microphone" circle />
<el-button @click="taoyao.mediaProducerPause(audioProducer.id)" v-show="audioProducer && !audioProducer.paused" type="danger" title="关闭麦克风" :icon="Mute" circle />
<el-button @click="taoyao.mediaProducerResume(videoProducer.id)" v-show="videoProducer && videoProducer.paused" type="primary" title="打开摄像头" :icon="VideoPlay" circle />
<el-button @click="taoyao.mediaProducerPause(videoProducer.id)" v-show="videoProducer && !videoProducer.paused" type="danger" title="关闭摄像头" :icon="VideoPause" circle />
<el-button @click="exchangeVideoSource" title="交换媒体" :icon="Refresh" circle />
<el-button title="拍照" :icon="Camera" circle />
<el-button title="录像" :icon="VideoCamera" circle />
<el-button title="媒体信息" :icon="InfoFilled" circle />
@@ -104,15 +104,26 @@ export default {
}
},
methods: {
media(track) {
if (track.kind === "video") {
exchangeVideoSource() {
// TODO文件支持
this.taoyao.videoSource = this.taoyao.videoSource === "camera" ? "screen" : "camera";
this.taoyao.updateVideoProducer();
},
media(track, producer) {
if(track.kind === "audio") {
// 不用加载音频
this.audioProducer = producer;
} else if (track.kind === "video") {
this.videoProducer = producer;
if (this.videoStream) {
// TODO资源释放
} else {
this.videoStream = new MediaStream();
this.videoStream.addTrack(track);
this.video.srcObject = this.videoStream;
this.videoStream.getVideoTracks().forEach(oldTrack => {
console.debug("关闭旧的媒体:", oldTrack);
oldTrack.stop();
});
}
this.videoStream = new MediaStream();
this.videoStream.addTrack(track);
this.video.srcObject = this.videoStream;
this.video.play().catch((error) => console.warn("视频播放失败", error));
} else {
console.debug("本地不支持的媒体类型:", track);

View File

@@ -5,14 +5,14 @@
<video ref="video"></video>
<p class="title">{{ client?.name || "" }}</p>
<div class="buttons" :style="{'--volume': client?.volume}">
<el-button v-show="!client.audioActive" type="primary" title="打开麦克风" :icon="Microphone" circle />
<el-button v-show="client.audioActive" type="danger" title="关闭麦克风" :icon="Mute" circle />
<el-button v-show="!client.videoActive" type="primary" title="打开摄像头" :icon="VideoPlay" circle />
<el-button v-show="client.videoActive" type="danger" title="关闭摄像头" :icon="VideoPause" circle />
<el-button @click="taoyao.mediaConsumerResume(audioConsumer.id)" v-show="audioConsumer && audioConsumer.paused" type="primary" title="打开麦克风" :icon="Microphone" circle />
<el-button @click="taoyao.mediaConsumerPause(audioConsumer.id)" v-show="audioConsumer && !audioConsumer.paused" type="danger" title="关闭麦克风" :icon="Mute" circle />
<el-button @click="taoyao.mediaConsumerResume(videoConsumer.id)" v-show="videoConsumer && videoConsumer.paused" type="primary" title="打开摄像头" :icon="VideoPlay" circle />
<el-button @click="taoyao.mediaConsumerPause(videoConsumer.id)" v-show="videoConsumer && !videoConsumer.paused" type="danger" title="关闭摄像头" :icon="VideoPause" circle />
<el-button title="拍照" :icon="Camera" circle />
<el-button title="录像" :icon="VideoCamera" circle />
<el-button title="媒体信息" :icon="InfoFilled" circle />
<el-button title="踢出" :icon="CircleClose" circle />
<el-button @click="roomExpel" title="踢出" :icon="CircleClose" circle />
</div>
</div>
</template>
@@ -69,8 +69,12 @@ export default {
}
},
methods: {
roomExpel() {
this.taoyao.roomExpel(this.client.clientId);
},
media(track, consumer) {
if(track.kind === 'audio') {
this.audioConsumer = consumer;
if (this.audioStream) {
// TODO资源释放
} else {
@@ -80,6 +84,7 @@ export default {
}
this.audio.play().catch((error) => console.warn("视频播放失败", error));
} else if(track.kind === 'video') {
this.videoConsumer = consumer;
if (this.videoStream) {
// TODO资源释放
} else {

File diff suppressed because it is too large Load Diff