首页 > 解决方案 > HTML5 H264 视频有时不显示

问题描述

给定来自生成 H264 流的 RTSP 摄像机的此流:

Input #0, rtsp, from 'rtsp://admin:admin@192.168.0.15:554':
  Metadata:
    title           : LIVE555 Streaming Media v2017.10.28
    comment         : LIVE555 Streaming Media v2017.10.28
  Duration: N/A, start: 0.881956, bitrate: N/A
    Stream #0:0: Video: h264 (Main), yuv420p(progressive), 1600x900, 25 fps, 25 tbr, 90k tbn, 50 tbc

我想运行 ffmpeg 并将其输出通过 MSE 传输到 HTML5 视频组件。

只要我运行这个 ffmpeg 命令,一切都很好而且顺利(管道被删除了!):

$ ffmpeg -i 'rtsp://admin:admin@192.168.0.15:554' -c:v copy -an -movflags frag_keyframe+empty_moov -f mp4

不过一开始需要一点时间。

我意识到该功能avformat_find_stream_info会在我的系统上造成大约 15-20 秒的延迟。是文档。

现在我也意识到,如果我添加-probesize 32, avformat_find_stream_info 将几乎立即返回,但它会引起一些警告:

$ ffmpeg -probesize 32 -i 'rtsp://admin:admin@192.168.0.15:554' -c:v copy -an -movflags frag_keyframe+empty_moov -f mp4

[rtsp @ 0x1b2b300] Stream #0: not enough frames to estimate rate; consider increasing probesize
[rtsp @ 0x1b2b300] decoding for stream 0 failed
Input #0, rtsp, from 'rtsp://admin:admin@192.168.0.15:554':
  Metadata:
    title           : LIVE555 Streaming Media v2017.10.28
    comment         : LIVE555 Streaming Media v2017.10.28
  Duration: N/A, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: h264 (Main), yuv420p(progressive), 1600x900, 25 tbr, 90k tbn, 50 tbc

如果我将此流转储(到文件 test.mp4 中),所有媒体播放器都可以完美播放它。

但是,如果我使用 MSE 将此输出通过管道传输到 HTML5 视频中,则流有时会正确显示,有时却不能正确显示。浏览器的控制台上不会打印任何警告或错误消息。

从第二个输出我可以看到 fps 丢失了。我试图手动设置它,但没有成功(似乎我无法手动更改它)。

如果我事先知道流的所有内容,如何避免 avformat_find_stream_info 并播放 HTML5 MSE?

更新

根据@szatmary 的评论和答案,我已经搜索了一个 h264 比特流解析器。

就是我发现的。我还保存了 HTML5 视频无法播放的 mp4 文件,但 VLC 确实可以播放,然后我进入了这个分析器。

这是我的分析截图: 在此处输入图像描述

这里有一些事实:

我有几件事要澄清:

  1. #62 和 #66 sps/pps 单元(或其他)只为接下来的帧保存元数据,或者它们甚至可以引用以前的帧?
  2. VLC播放20秒,是否可以先扫描整个文件,然后根据#62和#66信息播放#1的帧?- 如果 VLC 将文件作为流获取,在这种情况下它可能只播放几秒钟 (#66 - #103)。
  3. 最重要的是:我应该如何使用比特流解析器来制作播放这些数据的 HTML5 视频?我要不要在#62 之前放弃所有单位?还是在#66 之前?

现在我真的迷失在这个话题上了。我用 FFMPEG 创建了一个视频,但这次我允许它完成它的 avformat_find_stream_info 函数。

使用与以前相同的方法保存视频。VLC 现在播放 18 秒(这没关系,我在 ffmpeg 命令中有 1000 帧限制)。

但是,现在让我们看看比特流信息:

在此处输入图像描述

现在 PPS 和 SPS 分别是 130 和 133。这导致流比以前短 2 秒。(我猜)

现在我了解到,在正确解析的 h264 中,在第一个 SPS(/PPS) 之前仍然可以有很多单元。

所以我会微调我上面的问题:我应该如何使用比特流解析器来制作 HTML5 视频播放这些数据?

我发现的比特流解析器也不好,因为它使用二进制包装器=>它不能纯粹在客户端运行。

我现在在看mp4box

标签: ffmpeghtml5-videomedia-source

解决方案


如果我事先知道流的所有内容,如何避免 avformat_find_stream_info 并播放 HTML5 MSE?

您事先并不知道流的所有内容。您不知道分辨率、比特率、级别或配置文件或约束标志。你不知道缩放列表值,你不知道 VUI 数据,你不知道是否使用了 CABAC。

播放器需要所有这些东西来播放视频,直到播放器或ffmpeg看到流中的第一个sps / pps才知道它们。通过限制分析持续时间,您告诉 ffmpeg 放弃寻找它,因此不能保证产生有效的流。它有时可能有效,有时可能无效,这在很大程度上取决于您从 rstp 流中的哪个帧开始。

如果可以,一个可能的解决方案是向源视频添加更多关键帧,这将更频繁地发送 sps/pps。如果您不控制源流,则必须等到流中出现 sps/pps。


推荐阅读