Node.js搭建RTMP转HLS直播服务器:回调函数实现求助
解决RTMP转HLS直播服务的回调与流程问题
首先,作为JS新手能上手做这个跨设备直播项目已经超棒了!咱们一步步梳理代码里的问题,把RTMP转HLS的完整流程跑通。
先修正代码里的基础小问题
你的代码里有几个容易踩的小坑,先调整过来:
- 变量名拼写错误:
fmpeg应该是ffmpeg(你导入的是fluent-ffmpeg,变量名写错了) hls-server初始化方式不对:它需要绑定一个HTTP服务器实例,不能直接传端口- 缺失错误回调:新手很容易忽略这个,但没有错误回调的话,出问题你根本不知道哪里错了
- RTMP端口混淆:OBS默认推流用的是1935端口,不是你写的8000,这个要对应上
核心:实现有用的回调函数
空的callback()完全发挥不了监控作用,我们需要给FFmpeg绑定结束回调和错误回调,帮你监控转码状态:
// 转码完成的回调 function onConversionEnd() { console.log('RTMP转HLS流已结束'); // 如果需要清理旧的HLS片段、通知管理员,可以在这里加逻辑 } // 转码出错的回调 function onConversionError(err) { console.error('转码出错了:', err.message); // 这里可以加错误重试、记录日志的逻辑 }
然后把这两个回调绑定到FFmpeg的事件上:
ffmpeg(...) // ... 其他配置 ... .on('end', onConversionEnd) .on('error', onConversionError) .run()
完整流程改造:RTMP接收 + 转码 + HLS分发
你的代码缺少RTMP接收服务器——hls-server只负责提供HLS文件的HTTP访问,不能直接接收RTMP推流。我们需要用node-media-server来接收OBS的推流,再用FFmpeg把RTMP流转成HLS格式,最后用hls-server对外提供播放服务。
步骤1:安装依赖
先把需要的包都装上:
npm install node-media-server fluent-ffmpeg hls-server http
步骤2:完整可运行代码示例
// 导入所需模块 const http = require('http'); const NodeMediaServer = require('node-media-server'); const ffmpeg = require('fluent-ffmpeg'); const HLSServer = require('hls-server'); // 1. 启动RTMP服务器,接收OBS推流 const rmpServerConfig = { rtmp: { port: 1935, chunk_size: 60000, gop_cache: true, ping: 30, ping_timeout: 60 }, http: { port: 8000, allow_origin: '*' } }; const rtmpServer = new NodeMediaServer(rmpServerConfig); rtmpServer.run(); // 2. 启动HLS服务器,提供HLS流播放 const httpServer = http.createServer(); const hlsServer = new HLSServer(httpServer, { path: '/hls', // HLS流的访问路径:http://localhost:8080/hls/output.m3u8 dir: 'public/videos' // 存放HLS文件的目录(记得提前创建好) }); httpServer.listen(8080); console.log('HLS播放服务器运行在 http://localhost:8080'); // 3. 监听RTMP推流事件,收到推流后自动启动转码 rtmpServer.on('prePublish', (id, streamPath, args) => { console.log(`收到OBS推流:${streamPath}`); // RTMP输入流地址(node-media-server接收的流) const rtmpInput = `rtmp://localhost:1935${streamPath}`; // HLS输出文件路径 const hlsOutput = './public/videos/output.m3u8'; // 启动FFmpeg转码 ffmpeg(rtmpInput, { timeout: 432000 }) .addOptions([ '-c:v libx264', '-c:a aac', '-ac 1', '-strict -2', '-crf 18', '-profile:v baseline', // 关键参数:确保兼容iOS设备 '-maxrate 400k', '-bufsize 1835k', '-pix_fmt yuv420p', '-hls_time 10', // 每个HLS片段的时长(秒) '-hls_list_size 6', // 播放列表保留的最新片段数 '-hls_wrap 10', // 片段文件循环覆盖数量 '-start_number 1' ]) .output(hlsOutput) .on('end', () => { console.log(`推流结束,转码完成:${streamPath}`); }) .on('error', (err) => { console.error(`转码失败:${err.message}`); }) .run(); });
关键使用说明
- OBS推流设置:推流地址填
rtmp://localhost:1935/live,流密钥填test(对应代码里的streamPath是/live/test) - HLS播放地址:
http://localhost:8080/hls/output.m3u8,这个地址可以直接在iOS浏览器或播放器里打开 - 回调的作用:
prePublish事件会在OBS开始推流时自动触发,我们在这里启动转码;FFmpeg的end和error回调帮你实时监控转码状态,方便调试和维护
这样调整后,你的直播服务就能正常接收RTMP推流,转成HLS并提供全设备兼容的播放了!
内容的提问来源于stack exchange,提问作者Lorenzo Valenti
相关产品推荐
相关产品推荐

