cast_sender/
media_controller.rs1use std::sync::Arc;
2
3use smol::lock::Mutex;
4
5use crate::namespace::media::*;
6use crate::{App, Error, Payload, Receiver, Response};
7
8#[derive(Clone, Debug)]
9pub struct MediaController {
10 app: App,
11 receiver: Receiver,
12
13 media_session_id: Arc<Mutex<i32>>,
14}
15
16impl MediaController {
17 pub fn new(app: App, receiver: Receiver) -> Result<Self, Error> {
18 if !app
19 .namespaces
20 .contains(&crate::namespace::NamespaceUrn::Media)
21 {
22 return Err(Error::UnsupportedNamespace);
23 }
24
25 Ok(Self {
26 app,
27 receiver,
28 media_session_id: Arc::default(),
29 })
30 }
31
32 pub async fn load<P: Into<LoadRequestData>>(&self, load_request: P) -> Result<(), Error> {
33 let response = self
34 .receiver
35 .send_request(&self.app, Media::Load(load_request.into()))
36 .await?;
37
38 Self::handle_error(&response)?;
39
40 if let Payload::Media(Media::MediaStatus(response_data)) = response.payload {
41 *self.media_session_id.lock().await = response_data.first().media_session_id;
42 Ok(())
43 } else {
44 Err(Error::NoResponse)
45 }
46 }
47
48 pub async fn start(&self) -> Result<(), Error> {
49 let response = self
50 .receiver
51 .send_request(
52 &self.app,
53 Media::Play(RequestData {
54 media_session_id: Some(*self.media_session_id.lock().await),
55 }),
56 )
57 .await?;
58
59 Self::handle_error(&response)?;
60 Ok(())
61 }
62
63 pub async fn stop(&self) -> Result<(), Error> {
64 let response = self
65 .receiver
66 .send_request(
67 &self.app,
68 Media::Stop(RequestData {
69 media_session_id: Some(*self.media_session_id.lock().await),
70 }),
71 )
72 .await?;
73
74 Self::handle_error(&response)?;
75 Ok(())
76 }
77
78 pub async fn pause(&self) -> Result<(), Error> {
79 let response = self
80 .receiver
81 .send_request(
82 &self.app,
83 Media::Pause(RequestData {
84 media_session_id: Some(*self.media_session_id.lock().await),
85 }),
86 )
87 .await?;
88
89 Self::handle_error(&response)?;
90 Ok(())
91 }
92
93 fn handle_error(response: &Response) -> Result<(), Error> {
94 if let Payload::Media(Media::InvalidRequest(err)) = &response.payload {
95 return Err(Error::MediaError(crate::error::MediaError::InvalidRequest(
96 err.reason.clone(),
97 )));
98 }
99
100 if let Payload::Media(Media::InvalidPlayerState) = response.payload {
101 return Err(Error::MediaError(
102 crate::error::MediaError::InvalidPlayerState,
103 ));
104 }
105
106 if let Payload::Media(Media::LoadFailed) = response.payload {
107 return Err(Error::MediaError(crate::error::MediaError::LoadFailed));
108 }
109
110 if let Payload::Media(Media::LoadCancelled) = response.payload {
111 return Err(Error::MediaError(crate::error::MediaError::LoadCancelled));
112 }
113
114 Ok(())
115 }
116}