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}