使用视频标签实现无需WebRTC的HTML5实时流传输

14

我想将实时编码的数据封装到WebM或OGV中,并将其发送到HTML5浏览器。

WebM或OGV能够做到这一点,而MP4由于其MDAT原子结构无法实现此功能。(不能实时包装H264和MP3并将其发送到客户端)假设我正在从网络摄像头提供输入和内置麦克风提供音频。分片的MP4可以处理这个问题,但是要找到库来完成这项工作比较麻烦。

我需要这样做是因为我不想将音频和视频分开发送。

如果我分别发送它们,即通过音频标签发送音频并通过视频标签发送视频(音频和视频被解复用并发送),我是否可以在客户端浏览器上使用JavaScript同步它们?我看过一些示例,但还不确定。


我使用 Stream-m 服务器将 webm 流传输到客户端 HTML5 视频标签。 https://github.com/yomguy/stream-m 在生产环境中运行良好。 干杯!编辑:请注意,现在 IceCast 也可以直接流式传输 WebM ;) - yomguy
3个回答

12

我使用Ubuntu上的ffmpeg / ffserver以以下方式进行了WebM格式的转换(MP4和Ogg稍微简单一些,并且应该以类似的方式从同一服务器上工作,但您应该使用所有3种格式以便兼容各种浏览器)。

首先,从源代码中构建ffmpeg以包括libvpx驱动程序(即使您使用的版本已经有它,您也需要最新的版本(截至本月)才能流式传输WebM,因为他们刚刚添加了包括全局头文件的功能)。我在Ubuntu服务器和桌面上执行了此操作,这个指南向我展示了如何 - 其他操作系统的说明可以在这里找到

一旦您获得了适当版本的ffmpeg / ffserver,就可以为其设置流媒体,对于我的情况,是这样完成的。

在视频捕获设备上:

ffmpeg -f video4linux2 -standard ntsc -i /dev/video0 http://<server_ip>:8090/0.ffm
  • "-f video4linux2 -standard ntsc -i /dev/video0" 部分可能会根据您的输入源而改变(我的是视频捕捉卡)。

相关的 ffserver.conf 摘录:

Port 8090
#BindAddress <server_ip>
MaxHTTPConnections 2000
MAXClients 100
MaxBandwidth 1000000
CustomLog /var/log/ffserver
NoDaemon

<Feed 0.ffm>
File /tmp/0.ffm
FileMaxSize 5M
ACL allow <feeder_ip>
</Feed>
<Feed 0_webm.ffm>
File /tmp/0_webm.ffm
FileMaxSize 5M
ACL allow localhost
</Feed>

<Stream 0.mpg>
Feed 0.ffm
Format mpeg1video
NoAudio
VideoFrameRate 25
VideoBitRate 256
VideoSize cif
VideoBufferSize 40
VideoGopSize 12
</Stream>
<Stream 0.webm>
Feed 0_webm.ffm
Format webm
NoAudio
VideoCodec libvpx
VideoSize 320x240
VideoFrameRate 24
AVOptionVideo flags +global_header
AVOptionVideo cpu-used 0
AVOptionVideo qmin 1
AVOptionVideo qmax 31
AVOptionVideo quality good
PreRoll 0
StartSendOnKey
VideoBitRate 500K
</Stream>

<Stream index.html>
Format status
ACL allow <client_low_ip> <client_high_ip>
</Stream>
  • 请注意,此配置是针对位于feeder_ip的服务器执行上述ffmpeg命令,并在处理mpeg到webm转换时通过server_ip将服务器发送到client_low_ip至client_high_ip的服务器(继续如下)。

此ffmpeg命令在之前提到的server_ip机器上执行(它处理实际的mpeg --> webm转换并将其反馈到不同feed上的ffserver):

ffmpeg -i http://<server_ip>:8090/0.mpg -vcodec libvpx http://localhost:8090/0_webm.ffm

