Start introducing more video controls

This commit is contained in:
asonix 2022-09-25 17:36:07 -05:00
parent c9a74a73ca
commit c57a48db8a
6 changed files with 45 additions and 2 deletions

View File

@ -51,7 +51,9 @@ impl Args {
media_max_height,
media_max_area,
media_max_file_size,
media_max_frame_count,
media_enable_silent_video,
media_enable_full_video,
media_filters,
media_format,
media_cache_duration,
@ -69,7 +71,9 @@ impl Args {
max_height: media_max_height,
max_area: media_max_area,
max_file_size: media_max_file_size,
max_frame_count: media_max_frame_count,
enable_silent_video: media_enable_silent_video,
enable_full_video: media_enable_full_video,
filters: media_filters,
format: media_format,
cache_duration: media_cache_duration,
@ -312,8 +316,12 @@ struct Media {
#[serde(skip_serializing_if = "Option::is_none")]
max_file_size: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
max_frame_count: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
enable_silent_video: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
enable_full_video: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
filters: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
format: Option<ImageFormat>,
@ -412,9 +420,15 @@ struct Run {
/// The maximum size, in megabytes, for uploaded media
#[clap(long)]
media_max_file_size: Option<usize>,
/// Whether to enable GIF and silent MP4 uploads. Full videos are unsupported
/// The maximum number of frames allowed for uploaded GIF and MP4s.
#[clap(long)]
media_max_frame_count: Option<usize>,
/// Whether to enable GIF and silent MP4 uploads
#[clap(long)]
media_enable_silent_video: Option<bool>,
/// Whether to enable full MP4 uploads
#[clap(long)]
media_enable_full_video: Option<bool>,
/// Which media filters should be enabled on the `process` endpoint
#[clap(long)]
media_filters: Option<Vec<String>>,

View File

@ -65,7 +65,9 @@ struct MediaDefaults {
max_height: usize,
max_area: usize,
max_file_size: usize,
max_frame_count: usize,
enable_silent_video: bool,
enable_full_video: bool,
filters: Vec<String>,
skip_validate_imports: bool,
cache_duration: i64,
@ -150,7 +152,9 @@ impl Default for MediaDefaults {
max_height: 10_000,
max_area: 40_000_000,
max_file_size: 40,
max_frame_count: 3_600,
enable_silent_video: true,
enable_full_video: false,
filters: vec![
"blur".into(),
"crop".into(),

View File

@ -98,8 +98,12 @@ pub(crate) struct Media {
pub(crate) max_file_size: usize,
pub(crate) max_frame_count: usize,
pub(crate) enable_silent_video: bool,
pub(crate) enable_full_video: bool,
pub(crate) filters: BTreeSet<String>,
#[serde(skip_serializing_if = "Option::is_none")]

View File

@ -12,6 +12,7 @@ enum MaybeHumanDate {
pub(crate) struct Details {
width: usize,
height: usize,
frames: Option<usize>,
content_type: Serde<mime::Mime>,
created_at: MaybeHumanDate,
}
@ -33,6 +34,7 @@ impl Details {
details.width,
details.height,
details.mime_type,
details.frames,
))
}
@ -48,13 +50,15 @@ impl Details {
details.width,
details.height,
details.mime_type,
details.frames,
))
}
pub(crate) fn now(width: usize, height: usize, content_type: mime::Mime) -> Self {
pub(crate) fn now(width: usize, height: usize, content_type: mime::Mime, frames: Option<usize>) -> Self {
Details {
width,
height,
frames,
content_type: Serde::new(content_type),
created_at: MaybeHumanDate::HumanDate(time::OffsetDateTime::now_utc()),
}

View File

@ -99,6 +99,9 @@ pub(crate) enum UploadError {
#[error("Invalid media dimensions")]
Dimensions,
#[error("Too many frames")]
Frames,
#[error("Unable to download image, bad response {0}")]
Download(actix_web::http::StatusCode),

View File

@ -86,6 +86,7 @@ pub(crate) struct Details {
pub(crate) mime_type: mime::Mime,
pub(crate) width: usize,
pub(crate) height: usize,
pub(crate) frames: Option<usize>,
}
#[tracing::instrument(name = "Clear Metadata", skip(input))]
@ -210,6 +211,8 @@ pub(crate) async fn details_file(path_str: &str) -> Result<Details, Error> {
}
fn parse_details(s: std::borrow::Cow<'_, str>) -> Result<Details, Error> {
let frames = s.lines().count();
let mut lines = s.lines();
let first = lines.next().ok_or(UploadError::UnsupportedFormat)?;
@ -257,6 +260,11 @@ fn parse_details(s: std::borrow::Cow<'_, str>) -> Result<Details, Error> {
mime_type,
width,
height,
frames: if frames > 1 {
Some(frames)
} else {
None
},
})
}
@ -307,6 +315,12 @@ impl Details {
return Err(UploadError::Dimensions.into());
}
if let Some(frames) = self.frames {
if frames > crate::CONFIG.media.max_frame_count {
return Err(UploadError::Frames.into());
}
}
let input_type = match (self.mime_type.type_(), self.mime_type.subtype()) {
(mime::VIDEO, mime::MP4 | mime::MPEG) => ValidInputType::Mp4,
(mime::IMAGE, mime::GIF) => ValidInputType::Gif,