Compare commits

..

No commits in common. "f748b98ccc9e48f49bd7732552071f0db3bdee0a" and "6e2ba71f33a828d3dc6c66a0a942b329ecfef857" have entirely different histories.

6 changed files with 47 additions and 45 deletions

View file

@ -49,7 +49,8 @@ async fn download_single_video(
main: Option<ProgressBar>, main: Option<ProgressBar>,
) -> Result<()> { ) -> Result<()> {
let pb = multi.add(ProgressBar::new(1)); 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("#>-")); .progress_chars("#>-"));
pb.set_message(format!("Fetching player data for {}", video_title)); pb.set_message(format!("Fetching player data for {}", video_title));

View file

@ -12,8 +12,8 @@ use crate::{
deobfuscate::Deobfuscator, deobfuscate::Deobfuscator,
error::{DeobfError, Error, ExtractionError}, error::{DeobfError, Error, ExtractionError},
model::{ model::{
AudioCodec, AudioFormat, AudioStream, AudioTrack, ChannelId, QualityOrd, Subtitle, AudioCodec, AudioFormat, AudioStream, AudioTrack, ChannelId, Subtitle, VideoCodec,
VideoCodec, VideoFormat, VideoPlayer, VideoPlayerDetails, VideoStream, VideoFormat, VideoPlayer, VideoPlayerDetails, VideoStream,
}, },
param::Language, param::Language,
util, util,
@ -244,9 +244,9 @@ impl MapResponse<VideoPlayer> for response::Player {
} }
} }
video_streams.sort_by(QualityOrd::quality_cmp); video_streams.sort();
video_only_streams.sort_by(QualityOrd::quality_cmp); video_only_streams.sort();
audio_streams.sort_by(QualityOrd::quality_cmp); audio_streams.sort();
let subtitles = self.captions.map_or(Vec::new(), |captions| { let subtitles = self.captions.map_or(Vec::new(), |captions| {
captions captions

View file

@ -1,10 +1,10 @@
//! YouTube audio/video downloader //! 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 fancy_regex::Regex;
use futures::stream::{self, StreamExt}; use futures::stream::{self, StreamExt};
use indicatif::{ProgressBar, ProgressStyle}; use indicatif::ProgressBar;
use log::{debug, info}; use log::{debug, info};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use rand::Rng; use rand::Rng;
@ -150,7 +150,7 @@ async fn download_single_file<P: Into<PathBuf>>(
let mut file = fs::OpenOptions::new() let mut file = fs::OpenOptions::new()
.append(true) .append(true)
.create(true) .create(true)
.open(&output_path_tmp) .open(output_path_tmp.to_owned())
.await?; .await?;
if is_gvideo && size.is_some() { if is_gvideo && size.is_some() {
@ -159,7 +159,7 @@ async fn download_single_file<P: Into<PathBuf>>(
download_chunks_by_header(http, &mut file, url, size, offset, pb).await?; 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(()) Ok(())
} }
@ -391,13 +391,7 @@ pub async fn download_video(
download_streams(&downloads, http, pb.clone()).await?; download_streams(&downloads, http, pb.clone()).await?;
pb.set_message(format!("Converting {}", title)); 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?; convert_streams(&downloads, output_path, ffmpeg).await?;
pb.disable_steady_tick();
// Delete original files // Delete original files
stream::iter(&downloads) stream::iter(&downloads)

View file

@ -6,7 +6,6 @@ mod paginator;
pub mod richtext; pub mod richtext;
pub use convert::FromYtItem; pub use convert::FromYtItem;
pub use ordering::QualityOrd;
pub use paginator::Paginator; pub use paginator::Paginator;
use serde_with::serde_as; use serde_with::serde_as;
@ -192,7 +191,7 @@ pub struct VideoStream {
} }
/// Audio stream /// Audio stream
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[non_exhaustive] #[non_exhaustive]
pub struct AudioStream { pub struct AudioStream {
/// Audio stream URL /// Audio stream URL

View file

@ -4,12 +4,9 @@ use crate::model::AudioCodec;
use super::{AudioStream, VideoStream}; use super::{AudioStream, VideoStream};
pub trait QualityOrd { impl PartialOrd for VideoStream {
fn quality_cmp(&self, other: &Self) -> Ordering; fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
} Some(
impl QualityOrd for VideoStream {
fn quality_cmp(&self, other: &Self) -> Ordering {
match (self.width * self.height).cmp(&(other.width * other.height)) { match (self.width * self.height).cmp(&(other.width * other.height)) {
Ordering::Less => Ordering::Less, Ordering::Less => Ordering::Less,
Ordering::Greater => Ordering::Greater, Ordering::Greater => Ordering::Greater,
@ -18,12 +15,19 @@ impl QualityOrd for VideoStream {
Ordering::Greater => Ordering::Greater, Ordering::Greater => Ordering::Greater,
Ordering::Equal => self.average_bitrate.cmp(&other.average_bitrate), Ordering::Equal => self.average_bitrate.cmp(&other.average_bitrate),
}, },
} },
)
} }
} }
impl QualityOrd for AudioStream { impl Ord for VideoStream {
fn quality_cmp(&self, other: &Self) -> Ordering { fn cmp(&self, other: &Self) -> Ordering {
self.partial_cmp(other).unwrap()
}
}
impl PartialOrd for AudioStream {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
fn cmp_bitrate(s: &AudioStream) -> u32 { fn cmp_bitrate(s: &AudioStream) -> u32 {
match s.codec { match s.codec {
// Opus is more efficient // 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()
} }
} }

View file

@ -1,10 +1,9 @@
//! Filters for selecting audio/video streams //! Filters for selecting audio/video streams
use std::{cmp::Ordering, collections::HashSet}; use std::collections::HashSet;
use crate::model::{ use crate::model::{
AudioCodec, AudioFormat, AudioStream, QualityOrd, VideoCodec, VideoFormat, VideoPlayer, AudioCodec, AudioFormat, AudioStream, VideoCodec, VideoFormat, VideoPlayer, VideoStream,
VideoStream,
}; };
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
@ -303,15 +302,14 @@ impl VideoPlayer {
(Some(video_only_stream), self.select_audio_stream(filter)) (Some(video_only_stream), self.select_audio_stream(filter))
} }
(Some(video_stream), None) => (Some(video_stream), None), (Some(video_stream), None) => (Some(video_stream), None),
(Some(video_stream), Some(video_only_stream)) => { (Some(video_stream), Some(video_only_stream)) => match video_only_stream > video_stream
match video_only_stream.quality_cmp(video_stream) { {
Ordering::Greater => match self.select_audio_stream(filter) { true => match self.select_audio_stream(filter) {
Some(audio_stream) => (Some(video_only_stream), Some(audio_stream)), Some(audio_stream) => (Some(video_only_stream), Some(audio_stream)),
None => (Some(video_stream), None), None => (Some(video_stream), None),
}, },
_ => (Some(video_stream), None), false => (Some(video_stream), None),
} },
}
} }
} }
} }