前言
后端 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为例
- 下载 :ffmpeg官网下载压缩包
- 安装: 把下载的安装包解压到指定的目录
- 配置:把例如:把D:/ffmpeg/bin 配置到系统变量的Path中
- 验证是否安装成功:打开终端执行 ffmpeg -version查看版本号返回版本号说明安装配置成功
- 常用指令操作
推流场景汇总
本地文件(例如:.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 分钟上线直播。