pict-rs/src/ffmpeg.rs

98 lines
2.1 KiB
Rust
Raw Normal View History

2021-10-23 04:48:56 +00:00
use crate::{error::Error, process::Process, store::Store};
use actix_web::web::Bytes;
2021-10-23 04:48:56 +00:00
use tokio::io::AsyncRead;
2021-09-14 01:22:42 +00:00
use tracing::instrument;
2021-10-23 04:48:56 +00:00
#[derive(Debug)]
pub(crate) enum InputFormat {
Gif,
Mp4,
}
2021-09-14 01:22:42 +00:00
#[derive(Debug)]
pub(crate) enum ThumbnailFormat {
Jpeg,
// Webp,
}
impl InputFormat {
fn as_format(&self) -> &'static str {
match self {
InputFormat::Gif => "gif_pipe",
InputFormat::Mp4 => "mp4",
}
}
}
impl ThumbnailFormat {
fn as_codec(&self) -> &'static str {
match self {
ThumbnailFormat::Jpeg => "mjpeg",
// ThumbnailFormat::Webp => "webp",
}
}
fn as_format(&self) -> &'static str {
match self {
ThumbnailFormat::Jpeg => "singlejpeg",
// ThumbnailFormat::Webp => "webp",
}
}
}
pub(crate) fn to_mp4_bytes(
input: Bytes,
input_format: InputFormat,
) -> std::io::Result<impl AsyncRead + Unpin> {
2021-09-14 01:22:42 +00:00
let process = Process::run(
"ffmpeg",
&[
"-f",
input_format.as_format(),
"-i",
"pipe:",
"-movflags",
"faststart+frag_keyframe+empty_moov",
"-pix_fmt",
"yuv420p",
"-vf",
"scale=trunc(iw/2)*2:trunc(ih/2)*2",
"-an",
"-codec",
"h264",
"-f",
"mp4",
"pipe:",
],
)?;
Ok(process.bytes_read(input).unwrap())
}
2021-10-23 04:48:56 +00:00
#[instrument(name = "Create video thumbnail")]
pub(crate) async fn thumbnail<S: Store>(
store: S,
from: S::Identifier,
input_format: InputFormat,
format: ThumbnailFormat,
2021-10-23 04:48:56 +00:00
) -> Result<impl AsyncRead + Unpin, Error> {
let process = Process::run(
"ffmpeg",
&[
"-f",
input_format.as_format(),
"-i",
"pipe:",
"-vframes",
"1",
"-codec",
format.as_codec(),
"-f",
format.as_format(),
"pipe:",
],
)?;
2021-10-23 04:48:56 +00:00
Ok(process.store_read(store, from).unwrap())
}