You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:08:42