tanuki_common/capabilities/
media.rs1use alloc::{string::String, vec::Vec};
2
3use serde::{Deserialize, Serialize};
4
5use crate::{Property, property};
6
7pub trait MediaProperty: Property {}
8
9#[property(MediaProperty, State, key = "capabilities")]
10#[derive(Default)]
11#[non_exhaustive]
12pub struct MediaCapabilities {
13 pub play: bool,
14 pub pause: bool,
15 pub stop: bool,
16 pub next: bool,
17 pub previous: bool,
18 pub seek: bool,
19 pub repeat: bool,
20 pub shuffle: bool,
21}
22
23#[property(MediaProperty, State, key = "state")]
24#[derive(Default)]
25#[non_exhaustive]
26pub struct MediaState {
27 pub status: MediaStatus,
28 pub duration_ms: Option<u64>,
29 pub position_ms: Option<MediaPosition>,
30 pub repeat: Repeat,
31 pub shuffle: bool,
32 pub info: MediaInfo,
33 pub message: Option<String>,
34}
35
36#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
37#[serde(rename_all = "snake_case")]
38pub enum MediaStatus {
39 Playing,
40 Paused,
41 Stopped,
42 Buffering,
43 Idle,
44 #[default]
45 Unknown,
46}
47
48#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
49pub struct MediaPosition {
50 pub position_ms: i64,
51 pub timestamp_ms: i64,
52 pub rate: f32,
53}
54
55impl MediaPosition {
56 pub fn current_position(&self, current_timestamp_ms: i64) -> i64 {
57 let elapsed_ms = ((current_timestamp_ms - self.timestamp_ms) as f32 * self.rate) as i64;
58 self.position_ms + elapsed_ms
59 }
60}
61
62#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
63#[serde(rename_all = "snake_case")]
64pub enum Repeat {
65 #[default]
66 Off,
67 One,
68 All,
69}
70
71#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
72#[non_exhaustive]
73pub struct MediaInfo {
74 pub title: Option<String>,
75 pub artists: Vec<String>,
76 pub album: Option<String>,
77 pub track_number: Option<u32>,
78 pub disc_number: Option<u32>,
79 pub genre: Option<String>,
80 pub artwork_url: Option<String>,
81 pub url: Option<String>,
82 pub live: bool,
83}
84
85#[property(MediaProperty, Command, key = "command")]
86#[serde(tag = "type", rename_all = "snake_case")]
87#[non_exhaustive]
88pub enum MediaCommand {
89 Play,
90 Pause,
91 PlayPause,
92 Stop,
93 Next,
94 Previous,
95 Seek { position_ms: u64 },
96 SetRepeat { repeat: Repeat },
97 SetShuffle { shuffle: bool },
98}