Files
Alicho/docs/api/frontend.md
2025-10-28 10:27:49 +08:00

63 KiB
Raw Blame History

前端接口API参考

目录

概述

前端接口模块提供了应用程序与音频后端引擎通信的统一接口,支持本地和网络通信。前端接口封装了设备管理、网络发现、音频传输和编解码等复杂功能,使应用程序能够简单地集成高级音频处理能力。

核心特性:

  • 本地通信: 与同一设备上运行的音频引擎通信
  • 网络通信: 与远程音频引擎进行低延迟通信
  • 自动发现: 通过mDNS/Bonjour自动发现网络上的音频服务
  • 设备管理: 枚举、配置和监控音频设备变化
  • 编解码处理: 支持多种音频编解码器,包括无损和有损压缩
  • 低延迟传输: 针对实时音频优化的网络传输
  • 安全连接: 支持加密的音频流和控制通道

前端接口的架构示意图:

┌─────────────────────────────────┐      ┌─────────────────────────────────┐
│      应用程序                   │      │       音频引擎进程               │
│                                 │      │                                 │
│  ┌─────────────────────────┐    │      │  ┌─────────────────────────┐    │
│  │   前端管理器            │    │      │  │  音频引擎                │    │
│  │  FrontendManager        │    │      │  │                         │    │
│  └───────────┬─────────────┘    │      │  └───────────┬─────────────┘    │
│              │                  │      │              │                  │
│              ▼                  │      │              ▼                  │
│  ┌───────────────────────────┐  │      │  ┌───────────────────────────┐  │
│  │   引擎代理                │  │      │  │  通信管理器               │  │
│  │  EngineProxy             │  │      │  │  CommunicationManager     │  │
│  └───────────┬───────────────┘  │      │  └───────────┬───────────────┘  │
│              │                  │      │              │                  │
│              │                  │      │              │                  │
│  ┌───────────▼───────────────┐  │      │  ┌───────────▼───────────────┐  │
│  │ 通信管理器                │  │      │  │ ZeroMQ通信                │  │
│  │ (ZeroMQ/共享内存)        ├──┼──────┼─►│ (控制通道)                │  │
│  └───────────────────────────┘  │      │  └───────────────────────────┘  │
│                                 │      │                                 │
│  ┌───────────────────────────┐  │      │  ┌───────────────────────────┐  │
│  │ 设备管理器                │  │      │  │ 共享内存                  │  │
│  │ DeviceManager            ├──┼──────┼─►│ (数据通道)                │  │
│  └───────────────────────────┘  │      │  └───────────────────────────┘  │
│                                 │      │                                 │
│  ┌───────────────────────────┐  │      │                                 │
│  │ 网络传输                  │  │      │                                 │
│  │ NetworkTransport          │  │      │                                 │
│  └───────────────────────────┘  │      │                                 │
└─────────────────────────────────┘      └─────────────────────────────────┘
                │
                │                      ┌─────────────────────────────────┐
                │                      │      远程音频引擎               │
                │                      │                                 │
                │                      │  ┌─────────────────────────┐    │
                │                      │  │  网络服务器             │    │
                └──────────────────────┼─►│  NetworkServer          │    │
                                       │  └─────────────────────────┘    │
                                       │                                 │
                                       └─────────────────────────────────┘

前端管理器

FrontendManager

FrontendManager是前端接口的核心类,负责协调所有前端组件,管理与音频引擎的通信,以及处理音频设备和网络服务。

class FrontendManager {
public:
    explicit FrontendManager(const FrontendConfig& config);
    ~FrontendManager();
    
    // 生命周期管理
    common::ErrorCode initialize();
    common::ErrorCode shutdown();
    bool is_initialized() const;
    bool is_engine_connected() const;
    
    // 事件监听
    void add_event_listener(std::shared_ptr<IFrontendEventListener> listener);
    void remove_event_listener(std::shared_ptr<IFrontendEventListener> listener);
    
    // 音频引擎连接
    common::ErrorCode connect_to_engine(const std::string& endpoint = "");
    common::ErrorCode disconnect_from_engine();
    
    // 音频设备管理
    std::vector<AudioDeviceInfo> get_audio_devices() const;
    common::ErrorCode set_input_device(const std::string& device_id);
    common::ErrorCode set_output_device(const std::string& device_id);
    common::ErrorCode start_audio_stream();
    common::ErrorCode stop_audio_stream();
    
    // 网络服务管理
    common::ErrorCode start_network_discovery();
    common::ErrorCode stop_network_discovery();
    std::vector<NetworkServiceInfo> get_discovered_services() const;
    common::ErrorCode connect_to_network_service(const std::string& service_id);
    common::ErrorCode disconnect_from_network_service(const std::string& service_id);
    
    // 音频流控制
    common::ErrorCode start_network_audio_stream(const std::string& target_address, uint16_t port);
    common::ErrorCode stop_network_audio_stream();
    
    // 配置管理
    const FrontendConfig& config() const;
    common::ErrorCode update_config(const FrontendConfig& new_config);
    
    // 统计信息
    const FrontendStatistics& get_statistics() const;
    void reset_statistics();
    void print_statistics() const;
    
    // 音频数据处理
    common::ErrorCode send_audio_data(const engine::AudioBuffer& buffer);
    common::ErrorCode send_audio_data_to_network(const engine::AudioBuffer& buffer, 
                                                const std::string& target);
    
    // 控制命令
    common::ErrorCode send_control_command(const std::string& command, 
                                         const std::string& parameters = "");
};

前端配置

FrontendConfig定义了前端接口的配置选项,包括基础设置、网络设置和性能选项:

struct FrontendConfig {
    // 基础配置
    std::string process_name = "audio_frontend";
    std::string engine_endpoint = "tcp://localhost:5555";
    
    // 音频设备配置
    bool auto_detect_devices = true;
    bool enable_device_hotplug = true;
    uint32_t device_poll_interval_ms = 1000;
    
    // 网络配置
    bool enable_network_discovery = true;
    bool enable_network_streaming = true;
    uint16_t network_discovery_port = 7777;
    uint16_t audio_stream_port = 8888;
    uint16_t control_port = 9999;
    std::string network_interface = "0.0.0.0";
    
    // 缓冲配置
    uint32_t audio_buffer_size = 512;
    uint32_t network_buffer_size = 2048;
    uint32_t max_latency_ms = 50;
    
    // 安全配置
    bool require_authentication = false;
    std::string certificate_path = "";
    std::string private_key_path = "";
    
    // 性能配置
    uint32_t worker_thread_count = 2;
    bool enable_performance_monitoring = true;
    uint32_t statistics_interval_ms = 5000;
};

配置选项说明:

