当前位置: 首页 > 知识库问答 >
问题:

HTML5视频客户端实时http流的最佳方法[已关闭]

韩景胜
2023-03-14

我很难理解使用Node.js将ffmpeg的实时输出流到HTML5客户机的最佳方法,因为有许多变量在起作用,而且我在这方面没有太多经验,已经花了很多时间尝试不同的组合。

我的用例是:

1)IP视频摄像机RTSP H.264流由FFMPEG拾取,并使用node中的以下FFMPEG设置重新组合到mp4容器中,输出到stdout。这只在初始客户端连接上运行,这样部分内容请求就不会再次尝试生成FFMPEG。

liveFFMPEG = child_process.spawn("ffmpeg", [
                "-i", "rtsp://admin:12345@192.168.1.234:554" , "-vcodec", "copy", "-f",
                "mp4", "-reset_timestamps", "1", "-movflags", "frag_keyframe+empty_moov", 
                "-"   // output to stdout
                ],  {detached: false});

2)我使用节点http服务器捕获STDOUT并在客户机请求时将其流回客户机。当客户机第一次连接时,我生成上面的FFMPEG命令行,然后将STDOUT流管道传输到http响应。

liveFFMPEG.stdout.pipe(resp);

我还使用stream事件将FFMPEG数据写入HTTP响应,但没有什么不同

xliveFFMPEG.stdout.on("data",function(data) {
        resp.write(data);
}

我使用下面的HTTP头(在流预录文件时也使用并工作)

var total = 999999999         // fake a large file
var partialstart = 0
var partialend = total - 1

if (range !== undefined) {
    var parts = range.replace(/bytes=/, "").split("-"); 
    var partialstart = parts[0]; 
    var partialend = parts[1];
} 

var start = parseInt(partialstart, 10); 
var end = partialend ? parseInt(partialend, 10) : total;   // fake a large file if no range reques 

var chunksize = (end-start)+1; 

resp.writeHead(206, {
                  'Transfer-Encoding': 'chunked'
                 , 'Content-Type': 'video/mp4'
                 , 'Content-Length': chunksize // large size to fake a file
                 , 'Accept-Ranges': 'bytes ' + start + "-" + end + "/" + total
});

3)客户端必须使用HTML5视频标记。

我在向HTML5客户端流式播放(使用带有206 HTTP部分内容的fs.createReadStream)之前用上面的FFMPEG命令行录制的视频文件(但保存到一个文件而不是STDOUT中)方面没有问题,所以我知道FFMPEG流是正确的,当连接到HTTP节点服务器时,我甚至可以正确地看到VLC中的视频直播流。

然而,尝试通过节点HTTP从FFMPEG实时流似乎要困难得多,因为客户端将显示一个帧,然后停止。我怀疑问题是我没有将HTTP连接设置为与HTML5视频客户端兼容。我尝试了各种方法,比如使用HTTP206(部分内容)和200响应,将数据放入缓冲区,然后流式传输,但没有成功,所以我需要回到最初的原则,以确保我设置的方法是正确的。

以下是我对该如何工作的理解,如果我错了,请指正:

1)FFMPEG应该被设置为分割输出并使用一个空的moov(FFMPEG frag_keyframe和empty_moov mov标志)。这意味着客户机不使用通常在文件末尾的moov原子,这在流(没有文件末尾)时是不相关的,但意味着没有寻找可能,这对我的用例来说是好的。

2)即使我使用MP4片段和空的MOOV,我仍然必须使用HTTP部分内容,因为HTML5播放器将等到整个流下载完后才播放,而直播流永远不会结束,所以是不可行的。

3)我不明白为什么将STDOUT流传输到HTTP响应在实时流时不起作用,如果我保存到一个文件,我可以使用类似的代码轻松地将该文件传输到HTML5客户机。也许这是一个时间问题,因为FFMPEG产卵启动、连接到IP摄像机并将块发送到节点需要一秒钟,节点数据事件也是不规则的。但是字节流应该与保存到文件完全相同,HTTP应该能够满足延迟。

4)当从摄像机中传输FFMPEG创建的MP4文件时,从HTTP客户端查看网络日志时,我看到有3个客户端请求:对视频的一般GET请求,HTTP服务器返回大约40KB,然后是对文件最后10K字节范围的部分内容请求,然后是对中间未加载位的最终请求。也许HTML5客户机一旦收到第一个响应,就会要求文件的最后一部分加载MP4 MOOV Atom?如果是这种情况,它将不能用于流,因为没有MOOV文件和文件的结尾。

5)在尝试实时流时检查网络日志时,我得到一个中止的初始请求,只有大约200字节,然后再次中止一个200字节的重请求,第三个请求只有2K长。我不明白为什么HTML5客户端会中止请求,因为字节流与我从记录的文件流中成功使用的字节流完全相同。另外,node似乎没有将FFMPEG流的其余部分发送到客户机,但是我可以在。on事件例程中看到FFMPEG数据,因此它正在到达FFMPEG节点HTTP服务器。

6)虽然我认为通过管道将STDOUT流传输到HTTP响应缓冲区应该可以工作,但我是否必须构建一个中间缓冲区和流,以允许HTTP部分内容客户端请求像它(成功地)读取文件时那样正常工作?我认为这是我出现问题的主要原因,但我在Node中不确定如何最好地设置它。我不知道如何处理客户端对文件末尾数据的请求,因为没有文件末尾。

