Hand video playback off to a native audio-only stream when the app is backgrounded or locked, with no on-device video decode (UR-040). Adds player_enter/exit_background_audio commands, an audio-only stream URL for video items across the repository layer, and the frontend handoff state machine wired into VideoPlayer. Includes accompanying repository/offline/player refactoring and regenerates the traceability matrix.
48 lines
1.4 KiB
Rust
48 lines
1.4 KiB
Rust
//! Media session state commands.
|
|
//!
|
|
//! TRACES: UR-005 | DR-009
|
|
//!
|
|
//! Read and dismiss the current media session (the Now Playing surface backing
|
|
//! lockscreen/notification controls).
|
|
|
|
use tauri::State;
|
|
|
|
use super::{MediaSessionManagerWrapper, PlayerStateWrapper};
|
|
use crate::player::PlayerStatusEvent;
|
|
|
|
/// Get the current media session state
|
|
#[tauri::command]
|
|
#[specta::specta]
|
|
pub async fn player_get_session(
|
|
session: State<'_, MediaSessionManagerWrapper>,
|
|
) -> Result<crate::player::session::MediaSessionType, String> {
|
|
let manager = session.0.lock().map_err(|e| e.to_string())?;
|
|
Ok(manager.current().clone())
|
|
}
|
|
|
|
/// Dismiss the current media session (returns to Idle)
|
|
#[tauri::command]
|
|
#[specta::specta]
|
|
pub async fn player_dismiss_session(
|
|
session: State<'_, MediaSessionManagerWrapper>,
|
|
player: State<'_, PlayerStateWrapper>,
|
|
) -> Result<(), String> {
|
|
log::info!("[Session] Dismissing current media session");
|
|
|
|
// Dismiss the session
|
|
{
|
|
let mut manager = session.0.lock().map_err(|e| e.to_string())?;
|
|
manager.dismiss();
|
|
}
|
|
|
|
// Emit session changed event
|
|
if let Some(emitter) = player.0.lock().await.event_emitter() {
|
|
let manager = session.0.lock().map_err(|e| e.to_string())?;
|
|
emitter.emit(PlayerStatusEvent::SessionChanged {
|
|
session: manager.current().clone(),
|
|
});
|
|
}
|
|
|
|
Ok(())
|
|
}
|