151 lines
3.7 KiB
Nix
151 lines
3.7 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
with lib;
|
|
let
|
|
|
|
cfg = config.programs.custom.ffmpeg;
|
|
|
|
ffmpegTemplate = name:
|
|
{ profile, preset, tune ? null, width ? 1280, height ? 720
|
|
, resolution ? "720p" }:
|
|
pkgs.writeShellScriptBin "ffmpeg-${name}" ''
|
|
|
|
if [ $# -eq 0 ]
|
|
then
|
|
cat <<EOF
|
|
ffmpeg-<profile>-<preset>-<tunes>-${resolution} <input> <output>
|
|
|
|
profiles =
|
|
"baseline" - Primarily for low-cost applications that require additional data loss robustness
|
|
"main" - This profile is used for standard-definition digital TV broadcasts that use the MPEG-4 format as defined in the DVB standard.
|
|
"high" - The primary profile for broadcast and disc storage applications, particularly for high-definition television applications
|
|
|
|
presets =
|
|
"ultrafast"
|
|
"superfast"
|
|
"veryfast"
|
|
"faster"
|
|
"fast"
|
|
"medium"
|
|
"slow"
|
|
"slower"
|
|
"veryslow"
|
|
|
|
tunes = (optional)
|
|
"film" - use for high quality movie content; lowers deblockin
|
|
"animation" - good for cartoons; uses higher deblocking and more reference frames
|
|
"grain" - preserves the grain structure in old, grainy film material
|
|
"stillimage" - good for slideshow-like content
|
|
"fastdecode" - allows faster decoding by disabling certain filters
|
|
|
|
EOF
|
|
exit 0
|
|
fi
|
|
|
|
if [ $# -ne 2 ]
|
|
then
|
|
echo "ffmpeg-${name} <input> <output>"
|
|
exit 1
|
|
fi
|
|
|
|
input=$1
|
|
output=$2
|
|
|
|
if [ ! -f "$input" ]
|
|
then
|
|
echo "input does not exist $input"
|
|
exit 1
|
|
fi
|
|
|
|
# do it stereo
|
|
# -ac 2
|
|
# do it sample rate 44100
|
|
# -ar 44100
|
|
|
|
exec ${pkgs.ffmpeg}/bin/ffmpeg \
|
|
-i "$input" \
|
|
-filter:v scale=h='min(${toString height}\,ih)':w='min(${
|
|
toString width
|
|
}\,iw)' \
|
|
-vcodec libx264 \
|
|
-preset ${preset} \
|
|
-profile:v ${profile} \
|
|
${optionalString (tune != null) "-tune ${tune}"} \
|
|
-acodec aac \
|
|
-ac 2 \
|
|
-ar 44100 \
|
|
"$output" \
|
|
-hide_banner
|
|
'';
|
|
|
|
# https://en.wikipedia.org/wiki/H.264/MPEG-4_AVC#Profiles
|
|
profiles = [
|
|
"baseline"
|
|
"main"
|
|
"high"
|
|
#"high10"
|
|
#"high422"
|
|
#"high44"
|
|
];
|
|
presets = [
|
|
#"ultrafast"
|
|
#"superfast"
|
|
#"veryfast"
|
|
#"faster"
|
|
"fast"
|
|
"medium"
|
|
"slow"
|
|
#"slower"
|
|
"veryslow"
|
|
];
|
|
tunes = [ "film" "animation" "grain" "stillimage" "fastdecode" ];
|
|
|
|
ffmpegs = let
|
|
|
|
configurations = lib.cartesianProductOfSets {
|
|
profile = profiles;
|
|
preset = presets;
|
|
};
|
|
|
|
p720 = { profile, preset }:
|
|
ffmpegTemplate "${profile}-${preset}-720p" { inherit profile preset; };
|
|
|
|
p1080 = { profile, preset }:
|
|
ffmpegTemplate "${profile}-${preset}-1080p" {
|
|
inherit profile preset;
|
|
height = 1080;
|
|
width = 1920;
|
|
resolution = "1080p";
|
|
};
|
|
in (map p720 configurations) ++ (map p1080 configurations);
|
|
|
|
ffmpegsTune = let
|
|
configurations = lib.cartesianProductOfSets {
|
|
profile = profiles;
|
|
preset = presets;
|
|
tune = tunes;
|
|
};
|
|
|
|
p720 = { profile, preset, tune }:
|
|
ffmpegTemplate "${profile}-${preset}-${tune}-720p" {
|
|
inherit profile preset tune;
|
|
};
|
|
|
|
p1080 = { profile, preset, tune }:
|
|
ffmpegTemplate "${profile}-${preset}-${tune}-1080p" {
|
|
inherit profile preset tune;
|
|
height = 1080;
|
|
width = 1920;
|
|
resolution = "1080p";
|
|
};
|
|
|
|
in (map p720 configurations) ++ (map p1080 configurations);
|
|
|
|
in {
|
|
|
|
options.programs.custom.ffmpeg = {
|
|
enable = mkEnableOption "enable programs.custom.ffmpeg";
|
|
};
|
|
|
|
config =
|
|
mkIf cfg.enable { environment.systemPackages = ffmpegs ++ ffmpegsTune; };
|
|
}
|