一旦这些都启动了(首先是ffserver,然后是feeder_ip的ffmpeg进程,最后是server_ip的ffmpeg进程),您应该能够在http://:8090/0.webm访问实时流,并在http://:8090/检查状态。

希望这可以帮到您。


@EvrenBingøl,你能提供更多信息吗? - alfadog67
这已经有一段时间了,这是我记得的内容: 客户端从服务器请求一个ogv文件,该文件代表实时视频。 正在发送的数据在服务器上使用DirectX即时转换为ogv。因此,假设您想进行视频聊天。您将通过其标头(无论类型如何)将视频和音频数据发送到服务器,并且DirectX会将其转换为ogv并将其发送到接收端。Ogv非常好地处理块。 - Evren Bingøl
如果有人使用这个配置,请更新端口为HTTPPort,地址为HTTPAddress,删除NoDeamon。 - ThienSuBS

4

Evren,

既然您最初提出了这个问题,媒体源扩展https://www.w3.org/TR/media-source/已经足够成熟,能够播放非常短(30毫秒)的ISO-BMFF video/mp4片段,并且只需要一点缓冲。

请参考HTML5直播流

因此,您的陈述

(不能实时包装h264和mp3并将其包装并发送到客户端)

现在已经过时了。是的,您可以使用h264 + AAC来做。

有几种实现方法可供选择;看看Unreal Media Server。 从Unreal Media Server FAQ中:http://umediaserver.net/umediaserver/faq.html

Unreal HTML5直播与MPEG-DASH有何不同? 与MPEG-DASH不同,Unreal Media Server使用WebSocket协议将直播流传输到Web浏览器中的HTML5 MSE元素。这比通过MPEG-DASH每个HTTP请求获取片段更有效率。此外,Unreal Media Server发送最小持续时间的片段,低至30毫秒。这允许低延迟(小于1秒)直播流,而MPEG-DASH等其他基于HTTP块的直播流协议无法提供低延迟直播流。

他们的演示网页有一个来自RTSP相机的实时HTML5 feed:http://umediaserver.net/umediaserver/demos.html 请注意,在HTML5播放器中的延迟与Flash播放器中的延迟相当。


2
这篇文章读起来像是Unreal的广告。虽然说“有很多实现方式”,但唯一的建议却是需要许可证的Unreal解决方案。既然这个答案比之前4年前的最佳答案更为实用,那么我们希望看到其他人也能够构建其中的几种实现方式。 - JohnMetta

0

我不确定你是否能够做到这一点。HTML5尚未批准任何实时流传输机制。您可以使用WebSockets并实时向浏览器发送数据来完成此操作。但是,您必须自己编写解析逻辑,而且我不知道您将如何将数据作为到达播放器的内容进行提供。

至于视频和音频标签:视频标签可以播放同时具有音频和视频的容器文件。因此,请将您的内容包装在兼容的容器中。如果您修改浏览器以将您的实时流传输写入此视频文件,并在每个字节请求时流出该数据,则可以完成此操作。但这绝对不是易事。


1
我需要读取一个wmv文件,实时转码并渲染速度(就像我正在观看而不是写入文件),编码为VP8并包装在webm中。浏览器将指向被转码的file.webm文件。 当请求被发出时,我将在服务器端进行长轮询,并将其写入http套接字(您可以随意命名它,比如“响应”)。因此,有一种通信方式,即服务器将webm文件推送到浏览器。浏览器正在渐进式下载文件,至少它认为它是一个文件,但实际上它是一个被包装在webm中的直播流。 - Evren Bingøl
2
可行。或许更简单的方法是直接将内容写入文件并从Web服务器提供服务。使用Web服务器的限速设置来确保以“实时”方式提供服务,而不是更快或更慢。给转码一些启动时间以获得一些余地。应该可以工作。限速非常重要,这样播放器就不能以比您生成的速度(目标比特率)更快的速度拉取数据。 - av501

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接