配置项 描述 默认值 推荐设置
process_name 前端进程名称,用于标识 "audio_frontend" 应用名称
engine_endpoint 音频引擎连接地址 "tcp://localhost:5555" 本地部署保持默认
auto_detect_devices 是否自动检测音频设备 true 通常保持启用
enable_device_hotplug 是否监控设备热插拔 true 通常保持启用
enable_network_discovery 是否启用网络服务发现 true 需要网络功能时启用
enable_network_streaming 是否启用网络音频流 true 需要网络功能时启用
audio_buffer_size 音频缓冲区大小(帧) 512 低延迟场景: 128-256
高质量场景: 512-2048
network_buffer_size 网络缓冲区大小(字节) 2048 低延迟场景: 512-1024
高带宽场景: 4096+
max_latency_ms 最大可接受延迟(毫秒) 50 实时通信: 20-30
音乐制作: 30-50
流媒体: 100-300

生命周期管理

前端管理器的典型生命周期包括:

  1. 创建管理器:使用工厂函数创建前端管理器
  2. 初始化:调用initialize()进行初始化
  3. 连接引擎:调用connect_to_engine()连接到音频引擎
  4. 配置设备:枚举并设置音频设备
  5. 启动音频流:调用start_audio_stream()开始音频处理
  6. 处理音频数据:发送/接收音频数据
  7. 停止音频流:调用stop_audio_stream()停止音频处理
  8. 断开连接:调用disconnect_from_engine()断开引擎连接
  9. 关闭:调用shutdown()清理资源
// 示例:前端管理器基本生命周期
#include "audio_backend/frontend.h"

int main() {
    // 初始化前端系统
    audio_backend::frontend::initialize_frontend();
    
    // 创建前端管理器
    auto frontend = audio_backend::frontend::create_frontend_manager();
    
    // 初始化
    auto result = frontend->initialize();
    if (result != audio_backend::common::ErrorCode::SUCCESS) {
        std::cerr << "前端初始化失败: " << audio_backend::common::error_to_string(result) << std::endl;
        return 1;
    }
    
    // 连接到音频引擎
    result = frontend->connect_to_engine("tcp://localhost:5555");
    if (result != audio_backend::common::ErrorCode::SUCCESS) {
        std::cerr << "连接音频引擎失败" << std::endl;
        return 1;
    }
    
    // ... 应用逻辑 ...
    
    // 关闭前端管理器
    frontend->shutdown();
    
    // 清理前端系统
    audio_backend::frontend::shutdown_frontend();
    
    return 0;
}

音频设备管理

设备信息

AudioDeviceInfo结构提供了音频设备的详细信息:

struct AudioDeviceInfo {
    std::string id;                                       // 设备唯一标识符
    std::string name;                                    // 设备名称
    std::string driver_name;                             // 驱动名称
    bool is_input;                                       // 是否为输入设备
    bool is_output;                                      // 是否为输出设备
    bool is_default;                                     // 是否为默认设备
    std::vector<uint32_t> supported_sample_rates;        // 支持的采样率
    std::vector<uint16_t> supported_channel_counts;      // 支持的声道数
    std::vector<engine::AudioFormat> supported_formats;  // 支持的音频格式
    uint32_t default_buffer_size;                        // 默认缓冲区大小
    double input_latency;                               // 输入延迟(毫秒)
    double output_latency;                              // 输出延迟(毫秒)
};

枚举音频设备的示例:

void list_audio_devices(audio_backend::frontend::FrontendManager& frontend) {
    auto devices = frontend.get_audio_devices();
    
    std::cout << "发现 " << devices.size() << " 个音频设备:" << std::endl;
    std::cout << "-----------------------------------------" << std::endl;
    
    for (const auto& device : devices) {
        std::cout << (device.is_default ? "* " : "  ")
                 << device.name << " (" << device.id << ")" << std::endl;
        
        std::cout << "  类型: " 
                 << (device.is_input && device.is_output ? "输入/输出" : 
                     (device.is_input ? "输入" : "输出")) << std::endl;
        
        std::cout << "  驱动: " << device.driver_name << std::endl;
        
        std::cout << "  支持的采样率: ";
        for (auto rate : device.supported_sample_rates) {
            std::cout << rate << " ";
        }
        std::cout << std::endl;
        
        std::cout << "  支持的声道数: ";
        for (auto channels : device.supported_channel_counts) {
            std::cout << channels << " ";
        }
        std::cout << std::endl;
        
        std::cout << "  延迟: ";
        if (device.is_input) std::cout << "输入=" << device.input_latency << "ms ";
        if (device.is_output) std::cout << "输出=" << device.output_latency << "ms";
        std::cout << std::endl;
        
        std::cout << "-----------------------------------------" << std::endl;
    }
}

设备选择

前端管理器提供了设置输入和输出设备的方法:

common::ErrorCode set_input_device(const std::string& device_id);
common::ErrorCode set_output_device(const std::string& device_id);

设置音频设备的示例:

void configure_audio_devices(audio_backend::frontend::FrontendManager& frontend) {
    // 获取所有音频设备
    auto devices = frontend.get_audio_devices();
    
    // 查找默认输入和输出设备
    std::string input_device_id;
    std::string output_device_id;
    
    for (const auto& device : devices) {
        if (device.is_default) {
            if (device.is_input) {
                input_device_id = device.id;
            }
            if (device.is_output) {
                output_device_id = device.id;
            }
        }
    }
    
    // 设置输入设备
    if (!input_device_id.empty()) {
        auto result = frontend.set_input_device(input_device_id);
        if (result == audio_backend::common::ErrorCode::SUCCESS) {
            std::cout << "设置默认输入设备成功" << std::endl;
        } else {
            std::cerr << "设置默认输入设备失败" << std::endl;
        }
    }
    
    // 设置输出设备
    if (!output_device_id.empty()) {
        auto result = frontend.set_output_device(output_device_id);
        if (result == audio_backend::common::ErrorCode::SUCCESS) {
            std::cout << "设置默认输出设备成功" << std::endl;
        } else {
            std::cerr << "设置默认输出设备失败" << std::endl;
        }
    }
}

音频流控制

前端管理器提供了启动和停止音频流的方法:

common::ErrorCode start_audio_stream();
common::ErrorCode stop_audio_stream();

音频流控制示例:

void control_audio_stream(audio_backend::frontend::FrontendManager& frontend) {
    // 启动音频流
    auto result = frontend.start_audio_stream();
    if (result != audio_backend::common::ErrorCode::SUCCESS) {
        std::cerr << "启动音频流失败: " 
                 << audio_backend::common::error_to_string(result) << std::endl;
        return;
    }
    
    std::cout << "音频流已启动,按回车键停止..." << std::endl;
    std::cin.get();
    
    // 停止音频流
    result = frontend.stop_audio_stream();
    if (result != audio_backend::common::ErrorCode::SUCCESS) {
        std::cerr << "停止音频流失败: " 
                 << audio_backend::common::error_to_string(result) << std::endl;
        return;
    }
    
    std::cout << "音频流已停止" << std::endl;
}

网络通信

服务发现

前端接口支持通过mDNS/Bonjour协议自动发现网络上的音频服务

common::ErrorCode start_network_discovery();
common::ErrorCode stop_network_discovery();
std::vector<NetworkServiceInfo> get_discovered_services() const;

NetworkServiceInfo结构提供了网络服务的详细信息:

