gpt4 book ai didi

ffmpeg - 为什么 FFMpeg 输出错误的 NAL 单元类型? (javascript h264 直播)

转载 作者:行者123 更新时间:2023-12-04 22:59:29 30 4
gpt4 key购买 nike

我正在尝试使用 h264 编码在浏览器中设置直播,其中 javascript 解码 h264 帧并将其绘制在 Canvas 元素(或使用 WebGL)上。

Broadway 和 Prism 都实现了解码类型 1、5、7 和 8 的 NAL 单元。

我目前的设置如下:

  • FFMpeg 输出带有 h264 数据的 MPEG-TS 流
  • 流通过管道传送到 netcat,它监听端口 8084
  • NodeJS 中的 websocket 服务器将数据从端口 8084 传送到 8085 上的客户端
  • jsmpeg 库将 MPEG-TS 解码为单独的 NAL 单元
  • 单独的 NAL 单元由 Broadway 或 Prism 解码,输出到 Canvas

  • 我正在使用这个 FFMpeg 命令:
    ffmpeg -f v4l2 -i /dev/video0 -r 15 -c:v h264_nvenc -pix_fmt yuv420p -b:v 500k -profile:v baseline -tune zerolatency -f mpegts - | nc -l -p 8084 127.0.0.1

    问题是我得到的 NAL 单元是类型 9(或者可能是 6?),这是 javascript 正在接收的 NAL 单元之一的 header ,采用 Base64 和二进制格式:
    echo "AAAAAQnwAAAAAQYBBAAECBCAAAAAAWHg" | base64 -d | xxd -b
    00000000: 00000000 00000000 00000000 00000001 00001001 11110000 ......
    00000006: 00000000 00000000 00000000 00000001 00000110 00000001 ......
    0000000c: 00000100 00000000 00000100 00001000 00010000 10000000 ......
    00000012: 00000000 00000000 00000000 00000001 01100001 11100000 ....a.

    Broadway 和 Prism 都不支持这些 NAL 单元类型。如何将 FFMpeg 配置为仅输出类型 1、5、7 和 8 的 NAL 单元?

    编辑:我还尝试了以下命令:
    ffmpeg -f v4l2 -i /dev/video0 -r 15 -c:v h264_nvenc -pix_fmt yuv420p \
    -b:v 500k -profile:v baseline -tune zerolatency \
    -movflags frag_keyframe+empty_moov -g 52 -f mp4 - \
    | nc -l -p 8084 127.0.0.1

    它编码为 mp4,然后我尝试从三个零字节开始解析 NAL 单元。这些行看起来都类似于以下内容:
    echo "AAAACAYBBABOCBCAAAARemHk4f8df1Su" | base64 -d | xxd -b
    00000000: 00000000 00000000 00000000 00001000 00000110 00000001 ......
    00000006: 00000100 00000000 01001110 00001000 00010000 10000000 ..N...
    0000000c: 00000000 00000000 00010001 01111010 01100001 11100100 ...za.
    00000012: 11100001 11111111 00011101 01111111 01010100 10101110 ....T.

    那是类型 6(第 5 个字节中的 00110),仍然不是所需的 NAL 单元类型。

    更新:它对我不起作用的原因是 Javascript 中字符和字节之间的编码/解码问题。我已经把 working code on github对于其他可能想做类似事情的人。

    关于 NAL 单元,事实证明 FFMpeg 输出的原始视频包含只有几个字节的类型 6,然后是具有帧数据的类型 1。类型 6 可以丢弃。感谢评论和接受的答案,以了解这一点。

    最佳答案

    “jsmpeg 库将 MPEG-TS 解码为单独的 NAL 单元”存在误解,因为它确实将传输流解码为 PES 数据包。 PES 数据包可以包含多个 NAL 单元。

    删除访问单元分隔符很容易,因为它们实际上只有一个字节长。所以你可以跳过 0x0000000109f0 (从你的第一个转储)并在偏移量 6 处处理下一个 NAL 单元。

    那是第 6 类,即补充增强信息。它也需要跳过,因为您的解码器不支持它(解码不需要它)。 SEI NAL 单元通常也很短,大约 10-50 个字节。所以只要寻找下一个起始码0x00000001...

    关于ffmpeg - 为什么 FFMpeg 输出错误的 NAL 单元类型? (javascript h264 直播),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51272124/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com