Skip to main content

cast_sender/
media_controller.rs

1use 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}