[+] 拍照、录像控制

This commit is contained in:
acgist
2023-04-29 16:28:45 +08:00
parent 59df04faaf
commit 3cbbc8f936
9 changed files with 201 additions and 28 deletions

View File

@@ -6,11 +6,11 @@
<p class="title">{{ client?.name || "" }}</p>
<div class="buttons" :style="{'--volume': client?.volume}">
<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.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 @click="taoyao.mediaConsumerPause(videoConsumer.id)" v-show="videoConsumer && !videoConsumer.paused" type="danger" title="关闭摄像头" :icon="VideoPause" circle />
<el-button @click="taoyao.controlPhotograph(client.clientId)" title="拍照" :icon="Camera" circle />
<el-button @click="taoyao.controlRecord(client.clientId, (record = !record))" title="录像" :type="record ? 'danger' : ''" :icon="VideoCamera" circle />
<el-button title="媒体信息" :icon="InfoFilled" circle />
<el-button @click="roomExpel" title="踢出" :icon="CircleClose" circle />
</div>
@@ -48,6 +48,7 @@ export default {
return {
audio: null,
video: null,
record: false,
audioStream: null,
videoStream: null,
dataConsumer: null,

View File

@@ -5,12 +5,12 @@
<video ref="video"></video>
<p class="title">{{ client?.name || "" }}</p>
<div class="buttons">
<el-button @click="taoyao.mediaConsumerResume(audioConsumer.id)" v-show="stream" type="primary" title="打开麦克风" :icon="Microphone" circle />
<el-button @click="taoyao.mediaConsumerPause(audioConsumer.id)" v-show="stream" type="danger" title="关闭麦克风" :icon="Mute" circle />
<el-button @click="taoyao.mediaConsumerResume(videoConsumer.id)" v-show="stream" type="primary" title="打开摄像头" :icon="VideoPlay" circle />
<el-button @click="taoyao.mediaConsumerPause(videoConsumer.id)" v-show="stream" type="danger" title="关闭摄像头" :icon="VideoPause" circle />
<el-button title="拍照" :icon="Camera" circle />
<el-button title="录像" :icon="VideoCamera" circle />
<el-button @click="taoyao.sessionResume(client.id, 'audio')" v-show="audioStream && !client.remoteAudioEnabled" type="primary" title="打开麦克风" :icon="Microphone" circle />
<el-button @click="taoyao.sessionPause(client.id, 'audio')" v-show="audioStream && client.remoteAudioEnabled" type="danger" title="关闭麦克风" :icon="Mute" circle />
<el-button @click="taoyao.sessionResume(client.id, 'video')" v-show="videoStream && !client.remoteVideoEnabled" type="primary" title="打开摄像头" :icon="VideoPlay" circle />
<el-button @click="taoyao.sessionPause(client.id, 'video')" v-show="videoStream && client.remoteVideoEnabled" type="danger" title="关闭摄像头" :icon="VideoPause" circle />
<el-button @click="taoyao.controlPhotograph(client.clientId)" title="拍照" :icon="Camera" circle />
<el-button @click="taoyao.controlRecord(client.clientId, (record = !record))" title="录像" :type="record ? 'danger' : ''" :icon="VideoCamera" circle />
<el-button @click="close" title="踢出" :icon="CircleClose" circle />
</div>
</div>
@@ -47,7 +47,7 @@ export default {
return {
audio: null,
video: null,
stream: null,
record: false,
audioStream: null,
videoStream: null,
};

View File

@@ -177,6 +177,8 @@ const signalChannel = {
},
/**
* 重连
* TODO重连重建会话、房间
* TODO断开释放所有资源
*/
reconnect() {
const me = this;
@@ -245,12 +247,16 @@ class Session {
localStream;
// 本地音频
localAudioTrack;
localAudioEnabled;
// 本地视频
localVideoTrack;
localVideoEnabled;
// 远程音频
remoteAudioTrack;
remoteAudioEnabled;
// 远程视频
remoteVideoTrack;
remoteVideoEnabled;
// PeerConnection
peerConnection;
@@ -266,18 +272,56 @@ class Session {
this.sessionId = sessionId;
}
async pause() {
this.localAudioTrack.enabled = false;
this.localVideoTrack.enabled = false;
async pause(type) {
if(type === 'audio') {
this.localAudioEnabled = false;
this.localAudioTrack.enabled = false;
}
if(type === 'video') {
this.localVideoEnabled = false;
this.localVideoTrack.enabled = false;
}
}
async resume() {
this.localAudioTrack.enabled = true;
this.localVideoTrack.enabled = true;
async resume(type) {
if(type === 'audio') {
this.localAudioEnabled = true;
this.localAudioTrack.enabled = true;
}
if(type === 'video') {
this.localVideoEnabled = true;
this.localVideoTrack.enabled = true;
}
}
async pauseRemote(type) {
if(type === 'audio') {
this.remoteAudioEnabled = false;
this.remoteAudioTrack.enabled = false;
}
if(type === 'video') {
this.remoteVideoEnabled = false;
this.remoteVideoTrack.enabled = false;
}
}
async resumeRemote(type) {
if(type === 'audio') {
this.remoteAudioEnabled = true;
this.remoteAudioTrack.enabled = true;
}
if(type === 'video') {
this.remoteVideoEnabled = true;
this.remoteVideoTrack.enabled = true;
}
}
async close() {
this.closed = true;
this.localAudioEnabled = false;
this.localVideoEnabled = false;
this.remoteAudioEnabled = false;
this.remoteVideoEnabled = false;
this.localAudioTrack.stop();
this.localVideoTrack.stop();
this.remoteAudioTrack.stop();
@@ -830,6 +874,34 @@ class Taoyao extends RemoteClient {
console.info("关闭终端");
window.close();
}
/**
* 拍照
*
* @param {*} clientId
*/
controlPhotograph(clientId) {
const me = this;
me.push(
protocol.buildMessage("control::photograph", {
to: clientId
})
);
}
/**
* 录像
*
* @param {*} clientId
* @param {*} enabled
*/
controlRecord(clientId, enabled) {
const me = this;
me.push(
protocol.buildMessage("control::record", {
to: clientId,
enabled: enabled
})
);
}
/**
* 终端音量信令
*
@@ -2210,22 +2282,48 @@ class Taoyao extends RemoteClient {
} else {
}
}
async sessionPause(sessionId, type) {
const me = this;
const session = me.sessionClients.get(sessionId);
if(!session) {
return;
}
me.push(protocol.buildMessage("session::pause", {
type,
sessionId
}));
session.pauseRemote(type);
}
async defaultSessionPause(message) {
const me = this;
const { sessionId } = message.body;
const { type, sessionId } = message.body;
const session = me.sessionClients.get(sessionId);
if(session) {
session.pause();
session.pause(type);
} else {
}
}
async sessionResume(sessionId, type) {
const me = this;
const session = me.sessionClients.get(sessionId);
if(!session) {
return;
}
me.push(protocol.buildMessage("session::resume", {
type,
sessionId
}));
session.resumeRemote(type);
}
async defaultSessionResume(message) {
const me = this;
const { sessionId } = message.body;
const { type, sessionId } = message.body;
const session = me.sessionClients.get(sessionId);
if(session) {
session.resume();
session.resume(type);
}
}
@@ -2240,8 +2338,10 @@ class Taoyao extends RemoteClient {
const track = event.track;
if(track.kind === 'audio') {
session.remoteAudioTrack = track;
session.remoteAudioEnabled = true;
} else if(track.kind === 'video') {
session.remoteVideoTrack = track;
session.remoteVideoEnabled = true;
} else {
}
if(session.proxy && session.proxy.media) {
@@ -2268,7 +2368,9 @@ class Taoyao extends RemoteClient {
session.localStream = localStream;
session.peerConnection = peerConnection;
session.localAudioTrack = localStream.getAudioTracks()[0];
session.localAudioEnabled = true;
session.localVideoTrack = localStream.getVideoTracks()[0];
session.localVideoEnabled = true;
await session.peerConnection.addTrack(session.localAudioTrack, localStream);
await session.peerConnection.addTrack(session.localVideoTrack, localStream);
return peerConnection;