10 分钟搞定直播:Node.js + FFmpeg + flv.js 全栈实战

前言

后端 Node + 前端 flv.js + 推/拉流 FFmpeg,10 分钟搭好,支持文件、摄像头、桌面、画中画 4 种直播场景。

架构总览

角色 组件 说明
推流端 FFmpeg 采集 → RTMP
服务端 node-media-server RTMP 入口 / HTTP-FLV 出口
播放端 flv.js + <video> 浏览器无插件播放

服务端

arduino 复制代码
const NodeMediaServer = require('node-media-server');
const config = {
  rtmp: {                     // 接收推流
    port: 1935,
    chunk_size: 60000,
    gop_cache: true,
    ping: 30,
    ping_timeout: 60
  },
  http: {                     // 浏览器拉流
    port: 8000,
    allow_origin: '*'
  }
};
new NodeMediaServer(config).run();
console.log('RTMP 推流地址: rtmp://192.168.16.101:1935/live/stream');
console.log('HTTP-FLV 拉流地址: http://192.168.16.101:8000/live/stream.flv');

播放端

xml 复制代码
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8"/>
  <title>Node 直播 Demo</title>
  <script src="https://cdn.jsdelivr.net/npm/flv.js@latest/dist/flv.min.js"></script>
</head>
<body>
  <video id="video" width="640" height="360" controls autoplay></video>
  <script>
    if (flvjs.isSupported()) {
      const player = flvjs.createPlayer({
        type: 'flv',
        isLive: true,
        url: 'http://192.168.16.101:8000/live/stream.flv'
      });
      player.attachMediaElement(document.getElementById('video'));
      player.load();
      player.play();
    } else {
      alert('浏览器不支持 flv.js');
    }
  </script>
</body>
</html>

推流端

安装:以window为例

  1. 下载ffmpeg官网下载压缩包
  2. 安装: 把下载的安装包解压到指定的目录
  3. 配置:把例如:把D:/ffmpeg/bin 配置到系统变量的Path中
  4. 验证是否安装成功:打开终端执行 ffmpeg -version查看版本号返回版本号说明安装配置成功
  5. 常用指令操作

推流场景汇总

本地文件(例如:.mp4)
  • 执行指令 :ffmpeg -re -i 本地文件路径 -c copy -f flv 拉流地址
    • 本地文件路径(绝对路径):C:\Users\ly\Desktop\vd.mp4
    • 拉流地址:rtmp://localhost:1935/live/stream
    • 特殊说明前端页面的 fvl中的url和此指令的路径保持一致
全屏
  • 查看摄像头和麦克风的名称 :ffmpeg -list_devices true -f dshow -i dummy
    • 摄像头名:ACER HD User Facing
    • 麦克风名:麦克风阵列 (适用于数字麦克风的英特尔® 智音技术)
  • 执行指令 :ffmpeg -f dshow -i video="摄像头名":audio="麦克风名" -s 1280x720 -r 30 -c:v libx264 -preset ultrafast -tune zerolatency -c:a aac -ar 44100 -b:a 96k -f flv rtmp://localhost:1935/live/stream
    • 摄像头名:ACER HD User Facing
    • 麦克风名:麦克风阵列 (适用于数字麦克风的英特尔® 智音技术)
    • 拉流地址 :rtmp://localhost:1935/live/stream 说明:前端页面的 fvl中的url和此指令的路径保持一致
全屏 + 摄像头画中画(摄像头放右下角)
  • 执行指令:ffmpeg ^ -f gdigrab -framerate 30 -video_size 1920x1080 -i desktop ^ -f dshow -i video="ACER HD User Facing":audio="麦克风阵列 (适用于数字麦克风的英特尔® 智音技术)" ^ -filter_complex "[1:v]scale=320:180[cam];[0:v][cam]overlay=W-w-10:H-h-10" ^ -c:v libx264 -preset ultrafast -tune zerolatency -f flv ^ rtmp://localhost:1935/live/stream
抓屏幕
  • 获取所有窗口标题:Get-Process | Where-Object { $_.MainWindowTitle -ne "" } | Format-Table Id,ProcessName,MainWindowTitle

  • 执行指令 :ffmpeg -f gdigrab -framerate 30 -i title=一口气了解稳定币 ^ -vf scale=2trunc(iw/2):2trunc(ih/2),setsar=1:1 ^ -c:v libx264 -preset ultrafast -tune zerolatency ^ -f flv rtmp://localhost:1935/live/stream

  • 特别说明 :window上抓取屏幕时会出现黑屏,解决方法如下:改用 ScreenCaptureRecorder(DXGI 桌面复制,无视硬件加速)

  • 执行指令:ffmpeg -f dshow ^ -i video="screen-capture-recorder":audio="virtual-audio-capturer" ^ -c:v libx264 -preset ultrafast -tune zerolatency ^ -s 1280x720 -r 30 ^ -f flv rtmp://localhost:1935/live/stream

