Skip to content

feat: 支持 AirPlay/RAOP ALAC 音频发送路径 #10

@ByteColtX

Description

@ByteColtX

背景

当前 Rairstream 已能从 receiver capability 中识别 ALAC,但实际发送链路仍固定为 PCM/L16。这导致即使接收端声明支持 ALAC,发送端也无法使用更低带宽的无损编码路径。

当前状态:

  • discovery / inspect 能展示 ALAC capability
  • session 初始化固定使用 CodecDescription::pcm_stereo()
  • RTSP SDP 构造当前只覆盖 PCM/L16
  • RTP audio sink 当前发送的是重采样后的 PCM payload

目标

新增可用的 ALAC 发送路径,在 receiver 支持 ALAC 时允许发送端选择 ALAC 编码,同时保留 PCM/L16 作为默认/回退路径。

非目标

  • 不移除现有 PCM/L16 路径
  • 不在本 issue 中实现 AAC/AAC-ELD
  • 不改变现有 discovery capability 解析语义
  • 不要求第一版支持所有 AirPlay 设备型号,只需有清晰回退和验证矩阵

设计方向

建议引入发送 codec 抽象,将当前 PCM packetize 路径和未来 ALAC/AAC 路径分离:

  • 新增发送 codec 枚举,例如 SendCodec::PcmL16 / SendCodec::Alac
  • session planner 根据 receiver capability、配置和默认策略选择 codec
  • CodecDescription 扩展 ALAC 的 SDP 描述能力
  • audio sink 在 resample/downmix 后进入 codec-specific encoder
  • RTP timestamp、sequence、sync packet 继续以 PCM frame timeline 为基准
  • ALAC 编码失败或 receiver 不支持时回退到 PCM/L16

实现任务

  • 为发送 codec 增加模型层表示和选择策略
  • 扩展 CodecDescription,支持 ALAC 的 rtpmap / fmtp
  • 调整 RTSP ANNOUNCE SDP 构造,按 codec 输出正确 SDP
  • 引入 ALAC encoder backend
  • AudioResampler 输出的 PCM frame 接入 ALAC encoder
  • 调整 RaopAudioSink,支持 codec-specific payload 生成
  • 保持 RTP sequence/timestamp/sync 行为兼容现有路径
  • 增加配置项或 CLI 参数,用于指定 codec 策略,例如 auto / pcm / alac
  • 增加单元测试覆盖 codec 选择、SDP 输出、payload packetize
  • 增加真实 receiver 验证记录

验收标准

  • 当 receiver capability 包含 ALAC 且策略允许时,发送端使用 ALAC
  • 当 receiver 不支持 ALAC 时,自动使用 PCM/L16
  • 用户可强制使用 PCM/L16
  • inspect / debug log 能显示最终选择的发送 codec
  • 现有 PCM/L16 测试和真实设备发送行为不回退
  • ALAC 路径在至少一个真实 AirPlay receiver 上完成播放验证

风险点

  • 不同 AirPlay receiver 对 ALAC SDP/fmtp 的兼容性可能不同
  • ALAC packet framing 需要和 RAOP 接收端预期完全一致
  • encoder 依赖选择会影响 Windows 分发方式
  • 需要避免把 codec 算法延迟误计入 RTP timestamp timeline

参考位置

  • src/audio/raop.rs
  • src/session/planner.rs
  • src/session/raop.rs
  • src/transport/sink.rs
  • src/rtsp/protocol.rs
  • src/discovery/parser.rs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions