This repository has been archived on 2026-05-27. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
rustypipe/src/model/mod.rs
2022-09-20 21:22:18 +02:00

358 lines
9.3 KiB
Rust

pub mod locale;
mod ordering;
mod paginator;
pub mod stream_filter;
pub use locale::{Country, Language};
pub use paginator::Paginator;
use std::ops::Range;
use chrono::{DateTime, Local};
use serde::{Deserialize, Serialize};
/*
#PLAYER
*/
pub trait FileFormat {
fn extension(&self) -> &str;
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct VideoPlayer {
pub details: VideoPlayerDetails,
pub video_streams: Vec<VideoStream>,
pub video_only_streams: Vec<VideoStream>,
pub audio_streams: Vec<AudioStream>,
pub subtitles: Vec<Subtitle>,
pub expires_in_seconds: u32,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct VideoPlayerDetails {
pub id: String,
pub title: String,
pub description: Option<String>,
pub length: u32,
pub thumbnails: Vec<Thumbnail>,
pub channel: ChannelId,
pub publish_date: Option<DateTime<Local>>,
pub view_count: u64,
pub keywords: Vec<String>,
pub category: Option<String>,
pub is_live_content: bool,
pub is_family_safe: Option<bool>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct VideoStream {
pub url: String,
pub itag: u32,
pub bitrate: u32,
pub average_bitrate: u32,
pub size: Option<u64>,
pub index_range: Option<Range<u32>>,
pub init_range: Option<Range<u32>>,
pub width: u32,
pub height: u32,
pub fps: u8,
pub quality: String,
pub hdr: bool,
pub mime: String,
pub format: VideoFormat,
pub codec: VideoCodec,
pub throttled: bool,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct AudioStream {
pub url: String,
pub itag: u32,
pub bitrate: u32,
pub average_bitrate: u32,
pub size: u64,
pub index_range: Option<Range<u32>>,
pub init_range: Option<Range<u32>>,
pub mime: String,
pub format: AudioFormat,
pub codec: AudioCodec,
pub throttled: bool,
pub track: Option<AudioTrack>,
}
#[derive(
Default, Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash,
)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum VideoCodec {
#[default]
Unknown,
/// MPEG-4 Part 14 <https://en.wikipedia.org/wiki/MPEG-4_Part_14>
Mp4v,
/// avc1 aka H.264: <https://en.wikipedia.org/wiki/Advanced_Video_Coding>
Avc1,
/// VP9: <https://en.wikipedia.org/wiki/VP9>
Vp9,
/// AV1, the latest codec: <https://en.wikipedia.org/wiki/AV1>
Av01,
}
#[derive(
Default, Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash,
)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum AudioCodec {
#[default]
Unknown,
/// MP4A aka AAC: <https://en.wikipedia.org/wiki/Advanced_Audio_Coding>
Mp4a,
/// Opus: <https://en.wikipedia.org/wiki/Opus_(audio_format)>
Opus,
}
/// The video file format
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum VideoFormat {
#[serde(rename = "3gp")]
ThreeGp,
Mp4,
Webm,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct AudioTrack {
pub id: String,
pub lang: Option<String>,
pub lang_name: String,
pub is_default: bool,
}
impl FileFormat for VideoFormat {
fn extension(&self) -> &str {
match self {
VideoFormat::ThreeGp => ".3gp",
VideoFormat::Mp4 => ".mp4",
VideoFormat::Webm => ".webm",
}
}
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum AudioFormat {
M4a,
Webm,
}
impl FileFormat for AudioFormat {
fn extension(&self) -> &str {
match self {
AudioFormat::M4a => ".m4a",
AudioFormat::Webm => ".webm",
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct Thumbnail {
pub url: String,
pub width: u32,
pub height: u32,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct Subtitle {
pub url: String,
pub lang: String,
pub lang_name: String,
pub auto_generated: bool,
}
/*
#PLAYLIST
*/
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Playlist {
pub id: String,
pub name: String,
pub videos: Paginator<PlaylistVideo>,
pub video_count: u32,
pub thumbnail: Vec<Thumbnail>,
pub description: Option<String>,
pub channel: Option<ChannelId>,
pub last_update: Option<DateTime<Local>>,
pub last_update_txt: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct PlaylistVideo {
pub id: String,
pub title: String,
pub length: u32,
pub thumbnail: Vec<Thumbnail>,
pub channel: ChannelId,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ChannelId {
pub id: String,
pub name: String,
}
/*
#VIDEO DETAILS
*/
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct VideoDetails {
/// Unique YouTube video ID
pub id: String,
/// Video title
pub title: String,
/// Video description
pub description: String,
/// Channel of the video
pub channel: Channel,
/// Number of views
pub view_count: u64,
/// Number of likes
///
/// `None` if the like count was hidden by the creator.
pub like_count: Option<u32>,
/// Video publishing date. Start date in case of a livestream.
///
/// `None` if the date could not be parsed.
pub publish_date: Option<DateTime<Local>>,
/// Textual video publishing date (e.g. `Aug 2, 2013`, depends on language)
pub publish_date_txt: String,
/// Is the video a livestream?
pub is_live: bool,
/// Is the video published under the Creative Commons BY 3.0 license?
///
/// Information about the license:
///
/// https://www.youtube.com/t/creative_commons
///
/// https://creativecommons.org/licenses/by/3.0/
pub is_ccommons: bool,
/// Recommended videos
///
/// Note: Recommendations are not available for age-restricted videos
pub recommended: Paginator<RecommendedVideo>,
/// Paginator to fetch comments (most liked first)
pub top_comments: Paginator<Comment>,
/// Paginator to fetch comments (latest first)
pub latest_comments: Paginator<Comment>,
}
/*
@RECOMMENDATIONS
*/
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct RecommendedVideo {
/// Unique YouTube video ID
pub id: String,
/// Video title
pub title: String,
/// Video length in seconds.
///
/// Is `None` for livestreams.
pub length: Option<u32>,
/// Video thumbnail
pub thumbnail: Vec<Thumbnail>,
/// Channel of the video
pub channel: Channel,
/// Video publishing date.
///
/// `None` if the date could not be parsed.
pub publish_date: Option<DateTime<Local>>,
/// Textual video publish date (e.g. `11 months ago`, depends on language)
///
/// Is `None` for livestreams.
pub publish_date_txt: Option<String>,
/// View count
///
/// Is `None` if it could not be parsed
pub view_count: Option<u64>,
/// Is the video an active livestream?
pub is_live: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Channel {
/// Unique YouTube channel ID
pub id: String,
/// Channel name
pub name: String,
/// Channel avatar/profile picture
pub avatar: Vec<Thumbnail>,
/// Channel verification mark
pub verification: Verification,
/// Approximate number of subscribers
///
/// Info: This is only present in the `VideoDetails` response
pub subscriber_count: Option<u32>,
/// Textual subscriber count (e.g `1.41M subscribers`, depends on language)
pub subscriber_count_txt: Option<String>,
}
/*
@COMMENTS
*/
#[derive(Default, Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "snake_case")]
pub enum Verification {
#[default]
/// Unverified channel (default)
None,
/// Verified channel (✓ checkmark symbol)
Verified,
/// Verified music artist (♪ music note symbol)
Artist,
}
impl Verification {
pub fn verified(&self) -> bool {
self != &Self::None
}
}
// TODO: impl popularity comparison
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Comment {
/// Unique YouTube Comment-ID (e.g. `UgynScMrsqGSL8qvePl4AaABAg`)
pub id: String,
/// Comment text
pub text: String,
/// Comment author
///
/// There may be comments with missing authors (possibly deleted users?).
pub author: Option<Channel>,
/// Comment publishing date.
///
/// `None` if the date could not be parsed.
pub publish_date: Option<DateTime<Local>>,
/// Textual comment publish date (e.g. `14 hours ago`), depends on language setting
pub publish_date_txt: String,
/// Number of comment likes
pub like_count: Option<u32>,
/// Number of replies
pub reply_count: u32,
/// Paginator to fetch comment replies
pub replies: Paginator<Comment>,
/// Is the comment from the channel owner?
pub by_owner: bool,
/// Has the channel owner pinned the comment to the top?
pub pinned: bool,
/// Has the channel owner marked the comment with a ❤️ heart ?
pub hearted: bool,
}