如何将视频数据流传输到视频元素?

10

我有一个Node.js进程,可以将视频流输出到我的Node.js应用程序。

在客户端,有一个<video>标签。我希望将视频从Node.js中流式传输到视频标签的src属性中。根据我之前的经验,我们必须使用blob对象来实现。但是,我不太确定如何以及为什么要使用它。

我想到的另一种可能的解决方案是,在我的服务器上创建某种临时文件,然后将流写入该文件,然后将该文件作为视频的源提供服务。但这似乎不太直观。我想知道是否有更成熟的解决方案来解决这个问题。


创建一个文件,即使是临时文件,也不是一个坏的解决方案,它可以让你将完整的HTTP头部转移到像Apache这样支持“Range”头部的预先编写好的东西上;手动实现视频服务的HTTP可能会很棘手... - dandavis
1
我一直很好奇Node是否是这种解决方案的可行组件;由于它天生是单线程的,我一直怀疑它是否能够处理多个流。 - theaccordance
是的,我的赏金评论反映了这一点。目前Node为我们处理大部分工作,但我完全可以使用childProcess来生成其他进程来处理视频流。 - sg.cc
1
你是否正在使用H264/AAC格式的MP4容器? - lapinkoira
1
这应该可以帮助你更好地理解可读流:https://github.com/ndugger/blackbeard/blob/master/src/media.js -- 如果你还有困惑,请告诉我,我会写出正确的答案。 - ndugger
显示剩余3条评论
3个回答

4

m3u8 格式通常用于流媒体播放。 视频流传输/转码需要大量资源。如果您有这个选项,我建议您使用第三方服务来完成。


虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。如果链接页面更改,仅链接的答案可能会失效。- 来自审查 - ankitr
1
我非常熟悉stackoverflow,所以我知道仅提供链接的答案并不好。 首先,链接指向的是维基百科,而维基百科几乎不会更改。 其次,除了链接,我已经写出了我所知道的内容。 第三件事,如果您对此有更多了解,请在评论中添加更多详细信息。 - atinder

3

也许您想看一下以下选项:

  1. BinaryJS。这是一个基于Websockets的双向实时二进制数据传输工具。

  2. JSMpeg流服务器(如果需要捕获)。您只需启动ffmpeg并将其指向运行nodejs脚本的域和端口即可。 更多信息可以在此处找到。

  3. 直接管道流。好的答案在这里发布。简而言之,您只需指定Accept-RangesContent-RangeContent-LengthContent-Type标头,然后创建相关的读取流(带有startend选项),并将其管道传输到response对象。


2

实际上我在两周前的黑客马拉松中尝试过这个。最终我勉强让这个FLV流工作了,下面是我发布的内容。我的目的是制作一个库来自动化大部分涉及到的流程。

正如你所见,我在服务器上打开了一个新端口来处理流向客户端的不同数据流。这反映在客户端的src标签中。

三件事情你需要注意:

  1. 这是 ffmpeg 的 Linux 版本。

  2. 在 js 方面使用 Flowplayer

  3. npm fluent-ffmpeg

    // StreamServer.js

    var express = require('express'),
      app = express(),
      ffmpeg = require('fluent-ffmpeg');
    
    module.exports = function () {
        app.stream(req, res)
        {
            res.contentType('flv');
            // 确保您设置了正确的视频文件存储路径
            var pathToMovie = '/path/to/storage/' + req.params.filename;
            var proc = ffmpeg(pathToMovie)
              // 使用“flashvideo”预设(位于/lib/presets/flashvideo.js中)
              .preset('flashvideo')
              // 设置事件处理程序
              .on('end', function () {
                  console.log('文件已成功转换');
              })
              .on('error', function (err) {
                  console.log('发生错误:' + err.message);
              })
              // 保存到流
              .pipe(res, { end: true });
    
        };
    
    }
    

    //routes.js

    'use strict';
    var stream = require('../controllers/streaming.server.controller'),
     streamServer = require('../controllers/StreamServer.js'),
    express = require('express');
    

    //streaming.server.controller.js

    module.exports = function (app) {
        app.get('/api/stream', function (req, res) {
            streamServer.stream(req, res);
        });
    };
    
    var path = require('path'),
     express = require('express'),
     app = express(),
     routes = require('../routes/routes.js')(app),
     ffmpeg = require('fluent-ffmpeg');
    
    app.listen(4000);
    

编辑:客户端部分:

https://github.com/fluent-ffmpeg/node-fluent-ffmpeg/tree/master/examples/flowplayer

<html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
        <script type="text/javascript" src="/flowplayer.min.js"></script>
        <title>node-fluent-ffmpeg</title>
    </head>
    <body>

        <!-- this A tag is where your Flowplayer will be placed. it can be anywhere -->
        <a  
             href="http://localhost:4000/api/stream"
             style="display:block;width:520px;height:330px"  
             id="player"> 
        </a> 

        <!-- this will install flowplayer inside previous A- tag. -->
        <script>
            flowplayer("player", "/flowplayer.swf");
        </script>
    </body>
</html>

(只需更改href属性)


这看起来非常不错。你能加上客户端部分吗? - sg.cc

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