[*] 每日优化
This commit is contained in:
22
README.md
22
README.md
@@ -79,28 +79,6 @@ acgist/taoyao-signal-server
|
|||||||
|
|
||||||
[部署文档](./docs/Deploy.md)
|
[部署文档](./docs/Deploy.md)
|
||||||
|
|
||||||
### 集群
|
|
||||||
|
|
||||||
信令服务支持下挂多个媒体服务,但是信令服务本身不具备分布式集群功能,如需实现给出以下两种实现建议:
|
|
||||||
|
|
||||||
#### 信令分区
|
|
||||||
|
|
||||||
将信令服务进行分区管理,分区不要直接管理终端,优先选择分区,然后选择信令服务。
|
|
||||||
|
|
||||||
#### 代理终端
|
|
||||||
|
|
||||||
将下级信令服务的终端全部使用代理终端注册到上级信令服务,上级信令服务代理终端处理信令时直接路由到下级路由服务,这样一级一级路由直到发送给真正的终端为止。
|
|
||||||
|
|
||||||
## 重连
|
|
||||||
|
|
||||||
### 信令重连
|
|
||||||
|
|
||||||
所有终端信令默认支持重连
|
|
||||||
|
|
||||||
### 媒体重连
|
|
||||||
|
|
||||||
信令没有断开媒体重连依赖具体协议支持,如果信令断开默认关闭所有媒体,信令重连以后需要自己实现媒体重连(控制方主动邀请或者重连方主动进入)。
|
|
||||||
|
|
||||||
## 终端预览
|
## 终端预览
|
||||||
|
|
||||||

|

