diff --git a/index.html b/index.html index 99f203f..7723bc8 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ - Tauri + Vue + Typescript App + Thing diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 862e5ae..3d7c2b3 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -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, diff --git a/src-tauri/src/music/commands.rs b/src-tauri/src/music/commands.rs index de76f9b..c172b13 100644 --- a/src-tauri/src/music/commands.rs +++ b/src-tauri/src/music/commands.rs @@ -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, +) -> Result { + 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( diff --git a/src-tauri/src/music/feiniu/mod.rs b/src-tauri/src/music/feiniu/mod.rs index 5833c85..47452cc 100644 --- a/src-tauri/src/music/feiniu/mod.rs +++ b/src-tauri/src/music/feiniu/mod.rs @@ -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, 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:/feiniu`。首次调用惰性启动代理。 pub async fn media_prefix(&self) -> Result { let port = self.ensure_proxy().await?; diff --git a/src-tauri/src/music/mod.rs b/src-tauri/src/music/mod.rs index a13ddaa..37115d6 100644 --- a/src-tauri/src/music/mod.rs +++ b/src-tauri/src/music/mod.rs @@ -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}; diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 0d5726f..aff9de2 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -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": { diff --git a/src/stores/feiniuStore.ts b/src/stores/feiniuStore.ts index 830b297..fd23f23 100644 --- a/src/stores/feiniuStore.ts +++ b/src/stores/feiniuStore.ts @@ -96,14 +96,14 @@ function writeLS(key: string, value: string) { } } -/** 把浏览器抛出的播放异常翻译成可读文案 */ -function describePlayError(e: unknown): string { - const name = (e as { name?: string })?.name ?? '' - if (name === 'NotSupportedError') return '该音频无法播放:格式不支持或链接已失效' - if (name === 'NotAllowedError') return '播放被浏览器策略阻止,请再次点击播放' - if (name === 'AbortError') return '播放已中断' - return `播放失败:${e instanceof Error ? e.message : String(e)}` -} + /** 把浏览器抛出的播放异常翻译成可读文案 */ + function describePlayError(e: unknown): string { + const name = (e as { name?: string })?.name ?? '' + if (name === 'NotSupportedError') return '该音频无法播放:格式不支持或链接已失效' + if (name === 'NotAllowedError') return '播放被浏览器策略阻止,请再次点击播放' + if (name === 'AbortError') return '播放已中断' + return `播放失败:${e instanceof Error ? e.message : String(e)}` + } export const useFeiniuStore = defineStore('feiniu', () => { // ===== 连接 ===== @@ -185,6 +185,100 @@ export const useFeiniuStore = defineStore('feiniu', () => { const shufflePool = ref([]) const historyStack = ref([]) + // ===== Windows 系统媒体(SMTC)集成 ===== + // WebView2 会把页面媒体暴露给系统媒体浮层/媒体键,元数据需通过 MediaSession API 提供; + // 不提供时系统显示的是 document.title(此前为 "Tauri+Vue+Typescript App")。 + + /** 封面 data URL 缓存(coverId → dataUrl),避免同一首歌重复取封面 */ + const smtcCoverCache = new Map() + /** SMTC 进度上报节流(timeupdate ~4Hz,1s 一次足够) */ + let smtcLastPosAt = 0 + + /** 设置系统媒体浮层的歌曲信息(歌名/歌手/专辑/封面)。封面为飞牛曲目时经 + * Rust 命令取字节转 data URL——MediaSession artwork 由 WebView 以 CORS 模式 + * 拉取,代理地址无 CORS 头会失败,data URL 可绕过。 */ + function updateMediaSession(item: PlayableItem) { + if (!('mediaSession' in navigator)) return + const base = { + title: item.title, + artist: item.artistNames || '未知歌手', + album: item.album || '' + } + if (item.source === 'feiniu' && item.coverId) { + const key = item.coverId + const cached = smtcCoverCache.get(key) + // 歌名/歌手立即上屏,封面就绪后补挂 + navigator.mediaSession.metadata = new MediaMetadata({ + ...base, + artwork: cached ? [{ src: cached, sizes: '320x320' }] : [] + }) + if (!cached) { + invoke<{ data: string }>('feiniu_cover_data', { coverId: key, size: 320 }) + .then((r) => { + if (!r?.data) return + if (smtcCoverCache.size > 50) smtcCoverCache.clear() + smtcCoverCache.set(key, r.data) + // 播放期间用户可能已切歌:仅当仍是这首时才刷新封面 + const cur = navigator.mediaSession.metadata + if (cur?.title === item.title) { + navigator.mediaSession.metadata = new MediaMetadata({ + ...base, + artwork: [{ src: r.data, sizes: '320x320' }] + }) + } + }) + .catch(() => { + /* 封面取不到就只显示文字信息 */ + }) + } + return + } + // preview 源有直链封面;local/无封面源仅文字信息 + const artwork: MediaImage[] = [] + if (item.coverUrl) artwork.push({ src: item.coverUrl, sizes: '320x320' }) + navigator.mediaSession.metadata = new MediaMetadata({ ...base, artwork }) + } + + /** 注册系统媒体键/浮层按钮动作(一次性) */ + function setupMediaSessionHandlers(a: HTMLAudioElement) { + if (!('mediaSession' in navigator)) return + const ms = navigator.mediaSession + try { + ms.setActionHandler('play', () => void a.play().catch(() => {})) + ms.setActionHandler('pause', () => a.pause()) + ms.setActionHandler('previoustrack', () => prev()) + ms.setActionHandler('nexttrack', () => next()) + ms.setActionHandler('seekbackward', (d) => seek(Math.max(0, position.value - (d?.seekOffset ?? 10)))) + ms.setActionHandler('seekforward', (d) => seek(position.value + (d?.seekOffset ?? 10))) + ms.setActionHandler('seekto', (d) => { + if (d.seekTime != null) seek(d.seekTime) + }) + } catch { + /* 个别动作类型 WebView 不支持时忽略 */ + } + } + + function setSmtcState(state: 'playing' | 'paused') { + if ('mediaSession' in navigator) navigator.mediaSession.playbackState = state + } + + /** 同步播放进度到系统媒体浮层(SMTC 时间轴)。必须在时长已知后调用, + * 否则浮层只显示歌名没有进度条;position 越界会被 WebView 拒绝,做夹取。 */ + function updateSmtcPosition() { + if (!('mediaSession' in navigator)) return + const d = duration.value + if (!isFinite(d) || d <= 0) return + try { + navigator.mediaSession.setPositionState({ + duration: d, + playbackRate: audioEl?.playbackRate || 1, + position: Math.min(Math.max(position.value, 0), d) + }) + } catch { + /* 元数据切换瞬间的非法参数(如新歌时长未就绪)忽略 */ + } + } + function computeBuffered(a: HTMLAudioElement): number { const d = a.duration if (!isFinite(d) || d <= 0 || a.buffered.length === 0) return 0 @@ -204,28 +298,47 @@ export const useFeiniuStore = defineStore('feiniu', () => { a.addEventListener('loadedmetadata', () => { duration.value = isFinite(a.duration) ? a.duration : 0 bufferedPercent.value = computeBuffered(a) + updateSmtcPosition() }) a.addEventListener('durationchange', () => { duration.value = isFinite(a.duration) ? a.duration : 0 + updateSmtcPosition() }) - a.addEventListener('timeupdate', () => (position.value = a.currentTime)) + a.addEventListener('timeupdate', () => { + position.value = a.currentTime + const now = Date.now() + if (now - smtcLastPosAt >= 1000) { + smtcLastPosAt = now + updateSmtcPosition() + } + }) + a.addEventListener('seeked', () => updateSmtcPosition()) a.addEventListener('progress', () => (bufferedPercent.value = computeBuffered(a))) a.addEventListener('waiting', () => (loadingPlay.value = true)) a.addEventListener('canplay', () => (loadingPlay.value = false)) a.addEventListener('playing', () => { loadingPlay.value = false playing.value = true + setSmtcState('playing') + }) + a.addEventListener('play', () => { + playing.value = true + setSmtcState('playing') + }) + a.addEventListener('pause', () => { + playing.value = false + setSmtcState('paused') }) - a.addEventListener('play', () => (playing.value = true)) - a.addEventListener('pause', () => (playing.value = false)) a.addEventListener('ended', () => onEnded()) a.addEventListener('error', () => { // 主动清空 src 时也会触发 error,此时不应报错 if (!a.getAttribute('src')) return loadingPlay.value = false playing.value = false + setSmtcState('paused') playError.value = '音频加载失败:网络不可达或链接已失效' }) + setupMediaSessionHandlers(a) audioEl = a } return audioEl @@ -238,6 +351,7 @@ export const useFeiniuStore = defineStore('feiniu', () => { position.value = 0 duration.value = 0 bufferedPercent.value = 0 + setSmtcState('paused') if (audioEl) { audioEl.pause() audioEl.removeAttribute('src') @@ -805,6 +919,7 @@ export const useFeiniuStore = defineStore('feiniu', () => { const t = current.value if (!t) return preview.value = null + updateMediaSession(t) if (t.source === 'feiniu') { void loadLyric(t.guid) } else { @@ -872,6 +987,7 @@ export const useFeiniuStore = defineStore('feiniu', () => { const a = ensureAudio() a.pause() preview.value = { ...item, source: 'preview' } + updateMediaSession(preview.value) lyricLines.value = [] lyricRaw = '' lyricIdx = -1 diff --git a/temp/icon2.png b/temp/icon2.png deleted file mode 100644 index 89c96e3..0000000 Binary files a/temp/icon2.png and /dev/null differ diff --git a/temp/icon_s.png b/temp/icon_s.png deleted file mode 100644 index d0b7388..0000000 Binary files a/temp/icon_s.png and /dev/null differ diff --git a/temp/snap2.json b/temp/snap2.json deleted file mode 100644 index 2062d94..0000000 --- a/temp/snap2.json +++ /dev/null @@ -1 +0,0 @@ -{"schemaVersion":1,"timestamp":1785393390698,"coldStartMs":346.1,"isAdmin":true,"ready":true,"groups":[{"id":"cpu","name":"CPU","sensors":[{"id":"cpu/amd_ryzen_7_9800x3d/load/cpu_core_#1","name":"CPU Core #1","type":"load","hardwareName":"AMD Ryzen 7 9800X3D","value":19.05,"unit":"%"},{"id":"cpu/amd_ryzen_7_9800x3d/load/cpu_core_#2","name":"CPU Core #2","type":"load","hardwareName":"AMD Ryzen 7 9800X3D","value":9.52,"unit":"%"},{"id":"cpu/amd_ryzen_7_9800x3d/load/cpu_core_#3","name":"CPU Core #3","type":"load","hardwareName":"AMD Ryzen 7 9800X3D","value":1.59,"unit":"%"},{"id":"cpu/amd_ryzen_7_9800x3d/load/cpu_core_#4","name":"CPU Core #4","type":"load","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"%"},{"id":"cpu/amd_ryzen_7_9800x3d/load/cpu_core_#5","name":"CPU Core #5","type":"load","hardwareName":"AMD Ryzen 7 9800X3D","value":1.59,"unit":"%"},{"id":"cpu/amd_ryzen_7_9800x3d/load/cpu_core_#6","name":"CPU Core #6","type":"load","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"%"},{"id":"cpu/amd_ryzen_7_9800x3d/load/cpu_core_#7","name":"CPU Core #7","type":"load","hardwareName":"AMD Ryzen 7 9800X3D","value":11.11,"unit":"%"},{"id":"cpu/amd_ryzen_7_9800x3d/load/cpu_core_#8","name":"CPU Core #8","type":"load","hardwareName":"AMD Ryzen 7 9800X3D","value":3.17,"unit":"%"},{"id":"cpu/amd_ryzen_7_9800x3d/load/cpu_core_#9","name":"CPU Core #9","type":"load","hardwareName":"AMD Ryzen 7 9800X3D","value":4.76,"unit":"%"},{"id":"cpu/amd_ryzen_7_9800x3d/load/cpu_core_#10","name":"CPU Core #10","type":"load","hardwareName":"AMD Ryzen 7 9800X3D","value":6.35,"unit":"%"},{"id":"cpu/amd_ryzen_7_9800x3d/load/cpu_core_#11","name":"CPU Core #11","type":"load","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"%"},{"id":"cpu/amd_ryzen_7_9800x3d/load/cpu_core_#12","name":"CPU Core #12","type":"load","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"%"},{"id":"cpu/amd_ryzen_7_9800x3d/load/cpu_core_#13","name":"CPU Core #13","type":"load","hardwareName":"AMD Ryzen 7 9800X3D","value":1.59,"unit":"%"},{"id":"cpu/amd_ryzen_7_9800x3d/load/cpu_core_#14","name":"CPU Core #14","type":"load","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"%"},{"id":"cpu/amd_ryzen_7_9800x3d/load/cpu_core_#15","name":"CPU Core #15","type":"load","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"%"},{"id":"cpu/amd_ryzen_7_9800x3d/load/cpu_core_#16","name":"CPU Core #16","type":"load","hardwareName":"AMD Ryzen 7 9800X3D","value":1.59,"unit":"%"},{"id":"cpu/amd_ryzen_7_9800x3d/load/cpu_total","name":"CPU Total","type":"load","hardwareName":"AMD Ryzen 7 9800X3D","value":3.77,"unit":"%"},{"id":"cpu/amd_ryzen_7_9800x3d/load/cpu_core_max","name":"CPU Core Max","type":"load","hardwareName":"AMD Ryzen 7 9800X3D","value":19.05,"unit":"%"},{"id":"cpu/amd_ryzen_7_9800x3d/power/package","name":"Package","type":"power","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"W"},{"id":"cpu/amd_ryzen_7_9800x3d/clock/cores_(average)","name":"Cores (Average)","type":"clock","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"MHz"},{"id":"cpu/amd_ryzen_7_9800x3d/clock/cores_(average_effective)","name":"Cores (Average Effective)","type":"clock","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"MHz"},{"id":"cpu/amd_ryzen_7_9800x3d/clock/core_#1","name":"Core #1","type":"clock","hardwareName":"AMD Ryzen 7 9800X3D","unit":"MHz"},{"id":"cpu/amd_ryzen_7_9800x3d/clock/core_#1_(effective)","name":"Core #1 (Effective)","type":"clock","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"MHz"},{"id":"cpu/amd_ryzen_7_9800x3d/power/core_#1_(smu)","name":"Core #1 (SMU)","type":"power","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"W"},{"id":"cpu/amd_ryzen_7_9800x3d/clock/core_#2","name":"Core #2","type":"clock","hardwareName":"AMD Ryzen 7 9800X3D","unit":"MHz"},{"id":"cpu/amd_ryzen_7_9800x3d/clock/core_#2_(effective)","name":"Core #2 (Effective)","type":"clock","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"MHz"},{"id":"cpu/amd_ryzen_7_9800x3d/power/core_#2_(smu)","name":"Core #2 (SMU)","type":"power","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"W"},{"id":"cpu/amd_ryzen_7_9800x3d/clock/core_#3","name":"Core #3","type":"clock","hardwareName":"AMD Ryzen 7 9800X3D","unit":"MHz"},{"id":"cpu/amd_ryzen_7_9800x3d/clock/core_#3_(effective)","name":"Core #3 (Effective)","type":"clock","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"MHz"},{"id":"cpu/amd_ryzen_7_9800x3d/power/core_#3_(smu)","name":"Core #3 (SMU)","type":"power","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"W"},{"id":"cpu/amd_ryzen_7_9800x3d/clock/core_#4","name":"Core #4","type":"clock","hardwareName":"AMD Ryzen 7 9800X3D","unit":"MHz"},{"id":"cpu/amd_ryzen_7_9800x3d/clock/core_#4_(effective)","name":"Core #4 (Effective)","type":"clock","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"MHz"},{"id":"cpu/amd_ryzen_7_9800x3d/power/core_#4_(smu)","name":"Core #4 (SMU)","type":"power","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"W"},{"id":"cpu/amd_ryzen_7_9800x3d/clock/core_#5","name":"Core #5","type":"clock","hardwareName":"AMD Ryzen 7 9800X3D","unit":"MHz"},{"id":"cpu/amd_ryzen_7_9800x3d/clock/core_#5_(effective)","name":"Core #5 (Effective)","type":"clock","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"MHz"},{"id":"cpu/amd_ryzen_7_9800x3d/power/core_#5_(smu)","name":"Core #5 (SMU)","type":"power","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"W"},{"id":"cpu/amd_ryzen_7_9800x3d/clock/core_#6","name":"Core #6","type":"clock","hardwareName":"AMD Ryzen 7 9800X3D","unit":"MHz"},{"id":"cpu/amd_ryzen_7_9800x3d/clock/core_#6_(effective)","name":"Core #6 (Effective)","type":"clock","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"MHz"},{"id":"cpu/amd_ryzen_7_9800x3d/power/core_#6_(smu)","name":"Core #6 (SMU)","type":"power","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"W"},{"id":"cpu/amd_ryzen_7_9800x3d/clock/core_#7","name":"Core #7","type":"clock","hardwareName":"AMD Ryzen 7 9800X3D","unit":"MHz"},{"id":"cpu/amd_ryzen_7_9800x3d/clock/core_#7_(effective)","name":"Core #7 (Effective)","type":"clock","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"MHz"},{"id":"cpu/amd_ryzen_7_9800x3d/power/core_#7_(smu)","name":"Core #7 (SMU)","type":"power","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"W"},{"id":"cpu/amd_ryzen_7_9800x3d/clock/core_#8","name":"Core #8","type":"clock","hardwareName":"AMD Ryzen 7 9800X3D","unit":"MHz"},{"id":"cpu/amd_ryzen_7_9800x3d/clock/core_#8_(effective)","name":"Core #8 (Effective)","type":"clock","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"MHz"},{"id":"cpu/amd_ryzen_7_9800x3d/power/core_#8_(smu)","name":"Core #8 (SMU)","type":"power","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"W"},{"id":"cpu/amd_ryzen_7_9800x3d/temperature/core_(tctl/tdie)","name":"Core (Tctl/Tdie)","type":"temperature","hardwareName":"AMD Ryzen 7 9800X3D","value":0,"unit":"\u00B0C"}]},{"id":"memory","name":"Memory","sensors":[{"id":"memory/virtual_memory/data/memory_used","name":"Memory Used","type":"data","hardwareName":"Virtual Memory","value":29.933598,"unit":"GB"},{"id":"memory/virtual_memory/data/memory_available","name":"Memory Available","type":"data","hardwareName":"Virtual Memory","value":22.446678,"unit":"GB"},{"id":"memory/virtual_memory/load/memory","name":"Memory","type":"load","hardwareName":"Virtual Memory","value":57.146698,"unit":"%"},{"id":"memory/total_memory/data/memory_used","name":"Memory Used","type":"data","hardwareName":"Total Memory","value":12.919495,"unit":"GB"},{"id":"memory/total_memory/data/memory_available","name":"Memory Available","type":"data","hardwareName":"Total Memory","value":18.460781,"unit":"GB"},{"id":"memory/total_memory/load/memory","name":"Memory","type":"load","hardwareName":"Total Memory","value":41.17075,"unit":"%"}]},{"id":"storage","name":"Storage","sensors":[{"id":"storage/samsung_ssd_970_evo_plus_2tb/temperature/temperature","name":"Temperature","type":"temperature","hardwareName":"Samsung SSD 970 EVO Plus 2TB","value":40,"unit":"\u00B0C"},{"id":"storage/samsung_ssd_970_evo_plus_2tb/temperature/temperature_2","name":"Temperature 2","type":"temperature","hardwareName":"Samsung SSD 970 EVO Plus 2TB","value":46.850006,"unit":"\u00B0C"},{"id":"storage/samsung_ssd_970_evo_plus_2tb/temperature/temperature_warning","name":"Temperature warning","type":"temperature","hardwareName":"Samsung SSD 970 EVO Plus 2TB","value":81,"unit":"\u00B0C"},{"id":"storage/samsung_ssd_970_evo_plus_2tb/temperature/temperature_critical","name":"Temperature critical","type":"temperature","hardwareName":"Samsung SSD 970 EVO Plus 2TB","value":84,"unit":"\u00B0C"},{"id":"storage/samsung_ssd_970_evo_plus_2tb/data/data_read","name":"Data read","type":"data","hardwareName":"Samsung SSD 970 EVO Plus 2TB","value":66645,"unit":"GB"},{"id":"storage/samsung_ssd_970_evo_plus_2tb/data/data_written","name":"Data written","type":"data","hardwareName":"Samsung SSD 970 EVO Plus 2TB","value":37186,"unit":"GB"},{"id":"storage/samsung_ssd_970_evo_plus_2tb/load/used_space","name":"Used Space","type":"load","hardwareName":"Samsung SSD 970 EVO Plus 2TB","value":-922153000,"unit":"%"},{"id":"storage/samsung_ssd_970_evo_plus_2tb/data/free_space","name":"Free Space","type":"data","hardwareName":"Samsung SSD 970 EVO Plus 2TB","value":1.8446744E+10,"unit":"GB"},{"id":"storage/samsung_ssd_970_evo_plus_2tb/data/total_space","name":"Total Space","type":"data","hardwareName":"Samsung SSD 970 EVO Plus 2TB","value":2000.3989,"unit":"GB"},{"id":"storage/samsung_ssd_970_evo_plus_2tb/load/read_activity","name":"Read Activity","type":"load","hardwareName":"Samsung SSD 970 EVO Plus 2TB","value":0,"unit":"%"},{"id":"storage/samsung_ssd_970_evo_plus_2tb/load/write_activity","name":"Write Activity","type":"load","hardwareName":"Samsung SSD 970 EVO Plus 2TB","value":0,"unit":"%"},{"id":"storage/samsung_ssd_970_evo_plus_2tb/load/total_activity","name":"Total Activity","type":"load","hardwareName":"Samsung SSD 970 EVO Plus 2TB","value":0,"unit":"%"},{"id":"storage/samsung_ssd_970_evo_plus_500gb/temperature/temperature","name":"Temperature","type":"temperature","hardwareName":"Samsung SSD 970 EVO Plus 500GB","value":43,"unit":"\u00B0C"},{"id":"storage/samsung_ssd_970_evo_plus_500gb/temperature/temperature_2","name":"Temperature 2","type":"temperature","hardwareName":"Samsung SSD 970 EVO Plus 500GB","value":43.850006,"unit":"\u00B0C"},{"id":"storage/samsung_ssd_970_evo_plus_500gb/temperature/temperature_warning","name":"Temperature warning","type":"temperature","hardwareName":"Samsung SSD 970 EVO Plus 500GB","value":84,"unit":"\u00B0C"},{"id":"storage/samsung_ssd_970_evo_plus_500gb/temperature/temperature_critical","name":"Temperature critical","type":"temperature","hardwareName":"Samsung SSD 970 EVO Plus 500GB","value":84,"unit":"\u00B0C"},{"id":"storage/samsung_ssd_970_evo_plus_500gb/data/data_read","name":"Data read","type":"data","hardwareName":"Samsung SSD 970 EVO Plus 500GB","value":68692,"unit":"GB"},{"id":"storage/samsung_ssd_970_evo_plus_500gb/data/data_written","name":"Data written","type":"data","hardwareName":"Samsung SSD 970 EVO Plus 500GB","value":57143,"unit":"GB"},{"id":"storage/samsung_ssd_970_evo_plus_500gb/load/used_space","name":"Used Space","type":"load","hardwareName":"Samsung SSD 970 EVO Plus 500GB","value":63.86202,"unit":"%"},{"id":"storage/samsung_ssd_970_evo_plus_500gb/data/free_space","name":"Free Space","type":"data","hardwareName":"Samsung SSD 970 EVO Plus 500GB","value":180.72888,"unit":"GB"},{"id":"storage/samsung_ssd_970_evo_plus_500gb/data/total_space","name":"Total Space","type":"data","hardwareName":"Samsung SSD 970 EVO Plus 500GB","value":500.10785,"unit":"GB"},{"id":"storage/samsung_ssd_970_evo_plus_500gb/load/read_activity","name":"Read Activity","type":"load","hardwareName":"Samsung SSD 970 EVO Plus 500GB","value":0,"unit":"%"},{"id":"storage/samsung_ssd_970_evo_plus_500gb/load/write_activity","name":"Write Activity","type":"load","hardwareName":"Samsung SSD 970 EVO Plus 500GB","value":0.041056305,"unit":"%"},{"id":"storage/samsung_ssd_970_evo_plus_500gb/load/total_activity","name":"Total Activity","type":"load","hardwareName":"Samsung SSD 970 EVO Plus 500GB","value":0,"unit":"%"},{"id":"storage/zss11da02c/temperature/temperature","name":"Temperature","type":"temperature","hardwareName":"ZSS11DA02C","value":32,"unit":"\u00B0C"},{"id":"storage/zss11da02c/load/used_space","name":"Used Space","type":"load","hardwareName":"ZSS11DA02C","value":43.86588,"unit":"%"},{"id":"storage/zss11da02c/data/free_space","name":"Free Space","type":"data","hardwareName":"ZSS11DA02C","value":287.46854,"unit":"GB"},{"id":"storage/zss11da02c/data/total_space","name":"Total Space","type":"data","hardwareName":"ZSS11DA02C","value":512.11017,"unit":"GB"},{"id":"storage/zss11da02c/load/read_activity","name":"Read Activity","type":"load","hardwareName":"ZSS11DA02C","value":0,"unit":"%"},{"id":"storage/zss11da02c/load/write_activity","name":"Write Activity","type":"load","hardwareName":"ZSS11DA02C","value":0,"unit":"%"},{"id":"storage/zss11da02c/load/total_activity","name":"Total Activity","type":"load","hardwareName":"ZSS11DA02C","value":0.03464339,"unit":"%"}]},{"id":"gpuamd","name":"GpuAmd","sensors":[{"id":"gpuamd/amd_radeon_rx_7900_xt/load/d3d_3d","name":"D3D 3D","type":"load","hardwareName":"AMD Radeon RX 7900 XT","value":14.1529455,"unit":"%"},{"id":"gpuamd/amd_radeon_rx_7900_xt/load/d3d_copy","name":"D3D Copy","type":"load","hardwareName":"AMD Radeon RX 7900 XT","value":0,"unit":"%"},{"id":"gpuamd/amd_radeon_rx_7900_xt/load/d3d_compute_0","name":"D3D Compute 0","type":"load","hardwareName":"AMD Radeon RX 7900 XT","value":0,"unit":"%"},{"id":"gpuamd/amd_radeon_rx_7900_xt/load/d3d_copy","name":"D3D Copy","type":"load","hardwareName":"AMD Radeon RX 7900 XT","value":0.010940037,"unit":"%"},{"id":"gpuamd/amd_radeon_rx_7900_xt/load/d3d_timer_0","name":"D3D Timer 0","type":"load","hardwareName":"AMD Radeon RX 7900 XT","value":0,"unit":"%"},{"id":"gpuamd/amd_radeon_rx_7900_xt/load/d3d_security_1","name":"D3D Security 1","type":"load","hardwareName":"AMD Radeon RX 7900 XT","value":0,"unit":"%"},{"id":"gpuamd/amd_radeon_rx_7900_xt/load/d3d_video_jpeg_0","name":"D3D Video JPEG 0","type":"load","hardwareName":"AMD Radeon RX 7900 XT","value":0,"unit":"%"},{"id":"gpuamd/amd_radeon_rx_7900_xt/load/d3d_video_codec_engine","name":"D3D Video Codec Engine","type":"load","hardwareName":"AMD Radeon RX 7900 XT","value":10.0678215,"unit":"%"},{"id":"gpuamd/amd_radeon_rx_7900_xt/power/gpu_package","name":"GPU Package","type":"power","hardwareName":"AMD Radeon RX 7900 XT","value":103,"unit":"W"},{"id":"gpuamd/amd_radeon_rx_7900_xt/clock/gpu_core","name":"GPU Core","type":"clock","hardwareName":"AMD Radeon RX 7900 XT","value":1444,"unit":"MHz"},{"id":"gpuamd/amd_radeon_rx_7900_xt/clock/gpu_memory","name":"GPU Memory","type":"clock","hardwareName":"AMD Radeon RX 7900 XT","value":2487,"unit":"MHz"},{"id":"gpuamd/amd_radeon_rx_7900_xt/temperature/gpu_core","name":"GPU Core","type":"temperature","hardwareName":"AMD Radeon RX 7900 XT","value":54,"unit":"\u00B0C"},{"id":"gpuamd/amd_radeon_rx_7900_xt/temperature/gpu_memory","name":"GPU Memory","type":"temperature","hardwareName":"AMD Radeon RX 7900 XT","value":68,"unit":"\u00B0C"},{"id":"gpuamd/amd_radeon_rx_7900_xt/temperature/gpu_hot_spot","name":"GPU Hot Spot","type":"temperature","hardwareName":"AMD Radeon RX 7900 XT","value":62,"unit":"\u00B0C"},{"id":"gpuamd/amd_radeon_rx_7900_xt/load/gpu_core","name":"GPU Core","type":"load","hardwareName":"AMD Radeon RX 7900 XT","value":34,"unit":"%"},{"id":"gpuamd/amd_radeon_rx_7900_xt/load/gpu_memory","name":"GPU Memory","type":"load","hardwareName":"AMD Radeon RX 7900 XT","value":5,"unit":"%"}]}]} \ No newline at end of file diff --git a/temp/snapshot.json b/temp/snapshot.json deleted file mode 100644 index 3e0b7fe..0000000 --- a/temp/snapshot.json +++ /dev/null @@ -1 +0,0 @@ -{"error":"internal","message":".NET number values such as positive and negative infinity cannot be written as valid JSON. To make it work when using 'JsonSerializer', consider specifying 'JsonNumberHandling.AllowNamedFloatingPointLiterals' (see https://docs.microsoft.com/dotnet/api/system.text.json.serialization.jsonnumberhandling)."} \ No newline at end of file