强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

RTMP 协议精讲 / 08 - 音频编解码

音频编解码(Audio Codecs)

8.1 RTMP 音频架构

RTMP 中的音频数据以 FLV Audio Tag 格式封装,通过 Type 8 消息传输。音频在直播中的重要性不亚于视频——观众对音频卡顿的容忍度远低于视频。

音频数据在 RTMP 中的位置:

RTMP Connection
├── Message Type 8 (Audio)
│   ┌────────────────────────────────────────────┐
│   │  FLV Audio Tag Body                        │
│   │  ┌──────────┬──────────┬─────────────────┐│
│   │  │ Audio    │ AAC      │  Audio Data     ││
│   │  │ Header   │ Packet   │  (Raw/ADTS)     ││
│   │  │ (1 byte) │ Type     │                 ││
│   │  │          │ (1 byte) │                 ││
│   │  └──────────┴──────────┴─────────────────┘│
│   └────────────────────────────────────────────┘
│
└── Message Type 9 (Video) ...

8.2 FLV Audio Tag 结构

音频头(第一个字节)

 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
│Sound  │Sound  │
│Format │Rate   │
│(4b)   │(2b)   │
+-+-+-+-+-+-+-+-+
│Sound  │Sound  │
│Size   │Type   │
│(1b)   │(1b)   │
+-+-+-+-+-+-+-+-+

字段详解:
┌──────────────┬────────┬──────────────────────────────────────┐
│  字段        │  位数  │  取值                                 │
├──────────────┼────────┼──────────────────────────────────────┤
│ Sound Format │ 4 bits │ 音频编码格式                          │
│              │        │ 0=PCM/PCM_LE                         │
│              │        │ 1=ADPCM                              │
│              │        │ 2=MP3                                │
│              │        │ 3=PCM_LE (Little Endian)             │
│              │        │ 4=Nellymoser 16kHz Mono              │
│              │        │ 5=Nellymoser 8kHz Mono               │
│              │        │ 6=Nellymoser                         │
│              │        │ 7=G.711 A-law                        │
│              │        │ 8=G.711 mu-law                       │
│              │        │ 9=reserved                           │
│              │        │ 10=AAC                               │
│              │        │ 11=Speex                             │
│              │        │ 14=MP3 8kHz                          │
│              │        │ 15=Device-specific                   │
├──────────────┼────────┼──────────────────────────────────────┤
│ Sound Rate   │ 2 bits │ 采样率索引                            │
│              │        │ 0=5.5kHz (仅 Nellymoser/Speex)       │
│              │        │ 1=11kHz (22.05kHz for MP3/AAC)       │
│              │        │ 2=22kHz (44.1kHz for MP3/AAC)        │
│              │        │ 3=44kHz                              │
├──────────────┼────────┼──────────────────────────────────────┤
│ Sound Size   │ 1 bit  │ 采样位深                              │
│              │        │ 0=8-bit                              │
│              │        │ 1=16-bit                             │
├──────────────┼────────┼──────────────────────────────────────┤
│ Sound Type   │ 1 bit  │ 声道数                                │
│              │        │ 0=mono (单声道)                       │
│              │        │ 1=stereo (立体声)                     │
└──────────────┴────────┴──────────────────────────────────────┘

常见音频头值

十六进制 Sound Format Rate Size Type 典型配置
0xAF AAC (10) 3 (44kHz) 1 (16bit) 1 (stereo) AAC 44.1kHz 立体声
0x2F MP3 (2) 3 (44kHz) 1 (16bit) 1 (stereo) MP3 44.1kHz 立体声
0xAE AAC (10) 3 (44kHz) 1 (16bit) 0 (mono) AAC 44.1kHz 单声道

8.3 AAC 编码详解

AAC(Advanced Audio Coding)是 RTMP 直播中最常用的音频编码格式。

8.3.1 AAC Audio Tag 结构

当 Sound Format = 10 (AAC) 时:

AAC Audio Tag Body:
┌────────────────┬─────────────────┬──────────────────────────┐
│ Audio Header   │ AAC Packet Type │      AAC Data             │
│ (1 byte)       │ (1 byte)        │                           │
│ 0xAF           │                 │                           │
│                │ 0=Sequence Header│  AudioSpecificConfig      │
│                │ 1=AAC Raw       │  AAC 压缩数据              │
└────────────────┴─────────────────┴──────────────────────────┘

