232 lines
7.6 KiB
Nix
232 lines
7.6 KiB
Nix
{ config, lib, nixosConfig, pkgs, ... }:
|
||
let
|
||
mpv-prescalers = pkgs.fetchFromGitHub {
|
||
owner = "bjin";
|
||
repo = "mpv-prescalers";
|
||
rev = "b37d0f12223720f5ce48e149678162ae0a984176";
|
||
sha256 = "1mmf5827qsyph0wqkyvi7zfng1cskkapngn5hf9073zc61n4398y";
|
||
|
||
meta.license = lib.licenses.lgpl3Plus;
|
||
};
|
||
|
||
shaders = {
|
||
fsrcnnx_x2 = pkgs.fetchurl {
|
||
url = "https://github.com/igv/FSRCNN-TensorFlow/releases/download/1.1/FSRCNNX_x2_8-0-4-1.glsl";
|
||
sha256 = "03qv0l3b1bznarlv0jpi4gqg1zg3khsw5cp8pmabg73k0xpcwqix";
|
||
|
||
meta.license = lib.licenses.mit;
|
||
};
|
||
|
||
SSimDownscaler = pkgs.fetchurl {
|
||
url = "https://gist.github.com/igv/36508af3ffc84410fe39761d6969be10/raw/ac09db2c0664150863e85d5a4f9f0106b6443a12/SSimDownscaler.glsl";
|
||
sha256 = "1c3fp6llg0n8zdxadsg6g3kcvhqvikalbc9q61zgwvsx8q3d8rph";
|
||
|
||
meta.license = lib.licenses.lgpl3Plus;
|
||
};
|
||
|
||
KrigBilateral = pkgs.fetchurl {
|
||
url = "https://gist.github.com/igv/a015fc885d5c22e6891820ad89555637/raw/c471ef6dcbd3c4a977e1c95dc40944ee38fad08a/KrigBilateral.glsl";
|
||
sha256 = "11s0h6i0y3h2nrfp6lax6hzwvjbn93akjr6d61jrmz09zdf1iwmc";
|
||
|
||
meta.license = lib.licenses.lgpl3Plus;
|
||
};
|
||
};
|
||
|
||
gallery-view = pkgs.fetchFromGitHub {
|
||
owner = "occivink";
|
||
repo = "mpv-gallery-view";
|
||
rev = "5139d346de67e8dbee8c8983777026502d6bc627";
|
||
sha256 = "1xcl31rpb6kp479kil4srkclw9ly565zavr65ary9s8795ygfcrs";
|
||
|
||
meta.license = lib.licenses.gpl2;
|
||
};
|
||
|
||
cycleShaders = shaders: "cycle-values glsl-shaders ${lib.concatStringsSep " " shaders}";
|
||
in
|
||
{
|
||
programs.mpv = {
|
||
enable = nixosConfig.sbruder.gui.enable;
|
||
|
||
config = {
|
||
# Main application font
|
||
osd-font = "DINW07-Medium"; # not included in repository (unfree)
|
||
|
||
# Subtitles
|
||
sub-font = "Gandhi Sans"; # see osd-font
|
||
sub-bold = true;
|
||
sub-font-size = 44;
|
||
sub-use-margins = false;
|
||
sub-border-size = 2;
|
||
|
||
# Nicer looking vobsub/PGS subtitles
|
||
sub-gauss = 0.5;
|
||
sub-gray = true;
|
||
|
||
# Allow higher volumes
|
||
volume-max = 150;
|
||
|
||
# Downmix to stereo by default
|
||
audio-channels = "stereo";
|
||
|
||
# Allow seeking in streamed media
|
||
force-seekable = true;
|
||
|
||
# Enable hardware decoding when avaliable
|
||
hwdec = "auto-safe";
|
||
|
||
# Do not show images only one second
|
||
image-display-duration = "inf";
|
||
|
||
# Better quality (but not too high, otherwise too high frame drop)
|
||
profile = "gpu-hq";
|
||
deband = false;
|
||
dither-depth = "auto";
|
||
|
||
# Lossless screenshots
|
||
screenshot-format = "png";
|
||
|
||
# Use youtube-dl’s format configuration
|
||
ytdl-format = "ytdl";
|
||
};
|
||
|
||
bindings = {
|
||
# Audio filter bs2b (for headphones)
|
||
"b" = "af toggle bs2b";
|
||
|
||
# Toggle debanding
|
||
"D" = "cycle deband";
|
||
|
||
# Variable correction of audio pitch when changing speed
|
||
"k" = "cycle-values audio-pitch-correction no yes";
|
||
|
||
# Reverse cycling for audio and video (shift modifier on german keyboard layout)
|
||
"'" = "cycle audio down";
|
||
"-" = "cycle video down";
|
||
|
||
# Cycle between audio downmixes
|
||
"c" = "cycle-values audio-channels stereo mono auto";
|
||
|
||
# Cycle between smart scalers (and /dev/null = disabled)
|
||
"K" = cycleShaders [
|
||
"${mpv-prescalers}/compute/ravu-lite-r4.hook"
|
||
"${mpv-prescalers}/compute/ravu-lite-r3.hook"
|
||
"${mpv-prescalers}/compute/ravu-lite-r2.hook"
|
||
"/dev/null"
|
||
];
|
||
"Alt+K" = cycleShaders [
|
||
"${mpv-prescalers}/compute/ravu-zoom-r4-yuv.hook"
|
||
"${mpv-prescalers}/compute/ravu-zoom-r3-yuv.hook"
|
||
"${mpv-prescalers}/compute/ravu-zoom-r2-yuv.hook"
|
||
"/dev/null"
|
||
];
|
||
"Alt+k" = cycleShaders [
|
||
"${mpv-prescalers}/compute/nnedi3-nns256-win8x4.hook"
|
||
"${mpv-prescalers}/compute/nnedi3-nns128-win8x4.hook"
|
||
"/dev/null"
|
||
];
|
||
|
||
# Toggle pitchcontrol
|
||
"Ctrl+p" = "script-message-to pitchcontrol toggle";
|
||
|
||
# more granular panning
|
||
"Alt+left" = "add video-pan-x 0.05";
|
||
"Alt+right" = "add video-pan-x -0.05";
|
||
"Alt+up" = "add video-pan-y 0.05";
|
||
"Alt+down" = "add video-pan-y -0.05";
|
||
|
||
# sub-delay for fixing 24 empty frames on blu-ray
|
||
"Alt+z" = "add sub-delay -1";
|
||
"Alt+Z" = "add sub-delay +1";
|
||
|
||
# sponsorblock: set segment boundaries
|
||
"alt+g" = "script-binding sponsorblock/set_segment";
|
||
|
||
# Exits with error to not mark the video as watched in ytcc
|
||
"Shift+q" = "quit-watch-later 1";
|
||
};
|
||
|
||
profiles =
|
||
let
|
||
mkVisualiser = width: height: rate: {
|
||
lavfi-complex = lib.concatStringsSep ";" [
|
||
"[aid1]asplit=4[ao][a1][a2][a3]"
|
||
"[a1]avectorscope=m=lissajous:s=${toString (width / 3)}x${toString (height / 2)}:draw=dot:r=${toString rate}[avectorscope]"
|
||
"[a2]aresample=44100,showwaves=s=${toString (width / 3 * 2)}x${toString (height / 2)}:mode=p2p:colors=red|lightgreen:r=${toString rate}[showwaves]"
|
||
"[a3]showcqt=s=${toString width}x${toString (height / 2)}:axis=0:axis_h=0:r=${toString rate}[showcqt]"
|
||
"[showwaves][avectorscope]hstack=shortest=1[top]"
|
||
"[top][showcqt]vstack=shortest=1,fps=${toString rate}[vo]"
|
||
];
|
||
alpha = false;
|
||
};
|
||
in
|
||
{
|
||
visualiser = mkVisualiser 1920 1200 30;
|
||
visualiser-1080 = mkVisualiser 1920 1080 30;
|
||
visualiser-60 = mkVisualiser 1920 1080 60;
|
||
visualiser-1080-60 = mkVisualiser 1920 1080 60;
|
||
|
||
hqencode = {
|
||
ovc = "libx264";
|
||
ovcopts-add = "crf=18";
|
||
oac = "flac";
|
||
audio-format = "s16";
|
||
};
|
||
|
||
lq = {
|
||
scale = "bicubic_fast";
|
||
cscale = "bicubic_fast";
|
||
dscale = "bicubic_fast";
|
||
};
|
||
|
||
hq = {
|
||
scale = "ewa_lanczossharp";
|
||
dscale = "mitchell";
|
||
linear-downscaling = "no"; # for KrigBilateral
|
||
cscale = "ewa_lanczos";
|
||
glsl-shader = [
|
||
"${shaders.SSimDownscaler}" # dscale
|
||
"${shaders.KrigBilateral}" # cscale
|
||
"${shaders.fsrcnnx_x2}" # scale
|
||
];
|
||
};
|
||
|
||
interpolate = {
|
||
blend-subtitles = true;
|
||
video-sync = "display-resample";
|
||
interpolation = true;
|
||
tscale = "box";
|
||
tscale-window = "sphinx";
|
||
tscale-radius = 1.0;
|
||
tscale-clamp = 0.0;
|
||
};
|
||
|
||
# adapted from https://github.com/mpv-player/mpv/issues/4418#issuecomment-368272929
|
||
clear-speed.af-add = "scaletempo=stride=18:overlap=.6:search=10";
|
||
};
|
||
|
||
scripts = with pkgs.mpvScripts; [
|
||
pitchcontrol
|
||
sponsorblock
|
||
];
|
||
};
|
||
|
||
# mpv-gallery-view is not compatible with home-manager’s script injection meachanism
|
||
xdg.configFile."mpv/scripts/gallery-thumbgen-0.lua".source = "${gallery-view}/scripts/gallery-thumbgen.lua";
|
||
xdg.configFile."mpv/scripts/gallery-thumbgen-1.lua".source = "${gallery-view}/scripts/gallery-thumbgen.lua";
|
||
xdg.configFile."mpv/scripts/gallery-thumbgen-2.lua".source = "${gallery-view}/scripts/gallery-thumbgen.lua";
|
||
xdg.configFile."mpv/scripts/gallery-thumbgen-3.lua".source = "${gallery-view}/scripts/gallery-thumbgen.lua";
|
||
xdg.configFile."mpv/scripts/lib/gallery.lua".source = "${gallery-view}/scripts/lib/gallery.lua";
|
||
xdg.configFile."mpv/scripts/playlist-view.lua".source = "${gallery-view}/scripts/playlist-view.lua";
|
||
xdg.configFile."mpv/script-opts/playlist_view.conf".text = ''
|
||
thumbs_dir=${config.xdg.cacheHome}/thumbnails/mpv
|
||
'';
|
||
home.file."${config.xdg.cacheHome}/thumbnails/mpv/.create".text = "";
|
||
|
||
xdg.configFile."mpv/script-opts/stats.conf".text = ''
|
||
font=DINW07-Regular
|
||
font_mono=DINW07-Regular
|
||
font_size=10
|
||
redraw_delay=0.25
|
||
'';
|
||
}
|