音视频高级项目-基于obs多路推流项目介绍
内容来自:程序员老廖
1.1 项目背景
1.1.1 直播行业的发展
随着互联网技术的发展,直播已经成为内容创作者与观众互动的重要方式。主播们经常需要同时在多个平台进行直播,以扩大受众范围和提高收入。
生活化类比:想象你是一个街头艺人,想要同时在不同的广场表演给更多观众看。传统方式就像你需要:
- 🎭 雇佣多个替身分别去不同广场(多台电脑)
- 💰 付钱给中介帮你转播(第三方服务)
- 🎪 每个广场都要重新搭建舞台(重复配置)
而obs-multi-rtmp就像给你装了一个"分身术",让你站在一个舞台上,同时出现在所有广场!
传统方式的问题:
┌──────────────┐ ┌────────────┐ ┌─────────────┐
│ 电脑 1 │ │ 电脑 2 │ │ 电脑 3 │
│ OBS → 斗鱼 │ │ OBS → B站 │ │ OBS → 抖音 │
└──────────────┘ └────────────┘ └─────────────┘
💻💰 💻💰 💻💰
(资源浪费) (资源浪费) (资源浪费)
OBS多路推流实现代码和详细文档:音视频高级项目-基于obs多路推流实现-支持多协议(WebRTC / SRT / RTMP)
1.1.2 OBS Multi-RTMP 的诞生
obs-multi-rtmp 插件应运而生,它允许用户在单个 OBS 实例中同时向多个平台推流,解决了上述所有问题。
生活化类比:就像一个水龙头接了多个水管,同时给不同的花园浇水!
主要优势:
- ✅ 单一 OBS 实例,节省系统资源(就像一台发动机带动多个轮子)
- ✅ 统一管理所有推流目标(一个遥控器控制所有电视)
- ✅ 每个目标可以独立配置编码参数(每个水管可以调节水流大小)
- ✅ 完全免费开源(免费的"分身术")
- ✅ 支持多种流媒体协议(兼容各种"广场")
1.2 核心功能详解
1.2.1 多路推流
功能描述:同时向多个流媒体服务器推送视频流。
生活化类比:就像一个老师同时给多个班级上网课!
- 一班的学生在教室A听课
- 二班的学生在教室B听课
- 三班的学生在教室C听课
- 老师只需要讲一次,所有班级都能听到!
┌─────────────────┐
│ 你的直播 │
│ (摄像头+游戏) │
└────────┬────────┘
│
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
┌───────────┐ ┌──────────┐ ┌─────────┐
│ 斗鱼 🐟 │ │ B站 📺 │ │ 抖音 🎵 │
│ 1080p60 │ │ 1080p30 │ │ 720p30 │
│ 6000kbps │ │ 6000kbps │ │ 4000kbps│
└───────────┘ └──────────┘ └─────────┘
应用场景:
- 🎮 游戏主播:同时在 YouTube、Twitch、B站直播
- 🏢 企业活动:向不同地区的 CDN 节点推流
- 🔄 主备推流:提高可靠性(就像双保险)
- 🏠 内外网:内网和外网同时推流
1.2.2 独立编码器配置
功能描述:每个推流目标可以使用不同的编码器和编码参数。
生活化类比:就像给不同的朋友寄包裹!
- 给隔壁邻居:用自行车送,快速便宜(低码率)
- 给外地朋友:用快递,标准服务(中码率)
- 给重要客户:用顺丰特快,高质量(高码率)
同样的内容,根据"距离"(平台要求)选择不同的"运输方式"(编码参数)!
你的直播内容
│
┌─────────────────┼─────────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌─────────┐ ┌──────────┐
│YouTube │ │ Twitch │ │ B站 │
│高清画质 │ │标准画质 │ │中等画质 │
│1080p60 │ │ 720p60 │ │1080p30 │
│6000kbps │ │5000kbps │ │6000kbps │
│软件编码 │ │硬件编码 │ │软件编码 │
└──────────┘ └─────────┘ └──────────┘
🚀 🏃 🚶
(高质量) (平衡) (兼容)
为什么需要独立配置?
不同平台就像不同的"水管",有粗有细:
配置示例:
// YouTube 配置 - 高质量(像给VIP客户的豪华套餐)
VideoEncoderConfig youtube_config = {
.encoderId = "obs_x264", // 软件编码(精细加工)
.resolution = "1920x1080", // 全高清
.fps = 60, // 丝滑流畅
.bitrate = 6000, // 高码率
.preset = "medium" // 中等速度
};
// Twitch 配置 - 平衡(像标准快递)
VideoEncoderConfig twitch_config = {
.encoderId = "ffmpeg_nvenc", // 硬件编码(快速处理)
.resolution = "1280x720", // 高清
.fps = 60, // 流畅
.bitrate = 5000, // 中等码率
.preset = "p5" // 平衡模式
};
// B站 配置 - 兼容性(像经济实惠套餐)
VideoEncoderConfig bilibili_config = {
.encoderId = "obs_x264", // 软件编码
.resolution = "1920x1080", // 全高清
.fps = 30, // 标准流畅
.bitrate = 6000, // 中等码率
.preset = "veryfast" // 快速编码
};
1.2.3 场景选择
功能描述:每个推流目标可以选择不同的场景。
生活化类比:就像拍电影时给不同观众看不同的版本!
- 院线版:完整版,有特效有字幕(主平台)
- 电视版:删减版,去掉部分内容(次要平台)
- 导演剪辑版:加长版,包含花絮(录制)
你的OBS工作区
┌───────────────────────────┐
│ 场景1:完整场景 │
│ ├─ 游戏画面 🎮 │
│ ├─ 摄像头 📷 │
│ ├─ 聊天框 💬 │
│ └─ 捐赠提示 💰 │
│ │
│ 场景2:游戏场景 │
│ └─ 游戏画面 🎮 (纯净版) │
│ │
│ 场景3:录制场景 │
│ ├─ 游戏画面 🎮 │
│ ├─ 摄像头 📷 │
│ ├─ 聊天框 💬 │
│ ├─ 捐赠提示 💰 │
│ └─ 水印 © │
└──────────────────────────┘
│
├──► YouTube: 场景1 (完整场景)
├──► Twitch: 场景2 (游戏场景)
└──► 录制: 场景3 (录制场景)
实现方式:
// 为不同目标设置不同场景 target1->outputScene = "完整场景"; // YouTube - 给VIP观众看 target2->outputScene = "游戏场景"; // Twitch - 给普通观众看 target3->outputScene = "录制场景"; // 本地录制 - 存档用
1.2.4 分辨率和帧率定制
功能描述:每个目标可以输出不同的分辨率和帧率。
生活化类比:就像给不同的人发照片!📸
- 给专业摄影师:发原图,超高清(1080p60)
- 给朋友圈:发压缩图,标清(720p30)
- 给微信:发缩略图,省流量(480p24)
原始视频流 (1080p60fps)
│
├────────────────────────────────────┐
│ │
▼ ▼
┌────────────┐ ┌───────────┐
│ YouTube │ │ 抖音 │
│ 1080p60 │ │ 720p30 │
│ 不降低 │ │ 降一半 │
│ 高质量 │ │ 省流量 │
└────────────┘ └───────────┘
性能优化:
- 🚀 高端平台使用高分辨率(1080p/4K)- 像开跑车
- 🚗 标准平台使用中分辨率(720p)- 像开轿车
- 🚲 移动端平台使用低分辨率(480p)- 像骑自行车
降帧率示例:
// 原始视频:60fps(每秒60张照片) // 目标1:60fps(不降帧 - 全速播放) config1.fpsDenumerator = 1; // 60/1 = 60fps // 目标2:30fps(降一半 - 省一半流量) config2.fpsDenumerator = 2; // 60/2 = 30fps // 目标3:20fps(降到1/3 - 省更多流量) config3.fpsDenumerator = 3; // 60/3 = 20fps
1.2.5 音频轨道映射
功能描述:灵活配置音频轨道,不同目标可以包含不同的音频内容。
生活化类比:就像调音台的多个推子!🎚️ 想象你是DJ,有多个音源:
- 🎤 麦克风(你的声音)
- 🎮 游戏音效
- 🎵 背景音乐
- 🔔 提示音
你可以决定哪个平台听到哪些声音,就像给不同房间播放不同的音乐组合!
OBS音频轨道系统(像一个6层的蛋糕) ┌────────────────────────────────────┐ │ 轨道1: 🎤麦克风 + 🎮游戏 (主音频) │ ◄─ 所有平台都要 ├────────────────────────────────────┤ │ 轨道2: 🎮游戏音效 (纯净) │ ◄─ 可选 ├────────────────────────────────────┤ │ 轨道3: 🎤麦克风 (纯净) │ ◄─ 可选 ├────────────────────────────────────┤ │ 轨道4: 🎵背景音乐 (有版权) │ ◄─ 小心版权! ├────────────────────────────────────┤ │ 轨道5: 🔔音效提示 │ ◄─ 捐赠、关注等 ├────────────────────────────────────┤ │ 轨道6: 📢备用 │ ◄─ 预留 └────────────────────────────────────┘
应用场景:
场景1:版权音乐处理(避免被静音)
// YouTube(包含所有音频 - 因为你买了版权)
youtube_tracks = {1, 4, 5}; // 主音频 + 音乐 + 音效
// Twitch(不包含版权音乐 - 避免被静音)
twitch_tracks = {1, 5}; // 主音频 + 音效(无音乐)
// 本地录制(完整音频 - 自己存档没问题)
local_tracks = {1, 2, 3, 4, 5}; // 所有轨道
场景2:多语言直播(一个画面,多种语言)
// 中文频道(给中国观众)
chinese_tracks = {1}; // 中文解说 🇨🇳
// 英文频道(给国际观众)
english_tracks = {2}; // 英文解说 🇺🇸
// 游戏音效(两个频道共享)
game_audio_track = 3; // 游戏声音 🎮
1.2.6 同步控制
功能描述:推流目标可以与 OBS 主推流同步启动/停止。
生活化类比:就像汽车的主副驾驶安全带提醒!
- 主驾驶系安全带(主推流启动)→ 副驾驶也提醒(备份推流自动启动)
- 主驾驶解开安全带(主推流停止)→ 副驾驶提醒关闭(备份推流自动停止)
场景1:手动控制(你是老司机)
┌──────────────────────────┐
│ 主推流 YouTube │ 你手动启动
└─────────────┬────────────┘
│
├─ 不影响 ─► 备份推流(独立控制)
└─ 不影响 ─► 录制(独立控制)
场景2:自动同步(新手模式)
┌──────────────────────────┐
│ 主推流 YouTube │ 你手动启动
└─────────────┬────────────┘
│
├─ 自动启动 ─► 备份推流(跟着走)
└─ 自动启动 ─► 录制(跟着走)
配置选项:
- syncStart:主推流启动时自动启动(像连锁反应)
- syncStop:主推流停止时自动停止(像多米诺骨牌)
使用场景:
// 主平台(手动控制 - 你是船长) youtube_config.syncStart = false; // 我自己决定什么时候开始 youtube_config.syncStop = false; // 我自己决定什么时候结束 // 备份平台(自动同步 - 跟着船长走) backup_config.syncStart = true; // 船长开船,我就开船 backup_config.syncStop = true; // 船长停船,我就停船 // 录制(仅同步停止 - 确保不漏录) record_config.syncStart = false; // 我可能提前开始录 record_config.syncStop = true; // 但一定要跟着一起停!
1.2.7 状态监控
功能描述:实时显示每个推流的状态、码率、帧率、丢帧等信息。
生活化类比:就像汽车的仪表盘!
- 速度表 → 码率(数据传输速度)
- 转速表 → 帧率(画面流畅度)
- 油表 → 带宽使用情况
- 故障灯 → 丢帧警告
推流监控面板(像飞机驾驶舱) ╔════════════════════════════════════════════════════════════╗ ║ YouTube 推流监控 🟢 运行中 ║ ╠════════════════════════════════════════════════════════════╣ ║ ⏱️ 运行时间: 01:23:45 ║ ║ 📊 实时码率: 5850 kbps ████████████░░ (97%) ║ ║ 🎬 实时帧率: 59.8 fps ████████████░░ (99%) ║ ║ ⚠️ 丢帧统计: 12 帧 (0.2%) ✅ 正常 ║ ║ 📈 总数据量: 3.2 GB ║ ║ 🌐 网络状态: 优秀 (延迟: 15ms) ║ ╚════════════════════════════════════════════════════════════╝ ╔════════════════════════════════════════════════════════════╗ ║ Twitch 推流监控 🟢 运行中 ║ ╠════════════════════════════════════════════════════════════╣ ║ ⏱️ 运行时间: 01:23:45 ║ ║ 📊 实时码率: 4920 kbps ██████████░░░░ (82%) ║ ║ 🎬 实时帧率: 60.0 fps ███████████░░ (100%) ║ ║ ⚠️ 丢帧统计: 3 帧 (0.05%) ✅ 优秀 ║ ║ 📈 总数据量: 2.6 GB ║ ║ 🌐 网络状态: 良好 (延迟: 28ms) ║ ╚════════════════════════════════════════════════════════════╝ ╔════════════════════════════════════════════════════════════╗ ║ B站 推流监控 🔴 警告 ║ ╠════════════════════════════════════════════════════════════╣ ║ ⏱️ 运行时间: 01:23:45 ║ ║ 📊 实时码率: 5980 kbps ████████████░░ (99%) ║ ║ 🎬 实时帧率: 29.9 fps ███████████░░ (99%) ║ ║ ⚠️ 丢帧统计: 156 帧 (5.2%) ⚠️ 需要注意 ║ ║ 📈 总数据量: 3.1 GB ║ ║ 🌐 网络状态: 一般 (延迟: 85ms) ║ ╚════════════════════════════════════════════════════════════╝
监控指标详解:
UI 显示示例:
实时监控(每秒更新) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ [YouTube] 🟢 推流中 | ⏱️ 01:23:45 | 📊 5850 kbps | 🎬 59.8 fps | ⚠️ 12 (0.2%) [Twitch] 🟢 推流中 | ⏱️ 01:23:45 | 📊 4920 kbps | 🎬 60.0 fps | ⚠️ 3 (0.05%) [B站] 🔴 警告 | ⏱️ 01:23:45 | 📊 5980 kbps | 🎬 29.9 fps | ⚠️ 156 (5.2%) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- 丢帧数:编码器丢帧 + 网络丢帧
- 丢帧率:丢帧数 / 总帧数
- 网络拥塞:0-100%
UI 显示示例:
[YouTube] 推流中 | 01:23:45 | 5850 kbps | 59.8 fps | 丢帧: 12 (0.2%) [Twitch] 推流中 | 01:23:45 | 4920 kbps | 60.0 fps | 丢帧: 3 (0.05%) [B站] 推流中 | 01:23:45 | 5980 kbps | 29.9 fps | 丢帧: 0 (0%)
1.3 技术栈详解
1.3.1 编程语言:C++17
生活化类比:C++就像一把瑞士军刀🔪,功能强大但需要技巧!
为什么选择 C++?
- 🏎️ OBS Studio 本身使用 C/C++ 开发(原生支持)
- ⚡ 高性能,适合音视频处理(像F1赛车)
- 🔌 直接访问 OBS API(无需转接头)
- 🌍 跨平台支持(Windows/macOS/Linux通吃)
编程语言选择(像选交通工具) ┌─────────────────────────────────────────────────┐ │ Python 🐍 │ 简单易学,但速度慢 │ 🚲 自行车 │ JavaScript 📜│ 灵活方便,但不够快 │ 🛵 摩托车 │ C++ 🔧 │ 复杂强大,性能最高 │ 🏎️ F1赛车 │ Rust 🦀 │ 安全高效,但学习曲线陡 │ 🚀 火箭 └─────────────────────────────────────────────────┘
C++17 新特性的使用:
// 1. std::optional - 可选值(像薛定谔的猫,可能有可能没有)
std::optional<std::string> resolution;
if (resolution.has_value()) {
// 盒子里有猫!使用自定义分辨率
std::cout << "分辨率: " << resolution.value();
} else {
// 盒子是空的,使用默认值
std::cout << "使用默认分辨率";
}
// 2. 结构化绑定(像拆快递,一次拿出多个东西)
auto [width, height] = ParseResolution("1920x1080");
// 相当于:int width = 1920; int height = 1080;
// 3. if 初始化语句(边找边用,不浪费)
if (auto config = FindConfig(id); config != nullptr) {
// 找到了配置,立即使用
config->apply();
}
// 4. std::filesystem - 文件系统操作(像文件管理器)
std::filesystem::path config_path = GetConfigPath();
if (std::filesystem::exists(config_path)) {
// 文件存在,加载配置
LoadConfig(config_path);
}
1.3.2 UI 框架:Qt6
生活化类比:Qt就像乐高积木🧱,用标准零件搭建漂亮的房子!
为什么选择 Qt?
- 🏠 OBS Studio 使用 Qt 作为 UI 框架(原装配件)
- 🌍 跨平台 UI 开发(一次编写,到处运行)
- 🎨 丰富的控件库(各种形状的积木)
- 🔌 信号与槽机制(像电路连接)
Qt控件库(像家具商场) ┌──────────────────────────────────────┐ │ 🪟 QWidget │ 基础窗口(毛坯房) │ │ 🖼️ QDialog │ 对话框(弹窗) │ │ 🔘 QPushButton │ 按钮(开关) │ │ 🏷️ QLabel │ 标签(标识牌) │ │ ✏️ QLineEdit │ 文本框(输入框) │ │ 📋 QComboBox │ 下拉框(菜单) │ │ 📊 QTableWidget │ 表格(账本) │ │ ⏱️ QTimer │ 定时器(闹钟) │ └──────────────────────────────────────┘
Qt 核心组件:
// 1. QWidget - 基础控件类(像房子的地基)
QWidget *window = new QWidget();
window->setWindowTitle("多路推流");
window->resize(800, 600);
// 2. QLayout - 布局管理(像家具摆放规则)
QVBoxLayout *layout = new QVBoxLayout(); // 垂直布局(上下排列)
layout->addWidget(label); // 添加标签
layout->addWidget(button); // 添加按钮
// 3. 信号与槽 - 事件连接(像门铃和铃声)
QPushButton *button = new QPushButton("开始推流");
connect(button, &QPushButton::clicked, // 按钮被点击(门铃被按)
this, &MainWindow::startStream); // 执行函数(铃声响起)
// 4. QTimer - 定时器(像闹钟)
QTimer *timer = new QTimer(this);
timer->setInterval(1000); // 每1秒触发一次
connect(timer, &QTimer::timeout, this, &MainWindow::updateStats);
timer->start(); // 启动定时器
1.3.3 构建系统:CMake
生活化类比:CMake就像建筑工程的施工图纸📐,告诉工人怎么盖房子!
为什么使用 CMake?
- 📋 跨平台构建(同一份图纸,各地都能用)
- 🔧 自动查找依赖(自动找到需要的材料)
- 🏗️ 灵活配置(可以盖平房也可以盖楼房)
- 🤝 OBS 官方推荐(行业标准)
CMake构建流程(像盖房子)
┌─────────────────┐
│ 1. 设计图纸 │ CMakeLists.txt(施工图)
└────────┬────────┘
│
▼
┌─────────────────┐
│ 2. 准备材料 │ find_package(找砖头、水泥)
└────────┬────────┘
│
▼
┌─────────────────┐
│ 3. 开始施工 │ cmake --build(开始盖房)
└────────┬────────┘
│
▼
┌─────────────────┐
│ 4. 房子完工 │ obs-multi-rtmp.dll(成品)
└─────────────────┘
CMakeLists.txt 结构:
# 1. 项目基本信息(房子的名字和版本)
cmake_minimum_required(VERSION 3.20) # 最低CMake版本
project(obs-multi-rtmp VERSION 1.0.0) # 项目名称和版本
# 2. 查找依赖(找建筑材料)
find_package(libobs REQUIRED) # 必需:OBS核心库
find_package(obs-frontend-api REQUIRED) # 必需:OBS前端API
find_package(Qt6 COMPONENTS Widgets Core REQUIRED) # 必需:Qt6
# 3. 创建插件(开始盖房子)
add_library(obs-multi-rtmp MODULE) # MODULE = 插件类型
# 4. 链接库(把材料组装起来)
target_link_libraries(obs-multi-rtmp PRIVATE
OBS::libobs # OBS核心(地基)
OBS::obs-frontend-api # OBS前端(框架)
Qt6::Core # Qt核心(水电)
Qt6::Widgets # Qt控件(装修)
)
# 5. 添加源文件(具体的施工步骤)
target_sources(obs-multi-rtmp PRIVATE
src/obs-multi-rtmp.cpp # 主文件
src/push-widget.cpp # 推流控件
src/edit-widget.cpp # 编辑控件
# ... 更多文件
)
# 6. 安装规则(房子盖好后放哪里)
install(TARGETS obs-multi-rtmp
LIBRARY DESTINATION "obs-plugins/64bit" # 插件目录
)
1.3.4 OBS API
生活化类比:OBS API就像遥控器🎮,让你控制OBS这台大机器!
两大核心库:
OBS API架构(像电视台的控制室) ┌────────────────────────────────────┐ │ OBS Studio (电视台) │ ├────────────────────────────────────┤ │ libobs (核心库) │ │ ├─ 📹 视频处理 (摄像机控制) │ │ ├─ 🎤 音频处理 (调音台) │ │ ├─ 🎬 编码器管理 (后期制作) │ │ ├─ 📡 输出管理 (信号发射) │ │ └─ 🎭 场景管理 (导播台) │ ├────────────────────────────────────┤ │ obs-frontend-api (前端API) │ │ ├─ 🖥️ UI集成 (监视器) │ │ ├─ 🔔 事件回调 (通知系统) │ │ ├─ ⚙️ 配置管理 (设置面板) │ │ └─ 🪟 主窗口访问 (总控台) │ └────────────────────────────────────┘
常用 API 示例:
// 1. 创建输出(像打开一个新的发射器)
obs_output_t* output = obs_output_create(
"rtmp_output", // 类型:RTMP输出
"my_output", // 名称:我的输出
nullptr, // 设置:使用默认
nullptr // 热键:无
);
// 2. 创建编码器(像启动一台压缩机)
obs_encoder_t* encoder = obs_video_encoder_create(
"obs_x264", // 类型:x264编码器
"my_encoder", // 名称:我的编码器
settings, // 设置:码率、分辨率等
nullptr // 热键:无
);
// 3. 启动推流(像按下发射按钮)
bool success = obs_output_start(output);
if (success) {
printf("推流启动成功!🚀\n");
} else {
printf("推流启动失败!❌\n");
}
// 4. 获取统计信息(像看仪表盘)
uint64_t total_frames = obs_output_get_total_frames(output); // 总帧数
uint64_t dropped_frames = obs_output_get_frames_dropped(output); // 丢帧数
uint64_t total_bytes = obs_output_get_total_bytes(output); // 总字节数
printf("📊 统计信息:\n");
printf(" 总帧数: %llu\n", total_frames);
printf(" 丢帧数: %llu\n", dropped_frames);
printf(" 总数据: %.2f MB\n", total_bytes / 1024.0 / 1024.0);
1.3.5 JSON 库:nlohmann/json
为什么使用 JSON?
- 人类可读的配置格式
- 易于编辑和调试
- 跨平台兼容
- 支持嵌套结构
使用示例:
#include <json.hpp>
using json = nlohmann::json;
// 创建 JSON 对象
json config = {
{"name", "YouTube"},
{"protocol", "rtmp"},
{"server", "rtmp://a.rtmp.youtube.com/live2"},
{"bitrate", 6000}
};
// 序列化为字符串
std::string json_str = config.dump(4); // 4 空格缩进
// 从字符串解析
json loaded = json::parse(json_str);
// 访问值
std::string name = loaded["name"];
int bitrate = loaded["bitrate"];
1.4 支持的平台
1.4.1 Windows
支持版本:
- Windows 10 (64-bit)
- Windows 11 (64-bit)
编译器:
- Visual Studio 2019
- Visual Studio 2022
依赖:
- OBS Studio 28.0+
- Qt 6.2+
- Visual C++ Redistributable
1.4.2 macOS
支持版本:
- macOS 11 (Big Sur)
- macOS 12 (Monterey)
- macOS 13 (Ventura)
- macOS 14 (Sonoma)
架构:
- Intel x86_64
- Apple Silicon (M1/M2/M3)
依赖:
- Xcode 13+
- OBS Studio 28.0+
- Qt 6.2+
1.4.3 Linux
支持发行版:
- Ubuntu 20.04+
- Debian 11+
- Fedora 35+
- Arch Linux
依赖:
- GCC 9+ 或 Clang 10+
- OBS Studio 28.0+
- Qt 6.2+
1.5 项目架构概览
1.5.1 模块划分
obs-multi-rtmp
├── UI 层
│ ├── 主窗口 (MultiOutputWidget)
│ ├── 推流控件 (PushWidget)
│ ├── 编辑对话框 (EditOutputWidget)
│ └── 属性控件 (OBSPropertiesWidget)
├── 业务逻辑层
│ ├── 输出管理 (OutputManager)
│ ├── 编码器管理 (EncoderManager)
│ ├── 配置管理 (ConfigManager)
│ └── 协议管理 (ProtocolManager)
└── OBS 接口层
├── libobs API
├── obs-frontend-api
└── 信号处理
1.5.2 数据流
用户操作 ↓ UI 事件 ↓ 业务逻辑处理 ↓ OBS API 调用 ↓ 音视频处理 ↓ 网络传输
1.5.3 线程模型
- 主线程(UI 线程):处理 UI 事件和用户交互
- OBS 视频线程:视频渲染和编码
- OBS 音频线程:音频混音和编码
- 输出线程:网络传输(每个输出一个线程)
1.6 与其他方案的对比
1.6.1 vs 多个 OBS 实例
1.6.2 vs 第三方转播服务
1.6.3 vs NDI/SRT 转发
1.7 使用场景
1.7.1 个人主播
需求:同时在多个平台直播,扩大受众
配置示例:
- YouTube:1080p60,6000kbps
- Twitch:720p60,5000kbps
- B站:1080p30,6000kbps
1.7.2 企业直播
需求:多平台分发,不同平台不同内容
配置示例:
- 官网:完整内容,1080p60
- YouTube:公开内容,1080p30
- 内网:完整内容 + 内部信息,1080p60
1.7.3 教育培训
需求:主备推流,确保稳定性
配置示例:
- 主服务器:1080p30,4000kbps
- 备份服务器:1080p30,4000kbps
- 本地录制:1080p60,高质量
1.7.4 活动直播
需求:多机位,多平台,多语言
配置示例:
- 中文频道:机位1,中文解说
- 英文频道:机位2,英文解说
- 录制:所有机位,所有音轨
OBS多路推流实现代码和详细文档:音视频高级项目-基于obs多路推流实现-支持多协议(WebRTC / SRT / RTMP)
#一人推荐一个值得做的项目##校招##C++##简历中的项目经历要怎么写##春招 / 实习投递,你最焦虑的一件事#