feat: add playlist extraction
- replace original base.js with dummy
This commit is contained in:
parent
5db85c05e8
commit
5b8c3d646a
30 changed files with 123935 additions and 40441 deletions
|
|
@ -1,5 +1,5 @@
|
|||
pub mod stream_filter;
|
||||
mod ordering;
|
||||
pub mod stream_filter;
|
||||
|
||||
use std::ops::Range;
|
||||
|
||||
|
|
@ -11,7 +11,7 @@ pub trait FileFormat {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct PlayerData {
|
||||
pub struct VideoPlayer {
|
||||
pub info: VideoInfo,
|
||||
pub video_streams: Vec<VideoStream>,
|
||||
pub video_only_streams: Vec<VideoStream>,
|
||||
|
|
@ -20,6 +20,17 @@ pub struct PlayerData {
|
|||
pub expires_in_seconds: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Playlist {
|
||||
pub videos: Vec<Video>,
|
||||
pub n_videos: u32,
|
||||
pub ctoken: Option<String>,
|
||||
pub name: String,
|
||||
pub thumbnails: Vec<Thumbnail>,
|
||||
pub description: Option<String>,
|
||||
pub channel: Option<Channel>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct VideoInfo {
|
||||
pub id: String,
|
||||
|
|
@ -27,18 +38,13 @@ pub struct VideoInfo {
|
|||
pub description: Option<String>,
|
||||
pub length: u32,
|
||||
pub thumbnails: Vec<Thumbnail>,
|
||||
|
||||
pub channel_id: String,
|
||||
pub channel_name: String,
|
||||
|
||||
pub channel: Channel,
|
||||
pub publish_date: Option<DateTime<Utc>>,
|
||||
pub view_count: u64,
|
||||
pub keywords: Vec<String>,
|
||||
pub category: Option<String>,
|
||||
pub is_live_content: bool,
|
||||
pub is_family_safe: Option<bool>,
|
||||
// pub like_count: Option<u32>,
|
||||
// pub dislike_count: Option<u32>
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
|
|
@ -85,13 +91,13 @@ pub struct AudioStream {
|
|||
pub enum VideoCodec {
|
||||
#[default]
|
||||
Unknown,
|
||||
/// MPEG-4 Part 14 https://en.wikipedia.org/wiki/MPEG-4_Part_14
|
||||
/// 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 aka H.264: <https://en.wikipedia.org/wiki/Advanced_Video_Coding>
|
||||
Avc1,
|
||||
/// VP9: https://en.wikipedia.org/wiki/VP9
|
||||
/// VP9: <https://en.wikipedia.org/wiki/VP9>
|
||||
Vp9,
|
||||
/// AV1, the latest codec: https://en.wikipedia.org/wiki/AV1
|
||||
/// AV1, the latest codec: <https://en.wikipedia.org/wiki/AV1>
|
||||
Av01,
|
||||
}
|
||||
|
||||
|
|
@ -103,9 +109,9 @@ pub enum VideoCodec {
|
|||
pub enum AudioCodec {
|
||||
#[default]
|
||||
Unknown,
|
||||
/// MP4A aka AAC: https://en.wikipedia.org/wiki/Advanced_Audio_Coding
|
||||
/// MP4A aka AAC: <https://en.wikipedia.org/wiki/Advanced_Audio_Coding>
|
||||
Mp4a,
|
||||
/// Opus: https://en.wikipedia.org/wiki/Opus_(audio_format)
|
||||
/// Opus: <https://en.wikipedia.org/wiki/Opus_(audio_format)>
|
||||
Opus,
|
||||
}
|
||||
|
||||
|
|
@ -175,3 +181,18 @@ pub struct Locale {
|
|||
pub lang: String,
|
||||
pub country: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct Video {
|
||||
pub id: String,
|
||||
pub title: String,
|
||||
pub length: u32,
|
||||
pub thumbnails: Vec<Thumbnail>,
|
||||
pub channel: Channel,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct Channel {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
use super::{
|
||||
AudioCodec, AudioFormat, AudioStream, PlayerData, VideoCodec, VideoFormat, VideoStream,
|
||||
AudioCodec, AudioFormat, AudioStream, VideoCodec, VideoFormat, VideoPlayer, VideoStream,
|
||||
};
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
|
|
@ -108,7 +108,7 @@ impl Filter {
|
|||
|
||||
/// Set the preferred audio language (2 letter ISO 639-1 code, e.g. `en`, `fr`).
|
||||
/// Some YouTube videos feature multiple audio streams in
|
||||
/// different languages (e.g. https://www.youtube.com/watch?v=tVWWp1PqDus).
|
||||
/// different languages (e.g. <https://www.youtube.com/watch?v=tVWWp1PqDus>).
|
||||
///
|
||||
/// If this filter is unset or no stream matches,
|
||||
/// the filter returns the default audio stream.
|
||||
|
|
@ -232,7 +232,7 @@ impl Filter {
|
|||
}
|
||||
}
|
||||
|
||||
impl PlayerData {
|
||||
impl VideoPlayer {
|
||||
pub fn select_audio_stream(&self, filter: &Filter) -> Option<&AudioStream> {
|
||||
let mut fallback: Option<&AudioStream> = None;
|
||||
|
||||
|
|
@ -324,21 +324,25 @@ impl PlayerData {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::{fs::File, io::BufReader, path::Path};
|
||||
|
||||
use super::*;
|
||||
use once_cell::sync::Lazy;
|
||||
use rstest::rstest;
|
||||
use velcro::hash_set;
|
||||
|
||||
const PLAYER_ML: Lazy<PlayerData> = Lazy::new(|| {
|
||||
serde_json::from_str::<PlayerData>(include_str!(
|
||||
"../../testfiles/player_model/multilanguage.json"
|
||||
))
|
||||
.unwrap()
|
||||
const PLAYER_ML: Lazy<VideoPlayer> = Lazy::new(|| {
|
||||
let json_path = Path::new("testfiles/player_model/multilanguage.json");
|
||||
let json_file = File::open(json_path).unwrap();
|
||||
|
||||
serde_json::from_reader(BufReader::new(json_file)).unwrap()
|
||||
});
|
||||
|
||||
const PLAYER_HDR: Lazy<PlayerData> = Lazy::new(|| {
|
||||
serde_json::from_str::<PlayerData>(include_str!("../../testfiles/player_model/hdr.json"))
|
||||
.unwrap()
|
||||
const PLAYER_HDR: Lazy<VideoPlayer> = Lazy::new(|| {
|
||||
let json_path = Path::new("testfiles/player_model/hdr.json");
|
||||
let json_file = File::open(json_path).unwrap();
|
||||
|
||||
serde_json::from_reader(BufReader::new(json_file)).unwrap()
|
||||
});
|
||||
|
||||
#[rstest]
|
||||
|
|
|
|||
Reference in a new issue