diff --git a/cli/src/main.rs b/cli/src/main.rs index 6c21cde..6ab09a9 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -49,7 +49,8 @@ async fn download_single_video( main: Option, ) -> Result<()> { let pb = multi.add(ProgressBar::new(1)); - pb.set_style(ProgressStyle::with_template("{msg}\n{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({bytes_per_sec}, {eta})").unwrap() + pb.set_style(ProgressStyle::default_bar() + .template("{msg}\n{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({bytes_per_sec}, {eta})").unwrap() .progress_chars("#>-")); pb.set_message(format!("Fetching player data for {}", video_title)); diff --git a/src/client/player.rs b/src/client/player.rs index 129a9fb..88f3d90 100644 --- a/src/client/player.rs +++ b/src/client/player.rs @@ -12,8 +12,8 @@ use crate::{ deobfuscate::Deobfuscator, error::{DeobfError, Error, ExtractionError}, model::{ - AudioCodec, AudioFormat, AudioStream, AudioTrack, ChannelId, QualityOrd, Subtitle, - VideoCodec, VideoFormat, VideoPlayer, VideoPlayerDetails, VideoStream, + AudioCodec, AudioFormat, AudioStream, AudioTrack, ChannelId, Subtitle, VideoCodec, + VideoFormat, VideoPlayer, VideoPlayerDetails, VideoStream, }, param::Language, util, @@ -244,9 +244,9 @@ impl MapResponse for response::Player { } } - video_streams.sort_by(QualityOrd::quality_cmp); - video_only_streams.sort_by(QualityOrd::quality_cmp); - audio_streams.sort_by(QualityOrd::quality_cmp); + video_streams.sort(); + video_only_streams.sort(); + audio_streams.sort(); let subtitles = self.captions.map_or(Vec::new(), |captions| { captions diff --git a/src/download.rs b/src/download.rs index 00738c9..4dc144e 100644 --- a/src/download.rs +++ b/src/download.rs @@ -1,10 +1,10 @@ //! YouTube audio/video downloader -use std::{borrow::Cow, cmp::Ordering, ffi::OsString, ops::Range, path::PathBuf, time::Duration}; +use std::{borrow::Cow, cmp::Ordering, ffi::OsString, ops::Range, path::PathBuf}; use fancy_regex::Regex; use futures::stream::{self, StreamExt}; -use indicatif::{ProgressBar, ProgressStyle}; +use indicatif::ProgressBar; use log::{debug, info}; use once_cell::sync::Lazy; use rand::Rng; @@ -150,7 +150,7 @@ async fn download_single_file>( let mut file = fs::OpenOptions::new() .append(true) .create(true) - .open(&output_path_tmp) + .open(output_path_tmp.to_owned()) .await?; if is_gvideo && size.is_some() { @@ -159,7 +159,7 @@ async fn download_single_file>( download_chunks_by_header(http, &mut file, url, size, offset, pb).await?; } - fs::rename(&output_path_tmp, &output_path).await?; + fs::rename(output_path_tmp, output_path).await?; Ok(()) } @@ -391,13 +391,7 @@ pub async fn download_video( download_streams(&downloads, http, pb.clone()).await?; pb.set_message(format!("Converting {}", title)); - pb.set_style( - ProgressStyle::with_template("{msg}\n{spinner:.green} [{elapsed_precise}]") - .unwrap(), - ); - pb.enable_steady_tick(Duration::from_millis(100)); convert_streams(&downloads, output_path, ffmpeg).await?; - pb.disable_steady_tick(); // Delete original files stream::iter(&downloads) diff --git a/src/model/mod.rs b/src/model/mod.rs index db0a4b0..31d2291 100644 --- a/src/model/mod.rs +++ b/src/model/mod.rs @@ -6,7 +6,6 @@ mod paginator; pub mod richtext; pub use convert::FromYtItem; -pub use ordering::QualityOrd; pub use paginator::Paginator; use serde_with::serde_as; @@ -192,7 +191,7 @@ pub struct VideoStream { } /// Audio stream -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[non_exhaustive] pub struct AudioStream { /// Audio stream URL diff --git a/src/model/ordering.rs b/src/model/ordering.rs index 012f35b..e7df9af 100644 --- a/src/model/ordering.rs +++ b/src/model/ordering.rs @@ -4,26 +4,30 @@ use crate::model::AudioCodec; use super::{AudioStream, VideoStream}; -pub trait QualityOrd { - fn quality_cmp(&self, other: &Self) -> Ordering; -} - -impl QualityOrd for VideoStream { - fn quality_cmp(&self, other: &Self) -> Ordering { - match (self.width * self.height).cmp(&(other.width * other.height)) { - Ordering::Less => Ordering::Less, - Ordering::Greater => Ordering::Greater, - Ordering::Equal => match self.codec.cmp(&other.codec) { +impl PartialOrd for VideoStream { + fn partial_cmp(&self, other: &Self) -> Option { + Some( + match (self.width * self.height).cmp(&(other.width * other.height)) { Ordering::Less => Ordering::Less, Ordering::Greater => Ordering::Greater, - Ordering::Equal => self.average_bitrate.cmp(&other.average_bitrate), + Ordering::Equal => match self.codec.cmp(&other.codec) { + Ordering::Less => Ordering::Less, + Ordering::Greater => Ordering::Greater, + Ordering::Equal => self.average_bitrate.cmp(&other.average_bitrate), + }, }, - } + ) } } -impl QualityOrd for AudioStream { - fn quality_cmp(&self, other: &Self) -> Ordering { +impl Ord for VideoStream { + fn cmp(&self, other: &Self) -> Ordering { + self.partial_cmp(other).unwrap() + } +} + +impl PartialOrd for AudioStream { + fn partial_cmp(&self, other: &Self) -> Option { fn cmp_bitrate(s: &AudioStream) -> u32 { match s.codec { // Opus is more efficient @@ -32,6 +36,12 @@ impl QualityOrd for AudioStream { } } - cmp_bitrate(self).cmp(&cmp_bitrate(other)) + Some(cmp_bitrate(self).cmp(&cmp_bitrate(other))) + } +} + +impl Ord for AudioStream { + fn cmp(&self, other: &Self) -> Ordering { + self.partial_cmp(other).unwrap() } } diff --git a/src/param/stream_filter.rs b/src/param/stream_filter.rs index 64d32c5..ce14c3e 100644 --- a/src/param/stream_filter.rs +++ b/src/param/stream_filter.rs @@ -1,10 +1,9 @@ //! Filters for selecting audio/video streams -use std::{cmp::Ordering, collections::HashSet}; +use std::collections::HashSet; use crate::model::{ - AudioCodec, AudioFormat, AudioStream, QualityOrd, VideoCodec, VideoFormat, VideoPlayer, - VideoStream, + AudioCodec, AudioFormat, AudioStream, VideoCodec, VideoFormat, VideoPlayer, VideoStream, }; #[derive(Debug, Default, Clone)] @@ -303,15 +302,14 @@ impl VideoPlayer { (Some(video_only_stream), self.select_audio_stream(filter)) } (Some(video_stream), None) => (Some(video_stream), None), - (Some(video_stream), Some(video_only_stream)) => { - match video_only_stream.quality_cmp(video_stream) { - Ordering::Greater => match self.select_audio_stream(filter) { - Some(audio_stream) => (Some(video_only_stream), Some(audio_stream)), - None => (Some(video_stream), None), - }, - _ => (Some(video_stream), None), - } - } + (Some(video_stream), Some(video_only_stream)) => match video_only_stream > video_stream + { + true => match self.select_audio_stream(filter) { + Some(audio_stream) => (Some(video_only_stream), Some(audio_stream)), + None => (Some(video_stream), None), + }, + false => (Some(video_stream), None), + }, } } }