From 1de076ae16ca711be1c5d721cfd33ed38b0abca9 Mon Sep 17 00:00:00 2001 From: acgist <289547414@qq.com> Date: Thu, 2 Feb 2023 19:39:29 +0800 Subject: [PATCH] =?UTF-8?q?[*]=20=E7=BB=93=E6=9E=84=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- taoyao-media/README.md | 2 +- taoyao-media/config.js | 164 ++++++ taoyao-media/package.json | 16 + taoyao-media/server.js | 556 +++++++++++++++++- taoyao-signal/README.md | 14 +- taoyao-signal/pom.xml | 11 +- taoyao-signal/taoyao-live/pom.xml | 26 - .../com/acgist/taoyao/media}/live/Live.java | 2 +- .../media}/live/LiveListenerAdapter.java | 2 +- .../taoyao/media}/live/LiveManager.java | 2 +- .../live/controller/LiveController.java | 4 +- .../acgist/taoyao/media}/meeting/Meeting.java | 2 +- .../meeting/MeetingListenerAdapter.java | 2 +- .../taoyao/media}/meeting/MeetingManager.java | 2 +- .../meeting/controller/MeetingController.java | 6 +- .../listener/MeetingCreateListener.java | 6 +- .../listener/MeetingEnterListener.java | 6 +- taoyao-signal/taoyao-meeting/pom.xml | 26 - taoyao-signal/taoyao-server/pom.xml | 6 +- 19 files changed, 764 insertions(+), 91 deletions(-) create mode 100644 taoyao-media/config.js create mode 100644 taoyao-media/package.json delete mode 100644 taoyao-signal/taoyao-live/pom.xml rename taoyao-signal/{taoyao-live/src/main/java/com/acgist/taoyao => taoyao-media/src/main/java/com/acgist/taoyao/media}/live/Live.java (96%) rename taoyao-signal/{taoyao-live/src/main/java/com/acgist/taoyao => taoyao-media/src/main/java/com/acgist/taoyao/media}/live/LiveListenerAdapter.java (92%) rename taoyao-signal/{taoyao-live/src/main/java/com/acgist/taoyao => taoyao-media/src/main/java/com/acgist/taoyao/media}/live/LiveManager.java (78%) rename taoyao-signal/{taoyao-live/src/main/java/com/acgist/taoyao => taoyao-media/src/main/java/com/acgist/taoyao/media}/live/controller/LiveController.java (93%) rename taoyao-signal/{taoyao-meeting/src/main/java/com/acgist/taoyao => taoyao-media/src/main/java/com/acgist/taoyao/media}/meeting/Meeting.java (96%) rename taoyao-signal/{taoyao-meeting/src/main/java/com/acgist/taoyao => taoyao-media/src/main/java/com/acgist/taoyao/media}/meeting/MeetingListenerAdapter.java (91%) rename taoyao-signal/{taoyao-meeting/src/main/java/com/acgist/taoyao => taoyao-media/src/main/java/com/acgist/taoyao/media}/meeting/MeetingManager.java (97%) rename taoyao-signal/{taoyao-meeting/src/main/java/com/acgist/taoyao => taoyao-media/src/main/java/com/acgist/taoyao/media}/meeting/controller/MeetingController.java (90%) rename taoyao-signal/{taoyao-meeting/src/main/java/com/acgist/taoyao => taoyao-media/src/main/java/com/acgist/taoyao/media}/meeting/listener/MeetingCreateListener.java (79%) rename taoyao-signal/{taoyao-meeting/src/main/java/com/acgist/taoyao => taoyao-media/src/main/java/com/acgist/taoyao/media}/meeting/listener/MeetingEnterListener.java (86%) delete mode 100644 taoyao-signal/taoyao-meeting/pom.xml diff --git a/taoyao-media/README.md b/taoyao-media/README.md index e5d541f..3b1e0f5 100644 --- a/taoyao-media/README.md +++ b/taoyao-media/README.md @@ -16,5 +16,5 @@ git submodule update --remote ## 使用 ``` - +sudo npm install ``` \ No newline at end of file diff --git a/taoyao-media/config.js b/taoyao-media/config.js new file mode 100644 index 0000000..250b480 --- /dev/null +++ b/taoyao-media/config.js @@ -0,0 +1,164 @@ +/** + * 配置 + */ +const os = require('os'); + +module.exports = +{ + // Listening hostname (just for `gulp live` task). + domain : process.env.DOMAIN || 'localhost', + // Signaling settings (protoo WebSocket server and HTTP API server). + https : + { + listenIp : '0.0.0.0', + // NOTE: Don't change listenPort (client app assumes 4443). + listenPort : process.env.PROTOO_LISTEN_PORT || 4443, + // NOTE: Set your own valid certificate files. + tls : + { + cert : process.env.HTTPS_CERT_FULLCHAIN || `${__dirname}/certs/fullchain.pem`, + key : process.env.HTTPS_CERT_PRIVKEY || `${__dirname}/certs/privkey.pem` + } + }, + // mediasoup settings. + mediasoup : + { + // Number of mediasoup workers to launch. + numWorkers : Object.keys(os.cpus()).length, + // mediasoup WorkerSettings. + // See https://mediasoup.org/documentation/v3/mediasoup/api/#WorkerSettings + workerSettings : + { + logLevel : 'warn', + logTags : + [ + 'info', + 'ice', + 'dtls', + 'rtp', + 'srtp', + 'rtcp', + 'rtx', + 'bwe', + 'score', + 'simulcast', + 'svc', + 'sctp' + ], + rtcMinPort : process.env.MEDIASOUP_MIN_PORT || 40000, + rtcMaxPort : process.env.MEDIASOUP_MAX_PORT || 49999 + }, + // mediasoup Router options. + // See https://mediasoup.org/documentation/v3/mediasoup/api/#RouterOptions + routerOptions : + { + mediaCodecs : + [ + { + kind : 'audio', + mimeType : 'audio/opus', + clockRate : 48000, + channels : 2 + }, + { + kind : 'video', + mimeType : 'video/VP8', + clockRate : 90000, + parameters : + { + 'x-google-start-bitrate' : 1000 + } + }, + { + kind : 'video', + mimeType : 'video/VP9', + clockRate : 90000, + parameters : + { + 'profile-id' : 2, + 'x-google-start-bitrate' : 1000 + } + }, + { + kind : 'video', + mimeType : 'video/h264', + clockRate : 90000, + parameters : + { + 'packetization-mode' : 1, + 'profile-level-id' : '4d0032', + 'level-asymmetry-allowed' : 1, + 'x-google-start-bitrate' : 1000 + } + }, + { + kind : 'video', + mimeType : 'video/h264', + clockRate : 90000, + parameters : + { + 'packetization-mode' : 1, + 'profile-level-id' : '42e01f', + 'level-asymmetry-allowed' : 1, + 'x-google-start-bitrate' : 1000 + } + } + ] + }, + // mediasoup WebRtcServer options for WebRTC endpoints (mediasoup-client, + // libmediasoupclient). + // See https://mediasoup.org/documentation/v3/mediasoup/api/#WebRtcServerOptions + // NOTE: mediasoup-demo/server/lib/Room.js will increase this port for + // each mediasoup Worker since each Worker is a separate process. + webRtcServerOptions : + { + listenInfos : + [ + { + protocol : 'udp', + ip : process.env.MEDIASOUP_LISTEN_IP || '0.0.0.0', + announcedIp : process.env.MEDIASOUP_ANNOUNCED_IP, + port : 44444 + }, + { + protocol : 'tcp', + ip : process.env.MEDIASOUP_LISTEN_IP || '0.0.0.0', + announcedIp : process.env.MEDIASOUP_ANNOUNCED_IP, + port : 44444 + } + ], + }, + // mediasoup WebRtcTransport options for WebRTC endpoints (mediasoup-client, + // libmediasoupclient). + // See https://mediasoup.org/documentation/v3/mediasoup/api/#WebRtcTransportOptions + webRtcTransportOptions : + { + // listenIps is not needed since webRtcServer is used. + // However passing MEDIASOUP_USE_WEBRTC_SERVER=false will change it. + listenIps : + [ + { + ip : process.env.MEDIASOUP_LISTEN_IP || '0.0.0.0', + announcedIp : process.env.MEDIASOUP_ANNOUNCED_IP + } + ], + initialAvailableOutgoingBitrate : 1000000, + minimumAvailableOutgoingBitrate : 600000, + maxSctpMessageSize : 262144, + // Additional options that are not part of WebRtcTransportOptions. + maxIncomingBitrate : 1500000 + }, + // mediasoup PlainTransport options for legacy RTP endpoints (FFmpeg, + // GStreamer). + // See https://mediasoup.org/documentation/v3/mediasoup/api/#PlainTransportOptions + plainTransportOptions : + { + listenIp : + { + ip : process.env.MEDIASOUP_LISTEN_IP || '0.0.0.0', + announcedIp : process.env.MEDIASOUP_ANNOUNCED_IP + }, + maxSctpMessageSize : 262144 + } + } +}; \ No newline at end of file diff --git a/taoyao-media/package.json b/taoyao-media/package.json new file mode 100644 index 0000000..336520d --- /dev/null +++ b/taoyao-media/package.json @@ -0,0 +1,16 @@ +{ + "name": "taoyao-media", + "author": "acgist", + "version": "1.0.0", + "private": true, + "license": "All Rights Reserved", + "description": "taoyao media server", + "scripts": { + "start": "DEBUG=${DEBUG:='*mediasoup* *INFO* *WARN* *ERROR*'} INTERACTIVE=${INTERACTIVE:='true'} node server.js" + }, + "dependencies": { + "mediasoup": "file:./mediasoup" + }, + "devDependencies": { + } +} diff --git a/taoyao-media/server.js b/taoyao-media/server.js index 438b8fe..ef7dd0d 100644 --- a/taoyao-media/server.js +++ b/taoyao-media/server.js @@ -1,3 +1,557 @@ /** * 媒体服务 - */ \ No newline at end of file + */ +#!/usr/bin/env node + +process.title = 'taoyao-client'; +process.env.DEBUG = process.env.DEBUG || '*INFO* *WARN* *ERROR*'; + +const config = require('./config'); + +/* eslint-disable no-console */ +console.log('process.env.DEBUG:', process.env.DEBUG); +console.log('config.js:\n%s', JSON.stringify(config, null, ' ')); +/* eslint-enable no-console */ + +const fs = require('fs'); +const url = require('url'); +const https = require('https'); +const protoo = require('protoo-server'); +const express = require('express'); +const mediasoup = require('mediasoup'); + +const logger = new Logger(); + +// Async queue to manage rooms. +// @type {AwaitQueue} +const queue = new AwaitQueue(); + +// Map of Room instances indexed by roomId. +// @type {Map} +const rooms = new Map(); + +// HTTPS server. +// @type {https.Server} +let httpsServer; + +// Express application. +// @type {Function} +let expressApp; + +// Protoo WebSocket server. +// @type {protoo.WebSocketServer} +let protooWebSocketServer; + +// mediasoup Workers. +// @type {Array} +const mediasoupWorkers = []; + +// Index of next mediasoup Worker to use. +// @type {Number} +let nextMediasoupWorkerIdx = 0; + +run(); + +async function run() +{ + // Open the interactive server. + await interactiveServer(); + + // Open the interactive client. + if (process.env.INTERACTIVE === 'true' || process.env.INTERACTIVE === '1') + await interactiveClient(); + + // Run a mediasoup Worker. + await runMediasoupWorkers(); + + // Create Express app. + await createExpressApp(); + + // Run HTTPS server. + await runHttpsServer(); + + // Run a protoo WebSocketServer. + await runProtooWebSocketServer(); + + // Log rooms status every X seconds. + setInterval(() => + { + for (const room of rooms.values()) + { + room.logStatus(); + } + }, 120000); +} + +/** + * Launch as many mediasoup Workers as given in the configuration file. + */ +async function runMediasoupWorkers() +{ + const { numWorkers } = config.mediasoup; + + logger.info('running %d mediasoup Workers...', numWorkers); + + for (let i = 0; i < numWorkers; ++i) + { + const worker = await mediasoup.createWorker( + { + logLevel : config.mediasoup.workerSettings.logLevel, + logTags : config.mediasoup.workerSettings.logTags, + rtcMinPort : Number(config.mediasoup.workerSettings.rtcMinPort), + rtcMaxPort : Number(config.mediasoup.workerSettings.rtcMaxPort) + }); + + worker.on('died', () => + { + logger.error( + 'mediasoup Worker died, exiting in 2 seconds... [pid:%d]', worker.pid); + + setTimeout(() => process.exit(1), 2000); + }); + + mediasoupWorkers.push(worker); + + // Create a WebRtcServer in this Worker. + if (process.env.MEDIASOUP_USE_WEBRTC_SERVER !== 'false') + { + // Each mediasoup Worker will run its own WebRtcServer, so those cannot + // share the same listening ports. Hence we increase the value in config.js + // for each Worker. + const webRtcServerOptions = utils.clone(config.mediasoup.webRtcServerOptions); + const portIncrement = mediasoupWorkers.length - 1; + + for (const listenInfo of webRtcServerOptions.listenInfos) + { + listenInfo.port += portIncrement; + } + + const webRtcServer = await worker.createWebRtcServer(webRtcServerOptions); + + worker.appData.webRtcServer = webRtcServer; + } + + // Log worker resource usage every X seconds. + setInterval(async () => + { + const usage = await worker.getResourceUsage(); + + logger.info('mediasoup Worker resource usage [pid:%d]: %o', worker.pid, usage); + }, 120000); + } +} + +/** + * Create an Express based API server to manage Broadcaster requests. + */ +async function createExpressApp() +{ + logger.info('creating Express app...'); + + expressApp = express(); + + expressApp.use(bodyParser.json()); + + /** + * For every API request, verify that the roomId in the path matches and + * existing room. + */ + expressApp.param( + 'roomId', (req, res, next, roomId) => + { + // The room must exist for all API requests. + if (!rooms.has(roomId)) + { + const error = new Error(`room with id "${roomId}" not found`); + + error.status = 404; + throw error; + } + + req.room = rooms.get(roomId); + + next(); + }); + + /** + * API GET resource that returns the mediasoup Router RTP capabilities of + * the room. + */ + expressApp.get( + '/rooms/:roomId', (req, res) => + { + const data = req.room.getRouterRtpCapabilities(); + + res.status(200).json(data); + }); + + /** + * POST API to create a Broadcaster. + */ + expressApp.post( + '/rooms/:roomId/broadcasters', async (req, res, next) => + { + const { + id, + displayName, + device, + rtpCapabilities + } = req.body; + + try + { + const data = await req.room.createBroadcaster( + { + id, + displayName, + device, + rtpCapabilities + }); + + res.status(200).json(data); + } + catch (error) + { + next(error); + } + }); + + /** + * DELETE API to delete a Broadcaster. + */ + expressApp.delete( + '/rooms/:roomId/broadcasters/:broadcasterId', (req, res) => + { + const { broadcasterId } = req.params; + + req.room.deleteBroadcaster({ broadcasterId }); + + res.status(200).send('broadcaster deleted'); + }); + + /** + * POST API to create a mediasoup Transport associated to a Broadcaster. + * It can be a PlainTransport or a WebRtcTransport depending on the + * type parameters in the body. There are also additional parameters for + * PlainTransport. + */ + expressApp.post( + '/rooms/:roomId/broadcasters/:broadcasterId/transports', + async (req, res, next) => + { + const { broadcasterId } = req.params; + const { type, rtcpMux, comedia, sctpCapabilities } = req.body; + + try + { + const data = await req.room.createBroadcasterTransport( + { + broadcasterId, + type, + rtcpMux, + comedia, + sctpCapabilities + }); + + res.status(200).json(data); + } + catch (error) + { + next(error); + } + }); + + /** + * POST API to connect a Transport belonging to a Broadcaster. Not needed + * for PlainTransport if it was created with comedia option set to true. + */ + expressApp.post( + '/rooms/:roomId/broadcasters/:broadcasterId/transports/:transportId/connect', + async (req, res, next) => + { + const { broadcasterId, transportId } = req.params; + const { dtlsParameters } = req.body; + + try + { + const data = await req.room.connectBroadcasterTransport( + { + broadcasterId, + transportId, + dtlsParameters + }); + + res.status(200).json(data); + } + catch (error) + { + next(error); + } + }); + + /** + * POST API to create a mediasoup Producer associated to a Broadcaster. + * The exact Transport in which the Producer must be created is signaled in + * the URL path. Body parameters include kind and rtpParameters of the + * Producer. + */ + expressApp.post( + '/rooms/:roomId/broadcasters/:broadcasterId/transports/:transportId/producers', + async (req, res, next) => + { + const { broadcasterId, transportId } = req.params; + const { kind, rtpParameters } = req.body; + + try + { + const data = await req.room.createBroadcasterProducer( + { + broadcasterId, + transportId, + kind, + rtpParameters + }); + + res.status(200).json(data); + } + catch (error) + { + next(error); + } + }); + + /** + * POST API to create a mediasoup Consumer associated to a Broadcaster. + * The exact Transport in which the Consumer must be created is signaled in + * the URL path. Query parameters must include the desired producerId to + * consume. + */ + expressApp.post( + '/rooms/:roomId/broadcasters/:broadcasterId/transports/:transportId/consume', + async (req, res, next) => + { + const { broadcasterId, transportId } = req.params; + const { producerId } = req.query; + + try + { + const data = await req.room.createBroadcasterConsumer( + { + broadcasterId, + transportId, + producerId + }); + + res.status(200).json(data); + } + catch (error) + { + next(error); + } + }); + + /** + * POST API to create a mediasoup DataConsumer associated to a Broadcaster. + * The exact Transport in which the DataConsumer must be created is signaled in + * the URL path. Query body must include the desired producerId to + * consume. + */ + expressApp.post( + '/rooms/:roomId/broadcasters/:broadcasterId/transports/:transportId/consume/data', + async (req, res, next) => + { + const { broadcasterId, transportId } = req.params; + const { dataProducerId } = req.body; + + try + { + const data = await req.room.createBroadcasterDataConsumer( + { + broadcasterId, + transportId, + dataProducerId + }); + + res.status(200).json(data); + } + catch (error) + { + next(error); + } + }); + + /** + * POST API to create a mediasoup DataProducer associated to a Broadcaster. + * The exact Transport in which the DataProducer must be created is signaled in + */ + expressApp.post( + '/rooms/:roomId/broadcasters/:broadcasterId/transports/:transportId/produce/data', + async (req, res, next) => + { + const { broadcasterId, transportId } = req.params; + const { label, protocol, sctpStreamParameters, appData } = req.body; + + try + { + const data = await req.room.createBroadcasterDataProducer( + { + broadcasterId, + transportId, + label, + protocol, + sctpStreamParameters, + appData + }); + + res.status(200).json(data); + } + catch (error) + { + next(error); + } + }); + + /** + * Error handler. + */ + expressApp.use( + (error, req, res, next) => + { + if (error) + { + logger.warn('Express app %s', String(error)); + + error.status = error.status || (error.name === 'TypeError' ? 400 : 500); + + res.statusMessage = error.message; + res.status(error.status).send(String(error)); + } + else + { + next(); + } + }); +} + +/** + * Create a Node.js HTTPS server. It listens in the IP and port given in the + * configuration file and reuses the Express application as request listener. + */ +async function runHttpsServer() +{ + logger.info('running an HTTPS server...'); + + // HTTPS server for the protoo WebSocket server. + const tls = + { + cert : fs.readFileSync(config.https.tls.cert), + key : fs.readFileSync(config.https.tls.key) + }; + + httpsServer = https.createServer(tls, expressApp); + + await new Promise((resolve) => + { + httpsServer.listen( + Number(config.https.listenPort), config.https.listenIp, resolve); + }); +} + +/** + * Create a protoo WebSocketServer to allow WebSocket connections from browsers. + */ +async function runProtooWebSocketServer() +{ + logger.info('running protoo WebSocketServer...'); + + // Create the protoo WebSocket server. + protooWebSocketServer = new protoo.WebSocketServer(httpsServer, + { + maxReceivedFrameSize : 960000, // 960 KBytes. + maxReceivedMessageSize : 960000, + fragmentOutgoingMessages : true, + fragmentationThreshold : 960000 + }); + + // Handle connections from clients. + protooWebSocketServer.on('connectionrequest', (info, accept, reject) => + { + // The client indicates the roomId and peerId in the URL query. + const u = url.parse(info.request.url, true); + const roomId = u.query['roomId']; + const peerId = u.query['peerId']; + + if (!roomId || !peerId) + { + reject(400, 'Connection request without roomId and/or peerId'); + + return; + } + + let consumerReplicas = Number(u.query['consumerReplicas']); + + if (isNaN(consumerReplicas)) + { + consumerReplicas = 0; + } + + logger.info( + 'protoo connection request [roomId:%s, peerId:%s, address:%s, origin:%s]', + roomId, peerId, info.socket.remoteAddress, info.origin); + + // Serialize this code into the queue to avoid that two peers connecting at + // the same time with the same roomId create two separate rooms with same + // roomId. + queue.push(async () => + { + const room = await getOrCreateRoom({ roomId, consumerReplicas }); + + // Accept the protoo WebSocket connection. + const protooWebSocketTransport = accept(); + + room.handleProtooConnection({ peerId, protooWebSocketTransport }); + }) + .catch((error) => + { + logger.error('room creation or room joining failed:%o', error); + + reject(error); + }); + }); +} + +/** + * Get next mediasoup Worker. + */ +function getMediasoupWorker() +{ + const worker = mediasoupWorkers[nextMediasoupWorkerIdx]; + + if (++nextMediasoupWorkerIdx === mediasoupWorkers.length) + nextMediasoupWorkerIdx = 0; + + return worker; +} + +/** + * Get a Room instance (or create one if it does not exist). + */ +async function getOrCreateRoom({ roomId, consumerReplicas }) +{ + let room = rooms.get(roomId); + + // If the Room does not exist create a new one. + if (!room) + { + logger.info('creating a new Room [roomId:%s]', roomId); + + const mediasoupWorker = getMediasoupWorker(); + + room = await Room.create({ mediasoupWorker, roomId, consumerReplicas }); + + rooms.set(roomId, room); + room.on('close', () => rooms.delete(roomId)); + } + + return room; +} diff --git a/taoyao-signal/README.md b/taoyao-signal/README.md index 65a4c59..b0d1c42 100644 --- a/taoyao-signal/README.md +++ b/taoyao-signal/README.md @@ -7,13 +7,17 @@ |taoyao|桃夭|桃之夭夭灼灼其华| |taoyao-boot|基础|基础模块| |taoyao-node|集群|集群模块| -|taoyao-live|直播|直播、连麦、监控、视频同看| -|taoyao-media|媒体|Mediasoup| +|taoyao-media|媒体|媒体模块| |taoyao-signal|信令|信令服务| |taoyao-server|服务|启动服务| -|taoyao-meeting|会议|会议模式、广播模式、单人对讲| -> 媒体处理均由Mediasoup实现 +### 直播 + +直播、连麦、监控、视频同看 + +### 会议 + +会议模式、广播模式、单人对讲 ## 模块关系 @@ -21,8 +25,6 @@ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | taoyao-server | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| taoyao-live | taoyao-meeting | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | taoyao-media | Mediasoup | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | taoyao-signal | diff --git a/taoyao-signal/pom.xml b/taoyao-signal/pom.xml index 926c65d..885e259 100644 --- a/taoyao-signal/pom.xml +++ b/taoyao-signal/pom.xml @@ -37,11 +37,9 @@ taoyao-boot taoyao-node - taoyao-live taoyao-media taoyao-signal taoyao-server - taoyao-meeting @@ -109,7 +107,7 @@ com.acgist - taoyao-live + taoyao-node ${project.version} @@ -117,11 +115,6 @@ taoyao-media ${project.version} - - com.acgist - taoyao-server - ${project.version} - com.acgist taoyao-signal @@ -129,7 +122,7 @@ com.acgist - taoyao-meeting + taoyao-server ${project.version} diff --git a/taoyao-signal/taoyao-live/pom.xml b/taoyao-signal/taoyao-live/pom.xml deleted file mode 100644 index 2fc05eb..0000000 --- a/taoyao-signal/taoyao-live/pom.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - 4.0.0 - - - com.acgist - taoyao - 1.0.0 - - - taoyao-live - jar - - taoyao-live - 直播:直播、连麦 - - - - com.acgist - taoyao-media - - - - \ No newline at end of file diff --git a/taoyao-signal/taoyao-live/src/main/java/com/acgist/taoyao/live/Live.java b/taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/live/Live.java similarity index 96% rename from taoyao-signal/taoyao-live/src/main/java/com/acgist/taoyao/live/Live.java rename to taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/live/Live.java index 4d8a580..540609c 100644 --- a/taoyao-signal/taoyao-live/src/main/java/com/acgist/taoyao/live/Live.java +++ b/taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/live/Live.java @@ -1,4 +1,4 @@ -package com.acgist.taoyao.live; +package com.acgist.taoyao.media.live; import java.util.List; diff --git a/taoyao-signal/taoyao-live/src/main/java/com/acgist/taoyao/live/LiveListenerAdapter.java b/taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/live/LiveListenerAdapter.java similarity index 92% rename from taoyao-signal/taoyao-live/src/main/java/com/acgist/taoyao/live/LiveListenerAdapter.java rename to taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/live/LiveListenerAdapter.java index ada6f19..37b29dc 100644 --- a/taoyao-signal/taoyao-live/src/main/java/com/acgist/taoyao/live/LiveListenerAdapter.java +++ b/taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/live/LiveListenerAdapter.java @@ -1,4 +1,4 @@ -package com.acgist.taoyao.live; +package com.acgist.taoyao.media.live; import org.springframework.beans.factory.annotation.Autowired; diff --git a/taoyao-signal/taoyao-live/src/main/java/com/acgist/taoyao/live/LiveManager.java b/taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/live/LiveManager.java similarity index 78% rename from taoyao-signal/taoyao-live/src/main/java/com/acgist/taoyao/live/LiveManager.java rename to taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/live/LiveManager.java index 5476064..4dc1cd4 100644 --- a/taoyao-signal/taoyao-live/src/main/java/com/acgist/taoyao/live/LiveManager.java +++ b/taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/live/LiveManager.java @@ -1,4 +1,4 @@ -package com.acgist.taoyao.live; +package com.acgist.taoyao.media.live; import com.acgist.taoyao.boot.annotation.Manager; diff --git a/taoyao-signal/taoyao-live/src/main/java/com/acgist/taoyao/live/controller/LiveController.java b/taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/live/controller/LiveController.java similarity index 93% rename from taoyao-signal/taoyao-live/src/main/java/com/acgist/taoyao/live/controller/LiveController.java rename to taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/live/controller/LiveController.java index 50f3851..5ab0ce3 100644 --- a/taoyao-signal/taoyao-live/src/main/java/com/acgist/taoyao/live/controller/LiveController.java +++ b/taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/live/controller/LiveController.java @@ -1,4 +1,4 @@ -package com.acgist.taoyao.live.controller; +package com.acgist.taoyao.media.live.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -6,7 +6,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.live.Live; +import com.acgist.taoyao.media.live.Live; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; diff --git a/taoyao-signal/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/Meeting.java b/taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/meeting/Meeting.java similarity index 96% rename from taoyao-signal/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/Meeting.java rename to taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/meeting/Meeting.java index 5a397d9..de56d3a 100644 --- a/taoyao-signal/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/Meeting.java +++ b/taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/meeting/Meeting.java @@ -1,4 +1,4 @@ -package com.acgist.taoyao.meeting; +package com.acgist.taoyao.media.meeting; import java.util.List; diff --git a/taoyao-signal/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/MeetingListenerAdapter.java b/taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/meeting/MeetingListenerAdapter.java similarity index 91% rename from taoyao-signal/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/MeetingListenerAdapter.java rename to taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/meeting/MeetingListenerAdapter.java index af4db37..5dd27b8 100644 --- a/taoyao-signal/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/MeetingListenerAdapter.java +++ b/taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/meeting/MeetingListenerAdapter.java @@ -1,4 +1,4 @@ -package com.acgist.taoyao.meeting; +package com.acgist.taoyao.media.meeting; import org.springframework.beans.factory.annotation.Autowired; diff --git a/taoyao-signal/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/MeetingManager.java b/taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/meeting/MeetingManager.java similarity index 97% rename from taoyao-signal/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/MeetingManager.java rename to taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/meeting/MeetingManager.java index 233c5e3..8f6667c 100644 --- a/taoyao-signal/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/MeetingManager.java +++ b/taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/meeting/MeetingManager.java @@ -1,4 +1,4 @@ -package com.acgist.taoyao.meeting; +package com.acgist.taoyao.media.meeting; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; diff --git a/taoyao-signal/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/controller/MeetingController.java b/taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/meeting/controller/MeetingController.java similarity index 90% rename from taoyao-signal/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/controller/MeetingController.java rename to taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/meeting/controller/MeetingController.java index 5e38e34..71f792f 100644 --- a/taoyao-signal/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/controller/MeetingController.java +++ b/taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/meeting/controller/MeetingController.java @@ -1,4 +1,4 @@ -package com.acgist.taoyao.meeting.controller; +package com.acgist.taoyao.media.meeting.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; @@ -7,8 +7,8 @@ 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.meeting.Meeting; -import com.acgist.taoyao.meeting.MeetingManager; +import com.acgist.taoyao.media.meeting.Meeting; +import com.acgist.taoyao.media.meeting.MeetingManager; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; diff --git a/taoyao-signal/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/listener/MeetingCreateListener.java b/taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/meeting/listener/MeetingCreateListener.java similarity index 79% rename from taoyao-signal/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/listener/MeetingCreateListener.java rename to taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/meeting/listener/MeetingCreateListener.java index 696f38b..d8e9a28 100644 --- a/taoyao-signal/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/listener/MeetingCreateListener.java +++ b/taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/meeting/listener/MeetingCreateListener.java @@ -1,11 +1,11 @@ -package com.acgist.taoyao.meeting.listener; +package com.acgist.taoyao.media.meeting.listener; import java.util.Map; import com.acgist.taoyao.boot.annotation.EventListener; import com.acgist.taoyao.boot.model.Message; -import com.acgist.taoyao.meeting.Meeting; -import com.acgist.taoyao.meeting.MeetingListenerAdapter; +import com.acgist.taoyao.media.meeting.Meeting; +import com.acgist.taoyao.media.meeting.MeetingListenerAdapter; import com.acgist.taoyao.signal.event.meeting.MeetingCreateEvent; /** diff --git a/taoyao-signal/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/listener/MeetingEnterListener.java b/taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/meeting/listener/MeetingEnterListener.java similarity index 86% rename from taoyao-signal/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/listener/MeetingEnterListener.java rename to taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/meeting/listener/MeetingEnterListener.java index 18266b1..5d76e06 100644 --- a/taoyao-signal/taoyao-meeting/src/main/java/com/acgist/taoyao/meeting/listener/MeetingEnterListener.java +++ b/taoyao-signal/taoyao-media/src/main/java/com/acgist/taoyao/media/meeting/listener/MeetingEnterListener.java @@ -1,4 +1,4 @@ -package com.acgist.taoyao.meeting.listener; +package com.acgist.taoyao.media.meeting.listener; import java.util.Map; @@ -6,8 +6,8 @@ import com.acgist.taoyao.boot.annotation.EventListener; import com.acgist.taoyao.boot.model.Message; import com.acgist.taoyao.boot.model.MessageCode; import com.acgist.taoyao.boot.model.MessageCodeException; -import com.acgist.taoyao.meeting.Meeting; -import com.acgist.taoyao.meeting.MeetingListenerAdapter; +import com.acgist.taoyao.media.meeting.Meeting; +import com.acgist.taoyao.media.meeting.MeetingListenerAdapter; import com.acgist.taoyao.signal.event.meeting.MeetingEnterEvent; /** diff --git a/taoyao-signal/taoyao-meeting/pom.xml b/taoyao-signal/taoyao-meeting/pom.xml deleted file mode 100644 index d59724d..0000000 --- a/taoyao-signal/taoyao-meeting/pom.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - 4.0.0 - - - com.acgist - taoyao - 1.0.0 - - - taoyao-meeting - jar - - taoyao-meeting - 会议:会议模式、广播模式、单人对讲 - - - - com.acgist - taoyao-media - - - - \ No newline at end of file diff --git a/taoyao-signal/taoyao-server/pom.xml b/taoyao-signal/taoyao-server/pom.xml index 79b8168..a11490a 100644 --- a/taoyao-signal/taoyao-server/pom.xml +++ b/taoyao-signal/taoyao-server/pom.xml @@ -24,11 +24,7 @@ com.acgist - taoyao-live - - - com.acgist - taoyao-meeting + taoyao-media