struct NetworkServiceInfo {
    std::string service_id;        // 服务唯一标识符
    std::string service_name;      // 服务名称
    std::string address;           // IP地址
    uint16_t port;                 // 端口
    std::string service_type;      // 服务类型
    std::unordered_map<std::string, std::string> properties; // 服务属性
    std::chrono::steady_clock::time_point last_seen;         // 最后发现时间
};

服务发现示例:

void discover_audio_services(audio_backend::frontend::FrontendManager& frontend) {
    // 启动网络服务发现
    auto result = frontend.start_network_discovery();
    if (result != audio_backend::common::ErrorCode::SUCCESS) {
        std::cerr << "启动网络服务发现失败" << std::endl;
        return;
    }
    
    std::cout << "搜索网络音频服务中..." << std::endl;
    
    // 等待服务发现(实际应用中可能使用事件回调)
    std::this_thread::sleep_for(std::chrono::seconds(5));
    
    // 获取已发现的服务
    auto services = frontend.get_discovered_services();
    
    if (services.empty()) {
        std::cout << "未发现音频服务" << std::endl;
    } else {
        std::cout << "发现 " << services.size() << " 个音频服务:" << std::endl;
        
        for (const auto& service : services) {
            std::cout << "- " << service.service_name 
                     << " (" << service.address << ":" << service.port << ")" << std::endl;
            
            std::cout << "  服务类型: " << service.service_type << std::endl;
            std::cout << "  服务ID: " << service.service_id << std::endl;
            
            if (!service.properties.empty()) {
                std::cout << "  服务属性:" << std::endl;
                for (const auto& [key, value] : service.properties) {
                    std::cout << "    " << key << ": " << value << std::endl;
                }
            }
        }
    }
    
    // 停止网络服务发现
    frontend.stop_network_discovery();
}

会话管理

前端接口提供会话管理功能,用于建立和维护与远程服务的连接:

common::ErrorCode connect_to_network_service(const std::string& service_id);
common::ErrorCode disconnect_from_network_service(const std::string& service_id);

此外,还可以使用专用的会话管理器来管理更复杂的会话场景:

// 创建会话管理器
auto session_manager = audio_backend::frontend::create_session_manager();

// 创建会话服务器
auto session_server = audio_backend::frontend::create_session_server(9999);

会话管理示例:

void manage_network_session(audio_backend::frontend::FrontendManager& frontend) {
    // 启动网络服务发现
    frontend.start_network_discovery();
    
    // 等待服务发现
    std::this_thread::sleep_for(std::chrono::seconds(3));
    
    // 获取已发现的服务
    auto services = frontend.get_discovered_services();
    
    if (services.empty()) {
        std::cout << "未发现音频服务,无法建立会话" << std::endl;
        return;
    }
    
    // 连接到第一个发现的服务
    auto service = services[0];
    std::cout << "连接到服务: " << service.service_name << std::endl;
    
    auto result = frontend.connect_to_network_service(service.service_id);
    if (result != audio_backend::common::ErrorCode::SUCCESS) {
        std::cerr << "连接网络服务失败" << std::endl;
        return;
    }
    
    std::cout << "已连接到网络服务,按回车键断开..." << std::endl;
    std::cin.get();
    
    // 断开与服务的连接
    result = frontend.disconnect_from_network_service(service.service_id);
    if (result != audio_backend::common::ErrorCode::SUCCESS) {
        std::cerr << "断开网络服务失败" << std::endl;
        return;
    }
    
    std::cout << "已断开网络服务连接" << std::endl;
    
    // 停止网络服务发现
    frontend.stop_network_discovery();
}

音频流传输

前端接口提供了网络音频流传输功能:

common::ErrorCode start_network_audio_stream(const std::string& target_address, uint16_t port);
common::ErrorCode stop_network_audio_stream();
common::ErrorCode send_audio_data_to_network(const engine::AudioBuffer& buffer, const std::string& target);

此外,还可以使用专用的音频流发送器和接收器来进行更灵活的控制:

// 创建音频流发送器
auto sender = audio_backend::frontend::create_audio_stream_sender(48000, 2);

// 创建音频流接收器
auto receiver = audio_backend::frontend::create_audio_stream_receiver(48000, 2);

音频流传输示例:

void stream_audio_over_network(audio_backend::frontend::FrontendManager& frontend,
                              const std::string& target_address,
                              uint16_t port) {
    // 启动网络音频流
    auto result = frontend.start_network_audio_stream(target_address, port);
    if (result != audio_backend::common::ErrorCode::SUCCESS) {
        std::cerr << "启动网络音频流失败" << std::endl;
        return;
    }
    
    std::cout << "网络音频流已启动,流向: " << target_address << ":" << port << std::endl;
    std::cout << "按回车键停止..." << std::endl;
    std::cin.get();
    
    // 停止网络音频流
    result = frontend.stop_network_audio_stream();
    if (result != audio_backend::common::ErrorCode::SUCCESS) {
        std::cerr << "停止网络音频流失败" << std::endl;
        return;
    }
    
    std::cout << "网络音频流已停止" << std::endl;
}

音频编解码

编解码器接口

前端接口支持多种音频编解码器,用于网络传输时的压缩和解压缩:

namespace audio_backend::frontend::codec {

enum class CodecType {
    PCM,   // 无压缩PCM
    OPUS,  // Opus编解码器
    AAC,   // AAC编解码器
    FLAC   // FLAC编解码器
};

struct CodecConfig {
    CodecType codec_type;        // 编解码器类型
    uint32_t sample_rate;        // 采样率
    uint16_t channels;           // 声道数
    uint32_t bitrate;            // 比特率
    uint32_t complexity = 10;    // 复杂度 (0-10)
    bool vbr = true;            // 是否使用可变比特率
    bool fec = true;            // 是否使用前向纠错
    uint32_t packet_size_ms = 20; // 数据包大小(毫秒)
};

class IAudioCodec {
public:
    virtual ~IAudioCodec() = default;
    
    // 编码音频数据
    virtual std::vector<uint8_t> encode(const float* audio_data, 
                                       size_t samples_per_channel) = 0;
    
    // 解码音频数据
    virtual size_t decode(const uint8_t* encoded_data, 
                         size_t encoded_size,
                         float* output_buffer,
                         size_t output_buffer_size) = 0;
    
    // 获取配置
    virtual CodecConfig get_config() const = 0;
    
    // 获取延迟样本数
    virtual uint32_t get_codec_delay_samples() const = 0;
};

}  // namespace audio_backend::frontend::codec

缓冲区管理

前端接口提供了缓冲区管理,用于处理网络传输中的抖动和延迟:

namespace audio_backend::frontend::network {

struct BufferManagerConfig {
    uint32_t initial_buffer_size_ms;  // 初始缓冲区大小(毫秒)
    uint32_t min_buffer_size_ms;      // 最小缓冲区大小(毫秒)
    uint32_t max_buffer_size_ms;      // 最大缓冲区大小(毫秒)
    uint32_t target_buffer_size_ms;   // 目标缓冲区大小(毫秒)
    uint32_t sample_rate;            // 采样率
    uint16_t channels;               // 声道数
    bool adaptive_buffering;         // 是否启用自适应缓冲
    uint32_t adaptation_speed;       // 自适应速度 (1-10)
};

class BufferManager {
public:
    virtual ~BufferManager() = default;
    
