Skip to main content

browser_protocol/media/
mod.rs

1//! This domain allows detailed inspection of media elements.
2
3
4use serde::{Serialize, Deserialize};
5use serde_json::Value as JsonValue;
6use std::borrow::Cow;
7
8/// Players will get an ID that is unique within the agent context.
9
10pub type PlayerId<'a> = Cow<'a, str>;
11
12
13pub type Timestamp = f64;
14
15/// Have one type per entry in MediaLogRecord::Type
16/// Corresponds to kMessage
17
18#[derive(Debug, Clone, Serialize, Deserialize, Default)]
19#[serde(rename_all = "camelCase")]
20pub struct PlayerMessage<'a> {
21    /// Keep in sync with MediaLogMessageLevel
22    /// We are currently keeping the message level 'error' separate from the
23    /// PlayerError type because right now they represent different things,
24    /// this one being a DVLOG(ERROR) style log message that gets printed
25    /// based on what log level is selected in the UI, and the other is a
26    /// representation of a media::PipelineStatus object. Soon however we're
27    /// going to be moving away from using PipelineStatus for errors and
28    /// introducing a new error type which should hopefully let us integrate
29    /// the error log level into the PlayerError type.
30    level: Cow<'a, str>,
31    message: Cow<'a, str>,
32}
33
34impl<'a> PlayerMessage<'a> {
35    pub fn builder(level: impl Into<Cow<'a, str>>, message: impl Into<Cow<'a, str>>) -> PlayerMessageBuilder<'a> {
36        PlayerMessageBuilder {
37            level: level.into(),
38            message: message.into(),
39        }
40    }
41    pub fn level(&self) -> &str { self.level.as_ref() }
42    pub fn message(&self) -> &str { self.message.as_ref() }
43}
44
45
46pub struct PlayerMessageBuilder<'a> {
47    level: Cow<'a, str>,
48    message: Cow<'a, str>,
49}
50
51impl<'a> PlayerMessageBuilder<'a> {
52    pub fn build(self) -> PlayerMessage<'a> {
53        PlayerMessage {
54            level: self.level,
55            message: self.message,
56        }
57    }
58}
59
60/// Corresponds to kMediaPropertyChange
61
62#[derive(Debug, Clone, Serialize, Deserialize, Default)]
63#[serde(rename_all = "camelCase")]
64pub struct PlayerProperty<'a> {
65    name: Cow<'a, str>,
66    value: Cow<'a, str>,
67}
68
69impl<'a> PlayerProperty<'a> {
70    pub fn builder(name: impl Into<Cow<'a, str>>, value: impl Into<Cow<'a, str>>) -> PlayerPropertyBuilder<'a> {
71        PlayerPropertyBuilder {
72            name: name.into(),
73            value: value.into(),
74        }
75    }
76    pub fn name(&self) -> &str { self.name.as_ref() }
77    pub fn value(&self) -> &str { self.value.as_ref() }
78}
79
80
81pub struct PlayerPropertyBuilder<'a> {
82    name: Cow<'a, str>,
83    value: Cow<'a, str>,
84}
85
86impl<'a> PlayerPropertyBuilder<'a> {
87    pub fn build(self) -> PlayerProperty<'a> {
88        PlayerProperty {
89            name: self.name,
90            value: self.value,
91        }
92    }
93}
94
95/// Corresponds to kMediaEventTriggered
96
97#[derive(Debug, Clone, Serialize, Deserialize, Default)]
98#[serde(rename_all = "camelCase")]
99pub struct PlayerEvent<'a> {
100    timestamp: Timestamp,
101    value: Cow<'a, str>,
102}
103
104impl<'a> PlayerEvent<'a> {
105    pub fn builder(timestamp: Timestamp, value: impl Into<Cow<'a, str>>) -> PlayerEventBuilder<'a> {
106        PlayerEventBuilder {
107            timestamp: timestamp,
108            value: value.into(),
109        }
110    }
111    pub fn timestamp(&self) -> &Timestamp { &self.timestamp }
112    pub fn value(&self) -> &str { self.value.as_ref() }
113}
114
115
116pub struct PlayerEventBuilder<'a> {
117    timestamp: Timestamp,
118    value: Cow<'a, str>,
119}
120
121impl<'a> PlayerEventBuilder<'a> {
122    pub fn build(self) -> PlayerEvent<'a> {
123        PlayerEvent {
124            timestamp: self.timestamp,
125            value: self.value,
126        }
127    }
128}
129
130/// Represents logged source line numbers reported in an error.
131/// NOTE: file and line are from chromium c++ implementation code, not js.
132
133#[derive(Debug, Clone, Serialize, Deserialize, Default)]
134#[serde(rename_all = "camelCase")]
135pub struct PlayerErrorSourceLocation<'a> {
136    file: Cow<'a, str>,
137    line: i64,
138}
139
140impl<'a> PlayerErrorSourceLocation<'a> {
141    pub fn builder(file: impl Into<Cow<'a, str>>, line: i64) -> PlayerErrorSourceLocationBuilder<'a> {
142        PlayerErrorSourceLocationBuilder {
143            file: file.into(),
144            line: line,
145        }
146    }
147    pub fn file(&self) -> &str { self.file.as_ref() }
148    pub fn line(&self) -> i64 { self.line }
149}
150
151
152pub struct PlayerErrorSourceLocationBuilder<'a> {
153    file: Cow<'a, str>,
154    line: i64,
155}
156
157impl<'a> PlayerErrorSourceLocationBuilder<'a> {
158    pub fn build(self) -> PlayerErrorSourceLocation<'a> {
159        PlayerErrorSourceLocation {
160            file: self.file,
161            line: self.line,
162        }
163    }
164}
165
166/// Corresponds to kMediaError
167
168#[derive(Debug, Clone, Serialize, Deserialize, Default)]
169#[serde(rename_all = "camelCase")]
170pub struct PlayerError<'a> {
171    errorType: Cow<'a, str>,
172    /// Code is the numeric enum entry for a specific set of error codes, such
173    /// as PipelineStatusCodes in media/base/pipeline_status.h
174    code: i64,
175    /// A trace of where this error was caused / where it passed through.
176    stack: Vec<PlayerErrorSourceLocation<'a>>,
177    /// Errors potentially have a root cause error, ie, a DecoderError might be
178    /// caused by an WindowsError
179    cause: Vec<Box<PlayerError<'a>>>,
180    /// Extra data attached to an error, such as an HRESULT, Video Codec, etc.
181    data: serde_json::Map<String, JsonValue>,
182}
183
184impl<'a> PlayerError<'a> {
185    pub fn builder(errorType: impl Into<Cow<'a, str>>, code: i64, stack: Vec<PlayerErrorSourceLocation<'a>>, cause: Vec<Box<PlayerError<'a>>>, data: serde_json::Map<String, JsonValue>) -> PlayerErrorBuilder<'a> {
186        PlayerErrorBuilder {
187            errorType: errorType.into(),
188            code: code,
189            stack: stack,
190            cause: cause,
191            data: data,
192        }
193    }
194    pub fn errorType(&self) -> &str { self.errorType.as_ref() }
195    pub fn code(&self) -> i64 { self.code }
196    pub fn stack(&self) -> &[PlayerErrorSourceLocation<'a>] { &self.stack }
197    pub fn cause(&self) -> &[Box<PlayerError<'a>>] { &self.cause }
198    pub fn data(&self) -> &serde_json::Map<String, JsonValue> { &self.data }
199}
200
201
202pub struct PlayerErrorBuilder<'a> {
203    errorType: Cow<'a, str>,
204    code: i64,
205    stack: Vec<PlayerErrorSourceLocation<'a>>,
206    cause: Vec<Box<PlayerError<'a>>>,
207    data: serde_json::Map<String, JsonValue>,
208}
209
210impl<'a> PlayerErrorBuilder<'a> {
211    pub fn build(self) -> PlayerError<'a> {
212        PlayerError {
213            errorType: self.errorType,
214            code: self.code,
215            stack: self.stack,
216            cause: self.cause,
217            data: self.data,
218        }
219    }
220}
221
222
223#[derive(Debug, Clone, Serialize, Deserialize, Default)]
224#[serde(rename_all = "camelCase")]
225pub struct Player<'a> {
226    playerId: PlayerId<'a>,
227    #[serde(skip_serializing_if = "Option::is_none")]
228    domNodeId: Option<crate::dom::BackendNodeId>,
229}
230
231impl<'a> Player<'a> {
232    pub fn builder(playerId: PlayerId<'a>) -> PlayerBuilder<'a> {
233        PlayerBuilder {
234            playerId: playerId,
235            domNodeId: None,
236        }
237    }
238    pub fn playerId(&self) -> &PlayerId<'a> { &self.playerId }
239    pub fn domNodeId(&self) -> Option<&crate::dom::BackendNodeId> { self.domNodeId.as_ref() }
240}
241
242
243pub struct PlayerBuilder<'a> {
244    playerId: PlayerId<'a>,
245    domNodeId: Option<crate::dom::BackendNodeId>,
246}
247
248impl<'a> PlayerBuilder<'a> {
249    pub fn domNodeId(mut self, domNodeId: crate::dom::BackendNodeId) -> Self { self.domNodeId = Some(domNodeId); self }
250    pub fn build(self) -> Player<'a> {
251        Player {
252            playerId: self.playerId,
253            domNodeId: self.domNodeId,
254        }
255    }
256}
257
258#[derive(Debug, Clone, Serialize, Deserialize, Default)]
259pub struct EnableParams {}
260
261impl EnableParams { pub const METHOD: &'static str = "Media.enable"; }
262
263impl<'a> crate::CdpCommand<'a> for EnableParams {
264    const METHOD: &'static str = "Media.enable";
265    type Response = crate::EmptyReturns;
266}
267
268#[derive(Debug, Clone, Serialize, Deserialize, Default)]
269pub struct DisableParams {}
270
271impl DisableParams { pub const METHOD: &'static str = "Media.disable"; }
272
273impl<'a> crate::CdpCommand<'a> for DisableParams {
274    const METHOD: &'static str = "Media.disable";
275    type Response = crate::EmptyReturns;
276}