菜单

输出

相关源文件

输出是 OBS Studio 的核心组件,负责接收编码后的媒体数据并将其传输到流媒体服务、文件或其他目标。本文档介绍了输出系统的架构、输出类型以及它们如何与其他 OBS 部分进行交互。

有关在数据到达输出之前对其进行压缩的编码器的信息,请参阅 编码器

输出系统架构

OBS Studio 中的输出是媒体管道的最后阶段,接收来自编码器的编码数据包并将其传输到目的地。输出系统设计为可扩展的,允许各种输出类型,同时保持一致的接口。

来源

基本输出接口

所有输出类型均派生自 libobs 提供的基本输出接口。该接口定义了输出必须实现的通用功能和回调。

来源

媒体管道与数据流

输出系统代表 OBS 媒体管道的最后阶段。来自视频和音频编码器的数据包被发送到适当的输出,然后输出对其进行处理并传输到最终目的地。

来源

输出数据结构

当编码器生成数据时,它会被打包成 encoder_packet 结构,然后传递给输出。

encoder_packet {
    uint8_t *data                 // Compressed data
    size_t size                   // Size of data
    int64_t pts                   // Presentation timestamp
    int64_t dts                   // Decode timestamp
    int32_t timebase_num          // Timebase numerator
    int32_t timebase_den          // Timebase denominator
    enum obs_encoder_type type    // OBS_ENCODER_VIDEO or OBS_ENCODER_AUDIO
    bool keyframe                 // Whether this is a keyframe
    int track_idx                 // Audio track index (for multi-track)
}

来源

输出类型

OBS Studio 包含几种用于不同用例的输出类型。

RTMP 流式输出

RTMP 流式输出使用实时消息协议将编码媒体发送到 RTMP 服务器(如 Twitch、YouTube 等)。

来源

RTMP 输出

  1. 连接到 RTMP 服务器
  2. 发送编码的视频/音频数据包
  3. 处理网络问题和重新连接
  4. 可根据网络状况动态调整比特率

FFmpeg 文件输出

FFmpeg 文件输出使用 libavformat 将编码媒体记录到文件中。

来源

FFmpeg 输出

  1. 创建所需格式的 AVFormatContext
  2. 设置视频和音频流
  3. 接收来自编码器的编码数据包
  4. 使用 libavformat 将它们写入输出文件

FFmpeg 复用器输出

FFmpeg 复用器输出使用单独的进程来处理复用,这提供了更大的灵活性和稳定性。

来源

FFmpeg 复用器

  1. 启动单独的 FFmpeg 复用器进程
  2. 通过管道将编码数据包发送到复用器进程
  3. 复用器进程处理实际的文件写入或流式传输
  4. 支持 MP4、MKV 和 HLS 等多种格式

MPEGTS 输出

MPEGTS 输出专为使用 MPEG Transport Stream 格式的低延迟流式传输而设计。

来源

MPEGTS 输出

  1. 创建 MPEGTS 格式的流
  2. 支持多种网络协议(UDP、SRT、RIST)
  3. 针对低延迟应用进行了优化
  4. 适用于局域网流式传输或类似 IPTV 的应用

HLS 输出

HTTP Live Streaming (HLS) 输出创建分段文件,适合通过 HTTP 进行流式传输。

来源

HLS 输出

  1. 创建分段 TS 文件
  2. 生成 M3U8 播放列表文件
  3. 针对 HTTP 传输进行了优化
  4. 支持自适应流

实现细节

RTMP 流式实现

RTMP 流式输出实现在 rtmp-stream.c 中,并使用 librtmp 处理实际的 RTMP 协议。主要组件包括:

  1. 连接管理:处理与 RTMP 服务器的连接、身份验证以及失败时的重新连接
  2. 数据包队列:维护要发送的数据包队列
  3. 发送线程:将数据包发送到服务器的后台线程
  4. 动态比特率调整:可根据网络状况调整编码器比特率
  5. 帧丢弃:在带宽不足时丢弃帧的逻辑
