Compare commits

..

3 Commits

Author SHA1 Message Date
77121f74de update script-opts config 2025-09-09 00:40:49 -07:00
7e3f8170bf Merge branch 'master' of github.com:ksyasuda/dotfiles 2025-09-09 00:33:47 -07:00
6f8ff08859 add mpv 2025-09-09 00:29:30 -07:00
67 changed files with 17458 additions and 0 deletions

6
.config/mpv/.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
immersive-data
.ytdl_preload/
.ytdl-preload/
scripts/anilistUpdater/anilistToken.txt
.watch-later
state

2
.config/mpv/.prettierrc Normal file
View File

@@ -0,0 +1,2 @@
trailingComma: "es5"
singleQuote: true

Binary file not shown.

Binary file not shown.

281
.config/mpv/input.conf Normal file
View File

@@ -0,0 +1,281 @@
# mpv keybindings
#
# Location of user-defined bindings: ~/.config/mpv/input.conf
#
# Lines starting with # are comments. Use SHARP to assign the # key.
# Copy this file and uncomment and edit the bindings you want to change.
#
# List of commands and further details: DOCS/man/input.rst
# List of special keys: --input-keylist
# Keybindings testing mode: mpv --input-test --force-window --idle
#
# Use 'ignore' to unbind a key fully (e.g. 'ctrl+a ignore').
#
# Strings need to be quoted and escaped:
# KEY show-text "This is a single backslash: \\ and a quote: \" !"
#
# You can use modifier-key combinations like Shift+Left or Ctrl+Alt+x with
# the modifiers Shift, Ctrl, Alt and Meta (may not work on the terminal).
#
# The default keybindings are hardcoded into the mpv binary.
# You can disable them completely with: --no-input-default-bindings
# Developer note:
# On compilation, this file is baked into the mpv binary, and all lines are
# uncommented (unless '#' is followed by a space) - thus this file defines the
# default key bindings.
# If this is enabled, treat all the following bindings as default.
#default-bindings start
#MBTN_LEFT ignore # don't do anything
#MBTN_LEFT_DBL cycle fullscreen # toggle fullscreen on/off
#MBTN_RIGHT cycle pause # toggle pause on/off
#MBTN_BACK playlist-prev
#MBTN_FORWARD playlist-next
# Mouse wheels, touchpad or other input devices that have axes
# if the input devices supports precise scrolling it will also scale the
# numeric value accordingly
#WHEEL_UP seek 10
#WHEEL_DOWN seek -10
#WHEEL_LEFT add volume -2
#WHEEL_RIGHT add volume 2
## Seek units are in seconds, but note that these are limited by keyframes
#RIGHT seek 5
#LEFT seek -5
#UP seek 60
#DOWN seek -60
# Do smaller, always exact (non-keyframe-limited), seeks with shift.
# Don't show them on the OSD (no-osd).
#Shift+RIGHT no-osd seek 1 exact
#Shift+LEFT no-osd seek -1 exact
#Shift+UP no-osd seek 5 exact
#Shift+DOWN no-osd seek -5 exact
# Skip to previous/next subtitle (subject to some restrictions; see manpage)
#Ctrl+LEFT no-osd sub-seek -1
#Ctrl+RIGHT no-osd sub-seek 1
# Adjust timing to previous/next subtitle
#Ctrl+Shift+LEFT sub-step -1
#Ctrl+Shift+RIGHT sub-step 1
# Move video rectangle
#Alt+left add video-pan-x 0.1
#Alt+right add video-pan-x -0.1
#Alt+up add video-pan-y 0.1
#Alt+down add video-pan-y -0.1
# Zoom/unzoom video
#Alt++ add video-zoom 0.1
#Alt+- add video-zoom -0.1
# Reset video zoom/pan settings
#Alt+BS set video-zoom 0 ; set video-pan-x 0 ; set video-pan-y 0
#PGUP add chapter 1 # skip to next chapter
#PGDWN add chapter -1 # skip to previous chapter
#Shift+PGUP seek 600
#Shift+PGDWN seek -600
[ add speed -0.05 # scale playback speed
] add speed 0.05
#{ multiply speed 0.5
#} multiply speed 2.0
#BS set speed 1.0 # reset speed to normal
#Shift+BS revert-seek # undo previous (or marked) seek
#Shift+Ctrl+BS revert-seek mark # mark position for revert-seek
#q quit
#Q quit-watch-later
#q {encode} quit 4
#ESC set fullscreen no
#ESC {encode} quit 4
#p cycle pause # toggle pause/playback mode
#. frame-step # advance one frame and pause
#, frame-back-step # go back by one frame and pause
#SPACE cycle pause
#> playlist-next # skip to next file
#ENTER playlist-next # skip to next file
#< playlist-prev # skip to previous file
#O no-osd cycle-values osd-level 3 1 # cycle through OSD mode
#o show-progress
#P show-progress
#i script-binding stats/display-stats
#I script-binding stats/display-stats-toggle
#` script-binding console/enable
#z add sub-delay -0.1 # subtract 100 ms delay from subs
#Z add sub-delay +0.1 # add
#x add sub-delay +0.1 # same as previous binding (discouraged)
#ctrl++ add audio-delay 0.100 # this changes audio/video sync
#ctrl+- add audio-delay -0.100
#Shift+g add sub-scale +0.1 # increase subtitle font size
#Shift+f add sub-scale -0.1 # decrease subtitle font size
9 add volume -5
#/ add volume -2
0 add volume 5
#* add volume 2
#m cycle mute
#1 add contrast -1
#2 add contrast 1
#3 add brightness -1
#4 add brightness 1
#5 add gamma -1
#6 add gamma 1
#7 add saturation -1
#8 add saturation 1
#Alt+0 set window-scale 0.5
#Alt+1 set window-scale 1.0
#Alt+2 set window-scale 2.0
# toggle deinterlacer (automatically inserts or removes required filter)
#d cycle deinterlace
#r add sub-pos -1 # move subtitles up
#R add sub-pos +1 # down
#t add sub-pos +1 # same as previous binding (discouraged)
#v cycle sub-visibility
# stretch SSA/ASS subtitles with anamorphic videos to match historical
#V cycle sub-ass-vsfilter-aspect-compat
# switch between applying no style overrides to SSA/ASS subtitles, and
# overriding them almost completely with the normal subtitle style
#u cycle-values sub-ass-override "force" "no"
#j cycle sub # cycle through subtitles
#J cycle sub down # ...backwards
#SHARP cycle audio # switch audio streams
#_ cycle video
#T cycle ontop # toggle video window ontop of other windows
#f cycle fullscreen # toggle fullscreen
#s screenshot # take a screenshot
#S screenshot video # ...without subtitles
#Ctrl+s screenshot window # ...with subtitles and OSD, and scaled
#Alt+s screenshot each-frame # automatically screenshot every frame
#w add panscan -0.1 # zoom out with -panscan 0 -fs
#W add panscan +0.1 # in
#e add panscan +0.1 # same as previous binding (discouraged)
# cycle video aspect ratios; "-1" is the container aspect
#A cycle-values video-aspect-override "16:9" "4:3" "2.35:1" "-1"
#POWER quit
#PLAY cycle pause
#PAUSE cycle pause
#PLAYPAUSE cycle pause
#PLAYONLY set pause no
#PAUSEONLY set pause yes
#STOP quit
#FORWARD seek 60
#REWIND seek -60
#NEXT playlist-next
#PREV playlist-prev
#VOLUME_UP add volume 2
#VOLUME_DOWN add volume -2
#MUTE cycle mute
#CLOSE_WIN quit
#CLOSE_WIN {encode} quit 4
#ctrl+w quit
#E cycle edition # next edition
#l ab-loop # Set/clear A-B loop points
#L cycle-values loop-file "inf" "no" # toggle infinite looping
#ctrl+c quit 4
#DEL script-binding osc/visibility # cycle OSC display
#ctrl+h cycle-values hwdec "auto" "no" # cycle hardware decoding
#F8 show_text ${playlist} # show playlist
#F9 show_text ${track-list} # show list of audio/sub streams
#
# Legacy bindings (may or may not be removed in the future)
#
#! add chapter -1 # skip to previous chapter
#@ add chapter 1 # next
#
# Not assigned by default
# (not an exhaustive list of unbound commands)
#
# ? cycle angle # switch DVD/Bluray angle
# ? cycle sub-forced-only # toggle DVD forced subs
# ? cycle program # cycle transport stream programs
# ? stop # stop playback (quit or enter idle mode)
# n cycle_values af loudnorm=I=-30 loudnorm=I=-15 anull
CTRL+1 no-osd change-list glsl-shaders set "~/.config/mpv/shaders/FSR.glsl"; show-text "FSR"
CTRL+2 no-osd change-list glsl-shaders set "~/.config/mpv/shaders/NVScaler.glsl"; show-text "NIS"
CTRL+3 no-osd change-list glsl-shaders set "~/.config/mpv/shaders/CAS-scaled.glsl"; show-text "CAS"
CTRL+4 no-osd change-list glsl-shaders set "~/.config/mpv/shaders/FSRCNNX.glsl"; show-text "FSRCNNX"
CTRL+5 no-osd change-list glsl-shaders set "~/.config/mpv/shaders/ArtCNN_C4F32.glsl"; show-text "ArtCNN"
CTRL+6 no-osd change-list glsl-shaders set "~/.config/mpv/shaders/ArtCNN_C4F16_DS.glsl"; show-text "ArtCNN"
CTRL+7 no-osd change-list glsl-shaders set "~/.config/mpv/shaders/ArtCNN_C4F16.glsl"; show-text "ArtCNN"
CTRL+0 no-osd change-list glsl-shaders clr ""; show-text "GLSL shaders cleared"
ctrl+K cycle-values keep-open "yes" "no"
ctrl+r script-binding reload-scripts
ctrl+s script_binding autosubsync-menu
# {{{ sponsorblock
ctrl+g script-binding sponsorblock/set_segment
ctrl+G script-binding sponsorblock/submit_segment
ctrl+< script-binding sponsorblock/upvote_setment
ctrl+> script-binding sponsorblock/downvote_segment
#}}}
# {{{ anilist
ctrl+A script-binding update_anilist
ctrl+B script-binding launch_anilist
ctrl+E script-binding open_folder
ctrl+V script-binding mpvacious-secondary-sid-toggle
# }}}
# {{{ mpvacious (subs2srs)
a script-binding mpvacious-menu-open
ctrl+g ignore # script-binding mpvacious-animated-snapshot-toggle
ctrl+N script-binding mpvacious-export-note
ctrl+b ignore # script-binding mpvacious-update-selected-note
ctrl+B ignore # script-binding mpvacious-overwrite-selected-note
ctrl+m ignore # script-binding mpvacious-update-last-note
ctrl+M ignore # script-binding mpvacious-overwrite-last-note
G script-binding mpvacious-quick-card-menu-open
alt+g script-binding mpvacious-quick-card-sel-menu-open
ctrl+c script-binding mpvacious-copy-primary-sub-to-clipboard
ctrl+C script-binding mpvacious-copy-secondary-sub-to-clipboard
ctrl+= script-binding mpvacious-autocopy-toggle
H script-binding mpvacious-sub-seek-back
L script-binding mpvacious-sub-seek-forward
alt+h script-binding mpvacious-sub-seek-back-pause
alt+l script-binding mpvacious-sub-seek-forward-pause
ctrl+h script-binding mpvacious-sub-rewind
ctrl+H script-binding mpvacious-sub-replay
ctrl+L script-binding mpvacious-sub-play-up-to-next
ctrl+V script-binding mpvacious-secondary-sid-toggle
ctrl+K script-binding mpvacious-secondary-sid-prev
ctrl+J script-binding mpvacious-secondary-sid-next
# }}}
# {{ animecards
ctrl+v script-binding animecards/update-anki-card
# }}
# {{{ mpv-youtube-queue
ctrl+a script-binding mpv_youtube_queue/add_to_queue
ctrl+n script-binding mpv_youtube_queue/play_next_in_queue
ctrl+p script-binding mpv_youtube_queue/play_previous_in_queue
ctrl+q script-binding mpv_youtube_queue/print_queue
ctrl+k script-binding mpv_youtube_queue/move_cursor_up
ctrl+j script-binding mpv_youtube_queue/move_cursor_down
ctrl+ENTER script-binding mpv_youtube_queue/play_selected_video
ctrl+o script-binding mpv_youtube_queue/open_video_in_browser
ctrl+P script-binding mpv_youtube_queue/print_current_video
ctrl+O script-binding mpv_youtube_queue/open_channel_in_browser
ctrl+d script-binding mpv_youtube_queue/download_current_video
ctrl+D script-binding mpv_youtube_queue/download_selected_video
ctrl+m script-binding mpv_youtube_queue/move_video
ctrl+x script-binding mpv_youtube_queue/delete_video
#}}}
#{{{ MPV SELECT
g ignore
g-a script-binding select/select-aid
g-b script-binding select/select-binding
g-c script-binding select/select-chapter
g-e script-binding select/select-edition
g-h script-binding select/select-watch-history
g-l script-binding select/select-subtitle-line
g-m script-binding select/menu
g-p script-binding select/select-playlist
g-r script-binding select/show-properties
g-s script-binding select/select-sid
g-S script-binding select/select-secondary-sid
g-t script-binding select/select-track
g-v script-binding select/select-vid
g-w script-binding select/select-watch-later
# }}}

View File

@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<dir>/home/sudacode/.config/mpv/fonts</dir>
<include ignore_missing="yes">/etc/fonts/fonts.conf</include>
<include ignore_missing="yes">/etc/fonts/conf.d</include>
<alias>
<family>sans-serif</family>
<prefer>
<family>JetBrainsMono Nerd Font</family>
<family>Fluent System Icons</family>
<family>Noto Sans CJK JP</family>
<family>Noto Sans</family>
<family>Open Sans</family>
</prefer>
</alias>
</fontconfig>

View File

@@ -0,0 +1,139 @@
user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36"
cache=yes
demuxer-max-bytes=500M
demuxer-max-back-bytes=100M
cache-pause=no
ontop=yes
sub-font="JetBrainsMono Nerd Font"
sub-font-size=45
# osd-font="Fluent System Icons"
border=no
# geometry=50%
autofit=50%
volume=75
audio-spdif=ac3,dts-hd,truehd
# glsl-shaders="~~/shaders/Anime4K_Clamp_Highlights.glsl:~~/shaders/Anime4K_Restore_CNN_VL.glsl:~~/shaders/Anime4K_Upscale_CNN_x2_VL.glsl:~~/shaders/Anime4K_AutoDownscalePre_x2.glsl:~~/shaders/Anime4K_AutoDownscalePre_x4.glsl:~~/shaders/Anime4K_Upscale_CNN_x2_M.glsl"
# glsl-shaders="~~/shaders/FSRCNNX.glsl:~~/shaders/FSR.glsl:~~/shaders/NVScaler.glsl:~~/shaders/CAS-scaled.glsl"
# glsl-shaders="~~/shaders/ArtCNN_C4F32_DS.glsl"
glsl-shaders="~~/shaders/ArtCNN_C4F32.glsl"
# Can fix stuttering in some cases, in other cases probably causes it. Try it if you experience stuttering.
opengl-early-flush=no
video-sync=display-resample
osc=no
no-border
ytdl-raw-options=sub-langs=en.*,write-auto-subs=
ytdl-format=bestvideo+bestaudio/best
# get subtitles for videos automatically
sub-auto=fuzzy
slang=en,eng
# profile=svp
profile=high-quality
blend-subtitles=video
# GPU OPTIONS
vo=gpu-next
hwdec=nvdec
gpu-api=vulkan
scale=ewa_lanczossharp
dscale=catmull_rom
cscale=bicubic
tscale=oversample
interpolation=yes
interpolation-preserve=no
# fruit: 8-Bit/8-Bit+FRC display
# ordered: true 10-Bit/12-Bit display
# error-diffusion: high-end GPUs
dither=error-diffusion
dither-depth=auto
error-diffusion=sierra-lite # uncomment if not 'error-diffusion'
###### Antiring
scale-antiring=0.5
dscale-antiring=0.5
cscale-antiring=0.5
# laptop
# vo=gpu
# gpu-api=opengl
# gpu-context=wayland
# profile=opengl-hq
gpu-context=waylandvk
gpu-api=vulkan
vulkan-swap-mode=mailbox
swapchain-depth=2
vulkan-async-compute=no
vd-lavc-threads=0
opengl-pbo=yes
vd-lavc-film-grain=gpu
input-ipc-server=/tmp/mpvsocket
# ao=pule,pipewire
ao=pipewire,pulse
deband=yes
deband-iterations=4
deband-threshold=35
deband-range=16
deband-grain=4
subs-with-matching-audio=no
sub-fix-timing=yes
sub-ass-override=scale
#Some settings fixing VOB/PGS subtitles (creating blur & changing yellow subs to gray)
sub-gauss=1.0
sub-gray=yes
###### High-quality screenshots
screenshot-format=webp
screenshot-webp-lossless=yes
screenshot-high-bit-depth=yes
screenshot-sw=no
screenshot-directory="/truenas/sudacode/pictures/mpv"
screenshot-template="%f-%wH.%wM.%wS.%wT-#%#00n"
save-position-on-quit
watch-later-dir="~~/.watch-later"
resume-playback=yes
save-watch-history
watch-history-path="~~/state/watch_history.jsonl"
target-colorspace-hint=yes
[hdr]
target-colorspace-hint=yes
gpu-api=vulkan
gpu-context=waylandvk
[svp]
input-ipc-server=/tmp/mpvsocket # Receives input from SVP
hr-seek-framedrop=no # Fixes audio desync
resume-playback=no # Not compatible with SVP
[Idle]
profile-cond=p["idle-active"]
profile-restore=copy-equal
title=' '
keepaspect=no
[immersion]
cookies=yes
cookies-file=/truenas/sudacode/japanese/cookies.Japanese.txt
ytdl-raw-options=mark-watched=,write-auto-subs=,sub-langs=ja.*
ytdl-raw-options-append=cookies=/truenas/sudacode/japanese/cookies.Japanese.txt
ytdl-raw-options-append=sponsorblock-mark=all
ytdl-raw-options-append=sponsorblock-remove=sponsor
ytdl-format=bestvideo+bestaudio/best
# get subtitles for videos automatically
sub-auto=fuzzy
slang=ja,jpn,JA,JPN,ja.hi,ja.*
alang=ja,jpn
vlang=ja,jpn
sub-font="Noto Sans CJK JP"
sub-border-size=1
sub-shadow-color=0.0/0.0/0.0/0.50
sub-shadow-offset=2

View File

