From 3575cbee4e038f93d641fab3313bb83052abaccf Mon Sep 17 00:00:00 2001 From: acgist <289547414@qq.com> Date: Mon, 11 Sep 2023 09:11:03 +0800 Subject: [PATCH] =?UTF-8?q?[*]=20=E5=85=B1=E4=BA=AB=E6=9C=AC=E5=9C=B0?= =?UTF-8?q?=E8=A7=86=E9=A2=91=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- taoyao-client-media/src/Taoyao.js | 36 +--- taoyao-client-web/src/components/Taoyao.js | 187 +++++++++++++-------- 2 files changed, 130 insertions(+), 93 deletions(-) diff --git a/taoyao-client-media/src/Taoyao.js b/taoyao-client-media/src/Taoyao.js index a722eb1..074d339 100644 --- a/taoyao-client-media/src/Taoyao.js +++ b/taoyao-client-media/src/Taoyao.js @@ -887,23 +887,19 @@ class Taoyao { }); producer.observer.on("resume", () => { console.debug("生产者恢复", producer.id, streamId); - me.push( - protocol.buildMessage("media::producer::resume", { - roomId : roomId, - producerId: producer.id - }) - ); + me.push(protocol.buildMessage("media::producer::resume", { + roomId, + producerId: producer.id + })); }); // producer.observer.on("score", fn(score)); producer.on("score", (score) => { console.debug("生产者评分", producer.id, streamId, score); - me.push( - protocol.buildMessage("media::producer::score", { - roomId : roomId, - producerId: producer.id, - score : score, - }) - ); + me.push(protocol.buildMessage("media::producer::score", { + score, + roomId, + producerId: producer.id, + })); }); // producer.observer.on("videoorientationchange", fn(videoOrientation)); producer.on("videoorientationchange", (videoOrientation) => { @@ -926,13 +922,6 @@ class Taoyao { producerId: producer.id }; me.push(message); - // me.push( - // protocol.buildMessage("media::producer::score", { - // roomId : roomId, - // producerId: producer.id, - // score : producer.score, - // }) - // ); if (producer.kind === "audio") { // TODO:关闭生产者时移除监听 room.audioLevelObserver @@ -1161,13 +1150,6 @@ class Taoyao { ); await consumer.resume(); consumer.localPaused = false; - // me.push( - // protocol.buildMessage("media::consumer::score", { - // roomId : roomId, - // consumerId: consumer.id, - // score : consumer.score, - // }) - // ); })() ); } diff --git a/taoyao-client-web/src/components/Taoyao.js b/taoyao-client-web/src/components/Taoyao.js index 2f3d2a8..d7fe98a 100644 --- a/taoyao-client-web/src/components/Taoyao.js +++ b/taoyao-client-web/src/components/Taoyao.js @@ -550,6 +550,8 @@ class Taoyao extends RemoteClient { mediasoupDevice; // 文件共享 fileVideo; + // 文件共享地址 + fileVideoObjectURL; // 视频来源:file|camera|screen videoSource; // 强制使用TCP @@ -608,7 +610,6 @@ class Taoyao extends RemoteClient { dataProduce = true, audioProduce = true, videoProduce = true, - fileVideo = null, videoSource = "camera", forceTcp = false, forceVP8 = false, @@ -631,7 +632,6 @@ class Taoyao extends RemoteClient { this.dataProduce = dataProduce; this.audioProduce = audioProduce; this.videoProduce = videoProduce; - this.fileVideo = fileVideo; this.videoSource = videoSource; this.forceTcp = forceTcp; this.forceVP8 = forceVP8; @@ -930,6 +930,52 @@ class Taoyao extends RemoteClient { } } + /** + * 选择视频文件 + */ + async getFileVideo() { + const input = document.createElement("input"); + input.type = "file"; + const select = new Promise((resolve, reject) => { + input.onchange = (e) => { + resolve(input.value); + } + input.oncancel = (e) => { + resolve(null); + }; + }); + input.click(); + const file = await select; + input.remove(); + if(!file) { + console.debug("没有选择共享文件"); + return; + } + console.debug("选择文件", file); + this.fileVideo = document.createElement("video"); + this.fileVideo.loop = true; + this.fileVideo.muted = true; + this.fileVideo.controls = true; + this.fileVideo.src = URL.createObjectURL(input.files[0]); + this.fileVideo.style = "position:fixed;top:1rem;left:1rem;width:128px;border:2px solid #FFF;"; + // this.fileVideo.style.display = "none"; + document.body.appendChild(this.fileVideo); + // 开始播放不然不能采集 + await this.fileVideo.play(); + } + + /** + * 释放视频文件 + */ + async closeFileVideo() { + if(this.fileVideo) { + this.fileVideo.remove(); + } + if(this.fileVideoObjectURL) { + URL.revokeObjectURL(this.fileVideoObjectURL); + } + } + /** * @returns 媒体 */ @@ -937,6 +983,7 @@ class Taoyao extends RemoteClient { const me = this; let stream; if (me.videoSource === "file") { + await this.getFileVideo(); stream = me.fileVideo.captureStream(); } else if (me.videoSource === "camera") { console.debug("媒体配置", me.audioConfig, me.videoConfig); @@ -1016,6 +1063,7 @@ class Taoyao extends RemoteClient { let stream; const me = this; if (me.videoSource === "file") { + await this.getFileVideo(); stream = me.fileVideo.captureStream(); } else if (me.videoSource === "camera") { stream = await navigator.mediaDevices.getUserMedia({ @@ -1854,57 +1902,6 @@ class Taoyao extends RemoteClient { } } - /** - * 恢复生产者信令 - * - * @param {*} producerId 生产者ID - */ - mediaProducerResume(producerId) { - const me = this; - const producer = me.getProducer(producerId); - if(producer) { - if(!producer.paused) { - return; - } - console.debug("恢复生产者", producerId); - me.push(protocol.buildMessage("media::producer::resume", { - roomId : me.roomId, - producerId: producerId, - })); - } else { - console.debug("恢复生产者无效", producerId); - } - } - - /** - * 恢复生产者信令 - * - * @param {*} message 信令消息 - */ - async defaultMediaProducerResume(message) { - const me = this; - const { - roomId, - producerId - } = message.body; - const producer = me.getProducer(producerId); - if (producer) { - console.debug("恢复生产者", producerId); - producer.resume(); - } else { - console.debug("恢复生产者无效", producerId); - } - } - - /** - * 媒体生产者评分信令 - * - * @param {*} message 信令消息 - */ - defaultMediaProducerScore(message) { - console.debug("生产者评分", message); - } - /** * 消费媒体信令 * @@ -2396,6 +2393,7 @@ class Taoyao extends RemoteClient { async exchangeVideoSource(videoSource) { const me = this; console.debug("切换视频来源", videoSource, me.videoSource); + const old = this.videoSource; if(videoSource) { me.videoSource = videoSource; } else { @@ -2410,6 +2408,9 @@ class Taoyao extends RemoteClient { } } await me.updateVideoProducer(); + if(old === "file") { + this.closeFileVideo(); + } } /** @@ -2468,6 +2469,59 @@ class Taoyao extends RemoteClient { } } + /** + * 恢复生产者信令 + * + * @param {*} producerId 生产者ID + */ + mediaProducerResume(producerId) { + const producer = this.getProducer(producerId); + if(!producer) { + console.debug("恢复生产者(生产者无效)", producerId); + return; + } + if(!producer.paused) { + console.debug("恢复生产者(生产者已经恢复)", producerId); + return; + } + console.debug("恢复生产者", producerId); + this.push(protocol.buildMessage("media::producer::resume", { + producerId, + roomId: this.roomId, + })); + } + + /** + * 恢复生产者信令 + * + * @param {*} message 信令消息 + */ + async defaultMediaProducerResume(message) { + const { + producerId + } = message.body; + const producer = this.getProducer(producerId); + if (!producer) { + console.debug("恢复生产者(生产者无效)", producerId); + return; + } + if(!producer.paused) { + console.debug("恢复生产者(生产者已经恢复)", producerId); + return; + } + console.debug("恢复生产者", producerId); + producer.resume(); + } + + /** + * 媒体生产者评分信令 + * + * @param {*} message 信令消息 + */ + defaultMediaProducerScore(message) { + console.debug("生产者评分", message); + } + /** * 查询生产者状态信令 * @@ -3417,19 +3471,20 @@ class Taoyao extends RemoteClient { * @param {*} video 视频 */ localPhotograph(video) { - const me = this; - const canvas = document.createElement('canvas'); + const canvas = document.createElement("canvas"); canvas.width = video.videoWidth; canvas.height = video.videoHeight; - const context = canvas.getContext('2d'); + const context = canvas.getContext("2d"); context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight); - const dataURL = canvas.toDataURL('images/png'); - const download = document.createElement('a'); - download.href = dataURL; - download.download = 'taoyao.png'; - download.style.display = 'none'; - document.body.appendChild(download); + const dataURL = canvas.toDataURL("images/png"); + const download = document.createElement("a"); + download.href = dataURL; + download.download = "taoyao.png"; + // download.style.display = "none"; + // document.body.appendChild(download); download.click(); + // 释放资源 + canvas.remove(); download.remove(); } @@ -3485,11 +3540,11 @@ class Taoyao extends RemoteClient { me.mediaRecorder.onstop = (e) => { const blob = new Blob(me.mediaRecorderChunks); const objectURL = URL.createObjectURL(blob); - const download = document.createElement('a'); + const download = document.createElement("a"); download.href = objectURL; - download.download = 'taoyao.mp4'; - download.style.display = 'none'; - document.body.appendChild(download); + download.download = "taoyao.mp4"; + // download.style.display = "none"; + // document.body.appendChild(download); download.click(); download.remove(); URL.revokeObjectURL(objectURL);