    // 添加音频数据到缓冲区
    virtual void add_audio_data(const std::vector<uint8_t>& data,
                               uint32_t timestamp) = 0;
    
    // 获取可用的音频数据
    virtual engine::AudioBuffer get_audio_data(uint32_t num_frames) = 0;
    
    // 获取当前缓冲区状态
    virtual uint32_t get_buffered_ms() const = 0;
    virtual uint32_t get_underruns() const = 0;
    virtual uint32_t get_overruns() const = 0;
    
    // 缓冲区控制
    virtual void clear() = 0;
    virtual void pause() = 0;
    virtual void resume() = 0;
    
    // 配置
    virtual void set_config(const BufferManagerConfig& config) = 0;
    virtual BufferManagerConfig get_config() const = 0;
};

}  // namespace audio_backend::frontend::network

使用编解码器和缓冲区管理的示例:

void audio_codec_example() {
    // 创建Opus编解码器
    auto codec_config = audio_backend::frontend::codec::CodecConfig{
        audio_backend::frontend::codec::CodecType::OPUS,
        48000,  // 采样率
        2,     // 声道数
        128000 // 比特率
    };
    
    auto codec = audio_backend::frontend::codec::create_codec(codec_config);
    
    // 创建缓冲区管理器
    auto buffer_config = audio_backend::frontend::network::BufferManagerConfig{
        50,     // 初始缓冲50ms
        20,     // 最小缓冲20ms
        200,    // 最大缓冲200ms
        50,     // 目标缓冲50ms
        48000,  // 采样率
        2,      // 声道数
        true,   // 启用自适应缓冲
        5       // 中等自适应速度
    };
    
    auto buffer_manager = audio_backend::frontend::create_buffer_manager(
        buffer_config.initial_buffer_size_ms,
        buffer_config.sample_rate,
        buffer_config.channels);
    
    // 模拟音频处理流程
    const size_t frame_size = 480;  // 10ms @ 48kHz
    std::vector<float> audio_samples(frame_size * 2);  // 立体声
    
    // 生成一些示例音频数据(正弦波)
    for (size_t i = 0; i < frame_size; i++) {
        float sample = std::sin(2.0f * 3.14159f * 440.0f * i / 48000.0f);
        audio_samples[i * 2] = sample;     // 左声道
        audio_samples[i * 2 + 1] = sample; // 右声道
    }
    
    // 编码音频数据
    auto encoded_data = codec->encode(audio_samples.data(), frame_size);
    
    std::cout << "原始音频大小: " << (frame_size * 2 * sizeof(float)) << " 字节" << std::endl;
    std::cout << "编码后大小: " << encoded_data.size() << " 字节" << std::endl;
    std::cout << "压缩率: " << ((float)encoded_data.size() / (frame_size * 2 * sizeof(float)) * 100) << "%" << std::endl;
    
    // 将编码数据添加到缓冲区
    buffer_manager->add_audio_data(encoded_data, 0);
    
    // 获取音频数据
    auto output_buffer = buffer_manager->get_audio_data(frame_size);
    
    std::cout << "缓冲区状态: " << buffer_manager->get_buffered_ms() << "ms 已缓冲" << std::endl;
}

事件处理

事件类型

前端接口定义了多种事件类型,用于通知应用程序状态变化:

enum class FrontendEvent {
    EngineConnected,        // 音频引擎连接成功
    EngineDisconnected,     // 音频引擎断开连接
    DeviceAdded,           // 音频设备添加
    DeviceRemoved,         // 音频设备移除
    NetworkServiceFound,   // 发现网络服务
    NetworkServiceLost,    // 网络服务丢失
    AudioStreamStarted,    // 音频流开始
    AudioStreamStopped,    // 音频流停止
    ConfigurationChanged   // 配置变更
};

事件监听器

应用程序可以通过实现IFrontendEventListener接口来接收前端事件:

class IFrontendEventListener {
public:
    virtual ~IFrontendEventListener() = default;
    
    // 事件回调
    virtual void on_frontend_event(FrontendEvent event, const std::string& data) = 0;
    
    // 音频事件
    virtual void on_audio_device_changed(const std::string& device_id, bool added) = 0;
    virtual void on_audio_stream_data(const engine::AudioBuffer& buffer) = 0;
    
    // 网络事件
    virtual void on_network_service_discovered(const std::string& service_name, 
                                              const std::string& address, 
                                              uint16_t port) = 0;
    
    // 错误事件
    virtual void on_frontend_error(common::ErrorCode error, const std::string& message) = 0;
};

事件监听器示例:

class MyFrontendListener : public audio_backend::frontend::IFrontendEventListener {
public:
    void on_frontend_event(audio_backend::frontend::FrontendEvent event,
                          const std::string& data) override {
        std::cout << "前端事件: ";
        
        switch (event) {
            case audio_backend::frontend::FrontendEvent::EngineConnected:
                std::cout << "引擎已连接";
                break;
            case audio_backend::frontend::FrontendEvent::EngineDisconnected:
                std::cout << "引擎已断开";
                break;
            case audio_backend::frontend::FrontendEvent::DeviceAdded:
                std::cout << "设备已添加";
                break;
            case audio_backend::frontend::FrontendEvent::DeviceRemoved:
                std::cout << "设备已移除";
                break;
            case audio_backend::frontend::FrontendEvent::NetworkServiceFound:
                std::cout << "发现网络服务";
                break;
            case audio_backend::frontend::FrontendEvent::NetworkServiceLost:
                std::cout << "网络服务丢失";
                break;
            case audio_backend::frontend::FrontendEvent::AudioStreamStarted:
                std::cout << "音频流已启动";
                break;
            case audio_backend::frontend::FrontendEvent::AudioStreamStopped:
                std::cout << "音频流已停止";
                break;
            case audio_backend::frontend::FrontendEvent::ConfigurationChanged:
                std::cout << "配置已更改";
                break;
            default:
                std::cout << "未知事件";
                break;
        }
        
        if (!data.empty()) {
            std::cout << " - 数据: " << data;
        }
        
        std::cout << std::endl;
    }
    
    void on_audio_device_changed(const std::string& device_id, bool added) override {
        std::cout << "音频设备" << (added ? "添加" : "移除") << ": " << device_id << std::endl;
    }
    
    void on_audio_stream_data(const audio_backend::engine::AudioBuffer& buffer) override {
        // 实际应用中可能对音频数据进行处理
        std::cout << "接收到音频数据: " << buffer.frames() << " 帧, " 
                 << buffer.channels() << " 声道" << std::endl;
    }
    
    void on_network_service_discovered(const std::string& service_name, 
                                      const std::string& address, 
                                      uint16_t port) override {
        std::cout << "发现网络服务: " << service_name << " @ " 
                 << address << ":" << port << std::endl;
    }
    
