Skip to main content

youtube_api/models/
metadata.rs

1use serde::Deserialize;
2
3#[derive(Debug, Clone, Deserialize)]
4pub struct VideoMetadataResponse {
5    pub player_response: String
6}
7
8#[derive(Debug, Clone, Deserialize)]
9#[serde(rename_all = "camelCase")]
10pub struct VideoMetadata {
11    pub response_context: ResponseContext,
12    pub playability_status: PlayabilityStatus,
13    pub streaming_data: Option<StreamingData>,
14    pub playback_tracking: Option<PlaybackTracking>,
15    pub video_details: VideoDetails,
16    #[serde(default)]
17    pub annotations: Vec<Annotation>,
18    pub player_config: Option<PlayerConfig>,
19    pub storyboards: Option<Storyboards>,
20    pub microformat: Microformat,
21    pub tracking_params: String,
22    pub attestation: Option<Attestation>,
23    #[serde(default)]
24    pub messages: Vec<Message>,
25    pub endscreen: Option<Endscreen>,
26}
27
28#[derive(Debug, Clone, Deserialize)]
29#[serde(rename_all = "camelCase")]
30pub struct Annotation {
31    pub player_annotations_expanded_renderer: Option<PlayerAnnotationsExpandedRenderer>,
32}
33
34#[derive(Debug, Clone, Deserialize)]
35#[serde(rename_all = "camelCase")]
36pub struct PlayerAnnotationsExpandedRenderer {
37    pub featured_channel: FeaturedChannel,
38    pub allow_swipe_dismiss: bool,
39    pub annotation_id: String,
40}
41
42#[derive(Debug, Clone, Deserialize)]
43#[serde(rename_all = "camelCase")]
44pub struct FeaturedChannel {
45    pub start_time_ms: String,
46    pub end_time_ms: String,
47    pub watermark: WatermarkClass,
48    pub tracking_params: String,
49    pub navigation_endpoint: FeaturedChannelNavigationEndpoint,
50    pub channel_name: String,
51    pub subscribe_button: SubscribeButtonClass,
52}
53
54#[derive(Debug, Clone, Deserialize)]
55#[serde(rename_all = "camelCase")]
56pub struct FeaturedChannelNavigationEndpoint {
57    pub click_tracking_params: String,
58    pub browse_endpoint: BrowseEndpoint,
59}
60
61#[derive(Debug, Clone, Deserialize)]
62#[serde(rename_all = "camelCase")]
63pub struct BrowseEndpoint {
64    pub browse_id: String,
65}
66
67#[derive(Debug, Clone, Deserialize)]
68#[serde(rename_all = "camelCase")]
69pub struct SubscribeButtonClass {
70    pub subscribe_button_renderer: SubscribeButtonRenderer,
71}
72
73#[derive(Debug, Clone, Deserialize)]
74#[serde(rename_all = "camelCase")]
75pub struct SubscribeButtonRenderer {
76    pub button_text: MessageTitle,
77    pub subscribed: bool,
78    pub enabled: bool,
79    #[serde(rename = "type")]
80    pub subscribe_button_renderer_type: String,
81    pub channel_id: String,
82    pub show_preferences: bool,
83    pub subscribed_button_text: MessageTitle,
84    pub unsubscribed_button_text: MessageTitle,
85    pub tracking_params: String,
86    pub unsubscribe_button_text: MessageTitle,
87    pub service_endpoints: Vec<ServiceEndpoint>,
88    pub sign_in_endpoint: Option<SigninEndpoint>,
89}
90
91#[derive(Debug, Clone, Deserialize)]
92pub struct MessageTitle {
93    pub runs: Vec<Run>,
94}
95
96#[derive(Debug, Clone, Deserialize)]
97pub struct Run {
98    pub text: String,
99}
100
101#[derive(Debug, Clone, Deserialize)]
102#[serde(rename_all = "camelCase")]
103pub struct ServiceEndpoint {
104    pub click_tracking_params: String,
105    pub subscribe_endpoint: Option<SubscribeEndpoint>,
106    pub unsubscribe_endpoint: Option<SubscribeEndpoint>,
107}
108
109#[derive(Debug, Clone, Deserialize)]
110#[serde(rename_all = "camelCase")]
111pub struct SubscribeEndpoint {
112    pub channel_ids: Vec<String>,
113    pub params: String,
114}
115
116#[derive(Debug, Clone, Deserialize)]
117#[serde(rename_all = "camelCase")]
118pub struct SigninEndpoint {
119    pub click_tracking_params: String,
120    pub web_navigation_endpoint_data: Option<WebNavigationEndpointData>,
121}
122
123#[derive(Debug, Clone, Deserialize)]
124pub struct WebNavigationEndpointData {
125    pub url: String,
126}
127
128#[derive(Debug, Clone, Deserialize)]
129pub struct WatermarkClass {
130    pub thumbnails: Vec<ThumbnailElement>,
131}
132
133#[derive(Debug, Clone, Deserialize)]
134pub struct ThumbnailElement {
135    pub url: String,
136    pub width: i64,
137    pub height: i64,
138}
139
140#[derive(Debug, Clone, Deserialize)]
141#[serde(rename_all = "camelCase")]
142pub struct Attestation {
143    pub player_attestation_renderer: PlayerAttestationRenderer,
144}
145
146#[derive(Debug, Clone, Deserialize)]
147#[serde(rename_all = "camelCase")]
148pub struct PlayerAttestationRenderer {
149    pub challenge: String,
150    pub botguard_data: BotguardData,
151}
152
153#[derive(Debug, Clone, Deserialize)]
154#[serde(rename_all = "camelCase")]
155pub struct BotguardData {
156    pub program: String,
157    pub interpreter_url: String,
158}
159
160#[derive(Debug, Clone, Deserialize)]
161#[serde(rename_all = "camelCase")]
162pub struct Endscreen {
163    pub endscreen_renderer: EndscreenRenderer,
164}
165
166#[derive(Debug, Clone, Deserialize)]
167#[serde(rename_all = "camelCase")]
168pub struct EndscreenRenderer {
169    pub elements: Vec<Element>,
170    pub start_ms: String,
171    pub tracking_params: String,
172}
173
174#[derive(Debug, Clone, Deserialize)]
175#[serde(rename_all = "camelCase")]
176pub struct Element {
177    pub endscreen_element_renderer: EndscreenElementRenderer,
178}
179
180#[derive(Debug, Clone, Deserialize)]
181#[serde(rename_all = "camelCase")]
182pub struct EndscreenElementRenderer {
183    pub style: EndcardStyle,
184    pub image: WatermarkClass,
185    pub icon: Option<Icon>,
186    pub left: f64,
187    pub width: f64,
188    pub top: f64,
189    pub aspect_ratio: f64,
190    pub start_ms: String,
191    pub end_ms: String,
192    pub title: Title,
193    pub metadata: Description,
194    pub call_to_action: Option<Description>,
195    pub dismiss: Option<Description>,
196    pub endpoint: Endpoint,
197    pub hovercard_button: Option<SubscribeButtonClass>,
198    pub tracking_params: String,
199    pub is_subscribe: Option<bool>,
200    pub signin_endpoint: Option<SigninEndpoint>,
201    pub use_classic_subscribe_button: Option<bool>,
202    pub id: String,
203    pub video_duration: Option<Description>,
204    pub playlist_length: Option<Description>,
205}
206
207#[derive(Debug, Clone, Deserialize)]
208#[serde(rename_all = "UPPERCASE")]
209pub enum EndcardStyle {
210    Channel,
211    Video,
212    Playlist,
213    Website
214}
215
216#[derive(Debug, Clone, Deserialize)]
217#[serde(rename_all = "camelCase")]
218pub struct Description {
219    pub simple_text: String,
220}
221
222#[derive(Debug, Clone, Deserialize)]
223#[serde(rename_all = "camelCase")]
224pub struct Endpoint {
225    pub click_tracking_params: String,
226    pub browse_endpoint: Option<BrowseEndpoint>,
227    pub watch_endpoint: Option<WatchEndpoint>,
228}
229
230#[derive(Debug, Clone, Deserialize)]
231#[serde(rename_all = "camelCase")]
232pub struct WatchEndpoint {
233    pub video_id: String,
234    pub playlist_id: Option<String>,
235}
236
237#[derive(Debug, Clone, Deserialize)]
238pub struct Icon {
239    pub thumbnails: Vec<WebNavigationEndpointData>,
240}
241
242#[derive(Debug, Clone, Deserialize)]
243#[serde(rename_all = "camelCase")]
244pub struct Title {
245    pub accessibility: Accessibility,
246    pub simple_text: String,
247}
248
249#[derive(Debug, Clone, Deserialize)]
250#[serde(rename_all = "camelCase")]
251pub struct Accessibility {
252    pub accessibility_data: AccessibilityData,
253}
254
255#[derive(Debug, Clone, Deserialize)]
256pub struct AccessibilityData {
257    pub label: String,
258}
259
260#[derive(Debug, Clone, Deserialize)]
261#[serde(rename_all = "camelCase")]
262pub struct Message {
263    pub mealbar_promo_renderer: MealbarPromoRenderer,
264}
265
266#[derive(Debug, Clone, Deserialize)]
267#[serde(rename_all = "camelCase")]
268pub struct MealbarPromoRenderer {
269    pub message_texts: Vec<MessageTitle>,
270    pub action_button: ActionButtonClass,
271    pub dismiss_button: ActionButtonClass,
272    pub trigger_condition: String,
273    pub style: String,
274    pub tracking_params: String,
275    pub impression_endpoints: Vec<ImpressionEndpointElement>,
276    pub is_visible: bool,
277    pub message_title: MessageTitle,
278}
279
280#[derive(Debug, Clone, Deserialize)]
281#[serde(rename_all = "camelCase")]
282pub struct ActionButtonClass {
283    pub button_renderer: ButtonRenderer,
284}
285
286#[derive(Debug, Clone, Deserialize)]
287#[serde(rename_all = "camelCase")]
288pub struct ButtonRenderer {
289    pub style: String,
290    pub size: String,
291    pub text: MessageTitle,
292    pub service_endpoint: ImpressionEndpointElement,
293    pub navigation_endpoint: Option<ButtonRendererNavigationEndpoint>,
294    pub tracking_params: String,
295}
296
297#[derive(Debug, Clone, Deserialize)]
298#[serde(rename_all = "camelCase")]
299pub struct ButtonRendererNavigationEndpoint {
300    pub click_tracking_params: String,
301    pub url_endpoint: Option<UrlEndpoint>,
302}
303
304#[derive(Debug, Clone, Deserialize)]
305pub struct UrlEndpoint {
306    pub url: String,
307    pub target: String,
308}
309
310#[derive(Debug, Clone, Deserialize)]
311#[serde(rename_all = "camelCase")]
312pub struct ImpressionEndpointElement {
313    pub click_tracking_params: String,
314    pub feedback_endpoint: FeedbackEndpoint,
315}
316
317#[derive(Debug, Clone, Deserialize)]
318#[serde(rename_all = "camelCase")]
319pub struct FeedbackEndpoint {
320    pub feedback_token: String,
321    pub ui_actions: UiActions,
322}
323
324#[derive(Debug, Clone, Deserialize)]
325#[serde(rename_all = "camelCase")]
326pub struct UiActions {
327    pub hide_enclosing_container: bool,
328}
329
330#[derive(Debug, Clone, Deserialize)]
331#[serde(rename_all = "camelCase")]
332pub struct Microformat {
333    pub player_microformat_renderer: PlayerMicroformatRenderer,
334}
335
336#[derive(Debug, Clone, Deserialize)]
337#[serde(rename_all = "camelCase")]
338pub struct PlayerMicroformatRenderer {
339    pub thumbnail: WatermarkClass,
340    pub embed: Embed,
341    pub title: Description,
342    pub description: Option<Description>,
343    pub length_seconds: String,
344    pub owner_profile_url: String,
345    pub external_channel_id: String,
346    pub available_countries: Vec<String>,
347    pub is_unlisted: bool,
348    pub has_ypc_metadata: bool,
349    pub view_count: String,
350    pub category: String,
351    pub publish_date: String,
352    pub owner_channel_name: String,
353    pub upload_date: String,
354}
355
356#[derive(Debug, Clone, Deserialize)]
357#[serde(rename_all = "camelCase")]
358pub struct Embed {
359    pub iframe_url: String,
360    pub flash_url: String,
361    pub width: i64,
362    pub height: i64,
363    pub flash_secure_url: String,
364}
365
366#[derive(Debug, Clone, Deserialize)]
367#[serde(rename_all = "camelCase")]
368pub struct PlayabilityStatus {
369    pub status: PlaybackStatus,
370    #[serde(default)]
371    pub playable_in_embed: bool,
372    pub context_params: String,
373}
374
375#[derive(Debug, Clone, Deserialize)]
376#[serde(rename_all = "UPPERCASE")]
377pub enum PlaybackStatus {
378    Ok,
379    Unplayable
380}
381
382#[derive(Debug, Clone, Deserialize)]
383#[serde(rename_all = "camelCase")]
384pub struct PlaybackTracking {
385    pub videostats_playback_url: PtrackingUrlClass,
386    pub videostats_delayplay_url: PtrackingUrlClass,
387    pub videostats_watchtime_url: PtrackingUrlClass,
388    pub ptracking_url: PtrackingUrlClass,
389    pub qoe_url: PtrackingUrlClass,
390    pub set_awesome_url: AtrUrlClass,
391    pub atr_url: AtrUrlClass,
392    pub youtube_remarketing_url: Option<AtrUrlClass>,
393    pub google_remarketing_url: Option<AtrUrlClass>,
394}
395
396#[derive(Debug, Clone, Deserialize)]
397#[serde(rename_all = "camelCase")]
398pub struct AtrUrlClass {
399    pub base_url: String,
400    pub elapsed_media_time_seconds: i64,
401}
402
403#[derive(Debug, Clone, Deserialize)]
404#[serde(rename_all = "camelCase")]
405pub struct PtrackingUrlClass {
406    pub base_url: String,
407}
408
409#[derive(Debug, Clone, Deserialize)]
410#[serde(rename_all = "camelCase")]
411pub struct PlayerConfig {
412    pub audio_config: AudioConfig,
413    pub stream_selection_config: Option<StreamSelectionConfig>,
414    pub media_common_config: MediaCommonConfig,
415    pub web_player_config: WebPlayerConfig,
416}
417
418#[derive(Debug, Clone, Deserialize)]
419#[serde(rename_all = "camelCase")]
420pub struct AudioConfig {
421    pub loudness_db: Option<f64>,
422    pub perceptual_loudness_db: Option<f64>,
423    pub enable_per_format_loudness: bool,
424}
425
426#[derive(Debug, Clone, Deserialize)]
427#[serde(rename_all = "camelCase")]
428pub struct MediaCommonConfig {
429    pub dynamic_readahead_config: DynamicReadaheadConfig,
430}
431
432#[derive(Debug, Clone, Deserialize)]
433#[serde(rename_all = "camelCase")]
434pub struct DynamicReadaheadConfig {
435    pub max_read_ahead_media_time_ms: i64,
436    pub min_read_ahead_media_time_ms: i64,
437    pub read_ahead_growth_rate_ms: i64,
438}
439
440#[derive(Debug, Clone, Deserialize)]
441#[serde(rename_all = "camelCase")]
442pub struct StreamSelectionConfig {
443    pub max_bitrate: String,
444}
445
446#[derive(Debug, Clone, Deserialize)]
447#[serde(rename_all = "camelCase")]
448pub struct WebPlayerConfig {
449    pub web_player_actions_porting: WebPlayerActionsPorting,
450}
451
452#[derive(Debug, Clone, Deserialize)]
453#[serde(rename_all = "camelCase")]
454pub struct WebPlayerActionsPorting {
455    pub get_share_panel_command: GetSharePanelCommand,
456    pub subscribe_command: SubscribeCommand,
457    pub unsubscribe_command: UnsubscribeCommand,
458    pub add_to_watch_later_command: AddToWatchLaterCommand,
459    pub remove_from_watch_later_command: RemoveFromWatchLaterCommand,
460}
461
462#[derive(Debug, Clone, Deserialize)]
463#[serde(rename_all = "camelCase")]
464pub struct AddToWatchLaterCommand {
465    pub click_tracking_params: String,
466    pub playlist_edit_endpoint: AddToWatchLaterCommandPlaylistEditEndpoint,
467}
468
469#[derive(Debug, Clone, Deserialize)]
470#[serde(rename_all = "camelCase")]
471pub struct AddToWatchLaterCommandPlaylistEditEndpoint {
472    pub playlist_id: String,
473    pub actions: Vec<PurpleAction>,
474}
475
476#[derive(Debug, Clone, Deserialize)]
477#[serde(rename_all = "camelCase")]
478pub struct PurpleAction {
479    pub added_video_id: String,
480    pub action: String,
481}
482
483#[derive(Debug, Clone, Deserialize)]
484#[serde(rename_all = "camelCase")]
485pub struct GetSharePanelCommand {
486    pub click_tracking_params: String,
487    pub web_player_share_entity_service_endpoint: WebPlayerShareEntityServiceEndpoint,
488}
489
490#[derive(Debug, Clone, Deserialize)]
491#[serde(rename_all = "camelCase")]
492pub struct WebPlayerShareEntityServiceEndpoint {
493    pub serialized_share_entity: String,
494}
495
496#[derive(Debug, Clone, Deserialize)]
497#[serde(rename_all = "camelCase")]
498pub struct RemoveFromWatchLaterCommand {
499    pub click_tracking_params: String,
500    pub playlist_edit_endpoint: RemoveFromWatchLaterCommandPlaylistEditEndpoint,
501}
502
503#[derive(Debug, Clone, Deserialize)]
504#[serde(rename_all = "camelCase")]
505pub struct RemoveFromWatchLaterCommandPlaylistEditEndpoint {
506    pub playlist_id: String,
507    pub actions: Vec<FluffyAction>,
508}
509
510#[derive(Debug, Clone, Deserialize)]
511#[serde(rename_all = "camelCase")]
512pub struct FluffyAction {
513    pub action: String,
514    pub removed_video_id: String,
515}
516
517#[derive(Debug, Clone, Deserialize)]
518#[serde(rename_all = "camelCase")]
519pub struct SubscribeCommand {
520    pub click_tracking_params: String,
521    pub subscribe_endpoint: SubscribeEndpoint,
522}
523
524#[derive(Debug, Clone, Deserialize)]
525#[serde(rename_all = "camelCase")]
526pub struct UnsubscribeCommand {
527    pub click_tracking_params: String,
528    pub unsubscribe_endpoint: SubscribeEndpoint,
529}
530
531#[derive(Debug, Clone, Deserialize)]
532#[serde(rename_all = "camelCase")]
533pub struct ResponseContext {
534    pub service_tracking_params: Vec<ServiceTrackingParam>,
535}
536
537#[derive(Debug, Clone, Deserialize)]
538pub struct ServiceTrackingParam {
539    pub service: String,
540    pub params: Vec<Param>,
541}
542
543#[derive(Debug, Clone, Deserialize)]
544pub struct Param {
545    pub key: String,
546    pub value: String,
547}
548
549#[derive(Debug, Clone, Deserialize)]
550#[serde(rename_all = "camelCase")]
551pub struct Storyboards {
552    pub player_storyboard_spec_renderer: PlayerStoryboardSpecRenderer,
553}
554
555#[derive(Debug, Clone, Deserialize)]
556pub struct PlayerStoryboardSpecRenderer {
557    pub spec: String,
558}
559
560#[derive(Debug, Clone, Deserialize)]
561#[serde(rename_all = "camelCase")]
562pub struct StreamingData {
563    pub expires_in_seconds: String,
564    pub formats: Vec<Format>,
565    pub adaptive_formats: Vec<Format>,
566    pub probe_url: Option<String>,
567}
568
569#[derive(Debug, Clone, Deserialize)]
570#[serde(rename_all = "camelCase")]
571pub struct Format {
572    pub itag: i64,
573    pub mime_type: String,
574    pub bitrate: i64,
575    pub width: Option<i64>,
576    pub height: Option<i64>,
577    pub init_range: Option<Range>,
578    pub index_range: Option<Range>,
579    pub last_modified: String,
580    pub content_length: Option<String>,
581    pub quality: String,
582    pub fps: Option<i64>,
583    pub quality_label: Option<String>,
584    pub projection_type: ProjectionType,
585    pub average_bitrate: Option<i64>,
586    pub approx_duration_ms: Option<String>,
587    pub cipher: Option<String>,
588    pub color_info: Option<ColorInfo>,
589    pub high_replication: Option<bool>,
590    pub audio_quality: Option<String>,
591    pub audio_sample_rate: Option<String>,
592    pub audio_channels: Option<i64>,
593}
594
595#[derive(Debug, Clone, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
596#[serde(rename_all = "lowercase")]
597pub enum VideoQuality {
598    Small,
599    Medium,
600    Large
601}
602
603#[derive(Debug, Clone, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
604pub enum AudioQuality {
605    #[serde(rename = "AUDIO_QUALITY_LOW")]
606    Low,
607    #[serde(rename = "AUDIO_QUALITY_MEDIUM")]
608    Medium
609}
610
611#[derive(Debug, Clone, Deserialize)]
612#[serde(rename_all = "camelCase")]
613pub struct ColorInfo {
614    pub primaries: String,
615    pub transfer_characteristics: String,
616    pub matrix_coefficients: String,
617}
618
619#[derive(Debug, Clone, Deserialize)]
620pub struct Range {
621    pub start: String,
622    pub end: String,
623}
624
625#[derive(Debug, Clone, Deserialize)]
626#[serde(rename_all = "camelCase")]
627pub struct VideoDetails {
628    pub video_id: String,
629    pub title: String,
630    pub length_seconds: String,
631    #[serde(default)]
632    pub keywords: Vec<String>,
633    pub channel_id: String,
634    pub is_owner_viewing: bool,
635    pub short_description: String,
636    pub is_crawlable: bool,
637    pub thumbnail: WatermarkClass,
638    pub average_rating: f64,
639    pub allow_ratings: bool,
640    pub view_count: String,
641    pub author: String,
642    pub is_private: bool,
643    pub is_unplugged_corpus: bool,
644    pub is_live_content: bool,
645}
646
647#[derive(Debug, Clone, Deserialize)]
648#[serde(rename_all = "UPPERCASE")]
649pub enum ProjectionType {
650    Rectangular,
651}