diff --git a/README.md b/README.md
index ceeadc9..52ffd83 100644
--- a/README.md
+++ b/README.md
@@ -26,6 +26,10 @@
|taoyao-client-harmony|鸿蒙终端|鸿蒙智能终端接入|
|taoyao-signal-server|信令服务|终端信令控制|
+## 证书
+
+本地开发测试安装`docs/certs`中的`ca.crt`证书
+
## 部署
[部署文档](./docs/Deploy.md)
diff --git a/docs/Test.md b/docs/Test.md
deleted file mode 100644
index 70650e4..0000000
--- a/docs/Test.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# 测试
-
-## 推流测试
-
-```
-ffmpeg
-```
diff --git a/docs/etc/nginx.conf b/docs/etc/nginx.conf
index 14622a4..1332bd5 100644
--- a/docs/etc/nginx.conf
+++ b/docs/etc/nginx.conf
@@ -19,7 +19,7 @@ http {
default_type application/octet-stream;
gzip on;
- gzip_types text/xml text/css text/plain text/javascript image/gif image/png image/jpg image/webp image/jpeg image/x-icon image/svg+xml application/json application/javascript font/woff application/octet-stream application/vnd.ms-fontobject;
+ gzip_types font/woff text/xml text/css text/plain text/javascript image/gif image/png image/jpg image/webp image/jpeg image/x-icon image/svg+xml application/json application/javascript application/octet-stream application/vnd.ms-fontobject;
gzip_min_length 1k;
sendfile on;
diff --git a/taoyao-client-media/src/Config.js b/taoyao-client-media/src/Config.js
index 4eba195..d7b3899 100644
--- a/taoyao-client-media/src/Config.js
+++ b/taoyao-client-media/src/Config.js
@@ -119,12 +119,12 @@ module.exports = {
announcedIp: process.env.MEDIASOUP_ANNOUNCED_IP || defaultTaoyaoHost || "127.0.0.1",
},
// TCP
- // {
- // protocol: "tcp",
- // ip: process.env.MEDIASOUP_LISTEN_IP || "0.0.0.0",
- // port: 44444,
- // announcedIp: process.env.MEDIASOUP_ANNOUNCED_IP || defaultTaoyaoHost || "127.0.0.1",
- // },
+ {
+ protocol: "tcp",
+ ip: process.env.MEDIASOUP_LISTEN_IP || "0.0.0.0",
+ port: 44444,
+ announcedIp: process.env.MEDIASOUP_ANNOUNCED_IP || defaultTaoyaoHost || "127.0.0.1",
+ },
],
},
// WebRtcTransport:https://mediasoup.org/documentation/v3/mediasoup/api/#WebRtcTransportOptions
diff --git a/taoyao-client-media/src/Taoyao.js b/taoyao-client-media/src/Taoyao.js
index 94246c3..998e7b3 100644
--- a/taoyao-client-media/src/Taoyao.js
+++ b/taoyao-client-media/src/Taoyao.js
@@ -452,8 +452,8 @@ class Taoyao {
case "media::transport::close":
this.mediaTransportClose(message, body);
break;
- case "media::transport::plain::in":
- me.mediaTransportPlainIn(message, body);
+ case "media::transport::plain":
+ me.mediaTransportPlain(message, body);
break;
case "media::transport::webrtc::connect":
me.mediaTransportWebrtcConnect(message, body);
@@ -629,8 +629,8 @@ class Taoyao {
producer.on("videoorientationchange", (videoOrientation) => {
console.info("producer videoorientationchange:", producer.id, videoOrientation);
self.push(protocol.buildMessage("media::video::orientation::change", {
+ ...videoOrientation,
roomId: roomId,
- ...videoOrientation
}));
});
// await producer.enableTraceEvent([ 'rtp', 'keyframe', 'nack', 'pli', 'fir' ]);
@@ -821,6 +821,7 @@ class Taoyao {
});
consumer.on("producerpause", () => {
console.info("consumer producerpause:", consumer.id);
+ // consumer.pause();
this.push(
protocol.buildMessage("media::consumer::pause", {
roomId: roomId,
@@ -830,6 +831,7 @@ class Taoyao {
});
consumer.on("producerresume", () => {
console.info("consumer producerresume:", consumer.id);
+ // consumer.resume();
this.push(
protocol.buildMessage("media::consumer::resume", {
roomId: roomId,
@@ -1261,16 +1263,21 @@ class Taoyao {
* @param {*} message 消息
* @param {*} body 消息主体
*/
- async mediaTransportPlainIn(message, body) {
+ async mediaTransportPlain(message, body) {
const me = this;
- const { roomId, rtcpMux, comedia, clientId } = body;
+ const { roomId, rtcpMux, comedia, clientId, enableSctp, numSctpStreams, enableSrtp, srtpCryptoSuite } = body;
const plainTransportOptions = {
- rtcpMux: rtcpMux,
- comedia: comedia,
...config.mediasoup.plainTransportOptions,
+ rtcpMux: rtcpMux,
+ comedia: comedia,
+ enableSctp: enableSctp || Boolean(numSctpStreams),
+ numSctpStreams: numSctpStreams || 0,
+ enableSrtp: enableSrtp,
+ srtpCryptoSuite: srtpCryptoSuite,
};
const room = this.rooms.get(roomId);
const transport = await room.mediasoupRouter.createPlainTransport(plainTransportOptions);
+ me.transportEvent("plain", roomId, transport);
transport.clientId = clientId;
room.transports.set(transport.id, transport);
console.info(transport.tuple)
@@ -1336,8 +1343,35 @@ class Taoyao {
...webRtcTransportOptions,
webRtcServer: room.webRtcServer,
});
+ me.transportEvent("webrtc", roomId, transport);
transport.clientId = clientId;
- // 通用事件
+ room.transports.set(transport.id, transport);
+ message.body = {
+ roomId: roomId,
+ transportId: transport.id,
+ iceCandidates: transport.iceCandidates,
+ iceParameters: transport.iceParameters,
+ dtlsParameters: transport.dtlsParameters,
+ sctpParameters: transport.sctpParameters,
+ };
+ self.push(message);
+ const { maxIncomingBitrate } = config.mediasoup.webRtcTransportOptions;
+ // If set, apply max incoming bitrate limit.
+ if (maxIncomingBitrate) {
+ try {
+ await transport.setMaxIncomingBitrate(maxIncomingBitrate);
+ } catch (error) {}
+ }
+ }
+ /**
+ * 通道事件
+ *
+ * @param {*} type 类型:webrtc|plain|pipe|direct
+ * @param {*} roomId 房间ID
+ * @param {*} transport 通道
+ */
+ transportEvent(type, roomId, transport) {
+ /********************* 通用通道事件 *********************/
transport.on("routerclose", () => {
console.info("transport routerclose:", transport.id);
transport.close();
@@ -1377,50 +1411,41 @@ class Taoyao {
// });
// transport.observer.on("trace", fn(trace));
/********************* webRtcTransport通道事件 *********************/
- // transport.on("icestatechange", (iceState) => {
- // console.info("transport icestatechange:", transport.id, iceState);
- // });
- // transport.on("iceselectedtuplechange", (iceSelectedTuple) => {
- // console.info("transport iceselectedtuplechange:", transport.id, iceSelectedTuple);
- // });
- // transport.on("dtlsstatechange", (dtlsState) => {
- // console.info("transport dtlsstatechange:", transport.id, dtlsState);
- // });
- // transport.on("sctpstatechange", (sctpState) => {
- // console.info("transport sctpstatechange:", transport.id, sctpState);
- // });
- // transport.observer.on("icestatechange", fn(iceState));
- // transport.observer.on("iceselectedtuplechange", fn(iceSelectedTuple));
- // transport.observer.on("dtlsstatechange", fn(dtlsState));
- // transport.observer.on("sctpstatechange", fn(sctpState));
+ if("webrtc" === type) {
+ // transport.on("icestatechange", (iceState) => {
+ // console.info("transport icestatechange:", transport.id, iceState);
+ // });
+ // transport.on("iceselectedtuplechange", (iceSelectedTuple) => {
+ // console.info("transport iceselectedtuplechange:", transport.id, iceSelectedTuple);
+ // });
+ // transport.on("dtlsstatechange", (dtlsState) => {
+ // console.info("transport dtlsstatechange:", transport.id, dtlsState);
+ // });
+ // transport.on("sctpstatechange", (sctpState) => {
+ // console.info("transport sctpstatechange:", transport.id, sctpState);
+ // });
+ // transport.observer.on("icestatechange", fn(iceState));
+ // transport.observer.on("iceselectedtuplechange", fn(iceSelectedTuple));
+ // transport.observer.on("dtlsstatechange", fn(dtlsState));
+ // transport.observer.on("sctpstatechange", fn(sctpState));
+ }
/********************* plainTransport通道事件 *********************/
- // transport.on("tuple", fn(tuple));
- // transport.on("rtcptuple", fn(rtcpTuple));
- // transport.on("sctpstatechange", fn(sctpState));
- // transport.observer.on("tuple", fn(tuple));
- // transport.observer.on("rtcptuple", fn(rtcpTuple));
- // transport.observer.on("sctpstatechange", fn(sctpState));
+ if("plain" === type) {
+ // transport.on("tuple", fn(tuple));
+ // transport.on("rtcptuple", fn(rtcpTuple));
+ // transport.on("sctpstatechange", fn(sctpState));
+ // transport.observer.on("tuple", fn(tuple));
+ // transport.observer.on("rtcptuple", fn(rtcpTuple));
+ // transport.observer.on("sctpstatechange", fn(sctpState));
+ }
/********************* pipeTransport通道事件 *********************/
- // transport.on("sctpstatechange", fn(sctpState));
- // transport.observer.on("sctpstatechange", fn(sctpState));
+ if("pipe" === type) {
+ // transport.on("sctpstatechange", fn(sctpState));
+ // transport.observer.on("sctpstatechange", fn(sctpState));
+ }
/********************* directTransport通道事件 *********************/
- // transport.on("rtcp", fn(rtcpPacket));
- room.transports.set(transport.id, transport);
- message.body = {
- roomId: roomId,
- transportId: transport.id,
- iceCandidates: transport.iceCandidates,
- iceParameters: transport.iceParameters,
- dtlsParameters: transport.dtlsParameters,
- sctpParameters: transport.sctpParameters,
- };
- self.push(message);
- const { maxIncomingBitrate } = config.mediasoup.webRtcTransportOptions;
- // If set, apply max incoming bitrate limit.
- if (maxIncomingBitrate) {
- try {
- await transport.setMaxIncomingBitrate(maxIncomingBitrate);
- } catch (error) {}
+ if("rtcp" === type) {
+ // transport.on("rtcp", fn(rtcpPacket));
}
}
/**
diff --git a/taoyao-client-web/README.md b/taoyao-client-web/README.md
index 40bc4b2..6d26924 100644
--- a/taoyao-client-web/README.md
+++ b/taoyao-client-web/README.md
@@ -1,13 +1,7 @@
# Web终端
-注意部分`API`需要`localhost`或者`https`
-
## Web终端
* [mediasoup-client源码](https://github.com/versatica/mediasoup-client)
* [mediasoup-client文档](https://mediasoup.org/documentation/v3/mediasoup-client)
* [mediasoup-client接口](https://mediasoup.org/documentation/v3/mediasoup-client/api)
-
-## TODO
-
-按钮:选择房间、媒体服务、开关
diff --git a/taoyao-client-web/src/components/Taoyao.js b/taoyao-client-web/src/components/Taoyao.js
index b52bad0..eb7a136 100644
--- a/taoyao-client-web/src/components/Taoyao.js
+++ b/taoyao-client-web/src/components/Taoyao.js
@@ -21,8 +21,9 @@ const protocol = {
* @returns 索引
*/
buildId() {
- if (++this.index > this.maxIndex) {
- this.index = 0;
+ const me = this;
+ if (++me.index > me.maxIndex) {
+ me.index = 0;
}
const date = new Date();
return (
@@ -30,8 +31,8 @@ const protocol = {
1000000000000 * date.getHours() +
10000000000 * date.getMinutes() +
100000000 * date.getSeconds() +
- 1000 * this.clientIndex +
- this.index
+ 1000 * me.clientIndex +
+ me.index
);
},
/**
@@ -2010,23 +2011,25 @@ class Taoyao extends RemoteClient {
*/
closeMedia() {
let me = this;
- if (me.sendTransport) {
- me.sendTransport.close();
- }
- if (me.recvTransport) {
- me.recvTransport.close();
- }
if(me.audioTrack) {
me.audioTrack.stop();
}
if(me.videoTrack) {
me.videoTrack.stop();
}
+ if (me.sendTransport) {
+ me.sendTransport.close();
+ }
+ if (me.recvTransport) {
+ me.recvTransport.close();
+ }
me.sendTransport = null;
me.recvTransport = null;
+ me.dataProducer = null;
me.audioProducer = null;
me.videoProducer = null;
- me.dataProducer = null;
+ me.consumers.clear();
+ me.dataConsumers.clear();
}
/**
* 关闭资源
diff --git a/taoyao-signal-server/docs/assembly/dev.xml b/taoyao-signal-server/docs/assembly/dev.xml
index 949ffa3..c7aaee0 100644
--- a/taoyao-signal-server/docs/assembly/dev.xml
+++ b/taoyao-signal-server/docs/assembly/dev.xml
@@ -1,58 +1,60 @@
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
- dev
+ dev
-
- dir
-
+
+ dir
+
- false
+ false
-
-
- ${taoyao.maven.basedir}/docs
- ./
-
- README.md
-
-
-
- ${taoyao.maven.basedir}/docs/bin
- bin
- 0755
- true
-
-
- src/main/resources
- config
- true
-
- *.yml
- *.properties
-
-
-
- src/main/resources
- config
-
- *.jks
-
-
-
- target
- logs
-
- **/*
-
-
-
+
+
+ ${taoyao.maven.basedir}/docs
+ ./
+
+ README.md
+
+
+
+ ${taoyao.maven.basedir}/docs/bin
+ bin
+ 0755
+ true
+
+
+ src/main/resources
+ config
+ true
+
+ *.yml
+ *.properties
+
+
+
+ src/main/resources
+ config
+
+ *.jks
+ *.p12
+ *.pfx
+
+
+
+ target
+ logs
+
+ **/*
+
+
+
-
-
- lib
-
-
+
+
+ lib
+
+
diff --git a/taoyao-signal-server/docs/assembly/prd.xml b/taoyao-signal-server/docs/assembly/prd.xml
index 0458d14..f7077f1 100644
--- a/taoyao-signal-server/docs/assembly/prd.xml
+++ b/taoyao-signal-server/docs/assembly/prd.xml
@@ -37,7 +37,9 @@
src/main/resources
config
- *.jks
+ *.jks
+ *.p12
+ *.pfx
diff --git a/taoyao-signal-server/pom.xml b/taoyao-signal-server/pom.xml
index bbe50f3..0db026a 100644
--- a/taoyao-signal-server/pom.xml
+++ b/taoyao-signal-server/pom.xml
@@ -175,7 +175,9 @@
- *.jks
+ *.jks
+ *.p12
+ *.pfx
*.yml
*.properties
diff --git a/taoyao-signal-server/taoyao-server/src/main/java/com/acgist/taoyao/controller/ConfigController.java b/taoyao-signal-server/taoyao-server/src/main/java/com/acgist/taoyao/controller/ConfigController.java
index 3de4f12..05794ef 100644
--- a/taoyao-signal-server/taoyao-server/src/main/java/com/acgist/taoyao/controller/ConfigController.java
+++ b/taoyao-signal-server/taoyao-server/src/main/java/com/acgist/taoyao/controller/ConfigController.java
@@ -15,6 +15,7 @@ import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
/**
* 配置
@@ -24,6 +25,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
@Tag(name = "配置", description = "配置管理")
@RestController
@RequestMapping("/config")
+@RequiredArgsConstructor
public class ConfigController {
private final MediaProperties mediaProperties;
@@ -31,18 +33,6 @@ public class ConfigController {
private final SocketProperties socketProperties;
private final WebrtcProperties webrtcProperties;
- public ConfigController(
- MediaProperties mediaProperties,
- CameraProperties cameraProperties,
- SocketProperties socketProperties,
- WebrtcProperties webrtcProperties
- ) {
- this.mediaProperties = mediaProperties;
- this.cameraProperties = cameraProperties;
- this.socketProperties = socketProperties;
- this.webrtcProperties = webrtcProperties;
- }
-
@Operation(summary = "媒体配置", description = "媒体配置")
@GetMapping("/media")
@ApiResponse(content = @Content(schema = @Schema(implementation = MediaProperties.class)))
diff --git a/taoyao-signal-server/taoyao-server/src/main/java/com/acgist/taoyao/controller/ControlController.java b/taoyao-signal-server/taoyao-server/src/main/java/com/acgist/taoyao/controller/ControlController.java
index 5e059ad..fc06029 100644
--- a/taoyao-signal-server/taoyao-server/src/main/java/com/acgist/taoyao/controller/ControlController.java
+++ b/taoyao-signal-server/taoyao-server/src/main/java/com/acgist/taoyao/controller/ControlController.java
@@ -27,6 +27,7 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
+import lombok.RequiredArgsConstructor;
/**
* 控制
@@ -37,6 +38,7 @@ import jakarta.validation.constraints.NotNull;
@Validated
@RestController
@RequestMapping("/control")
+@RequiredArgsConstructor
public class ControlController {
private final ControlAiProtocol controlAiProtocol;
@@ -49,28 +51,6 @@ public class ControlController {
private final ControlConfigAudioProtocol controlConfigAudioProtocol;
private final ControlConfigVideoProtocol controlConfigVideoProtocol;
- public ControlController(
- ControlAiProtocol controlAiProtocol,
- ControlPtzProtocol controlPtzProtocol,
- ControlBellProtocol controlBellProtocol,
- ControlBeautyProtocol controlBeautyProtocol,
- ControlRecordProtocol controlRecordProtocol,
- ControlWatermarkProtocol controlWatermarkProtocol,
- ControlPhotographProtocol controlPhotographProtocol,
- ControlConfigAudioProtocol controlConfigAudioProtocol,
- ControlConfigVideoProtocol controlConfigVideoProtocol
- ) {
- this.controlAiProtocol = controlAiProtocol;
- this.controlPtzProtocol = controlPtzProtocol;
- this.controlBellProtocol = controlBellProtocol;
- this.controlBeautyProtocol = controlBeautyProtocol;
- this.controlRecordProtocol = controlRecordProtocol;
- this.controlWatermarkProtocol = controlWatermarkProtocol;
- this.controlPhotographProtocol = controlPhotographProtocol;
- this.controlConfigAudioProtocol = controlConfigAudioProtocol;
- this.controlConfigVideoProtocol = controlConfigVideoProtocol;
- }
-
@Operation(summary = "AI识别", description = "AI识别控制")
@GetMapping("/ai/{clientId}")
public Message ai(@PathVariable String clientId, @Valid AiProperties aiProperties) {
diff --git a/taoyao-signal-server/taoyao-server/src/main/java/com/acgist/taoyao/controller/PlatformController.java b/taoyao-signal-server/taoyao-server/src/main/java/com/acgist/taoyao/controller/PlatformController.java
index 55b1468..77cd0ee 100644
--- a/taoyao-signal-server/taoyao-server/src/main/java/com/acgist/taoyao/controller/PlatformController.java
+++ b/taoyao-signal-server/taoyao-server/src/main/java/com/acgist/taoyao/controller/PlatformController.java
@@ -7,6 +7,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.boot.model.MessageCode;
import com.acgist.taoyao.signal.protocol.platform.PlatformRebootProtocol;
import com.acgist.taoyao.signal.protocol.platform.PlatformShutdownProtocol;
@@ -38,6 +39,9 @@ public class PlatformController {
@Operation(summary = "重启平台", description = "重启平台")
@GetMapping("/reboot")
public Message platformReboot() {
+ if(this.platformRebootProtocol == null) {
+ return Message.fail(MessageCode.CODE_3406, "功能没有开启");
+ }
this.platformRebootProtocol.execute();
return Message.success();
}
@@ -45,6 +49,9 @@ public class PlatformController {
@Operation(summary = "关闭平台", description = "关闭平台")
@GetMapping("/shutdown")
public Message platformShutdown() {
+ if(this.platformShutdownProtocol == null) {
+ return Message.fail(MessageCode.CODE_3406, "功能没有开启");
+ }
this.platformShutdownProtocol.execute();
return Message.success();
}
diff --git a/taoyao-signal-server/taoyao-server/src/main/java/com/acgist/taoyao/controller/SystemController.java b/taoyao-signal-server/taoyao-server/src/main/java/com/acgist/taoyao/controller/SystemController.java
index 89da2af..198be38 100644
--- a/taoyao-signal-server/taoyao-server/src/main/java/com/acgist/taoyao/controller/SystemController.java
+++ b/taoyao-signal-server/taoyao-server/src/main/java/com/acgist/taoyao/controller/SystemController.java
@@ -7,6 +7,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.boot.model.MessageCode;
import com.acgist.taoyao.signal.protocol.system.SystemRebootProtocol;
import com.acgist.taoyao.signal.protocol.system.SystemShutdownProtocol;
@@ -38,6 +39,9 @@ public class SystemController {
@Operation(summary = "重启系统", description = "重启系统")
@GetMapping("/reboot")
public Message systemReboot() {
+ if(this.systemRebootProtocol == null) {
+ return Message.fail(MessageCode.CODE_3406, "功能没有开启");
+ }
this.systemRebootProtocol.execute();
return Message.success();
}
@@ -45,6 +49,9 @@ public class SystemController {
@Operation(summary = "关闭系统", description = "关闭系统")
@GetMapping("/shutdown")
public Message systemShutdown() {
+ if(this.systemShutdownProtocol == null) {
+ return Message.fail(MessageCode.CODE_3406, "功能没有开启");
+ }
this.systemShutdownProtocol.execute();
return Message.success();
}
diff --git a/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/signal/SocketSignalTest.java b/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/signal/SocketSignalTest.java
index 6c62f7f..cda69b8 100644
--- a/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/signal/SocketSignalTest.java
+++ b/taoyao-signal-server/taoyao-server/src/test/java/com/acgist/taoyao/signal/SocketSignalTest.java
@@ -80,7 +80,7 @@ public class SocketSignalTest {
}
""";
// {"header":{"v":"1.0.0","id":1215310510002009,"signal":"room::enter"},"body":{"roomId":"8260e615-3081-4bfc-96a8-574f4dd780d9"}}
- // {"header":{"v":"1.0.0","id":1215310510002010,"signal":"media::transport::plain::in"},"body":{"roomId":"8260e615-3081-4bfc-96a8-574f4dd780d9","rtcpMux":false,"comedia":true}}
+ // {"header":{"v":"1.0.0","id":1215310510002010,"signal":"media::transport::plain"},"body":{"roomId":"8260e615-3081-4bfc-96a8-574f4dd780d9","rtcpMux":false,"comedia":true}}
// {"header":{"v":"1.0.0","id":1215375110006012,"signal":"media::produce"},"body":{"kind":"video","roomId":"8260e615-3081-4bfc-96a8-574f4dd780d9","transportId":"14dc9307-bf9c-4442-a9ad-ce6a97623ef4","appData":{},"rtpParameters":{"codecs":[{"mimeType":"video/vp8","clockRate":90000,"payloadType":102,"rtcpFeedback":[]}],"encodings":[{"ssrc":123123}]}}}
// ffplay -protocol_whitelist "file,udp,rtp" taoyao.sdp
// ffmpeg -re -i video.mp4 -vcodec copy -map 0:0 -f rtp rtp://localhost:6666 > taoyao.sdp
diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/configuration/SignalAutoConfiguration.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/configuration/SignalAutoConfiguration.java
index ab12df5..74413a7 100644
--- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/configuration/SignalAutoConfiguration.java
+++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/configuration/SignalAutoConfiguration.java
@@ -1,6 +1,5 @@
package com.acgist.taoyao.signal.configuration;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -13,6 +12,7 @@ import com.acgist.taoyao.signal.event.EventPublisher;
import com.acgist.taoyao.signal.protocol.ProtocolManager;
import jakarta.annotation.PostConstruct;
+import lombok.RequiredArgsConstructor;
/**
* 信令自动配置
@@ -20,13 +20,13 @@ import jakarta.annotation.PostConstruct;
* @author acgist
*/
@AutoConfiguration
+@RequiredArgsConstructor
@EnableConfigurationProperties({
CameraProperties.class
})
public class SignalAutoConfiguration {
- @Autowired
- private ApplicationContext applicationContext;
+ private final ApplicationContext applicationContext;
@PostConstruct
public void init() {
diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/ClientController.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/ClientController.java
index f545987..99141c2 100644
--- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/ClientController.java
+++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/ClientController.java
@@ -17,6 +17,7 @@ import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
/**
* 终端
@@ -26,6 +27,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
@Tag(name = "终端", description = "终端管理")
@RestController
@RequestMapping("/client")
+@RequiredArgsConstructor
public class ClientController {
private final ClientManager clientManager;
@@ -33,16 +35,6 @@ public class ClientController {
private final ClientRebootProtocol clientRebootProtocol;
private final ClientShutdownProtocol clientShutdownProtocol;
- public ClientController(
- ClientManager clientManager, ClientWakeupProtocol clientWakeupProtocol,
- ClientRebootProtocol clientRebootProtocol, ClientShutdownProtocol clientShutdownProtocol
- ) {
- this.clientManager = clientManager;
- this.clientWakeupProtocol = clientWakeupProtocol;
- this.clientRebootProtocol = clientRebootProtocol;
- this.clientShutdownProtocol = clientShutdownProtocol;
- }
-
@Operation(summary = "终端列表", description = "终端列表")
@GetMapping("/list")
@ApiResponse(content = @Content(schema = @Schema(implementation = ClientStatus.class)))
diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/ProtocolController.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/ProtocolController.java
index 4a4d990..578f4fd 100644
--- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/ProtocolController.java
+++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/ProtocolController.java
@@ -15,6 +15,7 @@ import com.acgist.taoyao.signal.protocol.Protocol;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
/**
@@ -26,14 +27,11 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
@RequestMapping("/protocol")
+@RequiredArgsConstructor
public class ProtocolController {
private final ApplicationContext applicationContext;
- public ProtocolController(ApplicationContext applicationContext) {
- this.applicationContext = applicationContext;
- }
-
@Operation(summary = "信令列表", description = "信令列表Markdown")
@GetMapping("/list")
public String list() {
diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/RoomController.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/RoomController.java
index 219c9a9..8f4620a 100644
--- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/RoomController.java
+++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/controller/RoomController.java
@@ -19,6 +19,7 @@ import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
/**
* 房间
@@ -29,14 +30,11 @@ import io.swagger.v3.oas.annotations.tags.Tag;
@Validated
@RestController
@RequestMapping("/room")
+@RequiredArgsConstructor
public class RoomController {
private final RoomManager roomManager;
- public RoomController(RoomManager roomManager) {
- this.roomManager = roomManager;
- }
-
@Operation(summary = "房间信息", description = "房间信息")
@GetMapping("/log")
public Message log() {
diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/party/media/RouteType.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/party/media/RouterType.java
similarity index 92%
rename from taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/party/media/RouteType.java
rename to taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/party/media/RouterType.java
index 9f05665..7df002b 100644
--- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/party/media/RouteType.java
+++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/party/media/RouterType.java
@@ -5,7 +5,7 @@ package com.acgist.taoyao.signal.party.media;
*
* @author acgist
*/
-public enum RouteType {
+public enum RouterType {
// 对讲:只有两个人之间的媒体相互路由
ONE_TO_ONE,
diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaConsumeProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaConsumeProtocol.java
index 5a08e02..475062a 100644
--- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaConsumeProtocol.java
+++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaConsumeProtocol.java
@@ -67,11 +67,16 @@ public class MediaConsumeProtocol extends ProtocolRoomAdapter implements Applica
final ClientWrapper produceClientWrapper = producer.getProducerClient();
room.getClients().values().stream()
.filter(v -> v != produceClientWrapper)
+ .filter(v -> v.getRecvTransport() != null)
.filter(v -> v.getSubscribeType().canConsume(producer))
.forEach(v -> this.consume(room, v, producer, this.build()));
} else if(event.getClientWrapper() != null) {
// 创建WebRTC消费通道:消费其他终端
final ClientWrapper consumeClientWrapper = event.getClientWrapper();
+ if(consumeClientWrapper.getRecvTransport() == null) {
+ log.debug("没有消费通道:{}", consumeClientWrapper.getClientId());
+ return;
+ }
room.getClients().values().stream()
.filter(v -> v != consumeClientWrapper)
.flatMap(v -> v.getProducers().values().stream())
diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaSetRouterTypeProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaSetRouterTypeProtocol.java
new file mode 100644
index 0000000..c65cd57
--- /dev/null
+++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaSetRouterTypeProtocol.java
@@ -0,0 +1,34 @@
+package com.acgist.taoyao.signal.protocol.media;
+
+import java.util.Map;
+
+import com.acgist.taoyao.boot.model.Message;
+import com.acgist.taoyao.signal.client.Client;
+import com.acgist.taoyao.signal.client.ClientType;
+import com.acgist.taoyao.signal.party.media.Room;
+import com.acgist.taoyao.signal.protocol.ProtocolRoomAdapter;
+
+/**
+ * 设置路由类型信令
+ * 注意:不会添加移除消费者生产者,只会暂停恢复操作。
+ *
+ * @author acgist
+ */
+public class MediaSetRouterTypeProtocol extends ProtocolRoomAdapter {
+
+ public static final String SIGNAL = "media::set::router::type";
+
+ public MediaSetRouterTypeProtocol() {
+ super("设置路由类型信令", SIGNAL);
+ }
+
+ @Override
+ public void execute(String clientId, ClientType clientType, Room room, Client client, Client mediaClient, Message message, Map body) {
+ if(clientType.mediaClient()) {
+ // TODO:路由类型
+ } else {
+ this.logNoAdapter(clientType);
+ }
+ }
+
+}
diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaTransportPlainOutProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaTransportPlainOutProtocol.java
deleted file mode 100644
index ba36b6b..0000000
--- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaTransportPlainOutProtocol.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.acgist.taoyao.signal.protocol.media;
-
-/**
- * 创建RTP输出通道信令
- *
- * @author acgist
- */
-public class MediaTransportPlainOutProtocol {
-
-}
diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaTransportPlainInProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaTransportPlainProtocol.java
similarity index 82%
rename from taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaTransportPlainInProtocol.java
rename to taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaTransportPlainProtocol.java
index f60e677..865ae58 100644
--- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaTransportPlainInProtocol.java
+++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/media/MediaTransportPlainProtocol.java
@@ -22,7 +22,10 @@ import lombok.extern.slf4j.Slf4j;
/**
* 创建RTP输入通道信令
- * TODO:srtp
+ * 注意:
+ * 3. ffmpeg不支持rtcpMux
+ * 2. comedia必须开启srtp功能
+ * 1. 如果关闭comedia不会自动升级双向通道
*
* @author acgist
*/
@@ -34,14 +37,21 @@ import lombok.extern.slf4j.Slf4j;
"roomId": "房间ID",
"rtcpMux": RTP和RTCP端口复用(true|false),
"comedia": 自动终端端口(true|false),
+ "enableSctp": 是否开启sctp(true|false),
+ "numSctpStreams": sctp数量,
+ "enableSrtp": 是否开启srtp(true|false),
+ "srtpCryptoSuite": {
+ "cryptoSuite": "算法(AEAD_AES_256_GCM|AEAD_AES_128_GCM|AES_CM_128_HMAC_SHA1_80|AES_CM_128_HMAC_SHA1_32)",
+ "keyBase64": "密钥"
+ }
}
"""
)
-public class MediaTransportPlainInProtocol extends ProtocolRoomAdapter {
+public class MediaTransportPlainProtocol extends ProtocolRoomAdapter {
- public static final String SIGNAL = "media::transport::plain::in";
+ public static final String SIGNAL = "media::transport::plain";
- public MediaTransportPlainInProtocol() {
+ public MediaTransportPlainProtocol() {
super("创建RTP输入通道信令", SIGNAL);
}
@@ -65,6 +75,7 @@ public class MediaTransportPlainInProtocol extends ProtocolRoomAdapter {
log.warn("发送通道已经存在:{}", transportId);
}
clientWrapper.setSendTransport(sendTransport);
+ // TODO:双向队列
// 拷贝属性
sendTransport.copy(responseBody);
client.push(response);
diff --git a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomExpelProtocol.java b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomExpelProtocol.java
index b24e882..ffc34f2 100644
--- a/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomExpelProtocol.java
+++ b/taoyao-signal-server/taoyao-signal/src/main/java/com/acgist/taoyao/signal/protocol/room/RoomExpelProtocol.java
@@ -40,6 +40,8 @@ public class RoomExpelProtocol extends ProtocolRoomAdapter {
if(clientType.mediaClient()) {
final String expelClientId = MapUtils.get(body, Constant.CLIENT_ID);
room.unicast(expelClientId, message);
+ // 如果需要强制提出
+// room.leave(this.clientManager.clients(expelClientId));
} else {
this.logNoAdapter(clientType);
}