diff --git a/Cargo.lock b/Cargo.lock index 49a533e669af4d801be6601f9fba174090536faa..9b025daa4181e1510a78ee6f9d266fd1fb3eec4a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -540,9 +540,9 @@ dependencies = [ [[package]] name = "itoa" -version = "0.4.5" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jobserver" @@ -625,7 +625,7 @@ dependencies = [ [[package]] name = "media-ingestion" -version = "0.2.0" +version = "1.0.0" dependencies = [ "anyhow", "ffmpeg_api", @@ -1110,11 +1110,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.57" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -1163,9 +1164,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.18" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33f6461027d7f08a13715659b2948e1602c31a3756aeae9378bfe7518c72e82" +checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" dependencies = [ "clap", "lazy_static", @@ -1174,9 +1175,9 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.11" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c92e775028122a4b3dd55d58f14fc5120289c69bee99df1d117ae30f84b225c9" +checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" dependencies = [ "heck 0.3.1", "proc-macro-error", diff --git a/Cargo.toml b/Cargo.toml index d1df18c8417ae2a2fb76efd9b7deeb501bd1473f..7ca921229f74727f08c441614f0e50e80fa51716 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,17 +12,17 @@ repository = "https://github.com/justjanne/media-ingestion" readme = "README.md" license = "MPL-2.0" -edition = "2018" +edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -anyhow = "1.0.32" +anyhow = "1.0.98" fraction = "0.15.3" image = "0.25.6" -serde_json = "1.0.57" -serde = { version = "1.0.116", features = ["derive"] } -structopt = "0.3.18" +serde_json = "1.0.140" +serde = { version = "1.0.219", features = ["derive"] } +structopt = "0.3.26" ffmpeg_api = { path = "lib/ffmpeg_api" } media_time = { path = "lib/media_time" } diff --git a/lib/ffmpeg_api/Cargo.toml b/lib/ffmpeg_api/Cargo.toml index 407e9caab7441d469ba151b78f133e63d58ba7b1..4b7ae65238ef3fe68106621c7f858378e6f00baa 100644 --- a/lib/ffmpeg_api/Cargo.toml +++ b/lib/ffmpeg_api/Cargo.toml @@ -2,7 +2,7 @@ name = "ffmpeg_api" version = "0.1.0" authors = ["Janne Mareike Koschinski <janne@kuschku.de>"] -edition = "2018" +edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/lib/media_time/Cargo.toml b/lib/media_time/Cargo.toml index 6420efc39143cffdef20eddd8a7f02939615f727..224647b892c7fe1fcb3daf4c43efc6d1bc57003c 100644 --- a/lib/media_time/Cargo.toml +++ b/lib/media_time/Cargo.toml @@ -2,7 +2,7 @@ name = "media_time" version = "0.1.0" authors = ["Janne Mareike Koschinski <janne@kuschku.de>"] -edition = "2018" +edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/lib/webvtt/Cargo.toml b/lib/webvtt/Cargo.toml index 178a5cca295eebefdd64ef1c9ded38e281a541b6..20de307eb23f6175c8023ae72437eb96842ff76f 100644 --- a/lib/webvtt/Cargo.toml +++ b/lib/webvtt/Cargo.toml @@ -2,7 +2,7 @@ name = "webvtt" version = "0.1.0" authors = ["Janne Mareike Koschinski <janne@kuschku.de>"] -edition = "2018" +edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/lib.rs b/src/lib.rs index c806a501416782690a19b93fba88901759b65340..09c48ece0dfbd4f03fd1cc64c3c367a19ab47c82 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,22 +1,20 @@ #![allow(dead_code)] pub mod spritesheet; +mod options; use std::path::Path; use anyhow::format_err; use ffmpeg_api::api::*; use ffmpeg_api::enums::*; -use image::ImageFormat as ImageOutputFormat; +pub use options::ExtractOptions; +#[allow(clippy::too_many_arguments)] pub fn extract( - max_size: u32, - num_horizontal: u32, - num_vertical: u32, - frame_interval: media_time::MediaTime, input_file: &Path, output_folder: &Path, - format: ImageOutputFormat, + options: ExtractOptions, scaler: SwsScaler, flags: SwsFlags, ) -> anyhow::Result<()> { @@ -24,15 +22,11 @@ pub fn extract( avformat_context.open_input(input_file)?; let duration = avformat_context.duration()?; - std::fs::create_dir_all(&output_folder)?; + std::fs::create_dir_all(output_folder)?; let mut spritesheet_manager = spritesheet::SpritesheetManager::new( - max_size, - num_horizontal, - num_vertical, - frame_interval, + options, output_folder, "preview", - format, ); let mut stream: AVStream = avformat_context diff --git a/src/main.rs b/src/main.rs index 3882818df2afacffc71a5af01c9aa3536d919728..07a5327b0c9d216c0523616a6d93bffdc2cf4420 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ use ffmpeg_api::enums::{SwsFlags, SwsScaler}; use image::ImageFormat as ImageOutputFormat; use media_time::MediaTime; use structopt::StructOpt; +use media_ingestion::ExtractOptions; fn parse_scaler(src: &str) -> Result<SwsScaler, String> { match src { @@ -62,17 +63,19 @@ fn main() -> anyhow::Result<()> { } if let Err(err) = media_ingestion::extract( - options.max_size, - options.num_horizontal, - options.num_vertical, - MediaTime::from_seconds(options.frame_interval), Path::new(&options.input), Path::new(&options.output), - match options.format.as_str() { - "jpeg" | "jpg" => ImageOutputFormat::Jpeg, - "png" => ImageOutputFormat::Png, - "bmp" => ImageOutputFormat::Bmp, - _ => panic!("Unsupported image format: {}", options.format), + ExtractOptions { + max_size: options.max_size, + num_horizontal: options.num_horizontal, + num_vertical: options.num_vertical, + frame_interval: MediaTime::from_seconds(options.frame_interval), + format: match options.format.as_str() { + "jpeg" | "jpg" => ImageOutputFormat::Jpeg, + "png" => ImageOutputFormat::Png, + "bmp" => ImageOutputFormat::Bmp, + _ => panic!("Unsupported image format: {}", options.format), + } }, options.scaler, flags, diff --git a/src/options.rs b/src/options.rs new file mode 100644 index 0000000000000000000000000000000000000000..0f1362bccb2e27c485e8b1f142bb217e2ea1e1e2 --- /dev/null +++ b/src/options.rs @@ -0,0 +1,9 @@ +use image::ImageFormat as ImageOutputFormat; + +pub struct ExtractOptions { + pub max_size: u32, + pub num_horizontal: u32, + pub num_vertical: u32, + pub frame_interval: media_time::MediaTime, + pub format: ImageOutputFormat, +} diff --git a/src/spritesheet.rs b/src/spritesheet.rs index 1168e094b864644d808dd7e53fc397988de13c09..2350d8db3392715e7de1e8de9efb27b41686f108 100644 --- a/src/spritesheet.rs +++ b/src/spritesheet.rs @@ -6,6 +6,7 @@ use anyhow::{bail, Error, format_err}; use image::{DynamicImage, ImageFormat as ImageOutputFormat, RgbImage}; use media_time::MediaTime; use webvtt::{WebVTTCue, WebVTTFile}; +use crate::options::ExtractOptions; pub enum ImageFormat { Jpeg(i32), @@ -31,28 +32,24 @@ pub struct SpritesheetManager { impl SpritesheetManager { pub fn new( - max_side: u32, - num_horizontal: u32, - num_vertical: u32, - frame_interval: MediaTime, + options: ExtractOptions, output_path: impl Into<PathBuf>, name: impl AsRef<str>, - format: ImageOutputFormat, ) -> SpritesheetManager { SpritesheetManager { - num_horizontal, - num_vertical, - max_side, + num_horizontal: options.num_horizontal, + num_vertical: options.num_vertical, + max_side: options.max_size, sprite_width: 0, sprite_height: 0, spritesheet: RgbImage::new(0, 0), current_image: 0, last_timestamp: MediaTime::from_millis(0), - frame_interval, + frame_interval: options.frame_interval, metadata: WebVTTFile::new(), output_path: output_path.into(), name: String::from(name.as_ref()), - format, + format: options.format, initialized: false, } } @@ -184,7 +181,7 @@ impl SpritesheetManager { let new_buffer = self.reinit_buffer(); DynamicImage::ImageRgb8(std::mem::replace(&mut self.spritesheet, new_buffer)) - .write_to(&mut BufWriter::new(file), self.format.clone()) + .write_to(&mut BufWriter::new(file), self.format) .map_err(|err| format_err!("Could not write spritesheet {}: {}", &name, err))?; Ok(())