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}