|
||||||
|
|||||||
112
docs/Design.md
Normal file
112
docs/Design.md
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
# 整体设计
|
||||||
|
|
||||||
|
## 设计
|
||||||
|
|
||||||
|
项目当前采用方案:
|
||||||
|
|
||||||
|
* 监控(WebRTC)
|
||||||
|
* 会议(Mediasoup独立Router)
|
||||||
|
|
||||||
|
### 监控(WebRTC)
|
||||||
|
|
||||||
|
使用原始`WebRTC`实现,监控和被监控终端使用`P2P`连接。
|
||||||
|
|
||||||
|
#### 优点
|
||||||
|
|
||||||
|
* 实现逻辑简单
|
||||||
|
* `P2P`媒体直连,服务端没有压力。
|
||||||
|
|
||||||
|
#### 缺点
|
||||||
|
|
||||||
|
* 终端上行流量较大(同时被多个终端监控时)
|
||||||
|
|
||||||
|
### 监控(Mediasoup独立Router)
|
||||||
|
|
||||||
|
使用`Mediasoup`实现,所有终端进入一个`Router`,通过`Mediasoup`转发媒体实现监控。
|
||||||
|
|
||||||
|
#### 优点
|
||||||
|
|
||||||
|
* 终端只会存在一路上行流量
|
||||||
|
|
||||||
|
#### 缺点
|
||||||
|
|
||||||
|
* 单个`Router`压力较大(监控终端数量较多时)
|
||||||
|
|
||||||
|
### 监控(Mediasoup代理Router)
|
||||||
|
|
||||||
|
使用`Mediasoup`实现,每个终端对应一个代理`Router`,通过`PipeTransport`转发代理`Router`媒体实现监控。
|
||||||
|
|
||||||
|
#### 优点
|
||||||
|
|
||||||
|
* 终端只会存在一路上行流量
|
||||||
|
* 压力不会集中某个`Router`
|
||||||
|
|
||||||
|
#### 缺点
|
||||||
|
|
||||||
|
* 实现逻辑复杂
|
||||||
|
* 服务端压力较大(媒体通道生产者消费者数量增加)
|
||||||
|
|
||||||
|
### 会议(Mediasoup独立Router)
|
||||||
|
|
||||||
|
使用`Mediasoup`实现,每个会议对应一个`Router`,`Router`内部媒体直接转发实现会议。
|
||||||
|
|
||||||
|
#### 优点
|
||||||
|
|
||||||
|
* 实现逻辑清晰
|
||||||
|
|
||||||
|
#### 缺点
|
||||||
|
|
||||||
|
* 单个终端进入多个会议上行流量较大
|
||||||
|
|
||||||
|
### 会议(Mediasoup代理Router)
|
||||||
|
|
||||||
|
会议使用`Mediasoup`实现,每个终端对应一个代理`Router`,通过`PipeTransport`转发代理`Router`媒体实现会议。
|
||||||
|
|
||||||
|
#### 优点
|
||||||
|
|
||||||
|
* 终端只会存在一路上行流量
|
||||||
|
|
||||||
|
#### 缺点
|
||||||
|
|
||||||
|
* 实现逻辑复杂
|
||||||
|
* 服务端压力较大(媒体通道生产者消费者数量增加)
|
||||||
|
|
||||||
|
## 子网媒体转发
|
||||||
|
|
||||||
|
多个子网不能互通时解决方案
|
||||||
|
|
||||||
|
### 监控
|
||||||
|
|
||||||
|
如果只有两个子网可以直接通过`TURN`服务实现,如果超过两个子网需要`TURN`服务和防火墙自动转发实现。
|
||||||
|
|
||||||
|
### 会议
|
||||||
|
|
||||||
|
#### 实现多级平台
|
||||||
|
|
||||||
|
实现多级平台的代理终端功能,最后通过`PipeTransport`转发媒体。
|
||||||
|
|
||||||
|
#### 地址重写和防火墙自动转发(当前采用)
|
||||||
|
|
||||||
|
如果只有两个子网可以通过双网卡服务器直接通过`IP`地址重写实现,如果超过两个子网可以通过`IP`地址重写和防火墙自动转发实现,参考方案(拓扑网络)[./NetworkTopology.md]
|
||||||
|
|
||||||
|
## 多级平台
|
||||||
|
|
||||||
|
信令服务支持下挂多个媒体服务,但是信令服务本身不具备分布式集群功能,如需实现给出以下两种实现建议:
|
||||||
|
|
||||||
|
### 信令分区
|
||||||
|
|
||||||
|
将信令服务进行分区管理,分区不要直接管理终端,优先选择分区,然后选择信令服务。
|
||||||
|
|
||||||
|
### 代理终端
|
||||||
|
|
||||||
|
将下级信令服务的终端全部使用代理终端注册到上级信令服务,上级信令服务代理终端处理信令时直接路由到下级路由服务,这样一级一级路由直到发送给真正的终端为止。
|
||||||
|
|
||||||
|
## 重连
|
||||||
|
|
||||||
|
### 信令重连
|
||||||
|
|
||||||
|
所有终端信令默认支持重连
|
||||||
|
|
||||||
|
### 媒体重连
|
||||||
|
|
||||||
|
信令没有断开媒体重连依赖具体协议支持,如果信令断开默认关闭所有媒体,信令重连以后需要自己实现媒体重连(控制方主动邀请或者重连方主动进入)。
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# 拓扑网络
|
# 拓扑网络
|
||||||
|
|
||||||
多子网环境下的部署配置
|
多子网环境下的部署配置,当前设计只在顶层子网部署服务,每层子网采用双网卡服务器通过防火墙自动转发实现。
|
||||||
|
|
||||||
## 两个子网
|
## 两个子网
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,17 @@
|
|||||||
* [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)
|
||||||
|
|
||||||
|
## 终端媒体
|
||||||
|
|
||||||
|
终端页面组件需要提供`media`方法,同时挂载到终端的`proxy`属性下面。
|
||||||
|
媒体生成以后自动调用:
|
||||||
|
|
||||||
|
```
|
||||||
|
LocalClient.proxy.media(track, producer);
|
||||||
|
RemoteClient.proxy.media(track, consumer);
|
||||||
|
SessionClient.proxy.media(track);
|
||||||
|
```
|
||||||
|
|
||||||
## 终端列表
|
## 终端列表
|
||||||
|
|
||||||
`Web`终端并未对整个终端列表以及状态进行维护,所以需要开发者自己实现。
|
`Web`终端并未对整个终端列表以及状态进行维护,所以需要开发者自己实现。
|
||||||
|
|||||||
@@ -92,7 +92,7 @@
|
|||||||
<!-- 本地终端 -->
|
<!-- 本地终端 -->
|
||||||
<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>
|
||||||
@@ -206,7 +206,7 @@ export default {
|
|||||||
* @param {*} response 回调
|
* @param {*} response 回调
|
||||||
* @param {*} error 异常
|
* @param {*} error 异常
|
||||||
*
|
*
|
||||||
* @return 是否继续执行
|
* @return 是否执行完成
|
||||||
*/
|
*/
|
||||||
async callback(response, error) {
|
async callback(response, error) {
|
||||||
const me = this;
|
const me = this;
|
||||||
|
|||||||
@@ -1,88 +1,147 @@
|
|||||||
|
/**
|
||||||
|
* 配置:{ min: 8000, exact: 32000, ideal: 32000, max: 48000 }
|
||||||
|
*/
|
||||||
/**
|
/**
|
||||||
* 音频默认配置
|
* 音频默认配置
|
||||||
* TODO:MediaStreamTrack.applyConstraints().then().catch();
|
*
|
||||||
* const setting = {
|
|
||||||
* autoGainControl: true,
|
|
||||||
* noiseSuppression: true
|
|
||||||
* }
|
|
||||||
await track.applyConstraints(Object.assign(track.getSettings(), setting));
|
|
||||||
* TODO:播放音量(audio标签配置)、采集音量
|
|
||||||
* 支持属性:navigator.mediaDevices.getSupportedConstraints()
|
|
||||||
* https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSettings
|
* https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSettings
|
||||||
*/
|
*/
|
||||||
const defaultAudioConfig = {
|
const defaultAudioConfig = {
|
||||||
// 设备
|
// 指定设备
|
||||||
// deviceId : '',
|
// deviceId : '',
|
||||||
|
// 标识会话
|
||||||
|
// groupId : '',
|
||||||
// 音量(废弃):0.0~1.0
|
// 音量(废弃):0.0~1.0
|
||||||
// volume: 1.0,
|
// volume : 1.0,
|
||||||
// 延迟时间(单位:秒):500毫秒以内较好
|
// 延迟时间(单位:秒):500毫秒以内较好
|
||||||
// latency: 0.4,
|
// latency : 0.4,
|
||||||
// 采样位数:8|16|32
|
// 采样位数:8|16|32
|
||||||
sampleSize: { min: 8, ideal: 16, max: 32 },
|
sampleSize : { min: 8, ideal: 16, max: 32 },
|
||||||
// 采样率:8000|16000|32000|48000
|
// 采样率:8000|16000|32000|48000
|
||||||
sampleRate: { min: 8000, ideal: 32000, max: 48000 },
|
sampleRate : { min: 8000, ideal: 32000, max: 48000 },
|
||||||
// 声道数量:1|2
|
// 声道数量:1|2
|
||||||
channelCount: 1,
|
channelCount : 1,
|
||||||
// 是否开启自动增益:true|false
|
// 是否开启自动增益:true|false
|
||||||
autoGainControl: true,
|
autoGainControl : true,
|
||||||
// 是否开启降噪功能:true|false
|
// 是否开启降噪功能:true|false
|
||||||
noiseSuppression: true,
|
noiseSuppression: true,
|
||||||
// 是否开启回音消除:true|false
|
// 是否开启回音消除:true|false
|
||||||
echoCancellation: true,
|
echoCancellation: true,
|
||||||
// 消除回音方式:system|browser
|
|
||||||
echoCancellationType: "system",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 视频默认配置
|
* 视频默认配置
|
||||||
|
*
|
||||||
|
* https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSettings
|
||||||
*/
|
*/
|
||||||
const defaultVideoConfig = {
|
const defaultVideoConfig = {
|
||||||
// 设备
|
// 指定设备
|
||||||
// deviceId: '',
|
// deviceId : '',
|
||||||
|
// 标识会话
|
||||||
|
// groupId : '',
|
||||||
// 宽度
|
// 宽度
|
||||||
width: { min: 720, ideal: 1280, max: 4096 },
|
width : { min: 720, ideal: 1280, max: 4096 },
|
||||||
// 高度
|
// 高度
|
||||||
height: { min: 480, ideal: 720, max: 2160 },
|
height : { min: 480, ideal: 720, max: 2160 },
|
||||||
// 帧率
|
// 帧率
|
||||||
frameRate: { min: 15, ideal: 24, max: 45 },
|
frameRate : { min: 15, ideal: 24, max: 45 },
|
||||||
// 选摄像头:user|left|right|environment
|
// 摄像头:user|left|right|environment
|
||||||
facingMode: "environment",
|
facingMode : "environment",
|
||||||
|
// 裁剪
|
||||||
|
// resizeMode : null,
|
||||||
|
// 宽高比
|
||||||
|
// aspectRatio: 1.7777777778,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* VP9默认配置
|
* 共享屏幕默认配置
|
||||||
|
*
|
||||||
|
* https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSettings
|
||||||
*/
|
*/
|
||||||
const defaultKsvcEncodings = [{ scalabilityMode: "S3T3_KEY" }];
|
const defaultShareScreenConfig = {
|
||||||
|
// 显示鼠标:always|motion|never
|
||||||
|
cursor : "always",
|
||||||
|
// 逻辑窗口捕获(没有完全显示)
|
||||||
|
logicalSurface: true,
|
||||||
|
// 视频来源:window|monitor|browser|application
|
||||||
|
displaySurface: "monitor",
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* simulcast默认配置
|
* SVC默认配置
|
||||||
* TODO:update
|
* 支持编码:VP9
|
||||||
* https://gitee.com/acgist/mediasoup-demo/commit/090c82920d1b8015d457e4fafbb06607cb232885
|
*
|
||||||
* https://gitee.com/acgist/mediasoup-demo/commit/e4f70da0c69226b997d174c477d82f8dbb997e91
|
* https://w3c.github.io/webrtc-svc/
|
||||||
* https://gitee.com/acgist/mediasoup-demo/commit/2c67601d0a231bf901242c8e14cdd0d1ba39f3a4
|
* https://mediasoup.org/documentation/v3/mediasoup/rtp-parameters-and-capabilities/
|
||||||
* https://gitee.com/acgist/mediasoup-demo/commit/b9f3f28d2eab314b95392fa698d518177d5ad767
|
* https://mediasoup.org/documentation/v3/mediasoup/rtp-parameters-and-capabilities/#SVC
|
||||||
* https://gitee.com/acgist/mediasoup-demo/commit/1c59132ca926a6f9ca0c5c2bb155fac58eed9b06
|
*/
|
||||||
* https://gitee.com/acgist/mediasoup-demo/commit/d15a859306e1ba5d031cde90d02593e095719cbc
|
const defaultSvcEncodings = [
|
||||||
* https://gitee.com/acgist/mediasoup-demo/commit/13cf71cc608690ff96ec12e6d3f1262b40c4d8f3
|
{
|
||||||
|
dtx : true,
|
||||||
|
maxBitrate : 5000000,
|
||||||
|
scalabilityMode: 'L3T3_KEY'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simulcast默认配置
|
||||||
|
* 支持编码:VP8 H264
|
||||||
|
* 可以根据数量减少配置数量
|
||||||
|
* dtx:屏幕贡献开启效果显著
|
||||||
|
*
|
||||||
|
* https://w3c.github.io/webrtc-svc/
|
||||||
|
* https://mediasoup.org/documentation/v3/mediasoup/rtp-parameters-and-capabilities/
|
||||||
|
* https://mediasoup.org/documentation/v3/mediasoup/rtp-parameters-and-capabilities/#Simulcast
|
||||||
*/
|
*/
|
||||||
const defaultSimulcastEncodings = [
|
const defaultSimulcastEncodings = [
|
||||||
{ scaleResolutionDownBy: 4, maxBitrate: 500000, scalabilityMode: "S1T2" },
|
{
|
||||||
{ scaleResolutionDownBy: 2, maxBitrate: 1000000, scalabilityMode: "S1T2" },
|
dtx : true,
|
||||||
{ scaleResolutionDownBy: 1, maxBitrate: 5000000, scalabilityMode: "S1T2" },
|
maxBitrate : 5000000,
|
||||||
|
scalabilityMode : 'L1T3',
|
||||||
|
scaleResolutionDownBy: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dtx : true,
|
||||||
|
maxBitrate : 1000000,
|
||||||
|
scalabilityMode : 'L1T3',
|
||||||
|
scaleResolutionDownBy: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dtx : true,
|
||||||
|
maxBitrate : 500000,
|
||||||
|
scalabilityMode : 'L1T3',
|
||||||
|
scaleResolutionDownBy: 4,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RTCPeerConnection默认配置
|
* RTCPeerConnection默认配置
|
||||||
|
*
|
||||||
|
* https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection
|
||||||
*/
|
*/
|
||||||
const defaultRTCPeerConnectionConfig = {
|
const defaultRTCPeerConnectionConfig = {
|
||||||
// ICE代理的服务器
|
// ICE代理服务器
|
||||||
iceServers: [],
|
iceServers : [
|
||||||
|
{
|
||||||
|
// { "url": "stun:stun1.l.google.com:19302" },
|
||||||
|
urls: [
|
||||||
|
"stun:stun1.l.google.com:19302",
|
||||||
|
"stun:stun2.l.google.com:19302",
|
||||||
|
"stun:stun3.l.google.com:19302",
|
||||||
|
"stun:stun4.l.google.com:19302"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
// 目标对等身份
|
||||||
|
// peerIdentity : null,
|
||||||
// 传输通道绑定策略:balanced|max-compat|max-bundle
|
// 传输通道绑定策略:balanced|max-compat|max-bundle
|
||||||
bundlePolicy: "balanced",
|
bundlePolicy : "balanced",
|
||||||
// RTCP多路复用策略:require|negotiate
|
// RTCP多路复用策略:require|negotiate
|
||||||
rtcpMuxPolicy: "require",
|
rtcpMuxPolicy : "require",
|
||||||
|
// 连接证书
|
||||||
|
// certificates : null,
|
||||||
// ICE传输策略:all|relay
|
// ICE传输策略:all|relay
|
||||||
iceTransportPolicy: "all",
|
iceTransportPolicy : "all",
|
||||||
// ICE候选个数
|
// ICE候选个数
|
||||||
iceCandidatePoolSize: 8,
|
iceCandidatePoolSize: 8,
|
||||||
};
|
};
|
||||||
@@ -90,7 +149,8 @@ const defaultRTCPeerConnectionConfig = {
|
|||||||
export {
|
export {
|
||||||
defaultAudioConfig,
|
defaultAudioConfig,
|
||||||
defaultVideoConfig,
|
defaultVideoConfig,
|
||||||
defaultKsvcEncodings,
|
defaultShareScreenConfig,
|
||||||
|
defaultSvcEncodings,
|
||||||
defaultSimulcastEncodings,
|
defaultSimulcastEncodings,
|
||||||
defaultRTCPeerConnectionConfig,
|
defaultRTCPeerConnectionConfig,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ export default {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.client .mic{background:linear-gradient(to top, var(--el-color-primary) var(--volume, 100%), transparent 0%);}
|
.client .mic{background:linear-gradient(to top, var(--el-color-primary) var(--volume, 100%), transparent 0%);}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
<el-button @click="taoyao.mediaConsumerStatus()" :icon="InfoFilled" circle title="媒体信息" />
|
<el-button @click="taoyao.mediaConsumerStatus()" :icon="InfoFilled" circle title="媒体信息" />
|
||||||
<el-popover placement="top" :width="240" trigger="hover">
|
<el-popover placement="top" :width="240" trigger="hover">
|
||||||
<template #reference>
|
<template #reference>
|
||||||
|
|
||||||
<el-button>视频质量</el-button>
|
<el-button>视频质量</el-button>
|
||||||
</template>
|
</template>
|
||||||
<el-table :data="taoyao.options">
|
<el-table :data="taoyao.options">
|
||||||
@@ -120,6 +121,7 @@ export default {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.client .mic{background:linear-gradient(to top, var(--el-color-primary) var(--volume, 100%), transparent 0%);}
|
.client .mic{background:linear-gradient(to top, var(--el-color-primary) var(--volume, 100%), transparent 0%);}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ export default {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.client .mic{background:linear-gradient(to top, var(--el-color-primary) var(--volume, 100%), transparent 0%);}
|
.client .mic{background:linear-gradient(to top, var(--el-color-primary) var(--volume, 100%), transparent 0%);}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ import * as mediasoupClient from "mediasoup-client";
|
|||||||
import {
|
import {
|
||||||
defaultAudioConfig,
|
defaultAudioConfig,
|
||||||
defaultVideoConfig,
|
defaultVideoConfig,
|
||||||
defaultKsvcEncodings,
|
defaultShareScreenConfig,
|
||||||
|
defaultSvcEncodings,
|
||||||
defaultSimulcastEncodings,
|
defaultSimulcastEncodings,
|
||||||
defaultRTCPeerConnectionConfig,
|
defaultRTCPeerConnectionConfig,
|
||||||
} from "./Config.js";
|
} from "./Config.js";
|
||||||
@@ -484,12 +485,14 @@ class Taoyao extends RemoteClient {
|
|||||||
videoSource = "camera";
|
videoSource = "camera";
|
||||||
// 强制使用TCP
|
// 强制使用TCP
|
||||||
forceTcp;
|
forceTcp;
|
||||||
|
// 强制使用VP8
|
||||||
|
forceVP8;
|
||||||
// 强制使用VP9
|
// 强制使用VP9
|
||||||
forceVP9;
|
forceVP9;
|
||||||
// 强制使用H264
|
// 强制使用H264
|
||||||
forceH264;
|
forceH264;
|
||||||
// 同时上送多种质量媒体
|
// 同时上送多种质量媒体
|
||||||
useSimulcast;
|
useLayers;
|
||||||
// 是否消费数据
|
// 是否消费数据
|
||||||
dataConsume;
|
dataConsume;
|
||||||
// 是否消费音频
|
// 是否消费音频
|
||||||
@@ -858,6 +861,7 @@ class Taoyao extends RemoteClient {
|
|||||||
track.getCapabilities()
|
track.getCapabilities()
|
||||||
);
|
);
|
||||||
} else if (self.videoSource === "screen") {
|
} else if (self.videoSource === "screen") {
|
||||||
|
// TODO:默认配置
|
||||||
const stream = await navigator.mediaDevices.getDisplayMedia({
|
const stream = await navigator.mediaDevices.getDisplayMedia({
|
||||||
// 如果需要共享声音
|
// 如果需要共享声音
|
||||||
audio: false,
|
audio: false,
|
||||||
@@ -1605,10 +1609,6 @@ class Taoyao extends RemoteClient {
|
|||||||
*/
|
*/
|
||||||
async roomEnter(roomId, password) {
|
async roomEnter(roomId, password) {
|
||||||
const me = this;
|
const me = this;
|
||||||
if (!roomId) {
|
|
||||||
this.callbackError("无效房间");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// TODO:已经进入房间忽略
|
// TODO:已经进入房间忽略
|
||||||
me.roomId = roomId;
|
me.roomId = roomId;
|
||||||
let response = await me.request(
|
let response = await me.request(
|
||||||
@@ -1983,6 +1983,7 @@ class Taoyao extends RemoteClient {
|
|||||||
// await this.produceAudio();
|
// await this.produceAudio();
|
||||||
// await this.produceVideo();
|
// await this.produceVideo();
|
||||||
// await this.produceData();
|
// await this.produceData();
|
||||||
|
// TODO:返回通道还有音视频生产者
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 生产音频
|
* 生产音频
|
||||||
@@ -2113,17 +2114,23 @@ class Taoyao extends RemoteClient {
|
|||||||
if (!codec) {
|
if (!codec) {
|
||||||
self.callbackError("不支持VP9视频编码");
|
self.callbackError("不支持VP9视频编码");
|
||||||
}
|
}
|
||||||
|
} else if(self.forceVP8) {
|
||||||
|
codec = self.mediasoupDevice.rtpCapabilities.codecs.find(
|
||||||
|
(c) => c.mimeType.toLowerCase() === "video/vp8"
|
||||||
|
);
|
||||||
|
if (!codec) {
|
||||||
|
self.callbackError("不支持VP8视频编码");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (this.useSimulcast) {
|
if (this.useLayers) {
|
||||||
const firstVideoCodec =
|
const firstVideoCodec = this.mediasoupDevice.rtpCapabilities.codecs.find(
|
||||||
this.mediasoupDevice.rtpCapabilities.codecs.find(
|
(c) => c.kind === "video"
|
||||||
(c) => c.kind === "video"
|
);
|
||||||
);
|
|
||||||
if (
|
if (
|
||||||
(this.forceVP9 && codec) ||
|
(this.forceVP9 && codec) ||
|
||||||
firstVideoCodec.mimeType.toLowerCase() === "video/vp9"
|
firstVideoCodec.mimeType.toLowerCase() === "video/vp9"
|
||||||
) {
|
) {
|
||||||
encodings = defaultKsvcEncodings;
|
encodings = defaultSvcEncodings;
|
||||||
} else {
|
} else {
|
||||||
encodings = defaultSimulcastEncodings;
|
encodings = defaultSimulcastEncodings;
|
||||||
}
|
}
|
||||||
@@ -2599,6 +2606,26 @@ class Taoyao extends RemoteClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO:设置track配置
|
||||||
|
*
|
||||||
|
* @param {*} track
|
||||||
|
* @param {*} setting
|
||||||
|
*/
|
||||||
|
setTrack(track, setting) {
|
||||||
|
/*
|
||||||
|
* TODO:MediaStreamTrack.applyConstraints().then().catch();
|
||||||
|
* const setting = {
|
||||||
|
* autoGainControl: true,
|
||||||
|
* noiseSuppression: true
|
||||||
|
* }
|
||||||
|
await track.applyConstraints(Object.assign(track.getSettings(), setting));
|
||||||
|
* TODO:播放音量(audio标签配置)、采集音量
|
||||||
|
* 支持属性:navigator.mediaDevices.getSupportedConstraints()
|
||||||
|
* https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSettings
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关闭视频房间媒体
|
* 关闭视频房间媒体
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user