Ffmpeg指令汇总

裁剪、合并、截取

场景 命令示例
截取 00:01:30 起 30 秒 ffmpeg -i in.mp4 -ss 00:01:30 -t 30 -c copy clip.mp4
合并多个 MP4 printf "file '%s'\n" *.mp4 > list.txt && ffmpeg -f concat -i list.txt -c copy all.mp4
去掉片头 5 秒 ffmpeg -i in.mp4 -ss 5 -c copy nohead.mp4

提取与复用

场景 命令示例
提取音频(MP3) ffmpeg -i in.mp4 -vn -acodec libmp3lame -q:a 2 audio.mp3
提取视频裸流(H264) ffmpeg -i in.mp4 -vcodec copy -an video.h264
YUV 原始数据 → H264 ffmpeg -f rawvideo -pix_fmt yuv420p -s 1280x720 -r 30 -i in.yuv -c:v libx264 out.h264

格式/编码转换

场景 命令示例
MKV → MP4(无损封装) ffmpeg -i in.mkv -c copy out.mp4
MP4 → GIF(10 秒) ffmpeg -i in.mp4 -ss 0 -t 10 -vf fps=10,scale=320:-1 out.gif
压缩并重编码 ffmpeg -i in.mp4 -c:v libx264 -crf 28 -preset slow -c:a aac -b:a 128k small.mp4

过滤

场景 命令示例 说明
缩放为 50 % ffmpeg -i in.mp4 -vf scale=iw/2:-1 half.mp4 目标文件 :(in.mp4);输出文件 :(half.mp4);设置: 缩放为 50 %
添加文字水印 ffmpeg -i in.mp4 -vf "drawtext=text='Hello':fontsize=36:fontcolor=white:x=10:y=10" -c:a copy out.mp4 设置:水印文字hello 字体样式:大小36颜色white 坐标(10,10)
n× 倍速(音画同步) ffmpeg -i in.mp4 -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" fast.mp4 设置:n倍速
自动安全裁切 ffmpeg -i in.mp4 -filter:v "crop=min(800,iw-100):min(600,ih-50):100:50" -c:a copy cut.mp4 设置: 裁切 800:600
万能安全裁切 ffmpeg -i in.mp4 -filter:v "scale=1920:1080,crop=800:600:100:50" -c:a copy cut.mp4 设置: 先 scale 再 crop

HLS 切片

场景 命令示例 说明
MP4 → HLS (m3u8 + ts) ffmpeg -i in.mp4 -c:v libx264 -c:a aac -f hls -hls_time 6 -hls_list_size 0 index.m3u8 设置:把in.mp4切成6s的m3u8的切片集合(index0.ts,index1.ts,.....)

调试/播放

场景 命令示例 说明
查看媒体信息 ffprobe -v quiet -print_format json -show_streams in.mp4 返回视频信息json文件
播放 YUV ffplay -pix_fmt yuv420p -s 1280x720 out.yuv
播放 PCM ffplay -ar 44100 -ac 2 -f s16le out.pcm

总结

至此,一套「Node.js 极速直播」方案已就绪:

  • 后端 10 行代码开启 RTMP / HTTP-FLV 服务
  • 前端一行 <video> + flv.js 即播
  • FFmpeg 一条命令覆盖文件、摄像头、桌面、画中画全场景
  • 常用剪辑/转码/提取指令速查表随取随用

复制即用,10 分钟上线直播。

相关推荐
Warren983 小时前
Lua 脚本在 Redis 中的应用
java·前端·网络·vue.js·redis·junit·lua
mCell3 小时前
JavaScript 运行机制详解:再谈 Event Loop
前端·javascript·浏览器
帧栈7 小时前
开发避坑指南(27):Vue3中高效安全修改列表元素属性的方法
前端·vue.js
max5006007 小时前
基于桥梁三维模型的无人机检测路径规划系统设计与实现
前端·javascript·python·算法·无人机·easyui
smileNicky7 小时前
SpringBoot系列之从繁琐配置到一键启动之旅
java·spring boot·后端
excel8 小时前
使用函数式封装绘制科赫雪花(Koch Snowflake)
前端
David爱编程8 小时前
为什么必须学并发编程?一文带你看懂从单线程到多线程的演进史
java·后端
long3168 小时前
java 策略模式 demo
java·开发语言·后端·spring·设计模式
萌萌哒草头将军8 小时前
Node.js v24.6.0 新功能速览 🚀🚀🚀
前端·javascript·node.js
rannn_11110 小时前
【Javaweb学习|黑马笔记|Day1】初识,入门网页,HTML-CSS|常见的标签和样式|标题排版和样式、正文排版和样式
css·后端·学习·html·javaweb