This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

tools.mpv: add mpv tool with lazy-loaded subtitle downloader

Create mpv tool based on 2configs/mpv.nix configuration with:
- Custom mpv configuration and input bindings
- mpv scripts (sponsorblock, quality-menu, vr-reversal, visualizer)
- Separate mpv-dl-subs package that loads on-demand when pressing 'S'
- YouTube resolution limit and sponsorblock configuration

+113
+113
tools/mpv/flake-module.nix
··· 1 + { self, ... }: 2 + { 3 + perSystem = 4 + { pkgs, lib, ... }: 5 + { 6 + packages.mpv = 7 + let 8 + mpvInput = pkgs.writeText "mpv.input" '' 9 + : script-binding console/enable 10 + x add audio-delay -0.050 11 + X add audio-delay 0.050 12 + ''; 13 + 14 + mpvConfig = pkgs.writeText "mpv.conf" '' 15 + osd-font-size=20 16 + ''; 17 + 18 + # Lazy-loaded autosub script 19 + autosub = pkgs.writeText "autosub.lua" '' 20 + utils = require 'mp.utils' 21 + 22 + -- Log function: log to both terminal and mpv OSD (On-Screen Display) 23 + function log(string, secs) 24 + secs = secs or 2 -- secs defaults to 2 when the secs parameter is absent 25 + mp.msg.warn(string) -- This logs to the terminal 26 + mp.osd_message(string, secs) -- This logs to mpv screen 27 + end 28 + 29 + function download() 30 + log('Searching subtitles ...', 10) 31 + path = mp.get_property('path') 32 + 33 + -- Build dl_subs lazily when needed 34 + log('Building subtitle downloader...', 5) 35 + result = utils.subprocess({ args = {"nix", "build", "--no-link", "--print-out-paths", "${self}#mpv-dl-subs"} }) 36 + if result.error ~= nil then 37 + log('Failed to build subtitle downloader') 38 + return 39 + end 40 + 41 + dl_subs_path = string.gsub(result.stdout, "\n", "") .. "/bin/dl_subs" 42 + 43 + -- Download subtitles 44 + result = utils.subprocess({ args = {dl_subs_path, path} }) 45 + if result.error == nil then 46 + filename = string.gsub(result.stdout, "\n", "") 47 + log(filename) 48 + mp.commandv('sub_add', filename) 49 + log('Subtitles ready!') 50 + else 51 + log('Subtitles failed downloading') 52 + end 53 + end 54 + 55 + mp.add_key_binding('S', "download_subs", download) 56 + ''; 57 + 58 + mpvPackage = pkgs.mpv.override { 59 + scripts = with pkgs.mpvScripts; [ 60 + sponsorblock 61 + quality-menu 62 + vr-reversal 63 + visualizer 64 + ]; 65 + }; 66 + 67 + in 68 + pkgs.writeShellApplication { 69 + name = "mpv"; 70 + runtimeInputs = [ 71 + mpvPackage 72 + pkgs.yt-dlp 73 + ]; 74 + text = '' 75 + Y_RES=1081 76 + # we need to disable sponsorblock local database because of 77 + # https://github.com/po5/mpv_sponsorblock/issues/31 78 + exec mpv \ 79 + --no-config \ 80 + --input-conf=${mpvInput} \ 81 + --include=${mpvConfig} \ 82 + --script=${autosub} \ 83 + --ytdl-format="best[height<$Y_RES]" \ 84 + --script-opts=ytdl_hook-ytdl_path=${pkgs.yt-dlp}/bin/yt-dlp \ 85 + --script-opts-append=sponsorblock-local_database=no \ 86 + --audio-channels=2 \ 87 + "$@" 88 + ''; 89 + }; 90 + 91 + # Separate package for subtitle downloader 92 + packages.mpv-dl-subs = pkgs.writers.writePython3Bin "dl_subs" { 93 + libraries = [ pkgs.python3Packages.subliminal ]; 94 + flakeIgnore = [ "E501" ]; 95 + } '' 96 + import babelfish 97 + import subliminal 98 + from pathlib import Path 99 + import sys 100 + import os 101 + 102 + video_path = Path(sys.argv[1]) 103 + video = subliminal.scan_video(video_path) 104 + cache_path = Path(os.path.expanduser("~/.cache/subliminal")) / f"{video.title}.srt" 105 + if not cache_path.exists(): 106 + cache_path.parent.mkdir(parents=True, exist_ok=True) 107 + language = babelfish.Language("eng") 108 + sub = subliminal.download_best_subtitles([video], {language})[video][0] 109 + cache_path.write_bytes(sub.content) 110 + print(cache_path) 111 + ''; 112 + }; 113 + }