我正在尝试使用 Socket.io 设置实时流以从服务器传递 PNG 帧。现在,我想使用 MediaSource 扩展对其进行测试,因为我计划稍后添加音频,这就是我使用 MediaSource 而不是仅更新图像标签或画布的原因。 这是我到目前为止所拥有的:
import { io } from "https://cdn.socket.io/4.7.5/socket.io.esm.min.js";
const videoElement = document.getElementById('videoPlayer');
const mediaSource = new MediaSource();
videoElement.src = URL.createObjectURL(mediaSource);
const socket = io();
mediaSource.addEventListener('sourceopen', () => {
sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
socket.on('video-frame', (frame) => {
const frameBlob = new Uint8Array(frame);
sourceBuffer.appendBuffer(frameBlob);
});
});
mediaSource.addEventListener("sourceclose", () => {
console.log("Source Closed");
});
问题是我的 SourceBuffer 一直出现异常:
Uncaught (in promise) InvalidStateError: Failed to execute 'appendBuffer' on SourceBuffer': This SourceBuffer has been removed from the parent MediaSource.
这是因为 MediaSource 在我向视频添加任何帧之前关闭。为什么会这样呢?如何使用 MediaSource Extensions 实现逐帧 PNG 图像的直播?
我正在尝试使用 Socket.io 设置实时流以从服务器传送 PNG 帧。
为什么? 这可能是以这种方式传输视频的效率最低的方法之一。 您需要这些无损编码的帧有什么原因吗?
现在,我想用 MediaSource Extensions 来测试它
嗯,你不能,因为 MSE 不支持将任意帧推入源缓冲区。 您需要一个合适的编解码器和容器,并且需要 MSE 支持的编解码器和容器...这几乎只是 ISOBMFF(MP4) 中的 H.264 和 AAC。
我计划稍后添加音频,这就是为什么我使用 MediaSource 而不仅仅是更新图像标签或画布。
仅仅因为您打算拥有音轨并不意味着您无法在画布上显示图像/视频轨道。
只是,不要做任何这样的事情。 而且,也不需要 Socket.IO。 如果您确实想像这样将原始帧推送到客户端,那么您实际上需要将它们绘制到画布上。 如果您不需要原始帧,请使用适当的编解码器。
Web Codecs API 中还有一些新对象可能对您有用,但尚未得到广泛支持。