@@ -0,0 +1,243 @@
#
# Example mpv configuration file
#
# Warning:
#
# The commented example options usually do _not_ set the default values. Call
# mpv with --list-options to see the default values for most options. There is
# no builtin or example mpv.conf with all the defaults.
#
#
# Configuration files are read system-wide from /usr/local/etc/mpv.conf
# and per-user from ~~/mpv.conf, where per-user settings override
# system-wide settings, all of which are overridden by the command line.
#
# Configuration file settings and the command line options use the same
# underlying mechanisms. Most options can be put into the configuration file
# by dropping the preceding '--'. See the man page for a complete list of
# options.
#
# Lines starting with '#' are comments and are ignored.
#
# See the CONFIGURATION FILES section in the man page
# for a detailed description of the syntax.
#
# Profiles should be placed at the bottom of the configuration file to ensure
# that settings wanted as defaults are not restricted to specific profiles.
##################
# video settings #
##################
# Start in fullscreen mode by default.
#fs=yes
# force starting with centered window
# geometry=50%:50%
# don't allow a new window to have a size larger than 90% of the screen size
#autofit-larger=90%x90%
# Do not close the window on exit.
#keep-open=yes
# Do not wait with showing the video window until it has loaded. (This will
# resize the window once video is loaded. Also always shows a window with
# audio.)
#force-window=immediate
# Disable the On Screen Controller (OSC).
# osc=no
# Keep the player window on top of all other windows.
# window=scale=1.0
# Specify high quality video rendering preset (for --vo=gpu only)
# Can cause performance problems with some drivers and GPUs.
# profile=gpu-hq
# Force video to lock on the display's refresh rate, and change video and audio
# speed to some degree to ensure synchronous playback - can cause problems
# with some drivers and desktop environments.
#video-sync=display-resample
# Enable hardware decoding if available. Often, this does not work with all
# video outputs, but should work well with default settings on most systems.
# If performance or energy usage is an issue, forcing the vdpau or vaapi VOs
# may or may not help.
# discourged by mpv devs and not likely to make significant difference
# hwdec=auto-copy
# hwdec-codecs=all
##################
# audio settings #
##################
# Specify default audio device. You can list devices with: --audio-device=help
# The option takes the device string (the stuff between the '...').
#audio-device=alsa/default
# Do not filter audio to keep pitch when changing playback speed.
#audio-pitch-correction=no
# Output 5.1 audio natively, and upmix/downmix audio with a different format.
#audio-channels=5.1
# Disable any automatic remix, _if_ the audio output accepts the audio format.
# of the currently played file. See caveats mentioned in the manpage.
# (The default is "auto-safe", see manpage.)
#audio-channels=auto
##################
# other settings #
##################
# Pretend to be a web browser. Might fix playback with some streaming sites,
# but also will break with shoutcast streams.
# user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36"
user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36"
# user-agent="Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36"
# user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/37.0.2062.94 Chrome/37.0.2062.94 Safari/537.36"
# user-agent="Chromium/37.0.2062.94 Chrome/37.0.2062.94 Safari/537.36"
# cache settings
#
# Use a large seekable RAM cache even for local input.
cache=yes
#
# Use extra large RAM cache (needs cache=yes to make it useful).
demuxer-max-bytes=500M
demuxer-max-back-bytes=100M
#
# Disable the behavior that the player will pause if the cache goes below a
# certain fill size.
cache-pause=no
#
# Store cache payload on the hard disk instead of in RAM. (This may negatively
# impact performance unless used for slow input such as network.)
#cache-dir=~/.cache/
#cache-on-disk=yes
# Display English subtitles if available.
#slang=en
# Play Finnish audio if available, fall back to English otherwise.
#alang=fi,en
# Change subtitle encoding. For Arabic subtitles use 'cp1256'.
# If the file seems to be valid UTF-8, prefer UTF-8.
# (You can add '+' in front of the codepage to force it.)
#sub-codepage=cp1256
# You can also include other configuration files.
#include=/path/to/the/file/you/want/to/include
############
# Profiles #
############
# The options declared as part of profiles override global default settings,
# but only take effect when the profile is active.
# The following profile can be enabled on the command line with: --profile=eye-cancer
#[eye-cancer]
#sharpen=5
sub-font="JetBrainsMono Nerd Font"
sub-font-size=45
# osd-font="Fluent System Icons"
border=no
geometry=50%
volume=50
# speed-step=0.05
# audio-spdif=ac3,eac3,dts-hd,truehd
# glsl-shaders="~~/shaders/Anime4K_Clamp_Highlights.glsl:~~/shaders/Anime4K_Restore_CNN_VL.glsl:~~/shaders/Anime4K_Upscale_CNN_x2_VL.glsl:~~/shaders/Anime4K_AutoDownscalePre_x2.glsl:~~/shaders/Anime4K_AutoDownscalePre_x4.glsl:~~/shaders/Anime4K_Upscale_CNN_x2_M.glsl"
glsl-shaders="~~/shaders/ArtCNN_C4F16.glsl"
# glsl-shaders="~~/shaders/FSR.glsl"
# Can fix stuttering in some cases, in other cases probably causes it. Try it if you experience stuttering.
opengl-early-flush=no
video-sync=display-resample
osc=no
no-border
ytdl-raw-options=sub-langs=en.*,write-auto-subs=
ytdl-format=bestvideo+bestaudio/best
# get subtitles for videos automatically
sub-auto=fuzzy
slang=en,eng
# CATPPUCCIN MACHIATTO
# Main mpv options
background-color='#24273a'
osd-back-color='#181926'
osd-border-color='#181926'
osd-color='#cad3f5'
osd-shadow-color='#24273a'
# Stats script options
# Options are on separate lines for clarity
# Colors are in #BBGGRR format
script-opts-append=stats-border_color=30201e
script-opts-append=stats-font_color=f5d3ca
script-opts-append=stats-plot_bg_border_color=f8bdb7
script-opts-append=stats-plot_bg_color=30201e
script-opts-append=stats-plot_color=f8bdb7
# profile=svp
profile=gpu-hq
# GPU OPTIONS
vo=gpu-next
# hwdec=nvdec-copy
hwdec=videotoolbox
scale=bicubic
dscale=bicubic
cscale=bicubic
tscale=oversample
interpolation=yes
interpolation-preserve=no
input-ipc-server=/tmp/mpvsocket
# ao=pule,pipewire
# ao=pipewire,pulse
ontop=yes
ao=coreaudio
save-position-on-quit
watch-later-dir="~~.watch-later"
resume-playback=yes
save-watch-history
watch-history-path="~~state/watch_history.jsonl"
vd-lavc-threads=0
gpu-api=vulkan
gpu-context=macvk
opengl-pbo=yes
[svp]
input-ipc-server=/tmp/mpvsocket # Receives input from SVP
hr-seek-framedrop=no # Fixes audio desync
resume-playback=no # Not compatible with SVP
[Idle]
profile-cond=p["idle-active"]
profile-restore=copy-equal
title=' '
keepaspect=no
[immersion]
cookies=yes
cookies-file=/Volumes/sudacode/japanese/cookies.Japanese.txt
ytdl-raw-options=mark-watched=,write-auto-subs=,sub-langs=ja.*
ytdl-raw-options-append=cookies=/Volumes/sudacode/japanese/cookies.Japanese.txt
ytdl-raw-options-append=sponsorblock-mark=all
ytdl-raw-options-append=sponsorblock-remove=sponsor
ytdl-format=bestvideo+bestaudio/best
# get subtitles for videos automatically
sub-auto=fuzzy
slang=ja,jpn
alang=ja,jpn
vlang=ja,jpn

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,293 @@
local mp = require 'mp'
local scroll_list = {
global_style = [[]],
header_style = [[{\q2\fs35\c&00ccff&}]],
list_style = [[{\q2\fs25\c&Hffffff&}]],
wrapper_style = [[{\c&00ccff&\fs16}]],
cursor_style = [[{\c&00ccff&}]],
selected_style = [[{\c&Hfce788&}]],
cursor = [[➤\h]],
indent = [[\h\h\h\h]],
num_entries = 16,
wrap = false,
empty_text = "no entries"
}
--formats strings for ass handling
--this function is based on a similar function from https://github.com/mpv-player/mpv/blob/master/player/lua/console.lua#L110
function scroll_list.ass_escape(str, replace_newline)
if replace_newline == true then replace_newline = "\\\239\187\191n" end
--escape the invalid single characters
str = str:gsub('[\\{}\n]', {
-- There is no escape for '\' in ASS (I think?) but '\' is used verbatim if
-- it isn't followed by a recognised character, so add a zero-width
-- non-breaking space
['\\'] = '\\\239\187\191',
['{'] = '\\{',
['}'] = '\\}',
-- Precede newlines with a ZWNBSP to prevent ASS's weird collapsing of
-- consecutive newlines
['\n'] = '\239\187\191\\N',
})
-- Turn leading spaces into hard spaces to prevent ASS from stripping them
str = str:gsub('\\N ', '\\N\\h')
str = str:gsub('^ ', '\\h')
if replace_newline then
str = str:gsub("\\N", replace_newline)
end
return str
end
--format and return the header string
function scroll_list:format_header_string(str)
return str
end
--appends the entered text to the overlay
function scroll_list:append(text)
if text == nil then return end
self.ass.data = self.ass.data .. text
end
--appends a newline character to the osd
function scroll_list:newline()
self.ass.data = self.ass.data .. '\\N'
end
--re-parses the list into an ass string
--if the list is closed then it flags an update on the next open
function scroll_list:update()
if self.hidden then self.flag_update = true
else self:update_ass() end
end
--prints the header to the overlay
function scroll_list:format_header()
self:append(self.header_style)
self:append(self:format_header_string(self.header))
self:newline()
end
--formats each line of the list and prints it to the overlay
function scroll_list:format_line(index, item)
self:append(self.list_style)
if index == self.selected then self:append(self.cursor_style..self.cursor..self.selected_style)
else self:append(self.indent) end
self:append(item.style)
self:append(item.ass)
self:newline()
end
--refreshes the ass text using the contents of the list
function scroll_list:update_ass()
self.ass.data = self.global_style
self:format_header()
if #self.list < 1 then
self:append(self.empty_text)
self.ass:update()
return
end
local start = 1
local finish = start+self.num_entries-1
--handling cursor positioning
local mid = math.ceil(self.num_entries/2)+1
if self.selected+mid > finish then
local offset = self.selected - finish + mid
--if we've overshot the end of the list then undo some of the offset
if finish + offset > #self.list then
offset = offset - ((finish+offset) - #self.list)
end
start = start + offset
finish = finish + offset
end
--making sure that we don't overstep the boundaries
if start < 1 then start = 1 end
local overflow = finish < #self.list
--this is necessary when the number of items in the dir is less than the max
if not overflow then finish = #self.list end
--adding a header to show there are items above in the list
if start > 1 then self:append(self.wrapper_style..(start-1)..' item(s) above\\N\\N') end
for i=start, finish do
self:format_line(i, self.list[i])
end
if overflow then self:append('\\N'..self.wrapper_style..#self.list-finish..' item(s) remaining') end
self.ass:update()
end
--moves the selector down the list
function scroll_list:scroll_down()
if self.selected < #self.list then
self.selected = self.selected + 1
self:update_ass()
elseif self.wrap then
self.selected = 1
self:update_ass()
end
end
--moves the selector up the list
function scroll_list:scroll_up()
if self.selected > 1 then
self.selected = self.selected - 1
self:update_ass()
elseif self.wrap then
self.selected = #self.list
self:update_ass()
end
end
--moves the selector to the list next page
function scroll_list:move_pagedown()
if #self.list > self.num_entries then
self.selected = self.selected + self.num_entries
if self.selected > #self.list then self.selected = #self.list end
self:update_ass()
end
end
--moves the selector to the list previous page
function scroll_list:move_pageup()
if #self.list > self.num_entries then
self.selected = self.selected - self.num_entries
if self.selected < 1 then self.selected = 1 end
self:update_ass()
end
end
--moves the selector to the list begin
function scroll_list:move_begin()
if #self.list > 1 then
self.selected = 1
self:update_ass()
end
end
--moves the selector to the list end
function scroll_list:move_end()
if #self.list > 1 then
self.selected = #self.list
self:update_ass()
end
end
--adds the forced keybinds
function scroll_list:add_keybinds()
for _,v in ipairs(self.keybinds) do
mp.add_forced_key_binding(v[1], 'dynamic/'..self.ass.id..'/'..v[2], v[3], v[4])
end
end
--removes the forced keybinds
function scroll_list:remove_keybinds()
for _,v in ipairs(self.keybinds) do
mp.remove_key_binding('dynamic/'..self.ass.id..'/'..v[2])
end
end
--opens the list and sets the hidden flag
function scroll_list:open_list()
self.hidden = false
if not self.flag_update then self.ass:update()
else self.flag_update = false ; self:update_ass() end
end
--closes the list and sets the hidden flag
function scroll_list:close_list()
self.hidden = true
self.ass:remove()
end
--modifiable function that opens the list
function scroll_list:open()
if self.hidden then self:add_keybinds() end
self:open_list()
end
--modifiable function that closes the list
function scroll_list:close()
self:remove_keybinds()
self:close_list()
end
--toggles the list
function scroll_list:toggle()
if self.hidden then self:open()
else self:close() end
end
--clears the list in-place
function scroll_list:clear()
local i = 1
while self.list[i] do
self.list[i] = nil
i = i + 1
end
end
--added alias for ipairs(list.list) for lua 5.1
function scroll_list:ipairs()
return ipairs(self.list)
end
--append item to the end of the list
function scroll_list:insert(item)
self.list[#self.list + 1] = item
end
local metatable = {
__index = function(t, key)
if scroll_list[key] ~= nil then return scroll_list[key]
elseif key == "__current" then return t.list[t.selected]
elseif type(key) == "number" then return t.list[key] end
end,
__newindex = function(t, key, value)
if type(key) == "number" then rawset(t.list, key, value)
else rawset(t, key, value) end
end,
__scroll_list = scroll_list,
__len = function(t) return #t.list end,
__ipairs = function(t) return ipairs(t.list) end
}
--creates a new list object
function scroll_list:new()
local vars
vars = {
ass = mp.create_osd_overlay('ass-events'),
hidden = true,
flag_update = true,
header = "header \\N ----------------------------------------------",
list = {},
selected = 1,
keybinds = {
{'DOWN', 'scroll_down', function() vars:scroll_down() end, {repeatable = true}},
{'UP', 'scroll_up', function() vars:scroll_up() end, {repeatable = true}},
{'PGDWN', 'move_pagedown', function() vars:move_pagedown() end, {}},
{'PGUP', 'move_pageup', function() vars:move_pageup() end, {}},
{'HOME', 'move_begin', function() vars:move_begin() end, {}},
{'END', 'move_end', function() vars:move_end() end, {}},
{'ESC', 'close_browser', function() vars:close() end, {}}
}
}
return setmetatable(vars, metatable)
end
return scroll_list:new()

View File

@@ -0,0 +1,11 @@
# Use 'yes' or 'no' for boolean options below
# Example for multiple directories (comma or semicolon separated):
# DIRECTORIES=D:/Torrents,D:/Anime
# or
# DIRECTORIES=D:/Torrents;D:/Anime
DIRECTORIES=/truenas/jellyfin/anime
UPDATE_PERCENTAGE=85
SET_COMPLETED_TO_REWATCHING_ON_FIRST_EPISODE=no
UPDATE_PROGRESS_WHEN_REWATCHING=yes
SET_TO_COMPLETED_AFTER_LAST_EPISODE_CURRENT=yes
SET_TO_COMPLETED_AFTER_LAST_EPISODE_REWATCHING=yes

View File

@@ -0,0 +1,11 @@
# Use 'yes' or 'no' for boolean options below
# Example for multiple directories (comma or semicolon separated):
# DIRECTORIES=D:/Torrents,D:/Anime
# or
# DIRECTORIES=D:/Torrents;D:/Anime
DIRECTORIES=/Volumes/jellyfin/anime
UPDATE_PERCENTAGE=85
SET_COMPLETED_TO_REWATCHING_ON_FIRST_EPISODE=no
UPDATE_PROGRESS_WHEN_REWATCHING=yes
SET_TO_COMPLETED_AFTER_LAST_EPISODE_CURRENT=yes
SET_TO_COMPLETED_AFTER_LAST_EPISODE_REWATCHING=yes

View File

@@ -0,0 +1,107 @@
# =================================================
# Anacreon Script (Animecards) Config for MPV
# =================================================
# ⚠ WARNING:
# Use only yes/no (not true/false) in boolean options
# =================================================
# Anki Field Names
# These must match the field names in your Anki note type
# =================================================
FRONT_FIELD=Expression
SENTENCE_FIELD=Sentence
IMAGE_FIELD=Picture
SENTENCE_AUDIO_FIELD=SentenceAudio
# =================================================
# Behavior Settings
# =================================================
# [Not recommended] Copy subtitles to clipboard enabled by default? (yes/no)
# The more modern and recommended alternative is to use the websocket.
ENABLE_SUBS_TO_CLIP=no
# Ask before overwriting existing cards? (yes/no)
# Recommended to set yes unless you know what you are doing
ASK_TO_OVERWRITE=yes
# [Dangerous] Max cards that can be overwritten at once (-1 = unlimited)
OVERWRITE_LIMIT=8
# Keep bold formatting added by yomitan? (yes/no)
HIGHLIGHT_WORD=no
# Use MPV's built-in clipboard API (requires v0.40+)? (yes/no)
# Alternative clipboard method that may reduce latency on Windows.
# Supported on macOS and Wayland as well. Not supported on X11.
USE_MPV_CLIPBOARD_API=no
# ==========================================================
# Audio Settings
# ==========================================================
# [Optional] Padding and fade settings in seconds. (0 = disable)
# Padding grabs extra audio around your selected subs.
# Fade does a volume fade in/out effect.
AUDIO_CLIP_PADDING=0.75
AUDIO_CLIP_FADE=0.2
# Always create mono audio? (yes/no)
AUDIO_MONO=yes
# [Optional] Use MPV's current volume for card audio? (yes/no)
USE_MPV_VOLUME=no
# [Optional] Play sentence audio after updating the card? (yes/no)
AUTOPLAY_AUDIO=no
# =================================================
# Image Settings
# =================================================
# Format of screenshots: png, jpg or webp
# ⚠ Use png or jpg for iOS/Mac compatibility
# (webp won't display on iOS/Mac)
IMAGE_FORMAT=png
# Resize image to this height (in pixels).
# Preserves aspect ratio. (0 = keep original resolution)
IMAGE_HEIGHT=480
# [JPG only] Quality: from 0 (worst) to 100 (best)
JPG_QUALITY=88
# =================================================
# Animated Image Settings
# =================================================
# Enable animated export for the selected subtitle segment (yes/no)
ANIMATED_IMAGE_ENABLED=yes
# Animated format: webp or avif
ANIMATED_IMAGE_FORMAT=avif
# Resize animated image to this height (in pixels). (0 = keep original)
ANIMATED_IMAGE_HEIGHT=480
# Frames per second for animated export (1-30)
ANIMATED_IMAGE_FPS=24
# Quality 0-100 (mapped to CRF for avif)
ANIMATED_IMAGE_QUALITY=69
# =================================================
# Misc Info - Extra metadata for cards
# =================================================
# [Optional] Save extra metadata (filename, timestamp, etc.) to a field
WRITE_MISCINFO=yes
# Field to store the extra info (only used if WRITE_MISCINFO=yes)
MISCINFO_FIELD=MiscInfo
# Pattern for the Misc Info content:
# %f = filename (without extension)
# %F = filename (with extension)
# %t = timestamp (HH:MM:SS)
# %T = timestamp with milliseconds (HH:MM:SS:MLS)
# <br> = Next line tag
# Examples:
# MISCINFO_PATTERN %f (%t)
# MISCINFO_PATTERN=File: %F<br>Timestamp: %T
MISCINFO_PATTERN=[Anacreon Script] %f (%t)

View File

@@ -0,0 +1,33 @@
# Absolute paths to the executables, if needed:
# 1. ffmpeg
ffmpeg_path=/usr/bin/ffmpeg
# 2. ffsubsync
ffsubsync_path=/usr/bin/ffsubsync
# 3. alass
alass_path=/usr/bin/alass
# Preferred retiming tool. Allowed options: 'ffsubsync', 'alass', 'ask'.
# If set to 'ask', the add-on will ask to choose the tool every time:
# 1. Preferred tool for syncing to audio.
# audio_subsync_tool=ask
audio_subsync_tool=ffsubsync
# audio_subsync_tool=alass
# 2. Preferred tool for syncing to another subtitle.
# altsub_subsync_tool=ask
# altsub_subsync_tool=ffsubsync
altsub_subsync_tool=alass
# Unload old subs (yes,no)
# After retiming, tell mpv to forget the original subtitle track.
unload_old_sub=yes
# unload_old_sub=no
# Overwrite the original subtitle file.
# Replace the old subtitle file with the retimed file.
# overwrite_old_sub=yes
overwrite_old_sub=no

View File

@@ -0,0 +1,33 @@
# Absolute paths to the executables, if needed:
# 1. ffmpeg
ffmpeg_path=/opt/homebrew/bin/ffmpeg
# 2. ffsubsync
ffsubsync_path=/Users/sudacode/.local/bin/ffsubsync
# 3. alass
alass_path=/Users/sudacode/.local/bin/alass-cli
# Preferred retiming tool. Allowed options: 'ffsubsync', 'alass', 'ask'.
# If set to 'ask', the add-on will ask to choose the tool every time:
# 1. Preferred tool for syncing to audio.
# audio_subsync_tool=ask
audio_subsync_tool=ffsubsync
# audio_subsync_tool=alass
# 2. Preferred tool for syncing to another subtitle.
# altsub_subsync_tool=ask
# altsub_subsync_tool=ffsubsync
altsub_subsync_tool=alass
# Unload old subs (yes,no)
# After retiming, tell mpv to forget the original subtitle track.
unload_old_sub=yes
# unload_old_sub=no
# Overwrite the original subtitle file.
# Replace the old subtitle file with the retimed file.
# overwrite_old_sub=yes
overwrite_old_sub=no

View File

@@ -0,0 +1,22 @@
start_tracking_key=ctrl+t
data_dir=/home/sudacode/.config/mpv/scripts/immersion-tracker/data
csv_file=/truenas/sudacode/japanese/immersion_tracker.csv
session_file=/home/sudacode/.config/mpv/scripts/immersion-tracker/data/current_session.json
min_session_duration=30
save_interval=10
enable_debug_logging=no
backup_sessions=no
max_backup_files=10
use_title=yes
use_filename=no
custom_prefix=[Immersion]
max_title_length = 100
export_csv=yes
export_json=no
export_html=no
backup_csv=yes
show_session_start=yes
show_session_end=yes
show_progress_milestones=no
milestone_percentages=25507590

View File

@@ -0,0 +1,22 @@
start_tracking_key=ctrl+t
data_dir=/Users/sudacode/.config/mpv/scripts/immersion-tracker/data
csv_file=/Volumes/sudacode/japanese/immersion_tracker.csv
session_file=/Users/sudacode/.config/mpv/scripts/immersion-tracker/data/current_session.json
min_session_duration=30
save_interval=10
enable_debug_logging=no
backup_sessions=no
max_backup_files=10
use_title=yes
use_filename=no
custom_prefix=[Immersion]
max_title_length = 100
export_csv=yes
export_json=no
export_html=no
backup_csv=yes
show_session_start=yes
show_session_end=yes
show_progress_milestones=no
milestone_percentages=25507590

View File

@@ -0,0 +1,378 @@
# Language and display
# set language (for available options, see: https://github.com/Samillion/ModernZ/blob/main/docs/TRANSLATIONS.md)
language=en
# font for the OSC (default: mpv-osd-symbols or the one set in mpv.conf)
font=mpv-osd-symbols
# show mpv logo when idle
idlescreen=yes
# show OSC window top bar: "auto", "yes", or "no" (borderless/fullscreen)
window_top_bar=auto
# show OSC when windowed
showwindowed=yes
# show OSC when fullscreen
showfullscreen=yes
# show OSC when paused
showonpause=yes
# disable OSC hide timeout when paused
keeponpause=yes
# disable Santa hat in December
greenandgrumpy=no
# OSC behaviour and scaling
# time (in ms) before OSC hides if no mouse movement
hidetimeout=1500
# if seeking should reset the hidetimeout
seek_resets_hidetimeout=yes
# fade-out duration (in ms), set to 0 for no fade
fadeduration=200
# whether to enable fade-in effect
fadein=no
# minimum mouse movement (in pixels) required to show OSC
minmousemove=0
# show OSC only when hovering at the bottom
bottomhover=yes
# height of hover zone for bottomhover (in pixels)
bottomhover_zone=130
# show OSC when seeking
osc_on_seek=no
# show OSC on start of every file
osc_on_start=no
# pause video while seeking with mouse move (on button hold)
mouse_seek_pause=yes
# force show seekbar tooltip on mouse drag, even if not hovering seekbar
force_seek_tooltip=no
# scale osc with the video
vidscale=auto
# osc scale factor when windowed
scalewindowed=1.0
# osc scale factor when fullscreen
scalefullscreen=1.0
# Elements display
# show title in the OSC (above seekbar)
show_title=yes
# title above seekbar format: "${media-title}" or "${filename}"
title=${media-title}
# font size of the title text (above seekbar)
title_font_size=24
# chapter title font size
chapter_title_font_size=14
# show cached time information
cache_info=no
# show cache speed per second
cache_info_speed=no
# font size of the cache information
cache_info_font_size=12
# show chapter title alongside timestamp (below seekbar)
show_chapter_title=yes
# format for chapter display on seekbar hover (set to "no" to disable)
chapter_fmt=%s
# show total time instead of remaining time
timetotal=yes
# show timecodes with milliseconds
timems=no
# use the Unicode minus sign in remaining time
unicodeminus=no
# "dynamic" or "fixed". dynamic shows MM:SS when possible, fixed always shows HH:MM:SS
time_format=dynamic
# font size of the time display
time_font_size=16
# tooltips font size
tooltip_font_size=14
# Title bar settings
# show window title in borderless/fullscreen mode
window_title=no
# show window controls (close, minimize, maximize) in borderless/fullscreen
window_controls=yes
# same as title but for window_top_bar
windowcontrols_title=${media-title}
# Subtitle display settings
# raise subtitles above the OSC when shown
raise_subtitles=yes
# amount by which subtitles are raised when the OSC is shown (in pixels)
raise_subtitle_amount=125
# Buttons display and functionality
# show the jump backward and forward buttons
jump_buttons=yes
# change the jump amount in seconds
jump_amount=1
# change the jump amount in seconds when right-clicking jump buttons and shift-clicking chapter skip buttons
jump_more_amount=5
# show different icon when jump_amount is set to 5, 10, or 30
jump_icon_number=yes
# seek mode for jump buttons
jump_mode=relative
# enable continuous jumping when holding down seek buttons
jump_softrepeat=yes
# show the chapter skip backward and forward buttons
chapter_skip_buttons=no
# enable continuous skipping when holding down chapter skip buttons
chapter_softrepeat=yes
# show next/previous playlist track buttons
track_nextprev_buttons=yes
# show mute button and volume slider
volume_control=yes
# volume scale type: "linear" or "logarithmic"
volume_control_type=linear
# show playlist button: Left-click for simple playlist, Right-click for interactive playlist
playlist_button=yes
# hide playlist button when no playlist exists
hide_empty_playlist_button=yes
# gray out the playlist button when no playlist exists
gray_empty_playlist_button=yes
# show download button on web videos (requires yt-dlp and ffmpeg)
download_button=yes
# default download directory for videos (https://mpv.io/manual/master/#paths)
download_path=~~desktop/mpv
# show screenshot button
screenshot_button=no
# flag for screenshot button: "subtitles", "video", "window", "each-frame"
screenshot_flag=subtitles
# show window on top button
ontop_button=yes
# show loop button
loop_button=no
# show speed control button
speed_button=no
# speed change amount per click
speed_button_click=1
# speed change amount on scroll
speed_button_scroll=0.25
# show info button
info_button=yes
# show fullscreen toggle button
fullscreen_button=yes
# enable looping by right-clicking pause
loop_in_pause=yes
# force buttons to always be active. can add: playlist_prev,playlist_next
buttons_always_active=none
# icon size for the play/pause button
playpause_size=28
# icon size for the middle buttons
midbuttons_size=24
# icon size for the side buttons
sidebuttons_size=24
# show zoom controls in image viewer mode
zoom_control=yes
# maximum zoom in value
zoom_in_max=4
# minimum zoom out value
zoom_out_min=-1
# Colors and style
# accent color of the OSC and title bar
osc_color=#181926
# color of the title in borderless/fullscreen mode
window_title_color=#A5ADCB
# color of the window controls (close, minimize, maximize) in borderless/fullscreen mode
window_controls_color=#A5ADCB
# color of close window control on hover
windowcontrols_close_hover=#ED8796
# color of maximize window controls on hover
windowcontrols_max_hover=#EED49F
# color of minimize window controls on hover
windowcontrols_min_hover=#A6DA95
# color of the title (above seekbar)
title_color=#CAD3F5
# color of the cache information
cache_info_color=#CAD3F5
# color of the seekbar progress and handle
seekbarfg_color=#C6A0F6
# color of the remaining seekbar
seekbarbg_color=#B7BDF8
# color of the cache ranges on the seekbar
seekbar_cache_color=#A5ADCB
# match volume bar color with seekbar color (ignores side_buttons_color)
volumebar_match_seek_color=no
# color of the timestamps (below seekbar)
time_color=#CAD3F5
# color of the chapter title next to timestamp (below seekbar)
chapter_title_color=#A5ADCB
# color of the side buttons (audio, subtitles, playlist, etc.)
side_buttons_color=#A5ADCB
# color of the middle buttons (skip, jump, chapter, etc.)
middle_buttons_color=#A5ADCB
# color of the play/pause button
playpause_color=#A5ADCB
# color of the element when held down (pressed)
held_element_color=#999999
# color of a hovered button when hover_effect includes "color"
hover_effect_color=#C6A0F6
# color of the border for thumbnails (with thumbfast)
thumbnail_border_color=#181926
# color of the border outline for thumbnails
thumbnail_border_outline=#363A4F
# alpha of the OSC background box
fade_alpha=130
# blur strength for the OSC alpha fade. caution: high values can take a lot of CPU time to render
fade_blur_strength=100
# alpha of the window title bar (0 to disable)
window_fade_alpha=100
# blur strength for the window title bar. caution: high values can take a lot of CPU time to render
window_fade_blur_strength=100
# width of the thumbnail border (for thumbfast)
thumbnail_border=3
# rounded corner radius for thumbnail border (0 to disable)
thumbnail_border_radius=3
# Button hover effects
# active button hover effects: "glow", "size", "color"; can use multiple separated by commas
hover_effect=size,glow,color
# relative size of a hovered button if "size" effect is active
hover_button_size=115
# glow intensity when "glow" hover effect is active
button_glow_amount=5
# apply hover size effect to slider handle
hover_effect_for_sliders=yes
# Tooltips and hints
# enable tooltips for disabled buttons and elements
tooltips_for_disabled_elements=yes
# enable text hints for info, loop, ontop, and screenshot buttons
tooltip_hints=yes
# Progress bar settings
# size ratio of the seekbar handle (range: 0 ~ 1)
seek_handle_size=0.8
# show seek range overlay
seekrange=yes
# transparency of the seek range
seekrangealpha=150
# update chapter markers on the seekbar when duration changes
livemarkers=yes
# use keyframes when dragging the seekbar
seekbarkeyframes=no
# top chapter nibbles above seekbar
nibbles_top=yes
# bottom chapter nibbles below seekbar
nibbles_bottom=yes
# chapter nibble style. "triangle", "bar" or "single-bar"
nibbles_style=triangle
# automatically set keyframes for the seekbar based on video length
automatickeyframemode=yes
# videos longer than this (in seconds) will have keyframes on the seekbar
automatickeyframelimit=600
# always show a small progress line at the bottom of the screen
persistentprogress=no
# height of the persistent progress bar
persistentprogressheight=17
# show buffer status on web videos in the persistent progress line
persistentbuffer=no
# Miscellaneous settings
# only used at init to set visibility_mode(...)
visibility=auto
# visibility modes to cycle through, modes are separated by _
visibility_modes=never_auto_always
# minimum interval between OSC redraws (in seconds)
tick_delay=0.03
# use display FPS as the minimum redraw interval
tick_delay_follow_display_fps=no
# Elements Position
# Useful when adjusting font size or type
# title height position above seekbar
title_height=96
# title height position if a chapter title is below it
title_with_chapter_height=108
# chapter title height position above seekbar
chapter_title_height=91
# time codes height position
time_codes_height=35
# time codes height position with portrait window
time_codes_centered_height=57
# tooltip height position offset
tooltip_height_offset=2
# if tooltip contains many characters, it is moved to the left by offset
tooltip_left_offset=5
# portrait window width trigger to move some elements
portrait_window_trigger=1000
# hide volume bar trigger window width
hide_volume_bar_trigger=1150
# osc height offset if title above seekbar is disabled
notitle_osc_h_offset=25
# osc height offset if chapter title is disabled or doesn't exist
nochapter_osc_h_offset=10
# seek hover timecodes tooltip height position offset
seek_hover_tooltip_h_offset=0
# osc height without offsets
osc_height=132
## Mouse commands
## details: https://github.com/Samillion/ModernZ#mouse-commands-user-options
# title above seekbar mouse actions
title_mbtn_left_command=script-binding stats/display-page-5
title_mbtn_mid_command=show-text ${filename}
title_mbtn_right_command=show-text ${path}
# playlist button mouse actions
playlist_mbtn_left_command=script-binding select/select-playlist; script-message-to modernz osc-hide
playlist_mbtn_right_command=show-text ${playlist} 3000
# volume mouse actions
vol_ctrl_mbtn_left_command=no-osd cycle mute
vol_ctrl_mbtn_right_command=script-binding select/select-audio-device; script-message-to modernz osc-hide
vol_ctrl_wheel_down_command=no-osd add volume -5
vol_ctrl_wheel_up_command=no-osd add volume 5
# audio button mouse actions
audio_track_mbtn_left_command=script-binding select/select-aid; script-message-to modernz osc-hide
audio_track_mbtn_mid_command=cycle audio down
audio_track_mbtn_right_command=cycle audio
audio_track_wheel_down_command=cycle audio
audio_track_wheel_up_command=cycle audio down
# subtitle button mouse actions
sub_track_mbtn_left_command=script-binding select/select-sid; script-message-to modernz osc-hide
sub_track_mbtn_mid_command=cycle sub down
sub_track_mbtn_right_command=cycle sub
sub_track_wheel_down_command=cycle sub
sub_track_wheel_up_command=cycle sub down
# chapter skip buttons mouse actions
chapter_prev_mbtn_left_command=add chapter -1
chapter_prev_mbtn_mid_command=show-text ${chapter-list} 3000
chapter_prev_mbtn_right_command=script-binding select/select-chapter; script-message-to modernz osc-hide
chapter_next_mbtn_left_command=add chapter 1
chapter_next_mbtn_mid_command=show-text ${chapter-list} 3000
chapter_next_mbtn_right_command=script-binding select/select-chapter; script-message-to modernz osc-hide
# chapter title (below seekbar) mouse actions
chapter_title_mbtn_left_command=script-binding select/select-chapter; script-message-to modernz osc-hide
chapter_title_mbtn_right_command=show-text ${chapter-list} 3000
# playlist skip buttons mouse actions
playlist_prev_mbtn_left_command=playlist-prev
playlist_prev_mbtn_mid_command=show-text ${playlist} 3000
playlist_prev_mbtn_right_command=script-binding select/select-playlist; script-message-to modernz osc-hide
playlist_next_mbtn_left_command=playlist-next
playlist_next_mbtn_mid_command=show-text ${playlist} 3000
playlist_next_mbtn_right_command=script-binding select/select-playlist; script-message-to modernz osc-hide
# fullscreen button mouse actions
fullscreen_mbtn_left_command=cycle fullscreen
fullscreen_mbtn_right_command=cycle window-maximized
# info button mouse actions
info_mbtn_left_command=script-binding stats/display-page-1-toggle

View File

@@ -0,0 +1,35 @@
add_to_queue=ctrl+a
default_save_method=unwatched
download_current_video=ctrl+d
download_selected_video=ctrl+D
move_cursor_down=ctrl+j
move_cursor_up=ctrl+k
load_queue=ctrl+l
move_video=ctrl+m
play_next_in_queue=ctrl+n
open_video_in_browser=ctrl+o
open_channel_in_browser=ctrl+O
play_previous_in_queue=ctrl+p
print_current_video=ctrl+P
print_queue=ctrl+q
save_queue=ctrl+s
save_full_queue=ctrl+S
remove_from_queue=ctrl+x
play_selected_video=ctrl+ENTER
browser=zen-browser
clipboard_command=wl-paste
cursor_icon=➤
display_limit=10
download_directory=~/videos/YouTube
download_quality=1080p
downloader=curl
font_name=JetBrainsMono NF
font_size=12
marked_icon=⇅
menu_timeout=5
show_errors=yes
ytdlp_file_format=mp4
ytdlp_output_template=%(uploader)s/%(title)s.%(ext)s
use_history_db=yes
backend_host=http://localhost
backend_port=42069

View File

@@ -0,0 +1,35 @@
add_to_queue=ctrl+a
default_save_method=unwatched
download_current_video=ctrl+d
download_selected_video=ctrl+D
move_cursor_down=ctrl+j
move_cursor_up=ctrl+k
load_queue=ctrl+l
move_video=ctrl+m
play_next_in_queue=ctrl+n
open_video_in_browser=ctrl+o
open_channel_in_browser=ctrl+O
play_previous_in_queue=ctrl+p
print_current_video=ctrl+P
print_queue=ctrl+q
save_queue=ctrl+s
save_full_queue=ctrl+S
remove_from_queue=ctrl+x
play_selected_video=ctrl+ENTER
browser=zen-browser
clipboard_command=pbpaste
cursor_icon=➤
display_limit=10
download_directory=~/videos/YouTube
download_quality=1080p
downloader=curl
font_name=JetBrainsMono NF
font_size=12
marked_icon=⇅
menu_timeout=5
show_errors=yes
ytdlp_file_format=mp4
ytdlp_output_template=%(uploader)s/%(title)s.%(ext)s
use_history_db=yes
backend_host=http://localhost
backend_port=42069

View File

@@ -0,0 +1,19 @@
showwindowed=yes
showfullscreen=yes
scalewindowed=1
scalefullscreen=1
scaleforcedwindow=2
vidscale=yes
hidetimeout=1000
fadeduration=500
minmousemove=3
iamaprogrammer=yes
font='mpv-osd-symbols'
seekrangealpha=128
title='${media-title}'
showtitle=yes
visibility=auto
windowcontrols=auto
volumecontrol=yes
processvolume=yes
language=eng

View File

@@ -0,0 +1,34 @@
# enable automatic reload on timeout
# when paused-for-cache event fired, we will wait
# paused_for_cache_timer_timeout sedonds and then reload the video
paused_for_cache_timer_enabled=yes
# checking paused_for_cache property interval in seconds,
# can not be less than 0.05 (50 ms)
paused_for_cache_timer_interval=1
# time in seconds to wait until reload
paused_for_cache_timer_timeout=10
# enable automatic reload based on demuxer cache
# if demuxer-cache-time property didn't change in demuxer_cache_timer_timeout
# time interval, the video will be reloaded as soon as demuxer cache depleated
demuxer_cache_timer_enabled=yes
# checking demuxer-cache-time property interval in seconds,
# can not be less than 0.05 (50 ms)
demuxer_cache_timer_interval=2
# if demuxer cache didn't receive any data during demuxer_cache_timer_timeout
# we decide that it has no progress and will reload the stream when
# paused_for_cache event happens
demuxer_cache_timer_timeout=20
# when the end-of-file is reached, reload the stream to check
# if there is more content available.
reload_eof_enabled=no
# keybinding to reload stream from current time position
# you can disable keybinding by setting it to empty value
# reload_key_binding=
reload_key_binding=Ctrl+r

View File

@@ -0,0 +1 @@
plot_tonemapping_lut=yes

View File

@@ -0,0 +1,331 @@
###
### Main mpvacious configuration file.
### Save this file to ~/.config/mpv/script-opts/subs2srs.conf
###
##
## General settings
##
# Anki deck for new cards. Subdecks are supported.
deck_name=Minecraft
# Model names are listed in `Tools -> Manage note types` menu in Anki.
# If you don't have a model for Japanese, get it from
# https://tatsumoto.neocities.org/blog/setting-up-anki.html#import-an-example-mining-deck
model_name=Lapis
# Field names as they appear in the selected note type.
# If you set `audio_field` or `image_field` empty,
# the corresponding media file will not be created.
audio_field=SentenceAudio
image_field=Picture
sentence_field=Expression
secondary_field=SelectionText
# The tag(s) added to new notes. Spaces separate multiple tags.
# Leave nothing after `=` to disable tagging completely.
# The following substitutions are supported:
# %n - the name of the video
# %t - timestamp
# %d - episode number (if none, returns nothing)
# %e - SUBS2SRS_TAGS environment variable (if you have it set)
# note_tag=subs2srs
note_tag=%n-E%d %t
#note_tag=
# Size and name of the font used in the menu
menu_font_size=24
menu_font_name=Noto Serif CJK JP
# AnkiConnect server address
# The default address for a server on the same device is http://127.0.0.1:8765.
# If Anki is running and AnkiConnect is installed, opening this URL should
# open a page showing the current version of AnkiConnect.
# Change this if you have changed webBindAddress in AnkiConnect's settings.
ankiconnect_url=127.0.0.1:8765
##
## Toggleables.
## Possible values: `yes` or `no`.
# Use FFmpeg encoder instead of mpv encoder
# If mpvacious encounters problems creating audio and images for Anki cards,
# setting this to `yes` should fix them.
#
# You need to install ffmpeg and add it to the PATH first.
# https://wiki.archlinux.org/title/FFmpeg
# https://www.ffmpeg.org/download.html
#
# FFmpeg encoder is unable to create audio and images from remote content (like YouTube videos).
use_ffmpeg=yes
# Automatically create the deck for new cards (see deck_name option)
create_deck=no
# Allow making notes with the same sentence field.
allow_duplicates=no
# When mpv starts, automatically copy subs to the clipboard as they appear on screen.
# This option can be also toggled in the addon's OSD menu.
autoclip=no
# Possible options:
# "disabled" - autocopy is disabled
# "clipboard" - copy to the system clipboard (e.g. uses xclip)
# "goldendict" - send the subtitle string to goldendict (goldendict-ng).
# "custom_command" - run any custom command specified in `autoclip_custom_args`.
autoclip_method=custom_command
# Command to run when autoclip is enabled and set to "custom_command".
# If empty, nothing will be done.
# If set, calls the external program.
# The following substitutions are supported:
# %MPV_PRIMARY% - primary subtitle line
# %MPV_SECONDARY% - secondary subtitle line
autoclip_custom_args=wl-copy %MPV_PRIMARY%
# Remove all spaces from the primary subtitle text.
# Set this to "yes" for languages without spaces like Japanese.
# However, if mpvacious detects any latin characters in the string, spaces will not be removed.
nuke_spaces=yes
# if set to `yes`, the volume of the outputted audio file
# depends on the volume of the player at the time of export
tie_volumes=no
# This is used when selecting cards in Anki to update, it wont let you
# overwrite more than the value specified below
# Just remember that having multiple cards with the same sentence
# and the same audio recording is usually bad practice.
card_overwrite_safeguard = 1
# Remove text in parentheses and leading/trailing spaces or
# newlines that may interfere with Rikaitan before copying
# subtitles to the clipboard
clipboard_trim_enabled=yes
# Add media to fields before or after existing data
append_media=yes
# Remove text in brackets before substituting %n into tag
tag_nuke_brackets=yes
# Remove text in parentheses before substituting %n into tag
tag_nuke_parentheses=no
# Remove the episode number before substituting %n into tag
tag_del_episode_num=yes
# Remove everything after the episode number before substituting %n into tag
# Does nothing if the previous option tag_del_episode_num is disabled.
tag_del_after_episode_num=yes
# Convert filename to lowercase for tagging.
tag_filename_lowercase=no
# Lets you disable anki browser manipulation by mpvacious.
disable_gui_browse=no
# Play audio clip automatically in background
# after note creation (or note update) to ensure that the audio is correctly cut.
preview_audio=yes
# When selecting subtitle lines, print them on the screen.
show_selected_text=yes
# For convenience, read config file from disk before a card is made.
# Useful if you change your config often since you won't have to restart mpv every time,
# but reading from disk takes some time.
reload_config_before_card_creation=yes
##
## Image settings
##
# Snapshot format.
# Do not switch to `jpg` unless your computer doesn't support `webp` or `avif`.
snapshot_format=avif
# snapshot_format=webp
#snapshot_format=jpg
# Quality of produced image files. 0 = lowest, 100=highest.
snapshot_quality=88
# Image dimensions
# If either (but not both) of the width or height parameters is -2,
# the value will be calculated preserving the aspect-ratio.
snapshot_width=-2
snapshot_height=400
# Screenshot (yes, no)
# Usually not required.
# When making Anki cards, create a screenshot (by calling 'screenshot-to-file') instead of a snapshot.
# If set to yes, image dimensions and quality cannot be controlled due to mpv limitations.
# 'snapshot_format' is still respected.
# When using this, a custom sync server is recommended, e.g. https://github.com/ankicommunity/anki-sync-server
screenshot=yes
# The exact image template used when exporting to Anki's image field.
# Adding data-editor-shrink="true" makes the image smaller by default within the Anki viewer
# on versions 2.1.53+ (equivalent of double-clicking on the image).
# You likely would not want to change this unless you know what you are doing.
image_template=<img alt="snapshot" src="%s">
#image_template=<img alt="snapshot" data-editor-shrink="true" src="%s">
# Similar to image_template but with audio.
# Normally, the user doesn't need to change this setting,
# but it may be needed for audio files to be playable on AnkiWeb.
audio_template=[sound:%s]
#audio_template=<audio controls="" src="%s"></audio>
##
## Animated snapshots
## Animated snapshots will capture the video from the start to the end times selected when using mpvacious.
##
# If enabled, generates animated snapshots (something like GIFs) instead of static snapshots.
animated_snapshot_enabled=yes
# Animated snapshot format. Like "snapshot_format" but for animated images. Can be either avif or webp.
animated_snapshot_format=avif
# animated_snapshot_format=webp
# Number of frame per seconds, a value between 0 and 30 (30 included)
# Higher values will increase both quality and file size, lower values will do the opposite
animated_snapshot_fps=24
# Animated snapshot dimensions
# If either (but not both) of the width or height parameters is -2,
# the value will be calculated preserving the aspect-ratio.
animated_snapshot_width=-2
animated_snapshot_height=400
# Quality of the produced animation, 0 = lowest, 100 = highest
animated_snapshot_quality=69
##
## Audio settings
##
# Audio format.
# Opus is the recommended format.
audio_format=opus
# audio_format=mp3
# Container for opus files.
# It may be required to use a different container for Opus.
# This is the case on certain computers or devices
# which are running proprietary operating systems, e.g. AnkiMobile. Using them is discouraged.
# ・ Ogg/Opus play everywhere except AnkiWeb in Safari and AnkiMobile.
# ・ M4A (iOS 17.2 and probably even earlier) and WEBM (since iOS 17.4) play everywhere.
# ・ Opus in CAF can be used with older iOS. CAF plays only on Anki Desktop, Safari and AnkiMobile.
# ・ (iOS Lockdown Mode disables Opus support completely,
# though you may try to add an exception for AnkiMobile.)
# opus_container=ogg
#opus_container=opus
opus_container=m4a
# opus_container=webm
#opus_container=caf
# Sane values are 16k-32k for opus, 64k-128k for mp3.
audio_bitrate=32k
# Set a pad to the dialog timings. 0.5 = half a second.
# Pads are never applied to manually set timings.
audio_padding=0.0
#audio_padding=0.5
##
## Forvo support (Rikaitan users only)
##
# yes - fetch audio from Forvo if Rikaitan couldn't find the audio (default)
# always - always fetch audio from Forvo and replace the audio added by Rikaitan
# no - never use Forvo
use_forvo=yes
# Vocab field should be equal to {expression} field in Rikaitan
vocab_field=Expression
# Vocab Audio field should be equal to {audio} field in Rikaitan
vocab_audio_field=ExpressionAudio
##
## Misc info
## Various context information that can be written on your cards in a specified field.
##
# yes to enable or no to disable.
miscinfo_enable=yes
# Field name
miscinfo_field=ExtraInfo
# Format string used to fill the misc info field.
# It supports the same substitutions as `note_tag`. HTML is supported.
miscinfo_format=%n EP%d (%t)
#miscinfo_format=From <b>mpvacious</b> %n at %t.
##
## Secondary subtitles
## Mpvacious can try automatically loading secondary subtitles that will appear at the top.
## For example, you may want to load English subs alongside Japanese subs.
##
## Secondary subtitles should be present in the container.
## But if you manually set secondary sid from the command line, mpvacious won't change it.
##
# Load secondary subtitle track automatically when a file is opened.
secondary_sub_auto_load=yes
# Language of secondary subs. This is your native language or a language you know well.
# If you leave this parameter empty, secondary subs will NOT be automatically loaded.
secondary_sub_lang=eng,en
#secondary_sub_lang=
# Hover area.
# Proportion of the top part of the mpv window where the secondary subtitles are visible when hovered over.
# Possible values: from 0.0 to 1.0
secondary_sub_area=0.15
# Visibility state
# Can be set to: 'auto', 'never', 'always'.
# If set to 'never' or 'always', secondary_sub_area has no effect.
# If set to 'auto', visibility behaves according to the value of secondary_sub_area.
# Default binding to cycle this value: Ctrl+v.
secondary_sub_visibility=auto
# Perform two-pass loudness normalization.
# Parameter explanation can be found e.g. at:
# https://auphonic.com/blog/2013/01/07/loudness-targets-mobile-audio-podcasts-radio-tv/
# https://auphonic.com/blog/2019/08/19/dynamic-range-processing/
# MAKE SURE TO REMOVE loudnorm FROM CUSTOM ARGS BEFORE ENABLING.
loudnorm=no
loudnorm_target=-16
loudnorm_range=11
loudnorm_peak=-1.5
##
## Custom audio encoding arguments
## These arguments are added to the command line.
## `mpv` and `ffmpeg` accept slightly different parameters.
## Feel free to experiment for yourself, but be careful or media creation might stop working.
##
# loudnorm IN CUSTOM ARGS IS LEFT FOR BACKWARD COMPATIBILITY.
# MAKE SURE TO REMOVE ALL MENTIONS OF loudnorm FROM CUSTOM ARGS
# (E.G. SET TO EMPTY STRINGS) BEFORE ENABLING TWO-PASS loudnorm.
# ENABLING loudnorm BOTH THROUGH THE SWITCH AND THROUGH CUSTOM ARGS
# CAN LEAD TO UNPREDICTABLE RESULTS.
# Ffmpeg
ffmpeg_audio_args=-af loudnorm=I=-16:TP=-1.5:LRA=11:dual_mono=true
#ffmpeg_audio_args=
#ffmpeg_audio_args=-af silenceremove=1:0:-50dB
# mpv
# mpv accepts each filter as a separate argument, e.g. --af-append=1 --af-append=2
mpv_audio_args=--af-append=loudnorm=I=-16:TP=-1.5:LRA=11:dual_mono=true
#mpv_audio_args=
#mpv_audio_args=--af-append=silenceremove=1:0:-50dB

View File

@@ -0,0 +1,30 @@
# Socket path (leave empty for auto)
socket=
# Thumbnail path (leave empty for auto)
thumbnail=
# Maximum thumbnail size in pixels (scaled down to fit)
# Values are scaled when hidpi is enabled
max_height=400
max_width=400
# Overlay id
overlay_id=42
# Spawn thumbnailer on file load for faster initial thumbnails
spawn_first=yes
# Enable on network playback
network=yes
# Enable on audio playback
audio=no
# Enable hardware decoding
hwdec=yes
# Windows only: use native Windows API to write to pipe (requires LuaJIT)
direct_io=no
mpv_path=mpv

View File

@@ -0,0 +1,91 @@
# KEY BINDINGS
append_binding=ctrl+SPACE
# invoke or dismiss the quality menu
toggle_menu_binding=ctrl+u
# move the menu cursor up
up_binding=ctrl+k
# move the menu cursor down
down_binding=ctrl+j
# select menu entry
select_binding=ctrl+ENTER
# auto fetch recommended videos when opening a url
fetch_on_start=no
# auto load and add the "upnext" video to the playlist
auto_add=no
# formatting / cursors
cursor_selected=●
cursor_unselected=○
cursor_appended=▷
cursor_appended_selected=▶
# font size scales by window, if false requires larger font and padding sizes
scale_playlist_by_window=yes
# 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={\\fnJetBrainsMono Nerd Font\\fs12}
# paddings for top left corner
text_padding_x=5
text_padding_y=5
# Screen dim when menu is open 0.0 - 1.0 (0 is no dim, 1 is black)
curtain_opacity=0.7
# how many seconds until the quality menu times out
menu_timeout=10
# base url for loading new urls, %s will be replaced with video id
youtube_url=https://www.youtube.com/watch?v=%s
# Fallback Invidious instance. Used if "upnext" could not be retrieved from the normal youtube website
# See https://api.invidious.io/ for alternatives
invidious_instance=https://inv.tux.pizza
# Keep the width of the window the same when the next video is played
restore_window_width=no
# On Windows wget.exe may not be able to check SSL certificates for HTTPS, so you can disable it here
check_certificate=yes
# Use a cookies file
# Same as youtube-dl --cookies or wget --load-cookies
# If you don't set this, the script may create a cookie file for you
# For example "C:\\Users\\Username\\cookies.txt"
# Or "C:/Users/Username/cookies.txt"
#cookies=cookies.txt
# When a video is selected from the menu, the new video can be appended to the playlist
# or the playlist can be cleared and replaced with only the selected video.
# If yes, the video will be appended to the playlist. If no, the playlist will be cleared.
keep_playlist_on_select=yes
# What should happen if a video recommendation in uosc menu is clicked? Options are:
# submenu --> show a submenu with play/upnext/append option
# append --> append the video to the playlist
# insert --> play the video after the current video
# play --> append the video to the playlist and play it
# replace --> play the video and clear the playlist
uosc_entry_action=submenu
# Should the uosc menu stay open after clicking a video recommendation?
uosc_keep_menu_open=no
# Don't play/append videos that are shorter than this time. Format is "HH:MM:SS" or "MM:SS"
#skip_shorter_than=00:30
# Don't play/append videos that are longer than this time. Format is "HH:MM:SS" or "MM:SS"
#skip_longer_than=07:00
# Also don't show the videos in the menu that are too short or too long
#hide_skipped_videos=yes

View File

@@ -0,0 +1 @@
temp=/tmp/ytdl-preload

View File

@@ -0,0 +1 @@
../../submodules/mpv-anilist-updater/anilistUpdater/anilistUpdater.py

View File

@@ -0,0 +1 @@
../../submodules/mpv-anilist-updater/anilistUpdater/main.lua

View File

@@ -0,0 +1 @@
../submodules/animecards/animecards

View File

@@ -0,0 +1 @@
../submodules/autosubsync-mpv

View File

@@ -0,0 +1 @@
../submodules/immersion-tracker

View File

@@ -0,0 +1,388 @@
// Go to https://jimaku.cc/login and create a new account.
// Then go to https://jimaku.cc/account and click the `Generate` button to create a new API key
// Click the `Copy` button and paste it below
var API_KEY = "";
// Configuration options
var CONFIG = {
// Filter the response to only have the specified episode
prompt_episode: true,
// Subtitle suffix (e.g., ".JA" for Japanese subtitles)
subtitle_suffix: ".JA",
// Preferred subtitle format (order matters, first is most preferred)
preferred_formats: ["ass", "srt", "vtt"],
// Automatically load the subtitle after download
auto_load: true,
// Default subtitle delay in seconds (can be positive or negative)
default_delay: 0,
// Default subtitle font size
default_font_size: 16,
// Automatically rename the subtitle file after download
auto_rename: true,
// Automatically run autosubsync-mpv after downloading the subtitle
run_auto_subsync: true
};
// Keybindings
// var MANUAL_SEARCH_KEY = "g";
var FILENAME_AUTO_SEARCH_KEY = "ctrl+J";
var PARENT_FOLDER_AUTO_SEARCH_KEY = "n";
function api(url, extraArgs) {
var baseArgs = [
"curl",
"-s",
"--url",
url,
"--header",
"Authorization: " + API_KEY
];
var args = Array.prototype.concat.apply(baseArgs, extraArgs);
var res = mp.command_native({
name: "subprocess",
playback_only: false,
capture_stdout: true,
capture_stderr: true,
args: args
});
if (res.stdout) return JSON.parse(res.stdout);
}
function downloadSub(sub) {
return api(sub.url, ["--output", sub.name]);
}
function showMessage(message, persist) {
var ass_start = mp.get_property_osd("osd-ass-cc/0");
var ass_stop = mp.get_property_osd("osd-ass-cc/1");
mp.osd_message(
ass_start + "{\\fs16}" + message + ass_stop,
persist ? 999 : 2
);
}
// The timeout is neccessary due to a weird bug in mpv
function inputGet(args) {
mp.input.terminate();
setTimeout(function () {
mp.input.get(args);
}, 1);
}
// The timeout is neccessary due to a weird bug in mpv
function inputSelect(args) {
mp.input.terminate();
setTimeout(function () {
mp.input.select(args);
}, 1);
}
// Taken from mpv-subversive
// https://github.com/nairyosangha/mpv-subversive/blob/master/backend/backend.lua#L146
function sanitize(text) {
var subPatterns = [
/\.[a-zA-Z]+$/, // extension
/\./g,
/-/g,
/_/g,
/\[[^\]]+\]/g, // [] bracket
/\([^\)]+\)/g, // () bracket
/720[pP]/g,
/480[pP]/g,
/1080[pP]/g,
/[xX]26[45]/g,
/[bB]lu[-]?[rR]ay/g,
/^[\s]*/,
/[\s]*$/,
/1920x1080/g,
/1920X1080/g,
/Hi10P/g,
/FLAC/g,
/AAC/g
];
var result = text;
subPatterns.forEach(function (subPattern) {
var newResult = result.replace(subPattern, " ");
if (newResult.length > 0) {
result = newResult;
}
});
return result;
}
// Adapted from mpv-subversive
// https://github.com/nairyosangha/mpv-subversive/blob/master/backend/backend.lua#L164
function extractTitle(text) {
var matchers = [
{ regex: /^([\w\s\d]+)[Ss]\d+[Ee]?\d+/, group: 1 },
{ regex: /^([\w\s\d]+)-[\s]*\d+[\s]*[^\w]*$/, group: 1 },
{ regex: /^([\w\s\d]+)[Ee]?[Pp]?[\s]+\d+$/, group: 1 },
{ regex: /^([\w\s\d]+)[\s]\d+.*$/, group: 1 },
{ regex: /^\d+[\s]*(.+)$/, group: 1 }
];
for (var i = 0; i < matchers.length; i++) {
var matcher = matchers[i];
var match = text.match(matcher.regex);
if (match) {
return match[matcher.group].trim();
}
}
return text;
}
function getNames(results) {
return results.map(function (item) {
return item.name;
});
}
function runAutoSubSyncMPV() {
try {
mp.command_native(["script-binding", "autosubsync-menu"]);
} catch (e) {
showMessage("autosubsync-mpv not installed");
return;
}
}
function selectSub(selectedSub) {
showMessage("Downloading: " + selectedSub.name);
try {
downloadSub(selectedSub);
// Get current video filename without extension
var videoPath = mp.get_property("path");
if (!videoPath) {
throw new Error("No video file is currently playing");
}
var videoName = videoPath.substring(0, videoPath.lastIndexOf("."));
// Get subtitle extension
var subExt = selectedSub.name.substring(selectedSub.name.lastIndexOf("."));
var newSubName = selectedSub.name;
if (CONFIG.auto_rename) {
// Create new subtitle filename
newSubName = videoName + CONFIG.subtitle_suffix + subExt;
// Rename the downloaded subtitle file
var renameResult = mp.command_native({
name: "subprocess",
playback_only: false,
args: ["mv", selectedSub.name, newSubName]
});
if (renameResult.error) {
throw new Error(
"Failed to rename subtitle file: " + renameResult.error
);
}
showMessage(newSubName + " downloaded and renamed");
} else {
showMessage(newSubName + " downloaded");
}
if (CONFIG.auto_load) {
mp.commandv("sub_add", newSubName);
showMessage(newSubName + " added");
// Apply subtitle settings if configured
if (CONFIG.default_delay !== 0) {
mp.commandv("sub_delay", CONFIG.default_delay);
}
if (CONFIG.default_font_size !== 16) {
mp.commandv("sub_font_size", CONFIG.default_font_size);
}
}
if (CONFIG.run_auto_subsync) {
runAutoSubSyncMPV();
}
mp.set_property("pause", "no");
} catch (error) {
showMessage("Error: " + error.message, true);
mp.set_property("pause", "no");
}
}
function sortByPreferredFormat(files) {
return files.sort(function (a, b) {
var extA = a.name.substring(a.name.lastIndexOf(".") + 1).toLowerCase();
var extB = b.name.substring(b.name.lastIndexOf(".") + 1).toLowerCase();
var indexA = CONFIG.preferred_formats.indexOf(extA);
var indexB = CONFIG.preferred_formats.indexOf(extB);
if (indexA === -1) return 1;
if (indexB === -1) return -1;
return indexA - indexB;
});
}
function selectEpisode(anime, episode) {
mp.input.terminate();
var episodeResults;
if (episode) {
showMessage("Fetching subs for: " + anime.name + " episode " + episode);
episodeResults = api(
"https://jimaku.cc/api/entries/" + anime.id + "/files?episode=" + episode
);
} else {
showMessage("Fetching all subs for: " + anime.name);
episodeResults = api(
"https://jimaku.cc/api/entries/" + anime.id + "/files"
);
}
if (episodeResults.error) {
showMessage("Error: " + animeResults.error);
return;
}
if (episodeResults.length === 0) {
showMessage("No results found");
return;
}
// Sort results by preferred format
episodeResults = sortByPreferredFormat(episodeResults);
if (episodeResults.length === 1) {
var selectedEpisode = episodeResults[0];
selectSub(selectedEpisode);
return;
}
var items = getNames(episodeResults);
inputSelect({
prompt: "Select episode: ",
items: items,
submit: function (id) {
var selectedEpisode = episodeResults[id - 1];
selectSub(selectedEpisode);
}
});
}
function onAnimeSelected(anime) {
if (CONFIG.prompt_episode) {
inputGet({
prompt: "Episode (leave blank for all): ",
submit: function (episode) {
selectEpisode(anime, episode);
}
});
} else {
selectEpisode(anime);
}
}
function search(searchTerm, isAuto) {
mp.input.terminate();
showMessage('Searching for: "' + searchTerm + '"');
var animeResults = api(
encodeURI(
"https://jimaku.cc/api/entries/search?anime=true&query=" + searchTerm
)
);
if (animeResults.error) {
showMessage("Error: " + animeResults.error);
return;
}
if (animeResults.length === 0) {
showMessage("No results found");
if (isAuto) {
manualSearch(searchTerm);
}
return;
}
if (animeResults.length === 1) {
var selectedAnime = animeResults[0];
onAnimeSelected(selectedAnime);
return;
}
var items = getNames(animeResults);
inputSelect({
prompt: "Select anime: ",
items: items,
submit: function (id) {
var selectedAnime = animeResults[id - 1];
showMessage(selectedAnime.name, true);
onAnimeSelected(selectedAnime);
}
});
}
function manualSearch(defaultText) {
inputGet({
prompt: "Search term: ",
submit: search,
default_text: defaultText
});
mp.set_property("pause", "yes");
showMessage("Manual Jimaku Search", true);
}
function autoSearch() {
var filename = mp.get_property("filename");
var sanitizedFilename = sanitize(filename);
var currentAnime = extractTitle(sanitizedFilename);
mp.set_property("pause", "yes");
search(currentAnime, true);
}
function autoSearchParentFolder() {
var path = mp.get_property("stream-open-filename");
var pathSplit = path.split(path.indexOf("/") >= 0 ? "/" : "\\");
var filename =
pathSplit.length === 1 ? pathSplit[0] : pathSplit[pathSplit.length - 2];
var sanitizedFilename = sanitize(filename);
var currentAnime = extractTitle(sanitizedFilename);
mp.set_property("pause", "yes");
search(currentAnime, true);
}
// mp.add_key_binding(MANUAL_SEARCH_KEY, "jimaku-manual-search", manualSearch);
mp.add_key_binding(
FILENAME_AUTO_SEARCH_KEY,
"jimaku-filename-auto-search",
autoSearch
);
mp.add_key_binding(
PARENT_FOLDER_AUTO_SEARCH_KEY,
"jimaku-parent-folder-auto-search",
autoSearchParentFolder
);

View File

@@ -0,0 +1 @@
../submodules/ModernZ/modernz.lua

View File

@@ -0,0 +1 @@
../submodules/mpv-youtube-queue/mpv-youtube-queue.lua

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,416 @@
-- reload.lua
--
-- When an online video is stuck buffering or got very slow CDN
-- source, restarting often helps. This script provides automatic
-- reloading of videos that doesn't have buffering progress for some
-- time while keeping the current time position. It also adds `Ctrl+r`
-- keybinding to reload video manually.
--
-- SETTINGS
--
-- To override default setting put the `lua-settings/reload.conf` file in
-- mpv user folder, on linux it is `~/.config/mpv`. NOTE: config file
-- name should match the name of the script.
--
-- Default `reload.conf` settings:
--
-- ```
-- # enable automatic reload on timeout
-- # when paused-for-cache event fired, we will wait
-- # paused_for_cache_timer_timeout sedonds and then reload the video
-- paused_for_cache_timer_enabled=yes
--
-- # checking paused_for_cache property interval in seconds,
-- # can not be less than 0.05 (50 ms)
-- paused_for_cache_timer_interval=1
--
-- # time in seconds to wait until reload
-- paused_for_cache_timer_timeout=10
--
-- # enable automatic reload based on demuxer cache
-- # if demuxer-cache-time property didn't change in demuxer_cache_timer_timeout
-- # time interval, the video will be reloaded as soon as demuxer cache depleated
-- demuxer_cache_timer_enabled=yes
--
-- # checking demuxer-cache-time property interval in seconds,
-- # can not be less than 0.05 (50 ms)
-- demuxer_cache_timer_interval=2
--
-- # if demuxer cache didn't receive any data during demuxer_cache_timer_timeout
-- # we decide that it has no progress and will reload the stream when
-- # paused_for_cache event happens
-- demuxer_cache_timer_timeout=20
--
-- # when the end-of-file is reached, reload the stream to check
-- # if there is more content available.
-- reload_eof_enabled=no
--
-- # keybinding to reload stream from current time position
-- # you can disable keybinding by setting it to empty value
-- # reload_key_binding=
-- reload_key_binding=Ctrl+r
-- ```
--
-- DEBUGGING
--
-- Debug messages will be printed to stdout with mpv command line option
-- `--msg-level='reload=debug'`. You may also need to add the `--no-msg-color`
-- option to make the debug logs visible if you are using a dark colorscheme
-- in terminal.
local msg = require 'mp.msg'
local options = require 'mp.options'
local utils = require 'mp.utils'
local settings = {
paused_for_cache_timer_enabled = true,
paused_for_cache_timer_interval = 1,
paused_for_cache_timer_timeout = 10,
demuxer_cache_timer_enabled = true,
demuxer_cache_timer_interval = 2,
demuxer_cache_timer_timeout = 20,
reload_eof_enabled = false,
reload_key_binding = "Ctrl+r"
}
-- global state stores properties between reloads
local property_path = nil
local property_time_pos = 0
local property_keep_open = nil
-- FSM managing the demuxer cache.
--
-- States:
--
-- * fetch - fetching new data
-- * stale - unable to fetch new data for time < 'demuxer_cache_timer_timeout'
-- * stuck - unable to fetch new data for time >= 'demuxer_cache_timer_timeout'
--
-- State transitions:
--
-- +---------------------------+
-- v |
-- +-------+ +-------+ +-------+
-- + fetch +<--->+ stale +---->+ stuck |
-- +-------+ +-------+ +-------+
-- | ^ | ^ | ^
-- +---+ +---+ +---+
local demuxer_cache = {
timer = nil,
state = { name = 'uninitialized', demuxer_cache_time = 0, in_state_time = 0 },
events = {
continue_fetch = { name = 'continue_fetch', from = 'fetch', to = 'fetch' },
continue_stale = { name = 'continue_stale', from = 'stale', to = 'stale' },
continue_stuck = { name = 'continue_stuck', from = 'stuck', to = 'stuck' },
fetch_to_stale = { name = 'fetch_to_stale', from = 'fetch', to = 'stale' },
stale_to_fetch = { name = 'stale_to_fetch', from = 'stale', to = 'fetch' },
stale_to_stuck = { name = 'stale_to_stuck', from = 'stale', to = 'stuck' },
stuck_to_fetch = { name = 'stuck_to_fetch', from = 'stuck', to = 'fetch' }
}
}
-- Always start with 'fetch' state
function demuxer_cache.reset_state()
demuxer_cache.state = {
name = demuxer_cache.events.continue_fetch.to,
demuxer_cache_time = 0,
in_state_time = 0
}
end
-- Has 'demuxer_cache_time' changed
function demuxer_cache.has_progress_since(t)
return demuxer_cache.state.demuxer_cache_time ~= t
end
function demuxer_cache.is_state_fetch()
return demuxer_cache.state.name == demuxer_cache.events.continue_fetch.to
end
function demuxer_cache.is_state_stale()
return demuxer_cache.state.name == demuxer_cache.events.continue_stale.to
end
function demuxer_cache.is_state_stuck()
return demuxer_cache.state.name == demuxer_cache.events.continue_stuck.to
end
function demuxer_cache.transition(event)
if demuxer_cache.state.name == event.from then
-- state setup
demuxer_cache.state.demuxer_cache_time = event.demuxer_cache_time
if event.name == 'continue_fetch' then
demuxer_cache.state.in_state_time = demuxer_cache.state
.in_state_time +
event.interval
elseif event.name == 'continue_stale' then
demuxer_cache.state.in_state_time = demuxer_cache.state
.in_state_time +
event.interval
elseif event.name == 'continue_stuck' then
demuxer_cache.state.in_state_time = demuxer_cache.state
.in_state_time +
event.interval
elseif event.name == 'fetch_to_stale' then
demuxer_cache.state.in_state_time = 0
elseif event.name == 'stale_to_fetch' then
demuxer_cache.state.in_state_time = 0
elseif event.name == 'stale_to_stuck' then
demuxer_cache.state.in_state_time = 0
elseif event.name == 'stuck_to_fetch' then
demuxer_cache.state.in_state_time = 0
end
-- state transition
demuxer_cache.state.name = event.to
msg.debug('demuxer_cache.transition', event.name,
utils.to_string(demuxer_cache.state))
else
msg.error('demuxer_cache.transition', 'illegal transition', event.name,
'from state', demuxer_cache.state.name)
end
end
function demuxer_cache.initialize(demuxer_cache_timer_interval)
demuxer_cache.reset_state()
demuxer_cache.timer = mp.add_periodic_timer(demuxer_cache_timer_interval,
function()
demuxer_cache.demuxer_cache_timer_tick(
mp.get_property_native('demuxer-cache-time'),
demuxer_cache_timer_interval)
end)
end
-- If there is no progress of demuxer_cache_time in
-- settings.demuxer_cache_timer_timeout time interval switch state to
-- 'stuck' and switch back to 'fetch' as soon as any progress is made
function demuxer_cache.demuxer_cache_timer_tick(demuxer_cache_time,
demuxer_cache_timer_interval)
local event = nil
local cache_has_progress = demuxer_cache.has_progress_since(
demuxer_cache_time)
-- I miss pattern matching so much
if demuxer_cache.is_state_fetch() then
if cache_has_progress then
event = demuxer_cache.events.continue_fetch
else
event = demuxer_cache.events.fetch_to_stale
end
elseif demuxer_cache.is_state_stale() then
if cache_has_progress then
event = demuxer_cache.events.stale_to_fetch
elseif demuxer_cache.state.in_state_time <
settings.demuxer_cache_timer_timeout then
event = demuxer_cache.events.continue_stale
else
event = demuxer_cache.events.stale_to_stuck
end
elseif demuxer_cache.is_state_stuck() then
if cache_has_progress then
event = demuxer_cache.events.stuck_to_fetch
else
event = demuxer_cache.events.continue_stuck
end
end
event.demuxer_cache_time = demuxer_cache_time
event.interval = demuxer_cache_timer_interval
demuxer_cache.transition(event)
end
local paused_for_cache = { timer = nil, time = 0 }
function paused_for_cache.reset_timer()
msg.debug('paused_for_cache.reset_timer', paused_for_cache.time)
if paused_for_cache.timer then
paused_for_cache.timer:kill()
paused_for_cache.timer = nil
paused_for_cache.time = 0
end
end
function paused_for_cache.start_timer(interval_seconds, timeout_seconds)
msg.debug('paused_for_cache.start_timer', paused_for_cache.time)
if not paused_for_cache.timer then
paused_for_cache.timer = mp.add_periodic_timer(interval_seconds,
function()
paused_for_cache.time = paused_for_cache.time + interval_seconds
if paused_for_cache.time >= timeout_seconds then
paused_for_cache.reset_timer()
reload_resume()
end
msg.debug('paused_for_cache', 'tick', paused_for_cache.time)
end)
end
end
function paused_for_cache.handler(property, is_paused)
if is_paused then
if demuxer_cache.is_state_stuck() then
msg.info("demuxer cache has no progress")
-- reset demuxer state to avoid immediate reload if
-- paused_for_cache event triggered right after reload
demuxer_cache.reset_state()
reload_resume()
end
paused_for_cache.start_timer(settings.paused_for_cache_timer_interval,
settings.paused_for_cache_timer_timeout)
else
paused_for_cache.reset_timer()
end
end
function read_settings()
options.read_options(settings, mp.get_script_name())
msg.debug(utils.to_string(settings))
end
function reload(path, time_pos)
msg.debug("reload", path, time_pos)
if time_pos == nil then
mp.commandv("loadfile", path, "replace")
else
local success = mp.commandv("loadfile", path, "replace", -1,
"start=+" .. time_pos)
-- fallback to old syntax of loadfile for compatibility
if success == nil then
msg.warn(
"old loadfile syntax detected. falling back to using old syntax. update mpv to remove this warning")
mp.commandv("loadfile", path, "replace", "start=+" .. time_pos)
end
end
end
function reload_resume()
local path = mp.get_property("path", property_path)
local time_pos = mp.get_property("time-pos")
local reload_duration = mp.get_property_native("duration")
local playlist_count = mp.get_property_number("playlist/count")
local playlist_pos = mp.get_property_number("playlist-pos")
local playlist = {}
for i = 0, playlist_count - 1 do
playlist[i] = mp.get_property("playlist/" .. i .. "/filename")
end
-- 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
msg.info("reloading video from", time_pos, "second")
reload(path, time_pos)
-- VODs get stuck when reload is called without a time_pos
-- this is most noticeable in youtube videos whenever download gets stuck in the first frames
-- video would stay paused without being actually paused
-- issue surfaced in mpv 0.33, afaik
elseif reload_duration and reload_duration == 0 then
msg.info("reloading video from", time_pos, "second")
reload(path, time_pos)
else
msg.info("reloading stream")
reload(path, nil)
end
msg.info("file", playlist_pos + 1, "of", playlist_count, "in playlist")
for i = 0, playlist_pos - 1 do
mp.commandv("loadfile", playlist[i], "append")
end
mp.commandv("playlist-move", 0, playlist_pos + 1)
for i = playlist_pos + 1, playlist_count - 1 do
mp.commandv("loadfile", playlist[i], "append")
end
end
function reload_eof(property, eof_reached)
msg.debug("reload_eof", property, eof_reached)
local time_pos = mp.get_property_number("time-pos")
local duration = mp.get_property_number("duration")
if eof_reached and round(time_pos) == round(duration) then
msg.debug("property_time_pos", property_time_pos, "time_pos", time_pos)
-- Check that playback time_pos made progress after the last reload. When
-- eof is reached we try to reload the video, in case there is more content
-- available. If time_pos stayed the same after reload, it means that the
-- video length stayed the same, and we can end the playback.
if round(property_time_pos) == round(time_pos) then
msg.info("eof reached, playback ended")
mp.set_property("keep-open", property_keep_open)
else
msg.info("eof reached, checking if more content available")
reload_resume()
mp.set_property_bool("pause", false)
property_time_pos = time_pos
end
end
end
function on_file_loaded(event)
local debug_info = {
event = event,
time_pos = mp.get_property("time-pos"),
stream_pos = mp.get_property("stream-pos"),
stream_end = mp.get_property("stream-end"),
duration = mp.get_property("duration"),
seekable = mp.get_property("seekable"),
pause = mp.get_property("pause"),
paused_for_cache = mp.get_property("paused-for-cache"),
cache_buffering_state = mp.get_property("cache-buffering-state")
}
msg.debug("debug_info", utils.to_string(debug_info))
-- When the video is reloaded after being paused for cache, it won't start
-- playing again while all properties looks fine:
-- `pause=no`, `paused-for-cache=no` and `cache-buffering-state=100`.
-- As a workaround, we cycle through the paused state by sending two SPACE
-- keypresses.
-- What didn't work:
-- - Cycling through the `pause` property.
-- - Run the `playlist-play-index current` command.
mp.commandv("keypress", 'SPACE')
mp.commandv("keypress", 'SPACE')
end
-- Round positive numbers.
function round(num) return math.floor(num + 0.5) end
-- main
read_settings()
if settings.reload_key_binding ~= "" then
mp.add_key_binding(settings.reload_key_binding, "reload_resume",
reload_resume)
end
if settings.paused_for_cache_timer_enabled then
mp.observe_property("paused-for-cache", "bool", paused_for_cache.handler)
end
if settings.demuxer_cache_timer_enabled then
demuxer_cache.initialize(settings.demuxer_cache_timer_interval)
end
if settings.reload_eof_enabled then
-- vo-configured == video output created && its configuration went ok
mp.observe_property("vo-configured", "bool", function(name, vo_configured)
msg.debug(name, vo_configured)
if vo_configured then
property_path = mp.get_property("path")
property_keep_open = mp.get_property("keep-open")
mp.set_property("keep-open", "yes")
mp.set_property("keep-open-pause", "no")
end
end)
mp.observe_property("eof-reached", "bool", reload_eof)
end
mp.register_event("file-loaded", on_file_loaded)

View File

@@ -0,0 +1,83 @@
-- mpv_websocket
-- https://github.com/kuroahna/mpv_websocket
local utils = require("mp.utils")
local platform = mp.get_property_native("platform")
local config_file_path = mp.find_config_file("mpv.conf")
local config_folder_path, config_file = utils.split_path(config_file_path)
local mpv_websocket_path =
utils.join_path(config_folder_path, platform == "windows" and "mpv_websocket.exe" or "mpv_websocket")
local initialised_websocket
local _, err = utils.file_info(config_file_path)
if err then
error("failed to open mpv config file `" .. config_file_path .. "`")
end
local _, err = utils.file_info(mpv_websocket_path)
if err then
error("failed to open mpv_websocket")
end
local function find_mpv_socket(config_file_path)
local file = io.open(config_file_path, "r")
if file == nil then
error("failed to read mpv config file `" .. config_file_path .. "`")
end
local mpv_socket
for line in file:lines() do
mpv_socket = line:match("^input%-ipc%-server%s*=%s*(%g+)%s*")
if mpv_socket then
break
end
end
file:close()
if not mpv_socket then
error("input-ipc-server option does not exist in `" .. config_file_path .. "`")
end
return mpv_socket
end
local mpv_socket = find_mpv_socket(config_file_path)
if platform == "windows" then
mpv_socket = "\\\\.\\pipe" .. mpv_socket:gsub("/", "\\")
end
local function start_websocket()
initialised_websocket = mp.command_native_async({
name = "subprocess",
playback_only = false,
capture_stdout = true,
capture_stderr = true,
args = {
mpv_websocket_path,
"-m",
mpv_socket,
"-w",
"6677",
},
})
end
local function end_websocket()
mp.abort_async_command(initialised_websocket)
initialised_websocket = nil
end
local function toggle_websocket()
local paused = mp.get_property_bool("pause")
if initialised_websocket and paused then
end_websocket()
elseif not initialised_websocket and not paused then
start_websocket()
end
end
mp.register_script_message("togglewebsocket", toggle_websocket)
start_websocket()

View File

@@ -0,0 +1,679 @@
-- sponsorblock.lua
--
-- This script skips sponsored segments of YouTube videos
-- using data from https://github.com/ajayyy/SponsorBlock
local ON_WINDOWS = package.config:sub(1, 1) ~= "/"
local options = {
server_address = "https://sponsor.ajay.app",
python_path = ON_WINDOWS and "python" or "python3",
-- Categories to fetch
categories = "sponsor,intro,outro,interaction,selfpromo,filler",
-- Categories to skip automatically
skip_categories = "sponsor",
-- If true, sponsored segments will only be skipped once
skip_once = true,
-- Note that sponsored segments may ocasionally be inaccurate if this is turned off
-- see https://blog.ajay.app/voting-and-pseudo-randomness-or-sponsorblock-or-youtube-sponsorship-segment-blocker
local_database = false,
-- Update database on first run, does nothing if local_database is false
auto_update = true,
-- How long to wait between local database updates
-- Format: "X[d,h,m]", leave blank to update on every mpv run
auto_update_interval = "6h",
-- User ID used to submit sponsored segments, leave blank for random
user_id = "",
-- Name to display on the stats page https://sponsor.ajay.app/stats/ leave blank to keep current name
display_name = "",
-- Tell the server when a skip happens
report_views = true,
-- Auto upvote skipped sponsors
auto_upvote = false,
-- Use sponsor times from server if they're more up to date than our local database
server_fallback = true,
-- Create chapters at sponsor boundaries for OSC display and manual skipping
make_chapters = true,
-- Minimum duration for sponsors (in seconds), segments under that threshold will be ignored
min_duration = 1,
-- Fade audio for smoother transitions
audio_fade = false,
-- Audio fade step, applied once every 100ms until cap is reached
audio_fade_step = 10,
-- Audio fade cap
audio_fade_cap = 0,
-- Fast forward through sponsors instead of skipping
fast_forward = false,
-- Playback speed modifier when fast forwarding, applied once every second until cap is reached
fast_forward_increase = 0.2,
-- Playback speed cap
fast_forward_cap = 2,
-- Length of the sha256 prefix (3-32) when querying server, 0 to disable
sha256_length = 4,
-- Pattern for video id in local files, ignored if blank
-- Recommended value for base youtube-dl is "-([%w-_]+)%.[mw][kpe][v4b]m?$"
local_pattern = "",
-- Legacy option, use skip_categories instead
skip = true,
}
mp.options = require("mp.options")
mp.options.read_options(options, "sponsorblock")
local legacy = mp.command_native_async == nil
--[[
if legacy then
options.local_database = false
end
--]]
options.local_database = false
local utils = require("mp.utils")
scripts_dir = mp.find_config_file("scripts")
local sponsorblock = utils.join_path(scripts_dir, "sponsorblock_shared/sponsorblock.py")
local uid_path = utils.join_path(scripts_dir, "sponsorblock_shared/sponsorblock.txt")
local database_file = options.local_database and utils.join_path(scripts_dir, "sponsorblock_shared/sponsorblock.db")
or ""
local youtube_id = nil
local ranges = {}
local init = false
local segment = { a = 0, b = 0, progress = 0, first = true }
local retrying = false
local last_skip = { uuid = "", dir = nil }
local speed_timer = nil
local fade_timer = nil
local fade_dir = nil
local volume_before = mp.get_property_number("volume")
local categories = {}
local all_categories =
{ "sponsor", "intro", "outro", "interaction", "selfpromo", "preview", "music_offtopic", "filler" }
local chapter_cache = {}
for category in string.gmatch(options.skip_categories, "([^,]+)") do
categories[category] = true
end
function file_exists(name)
local f = io.open(name, "r")
if f ~= nil then
io.close(f)
return true
else
return false
end
end
function t_count(t)
local count = 0
for _ in pairs(t) do
count = count + 1
end
return count
end
function time_sort(a, b)
if a.time == b.time then
return string.match(a.title, "segment end")
end
return a.time < b.time
end
function parse_update_interval()
local s = options.auto_update_interval
if s == "" then
return 0
end -- Interval Disabled
local num, mod = s:match("^(%d+)([hdm])$")
if num == nil or mod == nil then
mp.osd_message("[sponsorblock] auto_update_interval " .. s .. " is invalid", 5)
return nil
end
local time_table = {
m = 60,
h = 60 * 60,
d = 60 * 60 * 24,
}
return num * time_table[mod]
end
function clean_chapters()
local chapters = mp.get_property_native("chapter-list")
local new_chapters = {}
for _, chapter in pairs(chapters) do
if chapter.title ~= "Preview segment start" and chapter.title ~= "Preview segment end" then
table.insert(new_chapters, chapter)
end
end
mp.set_property_native("chapter-list", new_chapters)
end
function create_chapter(chapter_title, chapter_time)
local chapters = mp.get_property_native("chapter-list")
local duration = mp.get_property_native("duration")
table.insert(
chapters,
{ title = chapter_title, time = (duration == nil or duration > chapter_time) and chapter_time
or duration - 0.001 }
)
table.sort(chapters, time_sort)
mp.set_property_native("chapter-list", chapters)
end
function process(uuid, t, new_ranges)
start_time = tonumber(string.match(t, "[^,]+"))
end_time = tonumber(string.sub(string.match(t, ",[^,]+"), 2))
for o_uuid, o_t in pairs(ranges) do
if
(start_time >= o_t.start_time and start_time <= o_t.end_time)
or (o_t.start_time >= start_time and o_t.start_time <= end_time)
then
new_ranges[o_uuid] = o_t
return
end
end
category = string.match(t, "[^,]+$")
if categories[category] and end_time - start_time >= options.min_duration then
new_ranges[uuid] = {
start_time = start_time,
end_time = end_time,
category = category,
skipped = false,
}
end
if options.make_chapters and not chapter_cache[uuid] then
chapter_cache[uuid] = true
local category_title = (category:gsub("^%l", string.upper):gsub("_", " "))
create_chapter(category_title .. " segment start (" .. string.sub(uuid, 1, 6) .. ")", start_time)
create_chapter(category_title .. " segment end (" .. string.sub(uuid, 1, 6) .. ")", end_time)
end
end
function getranges(_, exists, db, more)
if type(exists) == "table" and exists["status"] == "1" then
if options.server_fallback then
mp.add_timeout(0, function()
getranges(true, true, "")
end)
else
return mp.osd_message("[sponsorblock] database update failed, gave up")
end
end
if db ~= "" and db ~= database_file then
db = database_file
end
if exists ~= true and not file_exists(db) then
if not retrying then
mp.osd_message("[sponsorblock] database update failed, retrying...")
retrying = true
end
return update()
end
if retrying then
mp.osd_message("[sponsorblock] database update succeeded")
retrying = false
end
local sponsors
local args = {
options.python_path,
sponsorblock,
"ranges",
db,
options.server_address,
youtube_id,
options.categories,
tostring(options.sha256_length),
}
if not legacy then
sponsors = mp.command_native({ name = "subprocess", capture_stdout = true, playback_only = false, args = args })
else
sponsors = utils.subprocess({ args = args })
end
mp.msg.debug("Got: " .. string.gsub(sponsors.stdout, "[\n\r]", ""))
if not string.match(sponsors.stdout, "^%s*(.*%S)") then
return
end
if string.match(sponsors.stdout, "error") then
return getranges(true, true)
end
local new_ranges = {}
local r_count = 0
if more then
r_count = -1
end
for t in string.gmatch(sponsors.stdout, "[^:%s]+") do
uuid = string.match(t, "([^,]+),[^,]+$")
if ranges[uuid] then
new_ranges[uuid] = ranges[uuid]
else
process(uuid, t, new_ranges)
end
r_count = r_count + 1
end
local c_count = t_count(ranges)
if c_count == 0 or r_count >= c_count then
ranges = new_ranges
end
end
function fast_forward()
if options.fast_forward and options.fast_forward == true then
speed_timer = nil
mp.set_property("speed", 1)
end
local last_speed = mp.get_property_number("speed")
local new_speed = math.min(last_speed + options.fast_forward_increase, options.fast_forward_cap)
if new_speed <= last_speed then
return
end
mp.set_property("speed", new_speed)
end
function fade_audio(step)
local last_volume = mp.get_property_number("volume")
local new_volume = math.max(options.audio_fade_cap, math.min(last_volume + step, volume_before))
if new_volume == last_volume then
if step >= 0 then
fade_dir = nil
end
if fade_timer ~= nil then
fade_timer:kill()
end
fade_timer = nil
return
end
mp.set_property("volume", new_volume)
end
function skip_ads(name, pos)
if pos == nil then
return
end
local sponsor_ahead = false
for uuid, t in pairs(ranges) do
if
(options.fast_forward == uuid or not options.skip_once or not t.skipped)
and t.start_time <= pos
and t.end_time > pos
then
if options.fast_forward == uuid then
return
end
if options.fast_forward == false then
mp.osd_message("[sponsorblock] " .. t.category .. " skipped")
mp.set_property("time-pos", t.end_time)
else
mp.osd_message("[sponsorblock] skipping " .. t.category)
end
t.skipped = true
last_skip = { uuid = uuid, dir = nil }
if options.report_views or options.auto_upvote then
local args = {
options.python_path,
sponsorblock,
"stats",
database_file,
options.server_address,
youtube_id,
uuid,
options.report_views and "1" or "",
uid_path,
options.user_id,
options.auto_upvote and "1" or "",
}
if not legacy then
mp.command_native_async({ name = "subprocess", playback_only = false, args = args }, function() end)
else
utils.subprocess_detached({ args = args })
end
end
if options.fast_forward ~= false then
options.fast_forward = uuid
if speed_timer ~= nil then
speed_timer:kill()
end
speed_timer = mp.add_periodic_timer(1, fast_forward)
end
return
elseif (not options.skip_once or not t.skipped) and t.start_time <= pos + 1 and t.end_time > pos + 1 then
sponsor_ahead = true
end
end
if options.audio_fade then
if sponsor_ahead then
if fade_dir ~= false then
if fade_dir == nil then
volume_before = mp.get_property_number("volume")
end
if fade_timer ~= nil then
fade_timer:kill()
end
fade_dir = false
fade_timer = mp.add_periodic_timer(0.1, function()
fade_audio(-options.audio_fade_step)
end)
end
elseif fade_dir == false then
fade_dir = true
if fade_timer ~= nil then
fade_timer:kill()
end
fade_timer = mp.add_periodic_timer(0.1, function()
fade_audio(options.audio_fade_step)
end)
end
end
if options.fast_forward and options.fast_forward ~= true then
options.fast_forward = true
speed_timer:kill()
speed_timer = nil
mp.set_property("speed", 1)
end
end
function vote(dir)
if last_skip.uuid == "" then
return mp.osd_message("[sponsorblock] no sponsors skipped, can't submit vote")
end
local updown = dir == "1" and "up" or "down"
if last_skip.dir == dir then
return mp.osd_message("[sponsorblock] " .. updown .. "vote already submitted")
end
last_skip.dir = dir
local args = {
options.python_path,
sponsorblock,
"stats",
database_file,
options.server_address,
youtube_id,
last_skip.uuid,
"",
uid_path,
options.user_id,
dir,
}
if not legacy then
mp.command_native_async({ name = "subprocess", playback_only = false, args = args }, function() end)
else
utils.subprocess({ args = args })
end
mp.osd_message("[sponsorblock] " .. updown .. "vote submitted")
end
function update()
mp.command_native_async(
{
name = "subprocess",
playback_only = false,
args = {
options.python_path,
sponsorblock,
"update",
database_file,
options.server_address,
},
},
getranges
)
end
function file_loaded()
local initialized = init
ranges = {}
segment = { a = 0, b = 0, progress = 0, first = true }
last_skip = { uuid = "", dir = nil }
chapter_cache = {}
local video_path = mp.get_property("path", "")
mp.msg.debug("Path: " .. video_path)
local video_referer = string.match(mp.get_property("http-header-fields", ""), "Referer:([^,]+)") or ""
mp.msg.debug("Referer: " .. video_referer)
local urls = {
"https?://youtu%.be/([%w-_]+).*",
"https?://w?w?w?%.?youtube%.com/v/([%w-_]+).*",
"/watch.*[?&]v=([%w-_]+).*",
"/embed/([%w-_]+).*",
}
youtube_id = nil
for i, url in ipairs(urls) do
youtube_id = youtube_id or string.match(video_path, url) or string.match(video_referer, url)
if youtube_id then
break
end
end
youtube_id = youtube_id or string.match(video_path, options.local_pattern)
if not youtube_id or string.len(youtube_id) < 11 or (local_pattern and string.len(youtube_id) ~= 11) then
return
end
youtube_id = string.sub(youtube_id, 1, 11)
mp.msg.debug("Found YouTube ID: " .. youtube_id)
init = true
if not options.local_database then
getranges(true, true)
else
local exists = file_exists(database_file)
if exists and options.server_fallback then
getranges(true, true)
mp.add_timeout(0, function()
getranges(true, true, "", true)
end)
elseif exists then
getranges(true, true)
elseif options.server_fallback then
mp.add_timeout(0, function()
getranges(true, true, "")
end)
end
end
if initialized then
return
end
if options.skip then
mp.observe_property("time-pos", "native", skip_ads)
end
if options.display_name ~= "" then
local args = {
options.python_path,
sponsorblock,
"username",
database_file,
options.server_address,
youtube_id,
"",
"",
uid_path,
options.user_id,
options.display_name,
}
if not legacy then
mp.command_native_async({ name = "subprocess", playback_only = false, args = args }, function() end)
else
utils.subprocess_detached({ args = args })
end
end
if not options.local_database or (not options.auto_update and file_exists(database_file)) then
return
end
if file_exists(database_file) then
local db_info = utils.file_info(database_file)
local cur_time = os.time(os.date("*t"))
local upd_interval = parse_update_interval()
if upd_interval == nil or os.difftime(cur_time, db_info.mtime) < upd_interval then
return
end
end
update()
end
function set_segment()
if not youtube_id then
return
end
local pos = mp.get_property_number("time-pos")
if pos == nil then
return
end
if segment.progress > 1 then
segment.progress = segment.progress - 2
end
if segment.progress == 1 then
segment.progress = 0
segment.b = pos
mp.osd_message("[sponsorblock] segment boundary B set, press again for boundary A", 3)
else
segment.progress = 1
segment.a = pos
mp.osd_message("[sponsorblock] segment boundary A set, press again for boundary B", 3)
end
if options.make_chapters and not segment.first then
local start_time = math.min(segment.a, segment.b)
local end_time = math.max(segment.a, segment.b)
if end_time - start_time ~= 0 and end_time ~= 0 then
clean_chapters()
create_chapter("Preview segment start", start_time)
create_chapter("Preview segment end", end_time)
end
end
segment.first = false
end
function select_category(selected)
for category in string.gmatch(options.categories, "([^,]+)") do
mp.remove_key_binding("select_category_" .. category)
mp.remove_key_binding("kp_select_category_" .. category)
end
submit_segment(selected)
end
function submit_segment(category)
if not youtube_id then
return
end
local start_time = math.min(segment.a, segment.b)
local end_time = math.max(segment.a, segment.b)
if end_time - start_time == 0 or end_time == 0 then
mp.osd_message("[sponsorblock] empty segment, not submitting")
elseif segment.progress <= 1 then
segment.progress = segment.progress + 2
local category_list = ""
for category_id, category in pairs(all_categories) do
local category_title = (category:gsub("^%l", string.upper):gsub("_", " "))
category_list = category_list .. category_id .. ": " .. category_title .. "\n"
mp.add_forced_key_binding(tostring(category_id), "select_category_" .. category, function()
select_category(category)
end)
mp.add_forced_key_binding("KP" .. tostring(category_id), "kp_select_category_" .. category, function()
select_category(category)
end)
end
mp.osd_message(
string.format(
"[sponsorblock] press a number to select category for segment: %.2d:%.2d:%.2d to %.2d:%.2d:%.2d\n\n"
.. category_list
.. "\nyou can press Shift+G again for default (Sponsor) or hide this message with g",
math.floor(start_time / (60 * 60)),
math.floor(start_time / 60 % 60),
math.floor(start_time % 60),
math.floor(end_time / (60 * 60)),
math.floor(end_time / 60 % 60),
math.floor(end_time % 60)
),
30
)
else
mp.osd_message("[sponsorblock] submitting segment...", 30)
local submit
local args = {
options.python_path,
sponsorblock,
"submit",
database_file,
options.server_address,
youtube_id,
tostring(start_time),
tostring(end_time),
uid_path,
options.user_id,
category or "sponsor",
}
if not legacy then
submit =
mp.command_native({ name = "subprocess", capture_stdout = true, playback_only = false, args = args })
else
submit = utils.subprocess({ args = args })
end
if string.match(submit.stdout, "success") then
segment = { a = 0, b = 0, progress = 0, first = true }
mp.osd_message("[sponsorblock] segment submitted")
if options.make_chapters then
clean_chapters()
create_chapter("Submitted segment start", start_time)
create_chapter("Submitted segment end", end_time)
end
elseif string.match(submit.stdout, "error") then
mp.osd_message("[sponsorblock] segment submission failed, server may be down. try again", 5)
elseif string.match(submit.stdout, "502") then
mp.osd_message("[sponsorblock] segment submission failed, server is down. try again", 5)
elseif string.match(submit.stdout, "400") then
mp.osd_message("[sponsorblock] segment submission failed, impossible inputs", 5)
segment = { a = 0, b = 0, progress = 0, first = true }
elseif string.match(submit.stdout, "429") then
mp.osd_message("[sponsorblock] segment submission failed, rate limited. try again", 5)
elseif string.match(submit.stdout, "409") then
mp.osd_message("[sponsorblock] segment already submitted", 3)
segment = { a = 0, b = 0, progress = 0, first = true }
else
mp.osd_message("[sponsorblock] segment submission failed", 5)
end
end
end
mp.register_event("file-loaded", file_loaded)
mp.add_key_binding("ctrl+g", "set_segment", set_segment)
mp.add_key_binding("ctrl+G", "submit_segment", submit_segment)
mp.add_key_binding("ctrl+h", "upvote_segment", function()
return vote("1")
end)
mp.add_key_binding("ctrl+H", "downvote_segment", function()
return vote("0")
end)
-- Bindings below are for backwards compatibility and could be removed at any time
mp.add_key_binding(nil, "sponsorblock_set_segment", set_segment)
mp.add_key_binding(nil, "sponsorblock_submit_segment", submit_segment)
mp.add_key_binding(nil, "sponsorblock_upvote", function()
return vote("1")
end)
mp.add_key_binding(nil, "sponsorblock_downvote", function()
return vote("0")
end)

View File

@@ -0,0 +1,3 @@
-- This is a dummy main.lua
-- required for mpv 0.33
-- do not delete

View File

@@ -0,0 +1,122 @@
import urllib.request
import urllib.parse
import hashlib
import sqlite3
import random
import string
import json
import sys
import os
if sys.argv[1] in ["submit", "stats", "username"]:
if not sys.argv[8]:
if os.path.isfile(sys.argv[7]):
with open(sys.argv[7]) as f:
uid = f.read()
else:
uid = "".join(random.choices(string.ascii_letters + string.digits, k=36))
with open(sys.argv[7], "w") as f:
f.write(uid)
else:
uid = sys.argv[8]
opener = urllib.request.build_opener()
opener.addheaders = [("User-Agent", "mpv_sponsorblock/1.0 (https://github.com/po5/mpv_sponsorblock)")]
urllib.request.install_opener(opener)
if sys.argv[1] == "ranges" and (not sys.argv[2] or not os.path.isfile(sys.argv[2])):
sha = None
if 3 <= int(sys.argv[6]) <= 32:
sha = hashlib.sha256(sys.argv[4].encode()).hexdigest()[:int(sys.argv[6])]
times = []
try:
response = urllib.request.urlopen(sys.argv[3] + "/api/skipSegments" + ("/" + sha + "?" if sha else "?videoID=" + sys.argv[4] + "&") + urllib.parse.urlencode([("categories", json.dumps(sys.argv[5].split(",")))]))
segments = json.load(response)
for segment in segments:
if sha and sys.argv[4] != segment["videoID"]:
continue
if sha:
for s in segment["segments"]:
times.append(str(s["segment"][0]) + "," + str(s["segment"][1]) + "," + s["UUID"] + "," + s["category"])
else:
times.append(str(segment["segment"][0]) + "," + str(segment["segment"][1]) + "," + segment["UUID"] + "," + segment["category"])
print(":".join(times))
except (TimeoutError, urllib.error.URLError) as e:
print("error")
except urllib.error.HTTPError as e:
if e.code == 404:
print("")
else:
print("error")
elif sys.argv[1] == "ranges":
conn = sqlite3.connect(sys.argv[2])
conn.row_factory = sqlite3.Row
c = conn.cursor()
times = []
for category in sys.argv[5].split(","):
c.execute("SELECT startTime, endTime, votes, UUID, category FROM sponsorTimes WHERE videoID = ? AND shadowHidden = 0 AND votes > -1 AND category = ?", (sys.argv[4], category))
sponsors = c.fetchall()
best = list(sponsors)
dealtwith = []
similar = []
for sponsor_a in sponsors:
for sponsor_b in sponsors:
if sponsor_a is not sponsor_b and sponsor_a["startTime"] >= sponsor_b["startTime"] and sponsor_a["startTime"] <= sponsor_b["endTime"]:
similar.append([sponsor_a, sponsor_b])
if sponsor_a in best:
best.remove(sponsor_a)
if sponsor_b in best:
best.remove(sponsor_b)
for sponsors_a in similar:
if sponsors_a in dealtwith:
continue
group = set(sponsors_a)
for sponsors_b in similar:
if sponsors_b[0] in group or sponsors_b[1] in group:
group.add(sponsors_b[0])
group.add(sponsors_b[1])
dealtwith.append(sponsors_b)
best.append(max(group, key=lambda x:x["votes"]))
for time in best:
times.append(str(time["startTime"]) + "," + str(time["endTime"]) + "," + time["UUID"] + "," + time["category"])
print(":".join(times))
elif sys.argv[1] == "update":
try:
urllib.request.urlretrieve(sys.argv[3] + "/database.db", sys.argv[2] + ".tmp")
os.replace(sys.argv[2] + ".tmp", sys.argv[2])
except PermissionError:
print("database update failed, file currently in use", file=sys.stderr)
sys.exit(1)
except ConnectionResetError:
print("database update failed, connection reset", file=sys.stderr)
sys.exit(1)
except TimeoutError:
print("database update failed, timed out", file=sys.stderr)
sys.exit(1)
except urllib.error.URLError:
print("database update failed", file=sys.stderr)
sys.exit(1)
elif sys.argv[1] == "submit":
try:
req = urllib.request.Request(sys.argv[3] + "/api/skipSegments", data=json.dumps({"videoID": sys.argv[4], "segments": [{"segment": [float(sys.argv[5]), float(sys.argv[6])], "category": sys.argv[9]}], "userID": uid}).encode(), headers={"Content-Type": "application/json"})
response = urllib.request.urlopen(req)
print("success")
except urllib.error.HTTPError as e:
print(e.code)
except:
print("error")
elif sys.argv[1] == "stats":
try:
if sys.argv[6]:
urllib.request.urlopen(sys.argv[3] + "/api/viewedVideoSponsorTime?UUID=" + sys.argv[5])
if sys.argv[9]:
urllib.request.urlopen(sys.argv[3] + "/api/voteOnSponsorTime?UUID=" + sys.argv[5] + "&userID=" + uid + "&type=" + sys.argv[9])
except:
pass
elif sys.argv[1] == "username":
try:
data = urllib.parse.urlencode({"userID": uid, "userName": sys.argv[9]}).encode()
req = urllib.request.Request(sys.argv[3] + "/api/setUsername", data=data)
urllib.request.urlopen(req)
except:
pass

View File

@@ -0,0 +1 @@
dFlkoCOSK3BQhXGGhUsXSNU0sPr7AV7avndk

View File

@@ -0,0 +1 @@
../submodules/mpvacious

View File

@@ -0,0 +1 @@
../submodules/thumbfast/thumbfast.lua

View File

@@ -0,0 +1 @@
../submodules/mpv-youtube-upnext/youtube-upnext.lua

View File

@@ -0,0 +1 @@
../submodules/ytdl-preload/ytdl-preload.lua

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,415 @@
// LICENSE
// =======
// Copyright (c) 2017-2019 Advanced Micro Devices, Inc. All rights reserved.
// -------
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// -------
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
// Software.
// -------
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// FidelityFX CAS v1.0.2 by AMD
// ported to mpv by agyild
// Changelog
// Optimized texture lookups for OpenGL 4.0+, DirectX 10+, and OpenGL ES 3.1+
// Changed rcp + mul operations to div for better clarity when CAS_GO_SLOWER is set to 1, since the compiler should automatically
// optimize those instructions anyway.
// Made it directly operate on LUMA plane, since the original shader was operating on LUMA by deriving it from RGB. This should
// cause a major increase in performance, especially on OpenGL 4.0+ renderers (4 texture lookups vs. 16)
// Removed transparency preservation mechanism since the alpha channel is a separate source plan than LUMA
// Added custom gamma curve support for relinearization
// Removed final blending between the original and the sharpened pixels since it was redundant
//
// Notes
// Per AMD's guidelines only upscales content up to 4x (e.g., 1080p -> 2160p, 720p -> 1440p etc.) and everything else in between,
// that means CAS will scale up to 4x at maximum, and any further scaling will be processed by mpv's scalers
//
// The filter is designed to run in linear light, and does have an optional relinerization and delinearization pass which
// assumes BT.1886 content by default. Do not forget to change SOURCE_TRC and TARGET_TRC variables depending
// on what kind of content the filter is running on. You might want to create seperate versions of the file with different
// colorspace values, and apply them via autoprofiles. Note that running in non-linear light will result in oversharpening.
//!HOOK LUMA
//!BIND HOOKED
//!DESC FidelityFX Upsampling and Sharpening v1.0.2 (Relinearization)
//!WHEN OUTPUT.w OUTPUT.h * LUMA.w LUMA.h * / 1.0 >
// User variables - Relinearization
// Compatibility
#define SOURCE_TRC 4 // Is needed to convert from source colorspace to linear light. 0 = None (Skip conversion), 1 = Rec709, 2 = PQ, 3 = sRGB, 4 = BT.1886, 5 = HLG, 6 = Custom
#define CUSTOM_GAMMA 2.2 // Custom power gamma curve to use if and when SOURCE_TRC is 6.
// Shader code
float From709(float rec709) {
return max(min(rec709 / float(4.5), float(0.081)), pow((rec709 + float(0.099)) / float(1.099), float(1.0 / 0.45)));
}
float FromPq(float pq) {
float p = pow(pq, float(0.0126833));
return (pow(clamp(p - float(0.835938), 0.0, 1.0) / (float(18.8516) - float(18.6875) * p), float(6.27739)));
}
float FromSrgb(float srgb) {
return max(min(srgb / 12.92, float(0.04045)), pow((srgb + float(0.055)) / float(1.055), float(2.4)));
}
float FromHlg(float hlg) {
const float a = 0.17883277;
const float b = 0.28466892;
const float c = 0.55991073;
float linear;
if (hlg >= 0.0 && hlg <= 0.5) {
linear = pow(hlg, 2.0) / 3.0;
} else {
linear = (exp((hlg - c) / a) + b) / 12.0;
}
return linear;
}
vec4 hook() {
vec4 col = HOOKED_tex(HOOKED_pos);
col.r = clamp(col.r, 0.0, 1.0);
#if (SOURCE_TRC == 1)
col.r = From709(col.r);
#elif (SOURCE_TRC == 2)
col.r = FromPq(col.r);
#elif (SOURCE_TRC == 3)
col.r = FromSrgb(col.r);
#elif (SOURCE_TRC == 4)
col.r = pow(col.r, float(2.4));
#elif (SOURCE_TRC == 5)
col.r = FromHlg(col.r);
#elif (SOURCE_TRC == 6)
col.r = pow(col.r, float(CUSTOM_GAMMA));
#endif
return col;
}
//!HOOK LUMA
//!BIND HOOKED
//!DESC FidelityFX Upsampling and Sharpening v1.0.2
//!WHEN OUTPUT.w OUTPUT.h * LUMA.w LUMA.h * / 1.0 >
//!WIDTH OUTPUT.w OUTPUT.w LUMA.w 2 * < * LUMA.w 2 * OUTPUT.w LUMA.w 2 * > * + OUTPUT.w OUTPUT.w LUMA.w 2 * = * +
//!HEIGHT OUTPUT.h OUTPUT.h LUMA.h 2 * < * LUMA.h 2 * OUTPUT.h LUMA.h 2 * > * + OUTPUT.h OUTPUT.h LUMA.h 2 * = * +
// User variables - Upsampling and Sharpening
// Intensity
#define SHARPENING 0.0 // Adjusts the range the shader adapts to high contrast (0 is not all the way off). Higher values = more high contrast sharpening. 0.0 to 1.0.
// Performance
#define CAS_BETTER_DIAGONALS 1 // If set to 0, drops certain math and texture lookup operations for better performance. This is only useful on pre-OpenGL 4.0 renderers and there is no need to disable it otherwise. 0 or 1.
#define CAS_GO_SLOWER 0 // If set to 1, disables the use of optimized approximate transcendental functions which might slightly increase accuracy in exchange of performance. 0 or 1.
// Compatibility
#define TARGET_TRC 4 // Is needed to convert from source colorspace to target colorspace. 0 = None (Skip conversion), 1 = Rec709, 2 = PQ, 3 = sRGB, 4 = BT.1886, 5 = HLG, 6 = Custom
#define CUSTOM_GAMMA 2.2 // Custom power gamma curve to use if and when TARGET_TRC is 6.
// Shader code
float To709(float linear) {
return max(min(linear * float(4.5), float(0.018)), float(1.099) * pow(linear, float(0.45)) - float(0.099));
}
float ToPq(float linear) {
float p = pow(linear, float(0.159302));
return pow((float(0.835938) + float(18.8516) * p) / (float(1.0) + float(18.6875) * p), float(78.8438));
}
float ToSrgb(float linear) {
return max(min(linear * float(12.92), float(0.0031308)), float(1.055) * pow(linear, float(0.41666)) - float(0.055));
}
float ToHlg(float linear) {
const float a = 0.17883277;
const float b = 0.28466892;
const float c = 0.55991073;
float hlg;
if (linear <= 1.0 / 12.0) {
hlg = sqrt(3.0 * linear);
} else {
hlg = a * log(12.0 * linear - b) + c;
}
return hlg;
}
#if (CAS_GO_SLOWER == 0)
float APrxLoSqrtF1(float a) {
return uintBitsToFloat((floatBitsToUint(a) >> uint(1)) + uint(0x1fbc4639));
}
float APrxLoRcpF1(float a) {
return uintBitsToFloat(uint(0x7ef07ebb) - floatBitsToUint(a));
}
float APrxMedRcpF1(float a) {
float b = uintBitsToFloat(uint(0x7ef19fff) - floatBitsToUint(a));
return b * (-b * a + float(2.0));
}
#endif
vec4 hook()
{
// Scaling algorithm adaptively interpolates between nearest 4 results of the non-scaling algorithm.
// a b c d
// e f g h
// i j k l
// m n o p
// Working these 4 results.
// +-----+-----+
// | | |
// | f..|..g |
// | . | . |
// +-----+-----+
// | . | . |
// | j..|..k |
// | | |
// +-----+-----+
vec2 pp = HOOKED_pos * HOOKED_size - 0.5;
vec2 fp = floor(pp);
pp -= fp;
#if (defined(HOOKED_gather) && (__VERSION__ >= 400 || (GL_ES && __VERSION__ >= 310)))
vec4 abef = HOOKED_gather(vec2((fp - vec2(0.5)) * HOOKED_pt), 0);
float b = abef.z;
float e = abef.x;
float f = abef.y;
vec4 cdgh = HOOKED_gather(vec2((fp + vec2(1.5, -0.5)) * HOOKED_pt), 0);
float c = cdgh.w;
float g = cdgh.x;
float h = cdgh.y;
vec4 ijmn = HOOKED_gather(vec2((fp + vec2(-0.5, 1.5)) * HOOKED_pt), 0);
float i = ijmn.w;
float j = ijmn.z;
float n = ijmn.y;
vec4 klop = HOOKED_gather(vec2((fp + vec2(1.5)) * HOOKED_pt), 0);
float k = klop.w;
float l = klop.z;
float o = klop.x;
#if (CAS_BETTER_DIAGONALS == 1)
float a = abef.w;
float d = cdgh.z;
float m = ijmn.x;
float p = klop.y;
#endif
#else
ivec2 sp = ivec2(fp);
#if (CAS_BETTER_DIAGONALS == 1)
float a = texelFetch(HOOKED_raw, sp + ivec2(-1, -1), 0).r * HOOKED_mul;
float d = texelFetch(HOOKED_raw, sp + ivec2( 2, -1), 0).r * HOOKED_mul;
float m = texelFetch(HOOKED_raw, sp + ivec2(-1, 2), 0).r * HOOKED_mul;
float p = texelFetch(HOOKED_raw, sp + ivec2( 2, 2), 0).r * HOOKED_mul;
#endif
float b = texelFetch(HOOKED_raw, sp + ivec2( 0, -1), 0).r * HOOKED_mul;
float e = texelFetch(HOOKED_raw, sp + ivec2(-1, 0), 0).r * HOOKED_mul;
float f = texelFetch(HOOKED_raw, sp , 0).r * HOOKED_mul;
float c = texelFetch(HOOKED_raw, sp + ivec2( 1, -1), 0).r * HOOKED_mul;
float g = texelFetch(HOOKED_raw, sp + ivec2( 1, 0), 0).r * HOOKED_mul;
float h = texelFetch(HOOKED_raw, sp + ivec2( 2, 0), 0).r * HOOKED_mul;
float i = texelFetch(HOOKED_raw, sp + ivec2(-1, 1), 0).r * HOOKED_mul;
float j = texelFetch(HOOKED_raw, sp + ivec2( 0, 1), 0).r * HOOKED_mul;
float n = texelFetch(HOOKED_raw, sp + ivec2( 0, 2), 0).r * HOOKED_mul;
float k = texelFetch(HOOKED_raw, sp + ivec2( 1, 1), 0).r * HOOKED_mul;
float l = texelFetch(HOOKED_raw, sp + ivec2( 2, 1), 0).r * HOOKED_mul;
float o = texelFetch(HOOKED_raw, sp + ivec2( 1, 2), 0).r * HOOKED_mul;
#endif
// Soft min and max.
// These are 2.0x bigger (factored out the extra multiply).
// a b c b
// e f g * 0.5 + e f g * 0.5 [F]
// i j k j
float mnfL = min(min(b, min(e, f)), min(g, j));
float mxfL = max(max(b, max(e, f)), max(g, j));
#if (CAS_BETTER_DIAGONALS == 1)
float mnfL2 = min(min(mnfL, min(a, c)), min(i, k));
mnfL += mnfL2;
float mxfL2 = max(max(mxfL, max(a, c)), max(i, k));
mxfL += mxfL2;
#endif
// b c d c
// f g h * 0.5 + f g h * 0.5 [G]
// j k l k
float mngL = min(min(c, min(f, g)), min(h, k));
float mxgL = max(max(c, max(f, g)), max(h, k));
#if (CAS_BETTER_DIAGONALS == 1)
float mngL2 = min(min(mngL, min(b, d)), min(j, l));
mngL += mngL2;
float mxgL2 = max(max(mxgL, max(b, d)), max(j, l));
mxgL += mxgL2;
#endif
// e f g f
// i j k * 0.5 + i j k * 0.5 [J]
// m n o n
float mnjL = min(min(f, min(i, j)), min(k, n));
float mxjL = max(max(f, max(i, j)), max(k, n));
#if (CAS_BETTER_DIAGONALS == 1)
float mnjL2 = min(min(mnjL, min(e, g)), min(m, o));
mnjL += mnjL2;
float mxjL2 = max(max(mxjL, max(e, g)), max(m, o));
mxjL += mxjL2;
#endif
// f g h g
// j k l * 0.5 + j k l * 0.5 [K]
// n o p o
float mnkL = min(min(g, min(j, k)), min(l, o));
float mxkL = max(max(g, max(j, k)), max(l, o));
#if (CAS_BETTER_DIAGONALS == 1)
float mnkL2 = min(min(mnkL, min(f, h)), min(n, p));
mnkL += mnkL2;
float mxkL2 = max(max(mxkL, max(f, h)), max(n, p));
mxkL += mxkL2;
#endif
// Smooth minimum distance to signal limit divided by smooth max.
const float bdval = bool(CAS_BETTER_DIAGONALS) ? 2.0 : 1.0;
#if (CAS_GO_SLOWER == 1)
float ampfL = clamp(min(mnfL, bdval - mxfL) / mxfL, 0.0, 1.0);
float ampgL = clamp(min(mngL, bdval - mxgL) / mxgL, 0.0, 1.0);
float ampjL = clamp(min(mnjL, bdval - mxjL) / mxjL, 0.0, 1.0);
float ampkL = clamp(min(mnkL, bdval - mxkL) / mxkL, 0.0, 1.0);
#else
float ampfL = clamp(min(mnfL, bdval - mxfL) * APrxLoRcpF1(mxfL), 0.0, 1.0);
float ampgL = clamp(min(mngL, bdval - mxgL) * APrxLoRcpF1(mxgL), 0.0, 1.0);
float ampjL = clamp(min(mnjL, bdval - mxjL) * APrxLoRcpF1(mxjL), 0.0, 1.0);
float ampkL = clamp(min(mnkL, bdval - mxkL) * APrxLoRcpF1(mxkL), 0.0, 1.0);
#endif
// Shaping amount of sharpening.
#if (CAS_GO_SLOWER == 1)
ampfL = sqrt(ampfL);
ampgL = sqrt(ampgL);
ampjL = sqrt(ampjL);
ampkL = sqrt(ampkL);
#else
ampfL = APrxLoSqrtF1(ampfL);
ampgL = APrxLoSqrtF1(ampgL);
ampjL = APrxLoSqrtF1(ampjL);
ampkL = APrxLoSqrtF1(ampkL);
#endif
// Filter shape.
// 0 w 0
// w 1 w
// 0 w 0
const float peak = -(mix(8.0, 5.0, clamp(SHARPENING, 0.0, 1.0)));
float wfL = ampfL / peak;
float wgL = ampgL / peak;
float wjL = ampjL / peak;
float wkL = ampkL / peak;
// Blend between 4 results.
// s t
// u v
float s = (1.0 - pp.x) * (1.0 - pp.y);
float t = pp.x * (1.0 - pp.y);
float u = (1.0 - pp.x) * pp.y;
float v = pp.x * pp.y;
// Thin edges to hide bilinear interpolation (helps diagonals).
const float thinB = 0.03125; // 1.0 / 32.0
#if (CAS_GO_SLOWER == 1)
s /= thinB + mxfL - mnfL;
t /= thinB + mxgL - mngL;
u /= thinB + mxjL - mnjL;
v /= thinB + mxkL - mnkL;
#else
s *= APrxLoRcpF1(thinB + mxfL - mnfL);
t *= APrxLoRcpF1(thinB + mxgL - mngL);
u *= APrxLoRcpF1(thinB + mxjL - mnjL);
v *= APrxLoRcpF1(thinB + mxkL - mnkL);
#endif
// Final weighting.
// b c
// e f g h
// i j k l
// n o
// _____ _____ _____ _____
// fs gt
//
// _____ _____ _____ _____
// fs s gt fs t gt
// ju kv
// _____ _____ _____ _____
// fs gt
// ju u kv ju v kv
// _____ _____ _____ _____
//
// ju kv
float qbeL = wfL * s;
float qchL = wgL * t;
float qfL = wgL * t + wjL * u + s;
float qgL = wfL * s + wkL * v + t;
float qjL = wfL * s + wkL * v + u;
float qkL = wgL * t + wjL * u + v;
float qinL = wjL * u;
float qloL = wkL * v;
// Filter.
vec4 pix = vec4(0.0, 0.0, 0.0, 1.0);
float W = 2.0 * qbeL + 2.0 * qchL + 2.0 * qinL + 2.0 * qloL + qfL + qgL + qjL + qkL;
pix.r = b * qbeL + e * qbeL + c * qchL + h * qchL + i * qinL + n * qinL + l * qloL + o * qloL + f * qfL + g * qgL + j * qjL + k * qkL;
#if (CAS_GO_SLOWER == 1)
pix.r /= W;
#else
pix.r *= APrxMedRcpF1(W);
#endif
pix.r = clamp(pix.r, 0.0, 1.0);
#if (TARGET_TRC == 1)
pix.r = To709(pix.r);
#elif (TARGET_TRC == 2)
pix.r = ToPq(pix.r);
#elif (TARGET_TRC == 3)
pix.r = ToSrgb(pix.r);
#elif (TARGET_TRC == 4)
pix.r = pow(pix.r, float(1.0 / 2.4));
#elif (TARGET_TRC == 5)
pix.r = ToHlg(pix.r);
#elif (TARGET_TRC == 6)
pix.r = pow(pix.r, float(1.0 / CUSTOM_GAMMA));
#endif
return pix;
}

View File

@@ -0,0 +1,453 @@
// Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// FidelityFX FSR v1.0.2 by AMD
// ported to mpv by agyild
// Changelog
// Made it compatible with pre-OpenGL 4.0 renderers
// Made it directly operate on LUMA plane, since the original shader was operating on LUMA by deriving it from RGB. This should cause a major increase in performance, especially on OpenGL 4.0+ renderers (4+2 texture lookups vs. 12+5)
// Removed transparency preservation mechanism since the alpha channel is a separate source plane than LUMA
// Added optional performance-saving lossy optimizations to EASU (Credit: atyuwen, https://atyuwen.github.io/posts/optimizing-fsr/)
//
// Notes
// Per AMD's guidelines only upscales content up to 4x (e.g., 1080p -> 2160p, 720p -> 1440p etc.) and everything else in between,
// that means FSR will scale up to 4x at maximum, and any further scaling will be processed by mpv's scalers
//!HOOK LUMA
//!BIND HOOKED
//!SAVE EASUTEX
//!DESC FidelityFX Super Resolution v1.0.2 (EASU)
//!WHEN OUTPUT.w OUTPUT.h * LUMA.w LUMA.h * / 1.0 >
//!WIDTH OUTPUT.w OUTPUT.w LUMA.w 2 * < * LUMA.w 2 * OUTPUT.w LUMA.w 2 * > * + OUTPUT.w OUTPUT.w LUMA.w 2 * = * +
//!HEIGHT OUTPUT.h OUTPUT.h LUMA.h 2 * < * LUMA.h 2 * OUTPUT.h LUMA.h 2 * > * + OUTPUT.h OUTPUT.h LUMA.h 2 * = * +
//!COMPONENTS 1
// User variables - EASU
#define FSR_PQ 0 // Whether the source content has PQ gamma or not. Needs to be set to the same value for both passes. 0 or 1.
#define FSR_EASU_DERING 1 // If set to 0, disables deringing for a small increase in performance. 0 or 1.
#define FSR_EASU_SIMPLE_ANALYSIS 0 // If set to 1, uses a simpler single-pass direction and length analysis for an increase in performance. 0 or 1.
#define FSR_EASU_QUIT_EARLY 0 // If set to 1, uses bilinear filtering for non-edge pixels and skips EASU on those regions for an increase in performance. 0 or 1.
// Shader code
#ifndef FSR_EASU_DIR_THRESHOLD
#if (FSR_EASU_QUIT_EARLY == 1)
#define FSR_EASU_DIR_THRESHOLD 64.0
#elif (FSR_EASU_QUIT_EARLY == 0)
#define FSR_EASU_DIR_THRESHOLD 32768.0
#endif
#endif
float APrxLoRcpF1(float a) {
return uintBitsToFloat(uint(0x7ef07ebb) - floatBitsToUint(a));
}
float APrxLoRsqF1(float a) {
return uintBitsToFloat(uint(0x5f347d74) - (floatBitsToUint(a) >> uint(1)));
}
float AMin3F1(float x, float y, float z) {
return min(x, min(y, z));
}
float AMax3F1(float x, float y, float z) {
return max(x, max(y, z));
}
#if (FSR_PQ == 1)
float ToGamma2(float a) {
return pow(a, 4.0);
}
#endif
// Filtering for a given tap for the scalar.
void FsrEasuTap(
inout float aC, // Accumulated color, with negative lobe.
inout float aW, // Accumulated weight.
vec2 off, // Pixel offset from resolve position to tap.
vec2 dir, // Gradient direction.
vec2 len, // Length.
float lob, // Negative lobe strength.
float clp, // Clipping point.
float c){ // Tap color.
// Rotate offset by direction.
vec2 v;
v.x = (off.x * ( dir.x)) + (off.y * dir.y);
v.y = (off.x * (-dir.y)) + (off.y * dir.x);
// Anisotropy.
v *= len;
// Compute distance^2.
float d2 = v.x * v.x + v.y * v.y;
// Limit to the window as at corner, 2 taps can easily be outside.
d2 = min(d2, clp);
// Approximation of lancos2 without sin() or rcp(), or sqrt() to get x.
// (25/16 * (2/5 * x^2 - 1)^2 - (25/16 - 1)) * (1/4 * x^2 - 1)^2
// |_______________________________________| |_______________|
// base window
// The general form of the 'base' is,
// (a*(b*x^2-1)^2-(a-1))
// Where 'a=1/(2*b-b^2)' and 'b' moves around the negative lobe.
float wB = float(2.0 / 5.0) * d2 + -1.0;
float wA = lob * d2 + -1.0;
wB *= wB;
wA *= wA;
wB = float(25.0 / 16.0) * wB + float(-(25.0 / 16.0 - 1.0));
float w = wB * wA;
// Do weighted average.
aC += c * w;
aW += w;
}
// Accumulate direction and length.
void FsrEasuSet(
inout vec2 dir,
inout float len,
vec2 pp,
#if (FSR_EASU_SIMPLE_ANALYSIS == 1)
float b, float c,
float i, float j, float f, float e,
float k, float l, float h, float g,
float o, float n
#elif (FSR_EASU_SIMPLE_ANALYSIS == 0)
bool biS, bool biT, bool biU, bool biV,
float lA, float lB, float lC, float lD, float lE
#endif
){
// Compute bilinear weight, branches factor out as predicates are compiler time immediates.
// s t
// u v
#if (FSR_EASU_SIMPLE_ANALYSIS == 1)
vec4 w = vec4(0.0);
w.x = (1.0 - pp.x) * (1.0 - pp.y);
w.y = pp.x * (1.0 - pp.y);
w.z = (1.0 - pp.x) * pp.y;
w.w = pp.x * pp.y;
float lA = dot(w, vec4(b, c, f, g));
float lB = dot(w, vec4(e, f, i, j));
float lC = dot(w, vec4(f, g, j, k));
float lD = dot(w, vec4(g, h, k, l));
float lE = dot(w, vec4(j, k, n, o));
#elif (FSR_EASU_SIMPLE_ANALYSIS == 0)
float w = 0.0;
if (biS)
w = (1.0 - pp.x) * (1.0 - pp.y);
if (biT)
w = pp.x * (1.0 - pp.y);
if (biU)
w = (1.0 - pp.x) * pp.y;
if (biV)
w = pp.x * pp.y;
#endif
// Direction is the '+' diff.
// a
// b c d
// e
// Then takes magnitude from abs average of both sides of 'c'.
// Length converts gradient reversal to 0, smoothly to non-reversal at 1, shaped, then adding horz and vert terms.
float dc = lD - lC;
float cb = lC - lB;
float lenX = max(abs(dc), abs(cb));
lenX = APrxLoRcpF1(lenX);
float dirX = lD - lB;
lenX = clamp(abs(dirX) * lenX, 0.0, 1.0);
lenX *= lenX;
// Repeat for the y axis.
float ec = lE - lC;
float ca = lC - lA;
float lenY = max(abs(ec), abs(ca));
lenY = APrxLoRcpF1(lenY);
float dirY = lE - lA;
lenY = clamp(abs(dirY) * lenY, 0.0, 1.0);
lenY *= lenY;
#if (FSR_EASU_SIMPLE_ANALYSIS == 1)
len = lenX + lenY;
dir = vec2(dirX, dirY);
#elif (FSR_EASU_SIMPLE_ANALYSIS == 0)
dir += vec2(dirX, dirY) * w;
len += dot(vec2(w), vec2(lenX, lenY));
#endif
}
vec4 hook() {
// Result
vec4 pix = vec4(0.0, 0.0, 0.0, 1.0);
//------------------------------------------------------------------------------------------------------------------------------
// +---+---+
// | | |
// +--(0)--+
// | b | c |
// +---F---+---+---+
// | e | f | g | h |
// +--(1)--+--(2)--+
// | i | j | k | l |
// +---+---+---+---+
// | n | o |
// +--(3)--+
// | | |
// +---+---+
// Get position of 'F'.
vec2 pp = HOOKED_pos * HOOKED_size - vec2(0.5);
vec2 fp = floor(pp);
pp -= fp;
//------------------------------------------------------------------------------------------------------------------------------
// 12-tap kernel.
// b c
// e f g h
// i j k l
// n o
// Gather 4 ordering.
// a b
// r g
// Allowing dead-code removal to remove the 'z's.
#if (defined(HOOKED_gather) && (__VERSION__ >= 400 || (GL_ES && __VERSION__ >= 310)))
vec4 bczzL = HOOKED_gather(vec2((fp + vec2(1.0, -1.0)) * HOOKED_pt), 0);
vec4 ijfeL = HOOKED_gather(vec2((fp + vec2(0.0, 1.0)) * HOOKED_pt), 0);
vec4 klhgL = HOOKED_gather(vec2((fp + vec2(2.0, 1.0)) * HOOKED_pt), 0);
vec4 zzonL = HOOKED_gather(vec2((fp + vec2(1.0, 3.0)) * HOOKED_pt), 0);
#else
// pre-OpenGL 4.0 compatibility
float b = HOOKED_tex(vec2((fp + vec2(0.5, -0.5)) * HOOKED_pt)).r;
float c = HOOKED_tex(vec2((fp + vec2(1.5, -0.5)) * HOOKED_pt)).r;
float e = HOOKED_tex(vec2((fp + vec2(-0.5, 0.5)) * HOOKED_pt)).r;
float f = HOOKED_tex(vec2((fp + vec2( 0.5, 0.5)) * HOOKED_pt)).r;
float g = HOOKED_tex(vec2((fp + vec2( 1.5, 0.5)) * HOOKED_pt)).r;
float h = HOOKED_tex(vec2((fp + vec2( 2.5, 0.5)) * HOOKED_pt)).r;
float i = HOOKED_tex(vec2((fp + vec2(-0.5, 1.5)) * HOOKED_pt)).r;
float j = HOOKED_tex(vec2((fp + vec2( 0.5, 1.5)) * HOOKED_pt)).r;
float k = HOOKED_tex(vec2((fp + vec2( 1.5, 1.5)) * HOOKED_pt)).r;
float l = HOOKED_tex(vec2((fp + vec2( 2.5, 1.5)) * HOOKED_pt)).r;
float n = HOOKED_tex(vec2((fp + vec2(0.5, 2.5) ) * HOOKED_pt)).r;
float o = HOOKED_tex(vec2((fp + vec2(1.5, 2.5) ) * HOOKED_pt)).r;
vec4 bczzL = vec4(b, c, 0.0, 0.0);
vec4 ijfeL = vec4(i, j, f, e);
vec4 klhgL = vec4(k, l, h, g);
vec4 zzonL = vec4(0.0, 0.0, o, n);
#endif
//------------------------------------------------------------------------------------------------------------------------------
// Rename.
float bL = bczzL.x;
float cL = bczzL.y;
float iL = ijfeL.x;
float jL = ijfeL.y;
float fL = ijfeL.z;
float eL = ijfeL.w;
float kL = klhgL.x;
float lL = klhgL.y;
float hL = klhgL.z;
float gL = klhgL.w;
float oL = zzonL.z;
float nL = zzonL.w;
#if (FSR_PQ == 1)
// Not the most performance-friendly solution, but should work until mpv adds proper gamma transformation functions for shaders
bL = ToGamma2(bL);
cL = ToGamma2(cL);
iL = ToGamma2(iL);
jL = ToGamma2(jL);
fL = ToGamma2(fL);
eL = ToGamma2(eL);
kL = ToGamma2(kL);
lL = ToGamma2(lL);
hL = ToGamma2(hL);
gL = ToGamma2(gL);
oL = ToGamma2(oL);
nL = ToGamma2(nL);
#endif
// Accumulate for bilinear interpolation.
vec2 dir = vec2(0.0);
float len = 0.0;
#if (FSR_EASU_SIMPLE_ANALYSIS == 1)
FsrEasuSet(dir, len, pp, bL, cL, iL, jL, fL, eL, kL, lL, hL, gL, oL, nL);
#elif (FSR_EASU_SIMPLE_ANALYSIS == 0)
FsrEasuSet(dir, len, pp, true, false, false, false, bL, eL, fL, gL, jL);
FsrEasuSet(dir, len, pp, false, true, false, false, cL, fL, gL, hL, kL);
FsrEasuSet(dir, len, pp, false, false, true, false, fL, iL, jL, kL, nL);
FsrEasuSet(dir, len, pp, false, false, false, true, gL, jL, kL, lL, oL);
#endif
//------------------------------------------------------------------------------------------------------------------------------
// Normalize with approximation, and cleanup close to zero.
vec2 dir2 = dir * dir;
float dirR = dir2.x + dir2.y;
bool zro = dirR < float(1.0 / FSR_EASU_DIR_THRESHOLD);
dirR = APrxLoRsqF1(dirR);
#if (FSR_EASU_QUIT_EARLY == 1)
if (zro) {
vec4 w = vec4(0.0);
w.x = (1.0 - pp.x) * (1.0 - pp.y);
w.y = pp.x * (1.0 - pp.y);
w.z = (1.0 - pp.x) * pp.y;
w.w = pp.x * pp.y;
pix.r = clamp(dot(w, vec4(fL, gL, jL, kL)), 0.0, 1.0);
return pix;
}
#elif (FSR_EASU_QUIT_EARLY == 0)
dirR = zro ? 1.0 : dirR;
dir.x = zro ? 1.0 : dir.x;
#endif
dir *= vec2(dirR);
// Transform from {0 to 2} to {0 to 1} range, and shape with square.
len = len * 0.5;
len *= len;
// Stretch kernel {1.0 vert|horz, to sqrt(2.0) on diagonal}.
float stretch = (dir.x * dir.x + dir.y * dir.y) * APrxLoRcpF1(max(abs(dir.x), abs(dir.y)));
// Anisotropic length after rotation,
// x := 1.0 lerp to 'stretch' on edges
// y := 1.0 lerp to 2x on edges
vec2 len2 = vec2(1.0 + (stretch - 1.0) * len, 1.0 + -0.5 * len);
// Based on the amount of 'edge',
// the window shifts from +/-{sqrt(2.0) to slightly beyond 2.0}.
float lob = 0.5 + float((1.0 / 4.0 - 0.04) - 0.5) * len;
// Set distance^2 clipping point to the end of the adjustable window.
float clp = APrxLoRcpF1(lob);
//------------------------------------------------------------------------------------------------------------------------------
// Accumulation
// b c
// e f g h
// i j k l
// n o
float aC = 0.0;
float aW = 0.0;
FsrEasuTap(aC, aW, vec2( 0.0,-1.0) - pp, dir, len2, lob, clp, bL); // b
FsrEasuTap(aC, aW, vec2( 1.0,-1.0) - pp, dir, len2, lob, clp, cL); // c
FsrEasuTap(aC, aW, vec2(-1.0, 1.0) - pp, dir, len2, lob, clp, iL); // i
FsrEasuTap(aC, aW, vec2( 0.0, 1.0) - pp, dir, len2, lob, clp, jL); // j
FsrEasuTap(aC, aW, vec2( 0.0, 0.0) - pp, dir, len2, lob, clp, fL); // f
FsrEasuTap(aC, aW, vec2(-1.0, 0.0) - pp, dir, len2, lob, clp, eL); // e
FsrEasuTap(aC, aW, vec2( 1.0, 1.0) - pp, dir, len2, lob, clp, kL); // k
FsrEasuTap(aC, aW, vec2( 2.0, 1.0) - pp, dir, len2, lob, clp, lL); // l
FsrEasuTap(aC, aW, vec2( 2.0, 0.0) - pp, dir, len2, lob, clp, hL); // h
FsrEasuTap(aC, aW, vec2( 1.0, 0.0) - pp, dir, len2, lob, clp, gL); // g
FsrEasuTap(aC, aW, vec2( 1.0, 2.0) - pp, dir, len2, lob, clp, oL); // o
FsrEasuTap(aC, aW, vec2( 0.0, 2.0) - pp, dir, len2, lob, clp, nL); // n
//------------------------------------------------------------------------------------------------------------------------------
// Normalize and dering.
pix.r = aC / aW;
#if (FSR_EASU_DERING == 1)
float min1 = min(AMin3F1(fL, gL, jL), kL);
float max1 = max(AMax3F1(fL, gL, jL), kL);
pix.r = clamp(pix.r, min1, max1);
#endif
pix.r = clamp(pix.r, 0.0, 1.0);
return pix;
}
//!HOOK LUMA
//!BIND EASUTEX
//!DESC FidelityFX Super Resolution v1.0.2 (RCAS)
//!WIDTH EASUTEX.w
//!HEIGHT EASUTEX.h
//!COMPONENTS 1
// User variables - RCAS
#define SHARPNESS 0.2 // Controls the amount of sharpening. The scale is {0.0 := maximum, to N>0, where N is the number of stops (halving) of the reduction of sharpness}. 0.0 to 2.0.
#define FSR_RCAS_DENOISE 1 // If set to 1, lessens the sharpening on noisy areas. Can be disabled for better performance. 0 or 1.
#define FSR_PQ 0 // Whether the source content has PQ gamma or not. Needs to be set to the same value for both passes. 0 or 1.
// Shader code
#define FSR_RCAS_LIMIT (0.25 - (1.0 / 16.0)) // This is set at the limit of providing unnatural results for sharpening.
float APrxMedRcpF1(float a) {
float b = uintBitsToFloat(uint(0x7ef19fff) - floatBitsToUint(a));
return b * (-b * a + 2.0);
}
float AMax3F1(float x, float y, float z) {
return max(x, max(y, z));
}
float AMin3F1(float x, float y, float z) {
return min(x, min(y, z));
}
#if (FSR_PQ == 1)
float FromGamma2(float a) {
return sqrt(sqrt(a));
}
#endif
vec4 hook() {
// Algorithm uses minimal 3x3 pixel neighborhood.
// b
// d e f
// h
#if (defined(EASUTEX_gather) && (__VERSION__ >= 400 || (GL_ES && __VERSION__ >= 310)))
vec3 bde = EASUTEX_gather(EASUTEX_pos + EASUTEX_pt * vec2(-0.5), 0).xyz;
float b = bde.z;
float d = bde.x;
float e = bde.y;
vec2 fh = EASUTEX_gather(EASUTEX_pos + EASUTEX_pt * vec2(0.5), 0).zx;
float f = fh.x;
float h = fh.y;
#else
float b = EASUTEX_texOff(vec2( 0.0, -1.0)).r;
float d = EASUTEX_texOff(vec2(-1.0, 0.0)).r;
float e = EASUTEX_tex(EASUTEX_pos).r;
float f = EASUTEX_texOff(vec2(1.0, 0.0)).r;
float h = EASUTEX_texOff(vec2(0.0, 1.0)).r;
#endif
// Min and max of ring.
float mn1L = min(AMin3F1(b, d, f), h);
float mx1L = max(AMax3F1(b, d, f), h);
// Immediate constants for peak range.
vec2 peakC = vec2(1.0, -1.0 * 4.0);
// Limiters, these need to be high precision RCPs.
float hitMinL = min(mn1L, e) / (4.0 * mx1L);
float hitMaxL = (peakC.x - max(mx1L, e)) / (4.0 * mn1L + peakC.y);
float lobeL = max(-hitMinL, hitMaxL);
float lobe = max(float(-FSR_RCAS_LIMIT), min(lobeL, 0.0)) * exp2(-clamp(float(SHARPNESS), 0.0, 2.0));
// Apply noise removal.
#if (FSR_RCAS_DENOISE == 1)
// Noise detection.
float nz = 0.25 * b + 0.25 * d + 0.25 * f + 0.25 * h - e;
nz = clamp(abs(nz) * APrxMedRcpF1(AMax3F1(AMax3F1(b, d, e), f, h) - AMin3F1(AMin3F1(b, d, e), f, h)), 0.0, 1.0);
nz = -0.5 * nz + 1.0;
lobe *= nz;
#endif
// Resolve, which needs the medium precision rcp approximation to avoid visible tonality changes.
float rcpL = APrxMedRcpF1(4.0 * lobe + 1.0);
vec4 pix = vec4(0.0, 0.0, 0.0, 1.0);
pix.r = float((lobe * b + lobe * d + lobe * h + lobe * f + e) * rcpL);
#if (FSR_PQ == 1)
pix.r = FromGamma2(pix.r);
#endif
return pix;
}

View File

@@ -0,0 +1,426 @@
// Copyright (C) 2017-2021 igv
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3.0 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this program. If not, see <https://www.gnu.org/licenses/>.
//!HOOK LUMA
//!WHEN OUTPUT.w LUMA.w / 1.300 > OUTPUT.h LUMA.h / 1.300 > *
//!DESC feature map 1
//!BIND LUMA
//!SAVE FEATURE1
//!COMPONENTS 4
vec4 hook()
{
vec4 res = vec4(-0.1572492271661758,-0.0120896836742759,0.0061487639322877,-0.2852848768234253);
res += vec4(-0.0047900392673910,0.0537447109818459,-0.0000247144635068,0.0066653941757977) * float(LUMA_texOff(vec2(-2,-2)));
res += vec4(0.0073144687339664,-0.0309004038572311,-0.0109181385487318,-0.0092840325087309) * float(LUMA_texOff(vec2(-2,-1)));
res += vec4(0.0591700896620750,0.1974907070398331,-0.0197357516735792,-0.0546554848551750) * float(LUMA_texOff(vec2(-2,0)));
res += vec4(-0.0011764382943511,-0.0299451071768999,0.0229587312787771,0.0021908886265010) * float(LUMA_texOff(vec2(-2,1)));
res += vec4(0.0098101310431957,0.0080995410680771,-0.0030452020000666,-0.0132035519927740) * float(LUMA_texOff(vec2(-2,2)));
res += vec4(-0.0168330334126949,-0.0743711441755295,-0.0259261634200811,0.0234480481594801) * float(LUMA_texOff(vec2(-1,-2)));
res += vec4(0.0239933785051107,0.1896541714668274,0.0207756329327822,-0.0370332375168800) * float(LUMA_texOff(vec2(-1,-1)));
res += vec4(0.0094799501821399,-0.0652511194348335,-0.0004292793164495,-0.0726212188601494) * float(LUMA_texOff(vec2(-1,0)));
res += vec4(0.0297284796833992,-0.1210186630487442,-0.0202929321676493,-0.0574462898075581) * float(LUMA_texOff(vec2(-1,1)));
res += vec4(-0.0318185277283192,0.0840775370597839,0.0110451309010386,0.0415569432079792) * float(LUMA_texOff(vec2(-1,2)));
res += vec4(-0.0253141783177853,0.1168256178498268,0.1159729585051537,0.0963164269924164) * float(LUMA_texOff(vec2(0,-2)));
res += vec4(-0.1103615835309029,-0.0276833958923817,-0.4999594092369080,0.1053867191076279) * float(LUMA_texOff(vec2(0,-1)));
res += vec4(1.1100435256958008,0.0646764487028122,0.0154005717486143,0.8891586661338806) * float(LUMA_texOff(vec2(0,0)));
res += vec4(0.1229330673813820,0.1719468832015991,0.5730338096618652,-0.1645544171333313) * float(LUMA_texOff(vec2(0,1)));
res += vec4(-0.0090442728251219,-0.3023961782455444,-0.1589493155479431,0.0418574027717113) * float(LUMA_texOff(vec2(0,2)));
res += vec4(0.0031942036002874,-0.1310926079750061,0.0075543406419456,-0.0016449346439913) * float(LUMA_texOff(vec2(1,-2)));
res += vec4(-0.0995150282979012,-0.0701921209692955,-0.0130895879119635,0.1344170123338699) * float(LUMA_texOff(vec2(1,-1)));
res += vec4(0.0060519003309309,-0.1533465683460236,0.0114194005727768,0.0264683905988932) * float(LUMA_texOff(vec2(1,0)));
res += vec4(0.0244008023291826,0.1881769001483917,-0.0206351149827242,-0.0628309547901154) * float(LUMA_texOff(vec2(1,1)));
res += vec4(0.0075713125988841,0.0508594363927841,0.0430423170328140,-0.0124188791960478) * float(LUMA_texOff(vec2(1,2)));
res += vec4(-0.0166875869035721,-0.0047865519300103,0.0006719123339280,0.0316803231835365) * float(LUMA_texOff(vec2(2,-2)));
res += vec4(-0.0058461269363761,0.0990798473358154,-0.0177743826061487,-0.0066122291609645) * float(LUMA_texOff(vec2(2,-1)));
res += vec4(-0.0972401946783066,-0.0225446373224258,-0.0037693574558944,0.1953062713146210) * float(LUMA_texOff(vec2(2,0)));
res += vec4(-0.0216837190091610,-0.1824268400669098,0.0069816261529922,0.0283037684857845) * float(LUMA_texOff(vec2(2,1)));
res += vec4(-0.0025767991319299,0.0459827110171318,-0.0080216089263558,0.0084134787321091) * float(LUMA_texOff(vec2(2,2)));
return res;
}
//!HOOK LUMA
//!WHEN OUTPUT.w LUMA.w / 1.300 > OUTPUT.h LUMA.h / 1.300 > *
//!DESC feature map 2
//!BIND LUMA
//!SAVE FEATURE2
//!COMPONENTS 4
vec4 hook()
{
vec4 res = vec4(0.0541447550058365,0.0088306749239564,-0.0112389577552676,-0.0127860950306058);
res += vec4(0.0142660010606050,0.0137931071221828,0.0061188107356429,-0.0104134222492576) * float(LUMA_texOff(vec2(-2,-2)));
res += vec4(0.0147292809560895,-0.0289912857115269,0.0266769435256720,0.0933856964111328) * float(LUMA_texOff(vec2(-2,-1)));
res += vec4(-0.1734338253736496,0.1116316691040993,-0.1973157376050949,-0.0581855811178684) * float(LUMA_texOff(vec2(-2,0)));
res += vec4(0.0347507223486900,-0.0341566652059555,0.0061667622067034,0.0075258882716298) * float(LUMA_texOff(vec2(-2,1)));
res += vec4(0.0069884369149804,-0.0194250214844942,0.0080830128863454,-0.0036874092184007) * float(LUMA_texOff(vec2(-2,2)));
res += vec4(0.0233764201402664,0.0344744995236397,0.0162145942449570,0.0979529991745949) * float(LUMA_texOff(vec2(-1,-2)));
res += vec4(0.1280796974897385,-0.1018339172005653,-0.0132977198809385,-0.0019474622095004) * float(LUMA_texOff(vec2(-1,-1)));
res += vec4(0.4286882579326630,0.1222677752375603,0.7046694159507751,0.0945475697517395) * float(LUMA_texOff(vec2(-1,0)));
res += vec4(0.1107441782951355,-0.0134433070197701,-0.0174900908023119,-0.1686445474624634) * float(LUMA_texOff(vec2(-1,1)));
res += vec4(0.0321478620171547,0.0065357843413949,0.0300805997103453,0.0420113280415535) * float(LUMA_texOff(vec2(-1,2)));
res += vec4(-0.1240341588854790,0.0950303301215172,-0.0129648456349969,-0.2681856453418732) * float(LUMA_texOff(vec2(0,-2)));
res += vec4(0.4846960902214050,0.0351924635469913,0.0223043337464333,-0.1273630708456039) * float(LUMA_texOff(vec2(0,-1)));
res += vec4(-1.9379507303237915,-0.2444442063570023,0.0291962660849094,-0.3835578560829163) * float(LUMA_texOff(vec2(0,0)));
res += vec4(0.6396278142929077,-0.0765938311815262,-0.0552659817039967,0.4393545985221863) * float(LUMA_texOff(vec2(0,1)));
res += vec4(-0.1969728022813797,-0.0607173256576061,0.0131113547831774,0.0542017817497253) * float(LUMA_texOff(vec2(0,2)));
res += vec4(0.0091696009039879,-0.0031533432193100,-0.0368777588009834,-0.0459998287260532) * float(LUMA_texOff(vec2(1,-2)));
res += vec4(0.1096992492675781,0.2597902715206146,0.0304869692772627,-0.0195200722664595) * float(LUMA_texOff(vec2(1,-1)));
res += vec4(0.2889648377895355,-0.4275591969490051,-0.7414156794548035,0.2695442438125610) * float(LUMA_texOff(vec2(1,0)));
res += vec4(0.0892018377780914,-0.0229137558490038,0.0244414471089840,-0.1926898956298828) * float(LUMA_texOff(vec2(1,1)));
res += vec4(0.0576358586549759,0.0027846973389387,-0.0036861505359411,-0.0253547113388777) * float(LUMA_texOff(vec2(1,2)));
res += vec4(0.0159624069929123,0.0319602824747562,0.0019470085389912,0.0089780492708087) * float(LUMA_texOff(vec2(2,-2)));
res += vec4(0.0552792511880398,0.0543054342269897,0.0134062822908163,0.0545728243887424) * float(LUMA_texOff(vec2(2,-1)));
res += vec4(-0.1170092225074768,0.1963327825069427,0.1503890156745911,0.1891828328371048) * float(LUMA_texOff(vec2(2,0)));
res += vec4(-0.0084421783685684,0.1297017931938171,-0.0330600887537003,-0.0942063704133034) * float(LUMA_texOff(vec2(2,1)));
res += vec4(0.0118440408259630,-0.0337875857949257,0.0055063469335437,0.0254479162395000) * float(LUMA_texOff(vec2(2,2)));
return res;
}
//!HOOK LUMA
//!WHEN OUTPUT.w LUMA.w / 1.300 > OUTPUT.h LUMA.h / 1.300 > *
//!DESC mapping 1_1
//!BIND FEATURE1
//!BIND FEATURE2
//!SAVE MODEL21
//!COMPONENTS 4
vec4 hook()
{
vec4 res = vec4(-0.0445119962096214,-0.7632357478141785,0.0156328510493040,-0.2424548566341400);
res += mat4(0.1279004216194153,-0.0275541823357344,0.2275633513927460,0.2241709381341934,0.0197204202413559,-0.0456816256046295,-0.1296672523021698,0.0564568229019642,-0.0241488646715879,-0.0237508192658424,-0.1899632662534714,0.4177669584751129,-0.1814560592174530,-0.0526473335921764,0.1154382973909378,-0.0715614855289459) * FEATURE1_texOff(vec2(-1,-1));
res += mat4(-0.0660311505198479,0.0416736751794815,0.3146112561225891,0.1472041457891464,-0.3456672728061676,-0.0055983816273510,0.0022350433282554,0.0819796621799469,0.0057485047727823,0.1532524228096008,0.0204557459801435,-0.2500547170639038,-0.0524359568953514,-0.1911625266075134,-0.1078366711735725,-0.1296254843473434) * FEATURE2_texOff(vec2(-1,-1));
res += mat4(0.0904538556933403,-0.0150672039017081,0.3322310745716095,0.0638923197984695,0.5975797176361084,-0.2452044337987900,-0.4947478473186493,-0.0783191770315170,0.5771877169609070,-0.0870653912425041,-0.8966570496559143,-0.2140965163707733,-0.0493861362338066,-0.0380848757922649,-0.1345319598913193,-0.0186063013970852) * FEATURE1_texOff(vec2(-1,0));
res += mat4(-0.2523841261863708,0.1387074738740921,0.7878478765487671,-0.2251627445220947,0.2277439534664154,0.5417668819427490,0.0866540968418121,-0.1707777529954910,-0.0598246827721596,-0.4717158675193787,-1.2242834568023682,0.0454643070697784,-0.3503442704677582,0.0573085807263851,0.2530198395252228,-0.0207283068448305) * FEATURE2_texOff(vec2(-1,0));
res += mat4(0.0168380383402109,-0.2142438590526581,-0.0207892972975969,0.3628533780574799,0.2431225180625916,0.3098322153091431,0.4073205888271332,-0.2762102782726288,-0.0197229012846947,0.1305596232414246,-0.5697882771492004,-0.2976251542568207,-0.0551432967185974,0.2614036500453949,-0.1410341411828995,-0.2906406223773956) * FEATURE1_texOff(vec2(-1,1));
res += mat4(-0.0498303361237049,0.0224859956651926,0.1952174901962280,-0.0311204437166452,0.2501715123653412,-0.5893352627754211,-1.0793941020965576,0.0160885509103537,0.5081620812416077,0.0482814386487007,0.0546359121799469,-0.0501569248735905,0.1400523334741592,-0.0106841633096337,-0.0940591320395470,-0.1791856139898300) * FEATURE2_texOff(vec2(-1,1));
res += mat4(0.0393299944698811,0.2232691347599030,-0.1055066883563995,-0.1607919186353683,-0.1567825973033905,-0.0042221010662615,-0.0548228211700916,0.2352052628993988,0.1483389288187027,0.7503526806831360,0.0797731876373291,-0.0049001369625330,-0.0242983382195234,-0.0308702979236841,0.0828925222158432,0.0561857633292675) * FEATURE1_texOff(vec2(0,-1));
res += mat4(0.0926392748951912,-0.0418718457221985,-0.3060409128665924,-0.1883587390184402,0.0284292586147785,-0.3584854304790497,-0.7909982800483704,-0.0187337957322598,-0.2496993243694305,-0.7520986795425415,0.3771523833274841,-0.0259053874760866,0.0337998159229755,0.2209153026342392,0.0708771497011185,-0.2814430892467499) * FEATURE2_texOff(vec2(0,-1));
res += mat4(-0.5287809371948242,0.5777525901794434,0.0880500450730324,-0.8452472090721130,-0.3393408954143524,-0.2273543328046799,-0.1298527419567108,0.4990308582782745,1.2613251209259033,-0.7636719942092896,1.5694186687469482,-0.4087363779544830,0.0874531939625740,0.7067158818244934,-0.3419588804244995,-0.3265531957149506) * FEATURE1_texOff(vec2(0,0));
res += mat4(0.8229957222938538,-0.1236215904355049,-0.1859253048896790,1.6684840917587280,0.2000777721405029,-0.1239093989133835,1.5623438358306885,0.1779983490705490,0.1017884835600853,-0.3707404434680939,1.0626678466796875,-0.3124029338359833,0.0659058541059494,-0.3585464656352997,-0.1866402775049210,0.6733445525169373) * FEATURE2_texOff(vec2(0,0));
res += mat4(-0.5544115900993347,-0.1892931908369064,0.2460739761590958,-0.1056193932890892,-0.4318082630634308,0.1257930994033813,-0.2672747671604156,-0.1690235435962677,0.0018221997888759,-0.4397548139095306,-0.3007801771163940,0.1068472340703011,0.3506655991077423,0.1143834441900253,0.1363849341869354,-0.1417382210493088) * FEATURE1_texOff(vec2(0,1));
res += mat4(-0.0505668744444847,0.1831464916467667,0.3957343697547913,-0.2295413911342621,-0.3892803490161896,0.5436951518058777,0.1217770799994469,0.0223295800387859,-0.4462866187095642,-0.4055982232093811,-0.3771279454231262,0.0807068347930908,0.2116729617118835,0.0281026475131512,-0.0229265503585339,0.2868605256080627) * FEATURE2_texOff(vec2(0,1));
res += mat4(0.1962712109088898,-0.2373334914445877,-2.5208437442779541,-0.1988540291786194,0.2224564403295517,-0.1783192902803421,-0.3962321281433105,-0.1685980409383774,0.1910390257835388,0.2554391324520111,0.4586416482925415,0.2779130041599274,-0.2002453953027725,-0.0061091855168343,1.3808131217956543,0.0434907525777817) * FEATURE1_texOff(vec2(1,-1));
res += mat4(-0.0307611189782619,-0.0524470545351505,-0.5897512435913086,-0.0816674903035164,0.4052906930446625,0.2542210817337036,-1.9041002988815308,0.0835462361574173,-0.2484460622072220,-0.0184739269316196,0.4510098397731781,0.2587619423866272,0.1537084281444550,0.1503131389617920,-0.0742949545383453,0.0613216012716293) * FEATURE2_texOff(vec2(1,-1));
res += mat4(0.1772638261318207,0.0948876664042473,0.0083848545327783,-0.2919732332229614,0.2566950321197510,0.0288751143962145,-0.4624863862991333,-0.0608786940574646,0.3310996592044830,-0.0104284398257732,0.6334818005561829,-0.0027201652992517,-0.0342350602149963,0.1938806027173996,-0.2464301586151123,0.0125883584842086) * FEATURE1_texOff(vec2(1,0));
res += mat4(0.4839433431625366,-0.0502159744501114,-1.1114163398742676,-0.3965759575366974,0.2117286175489426,0.0414481423795223,-0.1332397013902664,-0.0549883767962456,-0.1275007277727127,0.7844302654266357,-0.0095163453370333,0.0961041301488876,-0.4759134948253632,-0.4284025132656097,-0.2072399407625198,-0.3953579664230347) * FEATURE2_texOff(vec2(1,0));
res += mat4(0.1605869531631470,-0.1715892106294632,0.0865620598196983,-0.0464400537312031,-0.2688548862934113,0.1722514480352402,0.0167612321674824,-0.0032994034700096,-0.3451044559478760,-0.2280300110578537,-0.0029796555172652,-0.1597652435302734,0.0500137843191624,0.1023071259260178,-0.0407028235495090,0.2228624969720840) * FEATURE1_texOff(vec2(1,1));
res += mat4(0.6999920010566711,0.0839441940188408,0.0815469548106194,-0.1509176045656204,-0.0690853074193001,-0.3200871348381042,0.0780162736773491,-0.1449639797210693,0.2868815064430237,0.3962450027465820,-0.3439113497734070,0.2657423913478851,0.0988137871026993,0.3471299111843109,-0.2186402678489685,-0.0648017078638077) * FEATURE2_texOff(vec2(1,1));
res = max(res, vec4(0.0)) + vec4(1.0311057567596436,0.1051208898425102,0.1158760935068130,0.0466635078191757) * min(res, vec4(0.0));
return res;
}
//!HOOK LUMA
//!WHEN OUTPUT.w LUMA.w / 1.300 > OUTPUT.h LUMA.h / 1.300 > *
//!DESC mapping 1_2
//!BIND FEATURE1
//!BIND FEATURE2
//!SAVE MODEL22
//!COMPONENTS 4
vec4 hook()
{
vec4 res = vec4(0.0713458731770515,-0.1403961777687073,-0.0019562745001167,0.0153338573873043);
res += mat4(-0.0950641855597496,-0.1496641039848328,-0.0653550028800964,0.0655386000871658,-0.0118882004171610,0.2012491524219513,-0.2844599783420563,-0.4794720113277435,0.1128025799989700,-0.0173030979931355,-0.0558849945664406,-0.2957552075386047,0.0128202112391591,0.0199047476053238,-0.0091027505695820,-0.0789640173316002) * FEATURE1_texOff(vec2(-1,-1));
res += mat4(0.1597457975149155,-0.0476507246494293,0.1466529071331024,0.0859163030982018,0.0797316282987595,-0.3380981683731079,0.2370245009660721,-0.1145931258797646,-0.0352988094091415,-0.0444888733327389,-0.2100716233253479,0.1305520236492157,-0.1359029710292816,0.1097442805767059,0.0449938289821148,-0.1155664771795273) * FEATURE2_texOff(vec2(-1,-1));
res += mat4(-0.0333916284143925,0.2415594160556793,0.0520512908697128,0.1228107511997223,-0.0491011217236519,0.4408806562423706,0.4631956815719604,0.2014560103416443,-0.3688595592975616,0.0367180295288563,0.2484581321477890,-0.1113442853093147,0.1283355057239532,0.0418004281818867,-0.0171243026852608,-0.1231943219900131) * FEATURE1_texOff(vec2(-1,0));
res += mat4(0.3493446409702301,0.4550022482872009,0.0368724688887596,0.0748724937438965,0.5001406073570251,0.0145555436611176,0.1236629858613014,0.3143120706081390,-0.1951988488435745,-0.0157914645969868,0.0937998965382576,-0.2233840376138687,0.5033411383628845,-0.3183194100856781,-0.2259195148944855,0.3639536798000336) * FEATURE2_texOff(vec2(-1,0));
res += mat4(-0.0742707476019859,-0.1287801116704941,-0.2533137500286102,0.0666435658931732,-0.0185621567070484,0.1427449285984039,-0.0724751204252243,-0.0781485065817833,-0.2270648330450058,-0.2314778864383698,0.3814929425716400,-0.1655400246381760,0.0408568829298019,-0.1139645278453827,0.1797397136688232,-0.0245632305741310) * FEATURE1_texOff(vec2(-1,1));
res += mat4(0.1184135973453522,0.0439366139471531,0.0225226897746325,-0.0038526873104274,0.1292685419321060,0.0629177838563919,0.3455114960670471,-0.1857204884290695,-0.4921502172946930,-0.1171003505587578,0.0188624169677496,-0.1101682260632515,0.0676844567060471,0.5154085755348206,-0.0898379907011986,0.3413280248641968) * FEATURE2_texOff(vec2(-1,1));
res += mat4(-0.2631838321685791,0.0215514600276947,0.3092688918113708,-0.0200904365628958,0.0678770467638969,0.1769931465387344,-0.3653681278228760,-0.3274513185024261,0.4608019888401031,-0.1544784456491470,0.1189439669251442,0.7015876173973083,0.2732816934585571,-0.0545057803392410,-0.3474545478820801,-0.0253226496279240) * FEATURE1_texOff(vec2(0,-1));
res += mat4(0.0994316861033440,0.0642566010355949,0.2031503319740295,0.2276959568262100,-0.1094077304005623,0.4463521838188171,0.0921792611479759,-0.3033096492290497,-0.0953373983502388,-0.1331395804882050,0.2615413069725037,-0.2874414622783661,-0.0389687754213810,0.0338272154331207,0.2804331183433533,-0.3443813025951385) * FEATURE2_texOff(vec2(0,-1));
res += mat4(-0.1806042939424515,-0.4840798676013947,0.4222546219825745,0.1238701492547989,0.0117481639608741,-0.5986865758895874,0.3057619929313660,0.1934896260499954,-0.7086342573165894,-0.8567376136779785,0.6944998502731323,-1.4599204063415527,0.0886754393577576,-0.4293498098850250,-0.1524195969104767,0.2418079674243927) * FEATURE1_texOff(vec2(0,0));
res += mat4(2.1706113815307617,0.3525652289390564,-0.7008359432220459,-0.4825965166091919,-0.3203429281711578,0.8500943183898926,-0.7993509769439697,0.4329842329025269,0.2106771767139435,1.1103280782699585,1.2092385292053223,1.4814503192901611,-0.4147390127182007,-0.7046836614608765,-0.1443170011043549,-0.6811133027076721) * FEATURE2_texOff(vec2(0,0));
res += mat4(-0.1489356607198715,0.1400019824504852,0.2425604313611984,-0.2098473459482193,-0.1580564379692078,0.1463224738836288,-0.2187854647636414,0.5174596905708313,-0.0143817225471139,-0.0362622961401939,-0.0068237944506109,0.4749472737312317,0.2914732992649078,-0.3306328952312469,-0.2444777786731720,-0.1171946674585342) * FEATURE1_texOff(vec2(0,1));
res += mat4(0.0455239675939083,0.3496046066284180,0.1297491937875748,-0.2541095912456512,0.3605501055717468,0.2339573651552200,-0.0188565086573362,-0.0526181310415268,0.1471424549818039,0.8212822079658508,0.0819099843502045,-0.0851665437221527,0.3739568293094635,0.1304695755243301,0.1481167376041412,-0.2134698331356049) * FEATURE2_texOff(vec2(0,1));
res += mat4(-0.2076720446348190,-0.0932599306106567,0.0648527294397354,-0.2374770641326904,-0.0927826911211014,0.1848200261592865,0.4131188094615936,0.3280069231987000,-0.2099185734987259,0.2130926996469498,-0.0362745784223080,0.0191331822425127,0.1590368449687958,0.0303016249090433,0.1207325309514999,0.2451425045728683) * FEATURE1_texOff(vec2(1,-1));
res += mat4(-0.0135009605437517,-0.0101303057745099,0.0752487555146217,0.0533373840153217,-0.0253537259995937,0.1318614929914474,-0.1263181120157242,0.0249524712562561,-0.1477261483669281,0.3236559033393860,0.0773291289806366,-0.1439673304557800,-0.2005890905857086,0.0892757251858711,0.0398719944059849,0.3675192892551422) * FEATURE2_texOff(vec2(1,-1));
res += mat4(-0.0193535499274731,-0.2256918102502823,0.0341436080634594,0.0795947611331940,0.1496857404708862,-0.2784725725650787,-0.0582313314080238,-0.2786065340042114,-0.1666128039360046,-0.6534121036529541,0.2695854306221008,-0.0179719906300306,0.0015976354479790,0.0139929885044694,-0.1706486046314240,-0.3274765610694885) * FEATURE1_texOff(vec2(1,0));
res += mat4(-0.7170836329460144,0.0868831276893616,0.1829078495502472,-0.0076045366004109,0.1525912433862686,-0.2558896839618683,0.0893209800124168,-0.3426039516925812,-0.2871107757091522,-0.2445062994956970,0.1676304638385773,0.2116415053606033,0.0883995518088341,-0.3880331516265869,0.2636835277080536,-0.2514505982398987) * FEATURE2_texOff(vec2(1,0));
res += mat4(-0.1861270815134048,0.2000686377286911,-0.1501186788082123,0.1525203883647919,0.1969228833913803,0.1174068301916122,-0.1281060427427292,-0.0854888409376144,0.0290613435208797,-0.0538076497614384,-0.0251582786440849,0.0692845508456230,0.0384319014847279,0.2888138592243195,0.1151804402470589,0.0990421250462532) * FEATURE1_texOff(vec2(1,1));
res += mat4(-0.0344385802745819,0.1270371377468109,0.0922426953911781,-0.0426749102771282,-0.1656492203474045,-0.3273328542709351,-0.0282224025577307,0.1099396124482155,-0.1113230437040329,0.2943290174007416,-0.2181112915277481,-0.3177657723426819,-0.1096536740660667,-0.0508293099701405,-0.0256164856255054,-0.0388228967785835) * FEATURE2_texOff(vec2(1,1));
res = max(res, vec4(0.0)) + vec4(0.7142407894134521,0.0686190053820610,0.3999933302402496,-1.0247212648391724) * min(res, vec4(0.0));
return res;
}
//!HOOK LUMA
//!WHEN OUTPUT.w LUMA.w / 1.300 > OUTPUT.h LUMA.h / 1.300 > *
//!DESC mapping 2_1
//!BIND MODEL21
//!BIND MODEL22
//!SAVE MODEL1
//!COMPONENTS 4
vec4 hook()
{
vec4 res = vec4(0.0203563515096903,0.1902436912059784,-0.0757935121655464,0.0393617525696754);
res += mat4(-0.1080558672547340,-0.0400269515812397,0.1042881682515144,-0.1994346678256989,0.0172465778887272,-0.0829331055283546,-0.1278677284717560,-0.0762506872415543,-0.0593080408871174,-0.0305212251842022,0.1326192617416382,-0.3380933105945587,-0.0722763314843178,-0.1975518912076950,-0.0223602931946516,0.2251029163599014) * MODEL21_texOff(vec2(-1,-1));
res += mat4(0.1747678220272064,0.0297168865799904,0.1054855734109879,0.0803295820951462,-0.0338115766644478,-0.3885377943515778,-0.3540246784687042,-0.0719623491168022,-0.0656022280454636,-0.0469004511833191,0.1379419565200806,0.0319863893091679,0.0799935683608055,-0.0099127553403378,0.1698455959558487,-0.0108015276491642) * MODEL22_texOff(vec2(-1,-1));
res += mat4(0.1587898135185242,0.3995443880558014,-0.0333226583898067,0.2373267263174057,-0.1616930961608887,0.0659186244010925,0.0141129801049829,-0.0541022196412086,-0.5743742585182190,0.1121487766504288,0.4259817600250244,0.0280795227736235,-0.3721714317798615,-0.3496374189853668,0.0997273251414299,-0.0079920450225472) * MODEL21_texOff(vec2(-1,0));
res += mat4(0.0928084030747414,0.3107658624649048,0.1375299990177155,0.1550617516040802,-0.0780353918671608,-0.0102957757189870,-0.2056752145290375,-0.3927979469299316,-1.2112152576446533,0.0213295854628086,0.1396545022726059,0.0492016039788723,-0.0569122135639191,-0.1691886335611343,-0.1535325646400452,0.2800904810428619) * MODEL22_texOff(vec2(-1,0));
res += mat4(0.2494744062423706,-0.0363066755235195,0.0959179550409317,-0.0048101749271154,-0.0195793900638819,0.0451166369020939,0.1470773071050644,-0.0050059854984283,0.2886958122253418,-0.3221147954463959,-0.7062104344367981,0.1646659970283508,-0.0092520527541637,-0.1254461258649826,0.0217506736516953,-0.0678806379437447) * MODEL21_texOff(vec2(-1,1));
res += mat4(-0.0686557441949844,-0.0414490625262260,-0.1855954080820084,0.0264346338808537,-0.0296857114881277,-0.0431593284010887,0.0669397041201591,-0.0946076661348343,-0.2036914378404617,-0.1336101740598679,-0.2099903970956802,-0.1327936947345734,-0.1002155169844627,-0.0368575826287270,-0.1660962998867035,0.0728288888931274) * MODEL22_texOff(vec2(-1,1));
res += mat4(0.5504320859909058,0.2939232587814331,0.4704743027687073,0.2129514217376709,0.0843106731772423,-0.1978624463081360,-0.3298224806785583,0.1919094175100327,0.1980742365121841,-0.0644423812627792,0.0091170109808445,-0.2124856859445572,0.0804558470845222,-0.1130188927054405,-0.6276652812957764,0.1861163526773453) * MODEL21_texOff(vec2(0,-1));
res += mat4(-0.3357668519020081,0.2093413323163986,0.4355416595935822,0.1550502777099609,-0.6510964035987854,-0.1751857399940491,-0.2060168534517288,-0.1710205078125000,-0.1202360317111015,-0.2500316798686981,0.1074745431542397,-0.2418434321880341,0.0133954072371125,-0.0555886104702950,0.1514673978090286,0.2739115655422211) * MODEL22_texOff(vec2(0,-1));
res += mat4(-0.3006273508071899,-0.2699472010135651,-0.1982013583183289,-0.0032952548936009,0.0307833012193441,0.3671586215496063,-0.0966020002961159,-0.2836556434631348,0.4297264218330383,0.6171903610229492,0.6723483800888062,0.2705117464065552,-0.1438141316175461,-0.0873940736055374,-0.7001031041145325,-0.2052250355482101) * MODEL21_texOff(vec2(0,0));
res += mat4(-0.2875024676322937,-1.6230558156967163,-0.6733398437500000,-0.9642448425292969,-0.1964960694313049,0.2485812455415726,0.1236900389194489,-1.1423941850662231,-0.0412602946162224,0.3412002623081207,0.3962794244289398,-0.2490761876106262,-0.0058065578341484,-0.4578708708286285,-0.2418260127305984,0.5357795953750610) * MODEL22_texOff(vec2(0,0));
res += mat4(0.0062361713498831,0.1925230026245117,0.0824977159500122,0.0561275146901608,0.0929671525955200,0.0698546022176743,0.3816939592361450,0.0395248420536518,-0.0719512030482292,0.0564917400479317,-0.1297784000635147,0.1245511695742607,0.0012355837970972,-0.0990515723824501,0.4213519692420959,-0.1645816713571548) * MODEL21_texOff(vec2(0,1));
res += mat4(-0.0611936338245869,-0.0220258161425591,-0.0040935277938843,-0.1060328409075737,-0.0583154149353504,-0.0171997752040625,0.1058546081185341,0.2793170809745789,-0.2339317053556442,-0.1972009539604187,-0.0600687190890312,-0.0684379041194916,0.0243016034364700,-0.2111079394817352,-0.2042971849441528,0.0724857896566391) * MODEL22_texOff(vec2(0,1));
res += mat4(-0.0833447948098183,-0.0533220991492271,0.0767802372574806,0.1182348504662514,-0.0223299078643322,-0.0479344800114632,-0.0119727496057749,0.0524821877479553,-0.0334780365228653,0.0719002187252045,0.0439689308404922,0.0475181229412556,0.0764308497309685,0.0086713796481490,-0.1700707823038101,0.0657354295253754) * MODEL21_texOff(vec2(1,-1));
res += mat4(0.1391696482896805,0.0739523395895958,0.0565792545676231,-0.0430364646017551,0.0943084582686424,0.0102064209058881,0.0120795257389545,-0.0841303989291191,0.1573246121406555,0.0164279472082853,0.0988841354846954,-0.1430613398551941,-0.0572808869183064,-0.0844292491674423,0.0621565617620945,0.0923799052834511) * MODEL22_texOff(vec2(1,-1));
res += mat4(-0.1223107874393463,-0.2441930323839188,-0.2410650849342346,-0.0162935722619295,0.0695567727088928,-0.0028583710081875,-0.0059417244046926,0.0715164169669151,-0.0668491795659065,-0.1499572396278381,0.0869924053549767,0.0553652904927731,0.2729566097259521,0.1370039582252502,-0.1282183527946472,-0.1451860070228577) * MODEL21_texOff(vec2(1,0));
res += mat4(0.1331952214241028,0.0021079662255943,-0.1116734445095062,-0.4168601930141449,0.0534659475088120,0.0037860786542296,-0.0366065911948681,0.1047701835632324,0.1491260826587677,0.0782341659069061,0.0949895009398460,-0.1160908639431000,-0.1057133302092552,-0.2699718773365021,-0.1193305626511574,0.2142304331064224) * MODEL22_texOff(vec2(1,0));
res += mat4(0.0041565205901861,-0.1065499857068062,-0.0629659667611122,-0.1144768893718719,0.0318886637687683,-0.0562519319355488,0.0043422472663224,0.0226082988083363,-0.1456198990345001,-0.2398656159639359,-0.2625046670436859,-0.0710547044873238,0.0067904205061495,0.0018544088816270,0.1019348874688148,-0.0186133962124586) * MODEL21_texOff(vec2(1,1));
res += mat4(0.0732532218098640,0.1516859829425812,0.0580205544829369,0.1968977004289627,-0.0066619524732232,-0.1597842127084732,-0.0990600511431694,-0.1059188917279243,0.0718481168150902,-0.2222738713026047,-0.1675696671009064,-0.1500017195940018,-0.0568779110908508,-0.0582777932286263,-0.0844587534666061,-0.0263266414403915) * MODEL22_texOff(vec2(1,1));
res = max(res, vec4(0.0)) + vec4(-0.2459529191255569,0.7563464641571045,-0.0705636814236641,-0.0094820559024811) * min(res, vec4(0.0));
return res;
}
//!HOOK LUMA
//!WHEN OUTPUT.w LUMA.w / 1.300 > OUTPUT.h LUMA.h / 1.300 > *
//!DESC mapping 2_2
//!BIND MODEL21
//!BIND MODEL22
//!SAVE MODEL2
//!COMPONENTS 4
vec4 hook()
{
vec4 res = vec4(-0.0448397286236286,-0.1649267971515656,-0.1192543581128120,-0.0061073559336364);
res += mat4(0.0724840760231018,-0.0480341166257858,-0.1082391515374184,-0.1447021961212158,0.0723197236657143,0.0481830574572086,0.0009448126656935,0.0353565886616707,-0.0653375908732414,0.0029647622723132,-0.0016588598955423,-0.2075651884078979,0.0403469167649746,0.3929971158504486,0.0342363268136978,0.1427230089902878) * MODEL21_texOff(vec2(-1,-1));
res += mat4(-0.0743464827537537,0.1844420731067657,0.0256296340376139,-0.2808582782745361,0.0351609662175179,0.3277008235454559,-0.0205841138958931,-0.5355809330940247,0.0681906566023827,0.2058052271604538,-0.0479847639799118,-0.3735262751579285,-0.0261550359427929,-0.1148884072899818,-0.2329017966985703,0.0728458985686302) * MODEL22_texOff(vec2(-1,-1));
res += mat4(-0.1236097738146782,0.1251334398984909,-0.1339431256055832,0.0198749266564846,-0.1325920224189758,-2.2431972026824951,-0.0680834427475929,-0.5671764612197876,-0.3431925177574158,-0.0983135104179382,-0.2207138091325760,-0.2374879121780396,0.0127309206873178,1.3076044321060181,0.0848151743412018,-0.1928595900535583) * MODEL21_texOff(vec2(-1,0));
res += mat4(-0.0471093133091927,-0.1513628512620926,-0.0134263765066862,-0.1519252359867096,-0.5260242223739624,0.2291621714830399,0.4088975787162781,-0.4315340518951416,0.0933236032724380,-1.0386694669723511,0.0015958193689585,-0.2737887501716614,-0.0246253963559866,-0.2722961604595184,-0.1770633459091187,-0.2291279733181000) * MODEL22_texOff(vec2(-1,0));
res += mat4(-0.0017552347853780,0.1903935521841049,-0.0740704238414764,-0.0917679518461227,0.0323882810771465,-0.3029108047485352,0.0532565414905548,-0.0651542618870735,0.4868686199188232,0.8539272546768188,0.4151960313320160,0.2619662582874298,-0.0413270294666290,0.1404227763414383,0.1027320474386215,0.3274228572845459) * MODEL21_texOff(vec2(-1,1));
res += mat4(0.1828346252441406,0.0274682324379683,-0.1169882863759995,0.0327291004359722,0.1786244213581085,-0.6569546461105347,-0.0609031207859516,-0.1676601022481918,-0.1481092721223831,0.2889067530632019,0.1246089115738869,0.2203597426414490,-0.0366856977343559,0.1539470851421356,0.0069492300972342,-0.1544002443552017) * MODEL22_texOff(vec2(-1,1));
res += mat4(0.2073992937803268,-0.0717074573040009,-0.0196173377335072,-0.0956910699605942,0.0728898122906685,0.0484567955136299,0.3063069283962250,-0.3200540542602539,0.0291527546942234,-0.0265460256487131,0.1168476045131683,-0.2479970753192902,0.1224220171570778,0.0745823010802269,0.1868897676467896,-0.1958049237728119) * MODEL21_texOff(vec2(0,-1));
res += mat4(0.0019954447634518,-0.0225235987454653,0.0812198966741562,0.0295672398060560,-0.2016931176185608,-0.2239151000976562,-0.2481262385845184,-0.2381946444511414,-0.0520484372973442,-0.1200495883822441,0.2121954560279846,-0.1573531329631805,-0.0198472067713737,0.1001087054610252,-0.1084884032607079,-0.3126969039440155) * MODEL22_texOff(vec2(0,-1));
res += mat4(0.3838330209255219,0.1678779572248459,0.6496244072914124,0.3783606290817261,-0.2198582738637924,-0.2351343184709549,-0.2852248847484589,0.6310021877288818,0.8083020448684692,0.0039323624223471,-0.0901831910014153,0.0797894075512886,-0.2271467447280884,0.7082978487014771,0.1513756662607193,0.2188975960016251) * MODEL21_texOff(vec2(0,0));
res += mat4(-0.2871031761169434,0.2316448241472244,0.4947948157787323,0.3308620452880859,-0.0623455122113228,-0.1314185708761215,-0.2664661705493927,0.8725078701972961,0.4541083276271820,0.1433589160442352,-1.1269453763961792,0.6427971124649048,-0.1016561388969421,0.3418317139148712,-0.0991155728697777,-1.0508837699890137) * MODEL22_texOff(vec2(0,0));
res += mat4(-0.2179604172706604,0.1258949041366577,-0.1155700981616974,-0.0536149404942989,-0.0140614463016391,-0.0091438721865416,-0.0501774959266186,-0.3570724725723267,-0.5832386016845703,0.2004123181104660,0.2986239194869995,-0.8139168024063110,0.0142666567116976,0.0681498944759369,0.1293468028306961,-0.1001938357949257) * MODEL21_texOff(vec2(0,1));
res += mat4(0.1952836811542511,-0.3092494010925293,0.3063779771327972,0.1934849917888641,0.0746696740388870,-0.3533902466297150,-0.1269576102495193,-0.2237875163555145,0.2470717132091522,-0.2640363574028015,-0.2862776815891266,0.1740108281373978,-0.0963631942868233,0.2631850540637970,0.0400718413293362,-0.3590607047080994) * MODEL22_texOff(vec2(0,1));
res += mat4(-0.5299927592277527,0.0979989692568779,0.1666737496852875,-0.1547524333000183,-0.0043443185277283,0.1540203243494034,0.0594348423182964,-0.0167275425046682,-0.1043610796332359,0.0504250898957253,0.0456700921058655,0.2525034546852112,0.2241353541612625,-0.1678503304719925,0.1532667279243469,0.2901742458343506) * MODEL21_texOff(vec2(1,-1));
res += mat4(0.0998796448111534,0.0385462641716003,-0.0762400180101395,-0.1255892217159271,0.0281430184841156,-0.0304958485066891,-0.1440480053424835,-0.1001605167984962,-0.2257689833641052,0.2056092917919159,0.0248535349965096,-0.1383949518203735,-0.0951708629727364,0.0997417271137238,0.0275330394506454,-0.5728432536125183) * MODEL22_texOff(vec2(1,-1));
res += mat4(0.4256163835525513,0.1745115518569946,-0.2409395426511765,0.3139856457710266,-0.0036795330233872,0.1819283962249756,-0.0864531323313713,0.0102691333740950,-0.3397279977798462,0.1107075437903404,-0.0035228815395385,-0.2207705229520798,-0.1779139339923859,-0.2106117755174637,0.0352664291858673,0.3615589439868927) * MODEL21_texOff(vec2(1,0));
res += mat4(-0.0345224253833294,-0.0669926702976227,0.0907212942838669,-0.3758732676506042,-0.0452554710209370,-0.1134464666247368,-0.0358871109783649,-0.1858227252960205,-0.0233245138078928,-0.0495684742927551,0.1976234614849091,-0.1165761798620224,-0.0340447537600994,0.1095624342560768,0.0110175255686045,-0.8269239664077759) * MODEL22_texOff(vec2(1,0));
res += mat4(-0.1379280686378479,0.1004267781972885,0.0723998174071312,-0.1510958224534988,0.0610648579895496,0.0451720170676708,-0.0231927260756493,-0.0251553766429424,0.2306085377931595,0.1033207178115845,-0.1316205114126205,0.1130664870142937,-0.0458516106009483,-0.1152514070272446,-0.0088650323450565,-0.0214479379355907) * MODEL21_texOff(vec2(1,1));
res += mat4(-0.0545783303678036,-0.0620098188519478,0.0347074456512928,0.1096799224615097,0.0036664425861090,-0.0413107499480247,0.1443250179290771,-0.1161036714911461,-0.0061624986119568,-0.0252977479249239,0.3230019211769104,-0.2536626160144806,-0.0565439648926258,0.0827583819627762,-0.0071726376190782,-0.1983329951763153) * MODEL22_texOff(vec2(1,1));
res = max(res, vec4(0.0)) + vec4(-0.6312188506126404,-0.1215368881821632,0.2487443536520004,0.4051703512668610) * min(res, vec4(0.0));
return res;
}
//!HOOK LUMA
//!WHEN OUTPUT.w LUMA.w / 1.300 > OUTPUT.h LUMA.h / 1.300 > *
//!DESC mapping 3_1
//!BIND MODEL1
//!BIND MODEL2
//!SAVE MODEL21
//!COMPONENTS 4
vec4 hook()
{
vec4 res = vec4(-0.0410279631614685,-0.1111723631620407,-0.0406232848763466,-0.0939496159553528);
res += mat4(0.1221675798296928,0.0083215842023492,-0.0162804014980793,0.0316714197397232,-0.2205813378095627,0.1500435769557953,0.2109555304050446,0.2741867899894714,0.0956874340772629,-0.0896854698657990,-0.1657065600156784,-0.1349759399890900,0.0601499564945698,-0.1523845940828323,-0.1828087568283081,-0.2727653682231903) * MODEL1_texOff(vec2(-1,-1));
res += mat4(-0.0918163508176804,0.1564485579729080,0.1133174449205399,0.2215953171253204,-0.0623677000403404,-0.0497728772461414,-0.0372809022665024,-0.0258478187024593,-0.1364922970533371,0.1053884625434875,0.3292874991893768,0.2693256139755249,-0.0347631797194481,-0.1470523178577423,0.0096792401745915,-0.0542853325605392) * MODEL2_texOff(vec2(-1,-1));
res += mat4(0.1331177949905396,-0.0964357852935791,-0.0706946700811386,0.1593225002288818,-0.4815943241119385,0.1224092170596123,-0.0870430991053581,0.0005010276800022,-0.0242684502154589,-0.2256436049938202,0.1367238312959671,0.0474774017930031,0.6886650323867798,-0.0065326127223670,0.1841574758291245,-0.1354993879795074) * MODEL1_texOff(vec2(-1,0));
res += mat4(-0.1049591675400734,0.0515934228897095,0.1128631457686424,0.1688040047883987,-0.0084041170775890,-0.0006375144002959,-0.0598374009132385,0.1424416452646255,-0.0048398924991488,0.1832167655229568,0.0231959503144026,0.0816788375377655,-0.1321710795164108,0.0397678017616272,-0.0058345394209027,0.5784573554992676) * MODEL2_texOff(vec2(-1,0));
res += mat4(0.1438693851232529,-0.0694608166813850,-0.0428275354206562,0.1599996536970139,-0.1651254445314407,0.1388883888721466,-0.0895452573895454,0.2569831907749176,0.3150432109832764,-0.0910519883036613,0.0367441214621067,0.1903669685125351,0.2805841267108917,-0.0444608181715012,0.0059385276399553,-0.2585869431495667) * MODEL1_texOff(vec2(-1,1));
res += mat4(-0.1217494234442711,0.0191769022494555,-0.0065453462302685,0.1391217857599258,0.0998920649290085,-0.0162798929959536,0.0502282194793224,0.0370145924389362,0.0290782172232866,-0.0099554909393191,0.0142515478655696,0.1248661577701569,-0.0076912571676075,0.0251651499420404,0.2190572917461395,0.0020069130696356) * MODEL2_texOff(vec2(-1,1));
res += mat4(0.2666685581207275,-0.1625511497259140,-0.3938800692558289,-0.0253848694264889,0.0987015441060066,0.2033616453409195,0.3128099143505096,0.4608893990516663,0.0620003379881382,-0.1389972567558289,-0.3095863461494446,-0.4023511111736298,-0.1105777546763420,0.1115406602621078,0.3639950752258301,0.0645622834563255) * MODEL1_texOff(vec2(0,-1));
res += mat4(-0.2135885655879974,-0.1035343706607819,0.1795026361942291,0.1828210204839706,0.0780984908342361,0.0656728670001030,0.0033678691834211,0.1361345648765564,0.1712654232978821,-0.0172833092510700,-0.0502183400094509,0.2910411655902863,0.0691247656941414,0.1935720741748810,0.0652214139699936,0.1608240753412247) * MODEL2_texOff(vec2(0,-1));
res += mat4(0.8243460655212402,-0.0979344248771667,-0.0366373993456364,0.1692261099815369,0.5517869591712952,0.3282494544982910,-0.7905511856079102,-0.4462923705577850,-0.0803156569600105,0.1172509342432022,0.1864327639341354,0.1471016854047775,0.1296005547046661,-0.1004103720188141,0.3174172043800354,-0.1181766316294670) * MODEL1_texOff(vec2(0,0));
res += mat4(0.0259374529123306,-0.0934808850288391,0.3008874654769897,0.3957927823066711,-0.4048821926116943,0.1461934000253677,-0.1819096356630325,-0.1908810287714005,0.3193186521530151,-0.7438099980354309,0.1919509470462799,-0.2065188735723495,0.1752236187458038,-0.6840037107467651,0.1588519066572189,-0.3956064879894257) * MODEL2_texOff(vec2(0,0));
res += mat4(0.1574442386627197,-0.0114925103262067,-0.1208277940750122,0.2058266401290894,0.2879209220409393,-0.0419875606894493,-0.1902059614658356,-0.2723863720893860,-0.1086223348975182,-0.0870924964547157,0.8605937957763672,0.2656622231006622,-0.1653763055801392,0.0816384851932526,-0.0137870563194156,0.1433854848146439) * MODEL1_texOff(vec2(0,1));
res += mat4(-0.1565909236669540,-0.0307490080595016,-0.1055604666471481,0.2573592662811279,-0.1186821162700653,0.1141471788287163,-0.0272745657712221,-0.1049114838242531,0.2445316016674042,-0.0027864547446370,-0.1759569346904755,-0.1556979566812515,0.0550616309046745,0.1704383641481400,0.0853662937879562,0.3280856907367706) * MODEL2_texOff(vec2(0,1));
res += mat4(0.1460669338703156,0.4202052652835846,-0.3638312816619873,-0.0958623066544533,-0.0492525361478329,-0.3664234280586243,0.0794373303651810,0.0399017669260502,0.0629198029637337,0.1662959158420563,-0.1001493930816650,-0.0587460733950138,-0.0396478697657585,0.0017320754704997,0.0314909480512142,-0.0202700830996037) * MODEL1_texOff(vec2(1,-1));
res += mat4(-0.0964399129152298,0.0380319654941559,0.0396055467426777,0.0265473183244467,-0.0161637403070927,-0.1872924566268921,0.1670000404119492,0.0029466480482370,-0.1093841269612312,-0.3629201948642731,-0.0562992505729198,0.1792684197425842,-0.0203859098255634,0.0983991250395775,0.0058611719869077,0.1627455651760101) * MODEL2_texOff(vec2(1,-1));
res += mat4(-0.1117974221706390,0.7562329173088074,-0.2046248912811279,0.1677842289209366,-0.2063486129045486,-0.6023545265197754,-0.5739209651947021,0.5110496878623962,-0.0715268924832344,-0.1373793482780457,0.1251420378684998,-0.0477442294359207,0.4961377978324890,0.2688887119293213,0.3146316707134247,-0.5197153687477112) * MODEL1_texOff(vec2(1,0));
res += mat4(-0.1314805448055267,0.0746279135346413,0.3457699418067932,0.2564856410026550,0.0839370116591454,-0.6136511564254761,-0.4646295011043549,0.0612256154417992,-0.1910563558340073,-0.0935136750340462,-0.2426030039787292,0.2102959007024765,0.1575350016355515,0.6145061254501343,0.3368154168128967,-0.0974092856049538) * MODEL2_texOff(vec2(1,0));
res += mat4(0.0565315335988998,0.2393359094858170,-0.0932938233017921,0.1555283814668655,0.0123879108577967,-0.1247719228267670,-0.0564610138535500,-0.1125799044966698,-0.0104600470513105,0.0482629500329494,0.2316472232341766,0.1083717569708824,-0.0525921434164047,0.0643989592790604,-0.0525734610855579,-0.0503251366317272) * MODEL1_texOff(vec2(1,1));
res += mat4(-0.1835366338491440,0.0978360474109650,-0.1111819595098495,0.2109299153089523,0.0509372949600220,-0.1992686837911606,0.0677929744124413,-0.0870024710893631,-0.0412262082099915,-0.0697719156742096,-0.0967373847961426,0.0137308547273278,0.0195730421692133,0.0410240143537521,0.1157210171222687,0.2283479571342468) * MODEL2_texOff(vec2(1,1));
res = max(res, vec4(0.0)) + vec4(0.1991519331932068,-0.1275756657123566,-0.0622864030301571,0.1586369574069977) * min(res, vec4(0.0));
return res;
}
//!HOOK LUMA
//!WHEN OUTPUT.w LUMA.w / 1.300 > OUTPUT.h LUMA.h / 1.300 > *
//!DESC mapping 3_2
//!BIND MODEL1
//!BIND MODEL2
//!SAVE MODEL22
//!COMPONENTS 4
vec4 hook()
{
vec4 res = vec4(-0.0089084329083562,-0.0336172059178352,0.0177190825343132,0.0529975406825542);
res += mat4(-0.0275970958173275,0.0141968233510852,0.1181544512510300,-0.0572245270013809,0.1161347925662994,-0.1156444773077965,-0.2549640238285065,0.0882879272103310,-0.0715355500578880,0.0151285668835044,0.1079384386539459,0.0650847703218460,-0.1597152203321457,0.0669793561100960,0.2084401696920395,-0.0951152443885803) * MODEL1_texOff(vec2(-1,-1));
res += mat4(0.0404323227703571,-0.0206144321709871,-0.1080420613288879,-0.2038477361202240,0.0248847268521786,-0.0064681121148169,0.0389525443315506,0.0011026862775907,0.0885242074728012,0.0295896343886852,-0.3323790132999420,0.1935138553380966,-0.0466548874974251,0.1023886054754257,0.1257870644330978,-0.1541756242513657) * MODEL2_texOff(vec2(-1,-1));
res += mat4(-0.0076520540751517,0.0361139886081219,0.1749804913997650,-0.2051989138126373,0.0022692133206874,-0.0282937753945589,-0.2039019316434860,-0.2343468815088272,-0.0357327871024609,-0.0570764988660812,0.2925858795642853,-0.1988349705934525,-0.0584560707211494,-0.0341510921716690,0.1300961822271347,0.5184492468833923) * MODEL1_texOff(vec2(-1,0));
res += mat4(0.0884973928332329,0.0333527140319347,0.0180535931140184,-0.2655122876167297,0.0433661043643951,0.0104369185864925,0.0010909073753282,-0.0705273598432541,-0.0602585524320602,0.2420269846916199,-0.4731841087341309,-0.8040290474891663,0.3066828548908234,-0.2466925680637360,0.0938910692930222,-0.2002603262662888) * MODEL2_texOff(vec2(-1,0));
res += mat4(0.0549152903258801,0.0291299298405647,0.0946277007460594,-0.0581608228385448,0.0669180899858475,-0.0635575056076050,-0.2427970170974731,-0.2677550315856934,0.2226776182651520,0.1301570236682892,-0.1519709974527359,0.0671724304556847,-0.0526433289051056,0.1898351758718491,0.2383745312690735,0.2191711813211441) * MODEL1_texOff(vec2(-1,1));
res += mat4(-0.0234222635626793,0.0238620284944773,0.0427630320191383,-0.1080563366413116,0.0332126952707767,-0.0039051575586200,0.0293126031756401,0.0161924213171005,0.0453971028327942,0.0131999952718616,-0.0689036697149277,0.2349009960889816,0.1013344153761864,0.2706570029258728,0.1191426888108253,-0.2830821871757507) * MODEL2_texOff(vec2(-1,1));
res += mat4(0.0181465242058039,-0.0571886636316776,0.4875229001045227,-0.4244020283222198,0.4331104159355164,0.1066712513566017,-0.5277034044265747,0.1110567077994347,-0.1179447323083878,-0.0273578558117151,0.1798476576805115,-0.2829602360725403,0.1012385115027428,-0.2528488039970398,0.1697608679533005,0.1121710017323494) * MODEL1_texOff(vec2(0,-1));
res += mat4(-0.1404130905866623,-0.0984055623412132,-0.0279541295021772,-0.1321212500333786,-0.0841855704784393,0.1336171030998230,-0.1458790600299835,-0.0044095455668867,0.2203754037618637,0.1455714553594589,-0.2362042963504791,-0.0329121425747871,-0.1683547794818878,0.0289597529917955,0.3424547612667084,0.0143845872953534) * MODEL2_texOff(vec2(0,-1));
res += mat4(0.0287246014922857,0.1948280781507492,0.5998955368995667,0.1192114129662514,-0.6269109249114990,0.8724324703216553,-0.6399638652801514,-0.4201497733592987,-0.3355066180229187,-0.1566904038190842,-0.4396412074565887,0.1525828838348389,0.5573399066925049,0.2324324846267700,0.2762884795665741,0.0406046211719513) * MODEL1_texOff(vec2(0,0));
res += mat4(0.3890096545219421,-0.0574061162769794,-0.1468243300914764,-0.5953360199928284,-0.1363215148448944,-0.2224670499563217,-0.2237723320722580,0.2738097012042999,-0.4868114292621613,-0.5029351711273193,-0.3570256233215332,-0.1776263266801834,-0.0176672954112291,-0.4318660795688629,1.0395888090133667,0.1728395074605942) * MODEL2_texOff(vec2(0,0));
res += mat4(0.1337304115295410,-0.0809440389275551,0.1600498855113983,-0.1108811497688293,-0.2376178801059723,-0.1532768607139587,-0.0447455830872059,0.2515332102775574,0.4848278462886810,-0.0915748402476311,-0.0336527302861214,-0.2141884714365005,0.2125129699707031,0.3237875998020172,0.0022272330243140,-0.0167857185006142) * MODEL1_texOff(vec2(0,1));
res += mat4(0.0457934997975826,0.0510537698864937,-0.0519523508846760,-0.4506326615810394,-0.1029204949736595,0.0116113182157278,-0.1750748157501221,-0.0048758201301098,0.1506977379322052,0.0633068457245827,-0.1628549993038177,-0.0144928665831685,0.1408756822347641,0.2896180152893066,0.0803691521286964,-0.4930096566677094) * MODEL2_texOff(vec2(0,1));
res += mat4(-0.0484248884022236,0.1371297985315323,-0.1235475391149521,-0.2618594765663147,-0.0280395895242691,0.0248795989900827,0.1204105168581009,0.3246576189994812,0.0426272377371788,-0.0520061068236828,0.0575957447290421,-0.2613646090030670,0.1165295541286469,-0.0390013493597507,-0.0470846109092236,-0.0014663023175672) * MODEL1_texOff(vec2(1,-1));
res += mat4(-0.1066762879490852,-0.0869804695248604,-0.0099332248792052,-0.1355892717838287,-0.0760413780808449,0.1377770304679871,-0.0263407956808805,0.0880135521292686,0.1496269851922989,-0.0487459264695644,0.1286851912736893,0.2218491584062576,0.1723349541425705,-0.0165541302412748,-0.0690477639436722,-0.2388458102941513) * MODEL2_texOff(vec2(1,-1));
res += mat4(-0.4236431121826172,0.0465179122984409,-0.1526456624269485,0.1426440477371216,0.5913932919502258,-0.1082349196076393,0.2731275856494904,-0.2687640488147736,-0.4628683030605316,-0.0537119321525097,-0.1597615629434586,0.0528527684509754,-0.3485085070133209,0.1395110934972763,0.0642972290515900,0.0323829315602779) * MODEL1_texOff(vec2(1,0));
res += mat4(0.0066713397391140,-0.0482029877603054,-0.1707276403903961,-0.1001396998763084,0.0539822019636631,-0.1624453216791153,0.4913550019264221,0.3687861263751984,0.0491421781480312,0.1311376541852951,0.0992425829172134,-0.4636098444461823,-0.3415873646736145,-0.0153833786025643,-0.0270162131637335,-0.0935514941811562) * MODEL2_texOff(vec2(1,0));
res += mat4(-0.1738258153200150,0.0458541549742222,-0.0653749182820320,-0.0156540926545858,-0.0357586294412613,-0.1486178338527679,0.1798035055398941,-0.1310307979583740,0.0783249065279961,-0.0261360015720129,-0.1047066971659660,0.3385537564754486,-0.0339452810585499,0.2299628853797913,-0.1408322304487228,-0.0352708548307419) * MODEL1_texOff(vec2(1,1));
res += mat4(0.0463018082082272,0.0565674640238285,-0.0538956597447395,-0.2354862987995148,0.0297824125736952,0.0307939313352108,0.1271791011095047,-0.1025698855519295,0.1060482114553452,-0.0703211054205894,-0.0083062350749969,0.0474255047738552,0.0442508421838284,0.1569559425115585,-0.0442709513008595,-0.1188704669475555) * MODEL2_texOff(vec2(1,1));
res = max(res, vec4(0.0)) + vec4(0.7366524934768677,1.0013850927352905,-0.0276311747729778,0.0734841898083687) * min(res, vec4(0.0));
return res;
}
//!HOOK LUMA
//!WHEN OUTPUT.w LUMA.w / 1.300 > OUTPUT.h LUMA.h / 1.300 > *
//!DESC mapping 4_1
//!BIND MODEL21
//!BIND MODEL22
//!SAVE MODEL1
//!COMPONENTS 4
vec4 hook()
{
vec4 res = vec4(-0.1306160986423492,-0.0808217376470566,-0.2880123555660248,0.0099629526957870);
res += mat4(-0.1033539846539497,0.0541300140321255,-0.0804840475320816,-0.0334571413695812,-0.0264753755182028,0.1118840202689171,0.1186013221740723,-0.0127575425431132,0.2236593365669250,0.0025286162272096,0.0985530614852905,0.0685181617736816,-0.1884875595569611,0.0530862808227539,-0.0482063069939613,0.0375233069062233) * MODEL21_texOff(vec2(-1,-1));
res += mat4(0.1837068796157837,-0.0632847175002098,0.0016613919287920,0.0392861217260361,0.2923883199691772,-0.1713902205228806,0.1907587945461273,0.0550456829369068,0.0644215345382690,-0.1046456992626190,0.0187383033335209,0.0770180150866508,0.1933846622705460,-0.0455715768039227,0.0375007353723049,-0.1053109914064407) * MODEL22_texOff(vec2(-1,-1));
res += mat4(-0.0972480997443199,0.2820451855659485,0.0114549007266760,-0.0954328626394272,0.0706252008676529,0.4829064607620239,-0.6371517181396484,0.0005180989392102,0.3280143439769745,0.0665246024727821,-0.0503116399049759,-0.1261110603809357,0.1114177703857422,-0.2053108513355255,0.1428771317005157,0.3926100134849548) * MODEL21_texOff(vec2(-1,0));
res += mat4(-0.2571723163127899,0.1627264618873596,-0.4940335154533386,-0.1361546218395233,0.0804422944784164,-0.4231885373592377,0.0650202706456184,0.0518481098115444,-0.0502478554844856,-0.1305799931287766,0.1814480125904083,0.0090866927057505,-0.0510044656693935,-0.1691461503505707,0.0922467112541199,-0.0314207412302494) * MODEL22_texOff(vec2(-1,0));
res += mat4(0.1270498335361481,0.0563284493982792,-0.0435525141656399,0.1569847911596298,0.0576847903430462,0.3461692929267883,-0.0325655154883862,-0.2688976824283600,-0.1341977864503860,-0.1382253766059875,0.2293784171342850,-0.1111817285418510,-0.1402447521686554,-0.3257531225681305,0.0598510466516018,0.1008039116859436) * MODEL21_texOff(vec2(-1,1));
res += mat4(0.1698816716670990,0.3491003513336182,-0.1367681026458740,-0.1165873408317566,-0.2091718912124634,-0.1487034261226654,-0.0569749698042870,-0.2100717276334763,0.0404917001724243,-0.1372035890817642,0.0689046755433083,-0.0367818064987659,-0.0325474888086319,-0.0114965448155999,-0.0137249026447535,-0.0279692262411118) * MODEL22_texOff(vec2(-1,1));
res += mat4(-0.0563433989882469,0.0132494345307350,-0.2434540390968323,0.0796563774347305,-0.2109155058860779,0.0387088693678379,-0.0591037571430206,0.0955820381641388,0.4660535752773285,-0.1204202473163605,0.1332369595766068,-0.0285425651818514,-0.3886952698230743,-0.0434980578720570,-0.0849134400486946,0.0802380964159966) * MODEL21_texOff(vec2(0,-1));
res += mat4(0.0412235632538795,0.1571959257125854,0.2050069272518158,-0.1138664111495018,0.1962715685367584,0.0594439841806889,0.0351715497672558,-0.0129811102524400,0.2055217623710632,-0.0647534057497978,0.0373471938073635,0.0877277255058289,-0.5734645724296570,0.1188675239682198,-0.1145943328738213,-0.1182733029127121) * MODEL22_texOff(vec2(0,-1));
res += mat4(-0.2004909217357635,-0.4817073047161102,0.5596802830696106,-0.0327854752540588,0.0989314392209053,0.4127818942070007,0.7265836596488953,-0.2692042589187622,0.5195841789245605,-0.2357539832592010,-0.3819393217563629,0.1755530238151550,0.6578183770179749,0.1075539961457253,-0.2688144743442535,0.3242723941802979) * MODEL21_texOff(vec2(0,0));
res += mat4(-0.3221310675144196,0.2978510260581970,0.2269985526800156,-0.3184116482734680,0.4845580160617828,0.4407236874103546,0.0099756307899952,-0.3121858239173889,-0.3810067176818848,-0.0553649961948395,0.0202834140509367,0.0409953594207764,0.2532750964164734,0.2731618583202362,0.1237529441714287,0.0134243080392480) * MODEL22_texOff(vec2(0,0));
res += mat4(0.1835541725158691,0.0549701862037182,-0.1749316602945328,-0.2030028849840164,0.0263462308794260,0.2781440317630768,0.0372458845376968,0.3643021881580353,-0.4047883749008179,0.0660117194056511,0.4863115549087524,-0.2024163603782654,-0.6403482556343079,0.2765505611896515,0.1417075097560883,0.5064445734024048) * MODEL21_texOff(vec2(0,1));
res += mat4(0.6106975078582764,-0.1570862233638763,-0.3223383128643036,-0.2497926801443100,-0.4854303300380707,0.0132978223264217,-0.0609334111213684,0.1285556703805923,-0.1412864029407501,-0.1379042416810989,-0.0258826259523630,0.1357705891132355,-0.1285902857780457,-0.0577826797962189,0.0550044551491737,0.1717510819435120) * MODEL22_texOff(vec2(0,1));
res += mat4(0.1389609426259995,0.0835867226123810,0.0309768319129944,-0.0278116948902607,-0.0390677824616432,-0.0111810686066747,-0.0025318188127130,0.0069569633342326,0.0347319357097149,0.0191543344408274,0.0314339138567448,-0.0228427499532700,0.0416300334036350,0.0249234102666378,0.1210031509399414,0.1142473593354225) * MODEL21_texOff(vec2(1,-1));
res += mat4(0.0607251487672329,0.0386395826935768,-0.0219341218471527,-0.1102298423647881,0.1487188935279846,0.0602982006967068,-0.0280748903751373,-0.0211924221366644,0.0042894422076643,-0.0269144997000694,0.0814756453037262,-0.0314031280577183,-0.0213186051696539,-0.1362965404987335,0.0382767543196678,-0.0669511556625366) * MODEL22_texOff(vec2(1,-1));
res += mat4(-0.2397561967372894,0.3023172020912170,-0.2398054003715515,0.0041919997893274,-0.1016605198383331,-0.1521034836769104,-0.1526568531990051,0.0272433310747147,0.0741761848330498,0.1116370111703873,0.1149727106094360,-0.0809784531593323,-0.1448147594928741,-0.0943927690386772,-0.0086280042305589,0.1243222951889038) * MODEL21_texOff(vec2(1,0));
res += mat4(-0.0469366572797298,-0.1655988991260529,-0.1029584184288979,-0.1347874104976654,0.2064601778984070,0.0521226711571217,-0.1366733759641647,-0.0041872998699546,0.1077186539769173,0.0184442866593599,-0.2309073060750961,-0.1637075096368790,-0.0417953692376614,-0.3190860450267792,-0.1593534499406815,0.0136412177234888) * MODEL22_texOff(vec2(1,0));
res += mat4(0.1698798984289169,0.0232755411416292,-0.0876034423708916,-0.3008348643779755,0.0789884999394417,0.0034748215693980,-0.0064704762771726,0.0057828431017697,-0.0190630126744509,-0.0334153175354004,-0.0195646341890097,0.0105131156742573,0.0995147302746773,-0.3130289018154144,-0.0724022984504700,0.0113303456455469) * MODEL21_texOff(vec2(1,1));
res += mat4(-0.0027791252359748,-0.0193455871194601,-0.0415000133216381,0.0568981170654297,-0.2745247483253479,0.1222846284508705,0.1899162530899048,0.1067754998803139,-0.0561975166201591,-0.1500336527824402,0.0526139959692955,-0.3491798937320709,-0.0692384615540504,-0.0307095069438219,0.0498757846653461,0.0019003645284101) * MODEL22_texOff(vec2(1,1));
res = max(res, vec4(0.0)) + vec4(0.1552927196025848,0.0782765746116638,0.7966942191123962,-1.1619627475738525) * min(res, vec4(0.0));
return res;
}
//!HOOK LUMA
//!WHEN OUTPUT.w LUMA.w / 1.300 > OUTPUT.h LUMA.h / 1.300 > *
//!DESC mapping 4_2
//!BIND MODEL21
//!BIND MODEL22
//!SAVE MODEL2
//!COMPONENTS 4
vec4 hook()
{
vec4 res = vec4(-0.1443098634481430,-0.1343899369239807,-0.0624338127672672,-0.1094277128577232);
res += mat4(-0.0689977407455444,-0.1693786680698395,0.0109281269833446,0.0609922930598259,0.0296908002346754,0.1195700988173485,-0.0694077461957932,0.0971287414431572,0.0253518298268318,0.1213042959570885,0.0703809782862663,0.0055739870294929,-0.1595942378044128,-0.1336689442396164,-0.0622441768646240,-0.0428023114800453) * MODEL21_texOff(vec2(-1,-1));
res += mat4(0.0860001668334007,-0.0226618759334087,0.1602241247892380,0.0431661494076252,0.1526461094617844,0.2752982378005981,0.0960300788283348,-0.0536719262599945,-0.0171773489564657,0.0457364916801453,-0.0360932648181915,-0.0397153608500957,-0.0277090407907963,0.0729821547865868,-0.0145150292664766,0.0252893269062042) * MODEL22_texOff(vec2(-1,-1));
res += mat4(-0.1407091915607452,-0.4007499516010284,-0.0302001200616360,-0.0606933943927288,-0.2960600554943085,-0.2263117432594299,0.0721478462219238,-0.4578711986541748,0.0960150733590126,-0.1606502830982208,0.2444226741790771,0.0000882153908606,0.1472496986389160,0.3256779909133911,-0.2132861614227295,0.0339313484728336) * MODEL21_texOff(vec2(-1,0));
res += mat4(-0.1477648764848709,-0.1487885862588882,-0.1973863691091537,0.0717295333743095,0.0843430235981941,0.6259996294975281,-0.1214931011199951,-0.1274987608194351,0.2359549105167389,0.3002171218395233,-0.0825233608484268,-0.0157950688153505,0.0706149637699127,0.1762917637825012,-0.0611497573554516,-0.0859689489006996) * MODEL22_texOff(vec2(-1,0));
res += mat4(0.0174895934760571,-0.0567042417824268,0.0409146919846535,0.0258173532783985,0.1421577036380768,0.1234543323516846,-0.1721662431955338,0.1492216140031815,0.1100751459598541,0.0501539446413517,0.1100447699427605,-0.1086079254746437,-0.0608497932553291,0.0087817469611764,0.0714464113116264,-0.1285197436809540) * MODEL21_texOff(vec2(-1,1));
res += mat4(-0.0017177806003019,-0.1463395059108734,-0.1085453778505325,0.1650195866823196,0.0813829153776169,0.1102061793208122,-0.0578421875834465,-0.0232036896049976,-0.1239888817071915,0.0155465165153146,0.1079114526510239,-0.0420837886631489,-0.0775837749242783,0.0148941157385707,-0.0502299368381500,-0.0654754191637039) * MODEL22_texOff(vec2(-1,1));
res += mat4(0.0918162539601326,0.0440697595477104,-0.0515748932957649,0.0417411290109158,0.0353216230869293,0.1535954177379608,0.0439723692834377,-0.1288845241069794,0.1076577678322792,-0.1306740194559097,0.0715952813625336,-0.0681907683610916,-0.3798767924308777,0.1023928597569466,-0.0970670804381371,0.0077168666757643) * MODEL21_texOff(vec2(0,-1));
res += mat4(0.0634560957551003,-0.0550306066870689,0.2073986232280731,0.0520241297781467,0.1162287592887878,-0.2218665480613708,0.3199682831764221,0.0606246069073677,-0.0058511858806014,-0.0667045339941978,-0.0449917949736118,0.0707788690924644,-0.3323366343975067,-0.0763893201947212,-0.0997853428125381,-0.1181001588702202) * MODEL22_texOff(vec2(0,-1));
res += mat4(-0.3101258873939514,0.2616009712219238,0.0584651045501232,0.1656491309404373,-0.0069236233830452,0.2573371529579163,-0.1793291717767715,-0.2718756198883057,0.0953581258654594,0.0524105131626129,0.1183085516095161,0.0583294369280338,0.5036848187446594,-0.5763167142868042,-0.2119628041982651,-0.3140562772750854) * MODEL21_texOff(vec2(0,0));
res += mat4(-0.2497755438089371,-0.0146329319104552,-0.2741575539112091,0.2459975033998489,0.3562706708908081,-0.6528629064559937,-0.4287456274032593,0.2055913358926773,0.1739019453525543,-0.3855968713760376,-0.0958273336291313,-0.7066691517829895,0.2365748286247253,-0.3046728968620300,-0.2590373754501343,-0.0496727414429188) * MODEL22_texOff(vec2(0,0));
res += mat4(-0.0844531357288361,-0.0321611948311329,-0.0951840654015541,0.0577518045902252,-0.1606003493070602,0.2776086628437042,-0.1355003118515015,-0.0880064144730568,-0.1277643740177155,-0.0514567233622074,0.1522682905197144,-0.1040910631418228,-0.2767944037914276,-0.1452194601297379,0.0089118303731084,0.0231996178627014) * MODEL21_texOff(vec2(0,1));
res += mat4(0.2603267133235931,0.0167464651167393,-0.2064073234796524,0.1782064288854599,0.4890212416648865,0.0559245310723782,0.1221160590648651,-0.0202587731182575,-0.4056585729122162,-0.1839511841535568,0.2775998413562775,0.0024275144096464,-0.2624500989913940,-0.0619418807327747,0.0153478365391493,0.0123427547514439) * MODEL22_texOff(vec2(0,1));
res += mat4(0.0816635638475418,-0.0134946266189218,0.0594766475260258,-0.0551253929734230,0.0134431896731257,-0.0652195811271667,-0.0563635528087616,-0.0066532371565700,-0.0004114551993553,0.0105680683627725,0.1324467360973358,0.0467248968780041,0.0301312971860170,-0.1073397025465965,-0.0363437235355377,-0.0474153012037277) * MODEL21_texOff(vec2(1,-1));
res += mat4(0.0199097190052271,0.0901319086551666,0.0448978282511234,0.0505443066358566,0.0438878424465656,-0.0494784042239189,0.0724927335977554,-0.0070675504393876,-0.0012125011999160,0.0295279901474714,0.0705125033855438,0.0555334389209747,-0.0403393507003784,-0.1271172016859055,0.0017914215568453,0.1462216079235077) * MODEL22_texOff(vec2(1,-1));
res += mat4(-0.2827299833297729,0.2052399665117264,0.0042732120491564,-0.3969024717807770,-0.0782120972871780,0.1960176974534988,-0.0675340741872787,0.0027962317690253,0.0516129024326801,-0.0352642722427845,0.0546326488256454,0.0065340655855834,-0.1062376946210861,0.1364430636167526,-0.0536947809159756,0.2098117172718048) * MODEL21_texOff(vec2(1,0));
res += mat4(0.0045875865034759,0.2162927240133286,-0.2158576399087906,-0.0047327815555036,0.1251590698957443,0.1279677897691727,-0.1188964918255806,0.0328494384884834,0.0076038073748350,-0.0561547242105007,0.0335608273744583,0.4332321286201477,0.0021786799188703,0.0844521671533585,-0.2102309316396713,-0.0189208015799522) * MODEL22_texOff(vec2(1,0));
res += mat4(0.0933093801140785,0.1548244059085846,-0.0598701611161232,0.0357220247387886,-0.1141726672649384,0.0536412484943867,-0.0159156844019890,-0.0445508137345314,0.1883231997489929,-0.1547038406133652,0.0530619807541370,0.0059371814131737,0.0602529086172581,-0.0435577929019928,0.0083390390500426,0.0191930737346411) * MODEL21_texOff(vec2(1,1));
res += mat4(-0.0351041629910469,0.2119503468275070,-0.0841927304863930,0.0079463515430689,0.0683520361781120,-0.1657009869813919,0.0611055232584476,-0.0063667562790215,0.0330024957656860,-0.1810818463563919,0.0872574150562286,0.1485669612884521,-0.1305806934833527,0.0041402997449040,0.0223289318382740,-0.0141495745629072) * MODEL22_texOff(vec2(1,1));
res = max(res, vec4(0.0)) + vec4(0.5769761204719543,0.1716064810752869,-0.0821026712656021,0.2092144042253494) * min(res, vec4(0.0));
return res;
}
//!HOOK LUMA
//!WHEN OUTPUT.w LUMA.w / 1.300 > OUTPUT.h LUMA.h / 1.300 > *
//!DESC sub-band residuals 1
//!BIND MODEL1
//!BIND MODEL2
//!BIND FEATURE1
//!SAVE RES1
//!COMPONENTS 4
vec4 hook()
{
vec4 res = vec4(0.0245648548007011,-0.4467784762382507,0.0197526942938566,-0.0110000418499112);
res += mat4(0.0302665308117867,-0.9262221455574036,-0.1161134764552116,-0.0506900474429131,0.2716045379638672,-0.0485871583223343,0.0044713355600834,-0.4274623394012451,0.0749531090259552,-0.3700785338878632,0.0350039415061474,-0.0540786534547806,-0.0607390031218529,-0.8019900321960449,0.0923245251178741,0.1258827745914459) * MODEL1_texOff(0);
res += mat4(-0.0649135261774063,0.0815236791968346,0.0067334296181798,0.1277425885200500,-0.0051357815973461,-0.1485908329486847,0.0074226572178304,0.0050623500719666,0.0588018335402012,-0.0692552924156189,0.1288725286722183,-0.0989386290311813,0.0427936837077141,0.0967708528041840,-0.0455632135272026,-0.0711275041103363) * MODEL2_texOff(0);
res += FEATURE1_texOff(0);
res = max(res, vec4(0.0)) + vec4(0.9927186965942383,0.0570580027997494,1.3226752281188965,1.0069466829299927) * min(res, vec4(0.0));
return res;
}
//!HOOK LUMA
//!WHEN OUTPUT.w LUMA.w / 1.300 > OUTPUT.h LUMA.h / 1.300 > *
//!DESC sub-band residuals 2
//!BIND MODEL1
//!BIND MODEL2
//!BIND FEATURE2
//!SAVE RES2
//!COMPONENTS 4
vec4 hook()
{
vec4 res = vec4(-0.0425243787467480,-0.3715015351772308,-0.0256227850914001,-0.2774516046047211);
res += mat4(0.0238118842244148,0.0295480657368898,-0.0066418983042240,0.1021223962306976,-0.0568209178745747,-0.4355100393295288,-0.2700522541999817,-0.2060186564922333,-0.0689613372087479,-0.1689691990613937,-0.0306748505681753,-0.2461252212524414,-0.0057375836186111,-0.1892303228378296,-0.0285871494561434,-0.5032613277435303) * MODEL1_texOff(0);
res += mat4(0.5463213324546814,0.0972800329327583,0.0307560767978430,0.0678058937191963,-0.0356063023209572,-0.7013865113258362,0.1890443563461304,-0.1036657467484474,-0.1745826154947281,-0.2942218780517578,-0.0485423319041729,-0.2983124554157257,-0.0524431839585304,-0.3261034786701202,0.3217246532440186,0.1958018541336060) * MODEL2_texOff(0);
res += FEATURE2_texOff(0);
res = max(res, vec4(0.0)) + vec4(0.1391339898109436,0.0960328355431557,0.6235341429710388,0.1177272796630859) * min(res, vec4(0.0));
return res;
}
//!HOOK LUMA
//!WHEN OUTPUT.w LUMA.w / 1.300 > OUTPUT.h LUMA.h / 1.300 > *
//!DESC sub-pixel convolution 1
//!BIND RES1
//!BIND RES2
//!SAVE SUBCONV1
//!COMPONENTS 4
vec4 hook()
{
vec4 res = vec4(0.2010385394096375,0.2058132737874985,0.1918809115886688,0.1961363703012466);
res += mat4x4(-0.0005980331334285,-0.0095877395942807,-0.0149448839947581,-0.0026380482595414,0.0320665836334229,-0.0706205591559410,-0.0054677254520357,0.0215112231671810,-0.0025710910558701,-0.0000433265340689,0.0044494951143861,-0.0034823501482606,-0.0050858515314758,0.0109513988718390,0.0208286065608263,-0.0032168829347938) * RES1_texOff(vec2(-1,-1));
res += mat4x4(-0.0145305208861828,0.0246876608580351,-0.0038286084309220,-0.0033089490607381,-0.0920709222555161,-0.0767898634076118,0.0012083095498383,-0.0751532614231110,0.0001302754972130,-0.0107085108757019,-0.0010383903281763,-0.0059571005403996,0.0809685289859772,0.0414833538234234,0.0227938480675220,-0.0211347509175539) * RES2_texOff(vec2(-1,-1));
res += mat4x4(0.0160999298095703,0.0364215746521950,-0.0377063788473606,-0.0449111759662628,-0.0476365163922310,0.1522845029830933,-0.0131391752511263,-0.0476671792566776,-0.0378389135003090,0.0235454943031073,0.0224007442593575,-0.0010372076649219,-0.0089435689151287,-0.0293026417493820,0.0274190884083509,0.0469092652201653) * RES1_texOff(vec2(-1,0));
res += mat4x4(0.0297575183212757,-0.0132508194074035,-0.0044682323932648,-0.0096222748979926,0.2525918781757355,0.1873829364776611,-0.5599535703659058,-0.2372044622898102,0.0033207221422344,0.0256173480302095,0.0294605866074562,0.0323960892856121,-0.1679904460906982,-0.1278967708349228,0.3168168365955353,0.1978507637977600) * RES2_texOff(vec2(-1,0));
res += mat4x4(-0.0047590560279787,-0.0149335600435734,0.0033453819341958,-0.0012247267877683,0.1112466752529144,0.0147760482504964,0.0031189601868391,0.0391573049128056,-0.0028154491446912,-0.0036881719715893,-0.0116015253588557,-0.0037573333829641,0.0047581391409039,0.0071071563288569,-0.0033221673220396,0.0004882142529823) * RES1_texOff(vec2(-1,1));
res += mat4x4(-0.0025197160430253,-0.0018677815096453,0.0038254233077168,0.0041981274262071,-0.1321131736040115,-0.0494364202022552,0.0760654658079147,-0.1386690139770508,-0.0016222692793235,-0.0060105528682470,0.0010201989207417,0.0092753591015935,-0.0194614846259356,0.0087382243946195,-0.0606758072972298,0.0156162241473794) * RES2_texOff(vec2(-1,1));
res += mat4x4(-0.0073722628876567,0.0012844242155552,0.0241398401558399,-0.0075527969747782,-0.0865194946527481,-0.0610522404313087,0.0289319511502981,-0.0994452014565468,0.0281447004526854,-0.0250582899898291,0.0044891634024680,-0.0246205236762762,0.0112307453528047,-0.0010844616917893,-0.0223584957420826,0.0177635718137026) * RES1_texOff(vec2(0,-1));
res += mat4x4(-0.0585863515734673,0.0953190475702286,-0.0555586628615856,0.1033507287502289,0.1560877263545990,-0.0690897777676582,-0.0341389514505863,-0.0661668032407761,0.0531073249876499,-0.0266165956854820,-0.0203275382518768,0.0017760475166142,-0.1300747394561768,0.1810652017593384,0.0381597876548767,0.1397419273853302) * RES2_texOff(vec2(0,-1));
res += mat4x4(0.6259804368019104,0.6062518954277039,0.5450409054756165,0.5966195464134216,-0.0423948727548122,0.0760537460446358,-0.0113651463761926,0.3007817566394806,-0.3218322694301605,0.2713021934032440,-0.3143473267555237,0.2303840517997742,0.3493050038814545,0.3590726852416992,0.4138027429580688,0.3391666412353516) * RES1_texOff(vec2(0,0));
res += mat4x4(0.0790478289127350,-0.0978994593024254,0.0779844969511032,-0.0823706611990929,0.0094470111653209,0.1671760678291321,0.1201528310775757,-0.2016288936138153,0.3667598366737366,0.3651430010795593,-0.3612343966960907,-0.2978236973285675,-0.4231655597686768,0.0091423410922289,-0.1918412446975708,0.4224558770656586) * RES2_texOff(vec2(0,0));
res += mat4x4(-0.0186564289033413,0.0274957418441772,-0.0064405309967697,0.0056951809674501,0.4864942431449890,-0.2563461959362030,0.4357284605503082,-0.2976118028163910,0.0374982468783855,0.0167757049202919,0.0305800959467888,0.0232830215245485,0.0138373551890254,-0.0191283021122217,0.0032355054281652,0.0055057541467249) * RES1_texOff(vec2(0,1));
res += mat4x4(-0.0276355985552073,0.0048149987123907,-0.0251619722694159,-0.0057246969081461,0.0271473955363035,-0.0042668608948588,-0.0594691745936871,0.2255926281213760,-0.0203660242259502,0.0721646770834923,0.0137230781838298,-0.0650938376784325,-0.3049557507038116,0.2035628110170364,-0.2509683668613434,0.1962853819131851) * RES2_texOff(vec2(0,1));
res += mat4x4(0.0109980758279562,-0.0053752651438117,-0.0112550277262926,0.0024017230607569,0.0362104885280132,0.0084348218515515,-0.0106990104541183,-0.0207723993808031,-0.0014961160486564,0.0066790678538382,0.0028113177977502,0.0025022011250257,-0.0093937022611499,0.0016421369509771,0.0035362334456295,-0.0058064293116331) * RES1_texOff(vec2(1,-1));
res += mat4x4(0.0138889988884330,-0.0078343702480197,0.0061464929021895,0.0202130675315857,-0.0257590841501951,-0.0366640128195286,0.0250097587704659,-0.0498071312904358,-0.0103149358183146,-0.0001786737266229,-0.0099909817799926,0.0062733208760619,0.0131437368690968,-0.0005469865864143,-0.0388854071497917,0.0612070746719837) * RES2_texOff(vec2(1,-1));
res += mat4x4(0.0052813654765487,0.0215748809278011,0.0107395220547915,-0.0079439217224717,0.0382786765694618,0.0697424262762070,-0.0415962152183056,0.0657853558659554,0.0209470037370920,-0.0218399092555046,-0.0447359494864941,0.0407319553196430,-0.0040902681648731,-0.0196106657385826,-0.0018554026028141,0.0203906055539846) * RES1_texOff(vec2(1,0));
res += mat4x4(-0.0106181986629963,0.0084018819034100,0.0131329754367471,-0.0198754761368036,0.1117177084088326,0.0990846082568169,-0.0732304081320763,0.0163581725209951,-0.0648830309510231,-0.0451613292098045,0.0206844564527273,0.0031441387254745,-0.0106161693111062,-0.0567689687013626,0.0782861113548279,-0.0306094046682119) * RES2_texOff(vec2(1,0));
res += mat4x4(0.0012452082009986,-0.0026056850329041,-0.0096226977184415,-0.0037850935477763,-0.0190967041999102,0.0534373670816422,0.1599360853433609,0.0834670960903168,-0.0070255175232887,0.0012873009545729,0.0030876772943884,-0.0093916896730661,-0.0033529615029693,0.0043485122732818,0.0089034689590335,-0.0067489291541278) * RES1_texOff(vec2(1,1));
res += mat4x4(0.0004713654634543,-0.0034161377698183,-0.0026913962792605,0.0053522582165897,-0.0040974905714393,0.0273330621421337,-0.0333138220012188,-0.0701237097382545,0.0082997502759099,-0.0183656588196754,-0.0122841577976942,-0.0052855615504086,-0.0023795007728040,-0.0438593104481697,-0.1101513057947159,-0.0182559806853533) * RES2_texOff(vec2(1,1));
return vec4(res);
}
//!HOOK LUMA
//!WHEN OUTPUT.w LUMA.w / 1.300 > OUTPUT.h LUMA.h / 1.300 > *
//!WIDTH LUMA.w 2 *
//!HEIGHT LUMA.h 2 *
//!DESC aggregation
//!BIND SUBCONV1
vec4 hook()
{
vec2 fcoord = fract(SUBCONV1_pos * SUBCONV1_size);
vec2 base = SUBCONV1_pos + (vec2(0.5) - fcoord) * SUBCONV1_pt;
ivec2 index = ivec2(fcoord * vec2(2));
vec4 res = SUBCONV1_tex(base);
return vec4(res[index.x * 2 + index.y], 0, 0, 1);
}

View File

@@ -0,0 +1,544 @@
// The MIT License(MIT)
//
// Copyright(c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files(the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// NVIDIA Image Scaling v1.0.2 by NVIDIA
// ported to mpv by agyild
// Changelog
// Made it directly operate on LUMA plane, since the original shader was operating
// on LUMA by deriving it from RGB. This should cause a major increase in performance,
// especially on OpenGL 4.0+ renderers
//!HOOK LUMA
//!BIND HOOKED
//!BIND coef_scaler
//!BIND coef_usm
//!DESC NVIDIA Image Scaling and Sharpening v1.0.2
//!COMPUTE 32 24 256 1
//!WHEN OUTPUT.w OUTPUT.h * LUMA.w LUMA.h * / 1.0 >
//!WIDTH OUTPUT.w
//!HEIGHT OUTPUT.h
// User variables
#define SHARPNESS 0.25 // Amount of sharpening. 0.0 to 1.0.
#define NIS_THREAD_GROUP_SIZE 256 // May be set to 128 for better performance on NVIDIA hardware, otherwise set to 256. Don't forget to modify the COMPUTE directive accordingly as well (e.g., COMPUTE 32 24 128 1).
#define NIS_HDR_MODE 0 // Must be set to 1 for content with PQ colorspace. 0 or 1.
// Constant variables
#define NIS_BLOCK_WIDTH 32
#define NIS_BLOCK_HEIGHT 24
#define kPhaseCount 64
#define kFilterSize 6
#define kSupportSize 6
#define kPadSize kSupportSize
#define NIS_SCALE_INT 1
#define NIS_SCALE_FLOAT 1.0f
#define kTilePitch (NIS_BLOCK_WIDTH + kPadSize)
#define kTileSize (kTilePitch * (NIS_BLOCK_HEIGHT + kPadSize))
#define kEdgeMapPitch (NIS_BLOCK_WIDTH + 2)
#define kEdgeMapSize (kEdgeMapPitch * (NIS_BLOCK_HEIGHT + 2))
const float sharpen_slider = clamp(SHARPNESS, 0.0f, 1.0f) - 0.5f;
const float MaxScale = (sharpen_slider >= 0.0f) ? 1.25f : 1.75f;
const float MinScale = (sharpen_slider >= 0.0f) ? 1.25f : 1.0f;
const float LimitScale = (sharpen_slider >= 0.0f) ? 1.25f : 1.0f;
const float kDetectRatio = 2 * 1127.f / 1024.f;
const float kDetectThres = (bool(NIS_HDR_MODE) ? 32.0f : 64.0f) / 1024.0f;
const float kMinContrastRatio = bool(NIS_HDR_MODE) ? 1.5f : 2.0f;
const float kMaxContrastRatio = bool(NIS_HDR_MODE) ? 5.0f : 10.0f;
const float kSharpStartY = bool(NIS_HDR_MODE) ? 0.35f : 0.45f;
const float kSharpEndY = bool(NIS_HDR_MODE) ? 0.55f : 0.9f;
const float kSharpStrengthMin = max(0.0f, 0.4f + sharpen_slider * MinScale * (bool(NIS_HDR_MODE) ? 1.1f : 1.2));
const float kSharpStrengthMax = ((bool(NIS_HDR_MODE) ? 2.2f : 1.6f) + sharpen_slider * MaxScale * 1.8f);
const float kSharpLimitMin = max((bool(NIS_HDR_MODE) ? 0.06f :0.1f), (bool(NIS_HDR_MODE) ? 0.1f : 0.14f) + sharpen_slider * LimitScale * (bool(NIS_HDR_MODE) ? 0.28f : 0.32f));
const float kSharpLimitMax = ((bool(NIS_HDR_MODE) ? 0.6f : 0.5f) + sharpen_slider * LimitScale * 0.6f);
const float kRatioNorm = 1.0f / (kMaxContrastRatio - kMinContrastRatio);
const float kSharpScaleY = 1.0f / (kSharpEndY - kSharpStartY);
const float kSharpStrengthScale = kSharpStrengthMax - kSharpStrengthMin;
const float kSharpLimitScale = kSharpLimitMax - kSharpLimitMin;
const float kContrastBoost = 1.0f;
const float kEps = 1.0f;
#define kScaleX (HOOKED_size.x / target_size.x)
#define kScaleY (HOOKED_size.y / target_size.y)
#define kSrcNormX HOOKED_pt.x
#define kSrcNormY HOOKED_pt.y
// HLSL to GLSL macros
#define saturate(x) clamp(x, 0, 1)
#define lerp(a, b, x) mix(a, b, x)
// CS Shared variables
shared float shPixelsY[kTileSize];
shared float shCoefScaler[kPhaseCount][kFilterSize];
shared float shCoefUSM[kPhaseCount][kFilterSize];
shared vec4 shEdgeMap[kEdgeMapSize];
// Shader code
vec4 GetEdgeMap(float p[4][4], int i, int j) {
const float g_0 = abs(p[0 + i][0 + j] + p[0 + i][1 + j] + p[0 + i][2 + j] - p[2 + i][0 + j] - p[2 + i][1 + j] - p[2 + i][2 + j]);
const float g_45 = abs(p[1 + i][0 + j] + p[0 + i][0 + j] + p[0 + i][1 + j] - p[2 + i][1 + j] - p[2 + i][2 + j] - p[1 + i][2 + j]);
const float g_90 = abs(p[0 + i][0 + j] + p[1 + i][0 + j] + p[2 + i][0 + j] - p[0 + i][2 + j] - p[1 + i][2 + j] - p[2 + i][2 + j]);
const float g_135 = abs(p[1 + i][0 + j] + p[2 + i][0 + j] + p[2 + i][1 + j] - p[0 + i][1 + j] - p[0 + i][2 + j] - p[1 + i][2 + j]);
const float g_0_90_max = max(g_0, g_90);
const float g_0_90_min = min(g_0, g_90);
const float g_45_135_max = max(g_45, g_135);
const float g_45_135_min = min(g_45, g_135);
float e_0_90 = 0;
float e_45_135 = 0;
if (g_0_90_max + g_45_135_max == 0)
{
return vec4(0, 0, 0, 0);
}
e_0_90 = min(g_0_90_max / (g_0_90_max + g_45_135_max), 1.0f);
e_45_135 = 1.0f - e_0_90;
bool c_0_90 = (g_0_90_max > (g_0_90_min * kDetectRatio)) && (g_0_90_max > kDetectThres) && (g_0_90_max > g_45_135_min);
bool c_45_135 = (g_45_135_max > (g_45_135_min * kDetectRatio)) && (g_45_135_max > kDetectThres) && (g_45_135_max > g_0_90_min);
bool c_g_0_90 = g_0_90_max == g_0;
bool c_g_45_135 = g_45_135_max == g_45;
float f_e_0_90 = (c_0_90 && c_45_135) ? e_0_90 : 1.0f;
float f_e_45_135 = (c_0_90 && c_45_135) ? e_45_135 : 1.0f;
float weight_0 = (c_0_90 && c_g_0_90) ? f_e_0_90 : 0.0f;
float weight_90 = (c_0_90 && !c_g_0_90) ? f_e_0_90 : 0.0f;
float weight_45 = (c_45_135 && c_g_45_135) ? f_e_45_135 : 0.0f;
float weight_135 = (c_45_135 && !c_g_45_135) ? f_e_45_135 : 0.0f;
return vec4(weight_0, weight_90, weight_45, weight_135);
}
void LoadFilterBanksSh(int i0, int di) {
// Load up filter banks to shared memory
// The work is spread over (kPhaseCount * 2) threads
for (int i = i0; i < kPhaseCount * 2; i += di)
{
int phase = i >> 1;
int vIdx = i & 1;
vec4 v = vec4(texelFetch(coef_scaler, ivec2(vIdx, phase), 0));
int filterOffset = vIdx * 4;
shCoefScaler[phase][filterOffset + 0] = v.x;
shCoefScaler[phase][filterOffset + 1] = v.y;
if (vIdx == 0)
{
shCoefScaler[phase][2] = v.z;
shCoefScaler[phase][3] = v.w;
}
v = vec4(texelFetch(coef_usm, ivec2(vIdx, phase), 0));
shCoefUSM[phase][filterOffset + 0] = v.x;
shCoefUSM[phase][filterOffset + 1] = v.y;
if (vIdx == 0)
{
shCoefUSM[phase][2] = v.z;
shCoefUSM[phase][3] = v.w;
}
}
}
float CalcLTI(float p0, float p1, float p2, float p3, float p4, float p5, int phase_index)
{
const bool selector = (phase_index <= kPhaseCount / 2);
float sel = selector ? p0 : p3;
const float a_min = min(min(p1, p2), sel);
const float a_max = max(max(p1, p2), sel);
sel = selector ? p2 : p5;
const float b_min = min(min(p3, p4), sel);
const float b_max = max(max(p3, p4), sel);
const float a_cont = a_max - a_min;
const float b_cont = b_max - b_min;
const float cont_ratio = max(a_cont, b_cont) / (min(a_cont, b_cont) + kEps);
return (1.0f - saturate((cont_ratio - kMinContrastRatio) * kRatioNorm)) * kContrastBoost;
}
vec4 GetInterpEdgeMap(const vec4 edge[2][2], float phase_frac_x, float phase_frac_y)
{
vec4 h0 = lerp(edge[0][0], edge[0][1], phase_frac_x);
vec4 h1 = lerp(edge[1][0], edge[1][1], phase_frac_x);
return lerp(h0, h1, phase_frac_y);
}
float EvalPoly6(const float pxl[6], int phase_int)
{
float y = 0.f;
{
for (int i = 0; i < 6; ++i)
{
y += shCoefScaler[phase_int][i] * pxl[i];
}
}
float y_usm = 0.f;
{
for (int i = 0; i < 6; ++i)
{
y_usm += shCoefUSM[phase_int][i] * pxl[i];
}
}
// let's compute a piece-wise ramp based on luma
const float y_scale = 1.0f - saturate((y * (1.0f / NIS_SCALE_FLOAT) - kSharpStartY) * kSharpScaleY);
// scale the ramp to sharpen as a function of luma
const float y_sharpness = y_scale * kSharpStrengthScale + kSharpStrengthMin;
y_usm *= y_sharpness;
// scale the ramp to limit USM as a function of luma
const float y_sharpness_limit = (y_scale * kSharpLimitScale + kSharpLimitMin) * y;
y_usm = min(y_sharpness_limit, max(-y_sharpness_limit, y_usm));
// reduce ringing
y_usm *= CalcLTI(pxl[0], pxl[1], pxl[2], pxl[3], pxl[4], pxl[5], phase_int);
return y + y_usm;
}
float FilterNormal(const float p[6][6], int phase_x_frac_int, int phase_y_frac_int)
{
float h_acc = 0.0f;
for (int j = 0; j < 6; ++j)
{
float v_acc = 0.0f;
for (int i = 0; i < 6; ++i)
{
v_acc += p[i][j] * shCoefScaler[phase_y_frac_int][i];
}
h_acc += v_acc * shCoefScaler[phase_x_frac_int][j];
}
// let's return the sum unpacked -> we can accumulate it later
return h_acc;
}
float AddDirFilters(float p[6][6], float phase_x_frac, float phase_y_frac, int phase_x_frac_int, int phase_y_frac_int, vec4 w)
{
float f = 0.f;
if (w.x > 0.0f)
{
// 0 deg filter
float interp0Deg[6];
{
for (int i = 0; i < 6; ++i)
{
interp0Deg[i] = lerp(p[i][2], p[i][3], phase_x_frac);
}
}
f += EvalPoly6(interp0Deg, phase_y_frac_int) * w.x;
}
if (w.y > 0.0f)
{
// 90 deg filter
float interp90Deg[6];
{
for (int i = 0; i < 6; ++i)
{
interp90Deg[i] = lerp(p[2][i], p[3][i], phase_y_frac);
}
}
f += EvalPoly6(interp90Deg, phase_x_frac_int) * w.y;
}
if (w.z > 0.0f)
{
//45 deg filter
float pphase_b45;
pphase_b45 = 0.5f + 0.5f * (phase_x_frac - phase_y_frac);
float temp_interp45Deg[7];
temp_interp45Deg[1] = lerp(p[2][1], p[1][2], pphase_b45);
temp_interp45Deg[3] = lerp(p[3][2], p[2][3], pphase_b45);
temp_interp45Deg[5] = lerp(p[4][3], p[3][4], pphase_b45);
{
pphase_b45 = pphase_b45 - 0.5f;
float a = (pphase_b45 >= 0.f) ? p[0][2] : p[2][0];
float b = (pphase_b45 >= 0.f) ? p[1][3] : p[3][1];
float c = (pphase_b45 >= 0.f) ? p[2][4] : p[4][2];
float d = (pphase_b45 >= 0.f) ? p[3][5] : p[5][3];
temp_interp45Deg[0] = lerp(p[1][1], a, abs(pphase_b45));
temp_interp45Deg[2] = lerp(p[2][2], b, abs(pphase_b45));
temp_interp45Deg[4] = lerp(p[3][3], c, abs(pphase_b45));
temp_interp45Deg[6] = lerp(p[4][4], d, abs(pphase_b45));
}
float interp45Deg[6];
float pphase_p45 = phase_x_frac + phase_y_frac;
if (pphase_p45 >= 1)
{
for (int i = 0; i < 6; i++)
{
interp45Deg[i] = temp_interp45Deg[i + 1];
}
pphase_p45 = pphase_p45 - 1;
}
else
{
for (int i = 0; i < 6; i++)
{
interp45Deg[i] = temp_interp45Deg[i];
}
}
f += EvalPoly6(interp45Deg, int(pphase_p45 * 64)) * w.z;
}
if (w.w > 0.0f)
{
//135 deg filter
float pphase_b135 = 0.5f * (phase_x_frac + phase_y_frac);
float temp_interp135Deg[7];
temp_interp135Deg[1] = lerp(p[3][1], p[4][2], pphase_b135);
temp_interp135Deg[3] = lerp(p[2][2], p[3][3], pphase_b135);
temp_interp135Deg[5] = lerp(p[1][3], p[2][4], pphase_b135);
{
pphase_b135 = pphase_b135 - 0.5f;
float a = (pphase_b135 >= 0.f) ? p[5][2] : p[3][0];
float b = (pphase_b135 >= 0.f) ? p[4][3] : p[2][1];
float c = (pphase_b135 >= 0.f) ? p[3][4] : p[1][2];
float d = (pphase_b135 >= 0.f) ? p[2][5] : p[0][3];
temp_interp135Deg[0] = lerp(p[4][1], a, abs(pphase_b135));
temp_interp135Deg[2] = lerp(p[3][2], b, abs(pphase_b135));
temp_interp135Deg[4] = lerp(p[2][3], c, abs(pphase_b135));
temp_interp135Deg[6] = lerp(p[1][4], d, abs(pphase_b135));
}
float interp135Deg[6];
float pphase_p135 = 1 + (phase_x_frac - phase_y_frac);
if (pphase_p135 >= 1)
{
for (int i = 0; i < 6; ++i)
{
interp135Deg[i] = temp_interp135Deg[i + 1];
}
pphase_p135 = pphase_p135 - 1;
}
else
{
for (int i = 0; i < 6; ++i)
{
interp135Deg[i] = temp_interp135Deg[i];
}
}
f += EvalPoly6(interp135Deg, int(pphase_p135 * 64)) * w.w;
}
return f;
}
void hook()
{
uvec2 blockIdx = gl_WorkGroupID.xy;
uint threadIdx = gl_LocalInvocationID.x;
// Figure out the range of pixels from input image that would be needed to be loaded for this thread-block
int dstBlockX = int(NIS_BLOCK_WIDTH * blockIdx.x);
int dstBlockY = int(NIS_BLOCK_HEIGHT * blockIdx.y);
const int srcBlockStartX = int(floor((dstBlockX + 0.5f) * kScaleX - 0.5f));
const int srcBlockStartY = int(floor((dstBlockY + 0.5f) * kScaleY - 0.5f));
const int srcBlockEndX = int(ceil((dstBlockX + NIS_BLOCK_WIDTH + 0.5f) * kScaleX - 0.5f));
const int srcBlockEndY = int(ceil((dstBlockY + NIS_BLOCK_HEIGHT + 0.5f) * kScaleY - 0.5f));
int numTilePixelsX = srcBlockEndX - srcBlockStartX + kSupportSize - 1;
int numTilePixelsY = srcBlockEndY - srcBlockStartY + kSupportSize - 1;
// round-up load region to even size since we're loading in 2x2 batches
numTilePixelsX += numTilePixelsX & 0x1;
numTilePixelsY += numTilePixelsY & 0x1;
const int numTilePixels = numTilePixelsX * numTilePixelsY;
// calculate the equivalent values for the edge map
const int numEdgeMapPixelsX = numTilePixelsX - kSupportSize + 2;
const int numEdgeMapPixelsY = numTilePixelsY - kSupportSize + 2;
const int numEdgeMapPixels = numEdgeMapPixelsX * numEdgeMapPixelsY;
// fill in input luma tile (shPixelsY) in batches of 2x2 pixels
// we use texture gather to get extra support necessary
// to compute 2x2 edge map outputs too
{
for (uint i = threadIdx * 2; i < uint(numTilePixels) >> 1; i += NIS_THREAD_GROUP_SIZE * 2)
{
uint py = (i / numTilePixelsX) * 2;
uint px = i % numTilePixelsX;
// 0.5 to be in the center of texel
// - (kSupportSize - 1) / 2 to shift by the kernel support size
float kShift = 0.5f - (kSupportSize - 1) / 2;
const float tx = (srcBlockStartX + px + kShift) * kSrcNormX;
const float ty = (srcBlockStartY + py + kShift) * kSrcNormY;
float p[2][2];
#ifdef HOOKED_gather
{
const vec4 sY = HOOKED_gather(vec2(tx, ty), 0);
p[0][0] = sY.w;
p[0][1] = sY.z;
p[1][0] = sY.x;
p[1][1] = sY.y;
}
#else
for (int j = 0; j < 2; j++)
{
for (int k = 0; k < 2; k++)
{
const float px = HOOKED_tex(vec2(tx + k * kSrcNormX, ty + j * kSrcNormY)).r;
p[j][k] = px;
}
}
#endif
const uint idx = py * kTilePitch + px;
shPixelsY[idx] = float(p[0][0]);
shPixelsY[idx + 1] = float(p[0][1]);
shPixelsY[idx + kTilePitch] = float(p[1][0]);
shPixelsY[idx + kTilePitch + 1] = float(p[1][1]);
}
}
groupMemoryBarrier();
barrier();
{
// fill in the edge map of 2x2 pixels
for (uint i = threadIdx * 2; i < uint(numEdgeMapPixels) >> 1; i += NIS_THREAD_GROUP_SIZE * 2)
{
uint py = (i / numEdgeMapPixelsX) * 2;
uint px = i % numEdgeMapPixelsX;
const uint edgeMapIdx = py * kEdgeMapPitch + px;
uint tileCornerIdx = (py+1) * kTilePitch + px + 1;
float p[4][4];
for (int j = 0; j < 4; j++)
{
for (int k = 0; k < 4; k++)
{
p[j][k] = shPixelsY[tileCornerIdx + j * kTilePitch + k];
}
}
shEdgeMap[edgeMapIdx] = vec4(GetEdgeMap(p, 0, 0));
shEdgeMap[edgeMapIdx + 1] = vec4(GetEdgeMap(p, 0, 1));
shEdgeMap[edgeMapIdx + kEdgeMapPitch] = vec4(GetEdgeMap(p, 1, 0));
shEdgeMap[edgeMapIdx + kEdgeMapPitch + 1] = vec4(GetEdgeMap(p, 1, 1));
}
}
LoadFilterBanksSh(int(threadIdx), NIS_THREAD_GROUP_SIZE);
groupMemoryBarrier();
barrier();
// output coord within a tile
const ivec2 pos = ivec2(uint(threadIdx) % uint(NIS_BLOCK_WIDTH), uint(threadIdx) / uint(NIS_BLOCK_WIDTH));
// x coord inside the output image
const int dstX = dstBlockX + pos.x;
// x coord inside the input image
const float srcX = (0.5f + dstX) * kScaleX - 0.5f;
// nearest integer part
const int px = int(floor(srcX) - srcBlockStartX);
// fractional part
const float fx = srcX - floor(srcX);
// discretized phase
const int fx_int = int(fx * kPhaseCount);
for (int k = 0; k < NIS_BLOCK_WIDTH * NIS_BLOCK_HEIGHT / NIS_THREAD_GROUP_SIZE; ++k)
{
// y coord inside the output image
const int dstY = dstBlockY + pos.y + k * (NIS_THREAD_GROUP_SIZE / NIS_BLOCK_WIDTH);
// y coord inside the input image
const float srcY = (0.5f + dstY) * kScaleY - 0.5f;
// nearest integer part
const int py = int(floor(srcY) - srcBlockStartY);
// fractional part
const float fy = srcY - floor(srcY);
// discretized phase
const int fy_int = int(fy * kPhaseCount);
// generate weights for directional filters
const int startEdgeMapIdx = py * kEdgeMapPitch + px;
vec4 edge[2][2];
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
// need to shift edge map sampling since it's a 2x2 centered inside 6x6 grid
edge[i][j] = shEdgeMap[startEdgeMapIdx + (i * kEdgeMapPitch) + j];
}
}
const vec4 w = GetInterpEdgeMap(edge, fx, fy) * NIS_SCALE_INT;
// load 6x6 support to regs
const int startTileIdx = py * kTilePitch + px;
float p[6][6];
{
for (int i = 0; i < 6; ++i)
{
for (int j = 0; j < 6; ++j)
{
p[i][j] = shPixelsY[startTileIdx + i * kTilePitch + j];
}
}
}
// weigth for luma
const float baseWeight = NIS_SCALE_FLOAT - w.x - w.y - w.z - w.w;
// final luma is a weighted product of directional & normal filters
float opY = 0;
// get traditional scaler filter output
opY += FilterNormal(p, fx_int, fy_int) * baseWeight;
// get directional filter bank output
opY += AddDirFilters(p, fx, fy, fx_int, fy_int, w);
// do bilinear tap for luma upscaling
vec4 op = HOOKED_tex(vec2((srcX + 0.5f) * kSrcNormX, (srcY + 0.5f) * kSrcNormY));
const float corr = opY * (1.0f / NIS_SCALE_FLOAT) - op.r;
op.x += corr;
imageStore(out_image, ivec2(dstX, dstY), op);
}
}
//!TEXTURE coef_scaler
//!SIZE 2 64
//!FORMAT rgba32f
//!FILTER NEAREST
00000000000000000000803f0000000000000000000000000000000000000000ed0d3e3ba91350bc0000803fd044583c89d25ebb0000000000000000000000003b70ce3b16fbcbbcb29d7f3f645ddc3c89d2debb000000000000000000000000e02d103c98dd13bda4df7e3fe7fb293d55c128bc6f12033a00000000000000005bb13f3c812642bd5b427e3ff931663d1ea768bc6f12033a00000000000000001ea7683cfaed6bbdfb5c7d3fbc05923d744694bc6f12033a0000000000000000b9fc873c03098abda3017c3fc5feb23d5839b4bc6f12833a0000000000000000075f983cbf0e9cbdfa7e7a3ff4fdd43dd044d8bca69bc43a00000000000000009eefa73c7b14aebdde02793f22fdf63d4850fcbc6f12033b0000000000000000ec51b83ced0dbebd22fd763f4d840d3ee02d10bd52491d3b0000000000000000efc9c33c5f07cebdb81e753f098a1f3e9c3322bded0d3e3b0000000000000000a913d03c88f4dbbd01de723fa1f8313e7dd033bd89d25e3b0000000000000000d044d83cf90fe9bd4e62703f9487453e82e247bde02d903b0000000000000000d3bce33cb3eaf3bd849e6d3f50fc583e88f45bbd2e90a03b0000000000000000faedeb3cdbf9febd83c06a3f448b6c3e44fa6dbdca54c13b00000000000000008e06f03c6f8104be82e2673f1283803e250681bd3b70ce3b0000000000000000b537f83ccc7f08be6f81643f83c08a3e280f8bbdd734ef3b00000000000000004850fc3c16fb0bbe97ff603f7d3f953e2b1895bdb9fc073c00000000000000004850fc3c60760fbe849e5d3f77be9f3ec0ec9ebd075f183c00000000000000006e34003dbc0512beecc0593ffa7eaa3ec3f5a8bd55c1283c00000000000000006e34003dcff713bec6dc553f7d3fb53ec5feb2bd3480373c00000000000000006e34003d068115bea5bd513f8941c03ec807bdbd82e2473c00000000000000006e34003d2b8716befb5c4d3f0c02cb3ea60ac6bdf775603c00000000000000004850fc3c197317be151d493fa245d63ea913d0bdd7346f3c0000000000000000b537f83c197317be34a2443f933ae13e8716d9bd24977f3c0000000000000000211ff43c197317bec520403f9f3cec3e6519e2bdb9fc873c00000000000000008e06f03c2b8716be083d3b3fab3ef73ed5e7eabd7446943c0000000000000000faedeb3c068115be143f363f2041013ffc18f3bde3a59b3c0000000000000000d3bce33ccff713bee561313f27c2063fb515fbbd0ad7a33c000000000000000040a4df3cce8812be68222c3f2d430c3f250601bec520b03c0000000000000000d044d83c857c10bee71d273fa5bd113f810405beec51b83c0000000000000000a913d03c5f070ebe6ade213fe71d173fb9fc07be5bb1bf3c000000000000000082e2c73cf1f40abe287e1c3f287e1c3ff1f40abe82e2c73c00000000000000005bb1bf3cb9fc07bee71d173f6ade213f5f070ebea913d03c0000000000000000ec51b83c810405bea5bd113fe71d273f857c10bed044d83c0000000000000000c520b03c250601be2d430c3f68222c3fce8812be40a4df3c00000000000000000ad7a33cb515fbbd27c2063fe561313fcff713bed3bce33c0000000000000000e3a59b3cfc18f3bd2041013f143f363f068115befaedeb3c00000000000000007446943cd5e7eabdab3ef73e083d3b3f2b8716be8e06f03c0000000000000000b9fc873c6519e2bd9f3cec3ec520403f197317be211ff43c000000000000000024977f3c8716d9bd933ae13e34a2443f197317beb537f83c0000000000000000d7346f3ca913d0bda245d63e151d493f197317be4850fc3c0000000000000000f775603ca60ac6bd0c02cb3efb5c4d3f2b8716be6e34003d000000000000000082e2473cc807bdbd8941c03ea5bd513f068115be6e34003d00000000000000003480373cc5feb2bd7d3fb53ec6dc553fcff713be6e34003d000000000000000055c1283cc3f5a8bdfa7eaa3eecc0593fbc0512be6e34003d0000000000000000075f183cc0ec9ebd77be9f3e849e5d3f60760fbe4850fc3c0000000000000000b9fc073c2b1895bd7d3f953e97ff603f16fb0bbe4850fc3c0000000000000000d734ef3b280f8bbd83c08a3e6f81643fcc7f08beb537f83c00000000000000003b70ce3b250681bd1283803e82e2673f6f8104be8e06f03c0000000000000000ca54c13b44fa6dbd448b6c3e83c06a3fdbf9febdfaedeb3c00000000000000002e90a03b88f45bbd50fc583e849e6d3fb3eaf3bdd3bce33c0000000000000000e02d903b82e247bd9487453e4e62703ff90fe9bdd044d83c000000000000000089d25e3b7dd033bda1f8313e01de723f88f4dbbda913d03c0000000000000000ed0d3e3b9c3322bd098a1f3eb81e753f5f07cebdefc9c33c000000000000000052491d3be02d10bd4d840d3e22fd763fed0dbebdec51b83c00000000000000006f12033b4850fcbc22fdf63dde02793f7b14aebd9eefa73c0000000000000000a69bc43ad044d8bcf4fdd43dfa7e7a3fbf0e9cbd075f983c00000000000000006f12833a5839b4bcc5feb23da3017c3f03098abdb9fc873c00000000000000006f12033a744694bcbc05923dfb5c7d3ffaed6bbd1ea7683c00000000000000006f12033a1ea768bcf931663d5b427e3f812642bd5bb13f3c00000000000000006f12033a55c128bce7fb293da4df7e3f98dd13bde02d103c00000000000000000000000089d2debb645ddc3cb29d7f3f16fbcbbc3b70ce3b00000000000000000000000089d25ebbd044583c0000803fa91350bced0d3e3b0000000000000000
//!TEXTURE coef_usm
//!SIZE 2 64
//!FORMAT rgba32f
//!FILTER NEAREST
0000000027a019bf27a0993f27a019bf00000000000000000000000000000000ed0d3e3b1ac01bbf006f993fe71d17bfed0d3ebb0000000000000000000000002e90a03bfb5c1dbff90f993fe63f14bf89d2debb6f12033a0000000000000000d734ef3b1b9e1ebf2731983fd3de10bf55c128bc000000000000000000000000075f183cb29d1fbfcb10973fff210dbffe6577bc0000000000000000000000003480373c4e6220bf48bf953fde0209bf77be9fbc6f12033a000000000000000082e2473c128320bfe63f943f34a204bf3d2cd4bc6f12033a00000000000000001ea7683cd3de20bfbe9f923fc52000bfdcd701bd6f12033a000000000000000024977f3c4e6220bfa54e903f7d3ff5be091b1ebd6f12033a0000000000000000b9fc873cb29d1fbf6ff08d3fe7fbe9be5af539bd6f12833a0000000000000000e02d903c20631ebf4f408b3fe483debe3ee859bd6f12833a00000000000000007446943cff211dbf696f883fbc05d2be6de77bbda69bc43a0000000000000000e3a59b3ccc5d1bbf1b2f853ff8c2c4be4df38ebda69bc43a000000000000000077be9f3cecc019bf910f823f22fdb6be5305a3bd6f12033b00000000000000000ad7a33cbec117bfc4427d3f423ea8be10e9b7bd52491d3b00000000000000000ad7a33cf4fd14bf7d3f753f50fc98be3b01cdbded0d3e3b00000000000000000ad7a33c05a312bf0de06d3f5eba89be6519e2bd89d25e3b00000000000000000ad7a33c3bdf0fbf8fc2653fb37b72beb515fbbd24977f3b00000000000000009eefa73cb1bf0cbfc4425d3faa8251bef08509bee02d903b00000000000000000ad7a33c637f09bf6f81543f69002fbe190416be2e90a03b000000000000000077be9f3c4f1e06bfcc5d4b3f16fb0bbe418222be7cf2b03b000000000000000077be9f3c3cbd02bf4182423fce19d1bda08930beca54c13b0000000000000000e3a59b3c5b42febe151d393f4bea84bddbf93ebe3b70ce3b0000000000000000075f983c99bbf6bef2412f3ffaedebbc287e4cbe89d2de3b0000000000000000075f983c6900efbe4260253f075f183cac8b5bbed734ef3b0000000000000000e02d903c27c2e6be0c021b3fca32443dfa7e6abeb9fc073c00000000000000004d158c3c77bedfbea5bd113f57ecaf3d6c787abee02d103c000000000000000026e4833c22fdd6beab3e073f1283003e810485be2e90203c000000000000000026e4833cf241cfbe7502fa3ed578293e3b018dbe55c1283c0000000000000000fe65773cb003c7be143fe63e97ff503ef4fd94be0e4f2f3c00000000000000001ea7683cd200bebe857cd03e6c787a3eadfa9cbe5bb13f3c0000000000000000f775603c1904b6bea301bc3ebc05923e0b46a5be82e2473c0000000000000000d044583cd6c5adbeb003a73eb003a73ed6c5adbed044583c000000000000000082e2473c0b46a5bebc05923ea301bc3e1904b6bef775603c00000000000000005bb13f3cadfa9cbe6c787a3e857cd03ed200bebe1ea7683c00000000000000000e4f2f3cf4fd94be97ff503e143fe63eb003c7befe65773c000000000000000055c1283c3b018dbed578293e7502fa3ef241cfbe26e4833c00000000000000002e90203c810485be1283003eab3e073f22fdd6be26e4833c0000000000000000e02d103c6c787abe57ecaf3da5bd113f77bedfbe4d158c3c0000000000000000b9fc073cfa7e6abeca32443d0c021b3f27c2e6bee02d903c0000000000000000d734ef3bac8b5bbe075f183c4260253f6900efbe075f983c000000000000000089d2de3b287e4cbefaedebbcf2412f3f99bbf6be075f983c00000000000000003b70ce3bdbf93ebe4bea84bd151d393f5b42febee3a59b3c0000000000000000ca54c13ba08930bece19d1bd4182423f3cbd02bf77be9f3c00000000000000007cf2b03b418222be16fb0bbecc5d4b3f4f1e06bf77be9f3c00000000000000002e90a03b190416be69002fbe6f81543f637f09bf0ad7a33c0000000000000000e02d903bf08509beaa8251bec4425d3fb1bf0cbf9eefa73c000000000000000024977f3bb515fbbdb37b72be8fc2653f3bdf0fbf0ad7a33c000000000000000089d25e3b6519e2bd5eba89be0de06d3f05a312bf0ad7a33c0000000000000000ed0d3e3b3b01cdbd50fc98be7d3f753ff4fd14bf0ad7a33c000000000000000052491d3b10e9b7bd423ea8bec4427d3fbec117bf0ad7a33c00000000000000006f12033b5305a3bd22fdb6be910f823fecc019bf77be9f3c0000000000000000a69bc43a4df38ebdf8c2c4be1b2f853fcc5d1bbfe3a59b3c0000000000000000a69bc43a6de77bbdbc05d2be696f883fff211dbf7446943c00000000000000006f12833a3ee859bde483debe4f408b3f20631ebfe02d903c00000000000000006f12833a5af539bde7fbe9be6ff08d3fb29d1fbfb9fc873c00000000000000006f12033a091b1ebd7d3ff5bea54e903f4e6220bf24977f3c00000000000000006f12033adcd701bdc52000bfbe9f923fd3de20bf1ea7683c00000000000000006f12033a3d2cd4bc34a204bfe63f943f128320bf82e2473c00000000000000006f12033a77be9fbcde0209bf48bf953f4e6220bf3480373c000000000000000000000000fe6577bcff210dbfcb10973fb29d1fbf075f183c00000000000000000000000055c128bcd3de10bf2731983f1b9e1ebfd734ef3b00000000000000006f12033a89d2debbe63f14bff90f993ffb5c1dbf2e90a03b000000000000000000000000ed0d3ebbe71d17bf006f993f1ac01bbfed0d3e3b0000000000000000