8.3.2 AAC Sequence Header (AudioSpecificConfig)

AAC Sequence Header 是 AudioSpecificConfig 数据,用于初始化 AAC 解码器:

AudioSpecificConfig (ISO 14496-3):

 5 bits       4 bits      4 bits       variable
┌──────────┬───────────┬───────────┬──────────────────┐
│ audio    │ sampling  │ channel   │  GASpecificConfig│
│ object   │ freq      │ config    │  (可选)          │
│ type     │ index     │           │                  │
└──────────┴───────────┴───────────┴──────────────────┘

Audio Object Type:
┌──────┬──────────────────────────────────────────────┐
│  值  │  类型                                        │
├──────┼──────────────────────────────────────────────┤
│  1   │  AAC Main                                    │
│  2   │  AAC LC (Low Complexity) — 最常用            │
│  3   │  AAC SSR (Scalable Sample Rate)              │
│  4   │  AAC LTP (Long Term Prediction)              │
│  5   │  SBR (Spectral Band Replication)             │
│  6   │  AAC Scalable                                │
│  7   │  TwinVQ                                      │
│  8   │  CELP                                        │
│  39   │  ER AAC LD                                   │
└──────┴──────────────────────────────────────────────┘

Sampling Frequency Index:
┌──────┬──────────────────────┐
│  值  │  采样率 (Hz)         │
├──────┼──────────────────────┤
│  0   │  96000               │
│  1   │  88200               │
│  2   │  64000               │
│  3   │  48000               │
│  4   │  44100  ← 最常用     │
│  5   │  32000               │
│  6   │  24000               │
│  7   │  22050               │
│  8   │  16000               │
│  9   │  12000               │
│  10  │  11025               │
│  11  │  8000                │
│  12  │  7350                │
└──────┴──────────────────────┘

Channel Configuration:
┌──────┬──────────────────────┐
│  值  │  声道配置             │
├──────┼──────────────────────┤
│  0   │  特定配置 (在 ASC 中) │
│  1   │  中心 (单声道)        │
│  2   │  左+右 (立体声)       │
│  3   │  中心+左+右           │
│  4   │  中心+左+右+后环绕    │
│  5   │  中心+左+右+后左+后右 │
│  6   │  5.1 (6 声道)         │
│  7   │  7.1 (7.1 声道)       │
└──────┴──────────────────────┘

8.3.3 AudioSpecificConfig 解析实现

#!/usr/bin/env python3
"""
AudioSpecificConfig 解析器
用于解析 AAC Sequence Header
"""

import struct
from dataclasses import dataclass


@dataclass
class AudioSpecificConfig:
    """AAC AudioSpecificConfig"""
    audio_object_type: int      # 音频对象类型
    sampling_frequency_index: int  # 采样率索引
    sampling_frequency: int     # 实际采样率 (Hz)
    channel_configuration: int  # 声道配置
    frame_length_flag: int = 0  # 帧长度标志
    depends_on_core_coder: int = 0
    extension_flag: int = 0

    # AAC-LC 特有
    sbr_present_flag: int = 0
    ps_present_flag: int = 0


# 采样率映射表
SAMPLING_FREQ_TABLE = {
    0: 96000, 1: 88200, 2: 64000, 3: 48000,
    4: 44100, 5: 32000, 6: 24000, 7: 22050,
    8: 16000, 9: 12000, 10: 11025, 11: 8000,
    12: 7350
}

# 音频对象类型名称
AUDIO_OBJECT_TYPE_NAMES = {
    0: "Null", 1: "AAC Main", 2: "AAC-LC", 3: "AAC-SSR",
    4: "AAC-LTP", 5: "SBR", 6: "AAC Scalable",
    7: "TwinVQ", 8: "CELP", 9: "HVXC",
    12: "TTSI", 13: "Main Synthesis", 14: "Wavetable Synthesis",
    39: "ER AAC LD", 42: "ER AAC ELD"
}

# 声道配置名称
CHANNEL_CONFIG_NAMES = {
    0: "Defined in AOT", 1: "Center (Mono)", 2: "L+R (Stereo)",
    3: "Center+L+R", 4: "Center+L+R+Rear", 5: "5 Surround",
    6: "5.1 Surround", 7: "7.1 Surround"
}