7)我试图处理206个部分内容请求是不是走错了路,这应该适用于正常的200个HTTP响应吗?HTTP 200响应适用于VLC,所以我怀疑HTML5视频客户端只能适用于部分内容请求?

由于我还在学习这些东西,所以很难通过这个问题的各个层(FFMPEG、节点、流、HTTP、HTML5视频)来工作,所以任何指针都将非常感谢。我花了几个小时在这个网站和网络上进行研究,我还没有遇到任何人谁已经能够在节点上做实时流,但我不能成为第一个,我认为这应该能够工作(不知何故!)。

共有1个答案

干照
2023-03-14

编辑3:从IOS 10开始,HLS将支持碎片化的mp4文件。现在的答案是创建碎片化的mp4资产,使用破折号和HLS清单。>假装flash、iOS9及以下版本和IE10及以下版本不存在。

编辑2:正如评论中的人指出的那样,事情发生了变化。几乎所有的浏览器都会支持AVC/AAC编解码器。iOS仍然需要HLS。但是通过像HLS.js这样的适配器,您可以在MSE中玩HLS。如果需要iOS,新的答案是hls+hls.js。或者只是碎片MP4(即破折号),如果你没有

视频,特别是现场视频非常困难,原因有很多。(请注意,最初的问题指定HTML5视频是一个要求,但询问者在评论中说Flash是可能的。所以立即,这个问题是误导性的)

现在让我们深入一点。

平台:

  • iOS
  • pc
  • Mac
  • Android

编解码器:

  • VP8/9
  • H.264
  • Thora(vp3)

浏览器中视频直播的常见传递方式:

    null
    null
    null

狩猎:

  • HLS(仅限iOS和mac)
  • H.264
  • MP4

火狐

  • 破折号(通过MSE但没有H.264)
  • H.264仅通过Flash!
  • VP9
  • MP4
  • OGG
  • WebM

IE

    null
    null
    null

最接近LCD的东西是使用HLS来吸引你的iOS用户,并为其他人使用flash。我个人最喜欢的是编码HLS,然后用flash为其他人播放HLS。你可以通过JW Player6在flash中玩HLS(或者像我一样在AS3中把你自己的HLS写到FLV中)

很快,最常见的方式将是iOS/Mac上的HLS和通过MSE在其他任何地方的DASH(这是网飞很快将做的)。但我们仍在等待大家升级浏览器。你可能还需要一个单独的Firefox dash/vp9(我知道Open264;它很烂。它不能在主或高配置文件中播放视频。所以它目前没有用)。

 类似资料:
  • 我真的很难理解使用Node.js将ffmpeg的实时输出流到HTML5客户端的最佳方法,因为有很多变量在起作用,而我在这方面没有太多经验,我花了很多时间尝试不同的组合。 我的用例是: 1)IP视频摄像机RTSP H.264流由FFMPEG拾取,并使用节点中的以下FFMPEG设置重新多路复用到mp4容器中,输出到stdout。这只在初始客户端连接上运行,以便部分内容请求不会再次尝试生成FFMPEG。

  • 问题内容: 我真的很想了解使用node.js将ffmpeg实时输出流到HTML5客户端的最佳方法,因为有很多变量在起作用,而且我在这个领域没有很多经验,花了很多小时尝试不同的组合。 我的用例是: 1)IP摄像机RTSP H.264流由FFMPEG采集,并使用节点中的以下FFMPEG设置重新混合到mp4容器中,并输出到STDOUT。这仅在初始客户端连接上运行,因此部分内容请求不会尝试再次产生FFMP

  • 问题内容: 我有第三方WSDL,我需要用Java编写代码以使Web服务客户端调用第三方WSDL中的操作。现在,我已经使用Axis的WSDL2JAVA工具生成了客户端存根,并使用XMLbeans进行了数据绑定。 进行此JAVA的最佳方法是什么? 我阅读了有关SAAJ的文章,看起来这种方法会更细化吗? 除了使用WSDL2Java工具之外,还有什么其他方法可以生成代码。也许wsimport还有其他选择。

  • 我有一个现有的应用程序,通过RTMP将实时音频从Flash客户端流到Wowza zerver。。。我能够将Flash客户端连接到该设备,并获得实时、低延迟的音频。 我想在PC、Android和iOS中连接一些基于HTML5的客户端,而不在客户端使用任何Flash。。。RTMP URI通常为“rtmp://myserver/live/mystream“我尝试从HTML5页面连接视频和音频标签,但没有

  • 问题内容: 这是我正在从事的项目的一部分。我有两个桌面Java应用程序,一个运行在服务器上(具有真实IP),另一个运行在客户端上。我只想从连接到服务器应用程序的网络摄像头流式传输实时视频,然后在客户端应用程序上播放它。我想从多个摄像机进行流式传输。 我一直在寻找Xuggler,JMF,Red5,VLCj之间的日子。我只是不知道应该从哪里开始,因为我刚接触编程中的媒体。 我从哪里开始有什么想法? 提

  • 本文向大家介绍js+HTML5实现视频截图的方法,包括了js+HTML5实现视频截图的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了js+HTML5实现视频截图的方法。分享给大家供大家参考。具体如下: 1. HTML部分: 2. 点击按钮时触发如下代码: 希望本文所述对大家的javascript程序设计有所帮助。