    void on_frontend_error(audio_backend::common::ErrorCode error, 
                          const std::string& message) override {
        std::cerr << "前端错误: " << audio_backend::common::error_to_string(error) 
                 << " - " << message << std::endl;
    }
};

// 使用事件监听器
void use_event_listener(audio_backend::frontend::FrontendManager& frontend) {
    auto listener = std::make_shared<MyFrontendListener>();
    
    frontend.add_event_listener(listener);
    
    // 执行会触发事件的操作
    // ...
    
    // 移除事件监听器
    frontend.remove_event_listener(listener);
}

工厂函数

基础工厂

前端接口提供了多种工厂函数,用于创建各种前端组件:

namespace audio_backend::frontend {

// 创建前端管理器
std::unique_ptr<Manager> create_frontend_manager(const std::string& process_name = "audio_frontend");

// 创建引擎代理
std::unique_ptr<EngineProxy> create_engine_proxy(const std::string& endpoint = "tcp://localhost:5555");

// 创建设备管理器
std::unique_ptr<DeviceManager> create_device_manager();

// 创建音频流发送器
std::unique_ptr<AudioStreamSender> create_audio_stream_sender(
    uint32_t sample_rate = 48000,
    uint16_t channels = 2,
    frontend::network::AudioCodec codec = frontend::network::AudioCodec::OPUS);

// 创建音频流接收器
std::unique_ptr<AudioStreamReceiver> create_audio_stream_receiver(
    uint32_t sample_rate = 48000,
    uint16_t channels = 2,
    frontend::network::AudioCodec codec = frontend::network::AudioCodec::OPUS);

// 创建服务发现
std::unique_ptr<ServiceDiscovery> create_service_discovery();

// 创建会话管理器
std::unique_ptr<SessionManager> create_session_manager();

// 创建会话服务器
std::unique_ptr<SessionServer> create_session_server(uint16_t port = 9999);

// 创建编解码器
std::unique_ptr<AudioCodec> create_audio_codec(
    frontend::codec::CodecType type,
    uint32_t sample_rate = 48000,
    uint16_t channels = 2,
    uint32_t bitrate = 128000);

// 创建缓冲管理器
std::unique_ptr<BufferManager> create_buffer_manager(
    uint32_t initial_buffer_size_ms = 50,
    uint32_t sample_rate = 48000,
    uint16_t channels = 2);

}  // namespace audio_backend::frontend

预配置组合

前端接口还提供了预配置的工厂函数,用于创建具有特定功能的前端管理器:

namespace audio_backend::frontend {

// 创建本地音频前端(无网络功能)
std::unique_ptr<Manager> create_local_frontend();

// 创建网络客户端前端(连接到远程音频引擎)
std::unique_ptr<Manager> create_network_client_frontend(
    const std::string& server_address,
    uint16_t port);

// 创建低延迟音频流配置
std::unique_ptr<Manager> create_low_latency_frontend();

// 创建高质量音频流配置
std::unique_ptr<Manager> create_high_quality_frontend();

// 创建平衡配置(延迟和质量的平衡)
std::unique_ptr<Manager> create_balanced_frontend();

}  // namespace audio_backend::frontend

使用工厂函数示例:

void factory_functions_example() {
    // 创建本地前端
    auto local_frontend = audio_backend::frontend::create_local_frontend();
    if (local_frontend) {
        std::cout << "创建本地前端成功" << std::endl;
    }
    
    // 创建低延迟前端
    auto low_latency = audio_backend::frontend::create_low_latency_frontend();
    if (low_latency) {
        std::cout << "创建低延迟前端成功" << std::endl;
    }
    
    // 创建高质量前端
    auto high_quality = audio_backend::frontend::create_high_quality_frontend();
    if (high_quality) {
        std::cout << "创建高质量前端成功" << std::endl;
    }
    
    // 创建平衡前端
    auto balanced = audio_backend::frontend::create_balanced_frontend();
    if (balanced) {
        std::cout << "创建平衡前端成功" << std::endl;
    }
}

实现示例

本地音频处理

以下是使用前端接口进行本地音频处理的完整示例:

#include "audio_backend/frontend.h"
#include <iostream>
#include <thread>
#include <chrono>

using namespace audio_backend;

// 自定义音频处理回调
class MyAudioProcessor : public frontend::IFrontendEventListener {
public:
    void on_frontend_event(frontend::FrontendEvent event, const std::string& data) override {
        std::cout << "事件: ";
        switch (event) {
            case frontend::FrontendEvent::AudioStreamStarted:
                std::cout << "音频流已启动" << std::endl;
                break;
            case frontend::FrontendEvent::AudioStreamStopped:
                std::cout << "音频流已停止" << std::endl;
                break;
            default:
                std::cout << "其他事件" << std::endl;
                break;
        }
    }
    
    void on_audio_device_changed(const std::string& device_id, bool added) override {
        // 不处理设备变化
    }
    
    void on_network_service_discovered(const std::string& service_name, 
                                      const std::string& address, 
                                      uint16_t port) override {
        // 不处理网络服务
    }
    
    void on_audio_stream_data(const engine::AudioBuffer& buffer) override {
        // 处理音频数据(在本例中,简单地计算音量)
        double sum = 0.0;
        size_t samples = buffer.frames() * buffer.channels();
        
        if (buffer.is_interleaved()) {
            const float* data = buffer.interleaved_data<float>();
            for (size_t i = 0; i < samples; i++) {
                sum += std::abs(data[i]);
            }
        } else {
            for (uint16_t ch = 0; ch < buffer.channels(); ch++) {
                const float* data = buffer.channel_data<float>(ch);
                for (uint32_t i = 0; i < buffer.frames(); i++) {
                    sum += std::abs(data[i]);
                }
            }
        }
        
        double average = sum / samples;
        frames_processed += buffer.frames();
        
        // 每秒更新一次统计
        auto now = std::chrono::steady_clock::now();
        if (now - last_update > std::chrono::seconds(1)) {
            std::cout << "已处理: " << frames_processed << " 帧, 平均音量: " 
                     << (average * 100) << "%" << std::endl;
            last_update = now;
        }
    }
    
    void on_frontend_error(common::ErrorCode error, const std::string& message) override {
        std::cerr << "错误: " << common::error_to_string(error) << " - " << message << std::endl;
    }
    
private:
    uint64_t frames_processed = 0;
    std::chrono::steady_clock::time_point last_update = std::chrono::steady_clock::now();
};

