我目前正在开发一个项目,我的目标是通过 LAN 传输我的网络摄像头,并以最少的设置读取 HTML5 视频元素中的流。我的设置涉及一个服务器(192.168.0.1 dev/video0 -> ffmpeg)和一个客户端(192.168.0.2 html5 浏览器)。我正在使用 ffmpeg,编解码器设置为 h264。
这是我正在使用的 ffmpeg 命令:
ffmpeg -f video4linux2 -i /dev/video0
-an -c:v libx264 -b:v 1024k -video_size 800x600 -pix_fmt yuv420p -preset ultrafast
-tune zerolatency -g 16 -keyint_min 16 -f mpegts pipe:1
此命令由一个简单的 Node.js 服务器生成,该服务器无需任何转换即可共享此流(只需将 ffpmeg 流通过管道传输到每个传入连接)。
当我通过以下命令使用 vlc 或 ffplay 时,效果非常好:
ffplay -fflags nobuffer -flags low_delay -probesize 32 -analyzeduration 0 -framedrop http://192.168.0.1:3000/stream
我什至可以运行 ffplay 的多个实例,并且视频可以正常播放。然而,当我尝试像这样使用 HTML5 元素时:
<video src="http://127.0.0.1:3000/stream" type="video/mp4"></video>
视频似乎“永远加载”,没有任何错误,
chrome://media-internals
没有任何可疑之处。我可以在网络选项卡中看到网络正在读取流,但视频无法播放(使用 hljs 和 videojs 得到相同的结果)。
我正在寻求帮助来理解:
<video>
元素有什么问题?任何帮助或指导将不胜感激。
由于
-f mpegts
选项,您的视频无法播放。 <video>
标签正在接收一些 .ts
文件数据字节,而不是通常预期的 .mp4
文件数据字节。
可能的解决方案:
(1) 使用 Safari 浏览器测试您的视频标签设置,因为它内置了 TS 容器格式的解码。
注意: 如果仍然无法解码 TS 文件,则意味着 Safari 需要 M3U8 播放列表文件(列出存储的 TS 文件的 URL),这在管道字节的情况下是不可能的。
(2) 如果使用
<video src="http://127.0.0.1:3000/stream">
那么首先尝试这个 FFmpeg 设置:
ffmpeg -f video4linux2 -i /dev/video0
-an -c:v libx264 -b:v 1024k -video_size 800x600 -pix_fmt yuv420p -preset ultrafast
-tune zerolatency -g 16 -keyint_min 16 -movflags frag_keyframe+separate_moof+omit_tfhd_offset+empty_moov pipe:1
这将为您提供一个碎片化的 MP4 容器(所有浏览器都支持),您可以在视频标签中播放它,就像您显示的代码预期的那样...