【发布时间】:2022-02-16 11:21:15
【问题描述】:
我正在尝试仅发送 WebM 文件的特定截断部分,从任意关键帧开始,从 Node.js 服务器由客户端使用 MediaSource 缓冲播放,但我不确定这是否是可能的或如何去做。
到目前为止,这是我正在尝试的:
- 使用来自https://github.com/acolwell/mse-tools的
mse_json_manifest查找初始化段+关键帧簇的字节偏移和大小 - 初始化段和随机选择的媒体段的连接流
- 通过 HTTP 请求或套接字事件将流发送到客户端
看起来发送初始化段总是有效的,因为客户端的 HTMl5 视频播放器显示原始文件的持续时间,但它不缓冲之后发送的连接媒体段。
这是相关的服务器代码:
const merge = (...streams: ReadStream[]) => {
let pass = new PassThrough();
let waiting = streams.length;
for (let stream of streams) {
pass = stream.pipe(pass, {end: false});
stream.once("end", () => --waiting === 0 && pass.emit("end"));
}
return pass;
}
io.on("connection", (socket) => {
const streams = [
fs.createReadStream(file, {
start: audioJson.init.offset,
end: audioJson.init.size,
}),
fs.createReadStream(file, {
start: audioJson.media[150].offset,
})
];
merge(...streams).on("data", (data) => socket.emit("audio-data", data));
});
客户:
const streamVideo = document.getElementById("webmStream");
const mediaSource = new MediaSource();
const streamSource = URL.createObjectURL(mediaSource);
streamVideo.src = streamSource;
const audioMime = `audio/webm; codecs="opus"`;
const videoMime = `video/webm; codecs="vp9"`;
mediaSource.addEventListener("sourceopen", () => {
const audioBuffer = mediaSource.addSourceBuffer(audioMime);
const audioChunks = [];
function appendOrQueueChunk(chunk) {
if (!audioBuffer.updating && !audioChunks.length) {
audioBuffer.appendBuffer(chunk);
} else {
audioChunks.push(chunk);
}
}
socket.on("audio-data", appendOrQueueChunk);
audioBuffer.addEventListener("updateend", () => {
if (audioChunks.length) audioBuffer.appendBuffer(audioChunks.shift());
});
还有一个 JSON 的 sn-p:
{
"type": "audio/webm;codecs=\"opus\"",
"duration": 93100.000000,
"init": { "offset": 0, "size": 526},
"media": [
{ "offset": 526, "size": 10941, "timecode": 0.000000 },
{ "offset": 11467, "size": 10382, "timecode": 0.260000 },
{ "offset": 21849, "size": 10301, "timecode": 0.520000 },
{ "offset": 32150, "size": 10495, "timecode": 0.780000 },
...
只要我直接从整个 WebM 文件的 fs.ReadStream 发出套接字事件,套接字流就可以正常工作,所以它可能与按顺序发送流有关,但我觉得完全超出了我的深度并认为我我在概念上遗漏了一些东西。
【问题讨论】:
标签: node.js typescript socket.io webm media-source