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

1818 lines
63 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 前端接口API参考
## 目录
- [概述](#概述)
- [前端管理器](#前端管理器)
- [FrontendManager](#frontendmanager)
- [前端配置](#前端配置)
- [生命周期管理](#生命周期管理)
- [音频设备管理](#音频设备管理)
- [设备信息](#设备信息)
- [设备选择](#设备选择)
- [音频流控制](#音频流控制)
- [网络通信](#网络通信)
- [服务发现](#服务发现)
- [会话管理](#会话管理)
- [音频流传输](#音频流传输)
- [音频编解码](#音频编解码)
- [编解码器接口](#编解码器接口)
- [缓冲区管理](#缓冲区管理)
- [事件处理](#事件处理)
- [事件类型](#事件类型)
- [事件监听器](#事件监听器)
- [工厂函数](#工厂函数)
- [基础工厂](#基础工厂)
- [预配置组合](#预配置组合)
- [实现示例](#实现示例)
- [本地音频处理](#本地音频处理)
- [远程音频传输](#远程音频传输)
- [网络服务发现](#网络服务发现)
- [性能优化](#性能优化)
- [延迟优化](#延迟优化)
- [带宽优化](#带宽优化)
- [跨平台考虑](#跨平台考虑)
- [网络兼容性](#网络兼容性)
- [设备兼容性](#设备兼容性)
## 概述
前端接口模块提供了应用程序与音频后端引擎通信的统一接口,支持本地和网络通信。前端接口封装了设备管理、网络发现、音频传输和编解码等复杂功能,使应用程序能够简单地集成高级音频处理能力。
核心特性:
- **本地通信**: 与同一设备上运行的音频引擎通信
- **网络通信**: 与远程音频引擎进行低延迟通信
- **自动发现**: 通过mDNS/Bonjour自动发现网络上的音频服务
- **设备管理**: 枚举、配置和监控音频设备变化
- **编解码处理**: 支持多种音频编解码器,包括无损和有损压缩
- **低延迟传输**: 针对实时音频优化的网络传输
- **安全连接**: 支持加密的音频流和控制通道
前端接口的架构示意图:
```
┌─────────────────────────────────┐ ┌─────────────────────────────────┐
│ 应用程序 │ │ 音频引擎进程 │
│ │ │ │
│ ┌─────────────────────────┐ │ │ ┌─────────────────────────┐ │
│ │ 前端管理器 │ │ │ │ 音频引擎 │ │
│ │ FrontendManager │ │ │ │ │ │
│ └───────────┬─────────────┘ │ │ └───────────┬─────────────┘ │
│ │ │ │ │ │
│ ▼ │ │ ▼ │
│ ┌───────────────────────────┐ │ │ ┌───────────────────────────┐ │
│ │ 引擎代理 │ │ │ │ 通信管理器 │ │
│ │ EngineProxy │ │ │ │ CommunicationManager │ │
│ └───────────┬───────────────┘ │ │ └───────────┬───────────────┘ │
│ │ │ │ │ │
│ │ │ │ │ │
│ ┌───────────▼───────────────┐ │ │ ┌───────────▼───────────────┐ │
│ │ 通信管理器 │ │ │ │ ZeroMQ通信 │ │
│ │ (ZeroMQ/共享内存) ├──┼──────┼─►│ (控制通道) │ │
│ └───────────────────────────┘ │ │ └───────────────────────────┘ │
│ │ │ │
│ ┌───────────────────────────┐ │ │ ┌───────────────────────────┐ │
│ │ 设备管理器 │ │ │ │ 共享内存 │ │
│ │ DeviceManager ├──┼──────┼─►│ (数据通道) │ │
│ └───────────────────────────┘ │ │ └───────────────────────────┘ │
│ │ │ │
│ ┌───────────────────────────┐ │ │ │
│ │ 网络传输 │ │ │ │
│ │ NetworkTransport │ │ │ │
│ └───────────────────────────┘ │ │ │
└─────────────────────────────────┘ └─────────────────────────────────┘
│ ┌─────────────────────────────────┐
│ │ 远程音频引擎 │
│ │ │
│ │ ┌─────────────────────────┐ │
│ │ │ 网络服务器 │ │
└──────────────────────┼─►│ NetworkServer │ │
│ └─────────────────────────┘ │
│ │
└─────────────────────────────────┘
```
## 前端管理器
### FrontendManager
`FrontendManager`是前端接口的核心类,负责协调所有前端组件,管理与音频引擎的通信,以及处理音频设备和网络服务。
```cpp
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`定义了前端接口的配置选项,包括基础设置、网络设置和性能选项:
```cpp
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<br>高质量场景: 512-2048 |
| **network_buffer_size** | 网络缓冲区大小(字节) | 2048 | 低延迟场景: 512-1024<br>高带宽场景: 4096+ |
| **max_latency_ms** | 最大可接受延迟(毫秒) | 50 | 实时通信: 20-30<br>音乐制作: 30-50<br>流媒体: 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()`清理资源
```cpp
// 示例:前端管理器基本生命周期
#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`结构提供了音频设备的详细信息:
```cpp
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; // 输出延迟(毫秒)
};
```
枚举音频设备的示例:
```cpp
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;
}
}
```
### 设备选择
前端管理器提供了设置输入和输出设备的方法:
```cpp
common::ErrorCode set_input_device(const std::string& device_id);
common::ErrorCode set_output_device(const std::string& device_id);
```
设置音频设备的示例:
```cpp
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;
}
}
}
```
### 音频流控制
前端管理器提供了启动和停止音频流的方法:
```cpp
common::ErrorCode start_audio_stream();
common::ErrorCode stop_audio_stream();
```
音频流控制示例:
```cpp
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协议自动发现网络上的音频服务
```cpp
common::ErrorCode start_network_discovery();
common::ErrorCode stop_network_discovery();
std::vector<NetworkServiceInfo> get_discovered_services() const;
```
`NetworkServiceInfo`结构提供了网络服务的详细信息:
```cpp
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; // 最后发现时间
};
```
服务发现示例:
```cpp
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();
}
```
### 会话管理
前端接口提供会话管理功能,用于建立和维护与远程服务的连接:
```cpp
common::ErrorCode connect_to_network_service(const std::string& service_id);
common::ErrorCode disconnect_from_network_service(const std::string& service_id);
```
此外,还可以使用专用的会话管理器来管理更复杂的会话场景:
```cpp
// 创建会话管理器
auto session_manager = audio_backend::frontend::create_session_manager();
// 创建会话服务器
auto session_server = audio_backend::frontend::create_session_server(9999);
```
会话管理示例:
```cpp
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();
}
```
### 音频流传输
前端接口提供了网络音频流传输功能:
```cpp
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);
```
此外,还可以使用专用的音频流发送器和接收器来进行更灵活的控制:
```cpp
// 创建音频流发送器
auto sender = audio_backend::frontend::create_audio_stream_sender(48000, 2);
// 创建音频流接收器
auto receiver = audio_backend::frontend::create_audio_stream_receiver(48000, 2);
```
音频流传输示例:
```cpp
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;
}
```
## 音频编解码
### 编解码器接口
前端接口支持多种音频编解码器,用于网络传输时的压缩和解压缩:
```cpp
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
```
### 缓冲区管理
前端接口提供了缓冲区管理,用于处理网络传输中的抖动和延迟:
```cpp
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
```
使用编解码器和缓冲区管理的示例:
```cpp
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;
}
```
## 事件处理
### 事件类型
前端接口定义了多种事件类型,用于通知应用程序状态变化:
```cpp
enum class FrontendEvent {
EngineConnected, // 音频引擎连接成功
EngineDisconnected, // 音频引擎断开连接
DeviceAdded, // 音频设备添加
DeviceRemoved, // 音频设备移除
NetworkServiceFound, // 发现网络服务
NetworkServiceLost, // 网络服务丢失
AudioStreamStarted, // 音频流开始
AudioStreamStopped, // 音频流停止
ConfigurationChanged // 配置变更
};
```
### 事件监听器
应用程序可以通过实现`IFrontendEventListener`接口来接收前端事件:
```cpp
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;
};
```
事件监听器示例:
```cpp
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);
}
```
## 工厂函数
### 基础工厂
前端接口提供了多种工厂函数,用于创建各种前端组件:
```cpp
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
```
### 预配置组合
前端接口还提供了预配置的工厂函数,用于创建具有特定功能的前端管理器:
```cpp
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
```
使用工厂函数示例:
```cpp
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;
}
}
```
## 实现示例
### 本地音频处理
以下是使用前端接口进行本地音频处理的完整示例:
```cpp
#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;
}
```
### 远程音频传输
以下是使用前端接口进行远程音频传输的完整示例:
```cpp
#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;
}
```
### 网络服务发现
以下是使用前端接口进行网络服务发现的示例:
```cpp
#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帧
```cpp
// 配置低延迟前端
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. **编解码器设置**:使用低延迟编解码器配置
```cpp
// 低延迟Opus编解码器配置
auto codec_config = frontend::codec::CodecConfig{
frontend::codec::CodecType::OPUS,
48000, // 采样率
2, // 声道数
64000, // 比特率
5, // 中等复杂度
false, // 禁用VBR
true, // 启用FEC
10 // 10ms包大小
};
```
3. **网络传输优化**使用UDP传输和抖动缓冲
```cpp
// 创建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. **编解码器设置**:使用高压缩率配置
```cpp
// 带宽优化Opus编解码器配置
auto codec_config = frontend::codec::CodecConfig{
frontend::codec::CodecType::OPUS,
48000, // 采样率
2, // 声道数
32000, // 低比特率
10, // 高复杂度
true, // 启用VBR
true, // 启用FEC
40 // 40ms包大小更大包减少带宽开销
};
```
2. **数据压缩**:对元数据进行压缩
```cpp
// 启用元数据压缩
transport->enable_metadata_compression(true);
```
3. **优化采样率**:根据带宽调整采样率
```cpp
// 根据网络带宽动态调整音频质量
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或应用沙盒
跨平台网络兼容性考虑:
```cpp
// 检测平台特定网络功能
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
- 应用沙盒限制对设备的访问
跨平台设备兼容性考虑:
```cpp
// 获取平台最佳设备配置
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;
}