int main() {
    // 初始化前端系统
    frontend::initialize_frontend();
    
    // 创建前端管理器(本地模式)
    auto frontend_manager = frontend::create_local_frontend();
    if (!frontend_manager) {
        std::cerr << "创建前端管理器失败" << std::endl;
        return 1;
    }
    
    // 初始化前端管理器
    auto result = frontend_manager->initialize();
    if (result != common::ErrorCode::SUCCESS) {
        std::cerr << "初始化前端管理器失败: " << common::error_to_string(result) << std::endl;
        return 1;
    }
    
    // 创建并添加事件监听器
    auto processor = std::make_shared<MyAudioProcessor>();
    frontend_manager->add_event_listener(processor);
    
    // 连接到本地音频引擎
    result = frontend_manager->connect_to_engine("tcp://localhost:5555");
    if (result != common::ErrorCode::SUCCESS) {
        std::cerr << "连接音频引擎失败: " << common::error_to_string(result) << std::endl;
        frontend_manager->shutdown();
        frontend::shutdown_frontend();
        return 1;
    }
    
    // 列出可用音频设备
    auto devices = frontend_manager->get_audio_devices();
    std::cout << "可用音频设备:" << std::endl;
    for (const auto& device : devices) {
        std::cout << (device.is_default ? "* " : "  ")
                 << device.name << (device.is_input ? " (输入)" : " (输出)") << std::endl;
    }
    
    // 设置默认输入设备
    for (const auto& device : devices) {
        if (device.is_default && device.is_input) {
            frontend_manager->set_input_device(device.id);
            break;
        }
    }
    
    // 设置默认输出设备
    for (const auto& device : devices) {
        if (device.is_default && device.is_output) {
            frontend_manager->set_output_device(device.id);
            break;
        }
    }
    
    // 启动音频流
    std::cout << "启动音频流..." << std::endl;
    result = frontend_manager->start_audio_stream();
    if (result != common::ErrorCode::SUCCESS) {
        std::cerr << "启动音频流失败: " << common::error_to_string(result) << std::endl;
        frontend_manager->shutdown();
        frontend::shutdown_frontend();
        return 1;
    }
    
    // 运行10秒钟
    std::cout << "音频处理中将运行10秒..." << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(10));
    
    // 停止音频流
    std::cout << "停止音频流..." << std::endl;
    result = frontend_manager->stop_audio_stream();
    if (result != common::ErrorCode::SUCCESS) {
        std::cerr << "停止音频流失败: " << common::error_to_string(result) << std::endl;
    }
    
    // 断开音频引擎连接
    frontend_manager->disconnect_from_engine();
    
    // 移除事件监听器
    frontend_manager->remove_event_listener(processor);
    
    // 关闭前端管理器
    frontend_manager->shutdown();
    
    // 清理前端系统
    frontend::shutdown_frontend();
    
    std::cout << "程序已完成" << std::endl;
    return 0;
}

远程音频传输

以下是使用前端接口进行远程音频传输的完整示例:

#include "audio_backend/frontend.h"
#include <iostream>
#include <thread>
#include <chrono>
#include <atomic>

using namespace audio_backend;

// 定义传输角色
enum class TransportRole {
    Sender,
    Receiver
};

// 网络音频监听器
class NetworkAudioListener : public frontend::IFrontendEventListener {
public:
    explicit NetworkAudioListener(TransportRole role)
        : role_(role), audio_frames_(0) {}
    
    void on_frontend_event(frontend::FrontendEvent event, const std::string& data) override {
        std::cout << (role_ == TransportRole::Sender ? "发送端" : "接收端")
                 << " 事件: ";
        
        switch (event) {
            case frontend::FrontendEvent::EngineConnected:
                std::cout << "引擎已连接" << std::endl;
                break;
            case frontend::FrontendEvent::NetworkServiceFound:
                std::cout << "发现服务: " << data << std::endl;
                services_discovered_ = true;
                break;
            case frontend::FrontendEvent::AudioStreamStarted:
                std::cout << "音频流已启动" << std::endl;
                stream_active_ = true;
                break;
            case frontend::FrontendEvent::AudioStreamStopped:
                std::cout << "音频流已停止" << std::endl;
                stream_active_ = false;
                break;
            default:
                std::cout << "其他事件" << std::endl;
                break;
        }
    }
    
    void on_audio_device_changed(const std::string& device_id, bool added) override {
        // 不处理设备变化
    }
    
    void on_network_service_discovered(const std::string& service_name, 
                                      const std::string& address, 
                                      uint16_t port) override {
        std::cout << "发现网络服务: " << service_name
                 << " @ " << address << ":" << port << std::endl;
                 
        discovered_address_ = address;
        discovered_port_ = port;
        services_discovered_ = true;
    }
    
    void on_audio_stream_data(const engine::AudioBuffer& buffer) override {
        audio_frames_ += buffer.frames();
        
        // 每秒报告一次
        auto now = std::chrono::steady_clock::now();
        if (now - last_report_ > std::chrono::seconds(1)) {
            double seconds = std::chrono::duration<double>(now - last_report_).count();
            double frames_per_second = audio_frames_ / seconds;
            
            std::cout << (role_ == TransportRole::Sender ? "发送" : "接收")
                     << " 速率: " << frames_per_second << " 帧/秒 ("
                     << (frames_per_second / buffer.sample_rate()) << "x 实时速率)"
                     << std::endl;
                     
            audio_frames_ = 0;
            last_report_ = now;
        }
    }
    
    void on_frontend_error(common::ErrorCode error, const std::string& message) override {
        std::cerr << (role_ == TransportRole::Sender ? "发送端" : "接收端")
                 << " 错误: " << common::error_to_string(error)
                 << " - " << message << std::endl;
    }
    
    bool has_discovered_service() const { return services_discovered_; }
    std::string get_discovered_address() const { return discovered_address_; }
    uint16_t get_discovered_port() const { return discovered_port_; }
    bool is_stream_active() const { return stream_active_; }
    
private:
    TransportRole role_;
    uint64_t audio_frames_;
    std::chrono::steady_clock::time_point last_report_ = std::chrono::steady_clock::now();
    std::atomic<bool> services_discovered_{false};
    std::atomic<bool> stream_active_{false};
    std::string discovered_address_;
    uint16_t discovered_port_ = 0;
};

