调整
This commit is contained in:
@@ -44,13 +44,14 @@ use monitor_kernel::{
|
||||
};
|
||||
use music::{
|
||||
feiniu_activate_connection, feiniu_cache_clear, feiniu_cache_fetch, feiniu_cache_status,
|
||||
feiniu_delete_connection, feiniu_delete_local, feiniu_fnconnect_resolve, feiniu_get_config,
|
||||
feiniu_list_connections, feiniu_list_tracks, feiniu_login, feiniu_logout, feiniu_lyric,
|
||||
feiniu_media_prefix, feiniu_save_connection, feiniu_scan_local, feiniu_test_connection,
|
||||
music_cancel_runtime_install, music_download, music_download_cancel, music_env_status,
|
||||
music_get_settings, music_get_sources, music_install_runtime, music_parse_playlist, music_ping,
|
||||
music_resolve, music_save_settings, music_search, music_stop_bridge, webdav_delete,
|
||||
webdav_get_secret, webdav_save_secret, webdav_test, webdav_upload, MusicManager,
|
||||
feiniu_cover_data, feiniu_delete_connection, feiniu_delete_local, feiniu_fnconnect_resolve,
|
||||
feiniu_get_config, feiniu_list_connections, feiniu_list_tracks, feiniu_login, feiniu_logout,
|
||||
feiniu_lyric, feiniu_media_prefix, feiniu_save_connection, feiniu_scan_local,
|
||||
feiniu_test_connection, music_cancel_runtime_install, music_download, music_download_cancel,
|
||||
music_env_status, music_get_settings, music_get_sources, music_install_runtime,
|
||||
music_parse_playlist, music_ping, music_resolve, music_save_settings, music_search,
|
||||
music_stop_bridge, webdav_delete, webdav_get_secret, webdav_save_secret, webdav_test,
|
||||
webdav_upload, MusicManager,
|
||||
};
|
||||
use network_monitor::network_status;
|
||||
use osd_window::{
|
||||
@@ -281,6 +282,7 @@ pub fn run() {
|
||||
feiniu_get_config,
|
||||
feiniu_list_tracks,
|
||||
feiniu_lyric,
|
||||
feiniu_cover_data,
|
||||
feiniu_media_prefix,
|
||||
feiniu_scan_local,
|
||||
feiniu_cache_status,
|
||||
|
||||
@@ -380,6 +380,28 @@ pub async fn feiniu_lyric(
|
||||
Ok(json!({ "lyric": text }))
|
||||
}
|
||||
|
||||
/// 封面 data URL(Windows SMTC / MediaSession artwork 用):
|
||||
/// Rust 侧取 NAS 封面字节转 base64,规避 WebView 对 artwork 的 CORS 要求。
|
||||
/// 返回 Value 且未标注 specta:前端直接按 JSON 使用(同 music_ping 豁免模式)。
|
||||
#[tauri::command]
|
||||
pub async fn feiniu_cover_data(
|
||||
state: State<'_, MusicManager>,
|
||||
cover_id: String,
|
||||
size: Option<u32>,
|
||||
) -> Result<serde_json::Value, String> {
|
||||
state.feiniu.sync_with_settings(&state.load_settings());
|
||||
let (bytes, ct) = state
|
||||
.feiniu
|
||||
.cover_bytes(&cover_id, size.unwrap_or(320))
|
||||
.await?;
|
||||
use base64::Engine;
|
||||
let data = format!(
|
||||
"data:{ct};base64,{}",
|
||||
base64::engine::general_purpose::STANDARD.encode(bytes)
|
||||
);
|
||||
Ok(json!({ "data": data }))
|
||||
}
|
||||
|
||||
/// 本地媒体地址前缀:{ mediaPrefix }(首次调用惰性启动本地流代理)。
|
||||
#[tauri::command]
|
||||
pub async fn feiniu_media_prefix(
|
||||
|
||||
@@ -315,6 +315,44 @@ impl Feiniu {
|
||||
Ok(extract_lyric_text(&v))
|
||||
}
|
||||
|
||||
/// 封面二进制(MediaSession artwork 用):`GET /music/api/v1/static/cover`。
|
||||
/// 返回 (字节, content-type)。与流代理同款认证注入,但不走代理——
|
||||
/// 前端拿到的是 data URL,规避 WebView 对 artwork 的 CORS 要求。
|
||||
pub async fn cover_bytes(&self, cover_id: &str, size: u32) -> Result<(Vec<u8>, String), String> {
|
||||
let (base, token, access_code) = self.auth_triple();
|
||||
if base.is_empty() || token.is_empty() {
|
||||
return Err("未登录".into());
|
||||
}
|
||||
let (_, client) = self.conn_client();
|
||||
let query = [
|
||||
("coverId".to_string(), cover_id.to_string()),
|
||||
("size".to_string(), size.to_string()),
|
||||
];
|
||||
let mut rb = client.get(format!("{base}/music/api/v1/static/cover")).query(&query);
|
||||
rb = rb.header("cookie", format!("music-token={token}"));
|
||||
if !access_code.is_empty() {
|
||||
use base64::Engine;
|
||||
rb = rb
|
||||
.header(
|
||||
"x-access-code",
|
||||
base64::engine::general_purpose::STANDARD.encode(access_code.as_bytes()),
|
||||
)
|
||||
.header("x-access-source", "app");
|
||||
}
|
||||
let resp = rb.send().await.map_err(|e| format!("请求失败: {e}"))?;
|
||||
if !resp.status().is_success() {
|
||||
return Err(format!("请求失败(HTTP {})", resp.status().as_u16()));
|
||||
}
|
||||
let ct = resp
|
||||
.headers()
|
||||
.get(reqwest::header::CONTENT_TYPE)
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.unwrap_or("image/jpeg")
|
||||
.to_string();
|
||||
let bytes = resp.bytes().await.map_err(|e| format!("读取失败: {e}"))?;
|
||||
Ok((bytes.to_vec(), ct))
|
||||
}
|
||||
|
||||
/// 本地媒体地址前缀:`http://127.0.0.1:<port>/feiniu`。首次调用惰性启动代理。
|
||||
pub async fn media_prefix(&self) -> Result<String, String> {
|
||||
let port = self.ensure_proxy().await?;
|
||||
|
||||
@@ -24,13 +24,14 @@ pub use feiniu::{extract_fn_id, normalize_base_url, resolve_base_url, Feiniu, Fe
|
||||
|
||||
pub use commands::{
|
||||
feiniu_activate_connection, feiniu_cache_clear, feiniu_cache_fetch, feiniu_cache_status,
|
||||
feiniu_delete_connection, feiniu_delete_local, feiniu_fnconnect_resolve, feiniu_get_config,
|
||||
feiniu_list_connections, feiniu_list_tracks, feiniu_login, feiniu_logout, feiniu_lyric,
|
||||
feiniu_media_prefix, feiniu_save_connection, feiniu_scan_local, feiniu_test_connection,
|
||||
music_cancel_runtime_install, music_download, music_download_cancel, music_env_status,
|
||||
music_get_settings, music_get_sources, music_install_runtime, music_parse_playlist, music_ping,
|
||||
music_resolve, music_save_settings, music_search, music_stop_bridge, webdav_delete,
|
||||
webdav_get_secret, webdav_save_secret, webdav_test, webdav_upload,
|
||||
feiniu_cover_data, feiniu_delete_connection, feiniu_delete_local, feiniu_fnconnect_resolve,
|
||||
feiniu_get_config, feiniu_list_connections, feiniu_list_tracks, feiniu_login, feiniu_logout,
|
||||
feiniu_lyric, feiniu_media_prefix, feiniu_save_connection, feiniu_scan_local,
|
||||
feiniu_test_connection, music_cancel_runtime_install, music_download, music_download_cancel,
|
||||
music_env_status, music_get_settings, music_get_sources, music_install_runtime,
|
||||
music_parse_playlist, music_ping, music_resolve, music_save_settings, music_search,
|
||||
music_stop_bridge, webdav_delete, webdav_get_secret, webdav_save_secret, webdav_test,
|
||||
webdav_upload,
|
||||
};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
}
|
||||
],
|
||||
"security": {
|
||||
"csp": "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: asset: http://asset.localhost; font-src 'self' data:; connect-src ipc: http://ipc.localhost; media-src 'self' data: blob:"
|
||||
"csp": "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: asset: http://asset.localhost http: https:; font-src 'self' data:; connect-src ipc: http://ipc.localhost http: https:; media-src 'self' data: blob: file: http: https:"
|
||||
}
|
||||
},
|
||||
"bundle": {
|
||||
|
||||
Reference in New Issue
Block a user