anicoder 0.1.2

Episode transcoder for Anigelo
Documentation
use std::fs;
use std::path::PathBuf;
use std::process::Command;
use walkdir::WalkDir;

const ALLOWED_EXTENSIONS: [&str; 4] = ["mkv", "avi", "mp4", "M4V"];

pub fn encode_to_h264(path: PathBuf) {
    let episodes = get_episodes(path);
    for episode in episodes {
        let new_path = episode.with_file_name(
          format!("transcoding {}.mkv", episode.file_stem().unwrap().to_string_lossy())
        );

        Command::new("ffmpeg")
            .arg("-i").arg(&episode)
            .arg("-preset").arg("slow")
            .arg("-crf").arg("23")
            .arg("-pix_fmt").arg("yuv420p")
            .arg("-c:a").arg("aac")
            .arg("-c:s").arg("copy")
            .arg(&new_path)
            .spawn().expect("ffmpeg failed")
            .wait().expect("ffmpeg failed");

        let transcoded_metadata = fs::metadata(&new_path);
        if transcoded_metadata.is_ok() && transcoded_metadata.unwrap().len() > 0 {
            match fs::remove_file(&episode) {
                Err(e) => eprintln!("Could not remove '{:?}', Error: {}", episode, e),
                Ok(()) => if let Err(e) = fs::rename(new_path, episode.with_extension("mkv")) {
                    eprintln!("Could not rename '{:?}', Error: {}", episode, e)
                }
            }
        }
    }
}

fn get_episodes(path: PathBuf) -> Vec<PathBuf> {
    WalkDir::new(path)
        .follow_links(true)
        .into_iter()
        .filter_map(|file| file.ok())
        .filter_map(|file| {
            let file = file.into_path();
            if is_allowed_extension(&file) {
                Some(file)
            } else { None }
        }).collect()
}

fn is_allowed_extension(file: &PathBuf) -> bool {
    if let Some(extension) = file.extension() {
        ALLOWED_EXTENSIONS.contains(&&*extension.to_string_lossy())
    } else {
        false
    }
}