Background-audio handoff for video + repository/player refactor
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.
This commit is contained in:
@@ -8,16 +8,10 @@ use serde::{Deserialize, Serialize};
|
||||
pub enum DownloadEvent {
|
||||
/// Download has been queued
|
||||
#[serde(rename_all = "camelCase")]
|
||||
Queued {
|
||||
download_id: i64,
|
||||
item_id: String,
|
||||
},
|
||||
Queued { download_id: i64, item_id: String },
|
||||
/// Download has started
|
||||
#[serde(rename_all = "camelCase")]
|
||||
Started {
|
||||
download_id: i64,
|
||||
item_id: String,
|
||||
},
|
||||
Started { download_id: i64, item_id: String },
|
||||
/// Download progress update
|
||||
#[serde(rename_all = "camelCase")]
|
||||
Progress {
|
||||
@@ -43,16 +37,10 @@ pub enum DownloadEvent {
|
||||
},
|
||||
/// Download paused
|
||||
#[serde(rename_all = "camelCase")]
|
||||
Paused {
|
||||
download_id: i64,
|
||||
item_id: String,
|
||||
},
|
||||
Paused { download_id: i64, item_id: String },
|
||||
/// Download cancelled
|
||||
#[serde(rename_all = "camelCase")]
|
||||
Cancelled {
|
||||
download_id: i64,
|
||||
item_id: String,
|
||||
},
|
||||
Cancelled { download_id: i64, item_id: String },
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -98,9 +86,21 @@ mod tests {
|
||||
let json = serde_json::to_string(&event).unwrap();
|
||||
assert!(json.contains("\"type\":\"completed\""));
|
||||
// Verify camelCase field names
|
||||
assert!(json.contains("\"downloadId\":42"), "Expected downloadId (camelCase), got: {}", json);
|
||||
assert!(json.contains("\"itemId\":\"song456\""), "Expected itemId (camelCase), got: {}", json);
|
||||
assert!(json.contains("\"filePath\":"), "Expected filePath (camelCase), got: {}", json);
|
||||
assert!(
|
||||
json.contains("\"downloadId\":42"),
|
||||
"Expected downloadId (camelCase), got: {}",
|
||||
json
|
||||
);
|
||||
assert!(
|
||||
json.contains("\"itemId\":\"song456\""),
|
||||
"Expected itemId (camelCase), got: {}",
|
||||
json
|
||||
);
|
||||
assert!(
|
||||
json.contains("\"filePath\":"),
|
||||
"Expected filePath (camelCase), got: {}",
|
||||
json
|
||||
);
|
||||
|
||||
// Verify roundtrip
|
||||
let deserialized: DownloadEvent = serde_json::from_str(&json).unwrap();
|
||||
|
||||
Reference in New Issue
Block a user