ci / api / api (push) Successful in 43s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 1m19s
ci / desktop / rust (desktop proxy) (push) Failing after 3m34s
ci / ts / ts (packages + web) (push) Failing after 2m49s
release / release (версия и заметки) (push) Successful in 5s
ci / db / db (push) Successful in 40s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m12s
ci / docker / docker (образы собираются — их сервер собирает сам при обновлении) (push) Successful in 1m28s
release / android (APK в релиз) (push) Failing after 2m0s
EOF Co-authored-by: Cursor <cursoragent@cursor.com>
63 lines
2.3 KiB
Rust
63 lines
2.3 KiB
Rust
use souvlaki::{MediaControlEvent, MediaControls, MediaMetadata, MediaPlayback, PlatformConfig};
|
|
use std::sync::Mutex;
|
|
use tauri::{AppHandle, Emitter, WebviewWindow};
|
|
|
|
pub struct Media {
|
|
controls: Mutex<Option<MediaControls>>,
|
|
}
|
|
|
|
impl Media {
|
|
pub fn new() -> Self {
|
|
Self { controls: Mutex::new(None) }
|
|
}
|
|
|
|
pub fn attach(&self, app: AppHandle, window: &WebviewWindow) -> Result<(), String> {
|
|
#[cfg(target_os = "windows")]
|
|
let hwnd = window.hwnd().ok().map(|h| h.0 as *mut std::ffi::c_void);
|
|
#[cfg(not(target_os = "windows"))]
|
|
let hwnd = {
|
|
let _ = window;
|
|
None
|
|
};
|
|
let mut controls = MediaControls::new(PlatformConfig {
|
|
dbus_name: "app.pipu.music.desktop",
|
|
display_name: "Pipu Music",
|
|
hwnd,
|
|
})
|
|
.map_err(|e| format!("{e:?}"))?;
|
|
let handle = app.clone();
|
|
controls
|
|
.attach(move |event| {
|
|
let name = match event {
|
|
MediaControlEvent::Play => "play",
|
|
MediaControlEvent::Pause => "pause",
|
|
MediaControlEvent::Toggle => "toggle",
|
|
MediaControlEvent::Next => "next",
|
|
MediaControlEvent::Previous => "previous",
|
|
MediaControlEvent::Stop => "stop",
|
|
_ => return,
|
|
};
|
|
let _ = handle.emit("media", name);
|
|
})
|
|
.map_err(|e| format!("{e:?}"))?;
|
|
*self.controls.lock().map_err(|e| e.to_string())? = Some(controls);
|
|
Ok(())
|
|
}
|
|
|
|
pub fn set(&self, title: &str, artist: &str, album: &str, cover_url: Option<&str>, playing: bool) -> Result<(), String> {
|
|
let mut slot = self.controls.lock().map_err(|e| e.to_string())?;
|
|
let Some(controls) = slot.as_mut() else { return Ok(()); };
|
|
controls
|
|
.set_metadata(MediaMetadata {
|
|
title: Some(title),
|
|
artist: Some(artist),
|
|
album: Some(album),
|
|
cover_url,
|
|
duration: None,
|
|
})
|
|
.map_err(|e| format!("{e:?}"))?;
|
|
let playback = if playing { MediaPlayback::Playing { progress: None } } else { MediaPlayback::Paused { progress: None } };
|
|
controls.set_playback(playback).map_err(|e| format!("{e:?}"))
|
|
}
|
|
}
|