def parse_audio_specific_config(data: bytes) -> AudioSpecificConfig:
    """
    解析 AudioSpecificConfig
    
    参数:
        data: AAC Sequence Header 的数据部分(不含 Audio Header 和 AAC Packet Type)
    
    返回:
        AudioSpecificConfig 对象
    """
    if len(data) < 2:
        raise ValueError("AudioSpecificConfig 至少需要 2 字节")

    # 位读取器
    bits = BitReader(data)

    # Audio Object Type (5 bits)
    audio_object_type = bits.read_bits(5)
    if audio_object_type == 31:
        # 扩展类型:再读 6 位 + 32
        audio_object_type = 32 + bits.read_bits(6)

    # Sampling Frequency Index (4 bits)
    sampling_freq_index = bits.read_bits(4)
    if sampling_freq_index == 15:
        # 自定义采样率:读 24 位
        sampling_freq = bits.read_bits(24)
    else:
        sampling_freq = SAMPLING_FREQ_TABLE.get(sampling_freq_index, 0)

    # Channel Configuration (4 bits)
    channel_config = bits.read_bits(4)

    config = AudioSpecificConfig(
        audio_object_type=audio_object_type,
        sampling_frequency_index=sampling_freq_index,
        sampling_frequency=sampling_freq,
        channel_configuration=channel_config,
    )

    # GASpecificConfig (如果 AOT 是 1-7 等)
    if audio_object_type in (1, 2, 3, 4, 6, 7):
        config.frame_length_flag = bits.read_bits(1)
        config.depends_on_core_coder = bits.read_bits(1)
        config.extension_flag = bits.read_bits(1)

    return config


def parse_aac_sequence_header(body: bytes) -> AudioSpecificConfig:
    """
    解析 AAC Sequence Header(完整的 Audio Tag Body)
    
    参数:
        body: Audio Tag Body(包含 1 byte Audio Header + 1 byte AAC Packet Type + ASC)
    """
    if len(body) < 4:
        raise ValueError("AAC Sequence Header 至少需要 4 字节")

    audio_header = body[0]  # 0xAF
    aac_packet_type = body[1]  # 0 = Sequence Header

    if aac_packet_type != 0:
        raise ValueError(f"不是 AAC Sequence Header,type={aac_packet_type}")

    asc_data = body[2:]
    return parse_audio_specific_config(asc_data)


class BitReader:
    """位读取器"""

    def __init__(self, data: bytes):
        self.data = data
        self.byte_pos = 0
        self.bit_pos = 0

    def read_bits(self, n: int) -> int:
        """读取 n 位"""
        result = 0
        for _ in range(n):
            if self.byte_pos >= len(self.data):
                break
            bit = (self.data[self.byte_pos] >> (7 - self.bit_pos)) & 1
            result = (result << 1) | bit
            self.bit_pos += 1
            if self.bit_pos >= 8:
                self.bit_pos = 0
                self.byte_pos += 1
        return result


def create_audio_specific_config(
    object_type: int = 2,
    sample_rate: int = 44100,
    channels: int = 2
) -> bytes:
    """
    创建 AudioSpecificConfig
    
    参数:
        object_type: 音频对象类型 (2=AAC-LC)
        sample_rate: 采样率
        channels: 声道数
    """
    # 查找采样率索引
    freq_index = None
    for idx, freq in SAMPLING_FREQ_TABLE.items():
        if freq == sample_rate:
            freq_index = idx
            break
    if freq_index is None:
        raise ValueError(f"不支持的采样率: {sample_rate}")

    # 编码 AudioSpecificConfig
    bits = 0
    bits |= (object_type & 0x1F) << (32 - 5)
    bits |= (freq_index & 0x0F) << (32 - 5 - 4)
    bits |= (channels & 0x0F) << (32 - 5 - 4 - 4)

    result = bits.to_bytes(2, 'big')
    return result


