[*] 共享本地视频文件

This commit is contained in:
acgist
2023-09-11 09:11:03 +08:00
parent dc2334e8b6
commit 3575cbee4e
2 changed files with 130 additions and 93 deletions

View File

@@ -887,23 +887,19 @@ class Taoyao {
}); });
producer.observer.on("resume", () => { producer.observer.on("resume", () => {
console.debug("生产者恢复", producer.id, streamId); console.debug("生产者恢复", producer.id, streamId);
me.push( me.push(protocol.buildMessage("media::producer::resume", {
protocol.buildMessage("media::producer::resume", { roomId,
roomId : roomId, producerId: producer.id
producerId: producer.id }));
})
);
}); });
// producer.observer.on("score", fn(score)); // producer.observer.on("score", fn(score));
producer.on("score", (score) => { producer.on("score", (score) => {
console.debug("生产者评分", producer.id, streamId, score); console.debug("生产者评分", producer.id, streamId, score);
me.push( me.push(protocol.buildMessage("media::producer::score", {
protocol.buildMessage("media::producer::score", { score,
roomId : roomId, roomId,
producerId: producer.id, producerId: producer.id,
score : score, }));
})
);
}); });
// producer.observer.on("videoorientationchange", fn(videoOrientation)); // producer.observer.on("videoorientationchange", fn(videoOrientation));
producer.on("videoorientationchange", (videoOrientation) => { producer.on("videoorientationchange", (videoOrientation) => {
@@ -926,13 +922,6 @@ class Taoyao {
producerId: producer.id producerId: producer.id
}; };
me.push(message); me.push(message);
// me.push(
// protocol.buildMessage("media::producer::score", {
// roomId : roomId,
// producerId: producer.id,
// score : producer.score,
// })
// );
if (producer.kind === "audio") { if (producer.kind === "audio") {
// TODO关闭生产者时移除监听 // TODO关闭生产者时移除监听
room.audioLevelObserver room.audioLevelObserver
@@ -1161,13 +1150,6 @@ class Taoyao {
); );
await consumer.resume(); await consumer.resume();
consumer.localPaused = false; consumer.localPaused = false;
// me.push(
// protocol.buildMessage("media::consumer::score", {
// roomId : roomId,
// consumerId: consumer.id,
// score : consumer.score,
// })
// );
})() })()
); );
} }

View File

@@ -550,6 +550,8 @@ class Taoyao extends RemoteClient {
mediasoupDevice; mediasoupDevice;
// 文件共享 // 文件共享
fileVideo; fileVideo;
// 文件共享地址
fileVideoObjectURL;
// 视频来源file|camera|screen // 视频来源file|camera|screen
videoSource; videoSource;
// 强制使用TCP // 强制使用TCP
@@ -608,7 +610,6 @@ class Taoyao extends RemoteClient {
dataProduce = true, dataProduce = true,
audioProduce = true, audioProduce = true,
videoProduce = true, videoProduce = true,
fileVideo = null,
videoSource = "camera", videoSource = "camera",
forceTcp = false, forceTcp = false,
forceVP8 = false, forceVP8 = false,
@@ -631,7 +632,6 @@ class Taoyao extends RemoteClient {
this.dataProduce = dataProduce; this.dataProduce = dataProduce;
this.audioProduce = audioProduce; this.audioProduce = audioProduce;
this.videoProduce = videoProduce; this.videoProduce = videoProduce;
this.fileVideo = fileVideo;
this.videoSource = videoSource; this.videoSource = videoSource;
this.forceTcp = forceTcp; this.forceTcp = forceTcp;
this.forceVP8 = forceVP8; 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 媒体 * @returns 媒体
*/ */
@@ -937,6 +983,7 @@ class Taoyao extends RemoteClient {
const me = this; const me = this;
let stream; let stream;
if (me.videoSource === "file") { if (me.videoSource === "file") {
await this.getFileVideo();
stream = me.fileVideo.captureStream(); stream = me.fileVideo.captureStream();
} else if (me.videoSource === "camera") { } else if (me.videoSource === "camera") {
console.debug("媒体配置", me.audioConfig, me.videoConfig); console.debug("媒体配置", me.audioConfig, me.videoConfig);
@@ -1016,6 +1063,7 @@ class Taoyao extends RemoteClient {
let stream; let stream;
const me = this; const me = this;
if (me.videoSource === "file") { if (me.videoSource === "file") {
await this.getFileVideo();
stream = me.fileVideo.captureStream(); stream = me.fileVideo.captureStream();
} else if (me.videoSource === "camera") { } else if (me.videoSource === "camera") {
stream = await navigator.mediaDevices.getUserMedia({ 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) { async exchangeVideoSource(videoSource) {
const me = this; const me = this;
console.debug("切换视频来源", videoSource, me.videoSource); console.debug("切换视频来源", videoSource, me.videoSource);
const old = this.videoSource;
if(videoSource) { if(videoSource) {
me.videoSource = videoSource; me.videoSource = videoSource;
} else { } else {
@@ -2410,6 +2408,9 @@ class Taoyao extends RemoteClient {
} }
} }
await me.updateVideoProducer(); 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 视频 * @param {*} video 视频
*/ */
localPhotograph(video) { localPhotograph(video) {
const me = this; const canvas = document.createElement("canvas");
const canvas = document.createElement('canvas');
canvas.width = video.videoWidth; canvas.width = video.videoWidth;
canvas.height = video.videoHeight; canvas.height = video.videoHeight;
const context = canvas.getContext('2d'); const context = canvas.getContext("2d");
context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight); context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
const dataURL = canvas.toDataURL('images/png'); const dataURL = canvas.toDataURL("images/png");
const download = document.createElement('a'); const download = document.createElement("a");
download.href = dataURL; download.href = dataURL;
download.download = 'taoyao.png'; download.download = "taoyao.png";
download.style.display = 'none'; // download.style.display = "none";
document.body.appendChild(download); // document.body.appendChild(download);
download.click(); download.click();
// 释放资源
canvas.remove();
download.remove(); download.remove();
} }
@@ -3485,11 +3540,11 @@ class Taoyao extends RemoteClient {
me.mediaRecorder.onstop = (e) => { me.mediaRecorder.onstop = (e) => {
const blob = new Blob(me.mediaRecorderChunks); const blob = new Blob(me.mediaRecorderChunks);
const objectURL = URL.createObjectURL(blob); const objectURL = URL.createObjectURL(blob);
const download = document.createElement('a'); const download = document.createElement("a");
download.href = objectURL; download.href = objectURL;
download.download = 'taoyao.mp4'; download.download = "taoyao.mp4";
download.style.display = 'none'; // download.style.display = "none";
document.body.appendChild(download); // document.body.appendChild(download);
download.click(); download.click();
download.remove(); download.remove();
URL.revokeObjectURL(objectURL); URL.revokeObjectURL(objectURL);