1use serde::{Deserialize, Serialize};
2
3#[cfg(not(feature = "std"))]
4use alloc::{string::String, vec::Vec};
5
6#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
7pub struct Vmix {
8 #[serde(rename = "version")]
9 pub version: String,
10
11 #[serde(rename = "edition")]
12 pub edition: String,
13
14 #[serde(rename = "preset", default)]
15 pub preset: Option<String>,
16
17 #[serde(rename = "inputs")]
18 pub inputs: Inputs,
19
20 #[serde(rename = "outputs", default)]
21 pub outputs: Option<Outputs>,
22
23 #[serde(rename = "overlays")]
24 pub overlays: Overlays,
25
26 #[serde(rename = "preview")]
27 pub preview: String,
28
29 #[serde(rename = "active")]
30 pub active: String,
31
32 #[serde(rename = "fadeToBlack", with = "xml_bool")]
33 pub fade_to_black: bool,
34
35 #[serde(rename = "transitions")]
36 pub transitions: Transitions,
37
38 #[serde(rename = "recording", with = "xml_bool")]
39 pub recording: bool,
40
41 #[serde(rename = "external", with = "xml_bool")]
42 pub external: bool,
43
44 #[serde(rename = "streaming", with = "xml_bool")]
45 pub streaming: bool,
46
47 #[serde(rename = "playList", with = "xml_bool")]
48 pub play_list: bool,
49
50 #[serde(rename = "multiCorder", with = "xml_bool")]
51 pub multi_corder: bool,
52
53 #[serde(rename = "fullscreen", with = "xml_bool")]
54 pub fullscreen: bool,
55
56 #[serde(rename = "mix", default)]
57 pub mix: Vec<Mix>,
58
59 #[serde(rename = "audio")]
60 pub audio: Audio,
61
62 #[serde(rename = "dynamic")]
63 pub dynamic: Dynamic,
64}
65
66#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
67pub struct Audio {
68 #[serde(rename = "master")]
69 pub master: AudioBus,
70
71 #[serde(rename = "busA", default)]
72 pub bus_a: Option<AudioBus>,
73
74 #[serde(rename = "busB", default)]
75 pub bus_b: Option<AudioBus>,
76
77 #[serde(rename = "busC", default)]
78 pub bus_c: Option<AudioBus>,
79
80 #[serde(rename = "busD", default)]
81 pub bus_d: Option<AudioBus>,
82
83 #[serde(rename = "busE", default)]
84 pub bus_e: Option<AudioBus>,
85
86 #[serde(rename = "busF", default)]
87 pub bus_f: Option<AudioBus>,
88
89 #[serde(rename = "busG", default)]
90 pub bus_g: Option<AudioBus>,
91}
92
93#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
94pub struct AudioBus {
95 #[serde(rename = "@volume")]
96 pub volume: f64,
97
98 #[serde(rename = "@muted", with = "xml_bool")]
99 pub muted: bool,
100
101 #[serde(rename = "@meterF1")]
102 pub meter_f1: f64,
103
104 #[serde(rename = "@meterF2")]
105 pub meter_f2: f64,
106
107 #[serde(rename = "@headphonesVolume", default)]
108 pub headphones_volume: Option<f64>,
109
110 #[serde(rename = "@solo", default, with = "xml_bool_option")]
111 pub solo: Option<bool>,
112
113 #[serde(rename = "@sendToMaster", default, with = "xml_bool_option")]
114 pub send_to_master: Option<bool>,
115}
116
117#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
118pub struct Dynamic {
119 #[serde(rename = "input1")]
120 pub input1: String,
121
122 #[serde(rename = "input2")]
123 pub input2: String,
124
125 #[serde(rename = "input3")]
126 pub input3: String,
127
128 #[serde(rename = "input4")]
129 pub input4: String,
130
131 #[serde(rename = "value1")]
132 pub value1: String,
133
134 #[serde(rename = "value2")]
135 pub value2: String,
136
137 #[serde(rename = "value3")]
138 pub value3: String,
139
140 #[serde(rename = "value4")]
141 pub value4: String,
142}
143
144#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
145pub struct Inputs {
146 #[serde(rename = "input")]
147 pub input: Vec<Input>,
148}
149
150#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
151pub struct Input {
152 #[serde(rename = "@key")]
154 pub key: String,
155
156 #[serde(rename = "@number")]
157 pub number: String,
158
159 #[serde(rename = "@type")]
160 pub input_type: String,
161
162 #[serde(rename = "@title")]
163 pub title: String,
164
165 #[serde(rename = "@shortTitle")]
166 pub short_title: String,
167
168 #[serde(rename = "@state")]
169 pub state: State,
170
171 #[serde(rename = "@position")]
172 pub position: String,
173
174 #[serde(rename = "@duration")]
175 pub duration: String,
176
177 #[serde(rename = "@loop", with = "xml_bool")]
178 pub input_loop: bool,
179
180 #[serde(rename = "@muted", default, with = "xml_bool_option")]
181 pub muted: Option<bool>,
182
183 #[serde(rename = "@volume", default)]
184 pub volume: Option<f64>,
185
186 #[serde(rename = "@balance", default)]
187 pub balance: Option<f64>,
188
189 #[serde(rename = "@solo", default, with = "xml_bool_option")]
190 pub solo: Option<bool>,
191
192 #[serde(rename = "@soloPFL", default, with = "xml_bool_option")]
193 pub solo_pfl: Option<bool>,
194
195 #[serde(rename = "@audiobusses", default)]
196 pub audiobusses: Option<String>,
197
198 #[serde(rename = "@meterF1", default)]
199 pub meter_f1: Option<f64>,
200
201 #[serde(rename = "@meterF2", default)]
202 pub meter_f2: Option<f64>,
203
204 #[serde(rename = "@gainDb", default)]
205 pub gain_db: Option<f64>,
206
207 #[serde(rename = "@selectedIndex", default)]
208 pub selected_index: Option<String>,
209
210 #[serde(rename = "@preset", default)]
211 pub preset: Option<String>,
212
213 #[serde(rename = "list", default)]
215 pub list: Option<List>,
216
217 #[serde(rename = "image", default)]
218 pub image: Vec<Image>,
219
220 #[serde(rename = "replay", default)]
221 pub replay: Option<Replay>,
222
223 #[serde(rename = "overlay", default)]
224 pub overlay: Vec<InputOverlay>,
225
226 #[serde(rename = "crop", default)]
227 pub crop: Option<Crop>,
228
229 #[serde(rename = "position", default)]
230 pub input_position: Option<Position>,
231}
232
233#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
234pub struct Image {
235 #[serde(rename = "index", default)]
236 pub index: Option<String>,
237
238 #[serde(rename = "name", default)]
239 pub name: Option<String>,
240}
241
242#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
243pub struct List {
244 #[serde(rename = "item", default)]
245 pub item: Vec<ListItem>,
246}
247
248#[derive(Serialize, Deserialize, Debug, Clone)]
249pub struct ItemClass {
250 #[serde(rename = "_selected")]
251 pub selected: String,
252}
253
254#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
255pub struct InputOverlay {
256 #[serde(rename = "@index")]
257 pub index: String,
258
259 #[serde(rename = "@key")]
260 pub key: String,
261
262 #[serde(rename = "position", default)]
263 pub position: Option<Position>,
264}
265
266#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
267pub struct Position {
268 #[serde(rename = "@panX", default)]
269 pub pan_x: Option<String>,
270
271 #[serde(rename = "@panY", default)]
272 pub pan_y: Option<String>,
273
274 #[serde(rename = "@zoomX", default)]
275 pub zoom_x: Option<String>,
276
277 #[serde(rename = "@zoomY", default)]
278 pub zoom_y: Option<String>,
279
280 #[serde(rename = "@x", default)]
281 pub x: Option<String>,
282
283 #[serde(rename = "@y", default)]
284 pub y: Option<String>,
285
286 #[serde(rename = "@width", default)]
287 pub width: Option<String>,
288
289 #[serde(rename = "@height", default)]
290 pub height: Option<String>,
291}
292
293#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
294pub struct Replay {
295 #[serde(rename = "timecode", default)]
297 pub timecode: String,
298
299 #[serde(rename = "timecodeA", default)]
300 pub timecode_a: String,
301
302 #[serde(rename = "timecodeB", default)]
303 pub timecode_b: String,
304
305 #[serde(rename = "@live", default)]
307 pub live: Option<String>,
308
309 #[serde(rename = "@recording", default)]
310 pub recording: Option<String>,
311
312 #[serde(rename = "@channelMode", default)]
313 pub channel_mode: String,
314
315 #[serde(rename = "@events", default)]
316 pub events: String,
317
318 #[serde(rename = "@eventsA", default)]
319 pub events_a: String,
320
321 #[serde(rename = "@eventsB", default)]
322 pub events_b: String,
323
324 #[serde(rename = "@cameraA", default)]
325 pub camera_a: String,
326
327 #[serde(rename = "@cameraB", default)]
328 pub camera_b: String,
329
330 #[serde(rename = "@speed", default)]
331 pub speed: String,
332
333 #[serde(rename = "@speedA", default)]
334 pub speed_a: String,
335
336 #[serde(rename = "@speedB", default)]
337 pub speed_b: String,
338}
339
340#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
341pub struct Overlays {
342 #[serde(rename = "overlay")]
343 pub overlay: Vec<OverlaysOverlay>,
344}
345
346#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
347pub struct OverlaysOverlay {
348 #[serde(rename = "@number")]
349 pub number: String,
350}
351
352#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
353pub struct Transitions {
354 #[serde(rename = "transition")]
355 pub transition: Vec<Transition>,
356}
357
358#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
359pub struct Transition {
360 #[serde(rename = "@number")]
361 pub number: String,
362
363 #[serde(rename = "@effect")]
364 pub effect: String,
365
366 #[serde(rename = "@duration")]
367 pub duration: String,
368}
369
370#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
371pub struct ListItem {
372 #[serde(rename = "@enabled", default)]
373 pub enabled: Option<String>,
374 #[serde(rename = "@selected", default)]
375 pub selected: Option<String>,
376 #[serde(rename = "@index", default)]
377 pub index: Option<String>,
378 #[serde(rename = "$value", default)]
379 pub text: Option<String>,
380}
381
382mod xml_bool {
384 use serde::{Deserialize, Deserializer, Serializer};
385
386 #[cfg(not(feature = "std"))]
387 use alloc::{format, string::String};
388
389 pub fn serialize<S>(value: &bool, serializer: S) -> Result<S::Ok, S::Error>
390 where
391 S: Serializer,
392 {
393 let s = if *value { "True" } else { "False" };
394 serializer.serialize_str(s)
395 }
396
397 pub fn deserialize<'de, D>(deserializer: D) -> Result<bool, D::Error>
398 where
399 D: Deserializer<'de>,
400 {
401 let s = String::deserialize(deserializer)?;
402 match s.as_str() {
403 "True" => Ok(true),
404 "False" => Ok(false),
405 _ => Err(serde::de::Error::custom(format!(
406 "Invalid boolean value: {}",
407 s
408 ))),
409 }
410 }
411}
412
413mod xml_bool_option {
415 use serde::{Deserialize, Deserializer, Serializer};
416
417 #[cfg(not(feature = "std"))]
418 use alloc::{format, string::String};
419
420 pub fn serialize<S>(value: &Option<bool>, serializer: S) -> Result<S::Ok, S::Error>
421 where
422 S: Serializer,
423 {
424 match value {
425 Some(b) => {
426 let s = if *b { "True" } else { "False" };
427 serializer.serialize_str(s)
428 }
429 None => serializer.serialize_none(),
430 }
431 }
432
433 pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<bool>, D::Error>
434 where
435 D: Deserializer<'de>,
436 {
437 let opt = Option::<String>::deserialize(deserializer)?;
438 match opt {
439 Some(s) => match s.as_str() {
440 "True" => Ok(Some(true)),
441 "False" => Ok(Some(false)),
442 _ => Err(serde::de::Error::custom(format!(
443 "Invalid boolean value: {}",
444 s
445 ))),
446 },
447 None => Ok(None),
448 }
449 }
450}
451
452#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
454pub struct Outputs {
455 #[serde(rename = "output", default)]
456 pub output: Vec<Output>,
457}
458
459#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
460pub struct Output {
461 #[serde(rename = "@type")]
462 pub output_type: String,
463 #[serde(rename = "@number")]
464 pub number: String,
465 #[serde(rename = "@source")]
466 pub source: String,
467 #[serde(rename = "@external", default)]
468 pub external: Option<String>,
469 #[serde(rename = "@ndi", default)]
470 pub ndi: Option<String>,
471 #[serde(rename = "@mix", default)]
472 pub mix: Option<String>,
473 #[serde(rename = "@inputNumber", default)]
474 pub input_number: Option<String>,
475}
476
477#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
479pub struct Mix {
480 #[serde(rename = "@number")]
481 pub number: String,
482 #[serde(rename = "preview")]
483 pub preview: String,
484 #[serde(rename = "active")]
485 pub active: String,
486}
487
488#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
490pub struct Crop {
491 #[serde(rename = "@X1")]
492 pub x1: String,
493 #[serde(rename = "@Y1")]
494 pub y1: String,
495 #[serde(rename = "@X2")]
496 pub x2: String,
497 #[serde(rename = "@Y2")]
498 pub y2: String,
499}
500
501#[derive(Serialize, Deserialize, Debug, Clone)]
502pub enum Audiobusses {
503 #[serde(rename = "M")]
504 M,
505
506 #[serde(rename = "A")]
507 A,
508
509 #[serde(rename = "B")]
510 B,
511
512 #[serde(rename = "C")]
513 C,
514
515 #[serde(rename = "D")]
516 D,
517
518 #[serde(rename = "E")]
519 E,
520
521 #[serde(rename = "F")]
522 F,
523
524 #[serde(rename = "G")]
525 G,
526}
527
528#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
529pub enum State {
530 #[serde(rename = "Paused")]
531 Paused,
532
533 #[serde(rename = "Running")]
534 Running,
535
536 #[serde(rename = "Completed")]
537 Completed,
538}