diff --git a/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/Meeting.java b/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/Meeting.java index b759987..1291fa9 100644 --- a/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/Meeting.java +++ b/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/Meeting.java @@ -26,5 +26,21 @@ public class Meeting { */ @Schema(title = "终端会话标识列表", description = "终端会话标识列表") private List sns; + /** + * 创建终端标识 + */ + @Schema(title = "创建终端标识", description = "创建终端标识") + private String creator; + + /** + * 新增终端会话标识 + * + * @param sn 终端会话标识 + */ + public void addSn(String sn) { + synchronized (this.sns) { + this.sns.add(sn); + } + } } diff --git a/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/MeetingManager.java b/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/MeetingManager.java index c5c7b25..c933d43 100644 --- a/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/MeetingManager.java +++ b/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/MeetingManager.java @@ -3,8 +3,11 @@ package com.acgist.taoyao.meeting; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import com.acgist.taoyao.boot.service.IdService; + import lombok.extern.slf4j.Slf4j; /** @@ -16,6 +19,9 @@ import lombok.extern.slf4j.Slf4j; @Service public class MeetingManager { + @Autowired + private IdService idService; + /** * 会议列表 */ @@ -49,5 +55,23 @@ public class MeetingManager { final Meeting meeting = this.meeting(id); return meeting == null ? List.of() : meeting.getSns(); } + + /** + * 创建会议 + * + * @param sn 创建会议终端标识 + * + * @return 会议信息 + */ + public Meeting create(String sn) { + final Meeting meeting = new Meeting(); + meeting.setId(this.idService.buildIdToString()); + meeting.setSns(new CopyOnWriteArrayList<>()); + meeting.setCreator(sn); + meeting.addSn(sn); + this.meetings.add(meeting); + log.info("创建会议:{}", meeting.getId()); + return meeting; + } } diff --git a/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/listener/MeetingCreateListener.java b/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/listener/MeetingCreateListener.java index e6afebc..e270c08 100644 --- a/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/listener/MeetingCreateListener.java +++ b/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/listener/MeetingCreateListener.java @@ -6,32 +6,34 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.acgist.taoyao.boot.model.Message; +import com.acgist.taoyao.meeting.Meeting; import com.acgist.taoyao.meeting.MeetingManager; import com.acgist.taoyao.signal.client.ClientSession; +import com.acgist.taoyao.signal.client.ClientSessionManager; import com.acgist.taoyao.signal.event.meeting.MeetingCreateEvent; import com.acgist.taoyao.signal.listener.ApplicationListenerAdapter; -import lombok.extern.slf4j.Slf4j; - /** * 创建会议监听 * * @author acgist */ -@Slf4j @Component public class MeetingCreateListener extends ApplicationListenerAdapter { @Autowired private MeetingManager meetingManager; + @Autowired + private ClientSessionManager clientSessionManager; @Override public void onApplicationEvent(MeetingCreateEvent event) { -// this.meetingManager.create(); final ClientSession session = event.getSession(); + final Meeting meeting = this.meetingManager.create(session.sn()); final Message message = event.getMessage(); - message.setBody(Map.of("id", "1234")); - session.push(message); + message.setBody(Map.of("id", meeting.getId())); + // 广播:不改ID触发创建终端事件回调 + this.clientSessionManager.broadcast(message); } } diff --git a/taoyao-server/src/main/resources/static/css/style.css b/taoyao-server/src/main/resources/static/css/style.css index e553416..78ad777 100644 --- a/taoyao-server/src/main/resources/static/css/style.css +++ b/taoyao-server/src/main/resources/static/css/style.css @@ -34,6 +34,6 @@ input::-webkit-calendar-picker-indicator{color:#1155AA;background:none;} .taoyao .meeting > .video video{width:100%;height:100%;} .taoyao .meeting .handler{position:absolute;bottom:0rem;text-align:center;width:100%;background:rgba(0,0,0,0.2);padding:0.2rem 0;} .taoyao .meeting .handler a{color:#fff;} -.taoyao .meeting .handler a.record:hover{color:#060!important;} +.taoyao .meeting .handler a:hover{color:#060!important;} +.taoyao .meeting .handler a.expel:hover{color:#C00!important;} .taoyao .meeting .handler a.record.active{color:#C00;} -.taoyao .meeting .handler a.kick:hover{color:#C00;} diff --git a/taoyao-server/src/main/resources/static/javascript/app.js b/taoyao-server/src/main/resources/static/javascript/app.js deleted file mode 100644 index 197deb9..0000000 --- a/taoyao-server/src/main/resources/static/javascript/app.js +++ /dev/null @@ -1,9 +0,0 @@ -/** 桃夭WebRTC终端应用功能 */ -// 样式操作 -function classSwitch(e, className) { - if(e.className.indexOf(className) >= 0) { - e.className = e.className.replace(className, '').replace(/(^\s)|(\s$)/g, ""); - } else { - e.className = e.className + ' ' + className; - } -} diff --git a/taoyao-server/src/main/resources/static/javascript/taoyao.js b/taoyao-server/src/main/resources/static/javascript/taoyao.js index 778454f..7a35516 100644 --- a/taoyao-server/src/main/resources/static/javascript/taoyao.js +++ b/taoyao-server/src/main/resources/static/javascript/taoyao.js @@ -277,6 +277,70 @@ const signalChannel = { } } }; +/** 终端 */ +function TaoyaoClient( + sn +) { + /** 终端标识 */ + this.sn = sn; + /** 视频对象 */ + this.video = null; + /** 媒体状态 */ + this.audioStatus = true; + this.videoStatus = true; + this.recordStatus = false; + /** 媒体信息 */ + this.audioStreamId = null; + this.videoStreamId = null; + /** 播放视频 */ + this.play = async function() { + await this.video.play(); + return this; + }; + /** 重新加载 */ + this.load = function() { + this.video.load(); + return this; + } + /** 暂停视频 */ + this.pause = function() { + this.video.pause(); + return this; + }; + /** 关闭视频 */ + this.close = function() { + this.video.close(); + return this; + }; + /** 设置视频对象 */ + this.buildVideo = async function(videoId, stream) { + if(!this.video) { + this.video = document.getElementById(videoId); + } + await this.buildStream(stream); + return this; + }; + /** 设置媒体流 */ + this.buildStream = async function(stream) { + if(stream) { + if ('srcObject' in this.video) { + this.video.srcObject = stream; + } else { + this.video.src = URL.createObjectURL(stream);; + } + } + await this.play(); + return this; + }; + /** 设置音频流 */ + this.buildAudioStream = function() { + + }; + /** 设置视频流 */ + this.buildVideoStream = function() { + + }; +} /** 桃夭 */ function Taoyao( webSocket, @@ -288,26 +352,20 @@ function Taoyao( this.webSocket = webSocket; /** IceServer地址 */ this.iceServer = iceServer; - /** 媒体状态 */ - this.audioStatus = true; - this.videoStatus = true; /** 设备状态 */ this.audioEnabled = true; this.videoEnabled = true; - /** 媒体信息 */ - this.audioStreamId = null; - this.videoStreamId = null; /** 媒体配置 */ this.audioConfig = audioConfig || defaultAudioConfig; this.videoConfig = videoConfig || defaultVideoConfig; - /** 本地视频 */ - this.localVideo = null; - /** 终端媒体 */ - this.clientMedia = {}; - /** 信令通道 */ - this.signalChannel = null; /** 发送信令 */ this.push = null; + /** 本地终端 */ + this.localClient = null; + /** 远程终端 */ + this.remoteClient = []; + /** 信令通道 */ + this.signalChannel = null; /** 检查设备 */ this.checkDevice = function() { let self = this; @@ -394,15 +452,10 @@ function Taoyao( } }); }; - /** 设置本地媒体 */ - this.localMedia = async function(localVideoId, stream) { - this.localVideo = document.getElementById(localVideoId); - if ('srcObject' in this.localVideo) { - this.localVideo.srcObject = stream; - } else { - this.localVideo.src = URL.createObjectURL(stream);; - } - await this.localVideo.play(); + /** 设置本地终端 */ + this.buildLocalClient = async function(localVideoId, stream) { + this.localClient = new TaoyaoClient(signalConfig.sn); + await this.localClient.buildVideo(localVideoId, stream); }; /** 关闭:关闭媒体 */ this.close = function() { diff --git a/taoyao-server/src/main/resources/static/meeting.html b/taoyao-server/src/main/resources/static/meeting.html index 397caa3..021d051 100644 --- a/taoyao-server/src/main/resources/static/meeting.html +++ b/taoyao-server/src/main/resources/static/meeting.html @@ -5,91 +5,128 @@ 会议 - + -
+
- - - - - + + + + +
-
+
- - - - + + + +
+
+
+
+ +
+
+ + + +
\ No newline at end of file diff --git a/taoyao-signal/README.md b/taoyao-signal/README.md index 2ae108f..04d2188 100644 --- a/taoyao-signal/README.md +++ b/taoyao-signal/README.md @@ -184,6 +184,12 @@ ### 创建会议信令(4000) +终端->服务端 + +``` +{} +``` + ### 关闭会议信令(4001) 释放资源、广播广播 @@ -243,3 +249,14 @@ MCU/SFU模式有效 ### 开启录像(5006) ### 停止录像(5007) + +### 配置媒体(5008) + +配置订阅媒体:码率、帧率、分辨率等等 + + +### IceCandidate + +### Offer + +### Answer \ No newline at end of file diff --git a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/ClientMediaHandler.java b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/ClientMediaHandler.java index df19260..122e57f 100644 --- a/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/ClientMediaHandler.java +++ b/taoyao-signal/src/main/java/com/acgist/taoyao/signal/media/ClientMediaHandler.java @@ -3,6 +3,8 @@ package com.acgist.taoyao.signal.media; /** * 终端媒体操作 * + * TODO:注意暂停心跳防止端口关闭 + * * @author acgist */ public interface ClientMediaHandler {