refactor: restructure project into a workspace by introducing a plugin API crate and modularizing individual plugin definitions.
Release / check-release (push) Successful in 17s
Release / build (push) Skipped
Release / package (deb) (push) Skipped
Release / package (rpm) (push) Skipped
Release / publish (push) Skipped
CI / test (push) Failing after 2m6s

This commit is contained in:
Elias Wendland
2026-07-17 15:50:50 +02:00
parent 2ea317e117
commit eb76ed1937
43 changed files with 4243 additions and 2296 deletions
+122
View File
@@ -0,0 +1,122 @@
// Copyright (C) 2026 Elias Wendland <eliaswendland@pm.me>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 3 exclusively.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use convertis_plugin_api::{Conversion, ConversionRequest, Plugin, PluginMetadata};
use std::process::Command;
const INPUTS: &[&str] = &[
"mp4",
"webm",
"mkv",
"avi",
"mov",
"wmv",
"flv",
"gif",
"animated-gif",
"m4v",
"mpeg",
"ogv",
"apng",
"webp",
"animated-webp",
];
const OUTPUTS: &[&str] = &[
"mp4",
"webm",
"mkv",
"avi",
"mov",
"wmv",
"flv",
"animated-gif",
"m4v",
"mpeg",
"ogv",
"apng",
"animated-webp",
];
struct FfmpegVideo;
impl Plugin for FfmpegVideo {
fn metadata(&self) -> PluginMetadata {
PluginMetadata {
id: "ffmpeg-video".into(),
package: "convertis-ffmpeg-video".into(),
description: "FFmpeg video conversion".into(),
conversions: INPUTS
.iter()
.flat_map(|from| {
OUTPUTS
.iter()
.filter(move |to| to != &from)
.map(move |to| Conversion::file(from, to, (240, 210, 180)))
})
.collect(),
options: vec![],
}
}
fn availability(&self) -> Result<(), String> {
Command::new("ffmpeg")
.arg("-version")
.output()
.map_err(|_| "'ffmpeg' is required".to_owned())
.and_then(|output| {
output
.status
.success()
.then_some(())
.ok_or_else(|| "'ffmpeg' is unavailable".to_owned())
})
}
fn convert(&self, request: &ConversionRequest) -> Result<(), String> {
let codec: &[&str] = match request.to.as_str() {
"mp4" | "mkv" | "mov" | "m4v" => &[
"-c:v", "libx264", "-crf", "23", "-c:a", "aac", "-pix_fmt", "yuv420p",
],
"webm" => &[
"-c:v",
"libvpx-vp9",
"-crf",
"30",
"-b:v",
"0",
"-c:a",
"libopus",
],
"avi" => &["-c:v", "mpeg4", "-qscale:v", "3", "-c:a", "libmp3lame"],
"gif" | "animated-gif" => &["-vf", "fps=15,scale=640:-1:flags=lanczos"],
"webp" | "animated-webp" => &["-c:v", "libwebp", "-q:v", "75", "-loop", "0"],
"apng" => &["-plays", "0"],
"mpeg" => &["-c:v", "mpeg2video", "-c:a", "mp2"],
_ => &[],
};
let output = Command::new("ffmpeg")
.arg("-v")
.arg("error")
.arg("-y")
.arg("-i")
.arg(&request.input)
.args(codec)
.arg(&request.output)
.output()
.map_err(|error| error.to_string())?;
if output.status.success() {
Ok(())
} else {
Err(String::from_utf8_lossy(&output.stderr).into_owned())
}
}
}
convertis_plugin_api::export_plugin!(FfmpegVideo, "ffmpeg-video");