mirror of
https://github.com/atdunbg/Nekosonic-Music.git
synced 2026-08-16 19:04:18 +08:00
- 详情页统一 DetailLayout 组件(常驻头部 + 独立滚动 + 紧凑态动画) - 歌曲/评论 tab 切换(懒加载 + 保活),专辑模糊搜索 - 皮肤系统 skins.ts(19 语义色 + 14 预设 + 自定义皮肤 + 壁纸) - 设置页皮肤模块(外观/主题色/皮肤编辑器/壁纸选择) - 可折叠侧边栏 + TopBar + 折叠态歌单浮层(高度不越 PlayerBar) - 首页扩展至 6 区块 + 通用卡片组件 + 虚拟歌曲列表 - audio.rs 拆为 8 模块,api.ts 拆为 api/ 目录,player store 拆为 4 store - 修复播放竞态、seek 暂停、评论提前加载、紧凑态卡死等
56 lines
1.8 KiB
Rust
56 lines
1.8 KiB
Rust
//! 音频输出设备管理
|
|
//!
|
|
//! 列举、查找、选择音频输出设备。当用户指定的设备不存在时回退到系统默认设备。
|
|
|
|
use cpal::traits::{DeviceTrait, HostTrait};
|
|
|
|
/// 获取系统默认输出设备的名称
|
|
pub fn get_system_default_device_name() -> Option<String> {
|
|
cpal::default_host()
|
|
.default_output_device()
|
|
.and_then(|d| d.name().ok())
|
|
}
|
|
|
|
/// 列出系统中所有可用的音频输出设备名称(去重排序后)
|
|
pub fn list_output_devices() -> Vec<String> {
|
|
let host = cpal::default_host();
|
|
if let Ok(devices) = host.output_devices() {
|
|
let mut names: Vec<String> = devices.filter_map(|d| d.name().ok()).collect();
|
|
names.sort();
|
|
names.dedup();
|
|
names
|
|
} else {
|
|
vec![]
|
|
}
|
|
}
|
|
|
|
/// 按名称查找音频输出设备,未找到则返回 None
|
|
pub fn find_device_by_name(name: &str) -> Option<cpal::Device> {
|
|
let host = cpal::default_host();
|
|
if let Ok(devices) = host.output_devices() {
|
|
for d in devices {
|
|
if let Ok(n) = d.name() {
|
|
if n == name {
|
|
return Some(d);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
None
|
|
}
|
|
|
|
/// 获取音频输出设备,优先使用指定名称的设备,否则回退到系统默认设备
|
|
pub fn get_output_device(selected: &Option<String>) -> cpal::Device {
|
|
match selected {
|
|
Some(name) => find_device_by_name(name).unwrap_or_else(|| {
|
|
eprintln!("[audio] 未找到设备 `{}`,回退默认", name);
|
|
cpal::default_host()
|
|
.default_output_device()
|
|
.expect("无可用音频设备")
|
|
}),
|
|
None => cpal::default_host()
|
|
.default_output_device()
|
|
.expect("无可用音频设备"),
|
|
}
|
|
}
|