Submodule .config/mpv/submodules/ModernZ added at 3b0c750466

Submodule .config/mpv/submodules/animecards added at ced1d30630

Submodule .config/mpv/submodules/autosubsync-mpv added at 125ac13d1b

Submodule .config/mpv/submodules/immersion-tracker added at f4a2c6012f

Submodule .config/mpv/submodules/mpv-anilist-updater added at a5851c4c0e

Submodule .config/mpv/submodules/mpv-youtube-queue added at 9d1b6d7eab

Submodule .config/mpv/submodules/mpv-youtube-upnext added at 33cb0eeffb

Submodule .config/mpv/submodules/mpvacious added at 2bbb89a4be

Submodule .config/mpv/submodules/thumbfast added at 9deb0733c4

Submodule .config/mpv/submodules/ytdl-preload added at 39759ecdc3

View File

@@ -26,6 +26,8 @@ return {
"typescript",
"rust",
"go",
"gowork",
"gotmpl",
"json",
"regex",
"latex",

36
.gitmodules vendored
View File

@@ -0,0 +1,36 @@
[submodule "/Users/sudacode/.config/mpv/submodules/mpv-youtube-upnext"]
path = /Users/sudacode/.config/mpv/submodules/mpv-youtube-upnext
url = https://github.com/ksyasuda/mpv-youtube-upnext
[submodule "/Users/sudacode/.config/mpv/submodules/mpv-youtube-queue"]
path = /Users/sudacode/.config/mpv/submodules/mpv-youtube-queue
url = https://github.com/ksyasuda/mpv-youtube-queue
[submodule "/Users/sudacode/.config/mpv/submodules/ModernZ"]
path = /Users/sudacode/.config/mpv/submodules/ModernZ
url = git@github.com:Samillion/ModernZ.git
[submodule "/Users/sudacode/.config/mpv/submodules/mpv-anilist-updater"]
path = /Users/sudacode/.config/mpv/submodules/mpv-anilist-updater
url = git@github.com:AzuredBlue/mpv-anilist-updater.git
[submodule "/Users/sudacode/.config/mpv/submodules/thumbfast"]
path = /Users/sudacode/.config/mpv/submodules/thumbfast
url = git@github.com:po5/thumbfast.git
[submodule "/Users/sudacode/.config/mpv/autosubsync-mpv"]
path = /Users/sudacode/.config/mpv/autosubsync-mpv
url = git@github.com:joaquintorres/autosubsync-mpv.git
[submodule "/Users/sudacode/.config/mpv/submodules/ytdl-preload"]
path = /Users/sudacode/.config/mpv/submodules/ytdl-preload
url = git@gist.github.com:17d90e3deeb35b5f75e55adb19098f58.git
[submodule "/Users/sudacode/.config/mpv/submodules/immersion-tracker"]
path = /Users/sudacode/.config/mpv/submodules/immersion-tracker
url = git@gitea.suda.codes:sudacode/immersion-tracker.git
[submodule "/Users/sudacode/.config/mpv/submodules/mpvacious"]
path = /Users/sudacode/.config/mpv/submodules/mpvacious
url = git@github.com:ksyasuda/mpvacious.git
[submodule "/Users/sudacode/.config/mpv/animecards"]
path = /Users/sudacode/.config/mpv/animecards
url = git@github.com:ksyasuda/Anacreon-Script
[submodule "/Users/sudacode/.config/mpv/submodules/animecards"]
path = /Users/sudacode/.config/mpv/submodules/animecards
url = git@github.com:ksyasuda/Anacreon-Script
[submodule "/Users/sudacode/.config/mpv/submodules/autosubsync-mpv"]
path = /Users/sudacode/.config/mpv/submodules/autosubsync-mpv
url = git@github.com:joaquintorres/autosubsync-mpv.git