有没有办法使用 h.264 编解码器恢复实时 h264 播放客户端重新加入?

问题描述

目前,我在使用 MediaSource API 来恢复实时 h264 播放时遇到了一些问题。 我的服务器端代码将保留来自 FFmpeg 的第一个数据包,然后将其分发给客户端。然而,这很有效,但会引发一个问题。

当我重新启动流并将其分派给客户端时,它按预期进行,这是我期望的结果,当客户端断开连接然后必须重新连接到流时,是上述 result

但是,如果我要重新加入信息流,我会将其作为 result

此外,FFMpeg 数据正在发送到上图中的客户端,只是由于某种原因没有呈现它。

这是我播放从服务器获取的音频/视频帧的函数

private _playFrame(type: 0 | 1) {
    const src = type === 0 ? this.audioSource : this.videoSource;
    if (!src || src.updating) return;
    const queue = type === 0 ? this.audioFrameQueue : this.videoFrameQueue;
    src.appendBuffer(queue.shift());
    if (this.video.src && this.video.paused) this.video.play().then(() => null);
}

解决方法

碎片化的 .mp4 数据流——用于实时播放的类型——在压缩媒体本身之前有一个描述它们的媒体的序言。

包含媒体元数据的序言是一个数据块——mp4 行话中的一个“原子”——名为 'moov'。它的子原子之一 'avcC' 包含所谓的 H.264 视频流的编解码器私有数据。如果您要求解码器处理 H.264 而不向其提供编解码器专用数据,则它无法解释 H.264,因此会跳过它。这适用于任何解码器,包括嵌入在浏览器或桌面媒体播放器包中的解码器。

'moov' 序言可能在来自 ffmpeg 的第一个数据包中(尽管您需要使用 tool like mp4dump 检查该数据才能确定)。

因此,要加入直播,观看者必须先接收序幕数据,然后再接收实时数据。