yt_transcript_rs/models.rs
1use crate::transcript_list::TranscriptList;
2use serde::{Deserialize, Serialize};
3
4/// # TranslationLanguage
5///
6/// Represents a language option available for YouTube transcript translation.
7///
8/// This struct contains both the human-readable language name and the
9/// ISO language code that YouTube uses to identify the language.
10///
11/// ## Fields
12///
13/// * `language` - The full, human-readable name of the language (e.g., "English")
14/// * `language_code` - The ISO language code used by YouTube (e.g., "en")
15///
16/// ## Example Usage
17///
18/// ```rust,no_run
19/// # use yt_transcript_rs::models::TranslationLanguage;
20/// let english = TranslationLanguage {
21/// language: "English".to_string(),
22/// language_code: "en".to_string(),
23/// };
24///
25/// println!("Language: {} ({})", english.language, english.language_code);
26/// ```
27#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
28pub struct TranslationLanguage {
29 /// The human-readable language name (e.g., "English", "Español", "Français")
30 pub language: String,
31
32 /// The ISO language code used by YouTube's API (e.g., "en", "es", "fr")
33 pub language_code: String,
34}
35
36/// # FetchedTranscriptSnippet
37///
38/// Represents a single segment of transcript text with its timing information.
39///
40/// YouTube transcripts are divided into discrete text segments, each with a
41/// specific start time and duration. This struct captures one such segment.
42///
43/// ## Fields
44///
45/// * `text` - The actual transcript text for this segment
46/// * `start` - The timestamp when this text appears (in seconds)
47/// * `duration` - How long this text stays on screen (in seconds)
48///
49/// ## Notes
50///
51/// - Transcript segments may overlap in time
52/// - The `text` may include HTML formatting if formatting preservation is enabled
53/// - Time values are floating point to allow for sub-second precision
54///
55/// ## Example Usage
56///
57/// ```rust,no_run
58/// # use yt_transcript_rs::models::FetchedTranscriptSnippet;
59/// let snippet = FetchedTranscriptSnippet {
60/// text: "Hello, world!".to_string(),
61/// start: 5.2,
62/// duration: 2.5,
63/// };
64///
65/// println!("[{:.1}s-{:.1}s]: {}",
66/// snippet.start,
67/// snippet.start + snippet.duration,
68/// snippet.text);
69/// // Outputs: [5.2s-7.7s]: Hello, world!
70/// ```
71#[derive(Debug, Clone, Serialize, Deserialize)]
72pub struct FetchedTranscriptSnippet {
73 /// The text content of this snippet
74 pub text: String,
75
76 /// The timestamp at which this snippet appears on screen in seconds
77 pub start: f64,
78
79 /// The duration of how long the snippet stays on screen in seconds.
80 /// Note that there can be overlaps between snippets
81 pub duration: f64,
82}
83
84/// # VideoDetails
85///
86/// Comprehensive metadata about a YouTube video.
87///
88/// This struct contains detailed information about a video, extracted from
89/// YouTube's player response. It includes basic information like title and author,
90/// as well as more detailed metadata like view count, keywords, and thumbnails.
91///
92/// ## Fields
93///
94/// * `video_id` - The unique YouTube ID for the video
95/// * `title` - The video's title
96/// * `length_seconds` - The video duration in seconds
97/// * `keywords` - Optional list of keywords/tags associated with the video
98/// * `channel_id` - The YouTube channel ID
99/// * `short_description` - The video description
100/// * `view_count` - Number of views as a string (to handle very large numbers)
101/// * `author` - Name of the channel/creator
102/// * `thumbnails` - List of available thumbnail images in various resolutions
103/// * `is_live_content` - Whether the video is or was a live stream
104///
105/// ## Example Usage
106///
107/// ```rust,no_run
108/// # use yt_transcript_rs::api::YouTubeTranscriptApi;
109/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
110/// let api = YouTubeTranscriptApi::new(None, None, None)?;
111/// let video_id = "dQw4w9WgXcQ";
112///
113/// // Fetch video details
114/// let details = api.fetch_video_details(video_id).await?;
115///
116/// println!("Title: {}", details.title);
117/// println!("By: {} ({})", details.author, details.channel_id);
118/// println!("Duration: {} seconds", details.length_seconds);
119/// println!("Views: {}", details.view_count);
120///
121/// // Get highest resolution thumbnail
122/// if let Some(thumbnail) = details.thumbnails.iter().max_by_key(|t| t.width * t.height) {
123/// println!("Thumbnail URL: {}", thumbnail.url);
124/// }
125/// # Ok(())
126/// # }
127/// ```
128#[derive(Debug, Clone, Serialize, Deserialize)]
129pub struct VideoDetails {
130 /// The unique YouTube video ID (e.g., "dQw4w9WgXcQ")
131 pub video_id: String,
132
133 /// The video's title
134 pub title: String,
135
136 /// Total duration of the video in seconds
137 pub length_seconds: u32,
138
139 /// Optional list of keywords/tags associated with the video
140 pub keywords: Option<Vec<String>>,
141
142 /// The YouTube channel ID that published the video
143 pub channel_id: String,
144
145 /// The video description text
146 pub short_description: String,
147
148 /// Number of views as a string (to handle potentially very large numbers)
149 pub view_count: String,
150
151 /// Name of the channel/creator who published the video
152 pub author: String,
153
154 /// List of available thumbnail images in various resolutions
155 pub thumbnails: Vec<VideoThumbnail>,
156
157 /// Whether the video is or was a live stream
158 pub is_live_content: bool,
159}
160
161/// # VideoThumbnail
162///
163/// Represents a single thumbnail image for a YouTube video.
164///
165/// YouTube provides thumbnails in multiple resolutions, and this struct
166/// stores information about one such thumbnail, including its URL and dimensions.
167///
168/// ## Fields
169///
170/// * `url` - Direct URL to the thumbnail image
171/// * `width` - Width of the thumbnail in pixels
172/// * `height` - Height of the thumbnail in pixels
173///
174/// ## Common Resolutions
175///
176/// YouTube typically provides thumbnails in these standard resolutions:
177/// - Default: 120×90
178/// - Medium: 320×180
179/// - High: 480×360
180/// - Standard: 640×480
181/// - Maxres: 1280×720
182///
183/// ## Example Usage
184///
185/// ```rust,no_run
186/// # use yt_transcript_rs::models::VideoThumbnail;
187/// let thumbnail = VideoThumbnail {
188/// url: "https://i.ytimg.com/vi/dQw4w9WgXcQ/hqdefault.jpg".to_string(),
189/// width: 480,
190/// height: 360,
191/// };
192///
193/// println!("Thumbnail ({}×{}): {}", thumbnail.width, thumbnail.height, thumbnail.url);
194/// ```
195#[derive(Debug, Clone, Serialize, Deserialize)]
196pub struct VideoThumbnail {
197 /// Direct URL to the thumbnail image
198 pub url: String,
199
200 /// Width of the thumbnail in pixels
201 pub width: u32,
202
203 /// Height of the thumbnail in pixels
204 pub height: u32,
205}
206
207/// Represents microformat data for a YouTube video
208#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
209pub struct MicroformatData {
210 /// Countries where the video is available
211 pub available_countries: Option<Vec<String>>,
212 /// Category of the video
213 pub category: Option<String>,
214 /// Description of the video
215 pub description: Option<String>,
216 /// Embed information
217 pub embed: Option<MicroformatEmbed>,
218 /// External channel ID
219 pub external_channel_id: Option<String>,
220 /// External video ID
221 pub external_video_id: Option<String>,
222 /// Whether the video has YPC metadata
223 pub has_ypc_metadata: Option<bool>,
224 /// Whether the video is family safe
225 pub is_family_safe: Option<bool>,
226 /// Whether the video is eligible for Shorts
227 pub is_shorts_eligible: Option<bool>,
228 /// Whether the video is unlisted
229 pub is_unlisted: Option<bool>,
230 /// Duration of the video in seconds
231 pub length_seconds: Option<String>,
232 /// Number of likes
233 pub like_count: Option<String>,
234 /// Name of the channel owner
235 pub owner_channel_name: Option<String>,
236 /// URL to the owner's profile
237 pub owner_profile_url: Option<String>,
238 /// Date when the video was published
239 pub publish_date: Option<String>,
240 /// Thumbnail information
241 pub thumbnail: Option<MicroformatThumbnail>,
242 /// Title of the video
243 pub title: Option<String>,
244 /// Date when the video was uploaded
245 pub upload_date: Option<String>,
246 /// Number of views
247 pub view_count: Option<String>,
248}
249
250/// Represents embed information in microformat data
251#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
252pub struct MicroformatEmbed {
253 /// Height of the embed
254 pub height: Option<i32>,
255 /// URL for the iframe embed
256 pub iframe_url: Option<String>,
257 /// Width of the embed
258 pub width: Option<i32>,
259}
260
261/// Represents thumbnail information in microformat data
262#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
263pub struct MicroformatThumbnail {
264 /// List of thumbnails in different sizes
265 pub thumbnails: Option<Vec<VideoThumbnail>>,
266}
267
268/// Represents a range with start and end values
269#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
270pub struct Range {
271 /// Start position
272 pub start: String,
273 /// End position
274 pub end: String,
275}
276
277/// Represents color information for a video format
278#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
279pub struct ColorInfo {
280 /// Primary colors used
281 pub primaries: Option<String>,
282 /// Transfer characteristics
283 pub transfer_characteristics: Option<String>,
284 /// Matrix coefficients
285 pub matrix_coefficients: Option<String>,
286}
287
288/// Represents a single video or audio format available for streaming
289#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
290pub struct StreamingFormat {
291 /// Format identification number
292 pub itag: u32,
293 /// URL to the media
294 pub url: Option<String>,
295 /// MIME type and codec information
296 pub mime_type: String,
297 /// Bitrate in bits per second
298 pub bitrate: u64,
299 /// Video width in pixels (video only)
300 pub width: Option<u32>,
301 /// Video height in pixels (video only)
302 pub height: Option<u32>,
303 /// Initialization range for segmented formats
304 pub init_range: Option<Range>,
305 /// Index range for segmented formats
306 pub index_range: Option<Range>,
307 /// Last modification timestamp
308 pub last_modified: Option<String>,
309 /// Content length in bytes
310 pub content_length: Option<String>,
311 /// Quality label (e.g., "medium", "hd720")
312 pub quality: String,
313 /// Frames per second (video only)
314 pub fps: Option<u32>,
315 /// Human-readable quality label (e.g., "720p")
316 pub quality_label: Option<String>,
317 /// Projection type (e.g., "RECTANGULAR")
318 pub projection_type: String,
319 /// Average bitrate in bits per second
320 pub average_bitrate: Option<u64>,
321 /// Audio quality (audio only)
322 pub audio_quality: Option<String>,
323 /// Approximate duration in milliseconds
324 pub approx_duration_ms: String,
325 /// Audio sample rate (audio only)
326 pub audio_sample_rate: Option<String>,
327 /// Number of audio channels (audio only)
328 pub audio_channels: Option<u32>,
329 /// Quality ordinal value
330 pub quality_ordinal: Option<String>,
331 /// High replication flag
332 pub high_replication: Option<bool>,
333 /// Color information
334 pub color_info: Option<ColorInfo>,
335 /// Loudness in decibels (audio only)
336 pub loudness_db: Option<f64>,
337 /// Whether DRC (Dynamic Range Compression) is used
338 pub is_drc: Option<bool>,
339 /// Extra tags
340 pub xtags: Option<String>,
341}
342
343/// Represents all available streaming data for a YouTube video
344#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
345pub struct StreamingData {
346 /// Time in seconds until the streaming URLs expire
347 pub expires_in_seconds: String,
348 /// Combined formats with both audio and video
349 pub formats: Vec<StreamingFormat>,
350 /// Separate adaptive formats for audio or video
351 pub adaptive_formats: Vec<StreamingFormat>,
352 /// Server ABR streaming URL
353 pub server_abr_streaming_url: Option<String>,
354}
355
356/// # VideoInfos
357///
358/// Comprehensive container for all available information about a YouTube video.
359///
360/// This struct combines metadata from different extractors into a single structure,
361/// providing a complete view of a video's details, streaming options, and available transcripts.
362///
363/// The advantage of using this struct is that it retrieves all information in a single request
364/// to YouTube, rather than making multiple separate requests.
365#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
366pub struct VideoInfos {
367 /// Basic details about the video (title, author, view count, etc.)
368 pub video_details: VideoDetails,
369
370 /// Extended metadata from the microformat section (categories, countries, embed info)
371 pub microformat: MicroformatData,
372
373 /// Information about available streaming formats (qualities, codecs, URLs)
374 pub streaming_data: StreamingData,
375
376 /// List of available transcripts/captions for the video
377 pub transcript_list: TranscriptList,
378}