Compare commits

..

2 commits

Author SHA1 Message Date
f748b98ccc fix: error with clippy 1.65 2022-11-04 19:59:41 +01:00
a706eb172e fix: stream ordering, downloader progress bar 2022-11-04 19:45:58 +01:00
6 changed files with 45 additions and 47 deletions

View file

@ -49,8 +49,7 @@ 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::default_bar() pb.set_style(ProgressStyle::with_template("{msg}\n{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({bytes_per_sec}, {eta})").unwrap()
.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, Subtitle, VideoCodec, AudioCodec, AudioFormat, AudioStream, AudioTrack, ChannelId, QualityOrd, Subtitle,
VideoFormat, VideoPlayer, VideoPlayerDetails, VideoStream, VideoCodec, VideoFormat, VideoPlayer, VideoPlayerDetails, VideoStream,
}, },
param::Language, param::Language,
util, util,
@ -244,9 +244,9 @@ impl MapResponse<VideoPlayer> for response::Player {
} }
} }
video_streams.sort(); video_streams.sort_by(QualityOrd::quality_cmp);
video_only_streams.sort(); video_only_streams.sort_by(QualityOrd::quality_cmp);
audio_streams.sort(); audio_streams.sort_by(QualityOrd::quality_cmp);
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}; use std::{borrow::Cow, cmp::Ordering, ffi::OsString, ops::Range, path::PathBuf, time::Duration};
use fancy_regex::Regex; use fancy_regex::Regex;
use futures::stream::{self, StreamExt}; use futures::stream::{self, StreamExt};
use indicatif::ProgressBar; use indicatif::{ProgressBar, ProgressStyle};
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.to_owned()) .open(&output_path_tmp)
.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,7 +391,13 @@ 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,6 +6,7 @@ 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;
@ -191,7 +192,7 @@ pub struct VideoStream {
} }
/// Audio stream /// Audio stream
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[non_exhaustive] #[non_exhaustive]
pub struct AudioStream { pub struct AudioStream {
/// Audio stream URL /// Audio stream URL

View file

@ -4,30 +4,26 @@ use crate::model::AudioCodec;
use super::{AudioStream, VideoStream}; use super::{AudioStream, VideoStream};
impl PartialOrd for VideoStream { pub trait QualityOrd {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { fn quality_cmp(&self, other: &Self) -> Ordering;
Some( }
match (self.width * self.height).cmp(&(other.width * other.height)) {
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) {
Ordering::Less => Ordering::Less, Ordering::Less => Ordering::Less,
Ordering::Greater => Ordering::Greater, Ordering::Greater => Ordering::Greater,
Ordering::Equal => match self.codec.cmp(&other.codec) { Ordering::Equal => self.average_bitrate.cmp(&other.average_bitrate),
Ordering::Less => Ordering::Less,
Ordering::Greater => Ordering::Greater,
Ordering::Equal => self.average_bitrate.cmp(&other.average_bitrate),
},
}, },
) }
} }
} }
impl Ord for VideoStream { impl QualityOrd for AudioStream {
fn cmp(&self, other: &Self) -> Ordering { fn quality_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
@ -36,12 +32,6 @@ impl PartialOrd for AudioStream {
} }
} }
Some(cmp_bitrate(self).cmp(&cmp_bitrate(other))) 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,9 +1,10 @@
//! Filters for selecting audio/video streams //! Filters for selecting audio/video streams
use std::collections::HashSet; use std::{cmp::Ordering, collections::HashSet};
use crate::model::{ use crate::model::{
AudioCodec, AudioFormat, AudioStream, VideoCodec, VideoFormat, VideoPlayer, VideoStream, AudioCodec, AudioFormat, AudioStream, QualityOrd, VideoCodec, VideoFormat, VideoPlayer,
VideoStream,
}; };
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
@ -302,14 +303,15 @@ 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)) => match video_only_stream > video_stream (Some(video_stream), Some(video_only_stream)) => {
{ match video_only_stream.quality_cmp(video_stream) {
true => match self.select_audio_stream(filter) { Ordering::Greater => 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),
}, },
false => (Some(video_stream), None), _ => (Some(video_stream), None),
}, }
}
} }
} }
} }