Files
MeowIndex/backend/src/encoder.rs
T
2023-02-24 12:30:18 -05:00

66 lines
1.9 KiB
Rust

use std::{env, fs};
use std::path::Path;
use std::process::{Command, Output};
use std::time::Instant;
use serde::{Deserialize};
use anyhow::{Context, Result};
use tempdir::TempDir;
use crate::utils::run_cmd;
#[derive(Deserialize, Debug)]
pub struct Encoder {
name: String,
cmd: String,
suffix: String,
}
#[derive(Deserialize, Debug)]
pub struct Encoders {
processes: u32,
encoders: Vec<Encoder>
}
impl Encoder {
pub fn execute(&self, orig: &str, out: &str) -> Result<Output> {
run_cmd(&*self.cmd
.replace("{{INPUT}}", &*shlex::quote(orig))
.replace("{{OUTPUT}}", &*shlex::quote(out)))
}
}
impl Encoders {
pub fn load() -> Result<Encoders> {
let file = env::var("MEOW_ENCODING_FILE").unwrap_or("encoding.toml".to_string());
let content = fs::read_to_string(file)?;
Ok(toml::from_str(&*content)?)
}
pub fn exec_all(&self, orig: &str, out: &Path) -> Result<()> {
for enc in &self.encoders {
let enc_out = out.with_extension(enc.suffix.to_owned());
// Skip if encoded video already exists
if enc_out.exists() { continue }
debug!("Encoding '{}' for {orig}...", enc.name);
let start = Instant::now();
// Create tmp (this is to prevent partially completed encoding results being detected as completed)
let tmp_dir = TempDir::new("meow_encoder_tmp")?;
let tmp_out = tmp_dir.path().join(out.file_name().context("No file name")?);
// Convert to tmp
enc.execute(orig, tmp_out.to_str().context("Call to path.to_str failed")?)?;
debug!("Done, took {:.2} minutes, copying result...", start.elapsed().as_secs_f32() / 60.0);
// Copy results
fs::copy(tmp_out, enc_out)?;
// Cleanup tmp
tmp_dir.close()?;
}
Ok(())
}
}