@((( atom ))) Hast du dir die Lastverteilung bei dir mal angeschaut. Bei mir braucht das Dithering mit error-diffusion am meisten (70%). Rein visuell macht der Unterschied im Dithering zwischen error-diffusion und fruit vermutlich weniger aus, als zwischen mit und ohne die externen Shader.
Das Dithering benötigt bei mir auch um die 70%
Gestern habe ich mich ein wenig mit der Automatisierung beschäftigt. Ich habe ja eine komplett automatische Maskierung auf Basis von Metadaten am Film. Die Maskierung wird angesteuert und der Zoom im Player wird gesetzt. Ich war gestern so weit, dass ich per LUA-Script in MPV den Zoom abhängig von einem Tag im Dateinamen des Films (z.B. "ar=2.4") setzen konnte. Das funktioniert problemlos. Dann müsste ich nur noch per UDP eine Nachricht an meine Maskierungssteuerung senden. Auch das ist irgendwie machbar. Leider bringt der eingebaute LUA-Interpreter sowas nicht mit. Man müsste wohl LUA installieren, auf JavaScript umsteigen oder ein kleines Programm aufrufen, das die UDP-Pakete versendet. Dasselbe gilt für das Parsen von XML. Das hatte ich mir einfacher vorgestellt. Ist aber alles irgendwie machbar.
Ich benutze eine Custom Auflösung mit 3840x1600 (2.4:1). Mit dem https://github.com/mpv-player/…er/TOOLS/lua/autocrop.lua script passt sich jeder Film automatissch in die Leinwand ein.
Das Script habe ich inzwischen modifiziert und habe zusätzlich optionalen Stretch/Zoom für unterschiedliche Formate hinzugefügt um das Bild auf 2.4:1 anzupassen.
Dazu benutzt man dann die Shift+C Taste um den Zoom anzupassen und es funktioniert komplett ohne Dateinamenänderungen etc. Bei allen formaten > 1.9:1 habe ich das momentan automatisch aktiviert.
Zusätzlich habe ich noch die Oberfläche angepasst und habe den Fullscreenbutton unten rechts mit einer "Toggle Zoom" Funktion ersetzt, womit ich die Funktion ein-/auschalten kann
Edit: meine momentanten Version von autocrop mit stretch/zoom/crop:
Vlt kann damit jemand was anfangen
--[[
This script uses the lavfi cropdetect filter to automatically
insert a crop filter with appropriate parameters for the
currently playing video.
It will automatically crop the video, when playback starts.
Also It registers the key-binding "C" (shift+c). You can manually
crop the video by pressing the "C" (shift+c) key.
If the "C" key is pressed again, the crop filter is removed
restoring playback to its original state.
The workflow is as follows: First, it inserts the filter
vf=lavfi=cropdetect. After <detect_seconds> (default is 1)
seconds, it then inserts the filter vf=crop=w:h:x:y, where
w,h,x,y are determined from the vf-metadata gathered by
cropdetect. The cropdetect filter is removed immediately after
the crop filter is inserted as it is no longer needed.
Since the crop parameters are determined from the 1 second of
video between inserting the cropdetect and crop filters, the "C"
key should be pressed at a position in the video where the crop
region is unambiguous (i.e., not a black frame, black background
title card, or dark scene).
The default options can be overridden by adding
script-opts-append=autocrop-<parameter>=<value> into mpv.conf
List of available parameters (For default values, see <options>):
auto: bool - Whether to automatically apply crop at the start of
playback. If you don't want to crop automatically, set it to
false or add "script-opts-append=autocrop-auto=no" into
mpv.conf.
auto_delay: seconds - Delay before starting crop in auto mode.
You can try to increase this value to avoid dark scene or
fade in at beginning. Automatic cropping will not occur if
the value is larger than the remaining playback time.
detect_limit: number[0-255] - Black threshold for cropdetect.
Smaller values will generally result in less cropping.
See limit of https://ffmpeg.org/ffmpeg-filters.html#cropdetect
detect_round: number[2^n] - The value which the width/height
should be divisible by. Smaller values have better detection
accuracy. If you have problems with other filters,
you can try to set it to 4 or 16.
See round of https://ffmpeg.org/ffmpeg-filters.html#cropdetect
detect_min_ratio: number[0.0-1.0] - The ratio of the minimum clip
size to the original. If the picture is over cropped or under
cropped, try adjusting this value.
detect_seconds: seconds - How long to gather cropdetect data.
Increasing this may be desirable to allow cropdetect more
time to collect data.
suppress_osd: bool - Whether the OSD shouldn't be used when filters
are applied and removed.
--]]
require "mp.msg"
require 'mp.options'
local options = {
auto = true,
auto_delay = 4,
detect_limit = "10/255",
detect_round = 2,
detect_min_ratio = 0.5,
detect_seconds = 3,
suppress_osd = false,
}
read_options(options)
local from_start = 1
local label_prefix = mp.get_script_name()
local labels = {
crop = string.format("%s-crop", label_prefix),
cropdetect = string.format("%s-cropdetect", label_prefix)
}
timers = {
auto_delay = nil,
detect_crop = nil
}
local command_prefix = options.suppress_osd and 'no-osd' or ''
function is_filter_present(label)
local filters = mp.get_property_native("vf")
for index, filter in pairs(filters) do
if filter["label"] == label then
return true
end
end
return false
end
function is_zoom_present()
if mp.get_property("video-scale-x") ~= "1.000000" then
return true
end
return false
end
function is_enough_time(seconds)
-- Plus 1 second for deviation.
local time_needed = seconds + 1
local playtime_remaining = mp.get_property_native("playtime-remaining")
return playtime_remaining and time_needed < playtime_remaining
end
function is_cropable()
for _, track in pairs(mp.get_property_native('track-list')) do
if track.type == 'video' and track.selected then
return not track.albumart
end
end
return false
end
function remove_filter(label)
if is_filter_present(label) then
mp.command(string.format('%s vf remove @%s', command_prefix, label))
return true
end
return false
end
function toggle_zoom()
if is_zoom_present() then
mp.command(string.format("%s set video-scale-x 1", command_prefix ))
mp.command(string.format("%s set video-scale-y 1", command_prefix ))
mp.command(string.format("%s set video-align-y 0.5",command_prefix ))
return true
end
return false
end
function cleanup()
-- Remove all existing filters.
for key, value in pairs(labels) do
remove_filter(value)
end
-- Kill all timers.
for index, timer in pairs(timers) do
if timer then
timer:kill()
timer = nil
end
end
end
function detect_crop()
-- If it's not cropable, exit.
if not is_cropable() then
mp.msg.warn("autocrop only works for videos.")
return
end
-- Verify if there is enough time to detect crop.
local time_needed = options.detect_seconds
if not is_enough_time(time_needed) then
mp.msg.warn("Not enough time to detect crop.")
return
end
-- Insert the cropdetect filter.
local limit = options.detect_limit
local round = options.detect_round
mp.command(
string.format(
'%s vf pre @%s:cropdetect=limit=%s:round=%d:reset=0',
command_prefix, labels.cropdetect, limit, round
)
)
-- Wait to gather data.
timers.detect_crop = mp.add_timeout(time_needed, detect_end)
end
function detect_end()
-- Get the metadata and remove the cropdetect filter.
local cropdetect_metadata =
mp.get_property_native(
string.format("vf-metadata/%s",
labels.cropdetect
)
)
remove_filter(labels.cropdetect)
-- Remove the timer of detect crop.
if timers.detect_crop then
timers.detect_crop:kill()
timers.detect_crop = nil
end
local meta = {}
-- Verify the existence of metadata.
if cropdetect_metadata then
meta = {
w = cropdetect_metadata["lavfi.cropdetect.w"],
h = cropdetect_metadata["lavfi.cropdetect.h"],
x = cropdetect_metadata["lavfi.cropdetect.x"],
y = cropdetect_metadata["lavfi.cropdetect.y"],
}
else
mp.msg.error("No crop data.")
mp.msg.info("Was the cropdetect filter successfully inserted?")
mp.msg.info("Does your version of ffmpeg/libav support AVFrame metadata?")
return
end
-- Verify that the metadata meets the requirements and convert it.
if meta.w and meta.h and meta.x and meta.y then
local width = mp.get_property_native("width")
local height = mp.get_property_native("height")
meta = {
w = tonumber(meta.w),
h = tonumber(meta.h),
x = tonumber(meta.x),
y = tonumber(meta.y),
min_w = width * options.detect_min_ratio,
min_h = height * options.detect_min_ratio,
max_w = width,
max_h = height
}
else
mp.msg.error("Got empty crop data.")
mp.msg.info("You might need to increase detect_seconds.")
return
end
apply_crop(meta)
end
function sleep (a)
local sec = tonumber(os.clock() + a);
while (os.clock() < sec) do
end
end
function apply_crop(meta)
-- Verify if it is necessary to crop.
local is_effective = meta.x > 0 or meta.y > 0
or meta.w < meta.max_w or meta.h < meta.max_h
-- Verify it is not over cropped.
local is_excessive = meta.w < meta.min_w and meta.h < meta.min_h
if is_excessive then
mp.msg.info("The area to be cropped is too large.")
mp.msg.info("You might need to decrease detect_min_ratio.")
return
end
-- Remove existing crop.
remove_filter(labels.crop)
-- Apply crop.
mp.command(
string.format("%s vf pre @%s:lavfi-crop=w=%s:h=%s:x=%s:y=%s",
command_prefix, labels.crop, meta.w, meta.h, meta.x, meta.y
)
)
local ratio = meta.w / meta.h
--mp.osd_message(ratio, 1)
if from_start == 0 then
-- add ratios that should not always zoom at start here
-- 16:9
if ratio >= 1.77 and ratio <= 1.78 then
mp.command(string.format("%s set video-scale-x 1.35", command_prefix ))
mp.command(string.format("%s set video-scale-y 1.25", command_prefix ))
mp.command(string.format("%s set video-align-y 0.515",command_prefix ))
mp.osd_message("16:9 detected",1)
end
end
-- ratio that should always zoom at start after this one
-- 1.9:1
if ratio >= 1.8999 and ratio <= 1.900001 then
mp.command(string.format("%s set video-scale-x 1.263", command_prefix ))
mp.command(string.format("%s set video-scale-y 1.12", command_prefix ))
mp.command(string.format("%s set video-align-y 0.51",command_prefix ))
mp.osd_message("1.9:1 detected",1)
end
-- 2:1
if ratio >= 1.9999 and ratio <= 2.000001 then
mp.command(string.format("%s set video-scale-x 1.2", command_prefix ))
mp.command(string.format("%s set video-scale-y 1.15", command_prefix ))
mp.command(string.format("%s set video-align-y 0.505",command_prefix ))
mp.osd_message("2:1 detected",1)
end
-- 2.2:1
if ratio >= 2.19999 and ratio <= 2.200001 then
mp.command(string.format("%s set video-scale-x 1.092", command_prefix ))
mp.command(string.format("%s set video-scale-y 1.105", command_prefix ))
mp.command(string.format("%s set video-align-y 0.5",command_prefix ))
mp.osd_message("2.2:1 detected",1)
end
-- 2.3:1 and higher
if ratio >= 2.3 then
mp.command(string.format("%s set video-scale-x %s", command_prefix, 2.4/ratio ))
mp.command(string.format("%s set video-scale-y %s", command_prefix, 2.4/ratio ))
mp.command(string.format("%s set video-align-y 0.5", command_prefix ))
--mp.osd_message("zoom small bars away",1)
end
end
function on_start()
-- Clean up at the beginning.
cleanup()
-- If auto is not true, exit.
if not options.auto then
return
end
-- If it is the beginning, wait for detect_crop
-- after auto_delay seconds, otherwise immediately.
local playback_time = mp.get_property_native("playback-time")
local is_delay_needed = playback_time
and options.auto_delay > playback_time
if is_delay_needed then
-- Verify if there is enough time for autocrop.
local time_needed = options.auto_delay + options.detect_seconds
if not is_enough_time(time_needed) then
mp.msg.warn("Not enough time for autocrop.")
return
end
timers.auto_delay = mp.add_timeout(time_needed,
function()
detect_crop()
-- Remove the timer of auto delay.
timers.auto_delay:kill()
timers.auto_delay = nil
end
)
else
detect_crop()
end
end
function on_toggle()
from_start = 0
-- If it is during auto_delay, kill the timer.
if timers.auto_delay then
timers.auto_delay:kill()
timers.auto_delay = nil
end
-- Cropped => Remove it.
if toggle_zoom() then
return
end
-- Detecting => Leave it.
if timers.detect_crop then
mp.msg.warn("Already cropdetecting!")
return
end
-- Neither => Do delectcrop.
detect_crop()
end
mp.add_key_binding("C", "toggle_crop", on_toggle)
mp.register_event("end-file", cleanup)
mp.register_event("file-loaded", on_start)
Alles anzeigen
Für die Modifizerung des Buttons habe ich die "osc.lua" aus git in den script orderner gepackt und in der config das original osc ausgeschaltet (osc=no)
Danach im osc.lua Script die Zeilen geändert:
-- removed old lines
--ne.eventresponder["mbtn_left_up"] =
--function () mp.commandv("cycle", "fullscreen") end
-- add new lines
ne.eventresponder["mbtn_left_up"] =
function () mp.command("keypress C") end
Für Fullscreen toggle benutze ich eh Doppelklick
Zur Vollständigkeit hier noch meine momentane Config:
#############################
# General #
#############################
profile=gpu-hq
input-ipc-server=mpvpipe
ao=wasapi
audio-exclusive=yes
audio-spdif=ac3,eac3,dts-hd,truehd,dts
#############################
# Subs and languages #
#############################
subs-with-matching-audio=no
sub-scale=1.25
slang=en,eng,de,ger
sub-forced-only=yes
alang=en,eng,fr,de
sid=no
#############################
# Window settings #
#############################
autofit=50% # for no fullscreen
geometry=100%:100% # for no fullscreen
ontop
snap-window
minmousemove=500
video-sync=display-resample
hr-seek-framedrop=no
no-resume-playback
border=no
osc=no
##############################
# script settings #
##############################
script-opts-append=autocrop-suppress_osd=yes
##############################
# Video Stuff #
##############################
video-output-levels=full
target-prim=dci-p3
hwdec=auto-copy
hdr-compute-peak=yes
target-trc=gamma2.2
tone-mapping=reinhard
tone-mapping-param=0.1
tone-mapping-max-boost=2.0
tone-mapping-desaturate=0.75
tone-mapping-desaturate-exponent=1.5
no-gamut-clipping
hdr-peak-decay-rate=50
dither-depth=auto
dither=error-diffusion
deband=yes
deband-iterations=4
deband-threshold=48
deband-grain=48
deband-range=16
scale=ewa_lanczossharp
cscale=ewa_lanczossharp
dscale=mitchell
correct-downscaling=yes
linear-downscaling=yes
sigmoid-upscaling=yes
scale-antiring=0.6 # luma upscale deringing
dscale-antiring=0.6 # luma downscale deringing
cscale-antiring=0.5 # chroma upscale deringing
glsl-shaders-clr
glsl-shaders="C:\Users\User\AppData\Roaming\mpv\Shaders\FSRCNNX_x2_8-0-4-1.glsl"
glsl-shaders-append="C:\Users\User\AppData\Roaming\mpv\Shaders\KrigBilateral.glsl"
glsl-shaders-append="C:\Users\User\AppData\Roaming\mpv\Shaders\adaptive-sharpen.glsl"
#log-file=log.txt
[HDR]
profile-desc=HDR options
profile-cond=width > 1920
target-peak=110
fs=yes
[SDR]
profile-desc=SDR options
profile-cond=width < 1921
#brightness=2
#gamma=1
fs=yes
Alles anzeigen