如何将视频数据流式传输到视频元素?
Posted
技术标签:
【中文标题】如何将视频数据流式传输到视频元素?【英文标题】:How to stream video data to a video element? 【发布时间】:2016-07-16 10:45:39 【问题描述】:我有一个 Node.js 进程,它将视频流输出到我的 Node.js 应用程序中。
在客户端,有一个<video>
标签。我想将视频从 Node.js 流式传输到视频标签的 src
属性中。我以前的经验告诉我,我们必须为此使用blob
对象。但是,我不能百分百确定我会如何以及为什么会使用它。
我正在考虑的另一个可能的解决方案是在我的服务器上创建某种临时文件,然后将流写入该文件,然后将该文件作为视频源提供。然而,这似乎并不直观。那么,我想知道,对于这样的问题是否有更成熟的解决方案。
【问题讨论】:
创建一个文件,即使是一个临时文件,也不是一个糟糕的解决方案,并且可以让您将完整的 http 头痛问题转移到支持Range
标头的 apache 之类的预先编写的东西上;视频服务的手动 http 实现可能很棘手......
@dandavis,是否可以以可以立即提供文件(即使没有完全写入)并在客户端播放的方式编写文件?
我一直很好奇node对于这种类型的解决方案是否是一个可行的组件;因为它本质上是单线程的,所以我一直质疑它是否可以处理多个流
您是否正在交付带有 H264/AAC 的 MP4 容器?
这应该可以帮助你稍微理解可读流:github.com/ndugger/blackbeard/blob/master/src/media.js -- 如果你还在苦苦挣扎,请告诉我,我会写出正确的答案。
【参考方案1】:
实际上,我在两周前的一次黑客马拉松上尝试过这个。我最终几乎没有让这个 flv 流工作,我已经在下面发布了。我的意图是创建一个库来自动化这将需要的大部分过程。
如您所见,我在服务器上打开了一个新端口来处理流向客户端的单独数据流。这反映在客户端的 src 标签中。
你需要的三样东西:
ffmpeg 的这个 Linux 版本。
Flowplayer在js端。
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');
// make sure you set the correct path to your video file storage
var pathToMovie = '/path/to/storage/' + req.params.filename;
var proc = ffmpeg(pathToMovie)
// use the 'flashvideo' preset (located in /lib/presets/flashvideo.js)
.preset('flashvideo')
// setup event handlers
.on('end', function ()
console.log('file has been converted succesfully');
)
.on('error', function (err)
console.log('an error happened: ' + err.message);
)
// save to stream
.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 属性)
【讨论】:
这看起来很不错。您可以添加客户端部分吗?【参考方案2】:您可能希望查看以下选项:
BinaryJS。它是基于websockets的双向实时二进制数据传输工具。
JSMpeg 流服务器(在捕获的情况下)来自 Phoboslab 的家伙。您需要做的就是启动ffmpeg
并将其指向运行nodejs 脚本的域和端口。
更多信息您可以找到here。
直接管道流。好的答案发布在here。简而言之,您只需要指定Accept-Ranges
、Content-Range
、Content-Length
和Content-Type
标头,然后创建相关的Read 流(使用start
和end
选项)并将其通过管道传输到@987654333 @对象。
【讨论】:
【参考方案3】:m3u8 格式通常用于流式传输。 视频流/转码是一种资源密集型的事情。如果您有该选项,我建议您使用第三方服务。
【讨论】:
虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review 对***非常熟悉,所以我知道只有链接的答案不好。首先是链接到几乎没有变化的***。其次,除了链接之外,我还写了我所知道的内容。第三件事如果您了解更多,请考虑在您的评论中添加更多详细信息。以上是关于如何将视频数据流式传输到视频元素?的主要内容,如果未能解决你的问题,请参考以下文章
正确处理将摄像机流式传输到 HTML 视频元素的 React Hooks
如何在我的应用程序上仅流式传输来自 youtube 视频的音频数据?
将设备上的视频流式传输到 videoview - Android