[*] 日常优化
This commit is contained in:
@@ -35,6 +35,7 @@
|
|||||||
* 码率等等参数配置验证
|
* 码率等等参数配置验证
|
||||||
* 查询消费者生产者信息
|
* 查询消费者生产者信息
|
||||||
* 存在TURN服务优先使用
|
* 存在TURN服务优先使用
|
||||||
|
* 安卓关闭视频没有删除预览
|
||||||
* 浏览器WebRTC监控页面关闭:`chrome://webrtc-internals/`
|
* 浏览器WebRTC监控页面关闭:`chrome://webrtc-internals/`
|
||||||
|
|
||||||
## 完成任务
|
## 完成任务
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
{
|
{
|
||||||
"name": "taoyao-client-media",
|
"name" : "taoyao-client-media",
|
||||||
"author": "acgist",
|
"author" : "acgist",
|
||||||
"version": "1.0.0",
|
"version" : "1.0.0",
|
||||||
"private": true,
|
"private" : true,
|
||||||
|
"license" : "Apache-2.0",
|
||||||
|
"homepage" : "https://gitee.com/acgist/taoyao",
|
||||||
"description": "taoyao client media",
|
"description": "taoyao client media",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "node src/Server.js",
|
"dev": "node src/Server.js",
|
||||||
"prd": "node src/Server.js"
|
"prd": "node src/Server.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ws": "^8.12.0",
|
"ws" : "^8.12.0",
|
||||||
"mediasoup": "^3.11.10"
|
"mediasoup": "^3.11.10"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,6 @@
|
|||||||
* [mediasoup-client文档](https://mediasoup.org/documentation/v3/mediasoup-client)
|
* [mediasoup-client文档](https://mediasoup.org/documentation/v3/mediasoup-client)
|
||||||
* [mediasoup-client接口](https://mediasoup.org/documentation/v3/mediasoup-client/api)
|
* [mediasoup-client接口](https://mediasoup.org/documentation/v3/mediasoup-client/api)
|
||||||
|
|
||||||
## 状态维护
|
## 终端列表
|
||||||
|
|
||||||
`Web`终端并未对整个终端列表以及状态进行维护,所以需要开发者自己实现。
|
`Web`终端并未对整个终端列表以及状态进行维护,所以需要开发者自己实现。
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
@@ -1,13 +1,16 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="zh-cn">
|
<html lang="zh-cn">
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
<head>
|
||||||
<link rel="icon" href="/favicon.ico" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<link rel="icon" href="./favicon.ico" />
|
||||||
<title>桃夭终端</title>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
</head>
|
<title>桃夭终端</title>
|
||||||
<body>
|
</head>
|
||||||
<div id="app"></div>
|
|
||||||
<script type="module" src="/src/main.js"></script>
|
<body>
|
||||||
</body>
|
<div id="app"></div>
|
||||||
</html>
|
<script type="module" src="./src/main.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -1,23 +1,25 @@
|
|||||||
{
|
{
|
||||||
"name": "taoyao-client-web",
|
"name" : "taoyao-client-web",
|
||||||
"author": "acgist",
|
"author" : "acgist",
|
||||||
"version": "1.0.0",
|
"version" : "1.0.0",
|
||||||
"private": true,
|
"private" : true,
|
||||||
|
"license" : "Apache-2.0",
|
||||||
|
"homepage" : "https://gitee.com/acgist/taoyao",
|
||||||
"description": "taoyao client web",
|
"description": "taoyao client web",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev" : "vite",
|
||||||
"build": "vite build",
|
"build" : "vite build",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"vue": "^3.2.44",
|
"vue" : "^3.2.44",
|
||||||
"moment": "^2.29.4",
|
"moment" : "^2.29.4",
|
||||||
"element-plus": "^2.2.32",
|
"element-plus" : "^2.2.32",
|
||||||
"mediasoup-client": "^3.6.82",
|
"mediasoup-client" : "^3.6.82",
|
||||||
"@element-plus/icons-vue": "^2.1.0"
|
"@element-plus/icons-vue": "^2.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"vite": "^4.0.0",
|
"vite" : "^4.0.0",
|
||||||
"@vitejs/plugin-vue": "^4.0.0"
|
"@vitejs/plugin-vue": "^4.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<!-- 桃夭 -->
|
<!-- 桃夭 -->
|
||||||
<template>
|
<template>
|
||||||
<div id="taoyao">
|
<div id="taoyao">
|
||||||
<!-- 信令 -->
|
<!-- 终端设置 -->
|
||||||
<el-dialog center width="30%" title="终端设置" :show-close="false" v-model="signalVisible">
|
<el-dialog center width="30%" title="终端设置" v-model="signalVisible" :show-close="false">
|
||||||
<el-form ref="SignalSetting">
|
<el-form ref="SignalSetting">
|
||||||
<el-form-item label="终端标识">
|
<el-form-item label="终端标识">
|
||||||
<el-input v-model="config.clientId" placeholder="终端标识" />
|
<el-input v-model="config.clientId" placeholder="终端标识" />
|
||||||
@@ -27,13 +27,14 @@
|
|||||||
<el-button type="primary" @click="connectSignal">连接信令</el-button>
|
<el-button type="primary" @click="connectSignal">连接信令</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<!-- 房间 -->
|
|
||||||
<el-dialog center width="30%" title="房间设置" :show-close="false" v-model="roomVisible" @open="loadList">
|
<!-- 房间设置 -->
|
||||||
|
<el-dialog center width="30%" title="房间设置" v-model="roomVisible" :show-close="false" @open="loadList">
|
||||||
<el-form ref="RoomSetting">
|
<el-form ref="RoomSetting">
|
||||||
<el-tabs v-model="roomActive">
|
<el-tabs v-model="roomActive">
|
||||||
<el-tab-pane label="监控终端" name="call">
|
<el-tab-pane label="监控终端" name="call">
|
||||||
<el-form-item label="终端标识">
|
<el-form-item label="终端标识">
|
||||||
<el-select v-model="room.callClientId" placeholder="终端标识">
|
<el-select v-model="room.callClientId" placeholder="监控终端标识">
|
||||||
<el-option v-for="value in clients" :key="value.clientId" :label="value.name || value.clientId" :value="value.clientId" />
|
<el-option v-for="value in clients" :key="value.clientId" :label="value.name || value.clientId" :value="value.clientId" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -50,14 +51,14 @@
|
|||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="选择房间" name="enter">
|
<el-tab-pane label="选择房间" name="enter">
|
||||||
<el-form-item label="房间标识">
|
<el-form-item label="房间标识">
|
||||||
<el-select v-model="room.roomId" placeholder="房间标识">
|
<el-select v-model="room.roomId" placeholder="进入房间标识">
|
||||||
<el-option v-for="value in rooms" :key="value.roomId" :label="value.name || value.roomId" :value="value.roomId" />
|
<el-option v-for="value in rooms" :key="value.roomId" :label="value.name || value.roomId" :value="value.roomId" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="邀请终端" name="invite">
|
<el-tab-pane label="邀请终端" name="invite">
|
||||||
<el-form-item label="终端标识">
|
<el-form-item label="终端标识">
|
||||||
<el-select v-model="room.inviteClientId" placeholder="终端标识">
|
<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-option v-for="value in clients" :key="value.clientId" :label="value.name || value.clientId" :value="value.clientId" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -77,7 +78,7 @@
|
|||||||
|
|
||||||
<!-- 菜单 -->
|
<!-- 菜单 -->
|
||||||
<div class="menus">
|
<div class="menus">
|
||||||
<el-button @click="signalVisible = true" :disabled="taoyao && taoyao.connect" type="primary">连接信令</el-button>
|
<el-button @click="signalVisible = true" :disabled="taoyao && taoyao.connect" type="primary">连接信令</el-button>
|
||||||
<el-button @click="roomActive = 'call'; roomVisible = true;" :disabled="!taoyao || !taoyao.connect" >监控终端</el-button>
|
<el-button @click="roomActive = 'call'; roomVisible = true;" :disabled="!taoyao || !taoyao.connect" >监控终端</el-button>
|
||||||
<el-button @click="roomActive = 'create'; roomVisible = true;" :disabled="!taoyao || !taoyao.connect" type="primary">创建房间</el-button>
|
<el-button @click="roomActive = 'create'; roomVisible = true;" :disabled="!taoyao || !taoyao.connect" type="primary">创建房间</el-button>
|
||||||
<el-button @click="roomActive = 'enter'; roomVisible = true;" :disabled="!taoyao || !taoyao.connect" type="primary">选择房间</el-button>
|
<el-button @click="roomActive = 'enter'; roomVisible = true;" :disabled="!taoyao || !taoyao.connect" type="primary">选择房间</el-button>
|
||||||
@@ -89,11 +90,11 @@
|
|||||||
<!-- 终端 -->
|
<!-- 终端 -->
|
||||||
<div class="clients">
|
<div class="clients">
|
||||||
<!-- 本地终端 -->
|
<!-- 本地终端 -->
|
||||||
<LocalClient v-if="taoyao && taoyao.roomId" 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 in remoteClients" :key="'remote-client-' + kv[0]" :ref="'remote-client-' + kv[0]" :client="kv[1]" :taoyao="taoyao"></RemoteClient>
|
<RemoteClient v-for="kv in remoteClients" :key="'remote-client-' + kv[0]" :ref="'remote-client-' + kv[0]" :client="kv[1]" :taoyao="taoyao"></RemoteClient>
|
||||||
<!-- 远程会话 -->
|
<!-- 远程会话 -->
|
||||||
<SessionClient v-for="kv in sessionClients" :key="'session-client-' + kv[0]" :ref="'session-client-' + kv[0]" :client="kv[1]" :taoyao="taoyao"></SessionClient>
|
<SessionClient v-for="kv in sessionClients" :key="'session-client-' + kv[0]" :ref="'session-client-' + kv[0]" :client="kv[1]" :taoyao="taoyao"></SessionClient>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -109,23 +110,42 @@ export default {
|
|||||||
name: "Taoyao",
|
name: "Taoyao",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
room: {},
|
room: {
|
||||||
rooms: null,
|
// 房间ID
|
||||||
medias: null,
|
roomId : null,
|
||||||
|
// 房间名称
|
||||||
|
name : null,
|
||||||
|
// 房间密码
|
||||||
|
password : null,
|
||||||
|
// 监控终端ID
|
||||||
|
callClientId : null,
|
||||||
|
// 媒体终端ID
|
||||||
|
mediaClientId : null,
|
||||||
|
// 邀请终端ID
|
||||||
|
inviteClientId: null,
|
||||||
|
},
|
||||||
|
// 房间列表
|
||||||
|
rooms : null,
|
||||||
|
// 媒体服务列表
|
||||||
|
medias : null,
|
||||||
|
// 终端列表
|
||||||
clients: null,
|
clients: null,
|
||||||
config: {
|
config: {
|
||||||
clientId: "taoyao",
|
clientId: "taoyao",
|
||||||
name: "taoyao",
|
name : "taoyao",
|
||||||
host: "localhost",
|
host : "localhost",
|
||||||
port: 8888,
|
port : 8888,
|
||||||
username: "taoyao",
|
username: "taoyao",
|
||||||
password: "taoyao",
|
password: "taoyao",
|
||||||
},
|
},
|
||||||
taoyao: null,
|
// 信令
|
||||||
roomActive: "call",
|
taoyao : null,
|
||||||
roomVisible: false,
|
roomActive : "call",
|
||||||
signalVisible: false,
|
roomVisible : false,
|
||||||
remoteClients: new Map(),
|
signalVisible : false,
|
||||||
|
// 会议终端
|
||||||
|
remoteClients : new Map(),
|
||||||
|
// 监控终端
|
||||||
sessionClients: new Map(),
|
sessionClients: new Map(),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -139,26 +159,19 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async connectSignal() {
|
async connectSignal() {
|
||||||
const me = this;
|
this.taoyao = new Taoyao({ ...this.config });
|
||||||
me.taoyao = new Taoyao({ ...this.config });
|
await this.taoyao.connectSignal(this.callback);
|
||||||
await me.taoyao.connectSignal(me.callback);
|
this.signalVisible = false;
|
||||||
me.signalVisible = false;
|
this.remoteClients = this.taoyao.remoteClients;
|
||||||
me.remoteClients = me.taoyao.remoteClients;
|
this.sessionClients = this.taoyao.sessionClients;
|
||||||
me.sessionClients = me.taoyao.sessionClients;
|
|
||||||
// 全局绑定
|
// 全局绑定
|
||||||
window.taoyao = me.taoyao;
|
window.taoyao = this.taoyao;
|
||||||
},
|
},
|
||||||
async loadList() {
|
async loadList() {
|
||||||
this.rooms = await this.taoyao.roomList();
|
this.rooms = await this.taoyao.roomList();
|
||||||
this.medias = await this.taoyao.mediaList();
|
this.medias = await this.taoyao.mediaList();
|
||||||
this.clients = await this.taoyao.clientList();
|
this.clients = await this.taoyao.clientList();
|
||||||
},
|
},
|
||||||
async roomLeave() {
|
|
||||||
this.taoyao.roomLeave();
|
|
||||||
},
|
|
||||||
async roomClose() {
|
|
||||||
this.taoyao.roomClose();
|
|
||||||
},
|
|
||||||
async sessionCall() {
|
async sessionCall() {
|
||||||
this.taoyao.sessionCall(this.room.callClientId);
|
this.taoyao.sessionCall(this.room.callClientId);
|
||||||
this.roomVisible = false;
|
this.roomVisible = false;
|
||||||
@@ -169,7 +182,11 @@ export default {
|
|||||||
await this.roomEnter();
|
await this.roomEnter();
|
||||||
},
|
},
|
||||||
async roomEnter() {
|
async roomEnter() {
|
||||||
await this.taoyao.roomEnter(this.room.roomId, this.room.password);
|
const response = await this.taoyao.roomEnter(this.room.roomId, this.room.password);
|
||||||
|
const { code, message } = response;
|
||||||
|
if(code !== '0000') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
await this.taoyao.mediaProduce();
|
await this.taoyao.mediaProduce();
|
||||||
this.roomVisible = false;
|
this.roomVisible = false;
|
||||||
},
|
},
|
||||||
@@ -177,29 +194,33 @@ export default {
|
|||||||
this.taoyao.roomInvite(this.room.inviteClientId);
|
this.taoyao.roomInvite(this.room.inviteClientId);
|
||||||
this.roomVisible = false;
|
this.roomVisible = false;
|
||||||
},
|
},
|
||||||
|
async roomLeave() {
|
||||||
|
this.taoyao.roomLeave();
|
||||||
|
},
|
||||||
|
async roomClose() {
|
||||||
|
this.taoyao.roomClose();
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* 信令回调
|
* 信令回调
|
||||||
*
|
*
|
||||||
* @param {*} message 消息
|
* @param {*} response 回调
|
||||||
* @param {*} error 异常
|
* @param {*} error 异常
|
||||||
*
|
*
|
||||||
* @return 是否继续执行
|
* @return 是否继续执行
|
||||||
*/
|
*/
|
||||||
async callback(message, error) {
|
async callback(response, error) {
|
||||||
const me = this;
|
const me = this;
|
||||||
switch (message.header.signal) {
|
const { code, message, header, body } = response;
|
||||||
|
const { signal } = header;
|
||||||
|
switch (signal) {
|
||||||
case "client::config":
|
case "client::config":
|
||||||
me.roomVisible = true;
|
me.roomVisible = true;
|
||||||
break;
|
break;
|
||||||
case "platform::error":
|
case "platform::error":
|
||||||
if (error) {
|
console.error(`发生${error ? "异常" : "错误"}`, response, error);
|
||||||
console.error("发生异常:", message, error);
|
|
||||||
} else {
|
|
||||||
console.warn("发生错误:", message);
|
|
||||||
}
|
|
||||||
ElMessage({
|
ElMessage({
|
||||||
type: "error",
|
type : "error",
|
||||||
message: message.message,
|
message: message,
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,4 +59,4 @@ body {
|
|||||||
text-rendering: optimizeLegibility;
|
text-rendering: optimizeLegibility;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -32,4 +32,4 @@ a,
|
|||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 1fr 1fr;
|
||||||
padding: 0 2rem;
|
padding: 0 2rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1611,15 +1611,15 @@ class Taoyao extends RemoteClient {
|
|||||||
}
|
}
|
||||||
// TODO:已经进入房间忽略
|
// TODO:已经进入房间忽略
|
||||||
me.roomId = roomId;
|
me.roomId = roomId;
|
||||||
const response = await me.request(
|
let response = await me.request(
|
||||||
protocol.buildMessage("media::router::rtp::capabilities", {
|
protocol.buildMessage("media::router::rtp::capabilities", {
|
||||||
roomId: me.roomId,
|
roomId: me.roomId,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
if(response.code !== '0000') {
|
if(response.code !== '0000') {
|
||||||
// TODO:提示
|
|
||||||
me.roomId = null;
|
me.roomId = null;
|
||||||
return;
|
this.callbackError(response.message);
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
const routerRtpCapabilities = response.body.rtpCapabilities;
|
const routerRtpCapabilities = response.body.rtpCapabilities;
|
||||||
me.mediasoupDevice = new mediasoupClient.Device();
|
me.mediasoupDevice = new mediasoupClient.Device();
|
||||||
@@ -1632,7 +1632,7 @@ class Taoyao extends RemoteClient {
|
|||||||
// mediasoupClient.parseScalabilityMode(undefined);
|
// mediasoupClient.parseScalabilityMode(undefined);
|
||||||
// // => { spatialLayers: 1, temporalLayers: 1 }
|
// // => { spatialLayers: 1, temporalLayers: 1 }
|
||||||
await me.mediasoupDevice.load({ routerRtpCapabilities });
|
await me.mediasoupDevice.load({ routerRtpCapabilities });
|
||||||
await me.request(
|
response = await me.request(
|
||||||
protocol.buildMessage("room::enter", {
|
protocol.buildMessage("room::enter", {
|
||||||
roomId: roomId,
|
roomId: roomId,
|
||||||
password: password,
|
password: password,
|
||||||
@@ -1640,6 +1640,12 @@ class Taoyao extends RemoteClient {
|
|||||||
sctpCapabilities: me.dataConsume || me.dataProduce ? me.mediasoupDevice.sctpCapabilities : undefined,
|
sctpCapabilities: me.dataConsume || me.dataProduce ? me.mediasoupDevice.sctpCapabilities : undefined,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
if(response.code !== '0000') {
|
||||||
|
me.roomId = null;
|
||||||
|
this.callbackError(response.message);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 进入房间信令
|
* 进入房间信令
|
||||||
|
|||||||
Reference in New Issue
Block a user