# 测试
def test_audio_specific_config():
    """测试 AudioSpecificConfig 解析"""
    # AAC-LC, 44100Hz, Stereo
    # Object Type=2, Freq Index=4, Channel=2
    # Binary: 00010 0100 0010 0000
    #         00010010 00010000 = 0x12 0x10
    data = bytes([0x12, 0x10])

    config = parse_audio_specific_config(data)
    print(f"Audio Object Type: {config.audio_object_type} ({AUDIO_OBJECT_TYPE_NAMES.get(config.audio_object_type, 'Unknown')})")
    print(f"Sampling Frequency: {config.sampling_frequency} Hz (index={config.sampling_frequency_index})")
    print(f"Channel Configuration: {config.channel_configuration} ({CHANNEL_CONFIG_NAMES.get(config.channel_configuration, 'Unknown')})")

    # 验证
    assert config.audio_object_type == 2  # AAC-LC
    assert config.sampling_frequency == 44100
    assert config.channel_configuration == 2  # Stereo

    # 编码验证
    encoded = create_audio_specific_config(2, 44100, 2)
    assert encoded == data

    print("✅ AudioSpecificConfig 测试通过")


if __name__ == '__main__':
    test_audio_specific_config()

8.4 AAC Raw Data

当 AAC Packet Type = 1 时,Body 中包含的是 AAC 压缩音频帧

AAC Raw Frame:
┌─────────────────────────────────────────────────────┐
│  AAC Frame (variable length)                         │
│  通常是 ADTS 或 RAW AAC 数据                         │
└─────────────────────────────────────────────────────┘

注意:
- RTMP 中的 AAC Raw 不含 ADTS 头
- 直接是 AAC 编码器输出的原始数据
- 需要配合之前收到的 AudioSpecificConfig 解码

8.5 ADTS 格式

ADTS(Audio Data Transport Stream)是 AAC 数据的传输格式,常用于 HLS/文件存储:

ADTS Header (7/9 bytes):
┌──────────────────────────────────────────────────────────────┐
│  syncword (12 bits)         = 0xFFF                           │
│  ID (1 bit)                 = 0 (MPEG-4)                     │
│  layer (2 bits)             = 00                              │
│  protection_absent (1 bit)  = 1 (无 CRC)                     │
│  profile (2 bits)           = AAC-LC 对应的 profile           │
│  sampling_freq_index (4 bits)                                │
│  private_bit (1 bit)                                         │
│  channel_config (3 bits)                                     │
│  original_copy (1 bit)                                       │
│  home (1 bit)                                                │
│  copyright_id (1 bit)                                        │
│  copyright_start (1 bit)                                     │
│  frame_length (13 bits)     = ADTS header + AAC data          │
│  buffer_fullness (11 bits)  = 0x7FF (VBR)                    │
│  num_frames_minus_1 (2 bits) = 0 (1 frame per ADTS)          │
│  CRC (16 bits, 可选)                                         │
└──────────────────────────────────────────────────────────────┘
def create_adts_header(
    object_type: int,
    sample_rate: int,
    channels: int,
    data_length: int
) -> bytes:
    """
    创建 ADTS Header
    
    参数:
        object_type: AAC Profile (0=Main, 1=LC, 2=SSR)
        sample_rate: 采样率
        channels: 声道数
        data_length: AAC 原始数据长度
    """
    # 采样率索引
    freq_table = {
        96000: 0, 88200: 1, 64000: 2, 48000: 3,
        44100: 4, 32000: 5, 24000: 6, 22050: 7,
        16000: 8, 12000: 9, 11025: 10, 8000: 11,
        7350: 12
    }
    freq_index = freq_table.get(sample_rate, 4)
    profile = object_type - 1  # AAC-LC=2, profile=1
    frame_length = 7 + data_length  # 7 bytes ADTS header + data

    adts = bytearray(7)
    adts[0] = 0xFF                        # syncword high
    adts[1] = 0xF0                        # syncword low + ID=0 + layer=00 + protection=1
    adts[1] |= (profile & 0x03) << 2     # profile
    adts[1] |= (freq_index >> 2) & 0x01  # sampling_freq_index bit 3
    adts[2] = (freq_index & 0x03) << 6   # sampling_freq_index bits 2-1
    adts[2] |= (channels & 0x07) << 2    # channel_config
    adts[3] = 0                           # 其他标志
    adts[4] = (frame_length >> 5) & 0xFF # frame_length 高 8 位
    adts[5] = (frame_length & 0x1F) << 3 # frame_length 低 5 位
    adts[6] = 0xFC                        # buffer_fullness + num_frames

    return bytes(adts)