// 远程音频传输示例
int main(int argc, char* argv[]) {
    if (argc < 2) {
        std::cerr << "用法: " << argv[0] << " [sender|receiver]" << std::endl;
        return 1;
    }
    
    std::string mode = argv[1];
    TransportRole role = (mode == "sender") ? TransportRole::Sender : TransportRole::Receiver;
    
    // 初始化前端系统
    frontend::initialize_frontend();
    
    // 创建前端管理器
    auto frontend_manager = frontend::create_frontend_manager();
    if (!frontend_manager) {
        std::cerr << "创建前端管理器失败" << std::endl;
        return 1;
    }
    
    // 配置前端管理器
    auto config = frontend_manager->config();
    config.enable_network_discovery = true;
    config.enable_network_streaming = true;
    config.audio_stream_port = 8888;
    frontend_manager->update_config(config);
    
    // 初始化前端管理器
    auto result = frontend_manager->initialize();
    if (result != common::ErrorCode::SUCCESS) {
        std::cerr << "初始化前端管理器失败" << std::endl;
        return 1;
    }
    
    // 创建并添加事件监听器
    auto listener = std::make_shared<NetworkAudioListener>(role);
    frontend_manager->add_event_listener(listener);
    
    // 连接到音频引擎
    result = frontend_manager->connect_to_engine();
    if (result != common::ErrorCode::SUCCESS) {
        std::cerr << "连接音频引擎失败" << std::endl;
        frontend_manager->shutdown();
        frontend::shutdown_frontend();
        return 1;
    }
    
    if (role == TransportRole::Sender) {
        // === 发送端 ===
        
        // 配置音频设备
        auto devices = frontend_manager->get_audio_devices();
        
        // 设置默认输入设备
        for (const auto& device : devices) {
            if (device.is_default && device.is_input) {
                frontend_manager->set_input_device(device.id);
                std::cout << "使用输入设备: " << device.name << std::endl;
                break;
            }
        }
        
        // 启动音频流
        result = frontend_manager->start_audio_stream();
        if (result != common::ErrorCode::SUCCESS) {
            std::cerr << "启动音频流失败" << std::endl;
            frontend_manager->shutdown();
            frontend::shutdown_frontend();
            return 1;
        }
        
        // 启动网络发现(可选)
        frontend_manager->start_network_discovery();
        
        // 启动网络音频流
        std::cout << "启动网络音频流,监听端口: " << config.audio_stream_port << std::endl;
        
        // 这里使用本地地址,实际应用中可能是远程地址
        result = frontend_manager->start_network_audio_stream("0.0.0.0", config.audio_stream_port);
        if (result != common::ErrorCode::SUCCESS) {
            std::cerr << "启动网络音频流失败" << std::endl;
            frontend_manager->shutdown();
            frontend::shutdown_frontend();
            return 1;
        }
        
        std::cout << "发送音频中,按回车停止..." << std::endl;
        std::cin.get();
        
        // 停止网络音频流
        frontend_manager->stop_network_audio_stream();
        
        // 停止音频流
        frontend_manager->stop_audio_stream();
        
    } else {
        // === 接收端 ===
        
        // 启动网络发现
        std::cout << "启动网络服务发现..." << std::endl;
        frontend_manager->start_network_discovery();
        
        // 设置默认输出设备
        auto devices = frontend_manager->get_audio_devices();
        for (const auto& device : devices) {
            if (device.is_default && device.is_output) {
                frontend_manager->set_output_device(device.id);
                std::cout << "使用输出设备: " << device.name << std::endl;
                break;
            }
        }
        
        // 等待发现服务
        std::cout << "等待发现音频发送服务..." << std::endl;
        
        // 在实际应用中,应该使用事件驱动方式等待服务发现
        // 这里简单起见使用轮询
        int timeout_seconds = 30;
        for (int i = 0; i < timeout_seconds; i++) {
            if (listener->has_discovered_service()) {
                break;
            }
            std::this_thread::sleep_for(std::chrono::seconds(1));
            std::cout << "等待中... " << (timeout_seconds - i - 1) << " 秒" << std::endl;
        }
        
        if (!listener->has_discovered_service()) {
            std::cerr << "未发现音频服务,超时" << std::endl;
            frontend_manager->shutdown();
            frontend::shutdown_frontend();
            return 1;
        }
        
        std::string address = listener->get_discovered_address();
        uint16_t port = listener->get_discovered_port();
        
        if (port == 0) {
            port = 8888; // 使用默认端口
        }
        
        std::cout << "连接到音频服务: " << address << ":" << port << std::endl;
        
        // 启动音频流
        result = frontend_manager->start_audio_stream();
        if (result != common::ErrorCode::SUCCESS) {
            std::cerr << "启动音频流失败" << std::endl;
            frontend_manager->shutdown();
            frontend::shutdown_frontend();
            return 1;
        }
        
        // 连接到网络音频流
        result = frontend_manager->start_network_audio_stream(address, port);
        if (result != common::ErrorCode::SUCCESS) {
            std::cerr << "连接网络音频流失败" << std::endl;
            frontend_manager->shutdown();
            frontend::shutdown_frontend();
            return 1;
        }
        
        std::cout << "接收音频中,按回车停止..." << std::endl;
        std::cin.get();
        
        // 停止网络音频流
        frontend_manager->stop_network_audio_stream();
        
        // 停止音频流
        frontend_manager->stop_audio_stream();
    }
    
    // 断开音频引擎连接
    frontend_manager->disconnect_from_engine();
    
    // 移除事件监听器
    frontend_manager->remove_event_listener(listener);
    
    // 关闭前端管理器
    frontend_manager->shutdown();
    
    // 清理前端系统
    frontend::shutdown_frontend();
    
    std::cout << "程序已完成" << std::endl;
    return 0;
}

网络服务发现

以下是使用前端接口进行网络服务发现的示例:

#include "audio_backend/frontend.h"
#include <iostream>
#include <thread>
#include <chrono>
#include <map>
#include <mutex>

using namespace audio_backend;

// 服务浏览器
class ServiceBrowser : public frontend::IFrontendEventListener {
public:
    void on_frontend_event(frontend::FrontendEvent event, const std::string& data) override {
        if (event == frontend::FrontendEvent::NetworkServiceFound) {
            std::cout << "发现服务: " << data << std::endl;
        } else if (event == frontend::FrontendEvent::NetworkServiceLost) {
            std::cout << "丢失服务: " << data << std::endl;
        }
    }
    
    void on_audio_device_changed(const std::string& device_id, bool added) override {
        // 不处理设备变化
    }
    
    void on_audio_stream_data(const engine::AudioBuffer& buffer) override {
        // 不处理音频数据
    }
    
    void on_network_service_discovered(const std::string& service_name, 
                                      const std::string& address, 
                                      uint16_t port) override {
        std::lock_guard<std::mutex> lock(mutex_);
        
        std::string key = service_name + "@" + address + ":" + std::to_string(port);
        
        if (services_.find(key) == services_.end()) {
            std::cout << "新服务: " << service_name << " @ " << address << ":" << port << std::endl;
            
            services_[key] = {
                service_name,
                address,
                port,
                std::chrono::steady_clock::now()
            };
        } else {
            // 更新最后发现时间
            services_[key].last_seen = std::chrono::steady_clock::now();
        }
    }
    
    void on_frontend_error(common::ErrorCode error, const std::string& message) override {
        std::cerr << "错误: " << common::error_to_string(error) << " - " << message << std::endl;
    }
    
    void print_active_services() {
        std::lock_guard<std::mutex> lock(mutex_);
        
        auto now = std::chrono::steady_clock::now();
        
        std::cout << "\n当前活动服务:" << std::endl;
        std::cout << "-----------------------------------------" << std::endl;
        
        int count = 0;
        for (const auto& [key, service] : services_) {
            // 检查服务是否在过去30秒内活动
            auto age = std::chrono::duration_cast<std::chrono::seconds>(now - service.last_seen).count();
            
            if (age <= 30) {
                std::cout << ++count << ". " << service.name 
                         << " @ " << service.address << ":" << service.port
                         << " (上次发现: " << age << " 秒前)" << std::endl;
            }
        }
        
        if (count == 0) {
            std::cout << "未发现活动服务" << std::endl;
        }
        
        std::cout << "-----------------------------------------" << std::endl;
    }
    
private:
    struct ServiceInfo {
        std::string name;
        std::string address;
        uint16_t port;
        std::chrono::steady_clock::time_point last_seen;
    };
    
