pcloud/stream/
video.rs

1use std::borrow::Cow;
2
3use super::StreamingLinkList;
4use crate::file::FileIdentifier;
5
6/// Parameters for retrieving a video file link, including options for controlling the audio bit rate,
7/// video bit rate, resolution, and fixed bitrate streaming.
8#[derive(Debug, Default, serde::Serialize)]
9pub struct GetVideoLinkParams<'a> {
10    /// Audio bit rate in kilobits per second (from 16 to 320).
11    #[serde(rename = "abitrate", skip_serializing_if = "Option::is_none")]
12    pub audio_bit_rate: Option<u16>,
13
14    /// Video bit rate in kilobits per second (from 16 to 4000).
15    #[serde(rename = "vbitrate", skip_serializing_if = "Option::is_none")]
16    pub video_bit_rate: Option<u32>,
17
18    /// Resolution of the video in the format WIDTHxHEIGHT (e.g., 1280x960), with a range of 64x64 to 1280x960.
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub resolution: Option<Cow<'a, str>>,
21
22    /// If set to true, disables adaptive streaming and forces the video stream to have a constant bitrate.
23    #[serde(
24        rename = "fixedbitrate",
25        skip_serializing_if = "crate::request::is_false",
26        serialize_with = "crate::request::serialize_bool"
27    )]
28    pub fixed_bit_rate: bool,
29}
30
31impl<'a> GetVideoLinkParams<'a> {
32    /// Sets the audio bit rate for the video link.
33    ///
34    /// # Arguments
35    ///
36    /// * `value` - Audio bit rate in kilobits per second (from 16 to 320).
37    pub fn set_audio_bit_rate(&mut self, value: u16) {
38        self.audio_bit_rate = Some(value);
39    }
40
41    /// Sets the audio bit rate and returns the updated `GetVideoLinkParams` object.
42    ///
43    /// # Arguments
44    ///
45    /// * `value` - Audio bit rate in kilobits per second (from 16 to 320).
46    pub fn with_audio_bit_rate(mut self, value: u16) -> Self {
47        self.set_audio_bit_rate(value);
48        self
49    }
50
51    /// Sets the video bit rate for the video link.
52    ///
53    /// # Arguments
54    ///
55    /// * `value` - Video bit rate in kilobits per second (from 16 to 4000).
56    pub fn set_video_bit_rate(&mut self, value: u32) {
57        self.video_bit_rate = Some(value);
58    }
59
60    /// Sets the video bit rate and returns the updated `GetVideoLinkParams` object.
61    ///
62    /// # Arguments
63    ///
64    /// * `value` - Video bit rate in kilobits per second (from 16 to 4000).
65    pub fn with_video_bit_rate(mut self, value: u32) -> Self {
66        self.set_video_bit_rate(value);
67        self
68    }
69
70    /// Sets the resolution for the video link.
71    ///
72    /// # Arguments
73    ///
74    /// * `value` - The resolution in the format WIDTHxHEIGHT (e.g., 1280x960).
75    pub fn set_resolution(&mut self, value: impl Into<Cow<'a, str>>) {
76        self.resolution = Some(value.into());
77    }
78
79    /// Sets the resolution and returns the updated `GetVideoLinkParams` object.
80    ///
81    /// # Arguments
82    ///
83    /// * `value` - The resolution in the format WIDTHxHEIGHT (e.g., 1280x960).
84    pub fn with_resolution(mut self, value: impl Into<Cow<'a, str>>) -> Self {
85        self.set_resolution(value);
86        self
87    }
88
89    /// Sets the `fixed_bit_rate` flag.
90    ///
91    /// # Arguments
92    ///
93    /// * `value` - A boolean indicating whether the video should have a fixed bitrate.
94    pub fn set_fixed_bit_rate(&mut self, value: bool) {
95        self.fixed_bit_rate = value;
96    }
97
98    /// Sets the `fixed_bit_rate` flag and returns the updated `GetVideoLinkParams` object.
99    ///
100    /// # Arguments
101    ///
102    /// * `value` - A boolean indicating whether the video should have a fixed bitrate.
103    pub fn with_fixed_bit_rate(mut self, value: bool) -> Self {
104        self.set_fixed_bit_rate(value);
105        self
106    }
107}
108
109/// Struct representing the parameters used when making a request to get a video link.
110#[derive(serde::Serialize)]
111struct Params<'a> {
112    /// The identifier for the file being requested.
113    #[serde(flatten)]
114    identifier: FileIdentifier<'a>,
115
116    /// The parameters controlling how the video link should be generated.
117    #[serde(flatten)]
118    params: GetVideoLinkParams<'a>,
119}
120
121impl crate::Client {
122    /// Gets a video link using only the file identifier, without additional parameters.
123    ///
124    /// # Arguments
125    ///
126    /// * `identifier` - The identifier of the file.
127    ///
128    /// # Returns
129    ///
130    /// A result containing the `StreamingLinkList` with the generated video links.
131    pub async fn get_video_link(
132        &self,
133        identifier: impl Into<FileIdentifier<'_>>,
134    ) -> crate::Result<StreamingLinkList> {
135        self.get_request::<StreamingLinkList, _>("getvideolink", identifier.into())
136            .await
137    }
138
139    /// Gets a video link using both the file identifier and additional parameters.
140    ///
141    /// # Arguments
142    ///
143    /// * `identifier` - The identifier of the file.
144    /// * `params` - The parameters to customize the video link (e.g., audio bit rate, video bit rate, resolution).
145    ///
146    /// # Returns
147    ///
148    /// A result containing the `StreamingLinkList` with the generated video links.
149    pub async fn get_video_link_with_params(
150        &self,
151        identifier: impl Into<FileIdentifier<'_>>,
152        params: GetVideoLinkParams<'_>,
153    ) -> crate::Result<StreamingLinkList> {
154        self.get_request::<StreamingLinkList, _>(
155            "getvideolink",
156            Params {
157                identifier: identifier.into(),
158                params,
159            },
160        )
161        .await
162    }
163}
164
165#[cfg(test)]
166mod tests {
167    use crate::{Client, Credentials};
168    use mockito::Matcher;
169
170    #[tokio::test]
171    async fn success() {
172        let mut server = mockito::Server::new_async().await;
173        let m = server.mock("GET", "/getvideolink")
174            .match_query(Matcher::AllOf(vec![
175                Matcher::UrlEncoded("access_token".into(), "access-token".into()),
176                Matcher::UrlEncoded("fileid".into(), "42".into()),
177            ]))
178            .with_status(200)
179            .with_body(r#"{
180        "result": 0,
181        "dwltag": "yvkNr0TqT6HFAWlVpdnHs5",
182        "hash": 17869736033964340520,
183        "size": 10485760,
184        "expires": "Sat, 24 Jul 2021 03:18:31 +0000",
185        "path": "\/DLZCAt2vXZejNfL5ZruLVZZTk2ev7Z2ZZNR5ZZdoz6ZXZQZZErw4bH0PfzBQt3LlgXMliXVtietX\/SAkdyBjkA7mQABbT.bin",
186        "hosts": [
187                "edef2.pcloud.com",
188                "eu3.pcloud.com"
189        ]
190}"#)
191.create();
192        let client = Client::new(server.url(), Credentials::access_token("access-token")).unwrap();
193        let result = client.get_video_link(42).await.unwrap();
194        let mut iter = result.links();
195        assert_eq!(iter.next().unwrap().to_string(), "https://edef2.pcloud.com/DLZCAt2vXZejNfL5ZruLVZZTk2ev7Z2ZZNR5ZZdoz6ZXZQZZErw4bH0PfzBQt3LlgXMliXVtietX/SAkdyBjkA7mQABbT.bin");
196        m.assert();
197    }
198}