dots

git clone git://mattcarlson.org/repos/dots.git
Log | Files | Refs

commit 632dc7d0c9f2f5e3ec335bbeeb5372dfa6b67266
parent 56057a5e6d03e51bf947254f8222e6f7207e0330
Author: Matthew Carlson <matt@mcarlson.xyz>
Date:   Mon,  2 Aug 2021 15:53:41 -0400

mpv conf

Diffstat:
D.config/mpv/input.conf | 1-
A.config/mpv/mpv.conf | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A.config/mpv/scripts/youtube-quality.lua | 275+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
M.config/sh/functionrc | 2+-
M.config/x/xresources | 2+-
5 files changed, 339 insertions(+), 3 deletions(-)

diff --git a/.config/mpv/input.conf b/.config/mpv/input.conf @@ -1 +0,0 @@ -I cycle-values vf "sub,lavfi=negate" "" diff --git a/.config/mpv/mpv.conf b/.config/mpv/mpv.conf @@ -0,0 +1,62 @@ +# audio +audio-file-auto = 'fuzzy' +audio-pitch-correction = 'yes' +audio-stream-silence +volume-max = 100 + +# lang +alang = 'eng,en' +slang = 'eng,en' + +# osd +osd-bar = 'no' +osd-border-color = '#000000FF' +osd-border-size = 1 +osd-color = '#FFFFFFFF' +osd-font-size = 32 +osd-font = 'Sans' +osd-margin-x = 15 +osd-margin-y = 15 + +# screenshot +screenshot-format = 'png' +screenshot-high-bit-depth = 'yes' +screenshot-jpeg-quality = 100 +screenshot-png-compression = 0 +screenshot-tag-colorspace = 'yes' +screenshot-template = '%F-%wH-%wM-%wS-%wT' +screenshot-directory = '~/pix/captures' + +# sub +blend-subtitles = 'yes' +demuxer-mkv-subtitle-preroll +embeddedfonts = 'no' +sub-auto = 'fuzzy' +sub-blur = 0.2 +sub-border-color = '0.0/0.0/0.0/1.0' +sub-border-size = '3.0' +sub-color = '1.0/1.0/1.0/1.0' +sub-fix-timing = 'yes' +sub-font-size = 32 +sub-font = 'Sans' +sub-gauss = 1.0 +sub-gray = 'yes' +sub-shadow-color = '0.0/0.0/0.0/0.25' +sub-shadow-offset = 0 + +# vid +cscale-antiring = 0.0 +cursor-autohide = 75 +deband-grain = 48 +deband-iterations = 4 +deband-range = 16 +deband-threshold = 48 +deband = 'yes' +dscale-antiring = 0.0 +force-seekable = 'yes' +hr-seek-framedrop = 'no' +interpolation = 'yes' +profile = 'gpu-hq' +scale-antiring = 0.0 +video-sync = 'display-resample' +vo = 'gpu' diff --git a/.config/mpv/scripts/youtube-quality.lua b/.config/mpv/scripts/youtube-quality.lua @@ -0,0 +1,275 @@ +-- youtube-quality.lua +-- +-- Change youtube video quality on the fly. +-- +-- Diplays a menu that lets you switch to different ytdl-format settings while +-- you're in the middle of a video (just like you were using the web player). +-- +-- Bound to ctrl-f by default. + +local mp = require 'mp' +local utils = require 'mp.utils' +local msg = require 'mp.msg' +local assdraw = require 'mp.assdraw' + +local opts = { + --key bindings + toggle_menu_binding = "ctrl+f", + up_binding = "UP", + down_binding = "DOWN", + select_binding = "ENTER", + + --formatting / cursors + selected_and_active = "▶ - ", + selected_and_inactive = "● - ", + unselected_and_active = "▷ - ", + unselected_and_inactive = "○ - ", + + --font size scales by window, if false requires larger font and padding sizes + scale_playlist_by_window=false, + + --playlist ass style overrides inside curly brackets, \keyvalue is one field, extra \ for escape in lua + --example {\\fnUbuntu\\fs10\\b0\\bord1} equals: font=Ubuntu, size=10, bold=no, border=1 + --read http://docs.aegisub.org/3.2/ASS_Tags/ for reference of tags + --undeclared tags will use default osd settings + --these styles will be used for the whole playlist. More specific styling will need to be hacked in + -- + --(a monospaced font is recommended but not required) + style_ass_tags = "{\\fnmonospace}", + + --paddings for top left corner + text_padding_x = 5, + text_padding_y = 5, + + --other + menu_timeout = 10, + + --use youtube-dl to fetch a list of available formats (overrides quality_strings) + fetch_formats = true, + + --default menu entries + quality_strings=[[ + [ + {"4320p" : "bestvideo[height<=?4320p]+bestaudio/best"}, + {"2160p" : "bestvideo[height<=?2160]+bestaudio/best"}, + {"1440p" : "bestvideo[height<=?1440]+bestaudio/best"}, + {"1080p" : "bestvideo[height<=?1080]+bestaudio/best"}, + {"720p" : "bestvideo[height<=?720]+bestaudio/best"}, + {"480p" : "bestvideo[height<=?480]+bestaudio/best"}, + {"360p" : "bestvideo[height<=?360]+bestaudio/best"}, + {"240p" : "bestvideo[height<=?240]+bestaudio/best"}, + {"144p" : "bestvideo[height<=?144]+bestaudio/best"} + ] + ]], +} +(require 'mp.options').read_options(opts, "youtube-quality") +opts.quality_strings = utils.parse_json(opts.quality_strings) + +local destroyer = nil + + +function show_menu() + local selected = 1 + local active = 0 + local current_ytdl_format = mp.get_property("ytdl-format") + msg.verbose("current ytdl-format: "..current_ytdl_format) + local num_options = 0 + local options = {} + + + if opts.fetch_formats then + options, num_options = download_formats() + end + + if next(options) == nil then + for i,v in ipairs(opts.quality_strings) do + num_options = num_options + 1 + for k,v2 in pairs(v) do + options[i] = {label = k, format=v2} + if v2 == current_ytdl_format then + active = i + selected = active + end + end + end + end + + --set the cursor to the currently format + for i,v in ipairs(options) do + if v.format == current_ytdl_format then + active = i + selected = active + break + end + end + + function selected_move(amt) + selected = selected + amt + if selected < 1 then selected = num_options + elseif selected > num_options then selected = 1 end + timeout:kill() + timeout:resume() + draw_menu() + end + function choose_prefix(i) + if i == selected and i == active then return opts.selected_and_active + elseif i == selected then return opts.selected_and_inactive end + + if i ~= selected and i == active then return opts.unselected_and_active + elseif i ~= selected then return opts.unselected_and_inactive end + return "> " --shouldn't get here. + end + + function draw_menu() + local ass = assdraw.ass_new() + + ass:pos(opts.text_padding_x, opts.text_padding_y) + ass:append(opts.style_ass_tags) + + for i,v in ipairs(options) do + ass:append(choose_prefix(i)..v.label.."\\N") + end + + local w, h = mp.get_osd_size() + if opts.scale_playlist_by_window then w,h = 0, 0 end + mp.set_osd_ass(w, h, ass.text) + end + + function destroy() + timeout:kill() + mp.set_osd_ass(0,0,"") + mp.remove_key_binding("move_up") + mp.remove_key_binding("move_down") + mp.remove_key_binding("select") + mp.remove_key_binding("escape") + destroyer = nil + end + timeout = mp.add_periodic_timer(opts.menu_timeout, destroy) + destroyer = destroy + + mp.add_forced_key_binding(opts.up_binding, "move_up", function() selected_move(-1) end, {repeatable=true}) + mp.add_forced_key_binding(opts.down_binding, "move_down", function() selected_move(1) end, {repeatable=true}) + mp.add_forced_key_binding(opts.select_binding, "select", function() + destroy() + mp.set_property("ytdl-format", options[selected].format) + reload_resume() + end) + mp.add_forced_key_binding(opts.toggle_menu_binding, "escape", destroy) + + draw_menu() + return +end + +local ytdl = { + path = "youtube-dl", + searched = false, + blacklisted = {} +} + +format_cache={} +function download_formats() + local function exec(args) + local ret = utils.subprocess({args = args}) + return ret.status, ret.stdout, ret + end + + local function table_size(t) + s = 0 + for i,v in ipairs(t) do + s = s+1 + end + return s + end + + local url = mp.get_property("path") + + url = string.gsub(url, "ytdl://", "") -- Strip possible ytdl:// prefix. + + -- don't fetch the format list if we already have it + if format_cache[url] ~= nil then + local res = format_cache[url] + return res, table_size(res) + end + mp.osd_message("fetching available formats with youtube-dl...", 60) + + if not (ytdl.searched) then + local ytdl_mcd = mp.find_config_file("youtube-dl") + if not (ytdl_mcd == nil) then + msg.verbose("found youtube-dl at: " .. ytdl_mcd) + ytdl.path = ytdl_mcd + end + ytdl.searched = true + end + + local command = {ytdl.path, "--no-warnings", "--no-playlist", "-J"} + table.insert(command, url) + local es, json, result = exec(command) + + if (es < 0) or (json == nil) or (json == "") then + mp.osd_message("fetching formats failed...", 1) + msg.error("failed to get format list: " .. err) + return {}, 0 + end + + local json, err = utils.parse_json(json) + + if (json == nil) then + mp.osd_message("fetching formats failed...", 1) + msg.error("failed to parse JSON data: " .. err) + return {}, 0 + end + + res = {} + msg.verbose("youtube-dl succeeded!") + for i,v in ipairs(json.formats) do + if v.vcodec ~= "none" then + local fps = v.fps and v.fps.."fps" or "" + local resolution = string.format("%sx%s", v.width, v.height) + local l = string.format("%-9s %-5s (%-4s / %s)", resolution, fps, v.ext, v.vcodec) + local f = string.format("%s+bestaudio/best", v.format_id) + table.insert(res, {label=l, format=f, width=v.width }) + end + end + + table.sort(res, function(a, b) return a.width > b.width end) + + mp.osd_message("", 0) + format_cache[url] = res + return res, table_size(res) +end + + +-- register script message to show menu +mp.register_script_message("toggle-quality-menu", +function() + if destroyer ~= nil then + destroyer() + else + show_menu() + end +end) + +-- keybind to launch menu +mp.add_key_binding(opts.toggle_menu_binding, "quality-menu", show_menu) + +-- special thanks to reload.lua (https://github.com/4e6/mpv-reload/) +function reload_resume() + local playlist_pos = mp.get_property_number("playlist-pos") + local reload_duration = mp.get_property_native("duration") + local time_pos = mp.get_property("time-pos") + + mp.set_property_number("playlist-pos", playlist_pos) + + -- Tries to determine live stream vs. pre-recordered VOD. VOD has non-zero + -- duration property. When reloading VOD, to keep the current time position + -- we should provide offset from the start. Stream doesn't have fixed start. + -- Decent choice would be to reload stream from it's current 'live' positon. + -- That's the reason we don't pass the offset when reloading streams. + if reload_duration and reload_duration > 0 then + local function seeker() + mp.commandv("seek", time_pos, "absolute") + mp.unregister_event(seeker) + end + mp.register_event("file-loaded", seeker) + end +end diff --git a/.config/sh/functionrc b/.config/sh/functionrc @@ -4,5 +4,5 @@ f() { fff "${@}" && cd "$(cat "${XDG_CACHE_HOME:-${HOME}/.cache}/fff/.fff_d")" || exit ; } s() { du -a "${HOME}" | awk '{ $1="" } { gsub("^ ", "", $0); print "\"" $0 "\"" }' | fzf | sed -e 's/^.//' -e 's/.$//' | open.sh ; } -rands() { </dev/urandom tr -dc 'A-Za-z0-9!"#$%&'\''()*+,-./:;<=>?@[\]^_`{|}~' | head -c "${1}" ; printf '%s\n'; } +rands() { </dev/urandom tr -dc 'A-Za-z0-9!"#$%&'\''()*+,-./:;<=>?@[\]^_`{|}~' | head -c "${1}"; printf '\n' ; } rp() { for f in *; do mv "${f}" "$(printf '%s\n' "${f}" | sed "s/${1}/${2}/g")"; done ; } diff --git a/.config/x/xresources b/.config/x/xresources @@ -21,7 +21,7 @@ Xft.antialias: 1 Xft.hinting: 1 Xft.autohint: 0 Xft.rgba: rgb -Xft.hintstyle: hintslight +Xft.hintstyle: hintmedium Xft.lcdfilter: lcddefault ! dwm