用Node.js处理将视频文件流到html5视频播放器以使视频控件继续工作的正确方法是什么?
我认为这与头的处理方式有关。不管怎样,这是背景资料。代码有点长,但是,它非常简单。
我学会了如何将小视频文件流式传输到HTML5视频播放器。有了这个设置,控制工作没有任何工作,我的部分,视频流完美。这里有一个完整的工作代码和示例视频的工作副本,可以在Google Docs上下载。
客户:
<html>
<title>Welcome</title>
<body>
<video controls>
<source src="movie.mp4" type="video/mp4"/>
<source src="movie.webm" type="video/webm"/>
<source src="movie.ogg" type="video/ogg"/>
<!-- fallback -->
Your browser does not support the <code>video</code> element.
</video>
</body>
</html>
服务器:
// Declare Vars & Read Files
var fs = require('fs'),
http = require('http'),
url = require('url'),
path = require('path');
var movie_webm, movie_mp4, movie_ogg;
// ... [snip] ... (Read index page)
fs.readFile(path.resolve(__dirname,"movie.mp4"), function (err, data) {
if (err) {
throw err;
}
movie_mp4 = data;
});
// ... [snip] ... (Read two other formats for the video)
// Serve & Stream Video
http.createServer(function (req, res) {
// ... [snip] ... (Serve client files)
var total;
if (reqResource == "/movie.mp4") {
total = movie_mp4.length;
}
// ... [snip] ... handle two other formats for the video
var range = req.headers.range;
var positions = range.replace(/bytes=/, "").split("-");
var start = parseInt(positions[0], 10);
var end = positions[1] ? parseInt(positions[1], 10) : total - 1;
var chunksize = (end - start) + 1;
if (reqResource == "/movie.mp4") {
res.writeHead(206, {
"Content-Range": "bytes " + start + "-" + end + "/" + total,
"Accept-Ranges": "bytes",
"Content-Length": chunksize,
"Content-Type": "video/mp4"
});
res.end(movie_mp4.slice(start, end + 1), "binary");
}
// ... [snip] ... handle two other formats for the video
}).listen(8888);
但此方法仅限于大小<1GB的文件。
通过使用fs.createReadStream()
,服务器可以在流中读取文件,而不是一次将其全部读入内存。这听起来像是正确的做事方式,语法极其简单:
服务器段:
movieStream = fs.createReadStream(pathToFile);
movieStream.on('open', function () {
res.writeHead(206, {
"Content-Range": "bytes " + start + "-" + end + "/" + total,
"Accept-Ranges": "bytes",
"Content-Length": chunksize,
"Content-Type": "video/mp4"
});
// This just pipes the read stream to the response object (which goes
//to the client)
movieStream.pipe(res);
});
movieStream.on('error', function (err) {
res.end(err);
});
这流视频刚刚好!但视频控制不再起作用。
HTML5视频控件工作需要接受范围
头(writeHead()
中的位)。
我认为,您应该首先检查请求中的accept ranges
头,然后读取并发送该位,而不是盲目地发送完整的文件。fs.CreateReadStream
支持Start
和End
选项。
所以我试了一个例子,它起作用了。代码并不漂亮,但很容易理解。首先,我们处理范围头以获得开始/结束位置。然后我们使用fs.stat
获取文件的大小,而不需要将整个文件读入内存。最后,使用fs.createeadstream
将请求的部分发送到客户端。
var fs = require("fs"),
http = require("http"),
url = require("url"),
path = require("path");
http.createServer(function (req, res) {
if (req.url != "/movie.mp4") {
res.writeHead(200, { "Content-Type": "text/html" });
res.end('<video src="http://localhost:8888/movie.mp4" controls></video>');
} else {
var file = path.resolve(__dirname,"movie.mp4");
fs.stat(file, function(err, stats) {
if (err) {
if (err.code === 'ENOENT') {
// 404 Error if file not found
return res.sendStatus(404);
}
res.end(err);
}
var range = req.headers.range;
if (!range) {
// 416 Wrong range
return res.sendStatus(416);
}
var positions = range.replace(/bytes=/, "").split("-");
var start = parseInt(positions[0], 10);
var total = stats.size;
var end = positions[1] ? parseInt(positions[1], 10) : total - 1;
var chunksize = (end - start) + 1;
res.writeHead(206, {
"Content-Range": "bytes " + start + "-" + end + "/" + total,
"Accept-Ranges": "bytes",
"Content-Length": chunksize,
"Content-Type": "video/mp4"
});
var stream = fs.createReadStream(file, { start: start, end: end })
.on("open", function() {
stream.pipe(res);
}).on("error", function(err) {
res.end(err);
});
});
}
}).listen(8888);
问题内容: Tl; Dr-问题: 用Node.js处理将视频文件流传输到html5视频播放器以 使视频控件继续工作 的正确方法是什么 ? 我 认为 这与处理标头的方式有关。无论如何,这是背景信息。代码 有点 冗长,但是非常简单。 客户: 服务器: 但是此方法仅限于大小小于1GB的文件。 流式传输(任何大小)视频文件 通过利用,服务器可以读取流中的文件,而不是一次将其全部读取到内存中。这听起来像做事
问题内容: Tl; Dr-问题: 用Node.js处理将视频文件流传输到html5视频播放器以 使视频控件继续工作 的正确方法是什么 ? 我 认为 这与处理标头的方式有关。无论如何,这是背景信息。代码 有点 冗长,但是非常简单。 使用Node将小视频文件流化为HTML5视频很容易 我学习了如何非常轻松地将小型视频文件流式传输到HTML5视频播放器。使用此设置,控件可以正常工作,而我的视频也完美无缺
我的应用程序中有一项服务。它发送和接收webservice请求和响应。当我收到来自web服务的特定响应时,我需要停止播放音频/视频文件(媒体文件正在从另一个应用程序播放)。当我完成某个过程时,我需要再次恢复。 注: 在andoid设备中,如果任何2G呼叫停止播放媒体文件,则音乐播放器播放任何音乐,然后当2G呼叫断开时,停止播放媒体文件。我只需要这样做。
我试图从谷歌驱动器流200MB视频文件。我已经尝试嵌入一个24MB的文件,共享给每个人,这工作: 当我在浏览器中正常导航到这个网址时,会显示一个我必须接受的安全请求。我相信这就是问题所在,因为它阻止了下载。也许我在URL中丢失了一些参数?我如何流较大的文件没有谷歌驱动器阻止请求?
我想玩。iPhone应用程序中的mpd文件,为此我尝试了VLC播放器,但它没有按照预期工作,播放视频花费了太多时间。我还有其他选择吗。像Android中的exoplayer这样的mpd文件。 我已经为此目的实现了VLC媒体播放器,但现在我正在寻找另一种选择。如果有人对此有任何想法,请帮助。
问题内容: 我要实现以下目标。 目的是使用户能够从他/她的硬盘驱动器中选择文件。 不上传的原因当然是传输成本和存储配额。没有理由保存文件。 可能吗? 问题答案: 可以播放本地视频文件。 通过元素选择文件时: “更改”事件被触发 从获取第一个File对象 制作指向File对象的对象URL 将对象URL设置为属性 靠后看