mirror of
https://github.com/lifegpc/pixiv_downloader.git
synced 2026-07-02 11:20:44 +08:00
@@ -360,6 +360,12 @@ pub async fn download_artwork(
|
||||
if !profile.is_auto() {
|
||||
options.set("profile", profile.as_str(), None)?;
|
||||
}
|
||||
match helper.x264_crf() {
|
||||
Some(crf) => {
|
||||
options.set("crf", format!("{}", crf), None)?;
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
let frames = UgoiraFrames::from_json(&ugoira_data["frames"])?;
|
||||
let output_file_name = base.join(format!("{}.mp4", id));
|
||||
convert_ugoira_to_mp4(
|
||||
|
||||
8
src/opt/crf.rs
Normal file
8
src/opt/crf.rs
Normal file
@@ -0,0 +1,8 @@
|
||||
use json::JsonValue;
|
||||
|
||||
pub fn check_crf(obj: &JsonValue) -> bool {
|
||||
match obj.as_f32() {
|
||||
Some(crf) => crf >= -1f32,
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
/// Author name filters
|
||||
pub mod author_name_filter;
|
||||
#[cfg(feature = "ugoira")]
|
||||
/// libx264 Constant Rate Factor settings
|
||||
pub mod crf;
|
||||
/// Proxy settings
|
||||
pub mod proxy;
|
||||
pub mod size;
|
||||
|
||||
@@ -439,6 +439,22 @@ impl OptHelper {
|
||||
false
|
||||
}
|
||||
|
||||
#[cfg(feature = "ugoira")]
|
||||
/// The Constant Rate Factor when converting ugoira(GIF) to video.
|
||||
pub fn x264_crf(&self) -> Option<f32> {
|
||||
match self.opt.get_ref().x264_crf {
|
||||
Some(r) => {
|
||||
return Some(r);
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
if self.settings.get_ref().have("x264-crf") {
|
||||
let v = self.settings.get_ref().get("x264-crf").unwrap();
|
||||
return v.as_f32();
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(feature = "ugoira")]
|
||||
/// Return the x264 profile when converting ugoira(GIF) to video.
|
||||
pub fn x264_profile(&self) -> X264Profile {
|
||||
@@ -449,7 +465,7 @@ impl OptHelper {
|
||||
None => {}
|
||||
}
|
||||
if self.settings.get_ref().have("x264-profile") {
|
||||
let v = self.settings.get_ref().get("server").unwrap();
|
||||
let v = self.settings.get_ref().get("x264-profile").unwrap();
|
||||
return X264Profile::from_str(v.as_str().unwrap()).unwrap();
|
||||
}
|
||||
X264Profile::default()
|
||||
|
||||
52
src/opts.rs
52
src/opts.rs
@@ -13,6 +13,8 @@ use std::convert::TryFrom;
|
||||
use std::env;
|
||||
#[cfg(feature = "server")]
|
||||
use std::net::SocketAddr;
|
||||
#[cfg(feature = "ugoira")]
|
||||
use std::num::ParseFloatError;
|
||||
use std::num::ParseIntError;
|
||||
use std::num::TryFromIntError;
|
||||
use std::str::FromStr;
|
||||
@@ -113,6 +115,9 @@ pub struct CommandOpts {
|
||||
pub user_agent: Option<String>,
|
||||
/// Urls want to download
|
||||
pub urls: Option<Vec<String>>,
|
||||
#[cfg(feature = "ugoira")]
|
||||
/// The Constant Rate Factor when converting ugoira(GIF) to video.
|
||||
pub x264_crf: Option<f32>,
|
||||
}
|
||||
|
||||
impl CommandOpts {
|
||||
@@ -151,6 +156,8 @@ impl CommandOpts {
|
||||
download_base: None,
|
||||
user_agent: None,
|
||||
urls: None,
|
||||
#[cfg(feature = "ugoira")]
|
||||
x264_crf: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,6 +267,20 @@ pub fn parse_bool<T: AsRef<str>>(s: Option<T>) -> Result<Option<bool>, String> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ugoira")]
|
||||
/// Parse [f32] from string
|
||||
pub fn parse_f32<T: AsRef<str>>(s: Option<T>) -> Result<Option<f32>, ParseFloatError> {
|
||||
match s {
|
||||
Some(s) => {
|
||||
let s = s.as_ref();
|
||||
let s = s.trim();
|
||||
let c = s.parse::<f32>()?;
|
||||
Ok(Some(c))
|
||||
}
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
/// Prase [i64] from string
|
||||
pub fn parse_i64<T: AsRef<str>>(s: Option<T>) -> Result<Option<i64>, ParseIntError> {
|
||||
match s {
|
||||
@@ -533,6 +554,13 @@ pub fn parse_cmd() -> Option<CommandOpts> {
|
||||
"DIR",
|
||||
);
|
||||
opts.optopt("", "user-agent", gettext("The User-Agent header."), "UA");
|
||||
#[cfg(feature = "ugoira")]
|
||||
opts.optopt(
|
||||
"",
|
||||
"x264-crf",
|
||||
gettext("The Constant Rate Factor when converting ugoira(GIF) to video."),
|
||||
"float",
|
||||
);
|
||||
let result = match opts.parse(&argv[1..]) {
|
||||
Ok(m) => m,
|
||||
Err(err) => {
|
||||
@@ -830,6 +858,30 @@ pub fn parse_cmd() -> Option<CommandOpts> {
|
||||
}
|
||||
re.as_mut().unwrap().download_base = result.opt_str("download-base");
|
||||
re.as_mut().unwrap().user_agent = result.opt_str("user-agent");
|
||||
#[cfg(feature = "ugoira")]
|
||||
match parse_optional_opt(&result, "x264-crf", -1f32, parse_f32) {
|
||||
Ok(r) => match r {
|
||||
Some(crf) => {
|
||||
if crf < -1f32 {
|
||||
println!("{}", gettext("x264-crf can not less than -1."));
|
||||
return None;
|
||||
} else {
|
||||
re.as_mut().unwrap().x264_crf.replace(crf);
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
},
|
||||
Err(e) => {
|
||||
println!(
|
||||
"{} {}",
|
||||
("Failed to parse <opt>:")
|
||||
.replace("<opt>", "x264-crf")
|
||||
.as_str(),
|
||||
e
|
||||
);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
re
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ use crate::retry_interval::check_retry_interval;
|
||||
use crate::settings::SettingDes;
|
||||
use crate::settings::JsonValueType;
|
||||
use crate::opt::author_name_filter::check_author_name_filters;
|
||||
#[cfg(feature = "ugoira")]
|
||||
use crate::opt::crf::check_crf;
|
||||
use crate::opt::proxy::check_proxy;
|
||||
use crate::opt::size::parse_u32_size;
|
||||
#[cfg(feature = "server")]
|
||||
@@ -55,6 +57,8 @@ pub fn get_settings_list() -> Vec<SettingDes> {
|
||||
SettingDes::new("db", gettext("Database settings."), JsonValueType::Object, Some(check_db_config)).unwrap(),
|
||||
SettingDes::new("download-base", gettext("The base directory to save downloaded files."), JsonValueType::Str, None).unwrap(),
|
||||
SettingDes::new("user-agent", gettext("The User-Agent header."), JsonValueType::Str, None).unwrap(),
|
||||
#[cfg(feature = "ugoira")]
|
||||
SettingDes::new("x264-crf", gettext("The Constant Rate Factor when converting ugoira(GIF) to video."), JsonValueType::Number, Some(check_crf)).unwrap(),
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ UgoiraError convert_ugoira_to_mp4(const char* src, const char* dest, const Ugoir
|
||||
int err = UGOIRA_OK;
|
||||
int zip_err = 0;
|
||||
zip_t* zip = NULL;
|
||||
int dcrf = 18;
|
||||
float dcrf = 18.0;
|
||||
AVDictionaryEntry* tmp_ent = NULL;
|
||||
if (max_fps <= 0) {
|
||||
return RERR(UGOIRA_INVALID_MAX_FPS);
|
||||
@@ -174,8 +174,8 @@ UgoiraError convert_ugoira_to_mp4(const char* src, const char* dest, const Ugoir
|
||||
}
|
||||
tmp_ent = av_dict_get(opts, "crf", NULL, 0);
|
||||
if (tmp_ent) {
|
||||
int tmp = 0;
|
||||
if (sscanf(tmp_ent->value, "%i", &tmp) != 1) {
|
||||
float tmp = 0;
|
||||
if (sscanf(tmp_ent->value, "%f", &tmp) != 1) {
|
||||
return RERR(UGOIRA_INVALID_CRF);
|
||||
}
|
||||
dcrf = tmp;
|
||||
@@ -331,7 +331,7 @@ UgoiraError convert_ugoira_to_mp4(const char* src, const char* dest, const Ugoir
|
||||
} else {
|
||||
av_opt_set(eoc->priv_data, "preset", "slow", 0);
|
||||
}
|
||||
av_opt_set_int(eoc->priv_data, "crf", dcrf, 0);
|
||||
av_opt_set_double(eoc->priv_data, "crf", dcrf, 0);
|
||||
if (opts) {
|
||||
tmp = av_dict_get(opts, "level", NULL, 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user