FFmpeg 录制是 OBS Studio 中主要的录像文件系统,负责处理编码并将捕获的音频和视频保存到磁盘。它提供了一个灵活的框架,可以以各种格式进行录制,同时保持高质量和高性能。本页介绍了 FFmpeg 录制子系统的架构和实现。
有关 FFmpeg 流媒体的信息,请参阅RTMP 流媒体。
OBS Studio 中的 FFmpeg 录制系统负责:
该系统使用一个独立的进程(obs-ffmpeg-mux)进行实际的文件写入,以防止主 OBS 进程中出现潜在的性能下降,并提供抵御编码错误的弹性。
来源:plugins/obs-ffmpeg/obs-ffmpeg-output.c579-602 plugins/obs-ffmpeg/obs-ffmpeg-mux.c95-111
该架构使用一个独立的进程进行复用和文件写入,这提供了以下几个好处:
来源: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_output 结构体在主 OBS 进程中管理录制过程。它负责:
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
复用器作为独立的执行文件(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 | .mov | QuickTime 容器格式 |
| FLV | .flv | Flash 视频容器格式 |
| TS | .ts | MPEG 传输流格式 |
| M3U8/TS | .m3u8 | HTTP 直播流格式 |
来源:plugins/obs-ffmpeg/obs-ffmpeg-output.c502-556 plugins/obs-ffmpeg/obs-ffmpeg-output.c946-1074
当从编码器接收到视频帧时:
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
音频帧处理遵循类似的模式:
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 引起的性能问题,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
该系统包含健壮的错误处理:
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 库支持广泛的格式和编解码器,使用户可以对其录制文件的质量、文件大小和兼容性拥有广泛的控制。