yt_live_rs/types.rs
1//! Shared types for the yt-live-rs library.
2//!
3//! This module contains the core data structures used throughout the library
4//! for representing video information, stream formats, and codec types.
5
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8use std::fmt;
9use std::str::FromStr;
10
11/// Metadata about a YouTube video or live stream.
12///
13/// This struct contains all the basic information about a video,
14/// including title, channel, and live status.
15///
16/// # Example
17///
18/// ```no_run
19/// # use yt_live_rs::Client;
20/// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
21/// let client = Client::builder().build()?;
22/// let info = client.get_video_info("https://youtube.com/watch?v=VIDEO_ID").await?;
23/// println!("Title: {}", info.title);
24/// println!("Channel: {}", info.channel);
25/// println!("Is Live: {}", info.is_live);
26/// # Ok(())
27/// # }
28/// ```
29#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
30pub struct VideoInfo {
31 /// YouTube video ID (e.g., "dQw4w9WgXcQ").
32 pub id: String,
33 /// Video title.
34 pub title: String,
35 /// Channel name.
36 pub channel: String,
37 /// Channel ID.
38 pub channel_id: String,
39 /// Video description.
40 pub description: String,
41 /// Whether the stream is currently live.
42 pub is_live: bool,
43 /// Thumbnail URL.
44 pub thumbnail: Option<String>,
45 /// Stream start timestamp (ISO 8601 format).
46 pub start_timestamp: Option<String>,
47 /// Video publish date.
48 pub publish_date: Option<String>,
49 /// Full video URL.
50 pub url: String,
51}
52
53/// Information about available streams for a video.
54///
55/// Contains the audio and video stream formats available for download,
56/// along with timing information.
57#[derive(Debug, Clone, Serialize, Deserialize)]
58pub struct StreamInfo {
59 /// Audio stream format (usually AAC at 128kbps).
60 pub audio: Option<StreamFormat>,
61 /// Video streams by quality label (e.g., "1080p60 (h264)").
62 pub video: HashMap<String, StreamFormat>,
63 /// Target duration of each fragment in seconds.
64 pub target_duration: u32,
65 /// Last known sequence number from the manifest.
66 pub last_sequence: Option<u64>,
67}
68
69/// Format information for a single stream.
70///
71/// Contains the URL template and metadata for downloading a specific
72/// audio or video stream.
73#[derive(Debug, Clone, Serialize, Deserialize)]
74pub struct StreamFormat {
75 /// YouTube itag identifier for this format.
76 pub itag: u32,
77 /// URL template with `%d` placeholder for sequence number.
78 pub url: String,
79 /// MIME type (e.g., "video/mp4", "audio/mp4").
80 pub mime_type: Option<String>,
81 /// Quality label (e.g., "1080p60", "audio").
82 pub quality_label: Option<String>,
83 /// Video/audio codec.
84 pub codec: Codec,
85}
86
87/// Video or audio codec type.
88///
89/// # Example
90///
91/// ```
92/// use yt_live_rs::Codec;
93/// use std::str::FromStr;
94///
95/// let codec = Codec::from_str("h264").unwrap();
96/// assert_eq!(codec, Codec::H264);
97/// assert_eq!(codec.to_string(), "h264");
98/// ```
99#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
100pub enum Codec {
101 /// H.264/AVC video codec. Most compatible.
102 H264,
103 /// VP9 video codec. Better compression than H.264.
104 VP9,
105 /// AV1 video codec. Best compression, but requires more CPU.
106 AV1,
107 /// AAC audio codec.
108 AAC,
109 /// Opus audio codec.
110 Opus,
111 /// Unknown or unsupported codec.
112 #[default]
113 Unknown,
114}
115
116impl fmt::Display for Codec {
117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118 match self {
119 Codec::H264 => write!(f, "h264"),
120 Codec::VP9 => write!(f, "vp9"),
121 Codec::AV1 => write!(f, "av1"),
122 Codec::AAC => write!(f, "aac"),
123 Codec::Opus => write!(f, "opus"),
124 Codec::Unknown => write!(f, "unknown"),
125 }
126 }
127}
128
129impl FromStr for Codec {
130 type Err = String;
131
132 fn from_str(s: &str) -> Result<Self, Self::Err> {
133 match s.to_lowercase().as_str() {
134 "h264" | "avc" | "avc1" => Ok(Codec::H264),
135 "vp9" | "vp09" => Ok(Codec::VP9),
136 "av1" | "av01" => Ok(Codec::AV1),
137 "aac" | "mp4a" => Ok(Codec::AAC),
138 "opus" => Ok(Codec::Opus),
139 _ => Err(format!("Unknown codec: {}", s)),
140 }
141 }
142}