菜单

FFmpeg 录制

相关源文件

FFmpeg 录制是 OBS Studio 中主要的录像文件系统,负责处理编码并将捕获的音频和视频保存到磁盘。它提供了一个灵活的框架,可以以各种格式进行录制,同时保持高质量和高性能。本页介绍了 FFmpeg 录制子系统的架构和实现。

有关 FFmpeg 流媒体的信息,请参阅RTMP 流媒体

概述

OBS Studio 中的 FFmpeg 录制系统负责:

  1. 从 OBS 编码器接收编码后的音频和视频数据包
  2. 使用 FFmpeg 库对其进行正确格式化
  3. 将它们复用到容器格式中(如 MP4、MKV 等)
  4. 将生成的文件写入磁盘

该系统使用一个独立的进程(obs-ffmpeg-mux)进行实际的文件写入,以防止主 OBS 进程中出现潜在的性能下降,并提供抵御编码错误的弹性。

来源:plugins/obs-ffmpeg/obs-ffmpeg-output.c579-602 plugins/obs-ffmpeg/obs-ffmpeg-mux.c95-111

架构

录制流程

该架构使用一个独立的进程进行复用和文件写入,这提供了以下几个好处:

  1. 将潜在的文件 I/O 瓶颈与主 OBS 进程隔离
  2. 防止录制失败影响流媒体或用户界面
  3. 允许在编码错误时进行恢复

来源:plugins/obs-ffmpeg/obs-ffmpeg-output.c646-723 plugins/obs-ffmpeg/obs-ffmpeg-output.c899-927 plugins/obs-ffmpeg/obs-ffmpeg-mux.c304-311

数据流详情

来源:plugins/obs-ffmpeg/obs-ffmpeg-output.c1086-1102 plugins/obs-ffmpeg/obs-ffmpeg-output.c1104-1126

核心组件

FFmpeg 输出

ffmpeg_output 结构体在主 OBS 进程中管理录制过程。它负责:

  • 编码器和 FFmpeg 上下文的初始化
  • 数据包队列的管理
  • 与复用器进程的通信
struct ffmpeg_output {
    obs_output_t *output;          // The OBS output instance
    struct ffmpeg_data ff_data;    // FFmpeg configuration and state
    pthread_t write_thread;        // Thread for writing packets to muxer
    DARRAY(AVPacket *) packets;    // Queue of packets to be written
    volatile bool active;          // Recording active flag
    uint64_t total_bytes;          // Total bytes written
}

来源:plugins/obs-ffmpeg/obs-ffmpeg-output.h90-118 plugins/obs-ffmpeg/obs-ffmpeg-output.c579-602

FFmpeg 复用器

复用器作为独立的执行文件(obs-ffmpeg-mux)实现,它:

  • 通过管道接收编码数据包
  • 配置输出容器格式
  • 将数据包写入输出文件
  • 处理错误和恢复

来源:plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c990-1009 plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c860-939

通信协议

OBS 进程通过管道与复用器进程通信。协议包括:

对于每个编码帧,此结构体通过管道发送到复用器进程,然后复用器进程根据其类型(视频、音频或控制消息)进行处理。

来源:plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.h22-39 plugins/obs-ffmpeg/obs-ffmpeg-mux.c603-638

配置与初始化

录制格式配置

FFmpeg 录制系统支持多种容器格式,用户可在设置中进行配置:

格式文件扩展名描述
MP4.mp4兼容性广,但若 OBS 崩溃可能导致文件损坏
MKV.mkv对崩溃更具弹性,稍后可复用为 MP4
MOV.movQuickTime 容器格式
FLV.flvFlash 视频容器格式
TS.tsMPEG 传输流格式
M3U8/TS.m3u8HTTP 直播流格式

初始化过程

来源:plugins/obs-ffmpeg/obs-ffmpeg-output.c502-556 plugins/obs-ffmpeg/obs-ffmpeg-output.c946-1074

数据处理

视频帧处理

当从编码器接收到视频帧时:

  1. 如有必要,将帧转换为适当的像素格式
  2. 计算帧时间戳
  3. 使用配置的编解码器对帧进行编码
  4. 将生成的数据包添加到写入队列
receive_video():
  1. Check if video encoder is active
  2. Convert frame format if necessary (using swscale)
  3. Send frame to encoder
  4. Receive encoded packet
  5. Add packet to queue
  6. Signal write thread

来源:plugins/obs-ffmpeg/obs-ffmpeg-output.c646-723

音频帧处理

音频帧处理遵循类似的模式:

  1. 音频采样被累积直到凑足一个完整帧
  2. 使用配置的音频编解码器对帧进行编码
  3. 数据包排队等待写入
receive_audio():
  1. Push audio data into excess_frames queue
  2. While enough samples are available:
     a. Pop samples for one frame
     b. Encode audio frame
     c. Add packet to queue
     d. Signal write thread

来源:plugins/obs-ffmpeg/obs-ffmpeg-output.c799-838

写入线程

写入线程处理数据包队列。

write_thread():
  1. Wait for signal (new data or stop event)
  2. Dequeue packet
  3. Write packet to muxer process
  4. Check for errors
  5. Repeat until stopped

来源:plugins/obs-ffmpeg/obs-ffmpeg-output.c899-927

文件分割录制

FFmpeg 录制系统支持根据以下条件自动分割文件:

  • 文件大小限制
  • 时间长度限制
  • 手动触发

此功能允许在长时间录制会话中创建多个文件,这可以改善文件处理,并减少因文件损坏而丢失大量数据的风险。

来源:plugins/obs-ffmpeg/obs-ffmpeg-mux.c688-733 plugins/obs-ffmpeg/obs-ffmpeg-mux.c738-807

性能考量

磁盘 I/O 管理

为避免磁盘 I/O 引起的性能问题,FFmpeg 复用器进程使用缓冲 I/O 和分块写入。

ffmpeg_mux_io_thread():
  1. Accumulate writes into chunks
  2. When chunk is full or force flush required:
     a. Perform any necessary seeking
     b. Write chunk to disk
  3. Signal buffer space available

这种方法通过减少磁盘操作次数,显著提高了性能,尤其是在较慢的存储设备上。

来源:plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c658-793

错误处理和恢复

该系统包含健壮的错误处理:

  1. 复用器进程错误被捕获并报告回 OBS
  2. 写入文件流过程中的网络问题被检测和处理
  3. 如果复用器进程失败,OBS 可以清理并报告相应的错误
process_packet():
  1. Write packet to muxer
  2. If error:
     a. Read error message from pipe
     b. Set appropriate error code
     c. Signal stop with error
     d. Deactivate recording

来源:plugins/obs-ffmpeg/obs-ffmpeg-output.c859-897 plugins/obs-ffmpeg/obs-ffmpeg-mux.c512-544

结论

OBS Studio 中的 FFmpeg 录制系统提供了一个灵活、健壮且高性能的解决方案,用于将捕获的内容录制到磁盘。通过为复用和文件操作使用独立的进程,它在处理潜在的 I/O 瓶颈的同时,保持了主要 OBS 应用程序的响应性。

该系统通过强大的 FFmpeg 库支持广泛的格式和编解码器,使用户可以对其录制文件的质量、文件大小和兼容性拥有广泛的控制。