struct rtmp_stream {
    obs_output_t *output;            // The output instance
    RTMP rtmp;                       // RTMP connection instance
    pthread_t send_thread;           // Thread for sending packets
    struct deque packets;            // Queue of packets to send
    bool active;                     // Whether the stream is active
    int64_t drop_threshold_usec;     // When to start dropping frames
    long dbr_est_bitrate;            // Estimated bitrate for dynamic adjustment
    // ... other fields
}

来源

FFmpeg 文件输出实现

FFmpeg 文件输出实现在 obs-ffmpeg-output.c 中,使用 libavformat 进行文件写入。主要组件包括:

  1. AVFormatContext:管理输出格式和文件
  2. AVStream:表示输出中的音频和视频流
  3. AVCodecContext:包含编解码器信息
  4. 写入线程:在后台线程中将数据包写入文件
struct ffmpeg_data {
    AVFormatContext *output;         // Output format context
    AVStream *video;                 // Video stream
    struct ffmpeg_audio_info *audio_infos;  // Audio streams
    AVFrame *vframe;                 // Video frame for conversion
    uint64_t start_timestamp;        // Starting timestamp
    // ... other fields
}

struct ffmpeg_output {
    obs_output_t *output;            // The output instance
    struct ffmpeg_data ff_data;      // FFmpeg-related data
    pthread_t write_thread;          // Thread for writing data
    bool active;                     // Whether the output is active
    // ... other fields
}

来源

FFmpeg 复用器实现

FFmpeg 复用器使用一个单独的进程进行复用,该进程实现在 obs-ffmpeg-mux.cffmpeg-mux.c 中。主要组件包括:

  1. 进程管道:OBS 和复用器进程之间的通信通道
  2. 命令行参数:生成用于配置复用器的参数
  3. 数据包转发:将 OBS 中的数据包发送到复用器进程
struct ffmpeg_muxer {
    obs_output_t *output;            // The output instance
    os_process_pipe_t *pipe;         // Pipe to the muxer process
    struct dstr path;                // Output file path
    bool active;                     // Whether the muxer is active
    // ... other fields
}

来源

高级特性

动态比特率调整

RTMP 流输出可以根据网络状况动态调整视频比特率

来源

系统:

  1. 监视发送时间和缓冲区满度
  2. 计算估计比特率
  3. 如果网络跟不上,则降低比特率
  4. 在条件改善时逐渐提高比特率

帧丢弃逻辑

当网络状况恶化时,输出可以策略性地丢弃帧以维持流的稳定性

来源

帧丢弃逻辑

  1. 始终保留关键帧
  2. 在拥塞严重时丢弃 P 帧
  3. 根据上次成功发送后的时间调整拥塞阈值

与 OBS UI 集成

输出通过设置对话框暴露给 OBS UI,用户可以在其中配置流服务、录制路径和其他与输出相关的设置。

来源

输出注册表

OBS 中的输出通过 OBS 模块系统进行注册

来源

每个输出注册:

  1. 创建/销毁回调
  2. 启动/停止方法
  3. 名称和属性
  4. 指示功能的标志

错误处理和诊断

输出包含错误处理,以便在出现问题时向用户提供有意义的反馈

  1. 网络错误:RTMP 流检测并报告连接问题
  2. 磁盘空间:文件输出检查并报告磁盘空间问题
  3. 编码错误:系统检测编码器失败
  4. 权限问题:文件输出检查文件访问权限

来源

结论

OBS 输出系统提供了一个灵活的框架,用于将编码后的媒体分发到各种目标。通过将编码和分发分离,OBS 可以支持广泛的输出类型,同时保持一致的 API 和行为。

主要的输出类型(RTMP 流、文件录制和各种复用器)涵盖了最常见的用例,而插件架构允许根据需要添加额外的输出类型。