    std::map<std::string, ServiceInfo> services_;
    std::mutex mutex_;
};

// 网络服务发现示例
int main() {
    // 初始化前端系统
    frontend::initialize_frontend();
    
    std::cout << "音频服务浏览器" << std::endl;
    std::cout << "===========================================" << std::endl;
    
    // 创建前端管理器
    auto frontend_manager = frontend::create_frontend_manager();
    if (!frontend_manager) {
        std::cerr << "创建前端管理器失败" << std::endl;
        return 1;
    }
    
    // 配置前端管理器
    auto config = frontend_manager->config();
    config.enable_network_discovery = true;
    frontend_manager->update_config(config);
    
    // 初始化前端管理器
    auto result = frontend_manager->initialize();
    if (result != common::ErrorCode::SUCCESS) {
        std::cerr << "初始化前端管理器失败" << std::endl;
        return 1;
    }
    
    // 创建服务浏览器
    auto browser = std::make_shared<ServiceBrowser>();
    frontend_manager->add_event_listener(browser);
    
    // 启动网络服务发现
    result = frontend_manager->start_network_discovery();
    if (result != common::ErrorCode::SUCCESS) {
        std::cerr << "启动网络服务发现失败" << std::endl;
        frontend_manager->shutdown();
        frontend::shutdown_frontend();
        return 1;
    }
    
    std::cout << "开始浏览网络音频服务..." << std::endl;
    std::cout << "每10秒打印一次活动服务列表" << std::endl;
    std::cout << "按回车键退出" << std::endl;
    
    // 创建一个独立线程来打印服务列表
    std::atomic<bool> running(true);
    std::thread printer_thread([&]() {
        while (running) {
            std::this_thread::sleep_for(std::chrono::seconds(10));
            if (running) {
                browser->print_active_services();
            }
        }
    });
    
    // 等待用户输入退出
    std::cin.get();
    running = false;
    
    // 等待打印线程结束
    if (printer_thread.joinable()) {
        printer_thread.join();
    }
    
    // 停止网络服务发现
    frontend_manager->stop_network_discovery();
    
    // 移除事件监听器
    frontend_manager->remove_event_listener(browser);
    
    // 关闭前端管理器
    frontend_manager->shutdown();
    
    // 清理前端系统
    frontend::shutdown_frontend();
    
    std::cout << "程序已完成" << std::endl;
    return 0;
}

性能优化

延迟优化

针对低延迟场景的优化策略:

  1. 缓冲区大小使用小缓冲区大小128-256帧

    // 配置低延迟前端
    auto config = frontend_manager->config();
    config.audio_buffer_size = 128;
    config.network_buffer_size = 512;
    config.max_latency_ms = 20;
    frontend_manager->update_config(config);
    
  2. 编解码器设置:使用低延迟编解码器配置

    // 低延迟Opus编解码器配置
    auto codec_config = frontend::codec::CodecConfig{
        frontend::codec::CodecType::OPUS,
        48000,    // 采样率
        2,        // 声道数
        64000,    // 比特率
        5,        // 中等复杂度
        false,    // 禁用VBR
        true,     // 启用FEC
        10        // 10ms包大小
    };
    
  3. 网络传输优化使用UDP传输和抖动缓冲

    // 创建UDP传输
    auto transport = frontend::create_udp_transport(config.audio_stream_port);
    
    // 配置抖动缓冲区
    auto buffer_config = frontend::network::BufferManagerConfig{
        20,      // 初始缓冲20ms
        5,       // 最小缓冲5ms
        50,      // 最大缓冲50ms
        20,      // 目标缓冲20ms
        48000,   // 采样率
        2,       // 声道数
        true,    // 启用自适应缓冲
        8        // 快速自适应
    };
    

带宽优化

针对带宽受限场景的优化策略:

  1. 编解码器设置:使用高压缩率配置

    // 带宽优化Opus编解码器配置
    auto codec_config = frontend::codec::CodecConfig{
        frontend::codec::CodecType::OPUS,
        48000,    // 采样率
        2,        // 声道数
        32000,    // 低比特率
        10,       // 高复杂度
        true,     // 启用VBR
        true,     // 启用FEC
        40        // 40ms包大小更大包减少带宽开销
    };
    
  2. 数据压缩:对元数据进行压缩

    // 启用元数据压缩
    transport->enable_metadata_compression(true);
    
  3. 优化采样率:根据带宽调整采样率

    // 根据网络带宽动态调整音频质量
    frontend_manager->set_adaptive_quality(true);
    

跨平台考虑

网络兼容性

不同平台的网络差异:

  1. Windows

    • 使用Winsock 2 API
    • mDNS实现使用Bonjour或DNS-SD
    • 网络安全策略Windows防火墙
  2. Linux

    • 使用标准BSD套接字
    • mDNS实现使用Avahi
    • 网络安全策略iptables或ufw
  3. macOS

    • 使用标准BSD套接字
    • mDNS实现使用Bonjour
    • 网络安全策略pf或应用沙盒

跨平台网络兼容性考虑:

// 检测平台特定网络功能
bool is_mdns_supported() {
    #ifdef _WIN32
        // Windows: 检查Bonjour或DNS-SD
        return check_windows_mdns_support();
    #elif defined(__APPLE__)
        // macOS: 内置Bonjour支持
        return true;
    #elif defined(__linux__)
        // Linux: 检查Avahi
        return check_linux_avahi_support();
    #else
        // 其他平台
        return false;
    #endif
}

设备兼容性

不同平台的音频设备差异:

  1. Windows

    • 支持WASAPI、DirectSound、ASIO
    • 设备枚举通过Windows Multimedia API
    • 设备格式限制与平台特定
  2. Linux

    • 支持ALSA、PulseAudio、JACK
    • 设备枚举因音频系统而异
    • 权限问题(如对/dev/snd的访问权限
  3. macOS

    • 支持CoreAudio
    • 设备枚举通过Audio Device API
    • 应用沙盒限制对设备的访问

跨平台设备兼容性考虑:

// 获取平台最佳设备配置
frontend::DeviceConfiguration get_platform_optimal_config() {
    frontend::DeviceConfiguration config;
    
    #ifdef _WIN32
        // Windows优化配置
        config.api = "wasapi";
        config.exclusive_mode = true;
        config.buffer_size = 480;  // 10ms @ 48kHz
    #elif defined(__APPLE__)
        // macOS优化配置
        config.api = "coreaudio";
        config.buffer_size = 256;
    #elif defined(__linux__)
        // Linux优化配置
        // 检测是否有JACK
        if (check_jack_available()) {
            config.api = "jack";
            config.buffer_size = 256;
        } else {
            config.api = "pulseaudio";
            config.buffer_size = 480;
        }
    #endif
    
    return config;
}