使用节点 JS 的 HLS 流式传输
Posted
技术标签:
【中文标题】使用节点 JS 的 HLS 流式传输【英文标题】:HLS Streaming using node JS 【发布时间】:2014-03-19 15:31:56 【问题描述】:我正在尝试使用 node.js 流式传输 HLS 内容。而且不知何故它不起作用。如果有人帮助我,那将有很大的帮助。
问题:- 尝试从 node.js 提供 HLS 内容(不是直播,而是一组 .ts 文件和 .m3u8 播放列表,或者换句话说是 VOD 内容)
文件夹结构
stream_test
|--- app.js
|--- node_modules
|--- streamcontent
|--- test.m3u8
|--- segment0.ts
|--- segment1.ts
.
.
.
|--- segment127.ts
我的app.js
看起来像这样
var http = require('http'),
url = require('url'),
path = require('path'),
fs = require('fs');
var mimeTypes =
"html": "text/html",
"jpeg": "image/jpeg",
"jpg": "image/jpeg",
"png": "image/png",
"js": "text/javascript",
"css": "text/css",
"ts": "video/MP2T",
"m3u8": "application/vnd.apple.mpegurl";
http.createServer(function(req, res)
var uri = url.parse(req.url).pathname;
var filename = path.join(process.cwd(), unescape(uri));
var stats;
console.log('filename '+filename);
try
stats = fs.lstatSync(filename); // throws if path doesn't exist
catch (e)
res.writeHead(404, 'Content-Type': 'text/plain');
res.write('404 Not Found\n');
res.end();
return;
if (stats.isFile())
// path exists, is a file
var mimeType = mimeTypes[path.extname(filename).split(".")[1]];
res.writeHead(200, 'Content-Type': mimeType );
var fileStream = fs.createReadStream(filename);
fileStream.pipe(res);
else if (stats.isDirectory())
// path exists, is a directory
res.writeHead(200, 'Content-Type': 'text/plain');
res.write('Index of '+uri+'\n');
res.write('TODO, show index?\n');
res.end();
else
// Symbolic link, other?
// TODO: follow symlinks? security?
res.writeHead(500, 'Content-Type': 'text/plain');
res.write('500 Internal server error\n');
res.end();
).listen(8000);
test.m3u8 长这样
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:19
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:12.595922,
segment0.ts
.
.
.
我使用 ffmpeg 创建了片段和 palylist
ffmpeg -i video-a.mp4 -c:a libmp3lame -ar 48000 -ab 64k -c:v libx264 -b:v 128k -flags -global_header -map 0 -f segment -segment_list test.m3u8 -segment_time 30 -segment_format mpegts segment_%05d.ts
测试场景:- 如果从 Apache 提供服务,则可以正常工作,如果从节点提供,则不能。
测试工具:- VNC播放器
【问题讨论】:
为什么不让express.static
为你做这件事?
"我之前使用过 "connect.static
",但它不起作用。但是使用 "express.static
" 它似乎可以工作. 谢谢你的想法。”
【参考方案1】:
根据 Brad 的想法,我能够使用 express.static 做到这一点。解决方案来了。
app.js是这样改的
var express = require('express');
var app = express();
var path = require('path');
app.use(express.static(path.join(__dirname,'streamcontent')));
app.listen(8000);
console.log('Listening on Port 8000');
.m3u8 播放列表更改为此
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:19
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:12.595922,
http://localhost:8000/segment0.ts
#EXTINF:10.135133,
http://localhost:8000/segment1.ts
#EXTINF:11.511511,
http://localhost:8000/segment2.ts
就是这样。瞧!!!
【讨论】:
没有。 m3u8 流在 chrome 中不起作用。我使用 VLC 播放器在 Windows 中进行测试。虽然在 Mac-Safari 中完美运行。不适用于 Win-Safari。 @bitoiu,hls 流不直接在视频标签中工作,但一些第三方提供像 hls.js 这样的播放器。 我用 Microsoft Edge 浏览器播放 m3u8 文件。以上是关于使用节点 JS 的 HLS 流式传输的主要内容,如果未能解决你的问题,请参考以下文章
使用节点 fluent-ffmpeg 流式传输 mp4 视频
使用 Nginx 或 Node 流式传输保存的 HLS 视频