def add_adts_to_aac_raw(aac_raw: bytes, object_type: int = 2,
                         sample_rate: int = 44100, channels: int = 2) -> bytes:
    """为 AAC Raw 数据添加 ADTS 头"""
    adts = create_adts_header(object_type, sample_rate, channels, len(aac_raw))
    return adts + aac_raw

8.6 MP3 编码

虽然 AAC 是主流,但 RTMP 也支持 MP3 编码(Sound Format = 2):

MP3 Audio Tag

MP3 Audio Tag Body:
┌────────────────┬──────────────────────────────┐
│ Audio Header   │      MP3 Frame Data          │
│ (1 byte)       │  (含 MP3 Header + Data)      │
│ 0x2F (典型)    │                               │
└────────────────┴──────────────────────────────┘

MP3 Frame Header (4 bytes):
┌──────────────────────────────────────────────────┐
│  syncword (11 bits)       = 0x7FF                 │
│  version (2 bits)         = 11 (MPEG1)            │
│  layer (2 bits)           = 01 (Layer III)        │
│  protection (1 bit)                                │
│  bitrate_index (4 bits)   = 码率索引               │
│  sampling_rate (2 bits)   = 采样率索引             │
│  padding (1 bit)                                   │
│  channel_mode (2 bits)    = 声道模式               │
│  ... 其他标志位                                     │
└──────────────────────────────────────────────────┘

8.7 音频配置参数

推流音频参数

参数 推荐值 说明
编码格式 AAC-LC 最广泛兼容
采样率 44100Hz CD 质量
声道 立体声 (2ch) 或单声道 (1ch)
采样位深 16-bit 标准位深
码率 128-192kbps 音乐/语音场景
AAC Profile LC Low Complexity

FFmpeg 音频编码命令

# AAC 编码(推荐)
ffmpeg -i input.mp4 -c:a aac -b:a 128k -ar 44100 -ac 2 -f flv rtmp://...

# AAC HE v1(低码率优化)
ffmpeg -i input.mp4 -c:a libfdk_aac -profile:a aac_he -b:a 64k -f flv rtmp://...

# AAC HE v2(更低码率)
ffmpeg -i input.mp4 -c:a libfdk_aac -profile:a aac_he_v2 -b:a 32k -f flv rtmp://...

# MP3 编码
ffmpeg -i input.mp4 -c:a libmp3lame -b:a 128k -ar 44100 -f flv rtmp://...

# Opus 编码(Enhanced RTMP,需服务端支持)
ffmpeg -i input.mp4 -c:a libopus -b:a 64k -f flv rtmp://...

AAC Profile 对比

Profile 说明 适用场景 码率范围
AAC-LC Low Complexity 通用 64-256kbps
HE-AAC v1 LC + SBR 低码率 32-64kbps
HE-AAC v2 LC + SBR + PS 超低码率 16-32kbps
AAC-LD Low Delay 实时通信 64-128kbps
AAC-ELD Enhanced LD 超低延迟 32-64kbps

8.8 音频与视频同步

音视频同步是直播系统中的核心挑战:

RTMP 时间戳同步

时间戳(毫秒)    视频帧              音频帧
  0               Video Keyframe     Audio Frame
  33              Video Inter        Audio Frame
  66              Video Inter        Audio Frame
  99              Video Inter        Audio Frame
  100                                  Audio Frame
  133              Video Inter
  ...

同步原则:
- 视频和音频使用同一个时间基(毫秒)
- 播放器根据时间戳对齐音视频
- 时间戳单调递增
- 音频时间戳通常更均匀(固定间隔)

音视频同步实现

class AVMuxer:
    """音视频复用器 — 同步音频和视频"""

    def __init__(self):
        self.video_timestamp = 0  # ms
        self.audio_timestamp = 0  # ms
        self.audio_frame_duration = 23  # ms (44100Hz, 1024 samples/frame)
        self.video_frame_duration = 33  # ms (30fps)

    def get_next_video_timestamp(self) -> int:
        ts = self.video_timestamp
        self.video_timestamp += self.video_frame_duration
        return ts

    def get_next_audio_timestamp(self) -> int:
        ts = self.audio_timestamp
        self.audio_timestamp += self.audio_frame_duration
        return ts

8.9 音频解码器完整实现

#!/usr/bin/env python3
"""
RTMP Audio Decoder
完整的音频消息解析器
"""

import struct
from dataclasses import dataclass


@dataclass
class AudioFrame:
    """音频帧信息"""
    codec: str
    codec_id: int
    sample_rate: int
    sample_size: int
    channels: int
    is_stereo: bool
    data: bytes
    timestamp: int = 0
    # AAC 特有
    aac_packet_type: int = -1
    aac_sequence_header: object = None


SOUND_FORMAT_NAMES = {
    0: 'PCM', 1: 'ADPCM', 2: 'MP3',
    3: 'PCM_LE', 4: 'Nellymoser 16kHz', 5: 'Nellymoser 8kHz',
    6: 'Nellymoser', 7: 'G.711 A-law', 8: 'G.711 mu-law',
    10: 'AAC', 11: 'Speex', 14: 'MP3 8kHz', 15: 'Device'
}

SAMPLE_RATE_MAP = {
    0: 5512, 1: 11025, 2: 22050, 3: 44100
}


def decode_audio_message(body: bytes, timestamp: int = 0) -> AudioFrame:
    """
    解析 Audio Message Body
    
    参数:
        body: Type 8 消息的 Body
        timestamp: 消息时间戳
    
    返回:
        AudioFrame 对象
    """
    if len(body) < 1:
        raise ValueError("Audio message body too short")

    header = body[0]
    sound_format = (header >> 4) & 0x0F
    sound_rate = (header >> 2) & 0x03
    sound_size = (header >> 1) & 0x01
    sound_type = header & 0x01

    codec_name = SOUND_FORMAT_NAMES.get(sound_format, f'Unknown({sound_format})')
    sample_rate = SAMPLE_RATE_MAP.get(sound_rate, 44100)
    sample_size = 8 if sound_size == 0 else 16
    channels = 1 if sound_type == 0 else 2

    frame = AudioFrame(
        codec=codec_name,
        codec_id=sound_format,
        sample_rate=sample_rate,
        sample_size=sample_size,
        channels=channels,
        is_stereo=(sound_type == 1),
        data=body[1:],
        timestamp=timestamp,
    )

    # AAC 特殊处理
    if sound_format == 10 and len(body) >= 2:
        frame.aac_packet_type = body[1]
        if body[1] == 0:
            # AAC Sequence Header
            try:
                config = parse_audio_specific_config(body[2:])
                frame.aac_sequence_header = config
                frame.sample_rate = config.sampling_frequency
                frame.channels = config.channel_configuration
            except Exception:
                pass
        frame.data = body[2:]

    return frame


# 测试
def test_audio_decoder():
    """测试音频解码"""
    # AAC Sequence Header: 0xAF 0x00 0x12 0x10
    body = bytes([0xAF, 0x00, 0x12, 0x10])
    frame = decode_audio_message(body, timestamp=1000)

    print(f"Codec: {frame.codec}")
    print(f"Sample Rate: {frame.sample_rate} Hz")
    print(f"Channels: {frame.channels}")
    print(f"Is Stereo: {frame.is_stereo}")
    print(f"AAC Packet Type: {'Sequence Header' if frame.aac_packet_type == 0 else 'Raw'}")

    assert frame.codec == 'AAC'
    assert frame.sample_rate == 44100
    assert frame.channels == 2
    print("✅ Audio decoder 测试通过")


if __name__ == '__main__':
    test_audio_decoder()

注意事项

  1. Sequence Header 优先:AAC Sequence Header 必须在任何 AAC Raw 数据之前发送
  2. 采样率映射:Sound Rate 字段对于 AAC/MP3 使用不同的映射(22kHz/44kHz vs 5.5kHz/11kHz)
  3. ADTS 头:RTMP 中的 AAC Raw 不含 ADTS 头,转封装为 HLS/MP4 时需要添加
  4. 音频帧时长:AAC-LC 每帧通常 1024 个采样,44100Hz 下约 23ms
  5. 单声道 vs 立体声:低码率场景建议使用单声道(减半码率),语音场景尤为推荐
  6. G.711 通话场景:WebRTC 关联的 RTMP 流可能使用 G.711 编码,采样率为 8kHz

扩展阅读


上一章07 - 视频编解码 下一章09 - 流媒体服务器 — 了解主流 RTMP 服务器与部署