Package: guix-patches;
Reported by: Tomas Volf <~@wolfsden.cz>
Date: Wed, 11 Dec 2024 21:54:02 UTC
Severity: normal
Tags: patch
Done: Maxim Cournoyer <maxim.cournoyer <at> gmail.com>
To reply to this bug, email your comments to 74801 AT debbugs.gnu.org.
There is no need to reopen the bug first.
Toggle the display of automated, internal messages from the tracker.
View this report as an mbox folder, status mbox, maintainer mbox
, guix-patches <at> gnu.org
:bug#74801
; Package guix-patches
.
(Wed, 11 Dec 2024 21:54:02 GMT) Full text and rfc822 format available.Tomas Volf <~@wolfsden.cz>
:, guix-patches <at> gnu.org
.
(Wed, 11 Dec 2024 21:54:02 GMT) Full text and rfc822 format available.Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
From: Tomas Volf <~@wolfsden.cz> To: guix-patches <at> gnu.org Cc: Tomas Volf <~@wolfsden.cz> Subject: [PATCH] gnu: home: services: Add home-mpv-service-type. Date: Wed, 11 Dec 2024 22:50:22 +0100
This commit adds a new service type to generate configuration file for the mpv media player. Originally I attempted to use Guix Records (via define-configuration) for this, but ran into the bug #74748, so I had to switch to procedures instead. The usage is (hopefully) sufficiently described in the documentation. When the bug is resolved, I will update it to use define-configuration instead. The full list of supported options is documented, however I decided to *not* document types and purpose for each individual fields. While I had mostly working prototype to extract the documentation from mpv, once I realized it would be few 10k of lines added, I decided it is not worth it. It would bloat the .texi file (by more than 50%), be hard to maintain and, in my opinion, would not provide enough value to justify that. The current version seems like sane middle ground. Option to configure inputs (for mpv) will come later in a separate patch. * gnu/home/services/mpv.scm: New file. * gnu/local.mk (GNU_SYSTEM_MODULES): Register it. * doc/guix.texi (mpv Media Player): Document it. Change-Id: I2deb44799a28047cb5d67da97dc6007a9df873af --- The change itself is not that large. Everything between `START.' and `END.' can be skipped in the code review. The (semi-)interesting parts are above and below. I would prefer to use define-configuration instead of reinventing the wheel, and I even had it implemented, but the performance is just unusable. Waiting 30s after hitting ENTER in the REPL is unbearable. doc/guix.texi | 427 ++++++ gnu/home/services/mpv.scm | 2722 +++++++++++++++++++++++++++++++++++++ gnu/local.mk | 1 + 3 files changed, 3150 insertions(+) create mode 100644 gnu/home/services/mpv.scm diff --git a/doc/guix.texi b/doc/guix.texi index 49c87700b9..249cb323e3 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -47711,6 +47711,433 @@ Media Home Services @end table @end deftp +@c This is ugly, but upstream does *not* capitalize the ``m'' even when +@c at the beginning of a sentence. So let us follow the branding. +@node mpv Media Player +@subsection mpv Media Player + +@cindex mpv, Home Service +@cindex mpv, configuration +Configuring the @uref{https://mpv.io/, mpv media player} can be somewhat +daunting task, due to the sheer amount of options available, especially +if one wants to be able to inherit the configuration in their code. The +@code{home-mpv-service-type} is provided to help with that problem. +When the service is added to your home environment, file based on the +passed configuration is generated and placed into the correct location. + +Due to the bug #74748, it does not use Guix Records to represent the +configuration, but uses keyword arguments to achieve similar result. +Example follows: + +@lisp +(service home-mpv-service-type + (make-home-mpv-configuration + #:global (make-mpv-profile-configuration + #:fullscreen #t + #:alang '("jpn" "eng")))) +@end lisp + +@defvar home-mpv-service-type +This is the type of the mpv home service, whose value is a +@code{home-mpv-configuration} object. +@end defvar + +@deffn {Procedure} make-home-mpv-configuration +Return a new instance of @code{home-mpv-configuration}. Available +keyword arguments are: + +@table @asis +@item @code{inherit} (default: @code{#t}) +Inherit fields from an another instance. + +@item @code{global} (default: @code{(make-mpv-profile-configuration)}) +The global configuration preceding all profiles. + +@item @code{profiles} (default: @code{()}) +An alist containing configuration for any additional profiles to include +in the configuration file. + +@lisp +(make-home-mpv-configuration + #:profiles `((fullscreen . ,(make-mpv-profile-configuration + #:fullscreen #t)))) +@end lisp + +@item @code{extra-config} (default: @code{#f}) +Additional content to include in the configuration file. It is placed +at the end of the file. + +@end table +@end deffn + +@deffn {Procedure} make-mpv-profile-configuration +Return a new instance of @code{mpv-profile-configuration}. As above, it +also supports the @code{#:inherit} argument. Additionally it supports +keyword arguments named after the options of @command{mpv}. Hence +@option{--fullscreen} (or @code{fullscreen} in the configuration file) +becomes @code{#:fullscreen}. + +Few options are using their aliases instead. @option{audio} instead of +@option{aid}, @option{video} instead of @option{vid}, @option{sub} +instead of @option{sid}, @option{screenshot-directory} instead of +@option{screenshot-dir} and @option{watch-later-directory} instead of +@option{watch-later-dir}. + +Valid values for the fields depend on their type. + +@table @asis +@item Flags +The value is evaluated for truthfulness. Typically you would use +@code{#f} or @code{#t}. + +@item Numerical fields +Integer and integer64 fields are validated by @code{integer?}, float and +double fields by @code{real?}. Ranges are checked when applicable. + +@item Aspect +Same as integer. + +@item ByteSize +Same as integer64. + +@item Choice +The value should be a symbol representing member of the enumeration. If +the choice has @samp{or ...} part, it can also be value of that +alternative type. + +@item @var{type} list +The value should be a list of the @var{type}. + +@end table + +Other types accept strings, with validation of the values where possible +(e.g. type @samp{Color} is validated, but type @samp{Audio channels or +channel map} is not). + +The full list of currently supported keyword arguments is below. For +the types, allowed values and full description please refer to the +@command{mpv --list-options} and +@uref{https://mpv.io/manual/stable/#options, mpv manual}. + +Only set fields are outputted to the configuration file. Accessors are +provided for every field, returning either their value or a sentinel +object @code{%unset}. + +@code{ab-loop-a}, @code{ab-loop-b}, @code{ab-loop-count}, +@code{access-references}, @code{ad}, @code{ad-lavc-ac3drc}, +@code{ad-lavc-downmix}, @code{ad-lavc-o}, @code{ad-lavc-threads}, +@code{ad-queue-enable}, @code{ad-queue-max-bytes}, +@code{ad-queue-max-samples}, @code{ad-queue-max-secs}, @code{af}, +@code{audio}, @code{alang}, @code{allow-delayed-peak-detect}, +@code{alsa-buffer-time}, @code{alsa-ignore-chmap}, +@code{alsa-mixer-device}, @code{alsa-mixer-index}, +@code{alsa-mixer-name}, @code{alsa-non-interleaved}, +@code{alsa-periods}, @code{alsa-resample}, @code{ao}, +@code{ao-null-broken-delay}, @code{ao-null-broken-eof}, +@code{ao-null-buffer}, @code{ao-null-channel-layouts}, +@code{ao-null-format}, @code{ao-null-latency}, @code{ao-null-outburst}, +@code{ao-null-speed}, @code{ao-null-untimed}, @code{ao-pcm-append}, +@code{ao-pcm-file}, @code{ao-pcm-waveheader}, +@code{audio-backward-batch}, @code{audio-backward-overlap}, +@code{audio-buffer}, @code{audio-channels}, @code{audio-client-name}, +@code{audio-delay}, @code{audio-demuxer}, @code{audio-device}, +@code{audio-display}, @code{audio-exclusive}, @code{audio-exts}, +@code{audio-fallback-to-null}, @code{audio-file-auto}, +@code{audio-file-paths}, @code{audio-files}, @code{audio-format}, +@code{audio-normalize-downmix}, @code{audio-pitch-correction}, +@code{audio-resample-cutoff}, @code{audio-resample-filter-size}, +@code{audio-resample-linear}, @code{audio-resample-max-output-size}, +@code{audio-resample-phase-shift}, @code{audio-reversal-buffer}, +@code{audio-samplerate}, @code{audio-spdif}, +@code{audio-stream-silence}, @code{audio-swresample-o}, +@code{audio-wait-open}, @code{auto-window-resize}, +@code{autocreate-playlist}, @code{autofit}, @code{autofit-larger}, +@code{autofit-smaller}, @code{autoload-files}, @code{autosync}, +@code{background}, @code{background-color}, @code{blend-subtitles}, +@code{bluray-device}, @code{border}, @code{border-background}, +@code{brightness}, @code{cache}, @code{cache-on-disk}, +@code{cache-pause}, @code{cache-pause-initial}, @code{cache-pause-wait}, +@code{cache-secs}, @code{cdda-cdtext}, @code{cdda-device}, +@code{cdda-overlap}, @code{cdda-paranoia}, @code{cdda-sector-size}, +@code{cdda-skip}, @code{cdda-span-a}, @code{cdda-span-b}, +@code{cdda-speed}, @code{cdda-toc-offset}, +@code{chapter-merge-threshold}, @code{chapter-seek-threshold}, +@code{chapters-file}, @code{config}, @code{container-fps-override}, +@code{contrast}, @code{cookies}, @code{cookies-file}, +@code{corner-rounding}, @code{correct-downscaling}, @code{correct-pts}, +@code{cover-art-auto}, @code{cover-art-files}, +@code{cover-art-whitelist}, @code{cscale}, @code{cscale-antiring}, +@code{cscale-blur}, @code{cscale-clamp}, @code{cscale-param1}, +@code{cscale-param2}, @code{cscale-radius}, @code{cscale-taper}, +@code{cscale-window}, @code{cscale-wparam}, @code{cscale-wtaper}, +@code{cursor-autohide}, @code{cursor-autohide-fs-only}, @code{deband}, +@code{deband-grain}, @code{deband-iterations}, @code{deband-range}, +@code{deband-threshold}, @code{deinterlace}, +@code{deinterlace-field-parity}, @code{demuxer}, +@code{demuxer-backward-playback-step}, @code{demuxer-cache-dir}, +@code{demuxer-cache-unlink-files}, @code{demuxer-cache-wait}, +@code{demuxer-donate-buffer}, @code{demuxer-hysteresis-secs}, +@code{demuxer-lavf-allow-mimetype}, @code{demuxer-lavf-analyzeduration}, +@code{demuxer-lavf-buffersize}, @code{demuxer-lavf-format}, +@code{demuxer-lavf-hacks}, @code{demuxer-lavf-linearize-timestamps}, +@code{demuxer-lavf-o}, @code{demuxer-lavf-probe-info}, +@code{demuxer-lavf-probescore}, @code{demuxer-lavf-probesize}, +@code{demuxer-lavf-propagate-opts}, @code{demuxer-max-back-bytes}, +@code{demuxer-max-bytes}, @code{demuxer-mkv-probe-start-time}, +@code{demuxer-mkv-probe-video-duration}, +@code{demuxer-mkv-subtitle-preroll}, +@code{demuxer-mkv-subtitle-preroll-secs}, +@code{demuxer-mkv-subtitle-preroll-secs-index}, +@code{demuxer-rawaudio-channels}, @code{demuxer-rawaudio-format}, +@code{demuxer-rawaudio-rate}, @code{demuxer-rawvideo-codec}, +@code{demuxer-rawvideo-format}, @code{demuxer-rawvideo-fps}, +@code{demuxer-rawvideo-h}, @code{demuxer-rawvideo-mp-format}, +@code{demuxer-rawvideo-size}, @code{demuxer-rawvideo-w}, +@code{demuxer-readahead-secs}, @code{demuxer-seekable-cache}, +@code{demuxer-termination-timeout}, @code{demuxer-thread}, +@code{directory-filter-types}, @code{directory-mode}, +@code{display-fps-override}, @code{display-tags}, @code{dither}, +@code{dither-depth}, @code{dither-size-fruit}, @code{drag-and-drop}, +@code{drm-connector}, @code{drm-device}, @code{drm-draw-plane}, +@code{drm-draw-surface-size}, @code{drm-drmprime-video-plane}, +@code{drm-format}, @code{drm-mode}, @code{drm-vrr-enabled}, +@code{dscale}, @code{dscale-antiring}, @code{dscale-blur}, +@code{dscale-clamp}, @code{dscale-param1}, @code{dscale-param2}, +@code{dscale-radius}, @code{dscale-taper}, @code{dscale-window}, +@code{dscale-wparam}, @code{dscale-wtaper}, @code{dump-stats}, +@code{dvbin-card}, @code{dvbin-channel-switch-offset}, +@code{dvbin-file}, @code{dvbin-full-transponder}, @code{dvbin-prog}, +@code{dvbin-timeout}, @code{dvd-angle}, @code{dvd-device}, +@code{dvd-speed}, @code{edition}, @code{egl-config-id}, +@code{egl-output-format}, @code{embeddedfonts}, @code{end}, +@code{error-diffusion}, @code{external-files}, @code{fbo-format}, +@code{focus-on}, @code{force-media-title}, @code{force-render}, +@code{force-rgba-osd-rendering}, @code{force-seekable}, +@code{force-window}, @code{force-window-position}, @code{framedrop}, +@code{frames}, @code{fs-screen}, @code{fs-screen-name}, +@code{fullscreen}, @code{gamma}, @code{gamma-auto}, @code{gamma-factor}, +@code{gamut-mapping-mode}, @code{gapless-audio}, @code{geometry}, +@code{glsl-shader-opts}, @code{glsl-shaders}, @code{gpu-api}, +@code{gpu-context}, @code{gpu-debug}, @code{gpu-dumb-mode}, +@code{gpu-hwdec-interop}, @code{gpu-shader-cache}, +@code{gpu-shader-cache-dir}, @code{gpu-sw}, @code{gpu-tex-pad-x}, +@code{gpu-tex-pad-y}, @code{hdr-compute-peak}, +@code{hdr-contrast-recovery}, @code{hdr-contrast-smoothness}, +@code{hdr-peak-decay-rate}, @code{hdr-peak-percentile}, +@code{hdr-scene-threshold-high}, @code{hdr-scene-threshold-low}, +@code{hidpi-window-scale}, @code{hls-bitrate}, @code{hr-seek}, +@code{hr-seek-demuxer-offset}, @code{hr-seek-framedrop}, +@code{http-header-fields}, @code{http-proxy}, @code{hue}, @code{hwdec}, +@code{hwdec-codecs}, @code{hwdec-extra-frames}, +@code{hwdec-image-format}, @code{icc-3dlut-size}, @code{icc-cache}, +@code{icc-cache-dir}, @code{icc-force-contrast}, @code{icc-intent}, +@code{icc-profile}, @code{icc-profile-auto}, @code{icc-use-luma}, +@code{idle}, @code{ignore-path-in-watch-later-config}, +@code{image-display-duration}, @code{image-exts}, @code{image-lut}, +@code{image-lut-type}, @code{image-subs-video-resolution}, +@code{include}, @code{index}, @code{initial-audio-sync}, +@code{input-ar-delay}, @code{input-ar-rate}, +@code{input-builtin-bindings}, @code{input-builtin-dragging}, +@code{input-commands}, @code{input-conf}, @code{input-cursor}, +@code{input-cursor-passthrough}, @code{input-default-bindings}, +@code{input-doubleclick-time}, @code{input-dragging-deadzone}, +@code{input-ipc-client}, @code{input-ipc-server}, +@code{input-key-fifo-size}, @code{input-media-keys}, +@code{input-preprocess-wheel}, @code{input-right-alt-gr}, +@code{input-terminal}, @code{input-test}, +@code{input-touch-emulate-mouse}, @code{input-vo-keyboard}, +@code{interpolation}, @code{interpolation-preserve}, +@code{interpolation-threshold}, @code{inverse-tone-mapping}, +@code{jack-autostart}, @code{jack-connect}, @code{jack-name}, +@code{jack-port}, @code{jack-std-channel-layout}, @code{keep-open}, +@code{keep-open-pause}, @code{keepaspect}, @code{keepaspect-window}, +@code{lavfi-complex}, @code{length}, @code{libplacebo-opts}, +@code{linear-downscaling}, @code{linear-upscaling}, +@code{load-auto-profiles}, @code{load-osd-console}, @code{load-scripts}, +@code{load-select}, @code{load-stats-overlay}, +@code{load-unsafe-playlists}, @code{log-file}, @code{loop-file}, +@code{loop-playlist}, @code{lut}, @code{lut-type}, @code{mc}, +@code{media-controls}, @code{merge-files}, @code{metadata-codepage}, +@code{mf-fps}, @code{mf-type}, @code{monitoraspect}, +@code{monitorpixelaspect}, @code{msg-color}, @code{msg-level}, +@code{msg-module}, @code{msg-time}, @code{mute}, @code{native-fs}, +@code{native-keyrepeat}, @code{native-touch}, @code{network-timeout}, +@code{oac}, @code{oacopts}, @code{ocopy-metadata}, @code{of}, +@code{ofopts}, @code{on-all-workspaces}, @code{ontop}, +@code{ontop-level}, @code{opengl-check-pattern-a}, +@code{opengl-check-pattern-b}, @code{opengl-early-flush}, +@code{opengl-es}, @code{opengl-glfinish}, @code{opengl-pbo}, +@code{opengl-rectangle-textures}, @code{opengl-swapinterval}, +@code{opengl-waitvsync}, @code{orawts}, @code{ordered-chapters}, +@code{ordered-chapters-files}, @code{oremove-metadata}, @code{osc}, +@code{osd-align-x}, @code{osd-align-y}, @code{osd-back-color}, +@code{osd-bar}, @code{osd-bar-align-x}, @code{osd-bar-align-y}, +@code{osd-bar-h}, @code{osd-bar-outline-size}, @code{osd-bar-w}, +@code{osd-blur}, @code{osd-bold}, @code{osd-border-style}, +@code{osd-color}, @code{osd-duration}, @code{osd-font}, +@code{osd-font-provider}, @code{osd-font-size}, @code{osd-fonts-dir}, +@code{osd-fractions}, @code{osd-italic}, @code{osd-justify}, +@code{osd-level}, @code{osd-margin-x}, @code{osd-margin-y}, +@code{osd-msg1}, @code{osd-msg2}, @code{osd-msg3}, @code{osd-on-seek}, +@code{osd-outline-color}, @code{osd-outline-size}, +@code{osd-playing-msg}, @code{osd-playing-msg-duration}, +@code{osd-playlist-entry}, @code{osd-scale}, @code{osd-scale-by-window}, +@code{osd-shadow-offset}, @code{osd-spacing}, @code{osd-status-msg}, +@code{oset-metadata}, @code{ovc}, @code{ovcopts}, @code{panscan}, +@code{pause}, @code{pitch}, @code{play-direction}, +@code{player-operation-mode}, @code{playlist-start}, +@code{prefetch-playlist}, @code{profile}, @code{pulse-allow-suspended}, +@code{pulse-buffer}, @code{pulse-host}, @code{pulse-latency-hacks}, +@code{quiet}, @code{really-quiet}, @code{rebase-start-time}, +@code{referrer}, @code{replaygain}, @code{replaygain-clip}, +@code{replaygain-fallback}, @code{replaygain-preamp}, +@code{reset-on-next-file}, @code{resume-playback}, +@code{resume-playback-check-mtime}, @code{rtsp-transport}, +@code{saturation}, @code{save-position-on-quit}, @code{scale}, +@code{scale-antiring}, @code{scale-blur}, @code{scale-clamp}, +@code{scale-param1}, @code{scale-param2}, @code{scale-radius}, +@code{scale-taper}, @code{scale-window}, @code{scale-wparam}, +@code{scale-wtaper}, @code{scaler-resizes-only}, @code{screen}, +@code{screen-name}, @code{screenshot-avif-encoder}, +@code{screenshot-avif-opts}, @code{screenshot-avif-pixfmt}, +@code{screenshot-directory}, @code{screenshot-format}, +@code{screenshot-high-bit-depth}, @code{screenshot-jpeg-quality}, +@code{screenshot-jpeg-source-chroma}, @code{screenshot-jxl-distance}, +@code{screenshot-jxl-effort}, @code{screenshot-png-compression}, +@code{screenshot-png-filter}, @code{screenshot-sw}, +@code{screenshot-tag-colorspace}, @code{screenshot-template}, +@code{screenshot-webp-compression}, @code{screenshot-webp-lossless}, +@code{screenshot-webp-quality}, @code{script-opts}, @code{scripts}, +@code{secondary-sid}, @code{secondary-sub-ass-override}, +@code{secondary-sub-delay}, @code{secondary-sub-pos}, +@code{secondary-sub-visibility}, @code{sharpen}, @code{show-in-taskbar}, +@code{shuffle}, @code{sub}, @code{sigmoid-center}, @code{sigmoid-slope}, +@code{sigmoid-upscaling}, @code{slang}, @code{snap-window}, +@code{speed}, @code{spirv-compiler}, @code{sstep}, @code{start}, +@code{stop-playback-on-init-failure}, @code{stop-screensaver}, +@code{stream-buffer-size}, @code{stream-dump}, @code{stream-lavf-o}, +@code{stream-record}, @code{stretch-dvd-subs}, +@code{stretch-image-subs-to-screen}, @code{sub-align-x}, +@code{sub-align-y}, @code{sub-ass}, @code{sub-ass-force-margins}, +@code{sub-ass-hinting}, @code{sub-ass-justify}, +@code{sub-ass-line-spacing}, @code{sub-ass-override}, +@code{sub-ass-scale-with-window}, @code{sub-ass-shaper}, +@code{sub-ass-style-overrides}, @code{sub-ass-styles}, +@code{sub-ass-use-video-data}, @code{sub-ass-video-aspect-override}, +@code{sub-ass-vsfilter-color-compat}, @code{sub-auto}, +@code{sub-auto-exts}, @code{sub-back-color}, @code{sub-blur}, +@code{sub-bold}, @code{sub-border-style}, @code{sub-clear-on-seek}, +@code{sub-codepage}, @code{sub-color}, @code{sub-create-cc-track}, +@code{sub-delay}, @code{sub-demuxer}, @code{sub-file-paths}, +@code{sub-files}, @code{sub-filter-jsre}, @code{sub-filter-regex}, +@code{sub-filter-regex-enable}, @code{sub-filter-regex-plain}, +@code{sub-filter-regex-warn}, @code{sub-filter-sdh}, +@code{sub-filter-sdh-enclosures}, @code{sub-filter-sdh-harder}, +@code{sub-fix-timing}, @code{sub-font}, @code{sub-font-provider}, +@code{sub-font-size}, @code{sub-fonts-dir}, +@code{sub-forced-events-only}, @code{sub-fps}, @code{sub-gauss}, +@code{sub-gray}, @code{sub-italic}, @code{sub-justify}, +@code{sub-lavc-o}, @code{sub-margin-x}, @code{sub-margin-y}, +@code{sub-outline-color}, @code{sub-outline-size}, +@code{sub-past-video-end}, @code{sub-pos}, @code{sub-scale}, +@code{sub-scale-by-window}, @code{sub-scale-with-window}, +@code{sub-shadow-offset}, @code{sub-spacing}, @code{sub-speed}, +@code{sub-stretch-durations}, @code{sub-use-margins}, +@code{sub-visibility}, @code{sub-vsfilter-bidi-compat}, +@code{subs-fallback}, @code{subs-fallback-forced}, +@code{subs-match-os-language}, @code{subs-with-matching-audio}, +@code{swapchain-depth}, @code{sws-allow-zimg}, @code{sws-bitexact}, +@code{sws-cgb}, @code{sws-chs}, @code{sws-cs}, @code{sws-cvs}, +@code{sws-fast}, @code{sws-lgb}, @code{sws-ls}, @code{sws-scaler}, +@code{target-colorspace-hint}, @code{target-contrast}, +@code{target-gamut}, @code{target-lut}, @code{target-peak}, +@code{target-prim}, @code{target-trc}, @code{taskbar-progress}, +@code{teletext-page}, @code{temporal-dither}, +@code{temporal-dither-period}, @code{term-osd}, @code{term-osd-bar}, +@code{term-osd-bar-chars}, @code{term-playing-msg}, +@code{term-status-msg}, @code{term-title}, @code{terminal}, +@code{title}, @code{title-bar}, @code{tls-ca-file}, +@code{tls-cert-file}, @code{tls-key-file}, @code{tls-verify}, +@code{tone-mapping}, @code{tone-mapping-max-boost}, +@code{tone-mapping-param}, @code{tone-mapping-visualize}, +@code{track-auto-selection}, @code{tscale}, @code{tscale-antiring}, +@code{tscale-blur}, @code{tscale-clamp}, @code{tscale-param1}, +@code{tscale-param2}, @code{tscale-radius}, @code{tscale-taper}, +@code{tscale-window}, @code{tscale-wparam}, @code{tscale-wtaper}, +@code{untimed}, @code{use-embedded-icc-profile}, +@code{use-filedir-conf}, @code{user-agent}, @code{vaapi-device}, +@code{vd}, @code{vd-apply-cropping}, @code{vd-lavc-assume-old-x264}, +@code{vd-lavc-bitexact}, @code{vd-lavc-check-hw-profile}, +@code{vd-lavc-dr}, @code{vd-lavc-fast}, @code{vd-lavc-film-grain}, +@code{vd-lavc-framedrop}, @code{vd-lavc-o}, @code{vd-lavc-show-all}, +@code{vd-lavc-skipframe}, @code{vd-lavc-skipidct}, +@code{vd-lavc-skiploopfilter}, @code{vd-lavc-software-fallback}, +@code{vd-lavc-threads}, @code{vd-queue-enable}, +@code{vd-queue-max-bytes}, @code{vd-queue-max-samples}, +@code{vd-queue-max-secs}, @code{vf}, @code{video}, @code{video-align-x}, +@code{video-align-y}, @code{video-aspect-method}, +@code{video-aspect-override}, @code{video-backward-batch}, +@code{video-backward-overlap}, @code{video-crop}, @code{video-exts}, +@code{video-latency-hacks}, @code{video-margin-ratio-bottom}, +@code{video-margin-ratio-left}, @code{video-margin-ratio-right}, +@code{video-margin-ratio-top}, @code{video-osd}, +@code{video-output-levels}, @code{video-pan-x}, @code{video-pan-y}, +@code{video-reversal-buffer}, @code{video-rotate}, @code{video-scale-x}, +@code{video-scale-y}, @code{video-sync}, +@code{video-sync-max-audio-change}, @code{video-sync-max-factor}, +@code{video-sync-max-video-change}, @code{video-timing-offset}, +@code{video-unscaled}, @code{video-zoom}, @code{vlang}, @code{vo}, +@code{vo-image-avif-encoder}, @code{vo-image-avif-opts}, +@code{vo-image-avif-pixfmt}, @code{vo-image-format}, +@code{vo-image-high-bit-depth}, @code{vo-image-jpeg-quality}, +@code{vo-image-jpeg-source-chroma}, @code{vo-image-jxl-distance}, +@code{vo-image-jxl-effort}, @code{vo-image-outdir}, +@code{vo-image-png-compression}, @code{vo-image-png-filter}, +@code{vo-image-tag-colorspace}, @code{vo-image-webp-compression}, +@code{vo-image-webp-lossless}, @code{vo-image-webp-quality}, +@code{vo-kitty-alt-screen}, @code{vo-kitty-cols}, +@code{vo-kitty-config-clear}, @code{vo-kitty-height}, +@code{vo-kitty-left}, @code{vo-kitty-rows}, @code{vo-kitty-top}, +@code{vo-kitty-use-shm}, @code{vo-kitty-width}, @code{vo-null-fps}, +@code{vo-sixel-alt-screen}, @code{vo-sixel-buffered}, +@code{vo-sixel-cols}, @code{vo-sixel-config-clear}, +@code{vo-sixel-dither}, @code{vo-sixel-fixedpalette}, +@code{vo-sixel-height}, @code{vo-sixel-left}, @code{vo-sixel-pad-x}, +@code{vo-sixel-pad-y}, @code{vo-sixel-reqcolors}, @code{vo-sixel-rows}, +@code{vo-sixel-threshold}, @code{vo-sixel-top}, @code{vo-sixel-width}, +@code{vo-tct-256}, @code{vo-tct-algo}, @code{vo-tct-buffering}, +@code{vo-tct-height}, @code{vo-tct-width}, @code{vo-vaapi-scaled-osd}, +@code{vo-vaapi-scaling}, @code{vo-vdpau-chroma-deint}, +@code{vo-vdpau-colorkey}, @code{vo-vdpau-composite-detect}, +@code{vo-vdpau-denoise}, @code{vo-vdpau-force-yuv}, @code{vo-vdpau-fps}, +@code{vo-vdpau-hqscaling}, @code{vo-vdpau-output-surfaces}, +@code{vo-vdpau-pullup}, @code{vo-vdpau-queuetime-fs}, +@code{vo-vdpau-queuetime-windowed}, @code{vo-vdpau-sharpen}, +@code{volume}, @code{volume-gain}, @code{volume-gain-max}, +@code{volume-gain-min}, @code{volume-max}, @code{vulkan-async-compute}, +@code{vulkan-async-transfer}, @code{vulkan-device}, +@code{vulkan-display-display}, @code{vulkan-display-mode}, +@code{vulkan-display-plane}, @code{vulkan-queue-count}, +@code{vulkan-swap-mode}, @code{watch-later-directory}, +@code{watch-later-options}, @code{wayland-app-id}, +@code{wayland-configure-bounds}, @code{wayland-content-type}, +@code{wayland-disable-vsync}, @code{wayland-edge-pixels-pointer}, +@code{wayland-edge-pixels-touch}, @code{wayland-present}, @code{wid}, +@code{window-dragging}, @code{window-maximized}, +@code{window-minimized}, @code{window-scale}, +@code{write-filename-in-watch-later-config}, +@code{x11-bypass-compositor}, @code{x11-name}, @code{x11-netwm}, +@code{x11-present}, @code{x11-wid-title}, @code{xv-adaptor}, +@code{xv-buffers}, @code{xv-ck}, @code{xv-ck-method}, +@code{xv-colorkey}, @code{xv-port}, @code{ytdl}, @code{ytdl-format}, +@code{ytdl-raw-options}, @code{zimg-dither}, @code{zimg-fast}, +@code{zimg-scaler}, @code{zimg-scaler-chroma}, +@code{zimg-scaler-chroma-param-a}, @code{zimg-scaler-chroma-param-b}, +@code{zimg-scaler-param-a}, @code{zimg-scaler-param-b}, and +@code{zimg-threads}. + +@end deffn + @node Sway window manager @subsection Sway window manager diff --git a/gnu/home/services/mpv.scm b/gnu/home/services/mpv.scm new file mode 100644 index 0000000000..8e6ac8b261 --- /dev/null +++ b/gnu/home/services/mpv.scm @@ -0,0 +1,2722 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2024 Tomas Volf <~@wolfsden.cz> +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix 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 General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. + +(define-module (gnu home services mpv) + #:use-module (gnu home services) + #:use-module (guix gexp) + #:use-module (ice-9 match) + #:use-module (ice-9 regex) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-2) + #:use-module (srfi srfi-9) + #:use-module (srfi srfi-26) + #:use-module (srfi srfi-71) + #:export (make-home-mpv-configuration + home-mpv-configuration? + home-mpv-configuration-global + home-mpv-configuration-profiles + home-mpv-configuration-extra-config + home-mpv-configuration-source-location + + serialize-home-mpv-configuration + + %unset + + make-mpv-profile-configuration + mpv-profile-configuration? + ;; Field accessor procedures are exported by a syntax form when + ;; they are defined, so they are not listed here. + + home-mpv-service-type)) + +(define %unset '(*unset*)) + + +;;; +;;; Basic types. +;;; +(define (serialize-type/boolean field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(if value "yes" "no") + "\n")) +(define type/boolean? + (const #t)) + +(define (serialize-type/integer field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(number->string value) + "\n")) +(define (type/integer? n) + ;; We assume integer is a signed 32bit number. + (and-let* (((integer? n)) + ((>= n -2147483648)) + ((<= n 2147483647))))) + +(define (serialize-type/integer64 field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(number->string value) + "\n")) +(define (type/integer64? n) + ;; We assume integer is a signed 64bit number. + (and-let* (((integer? n)) + ((>= n -9223372036854775808)) + ((<= n 9223372036854775807))))) + +(define (serialize-type/string field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$value + "\n")) +(define type/string? + string?) + +(define (serialize-type/float field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(number->string (exact->inexact value)) + "\n")) +(define type/float? + ;; I am not sure how to validate floats. + real?) + +(define (serialize-type/double field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(number->string (exact->inexact value)) + "\n")) +(define (type/double? value) + ;; I am not sure how to validate doubles. + real?) + + + + +;;; +;;; Additional types (possible based on the basic ones). +;;; + +;;; Aspect seems to be treated as an integer, so define it in terms of it. +(define serialize-type/aspect serialize-type/integer) +(define type/aspect? type/integer?) + +;;; `Audio channels or channel map' seems to be basically a free form string +;;; with no way to validate. +(define serialize-type/audio-channels-or-channel-map serialize-type/string) +(define type/audio-channels-or-channel-map? type/string?) + +;;; Does not seem possible to validate. +(define serialize-type/audio-format serialize-type/string) +(define type/audio-format? type/string?) + +;;; While most options list 4.6116860184274e+18 as a maximum value, we will +;;; use integer64 here. That should be enough for everyone for few more +;;; years. +(define serialize-type/byte-size serialize-type/integer64) +(define type/byte-size? type/integer64?) + +(define (serialize-type/color field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(if (list? value) + (string-join (map number->string value) "/") + value) + "\n")) +(define (type/color? value) + (define (ok-num? n) + (and (number? n) + (>= n 0) + (<= n 1))) + (if (list? value) + ;; Either a list of 3(4) numbers encoding RGB(A) on range from 0 to 1... + (match value + (((? ok-num? r) (? ok-num? g) (? ok-num? b)) + #t) + (((? ok-num? r) (? ok-num? g) (? ok-num? b) (? ok-num? alpha)) + #t) + (_ + #f)) + ;; ... or RGB(A) hex encoding. + (string-match "^#([A-Fa-f0-9]{2})?[A-Fa-f0-9]{6}$" value))) + +;;; I do not see value mirroring fourcc.org's database here. It is further +;;; complicated by arbitrary hex being accepted as well. So string it is. +(define serialize-type/fourcc serialize-type/string) +(define type/fourcc? type/string?) + +;;; No way to validate. +(define serialize-type/image-format serialize-type/string) +(define type/image-format? type/string?) + +;;; Looking at the documentation for --start, there is no way to make this +;;; bullet-proof, especially since even chapter numbers are accepted. +(define serialize-type/relative-time-or-percent-position serialize-type/string) +(define type/relative-time-or-percent-position? type/string?) + +(define serialize-type/time serialize-type/string) +(define type/time? type/string?) + +(define serialize-type/video-rectangle serialize-type/string) +(define (type/video-rectangle? value) + (or (string-match "-?[0-9]+%?:-?[0-9]+%?" value) + (string-match + "^(-?[0-9]+%?(x-?[0-9]+%?)?)?([+-]-?[0-9]+%?[+-]-?[0-9]+%?)?$" + value))) + +(define serialize-type/window-geometry serialize-type/string) +(define (type/window-geometry? value) + (or (string-match "-?[0-9]+%?:-?[0-9]+%?" value) + (string-match + "^(-?[0-9]+%?(x-?[0-9]+%?)?)?([+-]-?[0-9]+%?[+-]-?[0-9]+%?)?(/[0-9]+)?$" + value))) + +(define serialize-type/window-size serialize-type/string) +(define (type/window-size? value) + (string-match "^([0-9]+%?(x[0-9]+%?)?)?$" value)) + +(define (serialize-type/enumeration field-name value) + #~(string-append #$(symbol->string field-name) + "=" + ;; This could be either symbol or (in case of enumerations + ;; with alternate type) anything. So just use `format'. + #$(format #f "~s" value) + "\n")) +(define (type/enumeration? value) + ;; There is no general way to check enumerations. The field always has to + ;; define custom sanitizer. + #t) + + + + +;;; +;;; List types. +;;; +(define (serialize-type/list-of-string field-name lst) + #~(string-append #$(symbol->string field-name) + "=" + #$(string-join lst ",") + "\n")) +(define (type/list-of-string? lst) + (every type/string? lst)) + +(define (serialize-type/list-of-key-value field-name lst) + #~(string-append #$(symbol->string field-name) + "=" + #$(string-join (map (match-lambda + ((k . v) (format #f "~a=~a" k v))) + lst) + ",") + "\n")) +(define (type/list-of-key-value? lst) + (every (match-lambda + (((? string?) . (? string?)) #t) + (_ #f)) + lst)) + +(define serialize-type/list-of-object-setting serialize-type/list-of-string) +(define type/list-of-object-setting? type/list-of-string?) + +(define serialize-type/list-of-output-verbosity serialize-type/list-of-key-value) +(define type/list-of-output-verbosity? type/list-of-key-value?) + + + + +;;; +;;; Actual configuration record. Contains a lot of generated code. +;;; + +(define-record-type <profile-option> + (make-profile-option name type-check serializer) + profile-option? + (name profile-option-name) + (type-check profile-option-type-check) + (serializer profile-option-serializer)) + +(define %opts (make-hash-table)) + +(define-syntax define-opt + (lambda (x) + (syntax-case x () + ((_ name type extra-checks ...) + (let* ((d/n (syntax->datum #'name)) + (d/t (syntax->datum #'type)) + (d/accessor (string->symbol + (format #f "mpv-profile-configuration-~a" d/n))) + (d/type-check (string->symbol + (format #f "type/~a?" d/t))) + (d/serializer (string->symbol + (format #f "serialize-type/~a" d/t)))) + (with-syntax + ((kw (datum->syntax x (symbol->keyword d/n))) + (accessor (datum->syntax x d/accessor)) + (type-check (datum->syntax x d/type-check)) + (serializer (datum->syntax x d/serializer)) + (val (datum->syntax x 'val))) + #'(begin + (hashq-set! %opts 'name + (make-profile-option (symbol->string 'name) + (lambda (val) + (and (type-check val) + extra-checks ...)) + serializer)) + (define-public (accessor cfg) + (let ((x (hashq-ref (%mpv-profile-configuration-data cfg) + 'name + %unset))) + (if (eq? x %unset) + %unset + (car x))))))))))) + +;;; Generated code - START. +(define-opt ab-loop-a time) +(define-opt ab-loop-b time) +(define-opt + ab-loop-count + enumeration + (or (memq val '(inf)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt access-references boolean) +(define-opt ad string) +(define-opt + ad-lavc-ac3drc + float + (>= val 0) + (<= val 6)) +(define-opt ad-lavc-downmix boolean) +(define-opt ad-lavc-o list-of-key-value) +(define-opt + ad-lavc-threads + integer + (>= val 0) + (<= val 16)) +(define-opt ad-queue-enable boolean) +(define-opt + ad-queue-max-bytes + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + ad-queue-max-samples + integer64 + (>= val 0)) +(define-opt ad-queue-max-secs double (>= val 0)) +(define-opt af list-of-object-setting) +(define-opt + audio + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt alang list-of-string) +(define-opt allow-delayed-peak-detect boolean) +(define-opt + alsa-buffer-time + integer + (>= val 0) + (<= val 2147483647)) +(define-opt alsa-ignore-chmap boolean) +(define-opt alsa-mixer-device string) +(define-opt + alsa-mixer-index + integer + (>= val 0) + (<= val 99)) +(define-opt alsa-mixer-name string) +(define-opt alsa-non-interleaved boolean) +(define-opt + alsa-periods + integer + (>= val 0) + (<= val 2147483647)) +(define-opt alsa-resample boolean) +(define-opt ao list-of-object-setting) +(define-opt ao-null-broken-delay boolean) +(define-opt ao-null-broken-eof boolean) +(define-opt + ao-null-buffer + float + (>= val 0) + (<= val 100)) +(define-opt + ao-null-channel-layouts + audio-channels-or-channel-map) +(define-opt ao-null-format audio-format) +(define-opt + ao-null-latency + float + (>= val 0) + (<= val 100)) +(define-opt + ao-null-outburst + integer + (>= val 1) + (<= val 100000)) +(define-opt + ao-null-speed + float + (>= val 0) + (<= val 10000)) +(define-opt ao-null-untimed boolean) +(define-opt ao-pcm-append boolean) +(define-opt ao-pcm-file string) +(define-opt ao-pcm-waveheader boolean) +(define-opt + audio-backward-batch + integer + (>= val 0) + (<= val 1024)) +(define-opt + audio-backward-overlap + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 0) (<= val 1024)))) +(define-opt + audio-buffer + double + (>= val 0) + (<= val 10)) +(define-opt + audio-channels + audio-channels-or-channel-map) +(define-opt audio-client-name string) +(define-opt audio-delay float) +(define-opt audio-demuxer string) +(define-opt audio-device string) +(define-opt + audio-display + enumeration + (memq val '(no embedded-first external-first))) +(define-opt audio-exclusive boolean) +(define-opt audio-exts list-of-string) +(define-opt audio-fallback-to-null boolean) +(define-opt + audio-file-auto + enumeration + (memq val '(no exact fuzzy all))) +(define-opt audio-file-paths list-of-string) +(define-opt audio-files list-of-string) +(define-opt audio-format audio-format) +(define-opt audio-normalize-downmix boolean) +(define-opt audio-pitch-correction boolean) +(define-opt + audio-resample-cutoff + double + (>= val 0) + (<= val 1)) +(define-opt + audio-resample-filter-size + integer + (>= val 0) + (<= val 32)) +(define-opt audio-resample-linear boolean) +(define-opt + audio-resample-max-output-size + double) +(define-opt + audio-resample-phase-shift + integer + (>= val 0) + (<= val 30)) +(define-opt + audio-reversal-buffer + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + audio-samplerate + integer + (>= val 0) + (<= val 768000)) +(define-opt audio-spdif string) +(define-opt audio-stream-silence boolean) +(define-opt audio-swresample-o list-of-key-value) +(define-opt + audio-wait-open + float + (>= val 0) + (<= val 60)) +(define-opt auto-window-resize boolean) +(define-opt + autocreate-playlist + enumeration + (memq val '(no filter same))) +(define-opt autofit window-size) +(define-opt autofit-larger window-size) +(define-opt autofit-smaller window-size) +(define-opt autoload-files boolean) +(define-opt + autosync + enumeration + (or (memq val '(no)) + (and (integer? val) (>= val 0) (<= val 10000)))) +(define-opt + background + enumeration + (memq val '(none color tiles))) +(define-opt background-color color) +(define-opt + blend-subtitles + enumeration + (memq val '(no yes video))) +(define-opt bluray-device string) +(define-opt border boolean) +(define-opt + border-background + enumeration + (memq val '(none color tiles))) +(define-opt + brightness + float + (>= val -100) + (<= val 100)) +(define-opt + cache + enumeration + (memq val '(no auto yes))) +(define-opt cache-on-disk boolean) +(define-opt cache-pause boolean) +(define-opt cache-pause-initial boolean) +(define-opt cache-pause-wait float (>= val 0)) +(define-opt cache-secs double (>= val 0)) +(define-opt cdda-cdtext boolean) +(define-opt cdda-device string) +(define-opt + cdda-overlap + integer + (>= val 0) + (<= val 75)) +(define-opt + cdda-paranoia + integer + (>= val 0) + (<= val 2)) +(define-opt + cdda-sector-size + integer + (>= val 1) + (<= val 100)) +(define-opt cdda-skip boolean) +(define-opt cdda-span-a integer) +(define-opt cdda-span-b integer) +(define-opt + cdda-speed + integer + (>= val 1) + (<= val 100)) +(define-opt cdda-toc-offset integer) +(define-opt + chapter-merge-threshold + integer + (>= val 0) + (<= val 10000)) +(define-opt chapter-seek-threshold double) +(define-opt chapters-file string) +(define-opt config boolean) +(define-opt + container-fps-override + double + (>= val 0)) +(define-opt + contrast + float + (>= val -100) + (<= val 100)) +(define-opt cookies boolean) +(define-opt cookies-file string) +(define-opt + corner-rounding + float + (>= val 0) + (<= val 1)) +(define-opt correct-downscaling boolean) +(define-opt correct-pts boolean) +(define-opt + cover-art-auto + enumeration + (memq val '(no exact fuzzy all))) +(define-opt cover-art-files list-of-string) +(define-opt cover-art-whitelist list-of-string) +(define-opt + cscale + enumeration + (memq val + '(bilinear + bicubic_fast + oversample + spline16 + spline36 + spline64 + sinc + lanczos + ginseng + bicubic + hermite + catmull_rom + mitchell + robidoux + robidouxsharp + box + nearest + triangle + gaussian + jinc + ewa_lanczos + ewa_hanning + ewa_ginseng + ewa_lanczossharp + ewa_lanczos4sharpest + ewa_lanczossoft + haasnsoft + ewa_robidoux + ewa_robidouxsharp + bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx))) +(define-opt + cscale-antiring + float + (>= val 0) + (<= val 1)) +(define-opt cscale-blur float) +(define-opt + cscale-clamp + float + (>= val 0) + (<= val 1)) +(define-opt cscale-param1 float) +(define-opt cscale-param2 float) +(define-opt + cscale-radius + float + (>= val 0.5) + (<= val 16)) +(define-opt + cscale-taper + float + (>= val 0) + (<= val 1)) +(define-opt + cscale-window + enumeration + (memq val + '(bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt cscale-wparam float) +(define-opt + cscale-wtaper + float + (>= val 0) + (<= val 1)) +(define-opt + cursor-autohide + enumeration + (or (memq val '(no always)) + (and (integer? val) (>= val 0) (<= val 30000)))) +(define-opt cursor-autohide-fs-only boolean) +(define-opt deband boolean) +(define-opt + deband-grain + float + (>= val 0) + (<= val 4096)) +(define-opt + deband-iterations + integer + (>= val 0) + (<= val 16)) +(define-opt + deband-range + float + (>= val 1) + (<= val 64)) +(define-opt + deband-threshold + float + (>= val 0) + (<= val 4096)) +(define-opt + deinterlace + enumeration + (memq val '(no yes auto))) +(define-opt + deinterlace-field-parity + enumeration + (memq val '(tff bff auto))) +(define-opt demuxer string) +(define-opt + demuxer-backward-playback-step + double + (>= val 0)) +(define-opt demuxer-cache-dir string) +(define-opt + demuxer-cache-unlink-files + enumeration + (memq val '(immediate whendone no))) +(define-opt demuxer-cache-wait boolean) +(define-opt demuxer-donate-buffer boolean) +(define-opt + demuxer-hysteresis-secs + double + (>= val 0)) +(define-opt demuxer-lavf-allow-mimetype boolean) +(define-opt + demuxer-lavf-analyzeduration + float + (>= val 0) + (<= val 3600)) +(define-opt + demuxer-lavf-buffersize + integer + (>= val 1) + (<= val 10485760)) +(define-opt demuxer-lavf-format string) +(define-opt demuxer-lavf-hacks boolean) +(define-opt + demuxer-lavf-linearize-timestamps + enumeration + (memq val '(no auto yes))) +(define-opt demuxer-lavf-o list-of-key-value) +(define-opt + demuxer-lavf-probe-info + enumeration + (memq val '(no yes auto nostreams))) +(define-opt + demuxer-lavf-probescore + integer + (>= val 1) + (<= val 100)) +(define-opt + demuxer-lavf-probesize + integer + (>= val 32) + (<= val 2147483647)) +(define-opt demuxer-lavf-propagate-opts boolean) +(define-opt + demuxer-max-back-bytes + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + demuxer-max-bytes + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt demuxer-mkv-probe-start-time boolean) +(define-opt + demuxer-mkv-probe-video-duration + enumeration + (memq val '(no yes full))) +(define-opt + demuxer-mkv-subtitle-preroll + enumeration + (memq val '(no yes index))) +(define-opt + demuxer-mkv-subtitle-preroll-secs + double + (>= val 0)) +(define-opt + demuxer-mkv-subtitle-preroll-secs-index + double + (>= val 0)) +(define-opt + demuxer-rawaudio-channels + audio-channels-or-channel-map) +(define-opt + demuxer-rawaudio-format + enumeration + (memq val + '(u8 s8 + u16le + u16be + s16le + s16be + u24le + u24be + s24le + s24be + u32le + u32be + s32le + s32be + floatle + floatbe + doublele + doublebe + u16 + s16 + u24 + s24 + u32 + s32 + float + double))) +(define-opt + demuxer-rawaudio-rate + integer + (>= val 1000) + (<= val 384000)) +(define-opt demuxer-rawvideo-codec string) +(define-opt demuxer-rawvideo-format fourcc) +(define-opt + demuxer-rawvideo-fps + float + (>= val 0.001) + (<= val 1000)) +(define-opt + demuxer-rawvideo-h + integer + (>= val 1) + (<= val 8192)) +(define-opt + demuxer-rawvideo-mp-format + image-format) +(define-opt + demuxer-rawvideo-size + integer + (>= val 1) + (<= val 268435456)) +(define-opt + demuxer-rawvideo-w + integer + (>= val 1) + (<= val 8192)) +(define-opt + demuxer-readahead-secs + double + (>= val 0)) +(define-opt + demuxer-seekable-cache + enumeration + (memq val '(auto no yes))) +(define-opt demuxer-termination-timeout double) +(define-opt demuxer-thread boolean) +(define-opt + directory-filter-types + list-of-string) +(define-opt + directory-mode + enumeration + (memq val '(auto lazy recursive ignore))) +(define-opt + display-fps-override + double + (>= val 0)) +(define-opt display-tags list-of-string) +(define-opt + dither + enumeration + (memq val '(fruit ordered error-diffusion no))) +(define-opt + dither-depth + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val -1) (<= val 16)))) +(define-opt + dither-size-fruit + integer + (>= val 2) + (<= val 8)) +(define-opt + drag-and-drop + enumeration + (memq val '(no auto replace append insert-next))) +(define-opt drm-connector string) +(define-opt drm-device string) +(define-opt + drm-draw-plane + enumeration + (or (memq val '(primary overlay)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt drm-draw-surface-size window-size) +(define-opt + drm-drmprime-video-plane + enumeration + (or (memq val '(primary overlay)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt + drm-format + enumeration + (memq val + '(xrgb8888 xrgb2101010 xbgr8888 xbgr2101010 yuyv))) +(define-opt drm-mode string) +(define-opt + drm-vrr-enabled + enumeration + (memq val '(no yes auto))) +(define-opt + dscale + enumeration + (memq val + '(bilinear + bicubic_fast + oversample + spline16 + spline36 + spline64 + sinc + lanczos + ginseng + bicubic + hermite + catmull_rom + mitchell + robidoux + robidouxsharp + box + nearest + triangle + gaussian + jinc + ewa_lanczos + ewa_hanning + ewa_ginseng + ewa_lanczossharp + ewa_lanczos4sharpest + ewa_lanczossoft + haasnsoft + ewa_robidoux + ewa_robidouxsharp + bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx))) +(define-opt + dscale-antiring + float + (>= val 0) + (<= val 1)) +(define-opt dscale-blur float) +(define-opt + dscale-clamp + float + (>= val 0) + (<= val 1)) +(define-opt dscale-param1 float) +(define-opt dscale-param2 float) +(define-opt + dscale-radius + float + (>= val 0.5) + (<= val 16)) +(define-opt + dscale-taper + float + (>= val 0) + (<= val 1)) +(define-opt + dscale-window + enumeration + (memq val + '(bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt dscale-wparam float) +(define-opt + dscale-wtaper + float + (>= val 0) + (<= val 1)) +(define-opt dump-stats string) +(define-opt + dvbin-card + integer + (>= val 0) + (<= val 15)) +(define-opt dvbin-channel-switch-offset integer) +(define-opt dvbin-file string) +(define-opt dvbin-full-transponder boolean) +(define-opt dvbin-prog string) +(define-opt + dvbin-timeout + integer + (>= val 1) + (<= val 30)) +(define-opt + dvd-angle + integer + (>= val 1) + (<= val 99)) +(define-opt dvd-device string) +(define-opt dvd-speed integer) +(define-opt + edition + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt egl-config-id integer) +(define-opt + egl-output-format + enumeration + (memq val + '(auto rgb8 + rgba8 + rgb10 + rgb10_a2 + rgb16 + rgba16 + rgb16f + rgba16f + rgb32f + rgba32f))) +(define-opt embeddedfonts boolean) +(define-opt + end + relative-time-or-percent-position) +(define-opt error-diffusion string) +(define-opt external-files list-of-string) +(define-opt fbo-format string) +(define-opt + focus-on + enumeration + (memq val '(never open all))) +(define-opt force-media-title string) +(define-opt force-render boolean) +(define-opt force-rgba-osd-rendering boolean) +(define-opt force-seekable boolean) +(define-opt + force-window + enumeration + (memq val '(no yes immediate))) +(define-opt force-window-position boolean) +(define-opt + framedrop + enumeration + (memq val '(no vo decoder decoder+vo))) +(define-opt + frames + enumeration + (or (memq val '(all)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt + fs-screen + enumeration + (or (memq val '(all current)) + (and (integer? val) (>= val 0) (<= val 32)))) +(define-opt fs-screen-name string) +(define-opt fullscreen boolean) +(define-opt + gamma + float + (>= val -100) + (<= val 100)) +(define-opt gamma-auto boolean) +(define-opt + gamma-factor + float + (>= val 0.1) + (<= val 2)) +(define-opt + gamut-mapping-mode + enumeration + (memq val + '(auto clip + perceptual + relative + saturation + absolute + desaturate + darken + warn + linear))) +(define-opt + gapless-audio + enumeration + (memq val '(no yes weak))) +(define-opt geometry window-geometry) +(define-opt glsl-shader-opts list-of-key-value) +(define-opt glsl-shaders list-of-string) +(define-opt gpu-api list-of-object-setting) +(define-opt gpu-context list-of-object-setting) +(define-opt gpu-debug boolean) +(define-opt + gpu-dumb-mode + enumeration + (memq val '(auto yes no))) +(define-opt gpu-hwdec-interop string) +(define-opt gpu-shader-cache boolean) +(define-opt gpu-shader-cache-dir string) +(define-opt gpu-sw boolean) +(define-opt + gpu-tex-pad-x + integer + (>= val 0) + (<= val 4096)) +(define-opt + gpu-tex-pad-y + integer + (>= val 0) + (<= val 4096)) +(define-opt + hdr-compute-peak + enumeration + (memq val '(auto yes no))) +(define-opt + hdr-contrast-recovery + float + (>= val 0) + (<= val 2)) +(define-opt + hdr-contrast-smoothness + float + (>= val 1) + (<= val 100)) +(define-opt + hdr-peak-decay-rate + float + (>= val 0) + (<= val 1000)) +(define-opt + hdr-peak-percentile + float + (>= val 0) + (<= val 100)) +(define-opt + hdr-scene-threshold-high + float + (>= val 0) + (<= val 20)) +(define-opt + hdr-scene-threshold-low + float + (>= val 0) + (<= val 20)) +(define-opt hidpi-window-scale boolean) +(define-opt + hls-bitrate + enumeration + (or (memq val '(no min max)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt + hr-seek + enumeration + (memq val '(no absolute yes always default))) +(define-opt hr-seek-demuxer-offset float) +(define-opt hr-seek-framedrop boolean) +(define-opt http-header-fields list-of-string) +(define-opt http-proxy string) +(define-opt hue float (>= val -100) (<= val 100)) +(define-opt hwdec list-of-string) +(define-opt hwdec-codecs string) +(define-opt + hwdec-extra-frames + integer + (>= val 0) + (<= val 256)) +(define-opt hwdec-image-format image-format) +(define-opt icc-3dlut-size string) +(define-opt icc-cache boolean) +(define-opt icc-cache-dir string) +(define-opt + icc-force-contrast + enumeration + (or (memq val '(no inf)) + (and (integer? val) (>= val 0) (<= val 1000000)))) +(define-opt icc-intent integer) +(define-opt icc-profile string) +(define-opt icc-profile-auto boolean) +(define-opt icc-use-luma boolean) +(define-opt + idle + enumeration + (memq val '(no once yes))) +(define-opt + ignore-path-in-watch-later-config + boolean) +(define-opt + image-display-duration + double + (>= val 0)) +(define-opt image-exts list-of-string) +(define-opt image-lut string) +(define-opt + image-lut-type + enumeration + (memq val '(auto native normalized conversion))) +(define-opt image-subs-video-resolution boolean) +(define-opt include string) +(define-opt + index + enumeration + (memq val '(default recreate))) +(define-opt initial-audio-sync boolean) +(define-opt input-ar-delay integer) +(define-opt input-ar-rate integer) +(define-opt input-builtin-bindings boolean) +(define-opt input-builtin-dragging boolean) +(define-opt input-commands list-of-string) +(define-opt input-conf string) +(define-opt input-cursor boolean) +(define-opt input-cursor-passthrough boolean) +(define-opt input-default-bindings boolean) +(define-opt + input-doubleclick-time + integer + (>= val 0) + (<= val 1000)) +(define-opt input-dragging-deadzone integer) +(define-opt input-ipc-client string) +(define-opt input-ipc-server string) +(define-opt + input-key-fifo-size + integer + (>= val 2) + (<= val 65000)) +(define-opt input-media-keys boolean) +(define-opt input-preprocess-wheel boolean) +(define-opt input-right-alt-gr boolean) +(define-opt input-terminal boolean) +(define-opt input-test boolean) +(define-opt input-touch-emulate-mouse boolean) +(define-opt input-vo-keyboard boolean) +(define-opt interpolation boolean) +(define-opt interpolation-preserve boolean) +(define-opt interpolation-threshold float) +(define-opt inverse-tone-mapping boolean) +(define-opt jack-autostart boolean) +(define-opt jack-connect boolean) +(define-opt jack-name string) +(define-opt jack-port string) +(define-opt + jack-std-channel-layout + enumeration + (memq val '(waveext any))) +(define-opt + keep-open + enumeration + (memq val '(no yes always))) +(define-opt keep-open-pause boolean) +(define-opt keepaspect boolean) +(define-opt keepaspect-window boolean) +(define-opt lavfi-complex string) +(define-opt + length + relative-time-or-percent-position) +(define-opt libplacebo-opts list-of-key-value) +(define-opt linear-downscaling boolean) +(define-opt linear-upscaling boolean) +(define-opt + load-auto-profiles + enumeration + (memq val '(no yes auto))) +(define-opt load-osd-console boolean) +(define-opt load-scripts boolean) +(define-opt load-select boolean) +(define-opt load-stats-overlay boolean) +(define-opt load-unsafe-playlists boolean) +(define-opt log-file string) +(define-opt + loop-file + enumeration + (or (memq val '(no inf yes)) + (and (integer? val) (>= val 0) (<= val 10000)))) +(define-opt + loop-playlist + enumeration + (or (memq val '(no inf yes force)) + (and (integer? val) (>= val 1) (<= val 10000)))) +(define-opt lut string) +(define-opt + lut-type + enumeration + (memq val '(auto native normalized conversion))) +(define-opt mc float (>= val 0) (<= val 100)) +(define-opt + media-controls + enumeration + (memq val '(no player yes))) +(define-opt merge-files boolean) +(define-opt metadata-codepage string) +(define-opt mf-fps double) +(define-opt mf-type string) +(define-opt + monitoraspect + float + (>= val 0) + (<= val 9)) +(define-opt + monitorpixelaspect + float + (>= val 0.03125) + (<= val 32)) +(define-opt msg-color boolean) +(define-opt msg-level list-of-output-verbosity) +(define-opt msg-module boolean) +(define-opt msg-time boolean) +(define-opt mute boolean) +(define-opt native-fs boolean) +(define-opt native-keyrepeat boolean) +(define-opt native-touch boolean) +(define-opt network-timeout double (>= val 0)) +(define-opt oac string) +(define-opt oacopts list-of-key-value) +(define-opt ocopy-metadata boolean) +(define-opt of string) +(define-opt ofopts list-of-key-value) +(define-opt on-all-workspaces boolean) +(define-opt ontop boolean) +(define-opt + ontop-level + enumeration + (or (memq val '(window system desktop)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt opengl-check-pattern-a integer) +(define-opt opengl-check-pattern-b integer) +(define-opt + opengl-early-flush + enumeration + (memq val '(no yes auto))) +(define-opt + opengl-es + enumeration + (memq val '(auto yes no))) +(define-opt opengl-glfinish boolean) +(define-opt opengl-pbo boolean) +(define-opt opengl-rectangle-textures boolean) +(define-opt opengl-swapinterval integer) +(define-opt opengl-waitvsync boolean) +(define-opt orawts boolean) +(define-opt ordered-chapters boolean) +(define-opt ordered-chapters-files string) +(define-opt oremove-metadata list-of-string) +(define-opt osc boolean) +(define-opt + osd-align-x + enumeration + (memq val '(left center right))) +(define-opt + osd-align-y + enumeration + (memq val '(top center bottom))) +(define-opt osd-back-color color) +(define-opt osd-bar boolean) +(define-opt + osd-bar-align-x + float + (>= val -1) + (<= val 1)) +(define-opt + osd-bar-align-y + float + (>= val -1) + (<= val 1)) +(define-opt + osd-bar-h + float + (>= val 0.1) + (<= val 50)) +(define-opt + osd-bar-outline-size + float + (>= val 0) + (<= val 1000)) +(define-opt + osd-bar-w + float + (>= val 1) + (<= val 100)) +(define-opt + osd-blur + float + (>= val 0) + (<= val 20)) +(define-opt osd-bold boolean) +(define-opt + osd-border-style + enumeration + (memq val + '(outline-and-shadow opaque-box background-box))) +(define-opt osd-color color) +(define-opt + osd-duration + integer + (>= val 0) + (<= val 3600000)) +(define-opt osd-font string) +(define-opt + osd-font-provider + enumeration + (memq val '(auto none fontconfig))) +(define-opt + osd-font-size + float + (>= val 1) + (<= val 9000)) +(define-opt osd-fonts-dir string) +(define-opt osd-fractions boolean) +(define-opt osd-italic boolean) +(define-opt + osd-justify + enumeration + (memq val '(auto left center right))) +(define-opt + osd-level + enumeration + (memq val '(#{0}# #{1}# #{2}# #{3}#))) +(define-opt + osd-margin-x + integer + (>= val 0) + (<= val 300)) +(define-opt + osd-margin-y + integer + (>= val 0) + (<= val 600)) +(define-opt osd-msg1 string) +(define-opt osd-msg2 string) +(define-opt osd-msg3 string) +(define-opt + osd-on-seek + enumeration + (memq val '(no bar msg msg-bar))) +(define-opt osd-outline-color color) +(define-opt osd-outline-size float) +(define-opt osd-playing-msg string) +(define-opt + osd-playing-msg-duration + integer + (>= val 0) + (<= val 3600000)) +(define-opt + osd-playlist-entry + enumeration + (memq val '(title filename both))) +(define-opt + osd-scale + float + (>= val 0) + (<= val 100)) +(define-opt osd-scale-by-window boolean) +(define-opt osd-shadow-offset float) +(define-opt + osd-spacing + float + (>= val -10) + (<= val 10)) +(define-opt osd-status-msg string) +(define-opt oset-metadata list-of-key-value) +(define-opt ovc string) +(define-opt ovcopts list-of-key-value) +(define-opt panscan float (>= val 0) (<= val 1)) +(define-opt pause boolean) +(define-opt + pitch + double + (>= val 0.01) + (<= val 100)) +(define-opt + play-direction + enumeration + (memq val '(forward + backward -))) +(define-opt + player-operation-mode + enumeration + (memq val '(cplayer pseudo-gui))) +(define-opt + playlist-start + enumeration + (or (memq val '(auto no)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt prefetch-playlist boolean) +(define-opt profile list-of-string) +(define-opt pulse-allow-suspended boolean) +(define-opt + pulse-buffer + enumeration + (or (memq val '(native)) + (and (integer? val) (>= val 1) (<= val 2000)))) +(define-opt pulse-host string) +(define-opt pulse-latency-hacks boolean) +(define-opt quiet boolean) +(define-opt really-quiet boolean) +(define-opt rebase-start-time boolean) +(define-opt referrer string) +(define-opt + replaygain + enumeration + (memq val '(no track album))) +(define-opt replaygain-clip boolean) +(define-opt + replaygain-fallback + float + (>= val -200) + (<= val 60)) +(define-opt + replaygain-preamp + float + (>= val -150) + (<= val 150)) +(define-opt reset-on-next-file list-of-string) +(define-opt resume-playback boolean) +(define-opt resume-playback-check-mtime boolean) +(define-opt + rtsp-transport + enumeration + (memq val '(lavf udp tcp http udp_multicast))) +(define-opt + saturation + float + (>= val -100) + (<= val 100)) +(define-opt save-position-on-quit boolean) +(define-opt + scale + enumeration + (memq val + '(bilinear + bicubic_fast + oversample + spline16 + spline36 + spline64 + sinc + lanczos + ginseng + bicubic + hermite + catmull_rom + mitchell + robidoux + robidouxsharp + box + nearest + triangle + gaussian + jinc + ewa_lanczos + ewa_hanning + ewa_ginseng + ewa_lanczossharp + ewa_lanczos4sharpest + ewa_lanczossoft + haasnsoft + ewa_robidoux + ewa_robidouxsharp + bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx))) +(define-opt + scale-antiring + float + (>= val 0) + (<= val 1)) +(define-opt scale-blur float) +(define-opt + scale-clamp + float + (>= val 0) + (<= val 1)) +(define-opt scale-param1 float) +(define-opt scale-param2 float) +(define-opt + scale-radius + float + (>= val 0.5) + (<= val 16)) +(define-opt + scale-taper + float + (>= val 0) + (<= val 1)) +(define-opt + scale-window + enumeration + (memq val + '(bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt scale-wparam float) +(define-opt + scale-wtaper + float + (>= val 0) + (<= val 1)) +(define-opt scaler-resizes-only boolean) +(define-opt + screen + enumeration + (or (memq val '(default)) + (and (integer? val) (>= val 0) (<= val 32)))) +(define-opt screen-name string) +(define-opt screenshot-avif-encoder string) +(define-opt + screenshot-avif-opts + list-of-key-value) +(define-opt screenshot-avif-pixfmt string) +(define-opt screenshot-directory string) +(define-opt + screenshot-format + enumeration + (memq val '(jpg jpeg png webp jxl avif))) +(define-opt screenshot-high-bit-depth boolean) +(define-opt + screenshot-jpeg-quality + integer + (>= val 0) + (<= val 100)) +(define-opt + screenshot-jpeg-source-chroma + boolean) +(define-opt + screenshot-jxl-distance + double + (>= val 0) + (<= val 15)) +(define-opt + screenshot-jxl-effort + integer + (>= val 1) + (<= val 9)) +(define-opt + screenshot-png-compression + integer + (>= val 0) + (<= val 9)) +(define-opt + screenshot-png-filter + integer + (>= val 0) + (<= val 5)) +(define-opt screenshot-sw boolean) +(define-opt screenshot-tag-colorspace boolean) +(define-opt screenshot-template string) +(define-opt + screenshot-webp-compression + integer + (>= val 0) + (<= val 6)) +(define-opt screenshot-webp-lossless boolean) +(define-opt + screenshot-webp-quality + integer + (>= val 0) + (<= val 100)) +(define-opt script-opts list-of-key-value) +(define-opt scripts list-of-string) +(define-opt + secondary-sid + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt + secondary-sub-ass-override + enumeration + (memq val '(no yes scale force strip))) +(define-opt secondary-sub-delay float) +(define-opt + secondary-sub-pos + float + (>= val 0) + (<= val 150)) +(define-opt secondary-sub-visibility boolean) +(define-opt sharpen float) +(define-opt show-in-taskbar boolean) +(define-opt shuffle boolean) +(define-opt + sub + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt + sigmoid-center + float + (>= val 0) + (<= val 1)) +(define-opt + sigmoid-slope + float + (>= val 1) + (<= val 20)) +(define-opt sigmoid-upscaling boolean) +(define-opt slang list-of-string) +(define-opt snap-window boolean) +(define-opt + speed + double + (>= val 0.01) + (<= val 100)) +(define-opt + spirv-compiler + enumeration + (memq val '(auto))) +(define-opt sstep double (>= val 0)) +(define-opt + start + relative-time-or-percent-position) +(define-opt + stop-playback-on-init-failure + boolean) +(define-opt + stop-screensaver + enumeration + (memq val '(no yes always))) +(define-opt + stream-buffer-size + byte-size + (>= val 4096) + (<= val 536870912)) +(define-opt stream-dump string) +(define-opt stream-lavf-o list-of-key-value) +(define-opt stream-record string) +(define-opt stretch-dvd-subs boolean) +(define-opt stretch-image-subs-to-screen boolean) +(define-opt + sub-align-x + enumeration + (memq val '(left center right))) +(define-opt + sub-align-y + enumeration + (memq val '(top center bottom))) +(define-opt sub-ass boolean) +(define-opt sub-ass-force-margins boolean) +(define-opt + sub-ass-hinting + enumeration + (memq val '(none light normal native))) +(define-opt sub-ass-justify boolean) +(define-opt + sub-ass-line-spacing + float + (>= val -1000) + (<= val 1000)) +(define-opt + sub-ass-override + enumeration + (memq val '(no yes scale force strip))) +(define-opt sub-ass-scale-with-window boolean) +(define-opt + sub-ass-shaper + enumeration + (memq val '(simple complex))) +(define-opt + sub-ass-style-overrides + list-of-string) +(define-opt sub-ass-styles string) +(define-opt + sub-ass-use-video-data + enumeration + (memq val '(none aspect-ratio all))) +(define-opt + sub-ass-video-aspect-override + aspect + (>= val 0) + (<= val 10)) +(define-opt + sub-ass-vsfilter-color-compat + enumeration + (memq val '(no basic full force-601))) +(define-opt + sub-auto + enumeration + (memq val '(no exact fuzzy all))) +(define-opt sub-auto-exts list-of-string) +(define-opt sub-back-color color) +(define-opt + sub-blur + float + (>= val 0) + (<= val 20)) +(define-opt sub-bold boolean) +(define-opt + sub-border-style + enumeration + (memq val + '(outline-and-shadow opaque-box background-box))) +(define-opt sub-clear-on-seek boolean) +(define-opt sub-codepage string) +(define-opt sub-color color) +(define-opt sub-create-cc-track boolean) +(define-opt sub-delay float) +(define-opt sub-demuxer string) +(define-opt sub-file-paths list-of-string) +(define-opt sub-files list-of-string) +(define-opt sub-filter-jsre list-of-string) +(define-opt sub-filter-regex list-of-string) +(define-opt sub-filter-regex-enable boolean) +(define-opt sub-filter-regex-plain boolean) +(define-opt sub-filter-regex-warn boolean) +(define-opt sub-filter-sdh boolean) +(define-opt sub-filter-sdh-enclosures string) +(define-opt sub-filter-sdh-harder boolean) +(define-opt sub-fix-timing boolean) +(define-opt sub-font string) +(define-opt + sub-font-provider + enumeration + (memq val '(auto none fontconfig))) +(define-opt + sub-font-size + float + (>= val 1) + (<= val 9000)) +(define-opt sub-fonts-dir string) +(define-opt sub-forced-events-only boolean) +(define-opt sub-fps float) +(define-opt + sub-gauss + float + (>= val 0) + (<= val 3)) +(define-opt sub-gray boolean) +(define-opt sub-italic boolean) +(define-opt + sub-justify + enumeration + (memq val '(auto left center right))) +(define-opt sub-lavc-o list-of-key-value) +(define-opt + sub-margin-x + integer + (>= val 0) + (<= val 300)) +(define-opt + sub-margin-y + integer + (>= val 0) + (<= val 600)) +(define-opt sub-outline-color color) +(define-opt sub-outline-size float) +(define-opt sub-past-video-end boolean) +(define-opt + sub-pos + float + (>= val 0) + (<= val 150)) +(define-opt + sub-scale + float + (>= val 0) + (<= val 100)) +(define-opt sub-scale-by-window boolean) +(define-opt sub-scale-with-window boolean) +(define-opt sub-shadow-offset float) +(define-opt + sub-spacing + float + (>= val -10) + (<= val 10)) +(define-opt sub-speed float) +(define-opt sub-stretch-durations boolean) +(define-opt sub-use-margins boolean) +(define-opt sub-visibility boolean) +(define-opt sub-vsfilter-bidi-compat boolean) +(define-opt + subs-fallback + enumeration + (memq val '(no default yes))) +(define-opt + subs-fallback-forced + enumeration + (memq val '(no yes always))) +(define-opt subs-match-os-language boolean) +(define-opt + subs-with-matching-audio + enumeration + (memq val '(no forced yes))) +(define-opt + swapchain-depth + integer + (>= val 1) + (<= val 8)) +(define-opt sws-allow-zimg boolean) +(define-opt sws-bitexact boolean) +(define-opt + sws-cgb + float + (>= val 0) + (<= val 100)) +(define-opt sws-chs integer) +(define-opt + sws-cs + float + (>= val -100) + (<= val 100)) +(define-opt sws-cvs integer) +(define-opt sws-fast boolean) +(define-opt + sws-lgb + float + (>= val 0) + (<= val 100)) +(define-opt + sws-ls + float + (>= val -100) + (<= val 100)) +(define-opt + sws-scaler + enumeration + (memq val + '(fast-bilinear + bilinear + bicubic + x + point + area + bicublin + gauss + sinc + lanczos + spline))) +(define-opt target-colorspace-hint boolean) +(define-opt + target-contrast + enumeration + (or (memq val '(auto inf)) + (and (integer? val) (>= val 10) (<= val 1000000)))) +(define-opt + target-gamut + enumeration + (memq val + '(auto bt.601-525 + bt.601-625 + bt.709 + bt.2020 + bt.470m + apple + adobe + prophoto + cie1931 + dci-p3 + display-p3 + v-gamut + s-gamut + ebu3213 + film-c + aces-ap0 + aces-ap1))) +(define-opt target-lut string) +(define-opt + target-peak + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 10) (<= val 10000)))) +(define-opt + target-prim + enumeration + (memq val + '(auto bt.601-525 + bt.601-625 + bt.709 + bt.2020 + bt.470m + apple + adobe + prophoto + cie1931 + dci-p3 + display-p3 + v-gamut + s-gamut + ebu3213 + film-c + aces-ap0 + aces-ap1))) +(define-opt + target-trc + enumeration + (memq val + '(auto bt.1886 + srgb + linear + gamma1.8 + gamma2.0 + gamma2.2 + gamma2.4 + gamma2.6 + gamma2.8 + prophoto + pq + hlg + v-log + s-log1 + s-log2 + st428))) +(define-opt taskbar-progress boolean) +(define-opt + teletext-page + integer + (>= val -1) + (<= val 999)) +(define-opt temporal-dither boolean) +(define-opt + temporal-dither-period + integer + (>= val 1) + (<= val 128)) +(define-opt + term-osd + enumeration + (memq val '(force auto no))) +(define-opt term-osd-bar boolean) +(define-opt term-osd-bar-chars string) +(define-opt term-playing-msg string) +(define-opt term-status-msg string) +(define-opt term-title string) +(define-opt terminal boolean) +(define-opt title string) +(define-opt title-bar boolean) +(define-opt tls-ca-file string) +(define-opt tls-cert-file string) +(define-opt tls-key-file string) +(define-opt tls-verify boolean) +(define-opt + tone-mapping + enumeration + (memq val + '(auto clip + mobius + reinhard + hable + gamma + linear + spline + bt.2390 + bt.2446a + st2094-40 + st2094-10))) +(define-opt + tone-mapping-max-boost + float + (>= val 1) + (<= val 10)) +(define-opt tone-mapping-param float) +(define-opt tone-mapping-visualize boolean) +(define-opt track-auto-selection boolean) +(define-opt + tscale + enumeration + (memq val + '(oversample + linear + spline16 + spline36 + spline64 + sinc + lanczos + ginseng + bicubic + hermite + catmull_rom + mitchell + robidoux + robidouxsharp + box + nearest + triangle + gaussian + bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt + tscale-antiring + float + (>= val 0) + (<= val 1)) +(define-opt tscale-blur float) +(define-opt + tscale-clamp + float + (>= val 0) + (<= val 1)) +(define-opt tscale-param1 float) +(define-opt tscale-param2 float) +(define-opt + tscale-radius + float + (>= val 0.5) + (<= val 16)) +(define-opt + tscale-taper + float + (>= val 0) + (<= val 1)) +(define-opt + tscale-window + enumeration + (memq val + '(bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt tscale-wparam float) +(define-opt + tscale-wtaper + float + (>= val 0) + (<= val 1)) +(define-opt untimed boolean) +(define-opt use-embedded-icc-profile boolean) +(define-opt use-filedir-conf boolean) +(define-opt user-agent string) +(define-opt vaapi-device string) +(define-opt vd string) +(define-opt vd-apply-cropping boolean) +(define-opt vd-lavc-assume-old-x264 boolean) +(define-opt vd-lavc-bitexact boolean) +(define-opt vd-lavc-check-hw-profile boolean) +(define-opt + vd-lavc-dr + enumeration + (memq val '(auto no yes))) +(define-opt vd-lavc-fast boolean) +(define-opt + vd-lavc-film-grain + enumeration + (memq val '(auto cpu gpu))) +(define-opt + vd-lavc-framedrop + enumeration + (memq val + '(none default nonref bidir nonkey all))) +(define-opt vd-lavc-o list-of-key-value) +(define-opt vd-lavc-show-all boolean) +(define-opt + vd-lavc-skipframe + enumeration + (memq val + '(none default nonref bidir nonkey all))) +(define-opt + vd-lavc-skipidct + enumeration + (memq val + '(none default nonref bidir nonkey all))) +(define-opt + vd-lavc-skiploopfilter + enumeration + (memq val + '(none default nonref bidir nonkey all))) +(define-opt + vd-lavc-software-fallback + enumeration + (or (memq val '(no yes)) + (and (integer? val) + (>= val 1) + (<= val 2147483647)))) +(define-opt vd-lavc-threads integer (>= val 0)) +(define-opt vd-queue-enable boolean) +(define-opt + vd-queue-max-bytes + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + vd-queue-max-samples + integer64 + (>= val 0)) +(define-opt vd-queue-max-secs double (>= val 0)) +(define-opt vf list-of-object-setting) +(define-opt + video + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt + video-align-x + float + (>= val -1) + (<= val 1)) +(define-opt + video-align-y + float + (>= val -1) + (<= val 1)) +(define-opt + video-aspect-method + enumeration + (memq val '(bitstream container))) +(define-opt + video-aspect-override + aspect + (>= val -1) + (<= val 10)) +(define-opt + video-backward-batch + integer + (>= val 0) + (<= val 1024)) +(define-opt + video-backward-overlap + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 0) (<= val 1024)))) +(define-opt video-crop video-rectangle) +(define-opt video-exts list-of-string) +(define-opt video-latency-hacks boolean) +(define-opt + video-margin-ratio-bottom + float + (>= val 0) + (<= val 1)) +(define-opt + video-margin-ratio-left + float + (>= val 0) + (<= val 1)) +(define-opt + video-margin-ratio-right + float + (>= val 0) + (<= val 1)) +(define-opt + video-margin-ratio-top + float + (>= val 0) + (<= val 1)) +(define-opt video-osd boolean) +(define-opt + video-output-levels + enumeration + (memq val '(auto limited full))) +(define-opt video-pan-x float) +(define-opt video-pan-y float) +(define-opt + video-reversal-buffer + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + video-rotate + enumeration + (or (memq val '(no)) + (and (integer? val) (>= val 0) (<= val 359)))) +(define-opt + video-scale-x + float + (>= val 0) + (<= val 10000)) +(define-opt + video-scale-y + float + (>= val 0) + (<= val 10000)) +(define-opt + video-sync + enumeration + (memq val + '(audio display-resample + display-resample-vdrop + display-resample-desync + display-tempo + display-adrop + display-vdrop + display-desync + desync))) +(define-opt + video-sync-max-audio-change + double + (>= val 0) + (<= val 1)) +(define-opt + video-sync-max-factor + integer + (>= val 1) + (<= val 10)) +(define-opt + video-sync-max-video-change + double + (>= val 0)) +(define-opt + video-timing-offset + double + (>= val 0) + (<= val 1)) +(define-opt + video-unscaled + enumeration + (memq val '(no yes downscale-big))) +(define-opt + video-zoom + float + (>= val -20) + (<= val 20)) +(define-opt vlang list-of-string) +(define-opt vo list-of-object-setting) +(define-opt vo-image-avif-encoder string) +(define-opt vo-image-avif-opts list-of-key-value) +(define-opt vo-image-avif-pixfmt string) +(define-opt + vo-image-format + enumeration + (memq val '(jpg jpeg png webp jxl avif))) +(define-opt vo-image-high-bit-depth boolean) +(define-opt + vo-image-jpeg-quality + integer + (>= val 0) + (<= val 100)) +(define-opt vo-image-jpeg-source-chroma boolean) +(define-opt + vo-image-jxl-distance + double + (>= val 0) + (<= val 15)) +(define-opt + vo-image-jxl-effort + integer + (>= val 1) + (<= val 9)) +(define-opt vo-image-outdir string) +(define-opt + vo-image-png-compression + integer + (>= val 0) + (<= val 9)) +(define-opt + vo-image-png-filter + integer + (>= val 0) + (<= val 5)) +(define-opt vo-image-tag-colorspace boolean) +(define-opt + vo-image-webp-compression + integer + (>= val 0) + (<= val 6)) +(define-opt vo-image-webp-lossless boolean) +(define-opt + vo-image-webp-quality + integer + (>= val 0) + (<= val 100)) +(define-opt vo-kitty-alt-screen boolean) +(define-opt vo-kitty-cols integer) +(define-opt vo-kitty-config-clear boolean) +(define-opt vo-kitty-height integer) +(define-opt vo-kitty-left integer) +(define-opt vo-kitty-rows integer) +(define-opt vo-kitty-top integer) +(define-opt vo-kitty-use-shm boolean) +(define-opt vo-kitty-width integer) +(define-opt + vo-null-fps + double + (>= val 0) + (<= val 10000)) +(define-opt vo-sixel-alt-screen boolean) +(define-opt vo-sixel-buffered boolean) +(define-opt vo-sixel-cols integer) +(define-opt vo-sixel-config-clear boolean) +(define-opt + vo-sixel-dither + enumeration + (memq val + '(auto none + atkinson + fs + jajuni + stucki + burkes + arithmetic + xor))) +(define-opt vo-sixel-fixedpalette boolean) +(define-opt vo-sixel-height integer) +(define-opt vo-sixel-left integer) +(define-opt vo-sixel-pad-x integer) +(define-opt vo-sixel-pad-y integer) +(define-opt vo-sixel-reqcolors integer) +(define-opt vo-sixel-rows integer) +(define-opt vo-sixel-threshold integer) +(define-opt vo-sixel-top integer) +(define-opt vo-sixel-width integer) +(define-opt vo-tct-256 boolean) +(define-opt + vo-tct-algo + enumeration + (memq val '(plain half-blocks))) +(define-opt + vo-tct-buffering + enumeration + (memq val '(pixel line frame))) +(define-opt vo-tct-height integer) +(define-opt vo-tct-width integer) +(define-opt vo-vaapi-scaled-osd boolean) +(define-opt + vo-vaapi-scaling + enumeration + (memq val '(default fast hq nla))) +(define-opt vo-vdpau-chroma-deint boolean) +(define-opt vo-vdpau-colorkey color) +(define-opt vo-vdpau-composite-detect boolean) +(define-opt + vo-vdpau-denoise + float + (>= val 0) + (<= val 1)) +(define-opt vo-vdpau-force-yuv boolean) +(define-opt vo-vdpau-fps double) +(define-opt + vo-vdpau-hqscaling + integer + (>= val 0) + (<= val 9)) +(define-opt + vo-vdpau-output-surfaces + integer + (>= val 2) + (<= val 15)) +(define-opt vo-vdpau-pullup boolean) +(define-opt vo-vdpau-queuetime-fs integer) +(define-opt vo-vdpau-queuetime-windowed integer) +(define-opt + vo-vdpau-sharpen + float + (>= val -1) + (<= val 1)) +(define-opt + volume + float + (>= val -1) + (<= val 1000)) +(define-opt + volume-gain + float + (>= val -150) + (<= val 150)) +(define-opt + volume-gain-max + float + (>= val 0) + (<= val 150)) +(define-opt + volume-gain-min + float + (>= val -150) + (<= val 0)) +(define-opt + volume-max + float + (>= val 100) + (<= val 1000)) +(define-opt vulkan-async-compute boolean) +(define-opt vulkan-async-transfer boolean) +(define-opt vulkan-device string) +(define-opt vulkan-display-display integer) +(define-opt vulkan-display-mode integer) +(define-opt vulkan-display-plane integer) +(define-opt + vulkan-queue-count + integer + (>= val 1) + (<= val 8)) +(define-opt + vulkan-swap-mode + enumeration + (memq val + '(auto fifo fifo-relaxed mailbox immediate))) +(define-opt watch-later-directory string) +(define-opt watch-later-options list-of-string) +(define-opt wayland-app-id string) +(define-opt + wayland-configure-bounds + enumeration + (memq val '(auto no yes))) +(define-opt + wayland-content-type + enumeration + (memq val '(auto none photo video game))) +(define-opt wayland-disable-vsync boolean) +(define-opt + wayland-edge-pixels-pointer + integer + (>= val 0) + (<= val 2147483647)) +(define-opt + wayland-edge-pixels-touch + integer + (>= val 0) + (<= val 2147483647)) +(define-opt wayland-present boolean) +(define-opt wid integer64) +(define-opt window-dragging boolean) +(define-opt window-maximized boolean) +(define-opt window-minimized boolean) +(define-opt + window-scale + double + (>= val 0.001) + (<= val 100)) +(define-opt + write-filename-in-watch-later-config + boolean) +(define-opt + x11-bypass-compositor + enumeration + (memq val '(no yes fs-only never))) +(define-opt x11-name string) +(define-opt + x11-netwm + enumeration + (memq val '(auto no yes))) +(define-opt + x11-present + enumeration + (memq val '(no auto yes))) +(define-opt x11-wid-title boolean) +(define-opt xv-adaptor integer (>= val -1)) +(define-opt + xv-buffers + integer + (>= val 1) + (<= val 10)) +(define-opt + xv-ck + enumeration + (memq val '(use set cur))) +(define-opt + xv-ck-method + enumeration + (memq val '(none bg man auto))) +(define-opt xv-colorkey integer) +(define-opt xv-port integer (>= val 0)) +(define-opt ytdl boolean) +(define-opt ytdl-format string) +(define-opt ytdl-raw-options list-of-key-value) +(define-opt + zimg-dither + enumeration + (memq val '(no ordered random error-diffusion))) +(define-opt zimg-fast boolean) +(define-opt + zimg-scaler + enumeration + (memq val + '(point bilinear + bicubic + spline16 + spline36 + lanczos))) +(define-opt + zimg-scaler-chroma + enumeration + (memq val + '(point bilinear + bicubic + spline16 + spline36 + lanczos))) +(define-opt zimg-scaler-chroma-param-a double) +(define-opt zimg-scaler-chroma-param-b double) +(define-opt zimg-scaler-param-a double) +(define-opt zimg-scaler-param-b double) +(define-opt + zimg-threads + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 1) (<= val 64)))) +;;; Generated code - END. + +(define-record-type <mpv-profile-configuration> + (%make-mpv-profile-configuration data) + mpv-profile-configuration? + (data %mpv-profile-configuration-data)) + +(define (make-mpv-profile-configuration . args) + ;; I am not sure how can I copy a hash-map. Documentation does not mention + ;; anything. + (let ((new (make-hash-table))) + (let loop ((args args)) + (match args + ((#:inherit cfg . tail) + (hash-for-each (lambda (key val) + (hashq-set! new key val)) + (%mpv-profile-configuration-data cfg)) + (loop tail)) + (((? keyword? key) val . tail) + (let* ((key (keyword->symbol key)) + (opt (hashq-ref %opts key))) + (unless opt + (throw 'bad-config "Option not found" key)) + (unless ((profile-option-type-check opt) val) + (throw 'bad-config "Invalid value for" key val)) + (hashq-set! new key (cons val (profile-option-serializer opt)))) + (loop tail)) + (() + (%make-mpv-profile-configuration new)))))) + +(define (serialize-mpv-profile-configuration _ cfg) + (let ((sorted (sort + (hash-map->list cons (%mpv-profile-configuration-data cfg)) + (lambda (a b) + (string<? (symbol->string (car a)) + (symbol->string (car b))))))) + #~(string-append + #$@(map (match-lambda + ((field-name . value) + ((cdr value) field-name (car value)))) + sorted)))) + + + + +;;; +;;; Configuration base. +;;; +(define (serialize-type/mpv-profile-configurations _ profiles) + #~(string-append + #$@(map (match-lambda + ((name . config) + #~(string-append + #$(format #f "[~a]~%" name) + #$(serialize-mpv-profile-configuration _ config)))) + profiles))) +(define (type/mpv-profile-configurations? alist) + (every (match-lambda + (((? symbol?) . (? mpv-profile-configuration?)) #t) + (_ #f)) + alist)) + +(define (serialize-type/extra _ value) + (if value + #~(string-append #$value + ;; Ensure the extra content ends in a new line. + #$(if (string-suffix? "\n" value) + "" "\n")) + #~"")) +(define (type/extra? val) + (or (string? val) + (gexp? val))) + +(define-record-type <home-mpv-configuration> + (%make-home-mpv-configuration global profiles extra-config) + home-mpv-configuration? + (global home-mpv-configuration-global) + (profiles home-mpv-configuration-profiles) + (extra-config home-mpv-configuration-extra-config)) + +(define* (make-home-mpv-configuration + #:key + (inherit #f) + (global (if inherit + (home-mpv-configuration-global inherit) + (make-mpv-profile-configuration))) + (profiles (if inherit + (home-mpv-configuration-profiles inherit) + '())) + (extra-config (if inherit + (home-mpv-configuration-extra-config inherit) + #f))) + (unless (or (not global) (mpv-profile-configuration? global)) + (throw 'bad-config "global must satisfy mpv-profile-configuration?")) + (unless (type/mpv-profile-configurations? profiles) + (throw 'bad-config "profiles must be an alist of mpv-profile-configuration?")) + (unless (or (not extra-config) (type/extra? extra-config)) + (throw 'bad-config "extra-config must be a string or a gexp")) + (%make-home-mpv-configuration global profiles extra-config)) + +(define (serialize-home-mpv-configuration cfg) + #~(string-append #$(serialize-mpv-profile-configuration + 'global + (home-mpv-configuration-global cfg)) + #$(serialize-type/mpv-profile-configurations + 'profiles + (home-mpv-configuration-profiles cfg)) + #$(serialize-type/extra + 'extra-config + (home-mpv-configuration-extra-config cfg)))) + +(define (mpv-configuration-files cfg) + `(("mpv/mpv.conf" ,(mixed-text-file "mpv.conf" + (serialize-home-mpv-configuration cfg))))) + +(define home-mpv-service-type + (service-type + (name 'home-mpv) + (extensions + (list (service-extension home-xdg-configuration-files-service-type + mpv-configuration-files))) + (description + "Install configuration files for mpv into XDG configuration directory."))) diff --git a/gnu/local.mk b/gnu/local.mk index e149b0e9c4..73a5a659c1 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -110,6 +110,7 @@ GNU_SYSTEM_MODULES = \ %D%/home/services/mail.scm \ %D%/home/services/media.scm \ %D%/home/services/messaging.scm \ + %D%/home/services/mpv.scm \ %D%/home/services/music.scm \ %D%/home/services/pm.scm \ %D%/home/services/shells.scm \ -- 2.46.0
andrew <at> trop.in, janneke <at> gnu.org, ludo <at> gnu.org, maxim.cournoyer <at> gmail.com, tanguy <at> bioneland.org, guix-patches <at> gnu.org
:bug#74801
; Package guix-patches
.
(Wed, 02 Apr 2025 14:08:02 GMT) Full text and rfc822 format available.Message #8 received at 74801 <at> debbugs.gnu.org (full text, mbox):
From: Tomas Volf <~@wolfsden.cz> To: 74801 <at> debbugs.gnu.org Cc: Tomas Volf <~@wolfsden.cz> Subject: [PATCH v2] gnu: home: services: Add home-mpv-service-type. Date: Wed, 2 Apr 2025 16:05:33 +0200
This commit adds a new service type to generate configuration file for the mpv media player. Originally I attempted to use Guix Records (via define-configuration) for this, but ran into the bug #74748, so I had to switch to procedures instead. The usage is (hopefully) sufficiently described in the documentation. When the bug is resolved, I will update it to use define-configuration instead. The full list of supported options is documented, however I decided to *not* document types and purpose for each individual fields. While I had mostly working prototype to extract the documentation from mpv, once I realized it would be few 10k of lines added, I decided it is not worth it. It would bloat the .texi file (by more than 50%), be hard to maintain and, in my opinion, would not provide enough value to justify that. The current version seems like sane middle ground. Option to configure inputs (for mpv) will come later in a separate patch. * gnu/home/services/mpv.scm: New file. * gnu/local.mk (GNU_SYSTEM_MODULES): Register it. * doc/guix.texi (mpv Media Player): Document it. Change-Id: I2deb44799a28047cb5d67da97dc6007a9df873af --- Update for 0.39.0. doc/guix.texi | 428 ++++++ gnu/home/services/mpv.scm | 2732 +++++++++++++++++++++++++++++++++++++ gnu/local.mk | 1 + 3 files changed, 3161 insertions(+) create mode 100644 gnu/home/services/mpv.scm diff --git a/doc/guix.texi b/doc/guix.texi index 3d91dfd7b1..4019346588 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -49846,6 +49846,434 @@ Media Home Services @end table @end deftp +@c This is ugly, but upstream does *not* capitalize the ``m'' even when +@c at the beginning of a sentence. So let us follow the branding. +@node mpv Media Player +@subsection mpv Media Player + +@cindex mpv, Home Service +@cindex mpv, configuration +Configuring the @uref{https://mpv.io/, mpv media player} can be somewhat +daunting task, due to the sheer amount of options available, especially +if one wants to be able to inherit the configuration in their code. The +@code{home-mpv-service-type} is provided to help with that problem. +When the service is added to your home environment, file based on the +passed configuration is generated and placed into the correct location. + +Due to the bug #74748, it does not use Guix Records to represent the +configuration, but uses keyword arguments to achieve similar result. +Example follows: + +@lisp +(service home-mpv-service-type + (make-home-mpv-configuration + #:global (make-mpv-profile-configuration + #:fullscreen #t + #:alang '("jpn" "eng")))) +@end lisp + +@defvar home-mpv-service-type +This is the type of the mpv home service, whose value is a +@code{home-mpv-configuration} object. +@end defvar + +@deffn {Procedure} make-home-mpv-configuration +Return a new instance of @code{home-mpv-configuration}. Available +keyword arguments are: + +@table @asis +@item @code{inherit} (default: @code{#t}) +Inherit fields from an another instance. + +@item @code{global} (default: @code{(make-mpv-profile-configuration)}) +The global configuration preceding all profiles. + +@item @code{profiles} (default: @code{()}) +An alist containing configuration for any additional profiles to include +in the configuration file. + +@lisp +(make-home-mpv-configuration + #:profiles `((fullscreen . ,(make-mpv-profile-configuration + #:fullscreen #t)))) +@end lisp + +@item @code{extra-config} (default: @code{#f}) +Additional content to include in the configuration file. It is placed +at the end of the file. + +@end table +@end deffn + +@deffn {Procedure} make-mpv-profile-configuration +Return a new instance of @code{mpv-profile-configuration}. As above, it +also supports the @code{#:inherit} argument. Additionally it supports +keyword arguments named after the options of @command{mpv}. Hence +@option{--fullscreen} (or @code{fullscreen} in the configuration file) +becomes @code{#:fullscreen}. + +Few options are using their aliases instead. @option{audio} instead of +@option{aid}, @option{video} instead of @option{vid}, @option{sub} +instead of @option{sid}, @option{screenshot-directory} instead of +@option{screenshot-dir} and @option{watch-later-directory} instead of +@option{watch-later-dir}. + +Valid values for the fields depend on their type. + +@table @asis +@item Flags +The value is evaluated for truthfulness. Typically you would use +@code{#f} or @code{#t}. + +@item Numerical fields +Integer and integer64 fields are validated by @code{integer?}, float and +double fields by @code{real?}. Ranges are checked when applicable. + +@item Aspect +Same as integer. + +@item ByteSize +Same as integer64. + +@item Choice +The value should be a symbol representing member of the enumeration. If +the choice has @samp{or ...} part, it can also be value of that +alternative type. + +@item @var{type} list +The value should be a list of the @var{type}. + +@end table + +Other types accept strings, with validation of the values where possible +(e.g. type @samp{Color} is validated, but type @samp{Audio channels or +channel map} is not). + +The full list of currently supported keyword arguments is below. For +the types, allowed values and full description please refer to the +@command{mpv --list-options} and +@uref{https://mpv.io/manual/stable/#options, mpv manual}. + +Only set fields are outputted to the configuration file. Accessors are +provided for every field, returning either their value or a sentinel +object @code{%unset}. + +@code{ab-loop-a}, @code{ab-loop-b}, @code{ab-loop-count}, +@code{access-references}, @code{ad}, @code{ad-lavc-ac3drc}, +@code{ad-lavc-downmix}, @code{ad-lavc-o}, @code{ad-lavc-threads}, +@code{ad-queue-enable}, @code{ad-queue-max-bytes}, +@code{ad-queue-max-samples}, @code{ad-queue-max-secs}, @code{af}, +@code{audio}, @code{alang}, @code{allow-delayed-peak-detect}, +@code{alsa-buffer-time}, @code{alsa-ignore-chmap}, +@code{alsa-mixer-device}, @code{alsa-mixer-index}, +@code{alsa-mixer-name}, @code{alsa-non-interleaved}, +@code{alsa-periods}, @code{alsa-resample}, @code{ao}, +@code{ao-null-broken-delay}, @code{ao-null-broken-eof}, +@code{ao-null-buffer}, @code{ao-null-channel-layouts}, +@code{ao-null-format}, @code{ao-null-latency}, @code{ao-null-outburst}, +@code{ao-null-speed}, @code{ao-null-untimed}, @code{ao-pcm-append}, +@code{ao-pcm-file}, @code{ao-pcm-waveheader}, +@code{audio-backward-batch}, @code{audio-backward-overlap}, +@code{audio-buffer}, @code{audio-channels}, @code{audio-client-name}, +@code{audio-delay}, @code{audio-demuxer}, @code{audio-device}, +@code{audio-display}, @code{audio-exclusive}, @code{audio-exts}, +@code{audio-fallback-to-null}, @code{audio-file-auto}, +@code{audio-file-paths}, @code{audio-files}, @code{audio-format}, +@code{audio-normalize-downmix}, @code{audio-pitch-correction}, +@code{audio-resample-cutoff}, @code{audio-resample-filter-size}, +@code{audio-resample-linear}, @code{audio-resample-max-output-size}, +@code{audio-resample-phase-shift}, @code{audio-reversal-buffer}, +@code{audio-samplerate}, @code{audio-spdif}, +@code{audio-stream-silence}, @code{audio-swresample-o}, +@code{audio-wait-open}, @code{auto-window-resize}, +@code{autocreate-playlist}, @code{autofit}, @code{autofit-larger}, +@code{autofit-smaller}, @code{autoload-files}, @code{autosync}, +@code{background}, @code{background-color}, @code{blend-subtitles}, +@code{bluray-device}, @code{border}, @code{border-background}, +@code{brightness}, @code{cache}, @code{cache-on-disk}, +@code{cache-pause}, @code{cache-pause-initial}, @code{cache-pause-wait}, +@code{cache-secs}, @code{cdda-cdtext}, @code{cdda-device}, +@code{cdda-overlap}, @code{cdda-paranoia}, @code{cdda-sector-size}, +@code{cdda-skip}, @code{cdda-span-a}, @code{cdda-span-b}, +@code{cdda-speed}, @code{cdda-toc-offset}, +@code{chapter-merge-threshold}, @code{chapter-seek-threshold}, +@code{chapters-file}, @code{config}, @code{container-fps-override}, +@code{contrast}, @code{cookies}, @code{cookies-file}, +@code{corner-rounding}, @code{correct-downscaling}, @code{correct-pts}, +@code{cover-art-auto}, @code{cover-art-files}, +@code{cover-art-whitelist}, @code{cscale}, @code{cscale-antiring}, +@code{cscale-blur}, @code{cscale-clamp}, @code{cscale-param1}, +@code{cscale-param2}, @code{cscale-radius}, @code{cscale-taper}, +@code{cscale-window}, @code{cscale-wparam}, @code{cscale-wtaper}, +@code{cursor-autohide}, @code{cursor-autohide-fs-only}, @code{deband}, +@code{deband-grain}, @code{deband-iterations}, @code{deband-range}, +@code{deband-threshold}, @code{deinterlace}, +@code{deinterlace-field-parity}, @code{demuxer}, +@code{demuxer-backward-playback-step}, @code{demuxer-cache-dir}, +@code{demuxer-cache-unlink-files}, @code{demuxer-cache-wait}, +@code{demuxer-donate-buffer}, @code{demuxer-hysteresis-secs}, +@code{demuxer-lavf-allow-mimetype}, @code{demuxer-lavf-analyzeduration}, +@code{demuxer-lavf-buffersize}, @code{demuxer-lavf-format}, +@code{demuxer-lavf-hacks}, @code{demuxer-lavf-linearize-timestamps}, +@code{demuxer-lavf-o}, @code{demuxer-lavf-probe-info}, +@code{demuxer-lavf-probescore}, @code{demuxer-lavf-probesize}, +@code{demuxer-lavf-propagate-opts}, @code{demuxer-max-back-bytes}, +@code{demuxer-max-bytes}, @code{demuxer-mkv-probe-start-time}, +@code{demuxer-mkv-probe-video-duration}, +@code{demuxer-mkv-subtitle-preroll}, +@code{demuxer-mkv-subtitle-preroll-secs}, +@code{demuxer-mkv-subtitle-preroll-secs-index}, +@code{demuxer-rawaudio-channels}, @code{demuxer-rawaudio-format}, +@code{demuxer-rawaudio-rate}, @code{demuxer-rawvideo-codec}, +@code{demuxer-rawvideo-format}, @code{demuxer-rawvideo-fps}, +@code{demuxer-rawvideo-h}, @code{demuxer-rawvideo-mp-format}, +@code{demuxer-rawvideo-size}, @code{demuxer-rawvideo-w}, +@code{demuxer-readahead-secs}, @code{demuxer-seekable-cache}, +@code{demuxer-termination-timeout}, @code{demuxer-thread}, +@code{directory-filter-types}, @code{directory-mode}, +@code{display-fps-override}, @code{display-tags}, @code{dither}, +@code{dither-depth}, @code{dither-size-fruit}, @code{drag-and-drop}, +@code{drm-connector}, @code{drm-device}, @code{drm-draw-plane}, +@code{drm-draw-surface-size}, @code{drm-drmprime-video-plane}, +@code{drm-format}, @code{drm-mode}, @code{drm-vrr-enabled}, +@code{dscale}, @code{dscale-antiring}, @code{dscale-blur}, +@code{dscale-clamp}, @code{dscale-param1}, @code{dscale-param2}, +@code{dscale-radius}, @code{dscale-taper}, @code{dscale-window}, +@code{dscale-wparam}, @code{dscale-wtaper}, @code{dump-stats}, +@code{dvbin-card}, @code{dvbin-channel-switch-offset}, +@code{dvbin-file}, @code{dvbin-full-transponder}, @code{dvbin-prog}, +@code{dvbin-timeout}, @code{dvd-angle}, @code{dvd-device}, +@code{dvd-speed}, @code{edition}, @code{egl-config-id}, +@code{egl-output-format}, @code{embeddedfonts}, @code{end}, +@code{error-diffusion}, @code{external-files}, @code{fbo-format}, +@code{focus-on}, @code{force-media-title}, @code{force-render}, +@code{force-rgba-osd-rendering}, @code{force-seekable}, +@code{force-window}, @code{force-window-position}, @code{framedrop}, +@code{frames}, @code{fs-screen}, @code{fs-screen-name}, +@code{fullscreen}, @code{gamma}, @code{gamma-auto}, @code{gamma-factor}, +@code{gamut-mapping-mode}, @code{gapless-audio}, @code{geometry}, +@code{glsl-shader-opts}, @code{glsl-shaders}, @code{gpu-api}, +@code{gpu-context}, @code{gpu-debug}, @code{gpu-dumb-mode}, +@code{gpu-hwdec-interop}, @code{gpu-shader-cache}, +@code{gpu-shader-cache-dir}, @code{gpu-sw}, @code{gpu-tex-pad-x}, +@code{gpu-tex-pad-y}, @code{hdr-compute-peak}, +@code{hdr-contrast-recovery}, @code{hdr-contrast-smoothness}, +@code{hdr-peak-decay-rate}, @code{hdr-peak-percentile}, +@code{hdr-scene-threshold-high}, @code{hdr-scene-threshold-low}, +@code{hidpi-window-scale}, @code{hls-bitrate}, @code{hr-seek}, +@code{hr-seek-demuxer-offset}, @code{hr-seek-framedrop}, +@code{http-header-fields}, @code{http-proxy}, @code{hue}, @code{hwdec}, +@code{hwdec-codecs}, @code{hwdec-extra-frames}, +@code{hwdec-image-format}, @code{icc-3dlut-size}, @code{icc-cache}, +@code{icc-cache-dir}, @code{icc-force-contrast}, @code{icc-intent}, +@code{icc-profile}, @code{icc-profile-auto}, @code{icc-use-luma}, +@code{idle}, @code{ignore-path-in-watch-later-config}, +@code{image-display-duration}, @code{image-exts}, @code{image-lut}, +@code{image-lut-type}, @code{image-subs-video-resolution}, +@code{include}, @code{index}, @code{initial-audio-sync}, +@code{input-ar-delay}, @code{input-ar-rate}, +@code{input-builtin-bindings}, @code{input-builtin-dragging}, +@code{input-commands}, @code{input-conf}, @code{input-cursor}, +@code{input-cursor-passthrough}, @code{input-default-bindings}, +@code{input-doubleclick-time}, @code{input-dragging-deadzone}, +@code{input-ipc-client}, @code{input-ipc-server}, +@code{input-key-fifo-size}, @code{input-media-keys}, +@code{input-preprocess-wheel}, @code{input-right-alt-gr}, +@code{input-terminal}, @code{input-test}, +@code{input-touch-emulate-mouse}, @code{input-vo-keyboard}, +@code{interpolation}, @code{interpolation-preserve}, +@code{interpolation-threshold}, @code{inverse-tone-mapping}, +@code{jack-autostart}, @code{jack-connect}, @code{jack-name}, +@code{jack-port}, @code{jack-std-channel-layout}, @code{keep-open}, +@code{keep-open-pause}, @code{keepaspect}, @code{keepaspect-window}, +@code{lavfi-complex}, @code{length}, @code{libplacebo-opts}, +@code{linear-downscaling}, @code{linear-upscaling}, +@code{load-auto-profiles}, @code{load-osd-console}, @code{load-scripts}, +@code{load-select}, @code{load-stats-overlay}, +@code{load-unsafe-playlists}, @code{log-file}, @code{loop-file}, +@code{loop-playlist}, @code{lut}, @code{lut-type}, @code{mc}, +@code{media-controls}, @code{merge-files}, @code{metadata-codepage}, +@code{mf-fps}, @code{mf-type}, @code{monitoraspect}, +@code{monitorpixelaspect}, @code{msg-color}, @code{msg-level}, +@code{msg-module}, @code{msg-time}, @code{mute}, @code{native-fs}, +@code{native-keyrepeat}, @code{native-touch}, @code{network-timeout}, +@code{oac}, @code{oacopts}, @code{ocopy-metadata}, @code{of}, +@code{ofopts}, @code{on-all-workspaces}, @code{ontop}, +@code{ontop-level}, @code{opengl-check-pattern-a}, +@code{opengl-check-pattern-b}, @code{opengl-early-flush}, +@code{opengl-es}, @code{opengl-glfinish}, @code{opengl-pbo}, +@code{opengl-rectangle-textures}, @code{opengl-swapinterval}, +@code{opengl-waitvsync}, @code{orawts}, @code{ordered-chapters}, +@code{ordered-chapters-files}, @code{oremove-metadata}, @code{osc}, +@code{osd-align-x}, @code{osd-align-y}, @code{osd-back-color}, +@code{osd-bar}, @code{osd-bar-align-x}, @code{osd-bar-align-y}, +@code{osd-bar-h}, @code{osd-bar-outline-size}, @code{osd-bar-w}, +@code{osd-blur}, @code{osd-bold}, @code{osd-border-style}, +@code{osd-color}, @code{osd-duration}, @code{osd-font}, +@code{osd-font-provider}, @code{osd-font-size}, @code{osd-fonts-dir}, +@code{osd-fractions}, @code{osd-italic}, @code{osd-justify}, +@code{osd-level}, @code{osd-margin-x}, @code{osd-margin-y}, +@code{osd-msg1}, @code{osd-msg2}, @code{osd-msg3}, @code{osd-on-seek}, +@code{osd-outline-color}, @code{osd-outline-size}, +@code{osd-playing-msg}, @code{osd-playing-msg-duration}, +@code{osd-playlist-entry}, @code{osd-scale}, @code{osd-scale-by-window}, +@code{osd-shadow-offset}, @code{osd-spacing}, @code{osd-status-msg}, +@code{oset-metadata}, @code{ovc}, @code{ovcopts}, @code{panscan}, +@code{pause}, @code{pipewire-buffer}, @code{pipewire-remote}, +@code{pipewire-volume-mode}, @code{pitch}, @code{play-direction}, +@code{player-operation-mode}, @code{playlist-start}, +@code{prefetch-playlist}, @code{profile}, @code{pulse-allow-suspended}, +@code{pulse-buffer}, @code{pulse-host}, @code{pulse-latency-hacks}, +@code{quiet}, @code{really-quiet}, @code{rebase-start-time}, +@code{referrer}, @code{replaygain}, @code{replaygain-clip}, +@code{replaygain-fallback}, @code{replaygain-preamp}, +@code{reset-on-next-file}, @code{resume-playback}, +@code{resume-playback-check-mtime}, @code{rtsp-transport}, +@code{saturation}, @code{save-position-on-quit}, @code{scale}, +@code{scale-antiring}, @code{scale-blur}, @code{scale-clamp}, +@code{scale-param1}, @code{scale-param2}, @code{scale-radius}, +@code{scale-taper}, @code{scale-window}, @code{scale-wparam}, +@code{scale-wtaper}, @code{scaler-resizes-only}, @code{screen}, +@code{screen-name}, @code{screenshot-avif-encoder}, +@code{screenshot-avif-opts}, @code{screenshot-avif-pixfmt}, +@code{screenshot-directory}, @code{screenshot-format}, +@code{screenshot-high-bit-depth}, @code{screenshot-jpeg-quality}, +@code{screenshot-jpeg-source-chroma}, @code{screenshot-jxl-distance}, +@code{screenshot-jxl-effort}, @code{screenshot-png-compression}, +@code{screenshot-png-filter}, @code{screenshot-sw}, +@code{screenshot-tag-colorspace}, @code{screenshot-template}, +@code{screenshot-webp-compression}, @code{screenshot-webp-lossless}, +@code{screenshot-webp-quality}, @code{script-opts}, @code{scripts}, +@code{secondary-sid}, @code{secondary-sub-ass-override}, +@code{secondary-sub-delay}, @code{secondary-sub-pos}, +@code{secondary-sub-visibility}, @code{sharpen}, @code{show-in-taskbar}, +@code{shuffle}, @code{sub}, @code{sigmoid-center}, @code{sigmoid-slope}, +@code{sigmoid-upscaling}, @code{slang}, @code{snap-window}, +@code{speed}, @code{spirv-compiler}, @code{sstep}, @code{start}, +@code{stop-playback-on-init-failure}, @code{stop-screensaver}, +@code{stream-buffer-size}, @code{stream-dump}, @code{stream-lavf-o}, +@code{stream-record}, @code{stretch-dvd-subs}, +@code{stretch-image-subs-to-screen}, @code{sub-align-x}, +@code{sub-align-y}, @code{sub-ass}, @code{sub-ass-force-margins}, +@code{sub-ass-hinting}, @code{sub-ass-justify}, +@code{sub-ass-line-spacing}, @code{sub-ass-override}, +@code{sub-ass-scale-with-window}, @code{sub-ass-shaper}, +@code{sub-ass-style-overrides}, @code{sub-ass-styles}, +@code{sub-ass-use-video-data}, @code{sub-ass-video-aspect-override}, +@code{sub-ass-vsfilter-color-compat}, @code{sub-auto}, +@code{sub-auto-exts}, @code{sub-back-color}, @code{sub-blur}, +@code{sub-bold}, @code{sub-border-style}, @code{sub-clear-on-seek}, +@code{sub-codepage}, @code{sub-color}, @code{sub-create-cc-track}, +@code{sub-delay}, @code{sub-demuxer}, @code{sub-file-paths}, +@code{sub-files}, @code{sub-filter-jsre}, @code{sub-filter-regex}, +@code{sub-filter-regex-enable}, @code{sub-filter-regex-plain}, +@code{sub-filter-regex-warn}, @code{sub-filter-sdh}, +@code{sub-filter-sdh-enclosures}, @code{sub-filter-sdh-harder}, +@code{sub-fix-timing}, @code{sub-font}, @code{sub-font-provider}, +@code{sub-font-size}, @code{sub-fonts-dir}, +@code{sub-forced-events-only}, @code{sub-fps}, @code{sub-gauss}, +@code{sub-gray}, @code{sub-italic}, @code{sub-justify}, +@code{sub-lavc-o}, @code{sub-margin-x}, @code{sub-margin-y}, +@code{sub-outline-color}, @code{sub-outline-size}, +@code{sub-past-video-end}, @code{sub-pos}, @code{sub-scale}, +@code{sub-scale-by-window}, @code{sub-scale-with-window}, +@code{sub-shadow-offset}, @code{sub-spacing}, @code{sub-speed}, +@code{sub-stretch-durations}, @code{sub-use-margins}, +@code{sub-visibility}, @code{sub-vsfilter-bidi-compat}, +@code{subs-fallback}, @code{subs-fallback-forced}, +@code{subs-match-os-language}, @code{subs-with-matching-audio}, +@code{swapchain-depth}, @code{sws-allow-zimg}, @code{sws-bitexact}, +@code{sws-cgb}, @code{sws-chs}, @code{sws-cs}, @code{sws-cvs}, +@code{sws-fast}, @code{sws-lgb}, @code{sws-ls}, @code{sws-scaler}, +@code{target-colorspace-hint}, @code{target-contrast}, +@code{target-gamut}, @code{target-lut}, @code{target-peak}, +@code{target-prim}, @code{target-trc}, @code{taskbar-progress}, +@code{teletext-page}, @code{temporal-dither}, +@code{temporal-dither-period}, @code{term-osd}, @code{term-osd-bar}, +@code{term-osd-bar-chars}, @code{term-playing-msg}, +@code{term-status-msg}, @code{term-title}, @code{terminal}, +@code{title}, @code{title-bar}, @code{tls-ca-file}, +@code{tls-cert-file}, @code{tls-key-file}, @code{tls-verify}, +@code{tone-mapping}, @code{tone-mapping-max-boost}, +@code{tone-mapping-param}, @code{tone-mapping-visualize}, +@code{track-auto-selection}, @code{tscale}, @code{tscale-antiring}, +@code{tscale-blur}, @code{tscale-clamp}, @code{tscale-param1}, +@code{tscale-param2}, @code{tscale-radius}, @code{tscale-taper}, +@code{tscale-window}, @code{tscale-wparam}, @code{tscale-wtaper}, +@code{untimed}, @code{use-embedded-icc-profile}, +@code{use-filedir-conf}, @code{user-agent}, @code{vaapi-device}, +@code{vd}, @code{vd-apply-cropping}, @code{vd-lavc-assume-old-x264}, +@code{vd-lavc-bitexact}, @code{vd-lavc-check-hw-profile}, +@code{vd-lavc-dr}, @code{vd-lavc-fast}, @code{vd-lavc-film-grain}, +@code{vd-lavc-framedrop}, @code{vd-lavc-o}, @code{vd-lavc-show-all}, +@code{vd-lavc-skipframe}, @code{vd-lavc-skipidct}, +@code{vd-lavc-skiploopfilter}, @code{vd-lavc-software-fallback}, +@code{vd-lavc-threads}, @code{vd-queue-enable}, +@code{vd-queue-max-bytes}, @code{vd-queue-max-samples}, +@code{vd-queue-max-secs}, @code{vf}, @code{video}, @code{video-align-x}, +@code{video-align-y}, @code{video-aspect-method}, +@code{video-aspect-override}, @code{video-backward-batch}, +@code{video-backward-overlap}, @code{video-crop}, @code{video-exts}, +@code{video-latency-hacks}, @code{video-margin-ratio-bottom}, +@code{video-margin-ratio-left}, @code{video-margin-ratio-right}, +@code{video-margin-ratio-top}, @code{video-osd}, +@code{video-output-levels}, @code{video-pan-x}, @code{video-pan-y}, +@code{video-reversal-buffer}, @code{video-rotate}, @code{video-scale-x}, +@code{video-scale-y}, @code{video-sync}, +@code{video-sync-max-audio-change}, @code{video-sync-max-factor}, +@code{video-sync-max-video-change}, @code{video-timing-offset}, +@code{video-unscaled}, @code{video-zoom}, @code{vlang}, @code{vo}, +@code{vo-image-avif-encoder}, @code{vo-image-avif-opts}, +@code{vo-image-avif-pixfmt}, @code{vo-image-format}, +@code{vo-image-high-bit-depth}, @code{vo-image-jpeg-quality}, +@code{vo-image-jpeg-source-chroma}, @code{vo-image-jxl-distance}, +@code{vo-image-jxl-effort}, @code{vo-image-outdir}, +@code{vo-image-png-compression}, @code{vo-image-png-filter}, +@code{vo-image-tag-colorspace}, @code{vo-image-webp-compression}, +@code{vo-image-webp-lossless}, @code{vo-image-webp-quality}, +@code{vo-kitty-alt-screen}, @code{vo-kitty-cols}, +@code{vo-kitty-config-clear}, @code{vo-kitty-height}, +@code{vo-kitty-left}, @code{vo-kitty-rows}, @code{vo-kitty-top}, +@code{vo-kitty-use-shm}, @code{vo-kitty-width}, @code{vo-null-fps}, +@code{vo-sixel-alt-screen}, @code{vo-sixel-buffered}, +@code{vo-sixel-cols}, @code{vo-sixel-config-clear}, +@code{vo-sixel-dither}, @code{vo-sixel-fixedpalette}, +@code{vo-sixel-height}, @code{vo-sixel-left}, @code{vo-sixel-pad-x}, +@code{vo-sixel-pad-y}, @code{vo-sixel-reqcolors}, @code{vo-sixel-rows}, +@code{vo-sixel-threshold}, @code{vo-sixel-top}, @code{vo-sixel-width}, +@code{vo-tct-256}, @code{vo-tct-algo}, @code{vo-tct-buffering}, +@code{vo-tct-height}, @code{vo-tct-width}, @code{vo-vaapi-scaled-osd}, +@code{vo-vaapi-scaling}, @code{vo-vdpau-chroma-deint}, +@code{vo-vdpau-colorkey}, @code{vo-vdpau-composite-detect}, +@code{vo-vdpau-denoise}, @code{vo-vdpau-force-yuv}, @code{vo-vdpau-fps}, +@code{vo-vdpau-hqscaling}, @code{vo-vdpau-output-surfaces}, +@code{vo-vdpau-pullup}, @code{vo-vdpau-queuetime-fs}, +@code{vo-vdpau-queuetime-windowed}, @code{vo-vdpau-sharpen}, +@code{volume}, @code{volume-gain}, @code{volume-gain-max}, +@code{volume-gain-min}, @code{volume-max}, @code{vulkan-async-compute}, +@code{vulkan-async-transfer}, @code{vulkan-device}, +@code{vulkan-display-display}, @code{vulkan-display-mode}, +@code{vulkan-display-plane}, @code{vulkan-queue-count}, +@code{vulkan-swap-mode}, @code{watch-later-directory}, +@code{watch-later-options}, @code{wayland-app-id}, +@code{wayland-configure-bounds}, @code{wayland-content-type}, +@code{wayland-disable-vsync}, @code{wayland-edge-pixels-pointer}, +@code{wayland-edge-pixels-touch}, @code{wayland-present}, @code{wid}, +@code{window-dragging}, @code{window-maximized}, +@code{window-minimized}, @code{window-scale}, +@code{write-filename-in-watch-later-config}, +@code{x11-bypass-compositor}, @code{x11-name}, @code{x11-netwm}, +@code{x11-present}, @code{x11-wid-title}, @code{xv-adaptor}, +@code{xv-buffers}, @code{xv-ck}, @code{xv-ck-method}, +@code{xv-colorkey}, @code{xv-port}, @code{ytdl}, @code{ytdl-format}, +@code{ytdl-raw-options}, @code{zimg-dither}, @code{zimg-fast}, +@code{zimg-scaler}, @code{zimg-scaler-chroma}, +@code{zimg-scaler-chroma-param-a}, @code{zimg-scaler-chroma-param-b}, +@code{zimg-scaler-param-a}, @code{zimg-scaler-param-b}, and +@code{zimg-threads}. + +@end deffn + @node Sway window manager @subsection Sway window manager diff --git a/gnu/home/services/mpv.scm b/gnu/home/services/mpv.scm new file mode 100644 index 0000000000..e2fa44162a --- /dev/null +++ b/gnu/home/services/mpv.scm @@ -0,0 +1,2732 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2024 Tomas Volf <~@wolfsden.cz> +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix 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 General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. + +(define-module (gnu home services mpv) + #:use-module (gnu home services) + #:use-module (guix gexp) + #:use-module (ice-9 match) + #:use-module (ice-9 regex) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-2) + #:use-module (srfi srfi-9) + #:use-module (srfi srfi-26) + #:use-module (srfi srfi-71) + #:export (make-home-mpv-configuration + home-mpv-configuration? + home-mpv-configuration-global + home-mpv-configuration-profiles + home-mpv-configuration-extra-config + home-mpv-configuration-source-location + + serialize-home-mpv-configuration + + %unset + + make-mpv-profile-configuration + mpv-profile-configuration? + ;; Field accessor procedures are exported by a syntax form when + ;; they are defined, so they are not listed here. + + home-mpv-service-type)) + +(define %unset '(*unset*)) + + +;;; +;;; Basic types. +;;; +(define (serialize-type/boolean field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(if value "yes" "no") + "\n")) +(define type/boolean? + (const #t)) + +(define (serialize-type/integer field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(number->string value) + "\n")) +(define (type/integer? n) + ;; We assume integer is a signed 32bit number. + (and-let* (((integer? n)) + ((>= n -2147483648)) + ((<= n 2147483647))))) + +(define (serialize-type/integer64 field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(number->string value) + "\n")) +(define (type/integer64? n) + ;; We assume integer is a signed 64bit number. + (and-let* (((integer? n)) + ((>= n -9223372036854775808)) + ((<= n 9223372036854775807))))) + +(define (serialize-type/string field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$value + "\n")) +(define type/string? + string?) + +(define (serialize-type/float field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(number->string (exact->inexact value)) + "\n")) +(define type/float? + ;; I am not sure how to validate floats. + real?) + +(define (serialize-type/double field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(number->string (exact->inexact value)) + "\n")) +(define (type/double? value) + ;; I am not sure how to validate doubles. + real?) + + + + +;;; +;;; Additional types (possible based on the basic ones). +;;; + +;;; Aspect seems to be treated as an integer, so define it in terms of it. +(define serialize-type/aspect serialize-type/integer) +(define type/aspect? type/integer?) + +;;; `Audio channels or channel map' seems to be basically a free form string +;;; with no way to validate. +(define serialize-type/audio-channels-or-channel-map serialize-type/string) +(define type/audio-channels-or-channel-map? type/string?) + +;;; Does not seem possible to validate. +(define serialize-type/audio-format serialize-type/string) +(define type/audio-format? type/string?) + +;;; While most options list 4.6116860184274e+18 as a maximum value, we will +;;; use integer64 here. That should be enough for everyone for few more +;;; years. +(define serialize-type/byte-size serialize-type/integer64) +(define type/byte-size? type/integer64?) + +(define (serialize-type/color field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(if (list? value) + (string-join (map number->string value) "/") + value) + "\n")) +(define (type/color? value) + (define (ok-num? n) + (and (number? n) + (>= n 0) + (<= n 1))) + (if (list? value) + ;; Either a list of 3(4) numbers encoding RGB(A) on range from 0 to 1... + (match value + (((? ok-num? r) (? ok-num? g) (? ok-num? b)) + #t) + (((? ok-num? r) (? ok-num? g) (? ok-num? b) (? ok-num? alpha)) + #t) + (_ + #f)) + ;; ... or RGB(A) hex encoding. + (string-match "^#([A-Fa-f0-9]{2})?[A-Fa-f0-9]{6}$" value))) + +;;; I do not see value mirroring fourcc.org's database here. It is further +;;; complicated by arbitrary hex being accepted as well. So string it is. +(define serialize-type/fourcc serialize-type/string) +(define type/fourcc? type/string?) + +;;; No way to validate. +(define serialize-type/image-format serialize-type/string) +(define type/image-format? type/string?) + +;;; Looking at the documentation for --start, there is no way to make this +;;; bullet-proof, especially since even chapter numbers are accepted. +(define serialize-type/relative-time-or-percent-position serialize-type/string) +(define type/relative-time-or-percent-position? type/string?) + +(define serialize-type/time serialize-type/string) +(define type/time? type/string?) + +(define serialize-type/video-rectangle serialize-type/string) +(define (type/video-rectangle? value) + (or (string-match "-?[0-9]+%?:-?[0-9]+%?" value) + (string-match + "^(-?[0-9]+%?(x-?[0-9]+%?)?)?([+-]-?[0-9]+%?[+-]-?[0-9]+%?)?$" + value))) + +(define serialize-type/window-geometry serialize-type/string) +(define (type/window-geometry? value) + (or (string-match "-?[0-9]+%?:-?[0-9]+%?" value) + (string-match + "^(-?[0-9]+%?(x-?[0-9]+%?)?)?([+-]-?[0-9]+%?[+-]-?[0-9]+%?)?(/[0-9]+)?$" + value))) + +(define serialize-type/window-size serialize-type/string) +(define (type/window-size? value) + (string-match "^([0-9]+%?(x[0-9]+%?)?)?$" value)) + +(define (serialize-type/enumeration field-name value) + #~(string-append #$(symbol->string field-name) + "=" + ;; This could be either symbol or (in case of enumerations + ;; with alternate type) anything. So just use `format'. + #$(format #f "~s" value) + "\n")) +(define (type/enumeration? value) + ;; There is no general way to check enumerations. The field always has to + ;; define custom sanitizer. + #t) + + + + +;;; +;;; List types. +;;; +(define (serialize-type/list-of-string field-name lst) + #~(string-append #$(symbol->string field-name) + "=" + #$(string-join lst ",") + "\n")) +(define (type/list-of-string? lst) + (every type/string? lst)) + +(define (serialize-type/list-of-key-value field-name lst) + #~(string-append #$(symbol->string field-name) + "=" + #$(string-join (map (match-lambda + ((k . v) (format #f "~a=~a" k v))) + lst) + ",") + "\n")) +(define (type/list-of-key-value? lst) + (every (match-lambda + (((? string?) . (? string?)) #t) + (_ #f)) + lst)) + +(define serialize-type/list-of-object-setting serialize-type/list-of-string) +(define type/list-of-object-setting? type/list-of-string?) + +(define serialize-type/list-of-output-verbosity serialize-type/list-of-key-value) +(define type/list-of-output-verbosity? type/list-of-key-value?) + + + + +;;; +;;; Actual configuration record. Contains a lot of generated code. +;;; + +(define-record-type <profile-option> + (make-profile-option name type-check serializer) + profile-option? + (name profile-option-name) + (type-check profile-option-type-check) + (serializer profile-option-serializer)) + +(define %opts (make-hash-table)) + +(define-syntax define-opt + (lambda (x) + (syntax-case x () + ((_ name type extra-checks ...) + (let* ((d/n (syntax->datum #'name)) + (d/t (syntax->datum #'type)) + (d/accessor (string->symbol + (format #f "mpv-profile-configuration-~a" d/n))) + (d/type-check (string->symbol + (format #f "type/~a?" d/t))) + (d/serializer (string->symbol + (format #f "serialize-type/~a" d/t)))) + (with-syntax + ((kw (datum->syntax x (symbol->keyword d/n))) + (accessor (datum->syntax x d/accessor)) + (type-check (datum->syntax x d/type-check)) + (serializer (datum->syntax x d/serializer)) + (val (datum->syntax x 'val))) + #'(begin + (hashq-set! %opts 'name + (make-profile-option (symbol->string 'name) + (lambda (val) + (and (type-check val) + extra-checks ...)) + serializer)) + (define-public (accessor cfg) + (let ((x (hashq-ref (%mpv-profile-configuration-data cfg) + 'name + %unset))) + (if (eq? x %unset) + %unset + (car x))))))))))) + +;;; Generated code - START. +(define-opt ab-loop-a time) +(define-opt ab-loop-b time) +(define-opt + ab-loop-count + enumeration + (or (memq val '(inf)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt access-references boolean) +(define-opt ad string) +(define-opt + ad-lavc-ac3drc + float + (>= val 0) + (<= val 6)) +(define-opt ad-lavc-downmix boolean) +(define-opt ad-lavc-o list-of-key-value) +(define-opt + ad-lavc-threads + integer + (>= val 0) + (<= val 16)) +(define-opt ad-queue-enable boolean) +(define-opt + ad-queue-max-bytes + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + ad-queue-max-samples + integer64 + (>= val 0)) +(define-opt ad-queue-max-secs double (>= val 0)) +(define-opt af list-of-object-setting) +(define-opt + audio + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt alang list-of-string) +(define-opt allow-delayed-peak-detect boolean) +(define-opt + alsa-buffer-time + integer + (>= val 0) + (<= val 2147483647)) +(define-opt alsa-ignore-chmap boolean) +(define-opt alsa-mixer-device string) +(define-opt + alsa-mixer-index + integer + (>= val 0) + (<= val 99)) +(define-opt alsa-mixer-name string) +(define-opt alsa-non-interleaved boolean) +(define-opt + alsa-periods + integer + (>= val 0) + (<= val 2147483647)) +(define-opt alsa-resample boolean) +(define-opt ao list-of-object-setting) +(define-opt ao-null-broken-delay boolean) +(define-opt ao-null-broken-eof boolean) +(define-opt + ao-null-buffer + float + (>= val 0) + (<= val 100)) +(define-opt + ao-null-channel-layouts + audio-channels-or-channel-map) +(define-opt ao-null-format audio-format) +(define-opt + ao-null-latency + float + (>= val 0) + (<= val 100)) +(define-opt + ao-null-outburst + integer + (>= val 1) + (<= val 100000)) +(define-opt + ao-null-speed + float + (>= val 0) + (<= val 10000)) +(define-opt ao-null-untimed boolean) +(define-opt ao-pcm-append boolean) +(define-opt ao-pcm-file string) +(define-opt ao-pcm-waveheader boolean) +(define-opt + audio-backward-batch + integer + (>= val 0) + (<= val 1024)) +(define-opt + audio-backward-overlap + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 0) (<= val 1024)))) +(define-opt + audio-buffer + double + (>= val 0) + (<= val 10)) +(define-opt + audio-channels + audio-channels-or-channel-map) +(define-opt audio-client-name string) +(define-opt audio-delay float) +(define-opt audio-demuxer string) +(define-opt audio-device string) +(define-opt + audio-display + enumeration + (memq val '(no embedded-first external-first))) +(define-opt audio-exclusive boolean) +(define-opt audio-exts list-of-string) +(define-opt audio-fallback-to-null boolean) +(define-opt + audio-file-auto + enumeration + (memq val '(no exact fuzzy all))) +(define-opt audio-file-paths list-of-string) +(define-opt audio-files list-of-string) +(define-opt audio-format audio-format) +(define-opt audio-normalize-downmix boolean) +(define-opt audio-pitch-correction boolean) +(define-opt + audio-resample-cutoff + double + (>= val 0) + (<= val 1)) +(define-opt + audio-resample-filter-size + integer + (>= val 0) + (<= val 32)) +(define-opt audio-resample-linear boolean) +(define-opt + audio-resample-max-output-size + double) +(define-opt + audio-resample-phase-shift + integer + (>= val 0) + (<= val 30)) +(define-opt + audio-reversal-buffer + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + audio-samplerate + integer + (>= val 0) + (<= val 768000)) +(define-opt audio-spdif string) +(define-opt audio-stream-silence boolean) +(define-opt audio-swresample-o list-of-key-value) +(define-opt + audio-wait-open + float + (>= val 0) + (<= val 60)) +(define-opt auto-window-resize boolean) +(define-opt + autocreate-playlist + enumeration + (memq val '(no filter same))) +(define-opt autofit window-size) +(define-opt autofit-larger window-size) +(define-opt autofit-smaller window-size) +(define-opt autoload-files boolean) +(define-opt + autosync + enumeration + (or (memq val '(no)) + (and (integer? val) (>= val 0) (<= val 10000)))) +(define-opt + background + enumeration + (memq val '(none color tiles))) +(define-opt background-color color) +(define-opt + blend-subtitles + enumeration + (memq val '(no yes video))) +(define-opt bluray-device string) +(define-opt border boolean) +(define-opt + border-background + enumeration + (memq val '(none color tiles))) +(define-opt + brightness + float + (>= val -100) + (<= val 100)) +(define-opt + cache + enumeration + (memq val '(no auto yes))) +(define-opt cache-on-disk boolean) +(define-opt cache-pause boolean) +(define-opt cache-pause-initial boolean) +(define-opt cache-pause-wait float (>= val 0)) +(define-opt cache-secs double (>= val 0)) +(define-opt cdda-cdtext boolean) +(define-opt cdda-device string) +(define-opt + cdda-overlap + integer + (>= val 0) + (<= val 75)) +(define-opt + cdda-paranoia + integer + (>= val 0) + (<= val 2)) +(define-opt + cdda-sector-size + integer + (>= val 1) + (<= val 100)) +(define-opt cdda-skip boolean) +(define-opt cdda-span-a integer) +(define-opt cdda-span-b integer) +(define-opt + cdda-speed + integer + (>= val 1) + (<= val 100)) +(define-opt cdda-toc-offset integer) +(define-opt + chapter-merge-threshold + integer + (>= val 0) + (<= val 10000)) +(define-opt chapter-seek-threshold double) +(define-opt chapters-file string) +(define-opt config boolean) +(define-opt + container-fps-override + double + (>= val 0)) +(define-opt + contrast + float + (>= val -100) + (<= val 100)) +(define-opt cookies boolean) +(define-opt cookies-file string) +(define-opt + corner-rounding + float + (>= val 0) + (<= val 1)) +(define-opt correct-downscaling boolean) +(define-opt correct-pts boolean) +(define-opt + cover-art-auto + enumeration + (memq val '(no exact fuzzy all))) +(define-opt cover-art-files list-of-string) +(define-opt cover-art-whitelist list-of-string) +(define-opt + cscale + enumeration + (memq val + '(bilinear + bicubic_fast + oversample + spline16 + spline36 + spline64 + sinc + lanczos + ginseng + bicubic + hermite + catmull_rom + mitchell + robidoux + robidouxsharp + box + nearest + triangle + gaussian + jinc + ewa_lanczos + ewa_hanning + ewa_ginseng + ewa_lanczossharp + ewa_lanczos4sharpest + ewa_lanczossoft + haasnsoft + ewa_robidoux + ewa_robidouxsharp + bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx))) +(define-opt + cscale-antiring + float + (>= val 0) + (<= val 1)) +(define-opt cscale-blur float) +(define-opt + cscale-clamp + float + (>= val 0) + (<= val 1)) +(define-opt cscale-param1 float) +(define-opt cscale-param2 float) +(define-opt + cscale-radius + float + (>= val 0.5) + (<= val 16)) +(define-opt + cscale-taper + float + (>= val 0) + (<= val 1)) +(define-opt + cscale-window + enumeration + (memq val + '(bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt cscale-wparam float) +(define-opt + cscale-wtaper + float + (>= val 0) + (<= val 1)) +(define-opt + cursor-autohide + enumeration + (or (memq val '(no always)) + (and (integer? val) (>= val 0) (<= val 30000)))) +(define-opt cursor-autohide-fs-only boolean) +(define-opt deband boolean) +(define-opt + deband-grain + float + (>= val 0) + (<= val 4096)) +(define-opt + deband-iterations + integer + (>= val 0) + (<= val 16)) +(define-opt + deband-range + float + (>= val 1) + (<= val 64)) +(define-opt + deband-threshold + float + (>= val 0) + (<= val 4096)) +(define-opt + deinterlace + enumeration + (memq val '(no yes auto))) +(define-opt + deinterlace-field-parity + enumeration + (memq val '(tff bff auto))) +(define-opt demuxer string) +(define-opt + demuxer-backward-playback-step + double + (>= val 0)) +(define-opt demuxer-cache-dir string) +(define-opt + demuxer-cache-unlink-files + enumeration + (memq val '(immediate whendone no))) +(define-opt demuxer-cache-wait boolean) +(define-opt demuxer-donate-buffer boolean) +(define-opt + demuxer-hysteresis-secs + double + (>= val 0)) +(define-opt demuxer-lavf-allow-mimetype boolean) +(define-opt + demuxer-lavf-analyzeduration + float + (>= val 0) + (<= val 3600)) +(define-opt + demuxer-lavf-buffersize + integer + (>= val 1) + (<= val 10485760)) +(define-opt demuxer-lavf-format string) +(define-opt demuxer-lavf-hacks boolean) +(define-opt + demuxer-lavf-linearize-timestamps + enumeration + (memq val '(no auto yes))) +(define-opt demuxer-lavf-o list-of-key-value) +(define-opt + demuxer-lavf-probe-info + enumeration + (memq val '(no yes auto nostreams))) +(define-opt + demuxer-lavf-probescore + integer + (>= val 1) + (<= val 100)) +(define-opt + demuxer-lavf-probesize + integer + (>= val 32) + (<= val 2147483647)) +(define-opt demuxer-lavf-propagate-opts boolean) +(define-opt + demuxer-max-back-bytes + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + demuxer-max-bytes + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt demuxer-mkv-probe-start-time boolean) +(define-opt + demuxer-mkv-probe-video-duration + enumeration + (memq val '(no yes full))) +(define-opt + demuxer-mkv-subtitle-preroll + enumeration + (memq val '(no yes index))) +(define-opt + demuxer-mkv-subtitle-preroll-secs + double + (>= val 0)) +(define-opt + demuxer-mkv-subtitle-preroll-secs-index + double + (>= val 0)) +(define-opt + demuxer-rawaudio-channels + audio-channels-or-channel-map) +(define-opt + demuxer-rawaudio-format + enumeration + (memq val + '(u8 s8 + u16le + u16be + s16le + s16be + u24le + u24be + s24le + s24be + u32le + u32be + s32le + s32be + floatle + floatbe + doublele + doublebe + u16 + s16 + u24 + s24 + u32 + s32 + float + double))) +(define-opt + demuxer-rawaudio-rate + integer + (>= val 1000) + (<= val 384000)) +(define-opt demuxer-rawvideo-codec string) +(define-opt demuxer-rawvideo-format fourcc) +(define-opt + demuxer-rawvideo-fps + float + (>= val 0.001) + (<= val 1000)) +(define-opt + demuxer-rawvideo-h + integer + (>= val 1) + (<= val 8192)) +(define-opt + demuxer-rawvideo-mp-format + image-format) +(define-opt + demuxer-rawvideo-size + integer + (>= val 1) + (<= val 268435456)) +(define-opt + demuxer-rawvideo-w + integer + (>= val 1) + (<= val 8192)) +(define-opt + demuxer-readahead-secs + double + (>= val 0)) +(define-opt + demuxer-seekable-cache + enumeration + (memq val '(auto no yes))) +(define-opt demuxer-termination-timeout double) +(define-opt demuxer-thread boolean) +(define-opt + directory-filter-types + list-of-string) +(define-opt + directory-mode + enumeration + (memq val '(auto lazy recursive ignore))) +(define-opt + display-fps-override + double + (>= val 0)) +(define-opt display-tags list-of-string) +(define-opt + dither + enumeration + (memq val '(fruit ordered error-diffusion no))) +(define-opt + dither-depth + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val -1) (<= val 16)))) +(define-opt + dither-size-fruit + integer + (>= val 2) + (<= val 8)) +(define-opt + drag-and-drop + enumeration + (memq val '(no auto replace append insert-next))) +(define-opt drm-connector string) +(define-opt drm-device string) +(define-opt + drm-draw-plane + enumeration + (or (memq val '(primary overlay)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt drm-draw-surface-size window-size) +(define-opt + drm-drmprime-video-plane + enumeration + (or (memq val '(primary overlay)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt + drm-format + enumeration + (memq val + '(xrgb8888 xrgb2101010 xbgr8888 xbgr2101010 yuyv))) +(define-opt drm-mode string) +(define-opt + drm-vrr-enabled + enumeration + (memq val '(no yes auto))) +(define-opt + dscale + enumeration + (memq val + '(bilinear + bicubic_fast + oversample + spline16 + spline36 + spline64 + sinc + lanczos + ginseng + bicubic + hermite + catmull_rom + mitchell + robidoux + robidouxsharp + box + nearest + triangle + gaussian + jinc + ewa_lanczos + ewa_hanning + ewa_ginseng + ewa_lanczossharp + ewa_lanczos4sharpest + ewa_lanczossoft + haasnsoft + ewa_robidoux + ewa_robidouxsharp + bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx))) +(define-opt + dscale-antiring + float + (>= val 0) + (<= val 1)) +(define-opt dscale-blur float) +(define-opt + dscale-clamp + float + (>= val 0) + (<= val 1)) +(define-opt dscale-param1 float) +(define-opt dscale-param2 float) +(define-opt + dscale-radius + float + (>= val 0.5) + (<= val 16)) +(define-opt + dscale-taper + float + (>= val 0) + (<= val 1)) +(define-opt + dscale-window + enumeration + (memq val + '(bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt dscale-wparam float) +(define-opt + dscale-wtaper + float + (>= val 0) + (<= val 1)) +(define-opt dump-stats string) +(define-opt + dvbin-card + integer + (>= val 0) + (<= val 15)) +(define-opt dvbin-channel-switch-offset integer) +(define-opt dvbin-file string) +(define-opt dvbin-full-transponder boolean) +(define-opt dvbin-prog string) +(define-opt + dvbin-timeout + integer + (>= val 1) + (<= val 30)) +(define-opt + dvd-angle + integer + (>= val 1) + (<= val 99)) +(define-opt dvd-device string) +(define-opt dvd-speed integer) +(define-opt + edition + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt egl-config-id integer) +(define-opt + egl-output-format + enumeration + (memq val + '(auto rgb8 + rgba8 + rgb10 + rgb10_a2 + rgb16 + rgba16 + rgb16f + rgba16f + rgb32f + rgba32f))) +(define-opt embeddedfonts boolean) +(define-opt + end + relative-time-or-percent-position) +(define-opt error-diffusion string) +(define-opt external-files list-of-string) +(define-opt fbo-format string) +(define-opt + focus-on + enumeration + (memq val '(never open all))) +(define-opt force-media-title string) +(define-opt force-render boolean) +(define-opt force-rgba-osd-rendering boolean) +(define-opt force-seekable boolean) +(define-opt + force-window + enumeration + (memq val '(no yes immediate))) +(define-opt force-window-position boolean) +(define-opt + framedrop + enumeration + (memq val '(no vo decoder decoder+vo))) +(define-opt + frames + enumeration + (or (memq val '(all)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt + fs-screen + enumeration + (or (memq val '(all current)) + (and (integer? val) (>= val 0) (<= val 32)))) +(define-opt fs-screen-name string) +(define-opt fullscreen boolean) +(define-opt + gamma + float + (>= val -100) + (<= val 100)) +(define-opt gamma-auto boolean) +(define-opt + gamma-factor + float + (>= val 0.1) + (<= val 2)) +(define-opt + gamut-mapping-mode + enumeration + (memq val + '(auto clip + perceptual + relative + saturation + absolute + desaturate + darken + warn + linear))) +(define-opt + gapless-audio + enumeration + (memq val '(no yes weak))) +(define-opt geometry window-geometry) +(define-opt glsl-shader-opts list-of-key-value) +(define-opt glsl-shaders list-of-string) +(define-opt gpu-api list-of-object-setting) +(define-opt gpu-context list-of-object-setting) +(define-opt gpu-debug boolean) +(define-opt + gpu-dumb-mode + enumeration + (memq val '(auto yes no))) +(define-opt gpu-hwdec-interop string) +(define-opt gpu-shader-cache boolean) +(define-opt gpu-shader-cache-dir string) +(define-opt gpu-sw boolean) +(define-opt + gpu-tex-pad-x + integer + (>= val 0) + (<= val 4096)) +(define-opt + gpu-tex-pad-y + integer + (>= val 0) + (<= val 4096)) +(define-opt + hdr-compute-peak + enumeration + (memq val '(auto yes no))) +(define-opt + hdr-contrast-recovery + float + (>= val 0) + (<= val 2)) +(define-opt + hdr-contrast-smoothness + float + (>= val 1) + (<= val 100)) +(define-opt + hdr-peak-decay-rate + float + (>= val 0) + (<= val 1000)) +(define-opt + hdr-peak-percentile + float + (>= val 0) + (<= val 100)) +(define-opt + hdr-scene-threshold-high + float + (>= val 0) + (<= val 20)) +(define-opt + hdr-scene-threshold-low + float + (>= val 0) + (<= val 20)) +(define-opt hidpi-window-scale boolean) +(define-opt + hls-bitrate + enumeration + (or (memq val '(no min max)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt + hr-seek + enumeration + (memq val '(no absolute yes always default))) +(define-opt hr-seek-demuxer-offset float) +(define-opt hr-seek-framedrop boolean) +(define-opt http-header-fields list-of-string) +(define-opt http-proxy string) +(define-opt hue float (>= val -100) (<= val 100)) +(define-opt hwdec list-of-string) +(define-opt hwdec-codecs string) +(define-opt + hwdec-extra-frames + integer + (>= val 0) + (<= val 256)) +(define-opt hwdec-image-format image-format) +(define-opt icc-3dlut-size string) +(define-opt icc-cache boolean) +(define-opt icc-cache-dir string) +(define-opt + icc-force-contrast + enumeration + (or (memq val '(no inf)) + (and (integer? val) (>= val 0) (<= val 1000000)))) +(define-opt icc-intent integer) +(define-opt icc-profile string) +(define-opt icc-profile-auto boolean) +(define-opt icc-use-luma boolean) +(define-opt + idle + enumeration + (memq val '(no once yes))) +(define-opt + ignore-path-in-watch-later-config + boolean) +(define-opt + image-display-duration + double + (>= val 0)) +(define-opt image-exts list-of-string) +(define-opt image-lut string) +(define-opt + image-lut-type + enumeration + (memq val '(auto native normalized conversion))) +(define-opt image-subs-video-resolution boolean) +(define-opt include string) +(define-opt + index + enumeration + (memq val '(default recreate))) +(define-opt initial-audio-sync boolean) +(define-opt input-ar-delay integer) +(define-opt input-ar-rate integer) +(define-opt input-builtin-bindings boolean) +(define-opt input-builtin-dragging boolean) +(define-opt input-commands list-of-string) +(define-opt input-conf string) +(define-opt input-cursor boolean) +(define-opt input-cursor-passthrough boolean) +(define-opt input-default-bindings boolean) +(define-opt + input-doubleclick-time + integer + (>= val 0) + (<= val 1000)) +(define-opt input-dragging-deadzone integer) +(define-opt input-ipc-client string) +(define-opt input-ipc-server string) +(define-opt + input-key-fifo-size + integer + (>= val 2) + (<= val 65000)) +(define-opt input-media-keys boolean) +(define-opt input-preprocess-wheel boolean) +(define-opt input-right-alt-gr boolean) +(define-opt input-terminal boolean) +(define-opt input-test boolean) +(define-opt input-touch-emulate-mouse boolean) +(define-opt input-vo-keyboard boolean) +(define-opt interpolation boolean) +(define-opt interpolation-preserve boolean) +(define-opt interpolation-threshold float) +(define-opt inverse-tone-mapping boolean) +(define-opt jack-autostart boolean) +(define-opt jack-connect boolean) +(define-opt jack-name string) +(define-opt jack-port string) +(define-opt + jack-std-channel-layout + enumeration + (memq val '(waveext any))) +(define-opt + keep-open + enumeration + (memq val '(no yes always))) +(define-opt keep-open-pause boolean) +(define-opt keepaspect boolean) +(define-opt keepaspect-window boolean) +(define-opt lavfi-complex string) +(define-opt + length + relative-time-or-percent-position) +(define-opt libplacebo-opts list-of-key-value) +(define-opt linear-downscaling boolean) +(define-opt linear-upscaling boolean) +(define-opt + load-auto-profiles + enumeration + (memq val '(no yes auto))) +(define-opt load-osd-console boolean) +(define-opt load-scripts boolean) +(define-opt load-select boolean) +(define-opt load-stats-overlay boolean) +(define-opt load-unsafe-playlists boolean) +(define-opt log-file string) +(define-opt + loop-file + enumeration + (or (memq val '(no inf yes)) + (and (integer? val) (>= val 0) (<= val 10000)))) +(define-opt + loop-playlist + enumeration + (or (memq val '(no inf yes force)) + (and (integer? val) (>= val 1) (<= val 10000)))) +(define-opt lut string) +(define-opt + lut-type + enumeration + (memq val '(auto native normalized conversion))) +(define-opt mc float (>= val 0) (<= val 100)) +(define-opt + media-controls + enumeration + (memq val '(no player yes))) +(define-opt merge-files boolean) +(define-opt metadata-codepage string) +(define-opt mf-fps double) +(define-opt mf-type string) +(define-opt + monitoraspect + float + (>= val 0) + (<= val 9)) +(define-opt + monitorpixelaspect + float + (>= val 0.03125) + (<= val 32)) +(define-opt msg-color boolean) +(define-opt msg-level list-of-output-verbosity) +(define-opt msg-module boolean) +(define-opt msg-time boolean) +(define-opt mute boolean) +(define-opt native-fs boolean) +(define-opt native-keyrepeat boolean) +(define-opt native-touch boolean) +(define-opt network-timeout double (>= val 0)) +(define-opt oac string) +(define-opt oacopts list-of-key-value) +(define-opt ocopy-metadata boolean) +(define-opt of string) +(define-opt ofopts list-of-key-value) +(define-opt on-all-workspaces boolean) +(define-opt ontop boolean) +(define-opt + ontop-level + enumeration + (or (memq val '(window system desktop)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt opengl-check-pattern-a integer) +(define-opt opengl-check-pattern-b integer) +(define-opt + opengl-early-flush + enumeration + (memq val '(no yes auto))) +(define-opt + opengl-es + enumeration + (memq val '(auto yes no))) +(define-opt opengl-glfinish boolean) +(define-opt opengl-pbo boolean) +(define-opt opengl-rectangle-textures boolean) +(define-opt opengl-swapinterval integer) +(define-opt opengl-waitvsync boolean) +(define-opt orawts boolean) +(define-opt ordered-chapters boolean) +(define-opt ordered-chapters-files string) +(define-opt oremove-metadata list-of-string) +(define-opt osc boolean) +(define-opt + osd-align-x + enumeration + (memq val '(left center right))) +(define-opt + osd-align-y + enumeration + (memq val '(top center bottom))) +(define-opt osd-back-color color) +(define-opt osd-bar boolean) +(define-opt + osd-bar-align-x + float + (>= val -1) + (<= val 1)) +(define-opt + osd-bar-align-y + float + (>= val -1) + (<= val 1)) +(define-opt + osd-bar-h + float + (>= val 0.1) + (<= val 50)) +(define-opt + osd-bar-outline-size + float + (>= val 0) + (<= val 1000)) +(define-opt + osd-bar-w + float + (>= val 1) + (<= val 100)) +(define-opt + osd-blur + float + (>= val 0) + (<= val 20)) +(define-opt osd-bold boolean) +(define-opt + osd-border-style + enumeration + (memq val + '(outline-and-shadow opaque-box background-box))) +(define-opt osd-color color) +(define-opt + osd-duration + integer + (>= val 0) + (<= val 3600000)) +(define-opt osd-font string) +(define-opt + osd-font-provider + enumeration + (memq val '(auto none fontconfig))) +(define-opt + osd-font-size + float + (>= val 1) + (<= val 9000)) +(define-opt osd-fonts-dir string) +(define-opt osd-fractions boolean) +(define-opt osd-italic boolean) +(define-opt + osd-justify + enumeration + (memq val '(auto left center right))) +(define-opt + osd-level + enumeration + (memq val '(#{0}# #{1}# #{2}# #{3}#))) +(define-opt + osd-margin-x + integer + (>= val 0) + (<= val 300)) +(define-opt + osd-margin-y + integer + (>= val 0) + (<= val 600)) +(define-opt osd-msg1 string) +(define-opt osd-msg2 string) +(define-opt osd-msg3 string) +(define-opt + osd-on-seek + enumeration + (memq val '(no bar msg msg-bar))) +(define-opt osd-outline-color color) +(define-opt osd-outline-size float) +(define-opt osd-playing-msg string) +(define-opt + osd-playing-msg-duration + integer + (>= val 0) + (<= val 3600000)) +(define-opt + osd-playlist-entry + enumeration + (memq val '(title filename both))) +(define-opt + osd-scale + float + (>= val 0) + (<= val 100)) +(define-opt osd-scale-by-window boolean) +(define-opt osd-shadow-offset float) +(define-opt + osd-spacing + float + (>= val -10) + (<= val 10)) +(define-opt osd-status-msg string) +(define-opt oset-metadata list-of-key-value) +(define-opt ovc string) +(define-opt ovcopts list-of-key-value) +(define-opt panscan float (>= val 0) (<= val 1)) +(define-opt pause boolean) +(define-opt + pipewire-buffer + enumeration + (or (memq val '(native)) + (and (integer? val) (>= val 1) (<= val 2000)))) +(define-opt pipewire-remote string) +(define-opt + pipewire-volume-mode + enumeration + (memq val '(channel global))) +(define-opt + pitch + double + (>= val 0.01) + (<= val 100)) +(define-opt + play-direction + enumeration + (memq val '(forward + backward -))) +(define-opt + player-operation-mode + enumeration + (memq val '(cplayer pseudo-gui))) +(define-opt + playlist-start + enumeration + (or (memq val '(auto no)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt prefetch-playlist boolean) +(define-opt profile list-of-string) +(define-opt pulse-allow-suspended boolean) +(define-opt + pulse-buffer + enumeration + (or (memq val '(native)) + (and (integer? val) (>= val 1) (<= val 2000)))) +(define-opt pulse-host string) +(define-opt pulse-latency-hacks boolean) +(define-opt quiet boolean) +(define-opt really-quiet boolean) +(define-opt rebase-start-time boolean) +(define-opt referrer string) +(define-opt + replaygain + enumeration + (memq val '(no track album))) +(define-opt replaygain-clip boolean) +(define-opt + replaygain-fallback + float + (>= val -200) + (<= val 60)) +(define-opt + replaygain-preamp + float + (>= val -150) + (<= val 150)) +(define-opt reset-on-next-file list-of-string) +(define-opt resume-playback boolean) +(define-opt resume-playback-check-mtime boolean) +(define-opt + rtsp-transport + enumeration + (memq val '(lavf udp tcp http udp_multicast))) +(define-opt + saturation + float + (>= val -100) + (<= val 100)) +(define-opt save-position-on-quit boolean) +(define-opt + scale + enumeration + (memq val + '(bilinear + bicubic_fast + oversample + spline16 + spline36 + spline64 + sinc + lanczos + ginseng + bicubic + hermite + catmull_rom + mitchell + robidoux + robidouxsharp + box + nearest + triangle + gaussian + jinc + ewa_lanczos + ewa_hanning + ewa_ginseng + ewa_lanczossharp + ewa_lanczos4sharpest + ewa_lanczossoft + haasnsoft + ewa_robidoux + ewa_robidouxsharp + bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx))) +(define-opt + scale-antiring + float + (>= val 0) + (<= val 1)) +(define-opt scale-blur float) +(define-opt + scale-clamp + float + (>= val 0) + (<= val 1)) +(define-opt scale-param1 float) +(define-opt scale-param2 float) +(define-opt + scale-radius + float + (>= val 0.5) + (<= val 16)) +(define-opt + scale-taper + float + (>= val 0) + (<= val 1)) +(define-opt + scale-window + enumeration + (memq val + '(bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt scale-wparam float) +(define-opt + scale-wtaper + float + (>= val 0) + (<= val 1)) +(define-opt scaler-resizes-only boolean) +(define-opt + screen + enumeration + (or (memq val '(default)) + (and (integer? val) (>= val 0) (<= val 32)))) +(define-opt screen-name string) +(define-opt screenshot-avif-encoder string) +(define-opt + screenshot-avif-opts + list-of-key-value) +(define-opt screenshot-avif-pixfmt string) +(define-opt screenshot-directory string) +(define-opt + screenshot-format + enumeration + (memq val '(jpg jpeg png webp jxl avif))) +(define-opt screenshot-high-bit-depth boolean) +(define-opt + screenshot-jpeg-quality + integer + (>= val 0) + (<= val 100)) +(define-opt + screenshot-jpeg-source-chroma + boolean) +(define-opt + screenshot-jxl-distance + double + (>= val 0) + (<= val 15)) +(define-opt + screenshot-jxl-effort + integer + (>= val 1) + (<= val 9)) +(define-opt + screenshot-png-compression + integer + (>= val 0) + (<= val 9)) +(define-opt + screenshot-png-filter + integer + (>= val 0) + (<= val 5)) +(define-opt screenshot-sw boolean) +(define-opt screenshot-tag-colorspace boolean) +(define-opt screenshot-template string) +(define-opt + screenshot-webp-compression + integer + (>= val 0) + (<= val 6)) +(define-opt screenshot-webp-lossless boolean) +(define-opt + screenshot-webp-quality + integer + (>= val 0) + (<= val 100)) +(define-opt script-opts list-of-key-value) +(define-opt scripts list-of-string) +(define-opt + secondary-sid + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt + secondary-sub-ass-override + enumeration + (memq val '(no yes scale force strip))) +(define-opt secondary-sub-delay float) +(define-opt + secondary-sub-pos + float + (>= val 0) + (<= val 150)) +(define-opt secondary-sub-visibility boolean) +(define-opt sharpen float) +(define-opt show-in-taskbar boolean) +(define-opt shuffle boolean) +(define-opt + sub + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt + sigmoid-center + float + (>= val 0) + (<= val 1)) +(define-opt + sigmoid-slope + float + (>= val 1) + (<= val 20)) +(define-opt sigmoid-upscaling boolean) +(define-opt slang list-of-string) +(define-opt snap-window boolean) +(define-opt + speed + double + (>= val 0.01) + (<= val 100)) +(define-opt + spirv-compiler + enumeration + (memq val '(auto))) +(define-opt sstep double (>= val 0)) +(define-opt + start + relative-time-or-percent-position) +(define-opt + stop-playback-on-init-failure + boolean) +(define-opt + stop-screensaver + enumeration + (memq val '(no yes always))) +(define-opt + stream-buffer-size + byte-size + (>= val 4096) + (<= val 536870912)) +(define-opt stream-dump string) +(define-opt stream-lavf-o list-of-key-value) +(define-opt stream-record string) +(define-opt stretch-dvd-subs boolean) +(define-opt stretch-image-subs-to-screen boolean) +(define-opt + sub-align-x + enumeration + (memq val '(left center right))) +(define-opt + sub-align-y + enumeration + (memq val '(top center bottom))) +(define-opt sub-ass boolean) +(define-opt sub-ass-force-margins boolean) +(define-opt + sub-ass-hinting + enumeration + (memq val '(none light normal native))) +(define-opt sub-ass-justify boolean) +(define-opt + sub-ass-line-spacing + float + (>= val -1000) + (<= val 1000)) +(define-opt + sub-ass-override + enumeration + (memq val '(no yes scale force strip))) +(define-opt sub-ass-scale-with-window boolean) +(define-opt + sub-ass-shaper + enumeration + (memq val '(simple complex))) +(define-opt + sub-ass-style-overrides + list-of-string) +(define-opt sub-ass-styles string) +(define-opt + sub-ass-use-video-data + enumeration + (memq val '(none aspect-ratio all))) +(define-opt + sub-ass-video-aspect-override + aspect + (>= val 0) + (<= val 10)) +(define-opt + sub-ass-vsfilter-color-compat + enumeration + (memq val '(no basic full force-601))) +(define-opt + sub-auto + enumeration + (memq val '(no exact fuzzy all))) +(define-opt sub-auto-exts list-of-string) +(define-opt sub-back-color color) +(define-opt + sub-blur + float + (>= val 0) + (<= val 20)) +(define-opt sub-bold boolean) +(define-opt + sub-border-style + enumeration + (memq val + '(outline-and-shadow opaque-box background-box))) +(define-opt sub-clear-on-seek boolean) +(define-opt sub-codepage string) +(define-opt sub-color color) +(define-opt sub-create-cc-track boolean) +(define-opt sub-delay float) +(define-opt sub-demuxer string) +(define-opt sub-file-paths list-of-string) +(define-opt sub-files list-of-string) +(define-opt sub-filter-jsre list-of-string) +(define-opt sub-filter-regex list-of-string) +(define-opt sub-filter-regex-enable boolean) +(define-opt sub-filter-regex-plain boolean) +(define-opt sub-filter-regex-warn boolean) +(define-opt sub-filter-sdh boolean) +(define-opt sub-filter-sdh-enclosures string) +(define-opt sub-filter-sdh-harder boolean) +(define-opt sub-fix-timing boolean) +(define-opt sub-font string) +(define-opt + sub-font-provider + enumeration + (memq val '(auto none fontconfig))) +(define-opt + sub-font-size + float + (>= val 1) + (<= val 9000)) +(define-opt sub-fonts-dir string) +(define-opt sub-forced-events-only boolean) +(define-opt sub-fps float) +(define-opt + sub-gauss + float + (>= val 0) + (<= val 3)) +(define-opt sub-gray boolean) +(define-opt sub-italic boolean) +(define-opt + sub-justify + enumeration + (memq val '(auto left center right))) +(define-opt sub-lavc-o list-of-key-value) +(define-opt + sub-margin-x + integer + (>= val 0) + (<= val 300)) +(define-opt + sub-margin-y + integer + (>= val 0) + (<= val 600)) +(define-opt sub-outline-color color) +(define-opt sub-outline-size float) +(define-opt sub-past-video-end boolean) +(define-opt + sub-pos + float + (>= val 0) + (<= val 150)) +(define-opt + sub-scale + float + (>= val 0) + (<= val 100)) +(define-opt sub-scale-by-window boolean) +(define-opt sub-scale-with-window boolean) +(define-opt sub-shadow-offset float) +(define-opt + sub-spacing + float + (>= val -10) + (<= val 10)) +(define-opt sub-speed float) +(define-opt sub-stretch-durations boolean) +(define-opt sub-use-margins boolean) +(define-opt sub-visibility boolean) +(define-opt sub-vsfilter-bidi-compat boolean) +(define-opt + subs-fallback + enumeration + (memq val '(no default yes))) +(define-opt + subs-fallback-forced + enumeration + (memq val '(no yes always))) +(define-opt subs-match-os-language boolean) +(define-opt + subs-with-matching-audio + enumeration + (memq val '(no forced yes))) +(define-opt + swapchain-depth + integer + (>= val 1) + (<= val 8)) +(define-opt sws-allow-zimg boolean) +(define-opt sws-bitexact boolean) +(define-opt + sws-cgb + float + (>= val 0) + (<= val 100)) +(define-opt sws-chs integer) +(define-opt + sws-cs + float + (>= val -100) + (<= val 100)) +(define-opt sws-cvs integer) +(define-opt sws-fast boolean) +(define-opt + sws-lgb + float + (>= val 0) + (<= val 100)) +(define-opt + sws-ls + float + (>= val -100) + (<= val 100)) +(define-opt + sws-scaler + enumeration + (memq val + '(fast-bilinear + bilinear + bicubic + x + point + area + bicublin + gauss + sinc + lanczos + spline))) +(define-opt target-colorspace-hint boolean) +(define-opt + target-contrast + enumeration + (or (memq val '(auto inf)) + (and (integer? val) (>= val 10) (<= val 1000000)))) +(define-opt + target-gamut + enumeration + (memq val + '(auto bt.601-525 + bt.601-625 + bt.709 + bt.2020 + bt.470m + apple + adobe + prophoto + cie1931 + dci-p3 + display-p3 + v-gamut + s-gamut + ebu3213 + film-c + aces-ap0 + aces-ap1))) +(define-opt target-lut string) +(define-opt + target-peak + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 10) (<= val 10000)))) +(define-opt + target-prim + enumeration + (memq val + '(auto bt.601-525 + bt.601-625 + bt.709 + bt.2020 + bt.470m + apple + adobe + prophoto + cie1931 + dci-p3 + display-p3 + v-gamut + s-gamut + ebu3213 + film-c + aces-ap0 + aces-ap1))) +(define-opt + target-trc + enumeration + (memq val + '(auto bt.1886 + srgb + linear + gamma1.8 + gamma2.0 + gamma2.2 + gamma2.4 + gamma2.6 + gamma2.8 + prophoto + pq + hlg + v-log + s-log1 + s-log2 + st428))) +(define-opt taskbar-progress boolean) +(define-opt + teletext-page + integer + (>= val -1) + (<= val 999)) +(define-opt temporal-dither boolean) +(define-opt + temporal-dither-period + integer + (>= val 1) + (<= val 128)) +(define-opt + term-osd + enumeration + (memq val '(force auto no))) +(define-opt term-osd-bar boolean) +(define-opt term-osd-bar-chars string) +(define-opt term-playing-msg string) +(define-opt term-status-msg string) +(define-opt term-title string) +(define-opt terminal boolean) +(define-opt title string) +(define-opt title-bar boolean) +(define-opt tls-ca-file string) +(define-opt tls-cert-file string) +(define-opt tls-key-file string) +(define-opt tls-verify boolean) +(define-opt + tone-mapping + enumeration + (memq val + '(auto clip + mobius + reinhard + hable + gamma + linear + spline + bt.2390 + bt.2446a + st2094-40 + st2094-10))) +(define-opt + tone-mapping-max-boost + float + (>= val 1) + (<= val 10)) +(define-opt tone-mapping-param float) +(define-opt tone-mapping-visualize boolean) +(define-opt track-auto-selection boolean) +(define-opt + tscale + enumeration + (memq val + '(oversample + linear + spline16 + spline36 + spline64 + sinc + lanczos + ginseng + bicubic + hermite + catmull_rom + mitchell + robidoux + robidouxsharp + box + nearest + triangle + gaussian + bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt + tscale-antiring + float + (>= val 0) + (<= val 1)) +(define-opt tscale-blur float) +(define-opt + tscale-clamp + float + (>= val 0) + (<= val 1)) +(define-opt tscale-param1 float) +(define-opt tscale-param2 float) +(define-opt + tscale-radius + float + (>= val 0.5) + (<= val 16)) +(define-opt + tscale-taper + float + (>= val 0) + (<= val 1)) +(define-opt + tscale-window + enumeration + (memq val + '(bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt tscale-wparam float) +(define-opt + tscale-wtaper + float + (>= val 0) + (<= val 1)) +(define-opt untimed boolean) +(define-opt use-embedded-icc-profile boolean) +(define-opt use-filedir-conf boolean) +(define-opt user-agent string) +(define-opt vaapi-device string) +(define-opt vd string) +(define-opt vd-apply-cropping boolean) +(define-opt vd-lavc-assume-old-x264 boolean) +(define-opt vd-lavc-bitexact boolean) +(define-opt vd-lavc-check-hw-profile boolean) +(define-opt + vd-lavc-dr + enumeration + (memq val '(auto no yes))) +(define-opt vd-lavc-fast boolean) +(define-opt + vd-lavc-film-grain + enumeration + (memq val '(auto cpu gpu))) +(define-opt + vd-lavc-framedrop + enumeration + (memq val + '(none default nonref bidir nonkey all))) +(define-opt vd-lavc-o list-of-key-value) +(define-opt vd-lavc-show-all boolean) +(define-opt + vd-lavc-skipframe + enumeration + (memq val + '(none default nonref bidir nonkey all))) +(define-opt + vd-lavc-skipidct + enumeration + (memq val + '(none default nonref bidir nonkey all))) +(define-opt + vd-lavc-skiploopfilter + enumeration + (memq val + '(none default nonref bidir nonkey all))) +(define-opt + vd-lavc-software-fallback + enumeration + (or (memq val '(no yes)) + (and (integer? val) + (>= val 1) + (<= val 2147483647)))) +(define-opt vd-lavc-threads integer (>= val 0)) +(define-opt vd-queue-enable boolean) +(define-opt + vd-queue-max-bytes + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + vd-queue-max-samples + integer64 + (>= val 0)) +(define-opt vd-queue-max-secs double (>= val 0)) +(define-opt vf list-of-object-setting) +(define-opt + video + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt + video-align-x + float + (>= val -1) + (<= val 1)) +(define-opt + video-align-y + float + (>= val -1) + (<= val 1)) +(define-opt + video-aspect-method + enumeration + (memq val '(bitstream container))) +(define-opt + video-aspect-override + aspect + (>= val -1) + (<= val 10)) +(define-opt + video-backward-batch + integer + (>= val 0) + (<= val 1024)) +(define-opt + video-backward-overlap + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 0) (<= val 1024)))) +(define-opt video-crop video-rectangle) +(define-opt video-exts list-of-string) +(define-opt video-latency-hacks boolean) +(define-opt + video-margin-ratio-bottom + float + (>= val 0) + (<= val 1)) +(define-opt + video-margin-ratio-left + float + (>= val 0) + (<= val 1)) +(define-opt + video-margin-ratio-right + float + (>= val 0) + (<= val 1)) +(define-opt + video-margin-ratio-top + float + (>= val 0) + (<= val 1)) +(define-opt video-osd boolean) +(define-opt + video-output-levels + enumeration + (memq val '(auto limited full))) +(define-opt video-pan-x float) +(define-opt video-pan-y float) +(define-opt + video-reversal-buffer + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + video-rotate + enumeration + (or (memq val '(no)) + (and (integer? val) (>= val 0) (<= val 359)))) +(define-opt + video-scale-x + float + (>= val 0) + (<= val 10000)) +(define-opt + video-scale-y + float + (>= val 0) + (<= val 10000)) +(define-opt + video-sync + enumeration + (memq val + '(audio display-resample + display-resample-vdrop + display-resample-desync + display-tempo + display-adrop + display-vdrop + display-desync + desync))) +(define-opt + video-sync-max-audio-change + double + (>= val 0) + (<= val 1)) +(define-opt + video-sync-max-factor + integer + (>= val 1) + (<= val 10)) +(define-opt + video-sync-max-video-change + double + (>= val 0)) +(define-opt + video-timing-offset + double + (>= val 0) + (<= val 1)) +(define-opt + video-unscaled + enumeration + (memq val '(no yes downscale-big))) +(define-opt + video-zoom + float + (>= val -20) + (<= val 20)) +(define-opt vlang list-of-string) +(define-opt vo list-of-object-setting) +(define-opt vo-image-avif-encoder string) +(define-opt vo-image-avif-opts list-of-key-value) +(define-opt vo-image-avif-pixfmt string) +(define-opt + vo-image-format + enumeration + (memq val '(jpg jpeg png webp jxl avif))) +(define-opt vo-image-high-bit-depth boolean) +(define-opt + vo-image-jpeg-quality + integer + (>= val 0) + (<= val 100)) +(define-opt vo-image-jpeg-source-chroma boolean) +(define-opt + vo-image-jxl-distance + double + (>= val 0) + (<= val 15)) +(define-opt + vo-image-jxl-effort + integer + (>= val 1) + (<= val 9)) +(define-opt vo-image-outdir string) +(define-opt + vo-image-png-compression + integer + (>= val 0) + (<= val 9)) +(define-opt + vo-image-png-filter + integer + (>= val 0) + (<= val 5)) +(define-opt vo-image-tag-colorspace boolean) +(define-opt + vo-image-webp-compression + integer + (>= val 0) + (<= val 6)) +(define-opt vo-image-webp-lossless boolean) +(define-opt + vo-image-webp-quality + integer + (>= val 0) + (<= val 100)) +(define-opt vo-kitty-alt-screen boolean) +(define-opt vo-kitty-cols integer) +(define-opt vo-kitty-config-clear boolean) +(define-opt vo-kitty-height integer) +(define-opt vo-kitty-left integer) +(define-opt vo-kitty-rows integer) +(define-opt vo-kitty-top integer) +(define-opt vo-kitty-use-shm boolean) +(define-opt vo-kitty-width integer) +(define-opt + vo-null-fps + double + (>= val 0) + (<= val 10000)) +(define-opt vo-sixel-alt-screen boolean) +(define-opt vo-sixel-buffered boolean) +(define-opt vo-sixel-cols integer) +(define-opt vo-sixel-config-clear boolean) +(define-opt + vo-sixel-dither + enumeration + (memq val + '(auto none + atkinson + fs + jajuni + stucki + burkes + arithmetic + xor))) +(define-opt vo-sixel-fixedpalette boolean) +(define-opt vo-sixel-height integer) +(define-opt vo-sixel-left integer) +(define-opt vo-sixel-pad-x integer) +(define-opt vo-sixel-pad-y integer) +(define-opt vo-sixel-reqcolors integer) +(define-opt vo-sixel-rows integer) +(define-opt vo-sixel-threshold integer) +(define-opt vo-sixel-top integer) +(define-opt vo-sixel-width integer) +(define-opt vo-tct-256 boolean) +(define-opt + vo-tct-algo + enumeration + (memq val '(plain half-blocks))) +(define-opt + vo-tct-buffering + enumeration + (memq val '(pixel line frame))) +(define-opt vo-tct-height integer) +(define-opt vo-tct-width integer) +(define-opt vo-vaapi-scaled-osd boolean) +(define-opt + vo-vaapi-scaling + enumeration + (memq val '(default fast hq nla))) +(define-opt vo-vdpau-chroma-deint boolean) +(define-opt vo-vdpau-colorkey color) +(define-opt vo-vdpau-composite-detect boolean) +(define-opt + vo-vdpau-denoise + float + (>= val 0) + (<= val 1)) +(define-opt vo-vdpau-force-yuv boolean) +(define-opt vo-vdpau-fps double) +(define-opt + vo-vdpau-hqscaling + integer + (>= val 0) + (<= val 9)) +(define-opt + vo-vdpau-output-surfaces + integer + (>= val 2) + (<= val 15)) +(define-opt vo-vdpau-pullup boolean) +(define-opt vo-vdpau-queuetime-fs integer) +(define-opt vo-vdpau-queuetime-windowed integer) +(define-opt + vo-vdpau-sharpen + float + (>= val -1) + (<= val 1)) +(define-opt + volume + float + (>= val -1) + (<= val 1000)) +(define-opt + volume-gain + float + (>= val -150) + (<= val 150)) +(define-opt + volume-gain-max + float + (>= val 0) + (<= val 150)) +(define-opt + volume-gain-min + float + (>= val -150) + (<= val 0)) +(define-opt + volume-max + float + (>= val 100) + (<= val 1000)) +(define-opt vulkan-async-compute boolean) +(define-opt vulkan-async-transfer boolean) +(define-opt vulkan-device string) +(define-opt vulkan-display-display integer) +(define-opt vulkan-display-mode integer) +(define-opt vulkan-display-plane integer) +(define-opt + vulkan-queue-count + integer + (>= val 1) + (<= val 8)) +(define-opt + vulkan-swap-mode + enumeration + (memq val + '(auto fifo fifo-relaxed mailbox immediate))) +(define-opt watch-later-directory string) +(define-opt watch-later-options list-of-string) +(define-opt wayland-app-id string) +(define-opt + wayland-configure-bounds + enumeration + (memq val '(auto no yes))) +(define-opt + wayland-content-type + enumeration + (memq val '(auto none photo video game))) +(define-opt wayland-disable-vsync boolean) +(define-opt + wayland-edge-pixels-pointer + integer + (>= val 0) + (<= val 2147483647)) +(define-opt + wayland-edge-pixels-touch + integer + (>= val 0) + (<= val 2147483647)) +(define-opt wayland-present boolean) +(define-opt wid integer64) +(define-opt window-dragging boolean) +(define-opt window-maximized boolean) +(define-opt window-minimized boolean) +(define-opt + window-scale + double + (>= val 0.001) + (<= val 100)) +(define-opt + write-filename-in-watch-later-config + boolean) +(define-opt + x11-bypass-compositor + enumeration + (memq val '(no yes fs-only never))) +(define-opt x11-name string) +(define-opt + x11-netwm + enumeration + (memq val '(auto no yes))) +(define-opt + x11-present + enumeration + (memq val '(no auto yes))) +(define-opt x11-wid-title boolean) +(define-opt xv-adaptor integer (>= val -1)) +(define-opt + xv-buffers + integer + (>= val 1) + (<= val 10)) +(define-opt + xv-ck + enumeration + (memq val '(use set cur))) +(define-opt + xv-ck-method + enumeration + (memq val '(none bg man auto))) +(define-opt xv-colorkey integer) +(define-opt xv-port integer (>= val 0)) +(define-opt ytdl boolean) +(define-opt ytdl-format string) +(define-opt ytdl-raw-options list-of-key-value) +(define-opt + zimg-dither + enumeration + (memq val '(no ordered random error-diffusion))) +(define-opt zimg-fast boolean) +(define-opt + zimg-scaler + enumeration + (memq val + '(point bilinear + bicubic + spline16 + spline36 + lanczos))) +(define-opt + zimg-scaler-chroma + enumeration + (memq val + '(point bilinear + bicubic + spline16 + spline36 + lanczos))) +(define-opt zimg-scaler-chroma-param-a double) +(define-opt zimg-scaler-chroma-param-b double) +(define-opt zimg-scaler-param-a double) +(define-opt zimg-scaler-param-b double) +(define-opt + zimg-threads + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 1) (<= val 64)))) +;;; Generated code - END. + +(define-record-type <mpv-profile-configuration> + (%make-mpv-profile-configuration data) + mpv-profile-configuration? + (data %mpv-profile-configuration-data)) + +(define (make-mpv-profile-configuration . args) + ;; I am not sure how can I copy a hash-map. Documentation does not mention + ;; anything. + (let ((new (make-hash-table))) + (let loop ((args args)) + (match args + ((#:inherit cfg . tail) + (hash-for-each (lambda (key val) + (hashq-set! new key val)) + (%mpv-profile-configuration-data cfg)) + (loop tail)) + (((? keyword? key) val . tail) + (let* ((key (keyword->symbol key)) + (opt (hashq-ref %opts key))) + (unless opt + (throw 'bad-config "Option not found" key)) + (unless ((profile-option-type-check opt) val) + (throw 'bad-config "Invalid value for" key val)) + (hashq-set! new key (cons val (profile-option-serializer opt)))) + (loop tail)) + (() + (%make-mpv-profile-configuration new)))))) + +(define (serialize-mpv-profile-configuration _ cfg) + (let ((sorted (sort + (hash-map->list cons (%mpv-profile-configuration-data cfg)) + (lambda (a b) + (string<? (symbol->string (car a)) + (symbol->string (car b))))))) + #~(string-append + #$@(map (match-lambda + ((field-name . value) + ((cdr value) field-name (car value)))) + sorted)))) + + + + +;;; +;;; Configuration base. +;;; +(define (serialize-type/mpv-profile-configurations _ profiles) + #~(string-append + #$@(map (match-lambda + ((name . config) + #~(string-append + #$(format #f "[~a]~%" name) + #$(serialize-mpv-profile-configuration _ config)))) + profiles))) +(define (type/mpv-profile-configurations? alist) + (every (match-lambda + (((? symbol?) . (? mpv-profile-configuration?)) #t) + (_ #f)) + alist)) + +(define (serialize-type/extra _ value) + (if value + #~(string-append #$value + ;; Ensure the extra content ends in a new line. + #$(if (string-suffix? "\n" value) + "" "\n")) + #~"")) +(define (type/extra? val) + (or (string? val) + (gexp? val))) + +(define-record-type <home-mpv-configuration> + (%make-home-mpv-configuration global profiles extra-config) + home-mpv-configuration? + (global home-mpv-configuration-global) + (profiles home-mpv-configuration-profiles) + (extra-config home-mpv-configuration-extra-config)) + +(define* (make-home-mpv-configuration + #:key + (inherit #f) + (global (if inherit + (home-mpv-configuration-global inherit) + (make-mpv-profile-configuration))) + (profiles (if inherit + (home-mpv-configuration-profiles inherit) + '())) + (extra-config (if inherit + (home-mpv-configuration-extra-config inherit) + #f))) + (unless (or (not global) (mpv-profile-configuration? global)) + (throw 'bad-config "global must satisfy mpv-profile-configuration?")) + (unless (type/mpv-profile-configurations? profiles) + (throw 'bad-config "profiles must be an alist of mpv-profile-configuration?")) + (unless (or (not extra-config) (type/extra? extra-config)) + (throw 'bad-config "extra-config must be a string or a gexp")) + (%make-home-mpv-configuration global profiles extra-config)) + +(define (serialize-home-mpv-configuration cfg) + #~(string-append #$(serialize-mpv-profile-configuration + 'global + (home-mpv-configuration-global cfg)) + #$(serialize-type/mpv-profile-configurations + 'profiles + (home-mpv-configuration-profiles cfg)) + #$(serialize-type/extra + 'extra-config + (home-mpv-configuration-extra-config cfg)))) + +(define (mpv-configuration-files cfg) + `(("mpv/mpv.conf" ,(mixed-text-file "mpv.conf" + (serialize-home-mpv-configuration cfg))))) + +(define home-mpv-service-type + (service-type + (name 'home-mpv) + (extensions + (list (service-extension home-xdg-configuration-files-service-type + mpv-configuration-files))) + (description + "Install configuration files for mpv into XDG configuration directory."))) diff --git a/gnu/local.mk b/gnu/local.mk index f03fcb14fc..c5e545fcb9 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -113,6 +113,7 @@ GNU_SYSTEM_MODULES = \ %D%/home/services/mail.scm \ %D%/home/services/media.scm \ %D%/home/services/messaging.scm \ + %D%/home/services/mpv.scm \ %D%/home/services/music.scm \ %D%/home/services/pm.scm \ %D%/home/services/shells.scm \ -- 2.49.0
guix-patches <at> gnu.org
:bug#74801
; Package guix-patches
.
(Thu, 03 Apr 2025 13:26:03 GMT) Full text and rfc822 format available.Message #11 received at 74801 <at> debbugs.gnu.org (full text, mbox):
From: Maxim Cournoyer <maxim.cournoyer <at> gmail.com> To: Tomas Volf <~@wolfsden.cz> Cc: Ludovic Courtès <ludo <at> gnu.org>, Janneke Nieuwenhuizen <janneke <at> gnu.org>, Tanguy Le Carrour <tanguy <at> bioneland.org>, 74801 <at> debbugs.gnu.org, Andrew Tropin <andrew <at> trop.in> Subject: Re: [bug#74801] [PATCH v2] gnu: home: services: Add home-mpv-service-type. Date: Thu, 03 Apr 2025 22:25:30 +0900
Hi, Tomas Volf <~@wolfsden.cz> writes: > This commit adds a new service type to generate configuration file for the mpv > media player. > > Originally I attempted to use Guix Records (via define-configuration) for > this, but ran into the bug #74748, so I had to switch to procedures instead. > The usage is (hopefully) sufficiently described in the documentation. When > the bug is resolved, I will update it to use define-configuration instead. > > The full list of supported options is documented, however I decided to *not* > document types and purpose for each individual fields. While I had mostly > working prototype to extract the documentation from mpv, once I realized it > would be few 10k of lines added, I decided it is not worth it. It would bloat > the .texi file (by more than 50%), be hard to maintain and, in my opinion, > would not provide enough value to justify that. The current version seems > like sane middle ground. Wow! I didn't know mpv add so many configurable switches. [...] > +Due to the bug #74748, it does not use Guix Records to represent the > +configuration, but uses keyword arguments to achieve similar result. > +Example follows: > + > +@lisp > +(service home-mpv-service-type > + (make-home-mpv-configuration > + #:global (make-mpv-profile-configuration > + #:fullscreen #t > + #:alang '("jpn" "eng")))) > +@end lisp This looks reasonable if #74748 can't be resolved (I suspect it may cause an itch to Ludovic, but their plate is pretty full already I assume!). [...] > +@table @asis > +@item Flags > +The value is evaluated for truthfulness. Typically you would use > +@code{#f} or @code{#t}. nitpick: I'd leave out the implementation details (the phrase about truthfulness) and simply mention these expect a boolean value, #t or #f. [...] > +Only set fields are outputted to the configuration file. Accessors are > +provided for every field, returning either their value or a sentinel > +object @code{%unset}. This should be %unset-value, which is already defined in (gnu services configuration). [...] > + > +;;; > +;;; Basic types. > +;;; > +(define (serialize-type/boolean field-name value) Nitpick: it's more common in the code base to name serializers as 'serialize-boolean'; it'd be nicer to stick to that naming style, for consistency. > + #~(string-append #$(symbol->string field-name) > + "=" > + #$(if value "yes" "no") > + "\n")) > +(define type/boolean? > + (const #t)) Does the above really check anything? (type/boolean? "string") $25 = #t (type/boolean? 0) $26 = #t Seems like no. > +(define (serialize-type/integer field-name value) > + #~(string-append #$(symbol->string field-name) > + "=" > + #$(number->string value) > + "\n")) > +(define (type/integer? n) > + ;; We assume integer is a signed 32bit number. > + (and-let* (((integer? n)) > + ((>= n -2147483648)) > + ((<= n 2147483647))))) I'd use the maths to compute the values, for clarity and ensuring correctness, e.g. (* -1 (expt 2 (1- 32))) and (1- (expt 2 (1- 32))). > + > +(define (serialize-type/integer64 field-name value) > + #~(string-append #$(symbol->string field-name) > + "=" > + #$(number->string value) > + "\n")) > +(define (type/integer64? n) > + ;; We assume integer is a signed 64bit number. > + (and-let* (((integer? n)) > + ((>= n -9223372036854775808)) > + ((<= n 9223372036854775807))))) Likewise. > +(define (serialize-type/string field-name value) > + #~(string-append #$(symbol->string field-name) > + "=" > + #$value > + "\n")) > +(define type/string? > + string?) > + > +(define (serialize-type/float field-name value) > + #~(string-append #$(symbol->string field-name) > + "=" > + #$(number->string (exact->inexact value)) > + "\n")) > +(define type/float? > + ;; I am not sure how to validate floats. > + real?) Maybe inexact? would be closer. For floats you could check that (type/integer? (inexact->exact (truncate value))) is true. For doubles you could check that (type/integer64? (inexact->exact (truncate value))) is true. I think. For the rest, it looks good to me, except that you throw old fashioned exception values. Please take a look in the code base to see how raising error message exceptions that get shown nicely by the Guix command line. Maybe define-compile-time-procedure from (guix combinators) can be used, see it used for example in (gnu services base) for `assert-valid-name'. Could you send a v2 with the above taken into consideration? -- Thanks, Maxim
guix-patches <at> gnu.org
:bug#74801
; Package guix-patches
.
(Thu, 03 Apr 2025 16:35:01 GMT) Full text and rfc822 format available.Message #14 received at 74801 <at> debbugs.gnu.org (full text, mbox):
From: Tomas Volf <~@wolfsden.cz> To: Maxim Cournoyer <maxim.cournoyer <at> gmail.com> Cc: 74801 <at> debbugs.gnu.org Subject: Re: [bug#74801] [PATCH v2] gnu: home: services: Add home-mpv-service-type. Date: Thu, 03 Apr 2025 18:34:01 +0200
Hi Maxim, thanks a lot for the review! :) I have implemented most of your comments, only remaining question is about the type/... pattern, see below. Maxim Cournoyer <maxim.cournoyer <at> gmail.com> writes: > Hi, > > Tomas Volf <~@wolfsden.cz> writes: > >> This commit adds a new service type to generate configuration file for the mpv >> media player. >> >> Originally I attempted to use Guix Records (via define-configuration) for >> this, but ran into the bug #74748, so I had to switch to procedures instead. >> The usage is (hopefully) sufficiently described in the documentation. When >> the bug is resolved, I will update it to use define-configuration instead. >> >> The full list of supported options is documented, however I decided to *not* >> document types and purpose for each individual fields. While I had mostly >> working prototype to extract the documentation from mpv, once I realized it >> would be few 10k of lines added, I decided it is not worth it. It would bloat >> the .texi file (by more than 50%), be hard to maintain and, in my opinion, >> would not provide enough value to justify that. The current version seems >> like sane middle ground. > > Wow! I didn't know mpv add so many configurable switches. I was also surprised. :) > > > [...] > >> +Due to the bug #74748, it does not use Guix Records to represent the >> +configuration, but uses keyword arguments to achieve similar result. > > >> +Example follows: >> + >> +@lisp >> +(service home-mpv-service-type >> + (make-home-mpv-configuration >> + #:global (make-mpv-profile-configuration >> + #:fullscreen #t >> + #:alang '("jpn" "eng")))) >> +@end lisp > > This looks reasonable if #74748 can't be resolved (I suspect it may > cause an itch to Ludovic, but their plate is pretty full already I > assume!). > > [...] > >> +@table @asis >> +@item Flags >> +The value is evaluated for truthfulness. Typically you would use >> +@code{#f} or @code{#t}. > > nitpick: I'd leave out the implementation details (the phrase about > truthfulness) and simply mention these expect a boolean value, #t or #f. > I have liked the flexibility (no need to wrap procedure calls in ->bool), but will change this to #t/#f only, it does not matter much. > >> +Only set fields are outputted to the configuration file. Accessors are >> +provided for every field, returning either their value or a sentinel >> +object @code{%unset}. > > This should be %unset-value, which is already defined in (gnu services > configuration). I did not like that someone could set the field to '%unset-marker%, and it would be treated the same way as %unset-value. That is why my %unset value was a list '(*unset*), to ensure uniqueness as far as eq? goes. However I will give you that this is somewhat unlikely to cause any issues in practice, so I will yield here and use %unset-value instead. > > [...] > >> + >> +;;; >> +;;; Basic types. >> +;;; >> +(define (serialize-type/boolean field-name value) > > Nitpick: it's more common in the code base to name serializers as > 'serialize-boolean'; it'd be nicer to stick to that naming style, for > consistency. But it does follow the same pattern. The type is named type/boolean. So the pattern of serialize-$TYPE results in serialize-type/boolean. Without the type/ prefix I would run into collisions, since I need a predicate for an integer (type/integer?), but integer? is already a procedure doing something else. I am not sure I want to shadow it. Hm, would it make it better for you if I replaced the type/ prefix with mpv/ prefix? So mpv/integer, instead of type/integer? That would result in serialize-mpv/boolean, which might be better in your eyes? > >> + #~(string-append #$(symbol->string field-name) >> + "=" >> + #$(if value "yes" "no") >> + "\n")) >> +(define type/boolean? >> + (const #t)) > > Does the above really check anything? It does not, by design. :) > > (type/boolean? "string") > $25 = #t > > (type/boolean? 0) > $26 = #t > > Seems like no. Well, since any object is acceptable as test in an if, the (const #t) seemed appropriate. Now that I have per your suggestion above switched to #t or #f instead of truthfulness, I will update the check to check for #t or #f instead. > >> +(define (serialize-type/integer field-name value) >> + #~(string-append #$(symbol->string field-name) >> + "=" >> + #$(number->string value) >> + "\n")) >> +(define (type/integer? n) >> + ;; We assume integer is a signed 32bit number. >> + (and-let* (((integer? n)) >> + ((>= n -2147483648)) >> + ((<= n 2147483647))))) > > I'd use the maths to compute the values, for clarity and ensuring > correctness, e.g. (* -1 (expt 2 (1- 32))) and (1- (expt 2 (1- 32))). Done. > >> + >> +(define (serialize-type/integer64 field-name value) >> + #~(string-append #$(symbol->string field-name) >> + "=" >> + #$(number->string value) >> + "\n")) >> +(define (type/integer64? n) >> + ;; We assume integer is a signed 64bit number. >> + (and-let* (((integer? n)) >> + ((>= n -9223372036854775808)) >> + ((<= n 9223372036854775807))))) > > Likewise. Done. > >> +(define (serialize-type/string field-name value) >> + #~(string-append #$(symbol->string field-name) >> + "=" >> + #$value >> + "\n")) >> +(define type/string? >> + string?) >> + >> +(define (serialize-type/float field-name value) >> + #~(string-append #$(symbol->string field-name) >> + "=" >> + #$(number->string (exact->inexact value)) >> + "\n")) >> +(define type/float? >> + ;; I am not sure how to validate floats. >> + real?) > > Maybe inexact? would be closer. However values satisfying integer? should be accepted as well, at least from the user point of view it should be fine to write just 2, not 2.0, so inexact? does not seem ideal here. > For floats you could check that > > (type/integer? (inexact->exact (truncate value))) is true. > > For doubles you could check that > > (type/integer64? (inexact->exact (truncate value))) is true. > > I think. I am not sure this is correct, since floats/doubles can have large range than integers. So, if you do not mind too much, I will leave the real? for now. In practice I believe it should work well enough. > > For the rest, it looks good to me, except that you throw old fashioned > exception values. Please take a look in the code base to see how > raising error message exceptions that get shown nicely by the Guix command > line. > > Maybe define-compile-time-procedure from (guix combinators) can be used, > see it used for example in (gnu services base) for > `assert-valid-name'. I was not able to wrap my head around define-compile-time-procedure, but I took some other inspiration in the (gnu services base) module and used formatted-message. Seems to be printed well by guix build. --8<---------------cut here---------------start------------->8--- guix build: error: option fullscreena not found for mpv-profile-configuration --8<---------------cut here---------------end--------------->8--- and --8<---------------cut here---------------start------------->8--- guix build: error: invalid mpv configuration for fullscreen: yes --8<---------------cut here---------------end--------------->8--- > > Could you send a v2 with the above taken into consideration? Once I know what to do with the type/..., will send. :) Tomas -- There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors.
guix-patches <at> gnu.org
:bug#74801
; Package guix-patches
.
(Wed, 23 Apr 2025 05:41:05 GMT) Full text and rfc822 format available.Message #17 received at 74801 <at> debbugs.gnu.org (full text, mbox):
From: Maxim Cournoyer <maxim.cournoyer <at> gmail.com> To: Tomas Volf <~@wolfsden.cz> Cc: 74801 <at> debbugs.gnu.org Subject: Re: bug#74801: [PATCH] gnu: home: services: Add home-mpv-service-type. Date: Wed, 23 Apr 2025 14:39:59 +0900
Hi Tomas, Tomas Volf <~@wolfsden.cz> writes: [...] >>> + >>> +;;; >>> +;;; Basic types. >>> +;;; >>> +(define (serialize-type/boolean field-name value) >> >> Nitpick: it's more common in the code base to name serializers as >> 'serialize-boolean'; it'd be nicer to stick to that naming style, for >> consistency. > > But it does follow the same pattern. The type is named type/boolean. > So the pattern of serialize-$TYPE results in serialize-type/boolean. > Without the type/ prefix I would run into collisions, since I need a > predicate for an integer (type/integer?), but integer? is already a > procedure doing something else. I am not sure I want to shadow it. > > Hm, would it make it better for you if I replaced the type/ prefix with > mpv/ prefix? So mpv/integer, instead of type/integer? That would > result in serialize-mpv/boolean, which might be better in your eyes? I think that'd be more precise naming yes, if there's a valid reason that mpv/integer? != integer? (which I'm sure there is since you went to the trouble of defining it!) [...] >>> +(define (serialize-type/string field-name value) >>> + #~(string-append #$(symbol->string field-name) >>> + "=" >>> + #$value >>> + "\n")) >>> +(define type/string? >>> + string?) >>> + >>> +(define (serialize-type/float field-name value) >>> + #~(string-append #$(symbol->string field-name) >>> + "=" >>> + #$(number->string (exact->inexact value)) >>> + "\n")) >>> +(define type/float? >>> + ;; I am not sure how to validate floats. >>> + real?) >> >> Maybe inexact? would be closer. > > However values satisfying integer? should be accepted as well, at least > from the user point of view it should be fine to write just 2, not 2.0, > so inexact? does not seem ideal here. OK! >> For floats you could check that >> >> (type/integer? (inexact->exact (truncate value))) is true. >> >> For doubles you could check that >> >> (type/integer64? (inexact->exact (truncate value))) is true. >> >> I think. > > I am not sure this is correct, since floats/doubles can have large range > than integers. So, if you do not mind too much, I will leave the real? > for now. In practice I believe it should work well enough. OK! I don't mind, and I haven't got refreshed on the IEEE representations of numbers before I commented ;-). >> For the rest, it looks good to me, except that you throw old fashioned >> exception values. Please take a look in the code base to see how >> raising error message exceptions that get shown nicely by the Guix command >> line. >> >> Maybe define-compile-time-procedure from (guix combinators) can be used, >> see it used for example in (gnu services base) for >> `assert-valid-name'. > > I was not able to wrap my head around define-compile-time-procedure, but > I took some other inspiration in the (gnu services base) module and used > formatted-message. Seems to be printed well by guix build. > > guix build: error: option fullscreena not found for mpv-profile-configuration > > > and > > guix build: error: invalid mpv configuration for fullscreen: yes That's good enough to start! It can always be refined later. >> >> Could you send a v2 with the above taken into consideration? > > Once I know what to do with the type/..., will send. :) Sorry for the delay. Now you know :-). -- Thanks, Maxim
andrew <at> trop.in, gabriel <at> erlikon.ch, hako <at> ultrarare.space, janneke <at> gnu.org, ludo <at> gnu.org, maxim.cournoyer <at> gmail.com, tanguy <at> bioneland.org, guix-patches <at> gnu.org
:bug#74801
; Package guix-patches
.
(Fri, 02 May 2025 16:42:02 GMT) Full text and rfc822 format available.Message #20 received at 74801 <at> debbugs.gnu.org (full text, mbox):
From: Tomas Volf <~@wolfsden.cz> To: 74801 <at> debbugs.gnu.org Cc: Tomas Volf <~@wolfsden.cz> Subject: [PATCH v2] gnu: home: services: Add home-mpv-service-type. Date: Fri, 2 May 2025 18:40:40 +0200
This commit adds a new service type to generate configuration file for the mpv media player. Originally I attempted to use Guix Records (via define-configuration) for this, but ran into the bug #74748, so I had to switch to procedures instead. The usage is (hopefully) sufficiently described in the documentation. When the bug is resolved, I will update it to use define-configuration instead. The full list of supported options is documented, however I decided to *not* document types and purpose for each individual fields. While I had mostly working prototype to extract the documentation from mpv, once I realized it would be few 10k of lines added, I decided it is not worth it. It would bloat the .texi file (by more than 50%), be hard to maintain and, in my opinion, would not provide enough value to justify that. The current version seems like sane middle ground. Option to configure inputs (for mpv) will come later in a separate patch. * gnu/home/services/mpv.scm: New file. * gnu/local.mk (GNU_SYSTEM_MODULES): Register it. * doc/guix.texi (mpv Media Player): Document it. Change-Id: I2deb44799a28047cb5d67da97dc6007a9df873af --- doc/guix.texi | 427 ++++++ gnu/home/services/mpv.scm | 2746 +++++++++++++++++++++++++++++++++++++ gnu/local.mk | 1 + 3 files changed, 3174 insertions(+) create mode 100644 gnu/home/services/mpv.scm diff --git a/doc/guix.texi b/doc/guix.texi index 90d90b2e1e..325a0287a6 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -50711,6 +50711,433 @@ Media Home Services @end table @end deftp +@c This is ugly, but upstream does *not* capitalize the ``m'' even when +@c at the beginning of a sentence. So let us follow the branding. +@node mpv Media Player +@subsection mpv Media Player + +@cindex mpv, Home Service +@cindex mpv, configuration +Configuring the @uref{https://mpv.io/, mpv media player} can be somewhat +daunting task, due to the sheer amount of options available, especially +if one wants to be able to inherit the configuration in their code. The +@code{home-mpv-service-type} is provided to help with that problem. +When the service is added to your home environment, file based on the +passed configuration is generated and placed into the correct location. + +Due to the bug #74748, it does not use Guix Records to represent the +configuration, but uses keyword arguments to achieve similar result. +Example follows: + +@lisp +(service home-mpv-service-type + (make-home-mpv-configuration + #:global (make-mpv-profile-configuration + #:fullscreen #t + #:alang '("jpn" "eng")))) +@end lisp + +@defvar home-mpv-service-type +This is the type of the mpv home service, whose value is a +@code{home-mpv-configuration} object. +@end defvar + +@deffn {Procedure} make-home-mpv-configuration +Return a new instance of @code{home-mpv-configuration}. Available +keyword arguments are: + +@table @asis +@item @code{inherit} (default: @code{#t}) +Inherit fields from an another instance. + +@item @code{global} (default: @code{(make-mpv-profile-configuration)}) +The global configuration preceding all profiles. + +@item @code{profiles} (default: @code{()}) +An alist containing configuration for any additional profiles to include +in the configuration file. + +@lisp +(make-home-mpv-configuration + #:profiles `((fullscreen . ,(make-mpv-profile-configuration + #:fullscreen #t)))) +@end lisp + +@item @code{extra-config} (default: @code{#f}) +Additional content to include in the configuration file. It is placed +at the end of the file. + +@end table +@end deffn + +@deffn {Procedure} make-mpv-profile-configuration +Return a new instance of @code{mpv-profile-configuration}. As above, it +also supports the @code{#:inherit} argument. Additionally it supports +keyword arguments named after the options of @command{mpv}. Hence +@option{--fullscreen} (or @code{fullscreen} in the configuration file) +becomes @code{#:fullscreen}. + +Few options are using their aliases instead. @option{audio} instead of +@option{aid}, @option{video} instead of @option{vid}, @option{sub} +instead of @option{sid}, @option{screenshot-directory} instead of +@option{screenshot-dir} and @option{watch-later-directory} instead of +@option{watch-later-dir}. + +Valid values for the fields depend on their type. + +@table @asis +@item Flags +The value should be @code{#f} or @code{#t}. + +@item Numerical fields +Integer and integer64 fields are validated by @code{integer?}, float and +double fields by @code{real?}. Ranges are checked when applicable. + +@item Aspect +Same as integer. + +@item ByteSize +Same as integer64. + +@item Choice +The value should be a symbol representing member of the enumeration. If +the choice has @samp{or ...} part, it can also be value of that +alternative type. + +@item @var{type} list +The value should be a list of the @var{type}. + +@end table + +Other types accept strings, with validation of the values where possible +(e.g. type @samp{Color} is validated, but type @samp{Audio channels or +channel map} is not). + +The full list of currently supported keyword arguments is below. For +the types, allowed values and full description please refer to the +@command{mpv --list-options} and +@uref{https://mpv.io/manual/stable/#options, mpv manual}. + +Only set fields are outputted to the configuration file. Accessors are +provided for every field, returning either their value or a sentinel +object @code{%unset-value} (from @code{(gnu services configuration)}). + +@code{ab-loop-a}, @code{ab-loop-b}, @code{ab-loop-count}, +@code{access-references}, @code{ad}, @code{ad-lavc-ac3drc}, +@code{ad-lavc-downmix}, @code{ad-lavc-o}, @code{ad-lavc-threads}, +@code{ad-queue-enable}, @code{ad-queue-max-bytes}, +@code{ad-queue-max-samples}, @code{ad-queue-max-secs}, @code{af}, +@code{audio}, @code{alang}, @code{allow-delayed-peak-detect}, +@code{alsa-buffer-time}, @code{alsa-ignore-chmap}, +@code{alsa-mixer-device}, @code{alsa-mixer-index}, +@code{alsa-mixer-name}, @code{alsa-non-interleaved}, +@code{alsa-periods}, @code{alsa-resample}, @code{ao}, +@code{ao-null-broken-delay}, @code{ao-null-broken-eof}, +@code{ao-null-buffer}, @code{ao-null-channel-layouts}, +@code{ao-null-format}, @code{ao-null-latency}, @code{ao-null-outburst}, +@code{ao-null-speed}, @code{ao-null-untimed}, @code{ao-pcm-append}, +@code{ao-pcm-file}, @code{ao-pcm-waveheader}, +@code{audio-backward-batch}, @code{audio-backward-overlap}, +@code{audio-buffer}, @code{audio-channels}, @code{audio-client-name}, +@code{audio-delay}, @code{audio-demuxer}, @code{audio-device}, +@code{audio-display}, @code{audio-exclusive}, @code{audio-exts}, +@code{audio-fallback-to-null}, @code{audio-file-auto}, +@code{audio-file-paths}, @code{audio-files}, @code{audio-format}, +@code{audio-normalize-downmix}, @code{audio-pitch-correction}, +@code{audio-resample-cutoff}, @code{audio-resample-filter-size}, +@code{audio-resample-linear}, @code{audio-resample-max-output-size}, +@code{audio-resample-phase-shift}, @code{audio-reversal-buffer}, +@code{audio-samplerate}, @code{audio-spdif}, +@code{audio-stream-silence}, @code{audio-swresample-o}, +@code{audio-wait-open}, @code{auto-window-resize}, +@code{autocreate-playlist}, @code{autofit}, @code{autofit-larger}, +@code{autofit-smaller}, @code{autoload-files}, @code{autosync}, +@code{background}, @code{background-color}, @code{blend-subtitles}, +@code{bluray-device}, @code{border}, @code{border-background}, +@code{brightness}, @code{cache}, @code{cache-on-disk}, +@code{cache-pause}, @code{cache-pause-initial}, @code{cache-pause-wait}, +@code{cache-secs}, @code{cdda-cdtext}, @code{cdda-device}, +@code{cdda-overlap}, @code{cdda-paranoia}, @code{cdda-sector-size}, +@code{cdda-skip}, @code{cdda-span-a}, @code{cdda-span-b}, +@code{cdda-speed}, @code{cdda-toc-offset}, +@code{chapter-merge-threshold}, @code{chapter-seek-threshold}, +@code{chapters-file}, @code{config}, @code{container-fps-override}, +@code{contrast}, @code{cookies}, @code{cookies-file}, +@code{corner-rounding}, @code{correct-downscaling}, @code{correct-pts}, +@code{cover-art-auto}, @code{cover-art-files}, +@code{cover-art-whitelist}, @code{cscale}, @code{cscale-antiring}, +@code{cscale-blur}, @code{cscale-clamp}, @code{cscale-param1}, +@code{cscale-param2}, @code{cscale-radius}, @code{cscale-taper}, +@code{cscale-window}, @code{cscale-wparam}, @code{cscale-wtaper}, +@code{cursor-autohide}, @code{cursor-autohide-fs-only}, @code{deband}, +@code{deband-grain}, @code{deband-iterations}, @code{deband-range}, +@code{deband-threshold}, @code{deinterlace}, +@code{deinterlace-field-parity}, @code{demuxer}, +@code{demuxer-backward-playback-step}, @code{demuxer-cache-dir}, +@code{demuxer-cache-unlink-files}, @code{demuxer-cache-wait}, +@code{demuxer-donate-buffer}, @code{demuxer-hysteresis-secs}, +@code{demuxer-lavf-allow-mimetype}, @code{demuxer-lavf-analyzeduration}, +@code{demuxer-lavf-buffersize}, @code{demuxer-lavf-format}, +@code{demuxer-lavf-hacks}, @code{demuxer-lavf-linearize-timestamps}, +@code{demuxer-lavf-o}, @code{demuxer-lavf-probe-info}, +@code{demuxer-lavf-probescore}, @code{demuxer-lavf-probesize}, +@code{demuxer-lavf-propagate-opts}, @code{demuxer-max-back-bytes}, +@code{demuxer-max-bytes}, @code{demuxer-mkv-probe-start-time}, +@code{demuxer-mkv-probe-video-duration}, +@code{demuxer-mkv-subtitle-preroll}, +@code{demuxer-mkv-subtitle-preroll-secs}, +@code{demuxer-mkv-subtitle-preroll-secs-index}, +@code{demuxer-rawaudio-channels}, @code{demuxer-rawaudio-format}, +@code{demuxer-rawaudio-rate}, @code{demuxer-rawvideo-codec}, +@code{demuxer-rawvideo-format}, @code{demuxer-rawvideo-fps}, +@code{demuxer-rawvideo-h}, @code{demuxer-rawvideo-mp-format}, +@code{demuxer-rawvideo-size}, @code{demuxer-rawvideo-w}, +@code{demuxer-readahead-secs}, @code{demuxer-seekable-cache}, +@code{demuxer-termination-timeout}, @code{demuxer-thread}, +@code{directory-filter-types}, @code{directory-mode}, +@code{display-fps-override}, @code{display-tags}, @code{dither}, +@code{dither-depth}, @code{dither-size-fruit}, @code{drag-and-drop}, +@code{drm-connector}, @code{drm-device}, @code{drm-draw-plane}, +@code{drm-draw-surface-size}, @code{drm-drmprime-video-plane}, +@code{drm-format}, @code{drm-mode}, @code{drm-vrr-enabled}, +@code{dscale}, @code{dscale-antiring}, @code{dscale-blur}, +@code{dscale-clamp}, @code{dscale-param1}, @code{dscale-param2}, +@code{dscale-radius}, @code{dscale-taper}, @code{dscale-window}, +@code{dscale-wparam}, @code{dscale-wtaper}, @code{dump-stats}, +@code{dvbin-card}, @code{dvbin-channel-switch-offset}, +@code{dvbin-file}, @code{dvbin-full-transponder}, @code{dvbin-prog}, +@code{dvbin-timeout}, @code{dvd-angle}, @code{dvd-device}, +@code{dvd-speed}, @code{edition}, @code{egl-config-id}, +@code{egl-output-format}, @code{embeddedfonts}, @code{end}, +@code{error-diffusion}, @code{external-files}, @code{fbo-format}, +@code{focus-on}, @code{force-media-title}, @code{force-render}, +@code{force-rgba-osd-rendering}, @code{force-seekable}, +@code{force-window}, @code{force-window-position}, @code{framedrop}, +@code{frames}, @code{fs-screen}, @code{fs-screen-name}, +@code{fullscreen}, @code{gamma}, @code{gamma-auto}, @code{gamma-factor}, +@code{gamut-mapping-mode}, @code{gapless-audio}, @code{geometry}, +@code{glsl-shader-opts}, @code{glsl-shaders}, @code{gpu-api}, +@code{gpu-context}, @code{gpu-debug}, @code{gpu-dumb-mode}, +@code{gpu-hwdec-interop}, @code{gpu-shader-cache}, +@code{gpu-shader-cache-dir}, @code{gpu-sw}, @code{gpu-tex-pad-x}, +@code{gpu-tex-pad-y}, @code{hdr-compute-peak}, +@code{hdr-contrast-recovery}, @code{hdr-contrast-smoothness}, +@code{hdr-peak-decay-rate}, @code{hdr-peak-percentile}, +@code{hdr-scene-threshold-high}, @code{hdr-scene-threshold-low}, +@code{hidpi-window-scale}, @code{hls-bitrate}, @code{hr-seek}, +@code{hr-seek-demuxer-offset}, @code{hr-seek-framedrop}, +@code{http-header-fields}, @code{http-proxy}, @code{hue}, @code{hwdec}, +@code{hwdec-codecs}, @code{hwdec-extra-frames}, +@code{hwdec-image-format}, @code{icc-3dlut-size}, @code{icc-cache}, +@code{icc-cache-dir}, @code{icc-force-contrast}, @code{icc-intent}, +@code{icc-profile}, @code{icc-profile-auto}, @code{icc-use-luma}, +@code{idle}, @code{ignore-path-in-watch-later-config}, +@code{image-display-duration}, @code{image-exts}, @code{image-lut}, +@code{image-lut-type}, @code{image-subs-video-resolution}, +@code{include}, @code{index}, @code{initial-audio-sync}, +@code{input-ar-delay}, @code{input-ar-rate}, +@code{input-builtin-bindings}, @code{input-builtin-dragging}, +@code{input-commands}, @code{input-conf}, @code{input-cursor}, +@code{input-cursor-passthrough}, @code{input-default-bindings}, +@code{input-doubleclick-time}, @code{input-dragging-deadzone}, +@code{input-ipc-client}, @code{input-ipc-server}, +@code{input-key-fifo-size}, @code{input-media-keys}, +@code{input-preprocess-wheel}, @code{input-right-alt-gr}, +@code{input-terminal}, @code{input-test}, +@code{input-touch-emulate-mouse}, @code{input-vo-keyboard}, +@code{interpolation}, @code{interpolation-preserve}, +@code{interpolation-threshold}, @code{inverse-tone-mapping}, +@code{jack-autostart}, @code{jack-connect}, @code{jack-name}, +@code{jack-port}, @code{jack-std-channel-layout}, @code{keep-open}, +@code{keep-open-pause}, @code{keepaspect}, @code{keepaspect-window}, +@code{lavfi-complex}, @code{length}, @code{libplacebo-opts}, +@code{linear-downscaling}, @code{linear-upscaling}, +@code{load-auto-profiles}, @code{load-osd-console}, @code{load-scripts}, +@code{load-select}, @code{load-stats-overlay}, +@code{load-unsafe-playlists}, @code{log-file}, @code{loop-file}, +@code{loop-playlist}, @code{lut}, @code{lut-type}, @code{mc}, +@code{media-controls}, @code{merge-files}, @code{metadata-codepage}, +@code{mf-fps}, @code{mf-type}, @code{monitoraspect}, +@code{monitorpixelaspect}, @code{msg-color}, @code{msg-level}, +@code{msg-module}, @code{msg-time}, @code{mute}, @code{native-fs}, +@code{native-keyrepeat}, @code{native-touch}, @code{network-timeout}, +@code{oac}, @code{oacopts}, @code{ocopy-metadata}, @code{of}, +@code{ofopts}, @code{on-all-workspaces}, @code{ontop}, +@code{ontop-level}, @code{opengl-check-pattern-a}, +@code{opengl-check-pattern-b}, @code{opengl-early-flush}, +@code{opengl-es}, @code{opengl-glfinish}, @code{opengl-pbo}, +@code{opengl-rectangle-textures}, @code{opengl-swapinterval}, +@code{opengl-waitvsync}, @code{orawts}, @code{ordered-chapters}, +@code{ordered-chapters-files}, @code{oremove-metadata}, @code{osc}, +@code{osd-align-x}, @code{osd-align-y}, @code{osd-back-color}, +@code{osd-bar}, @code{osd-bar-align-x}, @code{osd-bar-align-y}, +@code{osd-bar-h}, @code{osd-bar-outline-size}, @code{osd-bar-w}, +@code{osd-blur}, @code{osd-bold}, @code{osd-border-style}, +@code{osd-color}, @code{osd-duration}, @code{osd-font}, +@code{osd-font-provider}, @code{osd-font-size}, @code{osd-fonts-dir}, +@code{osd-fractions}, @code{osd-italic}, @code{osd-justify}, +@code{osd-level}, @code{osd-margin-x}, @code{osd-margin-y}, +@code{osd-msg1}, @code{osd-msg2}, @code{osd-msg3}, @code{osd-on-seek}, +@code{osd-outline-color}, @code{osd-outline-size}, +@code{osd-playing-msg}, @code{osd-playing-msg-duration}, +@code{osd-playlist-entry}, @code{osd-scale}, @code{osd-scale-by-window}, +@code{osd-shadow-offset}, @code{osd-spacing}, @code{osd-status-msg}, +@code{oset-metadata}, @code{ovc}, @code{ovcopts}, @code{panscan}, +@code{pause}, @code{pipewire-buffer}, @code{pipewire-remote}, +@code{pipewire-volume-mode}, @code{pitch}, @code{play-direction}, +@code{player-operation-mode}, @code{playlist-start}, +@code{prefetch-playlist}, @code{profile}, @code{pulse-allow-suspended}, +@code{pulse-buffer}, @code{pulse-host}, @code{pulse-latency-hacks}, +@code{quiet}, @code{really-quiet}, @code{rebase-start-time}, +@code{referrer}, @code{replaygain}, @code{replaygain-clip}, +@code{replaygain-fallback}, @code{replaygain-preamp}, +@code{reset-on-next-file}, @code{resume-playback}, +@code{resume-playback-check-mtime}, @code{rtsp-transport}, +@code{saturation}, @code{save-position-on-quit}, @code{scale}, +@code{scale-antiring}, @code{scale-blur}, @code{scale-clamp}, +@code{scale-param1}, @code{scale-param2}, @code{scale-radius}, +@code{scale-taper}, @code{scale-window}, @code{scale-wparam}, +@code{scale-wtaper}, @code{scaler-resizes-only}, @code{screen}, +@code{screen-name}, @code{screenshot-avif-encoder}, +@code{screenshot-avif-opts}, @code{screenshot-avif-pixfmt}, +@code{screenshot-directory}, @code{screenshot-format}, +@code{screenshot-high-bit-depth}, @code{screenshot-jpeg-quality}, +@code{screenshot-jpeg-source-chroma}, @code{screenshot-jxl-distance}, +@code{screenshot-jxl-effort}, @code{screenshot-png-compression}, +@code{screenshot-png-filter}, @code{screenshot-sw}, +@code{screenshot-tag-colorspace}, @code{screenshot-template}, +@code{screenshot-webp-compression}, @code{screenshot-webp-lossless}, +@code{screenshot-webp-quality}, @code{script-opts}, @code{scripts}, +@code{secondary-sid}, @code{secondary-sub-ass-override}, +@code{secondary-sub-delay}, @code{secondary-sub-pos}, +@code{secondary-sub-visibility}, @code{sharpen}, @code{show-in-taskbar}, +@code{shuffle}, @code{sub}, @code{sigmoid-center}, @code{sigmoid-slope}, +@code{sigmoid-upscaling}, @code{slang}, @code{snap-window}, +@code{speed}, @code{spirv-compiler}, @code{sstep}, @code{start}, +@code{stop-playback-on-init-failure}, @code{stop-screensaver}, +@code{stream-buffer-size}, @code{stream-dump}, @code{stream-lavf-o}, +@code{stream-record}, @code{stretch-dvd-subs}, +@code{stretch-image-subs-to-screen}, @code{sub-align-x}, +@code{sub-align-y}, @code{sub-ass}, @code{sub-ass-force-margins}, +@code{sub-ass-hinting}, @code{sub-ass-justify}, +@code{sub-ass-line-spacing}, @code{sub-ass-override}, +@code{sub-ass-scale-with-window}, @code{sub-ass-shaper}, +@code{sub-ass-style-overrides}, @code{sub-ass-styles}, +@code{sub-ass-use-video-data}, @code{sub-ass-video-aspect-override}, +@code{sub-ass-vsfilter-color-compat}, @code{sub-auto}, +@code{sub-auto-exts}, @code{sub-back-color}, @code{sub-blur}, +@code{sub-bold}, @code{sub-border-style}, @code{sub-clear-on-seek}, +@code{sub-codepage}, @code{sub-color}, @code{sub-create-cc-track}, +@code{sub-delay}, @code{sub-demuxer}, @code{sub-file-paths}, +@code{sub-files}, @code{sub-filter-jsre}, @code{sub-filter-regex}, +@code{sub-filter-regex-enable}, @code{sub-filter-regex-plain}, +@code{sub-filter-regex-warn}, @code{sub-filter-sdh}, +@code{sub-filter-sdh-enclosures}, @code{sub-filter-sdh-harder}, +@code{sub-fix-timing}, @code{sub-font}, @code{sub-font-provider}, +@code{sub-font-size}, @code{sub-fonts-dir}, +@code{sub-forced-events-only}, @code{sub-fps}, @code{sub-gauss}, +@code{sub-gray}, @code{sub-italic}, @code{sub-justify}, +@code{sub-lavc-o}, @code{sub-margin-x}, @code{sub-margin-y}, +@code{sub-outline-color}, @code{sub-outline-size}, +@code{sub-past-video-end}, @code{sub-pos}, @code{sub-scale}, +@code{sub-scale-by-window}, @code{sub-scale-with-window}, +@code{sub-shadow-offset}, @code{sub-spacing}, @code{sub-speed}, +@code{sub-stretch-durations}, @code{sub-use-margins}, +@code{sub-visibility}, @code{sub-vsfilter-bidi-compat}, +@code{subs-fallback}, @code{subs-fallback-forced}, +@code{subs-match-os-language}, @code{subs-with-matching-audio}, +@code{swapchain-depth}, @code{sws-allow-zimg}, @code{sws-bitexact}, +@code{sws-cgb}, @code{sws-chs}, @code{sws-cs}, @code{sws-cvs}, +@code{sws-fast}, @code{sws-lgb}, @code{sws-ls}, @code{sws-scaler}, +@code{target-colorspace-hint}, @code{target-contrast}, +@code{target-gamut}, @code{target-lut}, @code{target-peak}, +@code{target-prim}, @code{target-trc}, @code{taskbar-progress}, +@code{teletext-page}, @code{temporal-dither}, +@code{temporal-dither-period}, @code{term-osd}, @code{term-osd-bar}, +@code{term-osd-bar-chars}, @code{term-playing-msg}, +@code{term-status-msg}, @code{term-title}, @code{terminal}, +@code{title}, @code{title-bar}, @code{tls-ca-file}, +@code{tls-cert-file}, @code{tls-key-file}, @code{tls-verify}, +@code{tone-mapping}, @code{tone-mapping-max-boost}, +@code{tone-mapping-param}, @code{tone-mapping-visualize}, +@code{track-auto-selection}, @code{tscale}, @code{tscale-antiring}, +@code{tscale-blur}, @code{tscale-clamp}, @code{tscale-param1}, +@code{tscale-param2}, @code{tscale-radius}, @code{tscale-taper}, +@code{tscale-window}, @code{tscale-wparam}, @code{tscale-wtaper}, +@code{untimed}, @code{use-embedded-icc-profile}, +@code{use-filedir-conf}, @code{user-agent}, @code{vaapi-device}, +@code{vd}, @code{vd-apply-cropping}, @code{vd-lavc-assume-old-x264}, +@code{vd-lavc-bitexact}, @code{vd-lavc-check-hw-profile}, +@code{vd-lavc-dr}, @code{vd-lavc-fast}, @code{vd-lavc-film-grain}, +@code{vd-lavc-framedrop}, @code{vd-lavc-o}, @code{vd-lavc-show-all}, +@code{vd-lavc-skipframe}, @code{vd-lavc-skipidct}, +@code{vd-lavc-skiploopfilter}, @code{vd-lavc-software-fallback}, +@code{vd-lavc-threads}, @code{vd-queue-enable}, +@code{vd-queue-max-bytes}, @code{vd-queue-max-samples}, +@code{vd-queue-max-secs}, @code{vf}, @code{video}, @code{video-align-x}, +@code{video-align-y}, @code{video-aspect-method}, +@code{video-aspect-override}, @code{video-backward-batch}, +@code{video-backward-overlap}, @code{video-crop}, @code{video-exts}, +@code{video-latency-hacks}, @code{video-margin-ratio-bottom}, +@code{video-margin-ratio-left}, @code{video-margin-ratio-right}, +@code{video-margin-ratio-top}, @code{video-osd}, +@code{video-output-levels}, @code{video-pan-x}, @code{video-pan-y}, +@code{video-reversal-buffer}, @code{video-rotate}, @code{video-scale-x}, +@code{video-scale-y}, @code{video-sync}, +@code{video-sync-max-audio-change}, @code{video-sync-max-factor}, +@code{video-sync-max-video-change}, @code{video-timing-offset}, +@code{video-unscaled}, @code{video-zoom}, @code{vlang}, @code{vo}, +@code{vo-image-avif-encoder}, @code{vo-image-avif-opts}, +@code{vo-image-avif-pixfmt}, @code{vo-image-format}, +@code{vo-image-high-bit-depth}, @code{vo-image-jpeg-quality}, +@code{vo-image-jpeg-source-chroma}, @code{vo-image-jxl-distance}, +@code{vo-image-jxl-effort}, @code{vo-image-outdir}, +@code{vo-image-png-compression}, @code{vo-image-png-filter}, +@code{vo-image-tag-colorspace}, @code{vo-image-webp-compression}, +@code{vo-image-webp-lossless}, @code{vo-image-webp-quality}, +@code{vo-kitty-alt-screen}, @code{vo-kitty-cols}, +@code{vo-kitty-config-clear}, @code{vo-kitty-height}, +@code{vo-kitty-left}, @code{vo-kitty-rows}, @code{vo-kitty-top}, +@code{vo-kitty-use-shm}, @code{vo-kitty-width}, @code{vo-null-fps}, +@code{vo-sixel-alt-screen}, @code{vo-sixel-buffered}, +@code{vo-sixel-cols}, @code{vo-sixel-config-clear}, +@code{vo-sixel-dither}, @code{vo-sixel-fixedpalette}, +@code{vo-sixel-height}, @code{vo-sixel-left}, @code{vo-sixel-pad-x}, +@code{vo-sixel-pad-y}, @code{vo-sixel-reqcolors}, @code{vo-sixel-rows}, +@code{vo-sixel-threshold}, @code{vo-sixel-top}, @code{vo-sixel-width}, +@code{vo-tct-256}, @code{vo-tct-algo}, @code{vo-tct-buffering}, +@code{vo-tct-height}, @code{vo-tct-width}, @code{vo-vaapi-scaled-osd}, +@code{vo-vaapi-scaling}, @code{vo-vdpau-chroma-deint}, +@code{vo-vdpau-colorkey}, @code{vo-vdpau-composite-detect}, +@code{vo-vdpau-denoise}, @code{vo-vdpau-force-yuv}, @code{vo-vdpau-fps}, +@code{vo-vdpau-hqscaling}, @code{vo-vdpau-output-surfaces}, +@code{vo-vdpau-pullup}, @code{vo-vdpau-queuetime-fs}, +@code{vo-vdpau-queuetime-windowed}, @code{vo-vdpau-sharpen}, +@code{volume}, @code{volume-gain}, @code{volume-gain-max}, +@code{volume-gain-min}, @code{volume-max}, @code{vulkan-async-compute}, +@code{vulkan-async-transfer}, @code{vulkan-device}, +@code{vulkan-display-display}, @code{vulkan-display-mode}, +@code{vulkan-display-plane}, @code{vulkan-queue-count}, +@code{vulkan-swap-mode}, @code{watch-later-directory}, +@code{watch-later-options}, @code{wayland-app-id}, +@code{wayland-configure-bounds}, @code{wayland-content-type}, +@code{wayland-disable-vsync}, @code{wayland-edge-pixels-pointer}, +@code{wayland-edge-pixels-touch}, @code{wayland-present}, @code{wid}, +@code{window-dragging}, @code{window-maximized}, +@code{window-minimized}, @code{window-scale}, +@code{write-filename-in-watch-later-config}, +@code{x11-bypass-compositor}, @code{x11-name}, @code{x11-netwm}, +@code{x11-present}, @code{x11-wid-title}, @code{xv-adaptor}, +@code{xv-buffers}, @code{xv-ck}, @code{xv-ck-method}, +@code{xv-colorkey}, @code{xv-port}, @code{ytdl}, @code{ytdl-format}, +@code{ytdl-raw-options}, @code{zimg-dither}, @code{zimg-fast}, +@code{zimg-scaler}, @code{zimg-scaler-chroma}, +@code{zimg-scaler-chroma-param-a}, @code{zimg-scaler-chroma-param-b}, +@code{zimg-scaler-param-a}, @code{zimg-scaler-param-b}, and +@code{zimg-threads}. + +@end deffn + @node Sway window manager @subsection Sway window manager diff --git a/gnu/home/services/mpv.scm b/gnu/home/services/mpv.scm new file mode 100644 index 0000000000..581c614a4b --- /dev/null +++ b/gnu/home/services/mpv.scm @@ -0,0 +1,2746 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2024, 2025 Tomas Volf <~@wolfsden.cz> +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix 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 General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. + +(define-module (gnu home services mpv) + #:use-module ((gnu services configuration) #:select (%unset-value + maybe-value-set?)) + #:use-module (gnu home services) + #:autoload (guix diagnostics) (formatted-message) + #:autoload (guix i18n) (G_) + #:use-module (guix gexp) + #:use-module (ice-9 match) + #:use-module (ice-9 regex) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-2) + #:use-module (srfi srfi-9) + #:use-module (srfi srfi-26) + #:use-module (srfi srfi-71) + #:export (make-home-mpv-configuration + home-mpv-configuration? + home-mpv-configuration-global + home-mpv-configuration-profiles + home-mpv-configuration-extra-config + home-mpv-configuration-source-location + + serialize-home-mpv-configuration + + make-mpv-profile-configuration + mpv-profile-configuration? + ;; Field accessor procedures are exported by a syntax form when + ;; they are defined, so they are not listed here. + + home-mpv-service-type)) + + +;;; +;;; Basic types. +;;; +(define (serialize-mpv/boolean field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(if value "yes" "no") + "\n")) +(define mpv/boolean? boolean?) + +(define (serialize-mpv/integer field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(number->string value) + "\n")) +(define (mpv/integer? n) + ;; We assume integer is a signed 32bit number. + (and-let* (((integer? n)) + ((>= n (* -1 (expt 2 (1- 32))))) + ((<= n (1- (expt 2 (1- 32)))))))) + +(define (serialize-mpv/integer64 field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(number->string value) + "\n")) +(define (mpv/integer64? n) + ;; We assume integer is a signed 64bit number. + (and-let* (((integer? n)) + ((>= n (* -1 (expt 2 (1- 64))))) + ((<= n (1- (expt 2 (1- 64)))))))) + +(define (serialize-mpv/string field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$value + "\n")) +(define mpv/string? + string?) + +(define (serialize-mpv/float field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(number->string (exact->inexact value)) + "\n")) +(define mpv/float? + ;; I am not sure how to validate floats. + real?) + +(define (serialize-mpv/double field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(number->string (exact->inexact value)) + "\n")) +(define mpv/double? + ;; I am not sure how to validate doubles. + real?) + + + + +;;; +;;; Additional types (possible based on the basic ones). +;;; + +;;; Aspect seems to be treated as an integer, so define it in terms of it. +(define serialize-mpv/aspect serialize-mpv/integer) +(define mpv/aspect? mpv/integer?) + +;;; `Audio channels or channel map' seems to be basically a free form string +;;; with no way to validate. +(define serialize-mpv/audio-channels-or-channel-map serialize-mpv/string) +(define mpv/audio-channels-or-channel-map? mpv/string?) + +;;; Does not seem possible to validate. +(define serialize-mpv/audio-format serialize-mpv/string) +(define mpv/audio-format? mpv/string?) + +;;; While most options list 4.6116860184274e+18 as a maximum value, we will +;;; use integer64 here. That should be enough for everyone for few more +;;; years. +(define serialize-mpv/byte-size serialize-mpv/integer64) +(define mpv/byte-size? mpv/integer64?) + +(define (serialize-mpv/color field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(if (list? value) + (string-join (map number->string value) "/") + value) + "\n")) +(define (mpv/color? value) + (define (ok-num? n) + (and (number? n) + (>= n 0) + (<= n 1))) + (if (list? value) + ;; Either a list of 3(4) numbers encoding RGB(A) on range from 0 to 1... + (match value + (((? ok-num? r) (? ok-num? g) (? ok-num? b)) + #t) + (((? ok-num? r) (? ok-num? g) (? ok-num? b) (? ok-num? alpha)) + #t) + (_ + #f)) + ;; ... or RGB(A) hex encoding. + (string-match "^#([A-Fa-f0-9]{2})?[A-Fa-f0-9]{6}$" value))) + +;;; I do not see value mirroring fourcc.org's database here. It is further +;;; complicated by arbitrary hex being accepted as well. So string it is. +(define serialize-mpv/fourcc serialize-mpv/string) +(define mpv/fourcc? mpv/string?) + +;;; No way to validate. +(define serialize-mpv/image-format serialize-mpv/string) +(define mpv/image-format? mpv/string?) + +;;; Looking at the documentation for --start, there is no way to make this +;;; bullet-proof, especially since even chapter numbers are accepted. +(define serialize-mpv/relative-time-or-percent-position serialize-mpv/string) +(define mpv/relative-time-or-percent-position? mpv/string?) + +(define serialize-mpv/time serialize-mpv/string) +(define mpv/time? mpv/string?) + +(define serialize-mpv/video-rectangle serialize-mpv/string) +(define (mpv/video-rectangle? value) + (or (string-match "-?[0-9]+%?:-?[0-9]+%?" value) + (string-match + "^(-?[0-9]+%?(x-?[0-9]+%?)?)?([+-]-?[0-9]+%?[+-]-?[0-9]+%?)?$" + value))) + +(define serialize-mpv/window-geometry serialize-mpv/string) +(define (mpv/window-geometry? value) + (or (string-match "-?[0-9]+%?:-?[0-9]+%?" value) + (string-match + "^(-?[0-9]+%?(x-?[0-9]+%?)?)?([+-]-?[0-9]+%?[+-]-?[0-9]+%?)?(/[0-9]+)?$" + value))) + +(define serialize-mpv/window-size serialize-mpv/string) +(define (mpv/window-size? value) + (string-match "^([0-9]+%?(x[0-9]+%?)?)?$" value)) + +(define (serialize-mpv/enumeration field-name value) + #~(string-append #$(symbol->string field-name) + "=" + ;; This could be either symbol or (in case of enumerations + ;; with alternate type) anything. So just use `format'. + #$(format #f "~s" value) + "\n")) +(define (mpv/enumeration? value) + ;; There is no general way to check enumerations. The field always has to + ;; define custom sanitizer. + #t) + + + + +;;; +;;; List types. +;;; +(define (serialize-mpv/list-of-string field-name lst) + #~(string-append #$(symbol->string field-name) + "=" + #$(string-join lst ",") + "\n")) +(define (mpv/list-of-string? lst) + (every mpv/string? lst)) + +(define (serialize-mpv/list-of-key-value field-name lst) + #~(string-append #$(symbol->string field-name) + "=" + #$(string-join (map (match-lambda + ((k . v) (format #f "~a=~a" k v))) + lst) + ",") + "\n")) +(define (mpv/list-of-key-value? lst) + (every (match-lambda + (((? string?) . (? string?)) #t) + (_ #f)) + lst)) + +(define serialize-mpv/list-of-object-setting serialize-mpv/list-of-string) +(define mpv/list-of-object-setting? mpv/list-of-string?) + +(define serialize-mpv/list-of-output-verbosity serialize-mpv/list-of-key-value) +(define mpv/list-of-output-verbosity? mpv/list-of-key-value?) + + + + +;;; +;;; Actual configuration record. Contains a lot of generated code. +;;; + +(define-record-type <profile-option> + (make-profile-option name type-check serializer) + profile-option? + (name profile-option-name) + (type-check profile-option-type-check) + (serializer profile-option-serializer)) + +(define %opts (make-hash-table)) + +(define-syntax define-opt + (lambda (x) + (syntax-case x () + ((_ name type extra-checks ...) + (let* ((d/n (syntax->datum #'name)) + (d/t (syntax->datum #'type)) + (d/accessor (string->symbol + (format #f "mpv-profile-configuration-~a" d/n))) + (d/type-check (string->symbol + (format #f "mpv/~a?" d/t))) + (d/serializer (string->symbol + (format #f "serialize-mpv/~a" d/t)))) + (with-syntax + ((kw (datum->syntax x (symbol->keyword d/n))) + (accessor (datum->syntax x d/accessor)) + (type-check (datum->syntax x d/type-check)) + (serializer (datum->syntax x d/serializer)) + (val (datum->syntax x 'val))) + #'(begin + (hashq-set! %opts 'name + (make-profile-option (symbol->string 'name) + (lambda (val) + (and (type-check val) + extra-checks ...)) + serializer)) + (define-public (accessor cfg) + (let ((x (hashq-ref (%mpv-profile-configuration-data cfg) + 'name + %unset-value))) + (if (eq? x %unset-value) + %unset-value + (car x))))))))))) + +;;; Generated code - START. +(define-opt ab-loop-a time) +(define-opt ab-loop-b time) +(define-opt + ab-loop-count + enumeration + (or (memq val '(inf)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt access-references boolean) +(define-opt ad string) +(define-opt + ad-lavc-ac3drc + float + (>= val 0) + (<= val 6)) +(define-opt ad-lavc-downmix boolean) +(define-opt ad-lavc-o list-of-key-value) +(define-opt + ad-lavc-threads + integer + (>= val 0) + (<= val 16)) +(define-opt ad-queue-enable boolean) +(define-opt + ad-queue-max-bytes + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + ad-queue-max-samples + integer64 + (>= val 0)) +(define-opt ad-queue-max-secs double (>= val 0)) +(define-opt af list-of-object-setting) +(define-opt + audio + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt alang list-of-string) +(define-opt allow-delayed-peak-detect boolean) +(define-opt + alsa-buffer-time + integer + (>= val 0) + (<= val 2147483647)) +(define-opt alsa-ignore-chmap boolean) +(define-opt alsa-mixer-device string) +(define-opt + alsa-mixer-index + integer + (>= val 0) + (<= val 99)) +(define-opt alsa-mixer-name string) +(define-opt alsa-non-interleaved boolean) +(define-opt + alsa-periods + integer + (>= val 0) + (<= val 2147483647)) +(define-opt alsa-resample boolean) +(define-opt ao list-of-object-setting) +(define-opt ao-null-broken-delay boolean) +(define-opt ao-null-broken-eof boolean) +(define-opt + ao-null-buffer + float + (>= val 0) + (<= val 100)) +(define-opt + ao-null-channel-layouts + audio-channels-or-channel-map) +(define-opt ao-null-format audio-format) +(define-opt + ao-null-latency + float + (>= val 0) + (<= val 100)) +(define-opt + ao-null-outburst + integer + (>= val 1) + (<= val 100000)) +(define-opt + ao-null-speed + float + (>= val 0) + (<= val 10000)) +(define-opt ao-null-untimed boolean) +(define-opt ao-pcm-append boolean) +(define-opt ao-pcm-file string) +(define-opt ao-pcm-waveheader boolean) +(define-opt + audio-backward-batch + integer + (>= val 0) + (<= val 1024)) +(define-opt + audio-backward-overlap + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 0) (<= val 1024)))) +(define-opt + audio-buffer + double + (>= val 0) + (<= val 10)) +(define-opt + audio-channels + audio-channels-or-channel-map) +(define-opt audio-client-name string) +(define-opt audio-delay float) +(define-opt audio-demuxer string) +(define-opt audio-device string) +(define-opt + audio-display + enumeration + (memq val '(no embedded-first external-first))) +(define-opt audio-exclusive boolean) +(define-opt audio-exts list-of-string) +(define-opt audio-fallback-to-null boolean) +(define-opt + audio-file-auto + enumeration + (memq val '(no exact fuzzy all))) +(define-opt audio-file-paths list-of-string) +(define-opt audio-files list-of-string) +(define-opt audio-format audio-format) +(define-opt audio-normalize-downmix boolean) +(define-opt audio-pitch-correction boolean) +(define-opt + audio-resample-cutoff + double + (>= val 0) + (<= val 1)) +(define-opt + audio-resample-filter-size + integer + (>= val 0) + (<= val 32)) +(define-opt audio-resample-linear boolean) +(define-opt + audio-resample-max-output-size + double) +(define-opt + audio-resample-phase-shift + integer + (>= val 0) + (<= val 30)) +(define-opt + audio-reversal-buffer + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + audio-samplerate + integer + (>= val 0) + (<= val 768000)) +(define-opt audio-spdif string) +(define-opt audio-stream-silence boolean) +(define-opt audio-swresample-o list-of-key-value) +(define-opt + audio-wait-open + float + (>= val 0) + (<= val 60)) +(define-opt auto-window-resize boolean) +(define-opt + autocreate-playlist + enumeration + (memq val '(no filter same))) +(define-opt autofit window-size) +(define-opt autofit-larger window-size) +(define-opt autofit-smaller window-size) +(define-opt autoload-files boolean) +(define-opt + autosync + enumeration + (or (memq val '(no)) + (and (integer? val) (>= val 0) (<= val 10000)))) +(define-opt + background + enumeration + (memq val '(none color tiles))) +(define-opt background-color color) +(define-opt + blend-subtitles + enumeration + (memq val '(no yes video))) +(define-opt bluray-device string) +(define-opt border boolean) +(define-opt + border-background + enumeration + (memq val '(none color tiles))) +(define-opt + brightness + float + (>= val -100) + (<= val 100)) +(define-opt + cache + enumeration + (memq val '(no auto yes))) +(define-opt cache-on-disk boolean) +(define-opt cache-pause boolean) +(define-opt cache-pause-initial boolean) +(define-opt cache-pause-wait float (>= val 0)) +(define-opt cache-secs double (>= val 0)) +(define-opt cdda-cdtext boolean) +(define-opt cdda-device string) +(define-opt + cdda-overlap + integer + (>= val 0) + (<= val 75)) +(define-opt + cdda-paranoia + integer + (>= val 0) + (<= val 2)) +(define-opt + cdda-sector-size + integer + (>= val 1) + (<= val 100)) +(define-opt cdda-skip boolean) +(define-opt cdda-span-a integer) +(define-opt cdda-span-b integer) +(define-opt + cdda-speed + integer + (>= val 1) + (<= val 100)) +(define-opt cdda-toc-offset integer) +(define-opt + chapter-merge-threshold + integer + (>= val 0) + (<= val 10000)) +(define-opt chapter-seek-threshold double) +(define-opt chapters-file string) +(define-opt config boolean) +(define-opt + container-fps-override + double + (>= val 0)) +(define-opt + contrast + float + (>= val -100) + (<= val 100)) +(define-opt cookies boolean) +(define-opt cookies-file string) +(define-opt + corner-rounding + float + (>= val 0) + (<= val 1)) +(define-opt correct-downscaling boolean) +(define-opt correct-pts boolean) +(define-opt + cover-art-auto + enumeration + (memq val '(no exact fuzzy all))) +(define-opt cover-art-files list-of-string) +(define-opt cover-art-whitelist list-of-string) +(define-opt + cscale + enumeration + (memq val + '(bilinear + bicubic_fast + oversample + spline16 + spline36 + spline64 + sinc + lanczos + ginseng + bicubic + hermite + catmull_rom + mitchell + robidoux + robidouxsharp + box + nearest + triangle + gaussian + jinc + ewa_lanczos + ewa_hanning + ewa_ginseng + ewa_lanczossharp + ewa_lanczos4sharpest + ewa_lanczossoft + haasnsoft + ewa_robidoux + ewa_robidouxsharp + bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx))) +(define-opt + cscale-antiring + float + (>= val 0) + (<= val 1)) +(define-opt cscale-blur float) +(define-opt + cscale-clamp + float + (>= val 0) + (<= val 1)) +(define-opt cscale-param1 float) +(define-opt cscale-param2 float) +(define-opt + cscale-radius + float + (>= val 0.5) + (<= val 16)) +(define-opt + cscale-taper + float + (>= val 0) + (<= val 1)) +(define-opt + cscale-window + enumeration + (memq val + '(bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt cscale-wparam float) +(define-opt + cscale-wtaper + float + (>= val 0) + (<= val 1)) +(define-opt + cursor-autohide + enumeration + (or (memq val '(no always)) + (and (integer? val) (>= val 0) (<= val 30000)))) +(define-opt cursor-autohide-fs-only boolean) +(define-opt deband boolean) +(define-opt + deband-grain + float + (>= val 0) + (<= val 4096)) +(define-opt + deband-iterations + integer + (>= val 0) + (<= val 16)) +(define-opt + deband-range + float + (>= val 1) + (<= val 64)) +(define-opt + deband-threshold + float + (>= val 0) + (<= val 4096)) +(define-opt + deinterlace + enumeration + (memq val '(no yes auto))) +(define-opt + deinterlace-field-parity + enumeration + (memq val '(tff bff auto))) +(define-opt demuxer string) +(define-opt + demuxer-backward-playback-step + double + (>= val 0)) +(define-opt demuxer-cache-dir string) +(define-opt + demuxer-cache-unlink-files + enumeration + (memq val '(immediate whendone no))) +(define-opt demuxer-cache-wait boolean) +(define-opt demuxer-donate-buffer boolean) +(define-opt + demuxer-hysteresis-secs + double + (>= val 0)) +(define-opt demuxer-lavf-allow-mimetype boolean) +(define-opt + demuxer-lavf-analyzeduration + float + (>= val 0) + (<= val 3600)) +(define-opt + demuxer-lavf-buffersize + integer + (>= val 1) + (<= val 10485760)) +(define-opt demuxer-lavf-format string) +(define-opt demuxer-lavf-hacks boolean) +(define-opt + demuxer-lavf-linearize-timestamps + enumeration + (memq val '(no auto yes))) +(define-opt demuxer-lavf-o list-of-key-value) +(define-opt + demuxer-lavf-probe-info + enumeration + (memq val '(no yes auto nostreams))) +(define-opt + demuxer-lavf-probescore + integer + (>= val 1) + (<= val 100)) +(define-opt + demuxer-lavf-probesize + integer + (>= val 32) + (<= val 2147483647)) +(define-opt demuxer-lavf-propagate-opts boolean) +(define-opt + demuxer-max-back-bytes + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + demuxer-max-bytes + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt demuxer-mkv-probe-start-time boolean) +(define-opt + demuxer-mkv-probe-video-duration + enumeration + (memq val '(no yes full))) +(define-opt + demuxer-mkv-subtitle-preroll + enumeration + (memq val '(no yes index))) +(define-opt + demuxer-mkv-subtitle-preroll-secs + double + (>= val 0)) +(define-opt + demuxer-mkv-subtitle-preroll-secs-index + double + (>= val 0)) +(define-opt + demuxer-rawaudio-channels + audio-channels-or-channel-map) +(define-opt + demuxer-rawaudio-format + enumeration + (memq val + '(u8 s8 + u16le + u16be + s16le + s16be + u24le + u24be + s24le + s24be + u32le + u32be + s32le + s32be + floatle + floatbe + doublele + doublebe + u16 + s16 + u24 + s24 + u32 + s32 + float + double))) +(define-opt + demuxer-rawaudio-rate + integer + (>= val 1000) + (<= val 384000)) +(define-opt demuxer-rawvideo-codec string) +(define-opt demuxer-rawvideo-format fourcc) +(define-opt + demuxer-rawvideo-fps + float + (>= val 0.001) + (<= val 1000)) +(define-opt + demuxer-rawvideo-h + integer + (>= val 1) + (<= val 8192)) +(define-opt + demuxer-rawvideo-mp-format + image-format) +(define-opt + demuxer-rawvideo-size + integer + (>= val 1) + (<= val 268435456)) +(define-opt + demuxer-rawvideo-w + integer + (>= val 1) + (<= val 8192)) +(define-opt + demuxer-readahead-secs + double + (>= val 0)) +(define-opt + demuxer-seekable-cache + enumeration + (memq val '(auto no yes))) +(define-opt demuxer-termination-timeout double) +(define-opt demuxer-thread boolean) +(define-opt + directory-filter-types + list-of-string) +(define-opt + directory-mode + enumeration + (memq val '(auto lazy recursive ignore))) +(define-opt + display-fps-override + double + (>= val 0)) +(define-opt display-tags list-of-string) +(define-opt + dither + enumeration + (memq val '(fruit ordered error-diffusion no))) +(define-opt + dither-depth + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val -1) (<= val 16)))) +(define-opt + dither-size-fruit + integer + (>= val 2) + (<= val 8)) +(define-opt + drag-and-drop + enumeration + (memq val '(no auto replace append insert-next))) +(define-opt drm-connector string) +(define-opt drm-device string) +(define-opt + drm-draw-plane + enumeration + (or (memq val '(primary overlay)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt drm-draw-surface-size window-size) +(define-opt + drm-drmprime-video-plane + enumeration + (or (memq val '(primary overlay)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt + drm-format + enumeration + (memq val + '(xrgb8888 xrgb2101010 xbgr8888 xbgr2101010 yuyv))) +(define-opt drm-mode string) +(define-opt + drm-vrr-enabled + enumeration + (memq val '(no yes auto))) +(define-opt + dscale + enumeration + (memq val + '(bilinear + bicubic_fast + oversample + spline16 + spline36 + spline64 + sinc + lanczos + ginseng + bicubic + hermite + catmull_rom + mitchell + robidoux + robidouxsharp + box + nearest + triangle + gaussian + jinc + ewa_lanczos + ewa_hanning + ewa_ginseng + ewa_lanczossharp + ewa_lanczos4sharpest + ewa_lanczossoft + haasnsoft + ewa_robidoux + ewa_robidouxsharp + bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx))) +(define-opt + dscale-antiring + float + (>= val 0) + (<= val 1)) +(define-opt dscale-blur float) +(define-opt + dscale-clamp + float + (>= val 0) + (<= val 1)) +(define-opt dscale-param1 float) +(define-opt dscale-param2 float) +(define-opt + dscale-radius + float + (>= val 0.5) + (<= val 16)) +(define-opt + dscale-taper + float + (>= val 0) + (<= val 1)) +(define-opt + dscale-window + enumeration + (memq val + '(bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt dscale-wparam float) +(define-opt + dscale-wtaper + float + (>= val 0) + (<= val 1)) +(define-opt dump-stats string) +(define-opt + dvbin-card + integer + (>= val 0) + (<= val 15)) +(define-opt dvbin-channel-switch-offset integer) +(define-opt dvbin-file string) +(define-opt dvbin-full-transponder boolean) +(define-opt dvbin-prog string) +(define-opt + dvbin-timeout + integer + (>= val 1) + (<= val 30)) +(define-opt + dvd-angle + integer + (>= val 1) + (<= val 99)) +(define-opt dvd-device string) +(define-opt dvd-speed integer) +(define-opt + edition + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt egl-config-id integer) +(define-opt + egl-output-format + enumeration + (memq val + '(auto rgb8 + rgba8 + rgb10 + rgb10_a2 + rgb16 + rgba16 + rgb16f + rgba16f + rgb32f + rgba32f))) +(define-opt embeddedfonts boolean) +(define-opt + end + relative-time-or-percent-position) +(define-opt error-diffusion string) +(define-opt external-files list-of-string) +(define-opt fbo-format string) +(define-opt + focus-on + enumeration + (memq val '(never open all))) +(define-opt force-media-title string) +(define-opt force-render boolean) +(define-opt force-rgba-osd-rendering boolean) +(define-opt force-seekable boolean) +(define-opt + force-window + enumeration + (memq val '(no yes immediate))) +(define-opt force-window-position boolean) +(define-opt + framedrop + enumeration + (memq val '(no vo decoder decoder+vo))) +(define-opt + frames + enumeration + (or (memq val '(all)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt + fs-screen + enumeration + (or (memq val '(all current)) + (and (integer? val) (>= val 0) (<= val 32)))) +(define-opt fs-screen-name string) +(define-opt fullscreen boolean) +(define-opt + gamma + float + (>= val -100) + (<= val 100)) +(define-opt gamma-auto boolean) +(define-opt + gamma-factor + float + (>= val 0.1) + (<= val 2)) +(define-opt + gamut-mapping-mode + enumeration + (memq val + '(auto clip + perceptual + relative + saturation + absolute + desaturate + darken + warn + linear))) +(define-opt + gapless-audio + enumeration + (memq val '(no yes weak))) +(define-opt geometry window-geometry) +(define-opt glsl-shader-opts list-of-key-value) +(define-opt glsl-shaders list-of-string) +(define-opt gpu-api list-of-object-setting) +(define-opt gpu-context list-of-object-setting) +(define-opt gpu-debug boolean) +(define-opt + gpu-dumb-mode + enumeration + (memq val '(auto yes no))) +(define-opt gpu-hwdec-interop string) +(define-opt gpu-shader-cache boolean) +(define-opt gpu-shader-cache-dir string) +(define-opt gpu-sw boolean) +(define-opt + gpu-tex-pad-x + integer + (>= val 0) + (<= val 4096)) +(define-opt + gpu-tex-pad-y + integer + (>= val 0) + (<= val 4096)) +(define-opt + hdr-compute-peak + enumeration + (memq val '(auto yes no))) +(define-opt + hdr-contrast-recovery + float + (>= val 0) + (<= val 2)) +(define-opt + hdr-contrast-smoothness + float + (>= val 1) + (<= val 100)) +(define-opt + hdr-peak-decay-rate + float + (>= val 0) + (<= val 1000)) +(define-opt + hdr-peak-percentile + float + (>= val 0) + (<= val 100)) +(define-opt + hdr-scene-threshold-high + float + (>= val 0) + (<= val 20)) +(define-opt + hdr-scene-threshold-low + float + (>= val 0) + (<= val 20)) +(define-opt hidpi-window-scale boolean) +(define-opt + hls-bitrate + enumeration + (or (memq val '(no min max)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt + hr-seek + enumeration + (memq val '(no absolute yes always default))) +(define-opt hr-seek-demuxer-offset float) +(define-opt hr-seek-framedrop boolean) +(define-opt http-header-fields list-of-string) +(define-opt http-proxy string) +(define-opt hue float (>= val -100) (<= val 100)) +(define-opt hwdec list-of-string) +(define-opt hwdec-codecs string) +(define-opt + hwdec-extra-frames + integer + (>= val 0) + (<= val 256)) +(define-opt hwdec-image-format image-format) +(define-opt icc-3dlut-size string) +(define-opt icc-cache boolean) +(define-opt icc-cache-dir string) +(define-opt + icc-force-contrast + enumeration + (or (memq val '(no inf)) + (and (integer? val) (>= val 0) (<= val 1000000)))) +(define-opt icc-intent integer) +(define-opt icc-profile string) +(define-opt icc-profile-auto boolean) +(define-opt icc-use-luma boolean) +(define-opt + idle + enumeration + (memq val '(no once yes))) +(define-opt + ignore-path-in-watch-later-config + boolean) +(define-opt + image-display-duration + double + (>= val 0)) +(define-opt image-exts list-of-string) +(define-opt image-lut string) +(define-opt + image-lut-type + enumeration + (memq val '(auto native normalized conversion))) +(define-opt image-subs-video-resolution boolean) +(define-opt include string) +(define-opt + index + enumeration + (memq val '(default recreate))) +(define-opt initial-audio-sync boolean) +(define-opt input-ar-delay integer) +(define-opt input-ar-rate integer) +(define-opt input-builtin-bindings boolean) +(define-opt input-builtin-dragging boolean) +(define-opt input-commands list-of-string) +(define-opt input-conf string) +(define-opt input-cursor boolean) +(define-opt input-cursor-passthrough boolean) +(define-opt input-default-bindings boolean) +(define-opt + input-doubleclick-time + integer + (>= val 0) + (<= val 1000)) +(define-opt input-dragging-deadzone integer) +(define-opt input-ipc-client string) +(define-opt input-ipc-server string) +(define-opt + input-key-fifo-size + integer + (>= val 2) + (<= val 65000)) +(define-opt input-media-keys boolean) +(define-opt input-preprocess-wheel boolean) +(define-opt input-right-alt-gr boolean) +(define-opt input-terminal boolean) +(define-opt input-test boolean) +(define-opt input-touch-emulate-mouse boolean) +(define-opt input-vo-keyboard boolean) +(define-opt interpolation boolean) +(define-opt interpolation-preserve boolean) +(define-opt interpolation-threshold float) +(define-opt inverse-tone-mapping boolean) +(define-opt jack-autostart boolean) +(define-opt jack-connect boolean) +(define-opt jack-name string) +(define-opt jack-port string) +(define-opt + jack-std-channel-layout + enumeration + (memq val '(waveext any))) +(define-opt + keep-open + enumeration + (memq val '(no yes always))) +(define-opt keep-open-pause boolean) +(define-opt keepaspect boolean) +(define-opt keepaspect-window boolean) +(define-opt lavfi-complex string) +(define-opt + length + relative-time-or-percent-position) +(define-opt libplacebo-opts list-of-key-value) +(define-opt linear-downscaling boolean) +(define-opt linear-upscaling boolean) +(define-opt + load-auto-profiles + enumeration + (memq val '(no yes auto))) +(define-opt load-osd-console boolean) +(define-opt load-scripts boolean) +(define-opt load-select boolean) +(define-opt load-stats-overlay boolean) +(define-opt load-unsafe-playlists boolean) +(define-opt log-file string) +(define-opt + loop-file + enumeration + (or (memq val '(no inf yes)) + (and (integer? val) (>= val 0) (<= val 10000)))) +(define-opt + loop-playlist + enumeration + (or (memq val '(no inf yes force)) + (and (integer? val) (>= val 1) (<= val 10000)))) +(define-opt lut string) +(define-opt + lut-type + enumeration + (memq val '(auto native normalized conversion))) +(define-opt mc float (>= val 0) (<= val 100)) +(define-opt + media-controls + enumeration + (memq val '(no player yes))) +(define-opt merge-files boolean) +(define-opt metadata-codepage string) +(define-opt mf-fps double) +(define-opt mf-type string) +(define-opt + monitoraspect + float + (>= val 0) + (<= val 9)) +(define-opt + monitorpixelaspect + float + (>= val 0.03125) + (<= val 32)) +(define-opt msg-color boolean) +(define-opt msg-level list-of-output-verbosity) +(define-opt msg-module boolean) +(define-opt msg-time boolean) +(define-opt mute boolean) +(define-opt native-fs boolean) +(define-opt native-keyrepeat boolean) +(define-opt native-touch boolean) +(define-opt network-timeout double (>= val 0)) +(define-opt oac string) +(define-opt oacopts list-of-key-value) +(define-opt ocopy-metadata boolean) +(define-opt of string) +(define-opt ofopts list-of-key-value) +(define-opt on-all-workspaces boolean) +(define-opt ontop boolean) +(define-opt + ontop-level + enumeration + (or (memq val '(window system desktop)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt opengl-check-pattern-a integer) +(define-opt opengl-check-pattern-b integer) +(define-opt + opengl-early-flush + enumeration + (memq val '(no yes auto))) +(define-opt + opengl-es + enumeration + (memq val '(auto yes no))) +(define-opt opengl-glfinish boolean) +(define-opt opengl-pbo boolean) +(define-opt opengl-rectangle-textures boolean) +(define-opt opengl-swapinterval integer) +(define-opt opengl-waitvsync boolean) +(define-opt orawts boolean) +(define-opt ordered-chapters boolean) +(define-opt ordered-chapters-files string) +(define-opt oremove-metadata list-of-string) +(define-opt osc boolean) +(define-opt + osd-align-x + enumeration + (memq val '(left center right))) +(define-opt + osd-align-y + enumeration + (memq val '(top center bottom))) +(define-opt osd-back-color color) +(define-opt osd-bar boolean) +(define-opt + osd-bar-align-x + float + (>= val -1) + (<= val 1)) +(define-opt + osd-bar-align-y + float + (>= val -1) + (<= val 1)) +(define-opt + osd-bar-h + float + (>= val 0.1) + (<= val 50)) +(define-opt + osd-bar-outline-size + float + (>= val 0) + (<= val 1000)) +(define-opt + osd-bar-w + float + (>= val 1) + (<= val 100)) +(define-opt + osd-blur + float + (>= val 0) + (<= val 20)) +(define-opt osd-bold boolean) +(define-opt + osd-border-style + enumeration + (memq val + '(outline-and-shadow opaque-box background-box))) +(define-opt osd-color color) +(define-opt + osd-duration + integer + (>= val 0) + (<= val 3600000)) +(define-opt osd-font string) +(define-opt + osd-font-provider + enumeration + (memq val '(auto none fontconfig))) +(define-opt + osd-font-size + float + (>= val 1) + (<= val 9000)) +(define-opt osd-fonts-dir string) +(define-opt osd-fractions boolean) +(define-opt osd-italic boolean) +(define-opt + osd-justify + enumeration + (memq val '(auto left center right))) +(define-opt + osd-level + enumeration + (memq val '(#{0}# #{1}# #{2}# #{3}#))) +(define-opt + osd-margin-x + integer + (>= val 0) + (<= val 300)) +(define-opt + osd-margin-y + integer + (>= val 0) + (<= val 600)) +(define-opt osd-msg1 string) +(define-opt osd-msg2 string) +(define-opt osd-msg3 string) +(define-opt + osd-on-seek + enumeration + (memq val '(no bar msg msg-bar))) +(define-opt osd-outline-color color) +(define-opt osd-outline-size float) +(define-opt osd-playing-msg string) +(define-opt + osd-playing-msg-duration + integer + (>= val 0) + (<= val 3600000)) +(define-opt + osd-playlist-entry + enumeration + (memq val '(title filename both))) +(define-opt + osd-scale + float + (>= val 0) + (<= val 100)) +(define-opt osd-scale-by-window boolean) +(define-opt osd-shadow-offset float) +(define-opt + osd-spacing + float + (>= val -10) + (<= val 10)) +(define-opt osd-status-msg string) +(define-opt oset-metadata list-of-key-value) +(define-opt ovc string) +(define-opt ovcopts list-of-key-value) +(define-opt panscan float (>= val 0) (<= val 1)) +(define-opt pause boolean) +(define-opt + pipewire-buffer + enumeration + (or (memq val '(native)) + (and (integer? val) (>= val 1) (<= val 2000)))) +(define-opt pipewire-remote string) +(define-opt + pipewire-volume-mode + enumeration + (memq val '(channel global))) +(define-opt + pitch + double + (>= val 0.01) + (<= val 100)) +(define-opt + play-direction + enumeration + (memq val '(forward + backward -))) +(define-opt + player-operation-mode + enumeration + (memq val '(cplayer pseudo-gui))) +(define-opt + playlist-start + enumeration + (or (memq val '(auto no)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt prefetch-playlist boolean) +(define-opt profile list-of-string) +(define-opt pulse-allow-suspended boolean) +(define-opt + pulse-buffer + enumeration + (or (memq val '(native)) + (and (integer? val) (>= val 1) (<= val 2000)))) +(define-opt pulse-host string) +(define-opt pulse-latency-hacks boolean) +(define-opt quiet boolean) +(define-opt really-quiet boolean) +(define-opt rebase-start-time boolean) +(define-opt referrer string) +(define-opt + replaygain + enumeration + (memq val '(no track album))) +(define-opt replaygain-clip boolean) +(define-opt + replaygain-fallback + float + (>= val -200) + (<= val 60)) +(define-opt + replaygain-preamp + float + (>= val -150) + (<= val 150)) +(define-opt reset-on-next-file list-of-string) +(define-opt resume-playback boolean) +(define-opt resume-playback-check-mtime boolean) +(define-opt + rtsp-transport + enumeration + (memq val '(lavf udp tcp http udp_multicast))) +(define-opt + saturation + float + (>= val -100) + (<= val 100)) +(define-opt save-position-on-quit boolean) +(define-opt + scale + enumeration + (memq val + '(bilinear + bicubic_fast + oversample + spline16 + spline36 + spline64 + sinc + lanczos + ginseng + bicubic + hermite + catmull_rom + mitchell + robidoux + robidouxsharp + box + nearest + triangle + gaussian + jinc + ewa_lanczos + ewa_hanning + ewa_ginseng + ewa_lanczossharp + ewa_lanczos4sharpest + ewa_lanczossoft + haasnsoft + ewa_robidoux + ewa_robidouxsharp + bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx))) +(define-opt + scale-antiring + float + (>= val 0) + (<= val 1)) +(define-opt scale-blur float) +(define-opt + scale-clamp + float + (>= val 0) + (<= val 1)) +(define-opt scale-param1 float) +(define-opt scale-param2 float) +(define-opt + scale-radius + float + (>= val 0.5) + (<= val 16)) +(define-opt + scale-taper + float + (>= val 0) + (<= val 1)) +(define-opt + scale-window + enumeration + (memq val + '(bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt scale-wparam float) +(define-opt + scale-wtaper + float + (>= val 0) + (<= val 1)) +(define-opt scaler-resizes-only boolean) +(define-opt + screen + enumeration + (or (memq val '(default)) + (and (integer? val) (>= val 0) (<= val 32)))) +(define-opt screen-name string) +(define-opt screenshot-avif-encoder string) +(define-opt + screenshot-avif-opts + list-of-key-value) +(define-opt screenshot-avif-pixfmt string) +(define-opt screenshot-directory string) +(define-opt + screenshot-format + enumeration + (memq val '(jpg jpeg png webp jxl avif))) +(define-opt screenshot-high-bit-depth boolean) +(define-opt + screenshot-jpeg-quality + integer + (>= val 0) + (<= val 100)) +(define-opt + screenshot-jpeg-source-chroma + boolean) +(define-opt + screenshot-jxl-distance + double + (>= val 0) + (<= val 15)) +(define-opt + screenshot-jxl-effort + integer + (>= val 1) + (<= val 9)) +(define-opt + screenshot-png-compression + integer + (>= val 0) + (<= val 9)) +(define-opt + screenshot-png-filter + integer + (>= val 0) + (<= val 5)) +(define-opt screenshot-sw boolean) +(define-opt screenshot-tag-colorspace boolean) +(define-opt screenshot-template string) +(define-opt + screenshot-webp-compression + integer + (>= val 0) + (<= val 6)) +(define-opt screenshot-webp-lossless boolean) +(define-opt + screenshot-webp-quality + integer + (>= val 0) + (<= val 100)) +(define-opt script-opts list-of-key-value) +(define-opt scripts list-of-string) +(define-opt + secondary-sid + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt + secondary-sub-ass-override + enumeration + (memq val '(no yes scale force strip))) +(define-opt secondary-sub-delay float) +(define-opt + secondary-sub-pos + float + (>= val 0) + (<= val 150)) +(define-opt secondary-sub-visibility boolean) +(define-opt sharpen float) +(define-opt show-in-taskbar boolean) +(define-opt shuffle boolean) +(define-opt + sub + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt + sigmoid-center + float + (>= val 0) + (<= val 1)) +(define-opt + sigmoid-slope + float + (>= val 1) + (<= val 20)) +(define-opt sigmoid-upscaling boolean) +(define-opt slang list-of-string) +(define-opt snap-window boolean) +(define-opt + speed + double + (>= val 0.01) + (<= val 100)) +(define-opt + spirv-compiler + enumeration + (memq val '(auto))) +(define-opt sstep double (>= val 0)) +(define-opt + start + relative-time-or-percent-position) +(define-opt + stop-playback-on-init-failure + boolean) +(define-opt + stop-screensaver + enumeration + (memq val '(no yes always))) +(define-opt + stream-buffer-size + byte-size + (>= val 4096) + (<= val 536870912)) +(define-opt stream-dump string) +(define-opt stream-lavf-o list-of-key-value) +(define-opt stream-record string) +(define-opt stretch-dvd-subs boolean) +(define-opt stretch-image-subs-to-screen boolean) +(define-opt + sub-align-x + enumeration + (memq val '(left center right))) +(define-opt + sub-align-y + enumeration + (memq val '(top center bottom))) +(define-opt sub-ass boolean) +(define-opt sub-ass-force-margins boolean) +(define-opt + sub-ass-hinting + enumeration + (memq val '(none light normal native))) +(define-opt sub-ass-justify boolean) +(define-opt + sub-ass-line-spacing + float + (>= val -1000) + (<= val 1000)) +(define-opt + sub-ass-override + enumeration + (memq val '(no yes scale force strip))) +(define-opt sub-ass-scale-with-window boolean) +(define-opt + sub-ass-shaper + enumeration + (memq val '(simple complex))) +(define-opt + sub-ass-style-overrides + list-of-string) +(define-opt sub-ass-styles string) +(define-opt + sub-ass-use-video-data + enumeration + (memq val '(none aspect-ratio all))) +(define-opt + sub-ass-video-aspect-override + aspect + (>= val 0) + (<= val 10)) +(define-opt + sub-ass-vsfilter-color-compat + enumeration + (memq val '(no basic full force-601))) +(define-opt + sub-auto + enumeration + (memq val '(no exact fuzzy all))) +(define-opt sub-auto-exts list-of-string) +(define-opt sub-back-color color) +(define-opt + sub-blur + float + (>= val 0) + (<= val 20)) +(define-opt sub-bold boolean) +(define-opt + sub-border-style + enumeration + (memq val + '(outline-and-shadow opaque-box background-box))) +(define-opt sub-clear-on-seek boolean) +(define-opt sub-codepage string) +(define-opt sub-color color) +(define-opt sub-create-cc-track boolean) +(define-opt sub-delay float) +(define-opt sub-demuxer string) +(define-opt sub-file-paths list-of-string) +(define-opt sub-files list-of-string) +(define-opt sub-filter-jsre list-of-string) +(define-opt sub-filter-regex list-of-string) +(define-opt sub-filter-regex-enable boolean) +(define-opt sub-filter-regex-plain boolean) +(define-opt sub-filter-regex-warn boolean) +(define-opt sub-filter-sdh boolean) +(define-opt sub-filter-sdh-enclosures string) +(define-opt sub-filter-sdh-harder boolean) +(define-opt sub-fix-timing boolean) +(define-opt sub-font string) +(define-opt + sub-font-provider + enumeration + (memq val '(auto none fontconfig))) +(define-opt + sub-font-size + float + (>= val 1) + (<= val 9000)) +(define-opt sub-fonts-dir string) +(define-opt sub-forced-events-only boolean) +(define-opt sub-fps float) +(define-opt + sub-gauss + float + (>= val 0) + (<= val 3)) +(define-opt sub-gray boolean) +(define-opt sub-italic boolean) +(define-opt + sub-justify + enumeration + (memq val '(auto left center right))) +(define-opt sub-lavc-o list-of-key-value) +(define-opt + sub-margin-x + integer + (>= val 0) + (<= val 300)) +(define-opt + sub-margin-y + integer + (>= val 0) + (<= val 600)) +(define-opt sub-outline-color color) +(define-opt sub-outline-size float) +(define-opt sub-past-video-end boolean) +(define-opt + sub-pos + float + (>= val 0) + (<= val 150)) +(define-opt + sub-scale + float + (>= val 0) + (<= val 100)) +(define-opt sub-scale-by-window boolean) +(define-opt sub-scale-with-window boolean) +(define-opt sub-shadow-offset float) +(define-opt + sub-spacing + float + (>= val -10) + (<= val 10)) +(define-opt sub-speed float) +(define-opt sub-stretch-durations boolean) +(define-opt sub-use-margins boolean) +(define-opt sub-visibility boolean) +(define-opt sub-vsfilter-bidi-compat boolean) +(define-opt + subs-fallback + enumeration + (memq val '(no default yes))) +(define-opt + subs-fallback-forced + enumeration + (memq val '(no yes always))) +(define-opt subs-match-os-language boolean) +(define-opt + subs-with-matching-audio + enumeration + (memq val '(no forced yes))) +(define-opt + swapchain-depth + integer + (>= val 1) + (<= val 8)) +(define-opt sws-allow-zimg boolean) +(define-opt sws-bitexact boolean) +(define-opt + sws-cgb + float + (>= val 0) + (<= val 100)) +(define-opt sws-chs integer) +(define-opt + sws-cs + float + (>= val -100) + (<= val 100)) +(define-opt sws-cvs integer) +(define-opt sws-fast boolean) +(define-opt + sws-lgb + float + (>= val 0) + (<= val 100)) +(define-opt + sws-ls + float + (>= val -100) + (<= val 100)) +(define-opt + sws-scaler + enumeration + (memq val + '(fast-bilinear + bilinear + bicubic + x + point + area + bicublin + gauss + sinc + lanczos + spline))) +(define-opt target-colorspace-hint boolean) +(define-opt + target-contrast + enumeration + (or (memq val '(auto inf)) + (and (integer? val) (>= val 10) (<= val 1000000)))) +(define-opt + target-gamut + enumeration + (memq val + '(auto bt.601-525 + bt.601-625 + bt.709 + bt.2020 + bt.470m + apple + adobe + prophoto + cie1931 + dci-p3 + display-p3 + v-gamut + s-gamut + ebu3213 + film-c + aces-ap0 + aces-ap1))) +(define-opt target-lut string) +(define-opt + target-peak + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 10) (<= val 10000)))) +(define-opt + target-prim + enumeration + (memq val + '(auto bt.601-525 + bt.601-625 + bt.709 + bt.2020 + bt.470m + apple + adobe + prophoto + cie1931 + dci-p3 + display-p3 + v-gamut + s-gamut + ebu3213 + film-c + aces-ap0 + aces-ap1))) +(define-opt + target-trc + enumeration + (memq val + '(auto bt.1886 + srgb + linear + gamma1.8 + gamma2.0 + gamma2.2 + gamma2.4 + gamma2.6 + gamma2.8 + prophoto + pq + hlg + v-log + s-log1 + s-log2 + st428))) +(define-opt taskbar-progress boolean) +(define-opt + teletext-page + integer + (>= val -1) + (<= val 999)) +(define-opt temporal-dither boolean) +(define-opt + temporal-dither-period + integer + (>= val 1) + (<= val 128)) +(define-opt + term-osd + enumeration + (memq val '(force auto no))) +(define-opt term-osd-bar boolean) +(define-opt term-osd-bar-chars string) +(define-opt term-playing-msg string) +(define-opt term-status-msg string) +(define-opt term-title string) +(define-opt terminal boolean) +(define-opt title string) +(define-opt title-bar boolean) +(define-opt tls-ca-file string) +(define-opt tls-cert-file string) +(define-opt tls-key-file string) +(define-opt tls-verify boolean) +(define-opt + tone-mapping + enumeration + (memq val + '(auto clip + mobius + reinhard + hable + gamma + linear + spline + bt.2390 + bt.2446a + st2094-40 + st2094-10))) +(define-opt + tone-mapping-max-boost + float + (>= val 1) + (<= val 10)) +(define-opt tone-mapping-param float) +(define-opt tone-mapping-visualize boolean) +(define-opt track-auto-selection boolean) +(define-opt + tscale + enumeration + (memq val + '(oversample + linear + spline16 + spline36 + spline64 + sinc + lanczos + ginseng + bicubic + hermite + catmull_rom + mitchell + robidoux + robidouxsharp + box + nearest + triangle + gaussian + bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt + tscale-antiring + float + (>= val 0) + (<= val 1)) +(define-opt tscale-blur float) +(define-opt + tscale-clamp + float + (>= val 0) + (<= val 1)) +(define-opt tscale-param1 float) +(define-opt tscale-param2 float) +(define-opt + tscale-radius + float + (>= val 0.5) + (<= val 16)) +(define-opt + tscale-taper + float + (>= val 0) + (<= val 1)) +(define-opt + tscale-window + enumeration + (memq val + '(bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt tscale-wparam float) +(define-opt + tscale-wtaper + float + (>= val 0) + (<= val 1)) +(define-opt untimed boolean) +(define-opt use-embedded-icc-profile boolean) +(define-opt use-filedir-conf boolean) +(define-opt user-agent string) +(define-opt vaapi-device string) +(define-opt vd string) +(define-opt vd-apply-cropping boolean) +(define-opt vd-lavc-assume-old-x264 boolean) +(define-opt vd-lavc-bitexact boolean) +(define-opt vd-lavc-check-hw-profile boolean) +(define-opt + vd-lavc-dr + enumeration + (memq val '(auto no yes))) +(define-opt vd-lavc-fast boolean) +(define-opt + vd-lavc-film-grain + enumeration + (memq val '(auto cpu gpu))) +(define-opt + vd-lavc-framedrop + enumeration + (memq val + '(none default nonref bidir nonkey all))) +(define-opt vd-lavc-o list-of-key-value) +(define-opt vd-lavc-show-all boolean) +(define-opt + vd-lavc-skipframe + enumeration + (memq val + '(none default nonref bidir nonkey all))) +(define-opt + vd-lavc-skipidct + enumeration + (memq val + '(none default nonref bidir nonkey all))) +(define-opt + vd-lavc-skiploopfilter + enumeration + (memq val + '(none default nonref bidir nonkey all))) +(define-opt + vd-lavc-software-fallback + enumeration + (or (memq val '(no yes)) + (and (integer? val) + (>= val 1) + (<= val 2147483647)))) +(define-opt vd-lavc-threads integer (>= val 0)) +(define-opt vd-queue-enable boolean) +(define-opt + vd-queue-max-bytes + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + vd-queue-max-samples + integer64 + (>= val 0)) +(define-opt vd-queue-max-secs double (>= val 0)) +(define-opt vf list-of-object-setting) +(define-opt + video + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt + video-align-x + float + (>= val -1) + (<= val 1)) +(define-opt + video-align-y + float + (>= val -1) + (<= val 1)) +(define-opt + video-aspect-method + enumeration + (memq val '(bitstream container))) +(define-opt + video-aspect-override + aspect + (>= val -1) + (<= val 10)) +(define-opt + video-backward-batch + integer + (>= val 0) + (<= val 1024)) +(define-opt + video-backward-overlap + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 0) (<= val 1024)))) +(define-opt video-crop video-rectangle) +(define-opt video-exts list-of-string) +(define-opt video-latency-hacks boolean) +(define-opt + video-margin-ratio-bottom + float + (>= val 0) + (<= val 1)) +(define-opt + video-margin-ratio-left + float + (>= val 0) + (<= val 1)) +(define-opt + video-margin-ratio-right + float + (>= val 0) + (<= val 1)) +(define-opt + video-margin-ratio-top + float + (>= val 0) + (<= val 1)) +(define-opt video-osd boolean) +(define-opt + video-output-levels + enumeration + (memq val '(auto limited full))) +(define-opt video-pan-x float) +(define-opt video-pan-y float) +(define-opt + video-reversal-buffer + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + video-rotate + enumeration + (or (memq val '(no)) + (and (integer? val) (>= val 0) (<= val 359)))) +(define-opt + video-scale-x + float + (>= val 0) + (<= val 10000)) +(define-opt + video-scale-y + float + (>= val 0) + (<= val 10000)) +(define-opt + video-sync + enumeration + (memq val + '(audio display-resample + display-resample-vdrop + display-resample-desync + display-tempo + display-adrop + display-vdrop + display-desync + desync))) +(define-opt + video-sync-max-audio-change + double + (>= val 0) + (<= val 1)) +(define-opt + video-sync-max-factor + integer + (>= val 1) + (<= val 10)) +(define-opt + video-sync-max-video-change + double + (>= val 0)) +(define-opt + video-timing-offset + double + (>= val 0) + (<= val 1)) +(define-opt + video-unscaled + enumeration + (memq val '(no yes downscale-big))) +(define-opt + video-zoom + float + (>= val -20) + (<= val 20)) +(define-opt vlang list-of-string) +(define-opt vo list-of-object-setting) +(define-opt vo-image-avif-encoder string) +(define-opt vo-image-avif-opts list-of-key-value) +(define-opt vo-image-avif-pixfmt string) +(define-opt + vo-image-format + enumeration + (memq val '(jpg jpeg png webp jxl avif))) +(define-opt vo-image-high-bit-depth boolean) +(define-opt + vo-image-jpeg-quality + integer + (>= val 0) + (<= val 100)) +(define-opt vo-image-jpeg-source-chroma boolean) +(define-opt + vo-image-jxl-distance + double + (>= val 0) + (<= val 15)) +(define-opt + vo-image-jxl-effort + integer + (>= val 1) + (<= val 9)) +(define-opt vo-image-outdir string) +(define-opt + vo-image-png-compression + integer + (>= val 0) + (<= val 9)) +(define-opt + vo-image-png-filter + integer + (>= val 0) + (<= val 5)) +(define-opt vo-image-tag-colorspace boolean) +(define-opt + vo-image-webp-compression + integer + (>= val 0) + (<= val 6)) +(define-opt vo-image-webp-lossless boolean) +(define-opt + vo-image-webp-quality + integer + (>= val 0) + (<= val 100)) +(define-opt vo-kitty-alt-screen boolean) +(define-opt vo-kitty-cols integer) +(define-opt vo-kitty-config-clear boolean) +(define-opt vo-kitty-height integer) +(define-opt vo-kitty-left integer) +(define-opt vo-kitty-rows integer) +(define-opt vo-kitty-top integer) +(define-opt vo-kitty-use-shm boolean) +(define-opt vo-kitty-width integer) +(define-opt + vo-null-fps + double + (>= val 0) + (<= val 10000)) +(define-opt vo-sixel-alt-screen boolean) +(define-opt vo-sixel-buffered boolean) +(define-opt vo-sixel-cols integer) +(define-opt vo-sixel-config-clear boolean) +(define-opt + vo-sixel-dither + enumeration + (memq val + '(auto none + atkinson + fs + jajuni + stucki + burkes + arithmetic + xor))) +(define-opt vo-sixel-fixedpalette boolean) +(define-opt vo-sixel-height integer) +(define-opt vo-sixel-left integer) +(define-opt vo-sixel-pad-x integer) +(define-opt vo-sixel-pad-y integer) +(define-opt vo-sixel-reqcolors integer) +(define-opt vo-sixel-rows integer) +(define-opt vo-sixel-threshold integer) +(define-opt vo-sixel-top integer) +(define-opt vo-sixel-width integer) +(define-opt vo-tct-256 boolean) +(define-opt + vo-tct-algo + enumeration + (memq val '(plain half-blocks))) +(define-opt + vo-tct-buffering + enumeration + (memq val '(pixel line frame))) +(define-opt vo-tct-height integer) +(define-opt vo-tct-width integer) +(define-opt vo-vaapi-scaled-osd boolean) +(define-opt + vo-vaapi-scaling + enumeration + (memq val '(default fast hq nla))) +(define-opt vo-vdpau-chroma-deint boolean) +(define-opt vo-vdpau-colorkey color) +(define-opt vo-vdpau-composite-detect boolean) +(define-opt + vo-vdpau-denoise + float + (>= val 0) + (<= val 1)) +(define-opt vo-vdpau-force-yuv boolean) +(define-opt vo-vdpau-fps double) +(define-opt + vo-vdpau-hqscaling + integer + (>= val 0) + (<= val 9)) +(define-opt + vo-vdpau-output-surfaces + integer + (>= val 2) + (<= val 15)) +(define-opt vo-vdpau-pullup boolean) +(define-opt vo-vdpau-queuetime-fs integer) +(define-opt vo-vdpau-queuetime-windowed integer) +(define-opt + vo-vdpau-sharpen + float + (>= val -1) + (<= val 1)) +(define-opt + volume + float + (>= val -1) + (<= val 1000)) +(define-opt + volume-gain + float + (>= val -150) + (<= val 150)) +(define-opt + volume-gain-max + float + (>= val 0) + (<= val 150)) +(define-opt + volume-gain-min + float + (>= val -150) + (<= val 0)) +(define-opt + volume-max + float + (>= val 100) + (<= val 1000)) +(define-opt vulkan-async-compute boolean) +(define-opt vulkan-async-transfer boolean) +(define-opt vulkan-device string) +(define-opt vulkan-display-display integer) +(define-opt vulkan-display-mode integer) +(define-opt vulkan-display-plane integer) +(define-opt + vulkan-queue-count + integer + (>= val 1) + (<= val 8)) +(define-opt + vulkan-swap-mode + enumeration + (memq val + '(auto fifo fifo-relaxed mailbox immediate))) +(define-opt watch-later-directory string) +(define-opt watch-later-options list-of-string) +(define-opt wayland-app-id string) +(define-opt + wayland-configure-bounds + enumeration + (memq val '(auto no yes))) +(define-opt + wayland-content-type + enumeration + (memq val '(auto none photo video game))) +(define-opt wayland-disable-vsync boolean) +(define-opt + wayland-edge-pixels-pointer + integer + (>= val 0) + (<= val 2147483647)) +(define-opt + wayland-edge-pixels-touch + integer + (>= val 0) + (<= val 2147483647)) +(define-opt wayland-present boolean) +(define-opt wid integer64) +(define-opt window-dragging boolean) +(define-opt window-maximized boolean) +(define-opt window-minimized boolean) +(define-opt + window-scale + double + (>= val 0.001) + (<= val 100)) +(define-opt + write-filename-in-watch-later-config + boolean) +(define-opt + x11-bypass-compositor + enumeration + (memq val '(no yes fs-only never))) +(define-opt x11-name string) +(define-opt + x11-netwm + enumeration + (memq val '(auto no yes))) +(define-opt + x11-present + enumeration + (memq val '(no auto yes))) +(define-opt x11-wid-title boolean) +(define-opt xv-adaptor integer (>= val -1)) +(define-opt + xv-buffers + integer + (>= val 1) + (<= val 10)) +(define-opt + xv-ck + enumeration + (memq val '(use set cur))) +(define-opt + xv-ck-method + enumeration + (memq val '(none bg man auto))) +(define-opt xv-colorkey integer) +(define-opt xv-port integer (>= val 0)) +(define-opt ytdl boolean) +(define-opt ytdl-format string) +(define-opt ytdl-raw-options list-of-key-value) +(define-opt + zimg-dither + enumeration + (memq val '(no ordered random error-diffusion))) +(define-opt zimg-fast boolean) +(define-opt + zimg-scaler + enumeration + (memq val + '(point bilinear + bicubic + spline16 + spline36 + lanczos))) +(define-opt + zimg-scaler-chroma + enumeration + (memq val + '(point bilinear + bicubic + spline16 + spline36 + lanczos))) +(define-opt zimg-scaler-chroma-param-a double) +(define-opt zimg-scaler-chroma-param-b double) +(define-opt zimg-scaler-param-a double) +(define-opt zimg-scaler-param-b double) +(define-opt + zimg-threads + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 1) (<= val 64)))) +;;; Generated code - END. + +(define-record-type <mpv-profile-configuration> + (%make-mpv-profile-configuration data) + mpv-profile-configuration? + (data %mpv-profile-configuration-data)) + +(define (make-mpv-profile-configuration . args) + ;; I am not sure how can I copy a hash-map. Documentation does not mention + ;; anything. + (let ((new (make-hash-table))) + (let loop ((args args)) + (match args + ((#:inherit cfg . tail) + (hash-for-each (lambda (key val) + (hashq-set! new key val)) + (%mpv-profile-configuration-data cfg)) + (loop tail)) + (((? keyword? key) val . tail) + (let* ((key (keyword->symbol key)) + (opt (hashq-ref %opts key))) + (unless opt + (raise-exception + (formatted-message + (G_ "option ~a not found for mpv-profile-configuration") key))) + (if (maybe-value-set? val) + (if ((profile-option-type-check opt) val) + (hashq-set! new key (cons val + (profile-option-serializer opt))) + (raise-exception + (formatted-message + (G_ "invalid mpv configuration for ~a: ~a~%") + key val))) + (hashq-remove! new key))) + (loop tail)) + (() + (%make-mpv-profile-configuration new)))))) + +(define (serialize-mpv-profile-configuration _ cfg) + (let ((sorted (sort + (hash-map->list cons (%mpv-profile-configuration-data cfg)) + (lambda (a b) + (string<? (symbol->string (car a)) + (symbol->string (car b))))))) + #~(string-append + #$@(map (match-lambda + ((field-name . value) + ((cdr value) field-name (car value)))) + sorted)))) + + + + +;;; +;;; Configuration base. +;;; +(define (serialize-mpv/mpv-profile-configurations _ profiles) + #~(string-append + #$@(map (match-lambda + ((name . config) + #~(string-append + #$(format #f "[~a]~%" name) + #$(serialize-mpv-profile-configuration _ config)))) + profiles))) +(define (mpv/mpv-profile-configurations? alist) + (and (list? alist) + (every (match-lambda + (((? symbol?) . (? mpv-profile-configuration?)) #t) + (_ #f)) + alist))) + +(define (serialize-mpv/extra _ value) + (if value + #~(string-append #$value + ;; Ensure the extra content ends in a new line. + #$(if (string-suffix? "\n" value) + "" "\n")) + #~"")) +(define (mpv/extra? val) + (or (string? val) + (gexp? val))) + +(define-record-type <home-mpv-configuration> + (%make-home-mpv-configuration global profiles extra-config) + home-mpv-configuration? + (global home-mpv-configuration-global) + (profiles home-mpv-configuration-profiles) + (extra-config home-mpv-configuration-extra-config)) + +(define* (make-home-mpv-configuration + #:key + (inherit #f) + (global (if inherit + (home-mpv-configuration-global inherit) + (make-mpv-profile-configuration))) + (profiles (if inherit + (home-mpv-configuration-profiles inherit) + '())) + (extra-config (if inherit + (home-mpv-configuration-extra-config inherit) + #f))) + (unless (mpv-profile-configuration? global) + (raise-exception + (formatted-message + (G_ "global must satisfy mpv-profile-configuration?")))) + (unless (mpv/mpv-profile-configurations? profiles) + (raise-exception + (formatted-message + (G_ "profiles must be an alist of mpv-profile-configuration?")))) + (unless (or (not extra-config) (mpv/extra? extra-config)) + (raise-exception + (formatted-message + (G_ "extra-config must be a string or a gexp")))) + (%make-home-mpv-configuration global profiles extra-config)) + +(define (serialize-home-mpv-configuration cfg) + #~(string-append #$(serialize-mpv-profile-configuration + 'global + (home-mpv-configuration-global cfg)) + #$(serialize-mpv/mpv-profile-configurations + 'profiles + (home-mpv-configuration-profiles cfg)) + #$(serialize-mpv/extra + 'extra-config + (home-mpv-configuration-extra-config cfg)))) + +(define (mpv-configuration-files cfg) + `(("mpv/mpv.conf" ,(mixed-text-file "mpv.conf" + (serialize-home-mpv-configuration cfg))))) + +(define home-mpv-service-type + (service-type + (name 'home-mpv) + (extensions + (list (service-extension home-xdg-configuration-files-service-type + mpv-configuration-files))) + (description + "Install configuration files for mpv into XDG configuration directory."))) diff --git a/gnu/local.mk b/gnu/local.mk index f6f95bbf10..cab6655c7b 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -113,6 +113,7 @@ GNU_SYSTEM_MODULES = \ %D%/home/services/mail.scm \ %D%/home/services/media.scm \ %D%/home/services/messaging.scm \ + %D%/home/services/mpv.scm \ %D%/home/services/music.scm \ %D%/home/services/pm.scm \ %D%/home/services/shells.scm \ -- 2.49.0
guix-patches <at> gnu.org
:bug#74801
; Package guix-patches
.
(Fri, 02 May 2025 16:42:03 GMT) Full text and rfc822 format available.Message #23 received at 74801 <at> debbugs.gnu.org (full text, mbox):
From: Tomas Volf <~@wolfsden.cz> To: Maxim Cournoyer <maxim.cournoyer <at> gmail.com> Cc: 74801 <at> debbugs.gnu.org Subject: Re: bug#74801: [PATCH] gnu: home: services: Add home-mpv-service-type. Date: Fri, 02 May 2025 18:40:58 +0200
Maxim Cournoyer <maxim.cournoyer <at> gmail.com> writes: > Hi Tomas, > > Tomas Volf <~@wolfsden.cz> writes: > > [...] > >>>> + >>>> +;;; >>>> +;;; Basic types. >>>> +;;; >>>> +(define (serialize-type/boolean field-name value) >>> >>> Nitpick: it's more common in the code base to name serializers as >>> 'serialize-boolean'; it'd be nicer to stick to that naming style, for >>> consistency. >> >> But it does follow the same pattern. The type is named type/boolean. >> So the pattern of serialize-$TYPE results in serialize-type/boolean. >> Without the type/ prefix I would run into collisions, since I need a >> predicate for an integer (type/integer?), but integer? is already a >> procedure doing something else. I am not sure I want to shadow it. >> >> Hm, would it make it better for you if I replaced the type/ prefix with >> mpv/ prefix? So mpv/integer, instead of type/integer? That would >> result in serialize-mpv/boolean, which might be better in your eyes? > > I think that'd be more precise naming yes, if there's a valid reason > that mpv/integer? != integer? (which I'm sure there is since you went to > the trouble of defining it!) Well, mpv/integer is basically an integer with additional range check. --8<---------------cut here---------------start------------->8--- (define (mpv/integer? n) ;; We assume integer is a signed 32bit number. (and-let* (((integer? n)) ((>= n (* -1 (expt 2 (1- 32))))) ((<= n (1- (expt 2 (1- 32)))))))) --8<---------------cut here---------------end--------------->8--- On the other hand, for e.g. mpv/boolean there is nothing extra to check, so it is just a matter of consistency to have all "types" sharing the same naming pattern. I have renamed all the type/ to mpv/, so hopefully you will find the new version better. :) >>> >>> Could you send a v2 with the above taken into consideration? >> >> Once I know what to do with the type/..., will send. :) > > Sorry for the delay. Now you know :-). And sorry for the delay from my side. :) I really appreciate you taking the time to do the review, and have now sent a v2 hopefully addressing all your concerns. Have a nice day, Tomas -- There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors.
guix-patches <at> gnu.org
:bug#74801
; Package guix-patches
.
(Tue, 06 May 2025 10:31:04 GMT) Full text and rfc822 format available.Message #26 received at 74801 <at> debbugs.gnu.org (full text, mbox):
From: Ludovic Courtès <ludo <at> gnu.org> To: Tomas Volf <~@wolfsden.cz> Cc: Tanguy Le Carrour <tanguy <at> bioneland.org>, Maxim Cournoyer <maxim.cournoyer <at> gmail.com>, Gabriel Wicki <gabriel <at> erlikon.ch>, Andrew Tropin <andrew <at> trop.in>, Hilton Chain <hako <at> ultrarare.space>, 74801 <at> debbugs.gnu.org, Janneke Nieuwenhuizen <janneke <at> gnu.org> Subject: Re: [bug#74801] [PATCH v2] gnu: home: services: Add home-mpv-service-type. Date: Tue, 06 May 2025 11:44:27 +0200
Hi, Tomas Volf <~@wolfsden.cz> writes: > This commit adds a new service type to generate configuration file for the mpv > media player. > > Originally I attempted to use Guix Records (via define-configuration) for > this, but ran into the bug #74748, so I had to switch to procedures instead. > The usage is (hopefully) sufficiently described in the documentation. When > the bug is resolved, I will update it to use define-configuration instead. Is #74748 still a significant issue after 5b158ddca9425d79ea4ceb374003fe0f7e6bd336? (This v2 already takes quite a few seconds to build, so it might be a good starting point for profiling…) > The full list of supported options is documented, however I decided to *not* > document types and purpose for each individual fields. While I had mostly > working prototype to extract the documentation from mpv, once I realized it > would be few 10k of lines added, I decided it is not worth it. It would bloat > the .texi file (by more than 50%), be hard to maintain and, in my opinion, > would not provide enough value to justify that. The current version seems > like sane middle ground. Sounds reasonable. > Option to configure inputs (for mpv) will come later in a separate patch. OK. (I think this text is not meant for the commit log itself; you can instead write it after the --- line.) > +@deffn {Procedure} make-home-mpv-configuration > +Return a new instance of @code{home-mpv-configuration}. Available > +keyword arguments are: > + > +@table @asis > +@item @code{inherit} (default: @code{#t}) > +Inherit fields from an another instance. > + > +@item @code{global} (default: @code{(make-mpv-profile-configuration)}) > +The global configuration preceding all profiles. > + > +@item @code{profiles} (default: @code{()}) > +An alist containing configuration for any additional profiles to include > +in the configuration file. > + > +@lisp > +(make-home-mpv-configuration > + #:profiles `((fullscreen . ,(make-mpv-profile-configuration > + #:fullscreen #t)))) > +@end lisp > + > +@item @code{extra-config} (default: @code{#f}) > +Additional content to include in the configuration file. It is placed > +at the end of the file. Two minor stylistic issues: 1. We almost always drop the ‘make-’ bit from constructors, so I wonder whether we should do the same here (OTOH these procedures are different from the usual record constructors, so…). 2. Please add question marks for boolean flags: #:inherit?, #:fullscreen?, etc. > +;;; Generated code - START. Could you include the code you used to generate the options? Apart from that it LGTM. Thanks, Ludo’.
guix-patches <at> gnu.org
:bug#74801
; Package guix-patches
.
(Tue, 06 May 2025 22:04:01 GMT) Full text and rfc822 format available.Message #29 received at 74801 <at> debbugs.gnu.org (full text, mbox):
From: Tomas Volf <~@wolfsden.cz> To: Ludovic Courtès <ludo <at> gnu.org> Cc: Tanguy Le Carrour <tanguy <at> bioneland.org>, Maxim Cournoyer <maxim.cournoyer <at> gmail.com>, Gabriel Wicki <gabriel <at> erlikon.ch>, Andrew Tropin <andrew <at> trop.in>, Hilton Chain <hako <at> ultrarare.space>, 74801 <at> debbugs.gnu.org, Janneke Nieuwenhuizen <janneke <at> gnu.org> Subject: Re: [bug#74801] [PATCH v2] gnu: home: services: Add home-mpv-service-type. Date: Wed, 07 May 2025 00:03:34 +0200
Ludovic Courtès <ludo <at> gnu.org> writes: > Hi, > > Tomas Volf <~@wolfsden.cz> writes: > >> This commit adds a new service type to generate configuration file for the mpv >> media player. >> >> Originally I attempted to use Guix Records (via define-configuration) for >> this, but ran into the bug #74748, so I had to switch to procedures instead. >> The usage is (hopefully) sufficiently described in the documentation. When >> the bug is resolved, I will update it to use define-configuration instead. > > Is #74748 still a significant issue after > 5b158ddca9425d79ea4ceb374003fe0f7e6bd336? > > (This v2 already takes quite a few seconds to build, so it might be a > good starting point for profiling…) I believe the workaround is still justified due to REPL part. In #74748 you write: > At the REPL you could type: > > ,o optimization-level 1 > > You could use ‘repl-option-set!’ from ~/.guile somehow I guess. But that means that every user experimenting with the configuration in their REPL needs to do the same. What is more, they first need to find out that they should do that. That seems not great. >> The full list of supported options is documented, however I decided to *not* >> document types and purpose for each individual fields. While I had mostly >> working prototype to extract the documentation from mpv, once I realized it >> would be few 10k of lines added, I decided it is not worth it. It would bloat >> the .texi file (by more than 50%), be hard to maintain and, in my opinion, >> would not provide enough value to justify that. The current version seems >> like sane middle ground. > > Sounds reasonable. > >> Option to configure inputs (for mpv) will come later in a separate patch. > > OK. > > (I think this text is not meant for the commit log itself; you can > instead write it after the --- line.) Will remove. I sometimes struggle with this a bit (since commit message I can write right away, the text for "after ---" I need to keep... somewhere, until the patch is ready). > >> +@deffn {Procedure} make-home-mpv-configuration >> +Return a new instance of @code{home-mpv-configuration}. Available >> +keyword arguments are: >> + >> +@table @asis >> +@item @code{inherit} (default: @code{#t}) >> +Inherit fields from an another instance. >> + >> +@item @code{global} (default: @code{(make-mpv-profile-configuration)}) >> +The global configuration preceding all profiles. >> + >> +@item @code{profiles} (default: @code{()}) >> +An alist containing configuration for any additional profiles to include >> +in the configuration file. >> + >> +@lisp >> +(make-home-mpv-configuration >> + #:profiles `((fullscreen . ,(make-mpv-profile-configuration >> + #:fullscreen #t)))) >> +@end lisp >> + >> +@item @code{extra-config} (default: @code{#f}) >> +Additional content to include in the configuration file. It is placed >> +at the end of the file. > > Two minor stylistic issues: > > 1. We almost always drop the ‘make-’ bit from constructors, so I > wonder whether we should do the same here (OTOH these procedures > are different from the usual record constructors, so…). Yeah, I did it like this on purpose to have a backwards compatible way to switch to normal records (named without the make-) later. > > 2. Please add question marks for boolean flags: #:inherit?, > #:fullscreen?, etc. Ah, good catch, will special-case 'boolean type in the generator (though #:inherit in particular is not a boolean flag). > >> +;;; Generated code - START. > > Could you include the code you used to generate the options? I definitely *could* do that. While the code is maybe a bit ugly, it is not intended to be kept secret. Couple of questions though. 1. Where should I put it? Somewhere in etc directory? Or next to the service, so e.g. gnu/home/services/mpv-refresh.sh? 2. It has external dependencies, some of which are packaged in Guix (emacs, emacs-paredit) and some of them are not (guile-wolfsden). Is that a problem? Do I need to rewrite it to use just packaged libraries and programs? > > Apart from that it LGTM. Thanks for the review. :) Once we clarify the fate of the code generator, I will send v3. Tomas -- There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors.
guix-patches <at> gnu.org
:bug#74801
; Package guix-patches
.
(Fri, 09 May 2025 08:53:02 GMT) Full text and rfc822 format available.Message #32 received at 74801 <at> debbugs.gnu.org (full text, mbox):
From: Ludovic Courtès <ludo <at> gnu.org> To: Tomas Volf <~@wolfsden.cz> Cc: Tanguy Le Carrour <tanguy <at> bioneland.org>, Maxim Cournoyer <maxim.cournoyer <at> gmail.com>, Gabriel Wicki <gabriel <at> erlikon.ch>, Andrew Tropin <andrew <at> trop.in>, Hilton Chain <hako <at> ultrarare.space>, 74801 <at> debbugs.gnu.org, Janneke Nieuwenhuizen <janneke <at> gnu.org> Subject: Re: [bug#74801] [PATCH v2] gnu: home: services: Add home-mpv-service-type. Date: Fri, 09 May 2025 10:49:14 +0200
Hello, Tomas Volf <~@wolfsden.cz> writes: > Ludovic Courtès <ludo <at> gnu.org> writes: [...] >> Could you include the code you used to generate the options? > > I definitely *could* do that. While the code is maybe a bit ugly, it is > not intended to be kept secret. Couple of questions though. > > 1. Where should I put it? Somewhere in etc directory? Or next to the > service, so e.g. gnu/home/services/mpv-refresh.sh? > > 2. It has external dependencies, some of which are packaged in Guix > (emacs, emacs-paredit) and some of them are not (guile-wolfsden). Is > that a problem? Do I need to rewrite it to use just packaged > libraries and programs? Well, in that case, maybe just include the URL in the script in the comment (“Generated by …”). Had it been pure Scheme (possibly based on (guix read-print) rather than Emacs), we could have included it straight in the code, as is done for Dovecot IIRC. Someone updating it could use the relevant procedures at the REPL to re-generate the option definitions. Thanks, Ludo’.
andrew <at> trop.in, gabriel <at> erlikon.ch, hako <at> ultrarare.space, janneke <at> gnu.org, ludo <at> gnu.org, maxim.cournoyer <at> gmail.com, tanguy <at> bioneland.org, guix-patches <at> gnu.org
:bug#74801
; Package guix-patches
.
(Fri, 09 May 2025 10:40:02 GMT) Full text and rfc822 format available.Message #35 received at 74801 <at> debbugs.gnu.org (full text, mbox):
From: Tomas Volf <~@wolfsden.cz> To: 74801 <at> debbugs.gnu.org Cc: Tomas Volf <~@wolfsden.cz> Subject: [PATCH v3] gnu: home: services: Add home-mpv-service-type. Date: Fri, 9 May 2025 12:33:54 +0200
This commit adds a new service type to generate configuration file for the mpv media player. * gnu/home/services/mpv.scm: New file. * gnu/local.mk (GNU_SYSTEM_MODULES): Register it. * doc/guix.texi (mpv Media Player): Document it. Change-Id: I2deb44799a28047cb5d67da97dc6007a9df873af --- Originally I attempted to use Guix Records (via define-configuration) for this, but ran into the bug #74748, so I had to switch to procedures instead. The usage is (hopefully) sufficiently described in the documentation. When the bug is resolved, I will update it to use define-configuration instead. The full list of supported options is documented, however I decided to *not* document types and purpose for each individual fields. While I had mostly working prototype to extract the documentation from mpv, once I realized it would be few 10k of lines added, I decided it is not worth it. It would bloat the .texi file (by more than 50%), be hard to maintain and, in my opinion, would not provide enough value to justify that. The current version seems like sane middle ground. Option to configure inputs (for mpv) will come later in a separate patch. v3: - Drop majority of commit message. (I am not sold on this.) - Use ? suffix for boolean options. - Include link to the updater script. doc/guix.texi | 429 ++++++ gnu/home/services/mpv.scm | 2751 +++++++++++++++++++++++++++++++++++++ gnu/local.mk | 1 + 3 files changed, 3181 insertions(+) create mode 100644 gnu/home/services/mpv.scm diff --git a/doc/guix.texi b/doc/guix.texi index 889eab2ab3..f8cb759948 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -50747,6 +50747,435 @@ Media Home Services @end table @end deftp +@c This is ugly, but upstream does *not* capitalize the ``m'' even when +@c at the beginning of a sentence. So let us follow the branding. +@node mpv Media Player +@subsection mpv Media Player + +@cindex mpv, Home Service +@cindex mpv, configuration +Configuring the @uref{https://mpv.io/, mpv media player} can be somewhat +daunting task, due to the sheer amount of options available, especially +if one wants to be able to inherit the configuration in their code. The +@code{home-mpv-service-type} is provided to help with that problem. +When the service is added to your home environment, file based on the +passed configuration is generated and placed into the correct location. + +Due to the bug #74748, it does not use Guix Records to represent the +configuration, but uses keyword arguments to achieve similar result. +Example follows: + +@lisp +(service home-mpv-service-type + (make-home-mpv-configuration + #:global (make-mpv-profile-configuration + #:fullscreen #t + #:alang '("jpn" "eng")))) +@end lisp + +@defvar home-mpv-service-type +This is the type of the mpv home service, whose value is a +@code{home-mpv-configuration} object. +@end defvar + +@deffn {Procedure} make-home-mpv-configuration +Return a new instance of @code{home-mpv-configuration}. Available +keyword arguments are: + +@table @asis +@item @code{inherit} (default: @code{#t}) +Inherit fields from an another instance. + +@item @code{global} (default: @code{(make-mpv-profile-configuration)}) +The global configuration preceding all profiles. + +@item @code{profiles} (default: @code{()}) +An alist containing configuration for any additional profiles to include +in the configuration file. + +@lisp +(make-home-mpv-configuration + #:profiles `((fullscreen . ,(make-mpv-profile-configuration + #:fullscreen #t)))) +@end lisp + +@item @code{extra-config} (default: @code{#f}) +Additional content to include in the configuration file. It is placed +at the end of the file. + +@end table +@end deffn + +@deffn {Procedure} make-mpv-profile-configuration +Return a new instance of @code{mpv-profile-configuration}. As above, it +also supports the @code{#:inherit} argument. Additionally it supports +keyword arguments named after the options of @command{mpv}. Hence +@option{--fullscreen} (or @code{fullscreen} in the configuration file) +becomes @code{#:fullscreen}. + +Few options are using their aliases instead. @option{audio} instead of +@option{aid}, @option{video} instead of @option{vid}, @option{sub} +instead of @option{sid}, @option{screenshot-directory} instead of +@option{screenshot-dir} and @option{watch-later-directory} instead of +@option{watch-later-dir}. + +Valid values for the fields depend on their type. + +@table @asis +@item Flags +The value should be @code{#f} or @code{#t}. + +@item Numerical fields +Integer and integer64 fields are validated by @code{integer?}, float and +double fields by @code{real?}. Ranges are checked when applicable. + +@item Aspect +Same as integer. + +@item ByteSize +Same as integer64. + +@item Choice +The value should be a symbol representing member of the enumeration. If +the choice has @samp{or ...} part, it can also be value of that +alternative type. + +@item @var{type} list +The value should be a list of the @var{type}. + +@end table + +Other types accept strings, with validation of the values where possible +(e.g. type @samp{Color} is validated, but type @samp{Audio channels or +channel map} is not). + +The full list of currently supported keyword arguments is below. For +the types, allowed values and full description please refer to the +@command{mpv --list-options} and +@uref{https://mpv.io/manual/stable/#options, mpv manual}. + +Only set fields are outputted to the configuration file. Accessors are +provided for every field, returning either their value or a sentinel +object @code{%unset-value} (from @code{(gnu services configuration)}). + +@code{ab-loop-a}, @code{ab-loop-b}, @code{ab-loop-count}, +@code{access-references?}, @code{ad}, @code{ad-lavc-ac3drc}, +@code{ad-lavc-downmix?}, @code{ad-lavc-o}, @code{ad-lavc-threads}, +@code{ad-queue-enable?}, @code{ad-queue-max-bytes}, +@code{ad-queue-max-samples}, @code{ad-queue-max-secs}, @code{af}, +@code{audio}, @code{alang}, @code{allow-delayed-peak-detect?}, +@code{alsa-buffer-time}, @code{alsa-ignore-chmap?}, +@code{alsa-mixer-device}, @code{alsa-mixer-index}, +@code{alsa-mixer-name}, @code{alsa-non-interleaved?}, +@code{alsa-periods}, @code{alsa-resample?}, @code{ao}, +@code{ao-null-broken-delay?}, @code{ao-null-broken-eof?}, +@code{ao-null-buffer}, @code{ao-null-channel-layouts}, +@code{ao-null-format}, @code{ao-null-latency}, @code{ao-null-outburst}, +@code{ao-null-speed}, @code{ao-null-untimed?}, @code{ao-pcm-append?}, +@code{ao-pcm-file}, @code{ao-pcm-waveheader?}, +@code{audio-backward-batch}, @code{audio-backward-overlap}, +@code{audio-buffer}, @code{audio-channels}, @code{audio-client-name}, +@code{audio-delay}, @code{audio-demuxer}, @code{audio-device}, +@code{audio-display}, @code{audio-exclusive?}, @code{audio-exts}, +@code{audio-fallback-to-null?}, @code{audio-file-auto}, +@code{audio-file-paths}, @code{audio-files}, @code{audio-format}, +@code{audio-normalize-downmix?}, @code{audio-pitch-correction?}, +@code{audio-resample-cutoff}, @code{audio-resample-filter-size}, +@code{audio-resample-linear?}, @code{audio-resample-max-output-size}, +@code{audio-resample-phase-shift}, @code{audio-reversal-buffer}, +@code{audio-samplerate}, @code{audio-spdif}, +@code{audio-stream-silence?}, @code{audio-swresample-o}, +@code{audio-wait-open}, @code{auto-window-resize?}, +@code{autocreate-playlist}, @code{autofit}, @code{autofit-larger}, +@code{autofit-smaller}, @code{autoload-files?}, @code{autosync}, +@code{background}, @code{background-color}, @code{blend-subtitles}, +@code{bluray-device}, @code{border?}, @code{border-background}, +@code{brightness}, @code{cache}, @code{cache-on-disk?}, +@code{cache-pause?}, @code{cache-pause-initial?}, +@code{cache-pause-wait}, @code{cache-secs}, @code{cdda-cdtext?}, +@code{cdda-device}, @code{cdda-overlap}, @code{cdda-paranoia}, +@code{cdda-sector-size}, @code{cdda-skip?}, @code{cdda-span-a}, +@code{cdda-span-b}, @code{cdda-speed}, @code{cdda-toc-offset}, +@code{chapter-merge-threshold}, @code{chapter-seek-threshold}, +@code{chapters-file}, @code{config?}, @code{container-fps-override}, +@code{contrast}, @code{cookies?}, @code{cookies-file}, +@code{corner-rounding}, @code{correct-downscaling?}, +@code{correct-pts?}, @code{cover-art-auto}, @code{cover-art-files}, +@code{cover-art-whitelist}, @code{cscale}, @code{cscale-antiring}, +@code{cscale-blur}, @code{cscale-clamp}, @code{cscale-param1}, +@code{cscale-param2}, @code{cscale-radius}, @code{cscale-taper}, +@code{cscale-window}, @code{cscale-wparam}, @code{cscale-wtaper}, +@code{cursor-autohide}, @code{cursor-autohide-fs-only?}, @code{deband?}, +@code{deband-grain}, @code{deband-iterations}, @code{deband-range}, +@code{deband-threshold}, @code{deinterlace}, +@code{deinterlace-field-parity}, @code{demuxer}, +@code{demuxer-backward-playback-step}, @code{demuxer-cache-dir}, +@code{demuxer-cache-unlink-files}, @code{demuxer-cache-wait?}, +@code{demuxer-donate-buffer?}, @code{demuxer-hysteresis-secs}, +@code{demuxer-lavf-allow-mimetype?}, +@code{demuxer-lavf-analyzeduration}, @code{demuxer-lavf-buffersize}, +@code{demuxer-lavf-format}, @code{demuxer-lavf-hacks?}, +@code{demuxer-lavf-linearize-timestamps}, @code{demuxer-lavf-o}, +@code{demuxer-lavf-probe-info}, @code{demuxer-lavf-probescore}, +@code{demuxer-lavf-probesize}, @code{demuxer-lavf-propagate-opts?}, +@code{demuxer-max-back-bytes}, @code{demuxer-max-bytes}, +@code{demuxer-mkv-probe-start-time?}, +@code{demuxer-mkv-probe-video-duration}, +@code{demuxer-mkv-subtitle-preroll}, +@code{demuxer-mkv-subtitle-preroll-secs}, +@code{demuxer-mkv-subtitle-preroll-secs-index}, +@code{demuxer-rawaudio-channels}, @code{demuxer-rawaudio-format}, +@code{demuxer-rawaudio-rate}, @code{demuxer-rawvideo-codec}, +@code{demuxer-rawvideo-format}, @code{demuxer-rawvideo-fps}, +@code{demuxer-rawvideo-h}, @code{demuxer-rawvideo-mp-format}, +@code{demuxer-rawvideo-size}, @code{demuxer-rawvideo-w}, +@code{demuxer-readahead-secs}, @code{demuxer-seekable-cache}, +@code{demuxer-termination-timeout}, @code{demuxer-thread?}, +@code{directory-filter-types}, @code{directory-mode}, +@code{display-fps-override}, @code{display-tags}, @code{dither}, +@code{dither-depth}, @code{dither-size-fruit}, @code{drag-and-drop}, +@code{drm-connector}, @code{drm-device}, @code{drm-draw-plane}, +@code{drm-draw-surface-size}, @code{drm-drmprime-video-plane}, +@code{drm-format}, @code{drm-mode}, @code{drm-vrr-enabled}, +@code{dscale}, @code{dscale-antiring}, @code{dscale-blur}, +@code{dscale-clamp}, @code{dscale-param1}, @code{dscale-param2}, +@code{dscale-radius}, @code{dscale-taper}, @code{dscale-window}, +@code{dscale-wparam}, @code{dscale-wtaper}, @code{dump-stats}, +@code{dvbin-card}, @code{dvbin-channel-switch-offset}, +@code{dvbin-file}, @code{dvbin-full-transponder?}, @code{dvbin-prog}, +@code{dvbin-timeout}, @code{dvd-angle}, @code{dvd-device}, +@code{dvd-speed}, @code{edition}, @code{egl-config-id}, +@code{egl-output-format}, @code{embeddedfonts?}, @code{end}, +@code{error-diffusion}, @code{external-files}, @code{fbo-format}, +@code{focus-on}, @code{force-media-title}, @code{force-render?}, +@code{force-rgba-osd-rendering?}, @code{force-seekable?}, +@code{force-window}, @code{force-window-position?}, @code{framedrop}, +@code{frames}, @code{fs-screen}, @code{fs-screen-name}, +@code{fullscreen?}, @code{gamma}, @code{gamma-auto?}, +@code{gamma-factor}, @code{gamut-mapping-mode}, @code{gapless-audio}, +@code{geometry}, @code{glsl-shader-opts}, @code{glsl-shaders}, +@code{gpu-api}, @code{gpu-context}, @code{gpu-debug?}, +@code{gpu-dumb-mode}, @code{gpu-hwdec-interop}, +@code{gpu-shader-cache?}, @code{gpu-shader-cache-dir}, @code{gpu-sw?}, +@code{gpu-tex-pad-x}, @code{gpu-tex-pad-y}, @code{hdr-compute-peak}, +@code{hdr-contrast-recovery}, @code{hdr-contrast-smoothness}, +@code{hdr-peak-decay-rate}, @code{hdr-peak-percentile}, +@code{hdr-scene-threshold-high}, @code{hdr-scene-threshold-low}, +@code{hidpi-window-scale?}, @code{hls-bitrate}, @code{hr-seek}, +@code{hr-seek-demuxer-offset}, @code{hr-seek-framedrop?}, +@code{http-header-fields}, @code{http-proxy}, @code{hue}, @code{hwdec}, +@code{hwdec-codecs}, @code{hwdec-extra-frames}, +@code{hwdec-image-format}, @code{icc-3dlut-size}, @code{icc-cache?}, +@code{icc-cache-dir}, @code{icc-force-contrast}, @code{icc-intent}, +@code{icc-profile}, @code{icc-profile-auto?}, @code{icc-use-luma?}, +@code{idle}, @code{ignore-path-in-watch-later-config?}, +@code{image-display-duration}, @code{image-exts}, @code{image-lut}, +@code{image-lut-type}, @code{image-subs-video-resolution?}, +@code{include}, @code{index}, @code{initial-audio-sync?}, +@code{input-ar-delay}, @code{input-ar-rate}, +@code{input-builtin-bindings?}, @code{input-builtin-dragging?}, +@code{input-commands}, @code{input-conf}, @code{input-cursor?}, +@code{input-cursor-passthrough?}, @code{input-default-bindings?}, +@code{input-doubleclick-time}, @code{input-dragging-deadzone}, +@code{input-ipc-client}, @code{input-ipc-server}, +@code{input-key-fifo-size}, @code{input-media-keys?}, +@code{input-preprocess-wheel?}, @code{input-right-alt-gr?}, +@code{input-terminal?}, @code{input-test?}, +@code{input-touch-emulate-mouse?}, @code{input-vo-keyboard?}, +@code{interpolation?}, @code{interpolation-preserve?}, +@code{interpolation-threshold}, @code{inverse-tone-mapping?}, +@code{jack-autostart?}, @code{jack-connect?}, @code{jack-name}, +@code{jack-port}, @code{jack-std-channel-layout}, @code{keep-open}, +@code{keep-open-pause?}, @code{keepaspect?}, @code{keepaspect-window?}, +@code{lavfi-complex}, @code{length}, @code{libplacebo-opts}, +@code{linear-downscaling?}, @code{linear-upscaling?}, +@code{load-auto-profiles}, @code{load-osd-console?}, +@code{load-scripts?}, @code{load-select?}, @code{load-stats-overlay?}, +@code{load-unsafe-playlists?}, @code{log-file}, @code{loop-file}, +@code{loop-playlist}, @code{lut}, @code{lut-type}, @code{mc}, +@code{media-controls}, @code{merge-files?}, @code{metadata-codepage}, +@code{mf-fps}, @code{mf-type}, @code{monitoraspect}, +@code{monitorpixelaspect}, @code{msg-color?}, @code{msg-level}, +@code{msg-module?}, @code{msg-time?}, @code{mute?}, @code{native-fs?}, +@code{native-keyrepeat?}, @code{native-touch?}, @code{network-timeout}, +@code{oac}, @code{oacopts}, @code{ocopy-metadata?}, @code{of}, +@code{ofopts}, @code{on-all-workspaces?}, @code{ontop?}, +@code{ontop-level}, @code{opengl-check-pattern-a}, +@code{opengl-check-pattern-b}, @code{opengl-early-flush}, +@code{opengl-es}, @code{opengl-glfinish?}, @code{opengl-pbo?}, +@code{opengl-rectangle-textures?}, @code{opengl-swapinterval}, +@code{opengl-waitvsync?}, @code{orawts?}, @code{ordered-chapters?}, +@code{ordered-chapters-files}, @code{oremove-metadata}, @code{osc?}, +@code{osd-align-x}, @code{osd-align-y}, @code{osd-back-color}, +@code{osd-bar?}, @code{osd-bar-align-x}, @code{osd-bar-align-y}, +@code{osd-bar-h}, @code{osd-bar-outline-size}, @code{osd-bar-w}, +@code{osd-blur}, @code{osd-bold?}, @code{osd-border-style}, +@code{osd-color}, @code{osd-duration}, @code{osd-font}, +@code{osd-font-provider}, @code{osd-font-size}, @code{osd-fonts-dir}, +@code{osd-fractions?}, @code{osd-italic?}, @code{osd-justify}, +@code{osd-level}, @code{osd-margin-x}, @code{osd-margin-y}, +@code{osd-msg1}, @code{osd-msg2}, @code{osd-msg3}, @code{osd-on-seek}, +@code{osd-outline-color}, @code{osd-outline-size}, +@code{osd-playing-msg}, @code{osd-playing-msg-duration}, +@code{osd-playlist-entry}, @code{osd-scale}, +@code{osd-scale-by-window?}, @code{osd-shadow-offset}, +@code{osd-spacing}, @code{osd-status-msg}, @code{oset-metadata}, +@code{ovc}, @code{ovcopts}, @code{panscan}, @code{pause?}, +@code{pipewire-buffer}, @code{pipewire-remote}, +@code{pipewire-volume-mode}, @code{pitch}, @code{play-direction}, +@code{player-operation-mode}, @code{playlist-start}, +@code{prefetch-playlist?}, @code{profile}, +@code{pulse-allow-suspended?}, @code{pulse-buffer}, @code{pulse-host}, +@code{pulse-latency-hacks?}, @code{quiet?}, @code{really-quiet?}, +@code{rebase-start-time?}, @code{referrer}, @code{replaygain}, +@code{replaygain-clip?}, @code{replaygain-fallback}, +@code{replaygain-preamp}, @code{reset-on-next-file}, +@code{resume-playback?}, @code{resume-playback-check-mtime?}, +@code{rtsp-transport}, @code{saturation}, @code{save-position-on-quit?}, +@code{scale}, @code{scale-antiring}, @code{scale-blur}, +@code{scale-clamp}, @code{scale-param1}, @code{scale-param2}, +@code{scale-radius}, @code{scale-taper}, @code{scale-window}, +@code{scale-wparam}, @code{scale-wtaper}, @code{scaler-resizes-only?}, +@code{screen}, @code{screen-name}, @code{screenshot-avif-encoder}, +@code{screenshot-avif-opts}, @code{screenshot-avif-pixfmt}, +@code{screenshot-directory}, @code{screenshot-format}, +@code{screenshot-high-bit-depth?}, @code{screenshot-jpeg-quality}, +@code{screenshot-jpeg-source-chroma?}, @code{screenshot-jxl-distance}, +@code{screenshot-jxl-effort}, @code{screenshot-png-compression}, +@code{screenshot-png-filter}, @code{screenshot-sw?}, +@code{screenshot-tag-colorspace?}, @code{screenshot-template}, +@code{screenshot-webp-compression}, @code{screenshot-webp-lossless?}, +@code{screenshot-webp-quality}, @code{script-opts}, @code{scripts}, +@code{secondary-sid}, @code{secondary-sub-ass-override}, +@code{secondary-sub-delay}, @code{secondary-sub-pos}, +@code{secondary-sub-visibility?}, @code{sharpen}, +@code{show-in-taskbar?}, @code{shuffle?}, @code{sub}, +@code{sigmoid-center}, @code{sigmoid-slope}, @code{sigmoid-upscaling?}, +@code{slang}, @code{snap-window?}, @code{speed}, @code{spirv-compiler}, +@code{sstep}, @code{start}, @code{stop-playback-on-init-failure?}, +@code{stop-screensaver}, @code{stream-buffer-size}, @code{stream-dump}, +@code{stream-lavf-o}, @code{stream-record}, @code{stretch-dvd-subs?}, +@code{stretch-image-subs-to-screen?}, @code{sub-align-x}, +@code{sub-align-y}, @code{sub-ass?}, @code{sub-ass-force-margins?}, +@code{sub-ass-hinting}, @code{sub-ass-justify?}, +@code{sub-ass-line-spacing}, @code{sub-ass-override}, +@code{sub-ass-scale-with-window?}, @code{sub-ass-shaper}, +@code{sub-ass-style-overrides}, @code{sub-ass-styles}, +@code{sub-ass-use-video-data}, @code{sub-ass-video-aspect-override}, +@code{sub-ass-vsfilter-color-compat}, @code{sub-auto}, +@code{sub-auto-exts}, @code{sub-back-color}, @code{sub-blur}, +@code{sub-bold?}, @code{sub-border-style}, @code{sub-clear-on-seek?}, +@code{sub-codepage}, @code{sub-color}, @code{sub-create-cc-track?}, +@code{sub-delay}, @code{sub-demuxer}, @code{sub-file-paths}, +@code{sub-files}, @code{sub-filter-jsre}, @code{sub-filter-regex}, +@code{sub-filter-regex-enable?}, @code{sub-filter-regex-plain?}, +@code{sub-filter-regex-warn?}, @code{sub-filter-sdh?}, +@code{sub-filter-sdh-enclosures}, @code{sub-filter-sdh-harder?}, +@code{sub-fix-timing?}, @code{sub-font}, @code{sub-font-provider}, +@code{sub-font-size}, @code{sub-fonts-dir}, +@code{sub-forced-events-only?}, @code{sub-fps}, @code{sub-gauss}, +@code{sub-gray?}, @code{sub-italic?}, @code{sub-justify}, +@code{sub-lavc-o}, @code{sub-margin-x}, @code{sub-margin-y}, +@code{sub-outline-color}, @code{sub-outline-size}, +@code{sub-past-video-end?}, @code{sub-pos}, @code{sub-scale}, +@code{sub-scale-by-window?}, @code{sub-scale-with-window?}, +@code{sub-shadow-offset}, @code{sub-spacing}, @code{sub-speed}, +@code{sub-stretch-durations?}, @code{sub-use-margins?}, +@code{sub-visibility?}, @code{sub-vsfilter-bidi-compat?}, +@code{subs-fallback}, @code{subs-fallback-forced}, +@code{subs-match-os-language?}, @code{subs-with-matching-audio}, +@code{swapchain-depth}, @code{sws-allow-zimg?}, @code{sws-bitexact?}, +@code{sws-cgb}, @code{sws-chs}, @code{sws-cs}, @code{sws-cvs}, +@code{sws-fast?}, @code{sws-lgb}, @code{sws-ls}, @code{sws-scaler}, +@code{target-colorspace-hint?}, @code{target-contrast}, +@code{target-gamut}, @code{target-lut}, @code{target-peak}, +@code{target-prim}, @code{target-trc}, @code{taskbar-progress?}, +@code{teletext-page}, @code{temporal-dither?}, +@code{temporal-dither-period}, @code{term-osd}, @code{term-osd-bar?}, +@code{term-osd-bar-chars}, @code{term-playing-msg}, +@code{term-status-msg}, @code{term-title}, @code{terminal?}, +@code{title}, @code{title-bar?}, @code{tls-ca-file}, +@code{tls-cert-file}, @code{tls-key-file}, @code{tls-verify?}, +@code{tone-mapping}, @code{tone-mapping-max-boost}, +@code{tone-mapping-param}, @code{tone-mapping-visualize?}, +@code{track-auto-selection?}, @code{tscale}, @code{tscale-antiring}, +@code{tscale-blur}, @code{tscale-clamp}, @code{tscale-param1}, +@code{tscale-param2}, @code{tscale-radius}, @code{tscale-taper}, +@code{tscale-window}, @code{tscale-wparam}, @code{tscale-wtaper}, +@code{untimed?}, @code{use-embedded-icc-profile?}, +@code{use-filedir-conf?}, @code{user-agent}, @code{vaapi-device}, +@code{vd}, @code{vd-apply-cropping?}, @code{vd-lavc-assume-old-x264?}, +@code{vd-lavc-bitexact?}, @code{vd-lavc-check-hw-profile?}, +@code{vd-lavc-dr}, @code{vd-lavc-fast?}, @code{vd-lavc-film-grain}, +@code{vd-lavc-framedrop}, @code{vd-lavc-o}, @code{vd-lavc-show-all?}, +@code{vd-lavc-skipframe}, @code{vd-lavc-skipidct}, +@code{vd-lavc-skiploopfilter}, @code{vd-lavc-software-fallback}, +@code{vd-lavc-threads}, @code{vd-queue-enable?}, +@code{vd-queue-max-bytes}, @code{vd-queue-max-samples}, +@code{vd-queue-max-secs}, @code{vf}, @code{video}, @code{video-align-x}, +@code{video-align-y}, @code{video-aspect-method}, +@code{video-aspect-override}, @code{video-backward-batch}, +@code{video-backward-overlap}, @code{video-crop}, @code{video-exts}, +@code{video-latency-hacks?}, @code{video-margin-ratio-bottom}, +@code{video-margin-ratio-left}, @code{video-margin-ratio-right}, +@code{video-margin-ratio-top}, @code{video-osd?}, +@code{video-output-levels}, @code{video-pan-x}, @code{video-pan-y}, +@code{video-reversal-buffer}, @code{video-rotate}, @code{video-scale-x}, +@code{video-scale-y}, @code{video-sync}, +@code{video-sync-max-audio-change}, @code{video-sync-max-factor}, +@code{video-sync-max-video-change}, @code{video-timing-offset}, +@code{video-unscaled}, @code{video-zoom}, @code{vlang}, @code{vo}, +@code{vo-image-avif-encoder}, @code{vo-image-avif-opts}, +@code{vo-image-avif-pixfmt}, @code{vo-image-format}, +@code{vo-image-high-bit-depth?}, @code{vo-image-jpeg-quality}, +@code{vo-image-jpeg-source-chroma?}, @code{vo-image-jxl-distance}, +@code{vo-image-jxl-effort}, @code{vo-image-outdir}, +@code{vo-image-png-compression}, @code{vo-image-png-filter}, +@code{vo-image-tag-colorspace?}, @code{vo-image-webp-compression}, +@code{vo-image-webp-lossless?}, @code{vo-image-webp-quality}, +@code{vo-kitty-alt-screen?}, @code{vo-kitty-cols}, +@code{vo-kitty-config-clear?}, @code{vo-kitty-height}, +@code{vo-kitty-left}, @code{vo-kitty-rows}, @code{vo-kitty-top}, +@code{vo-kitty-use-shm?}, @code{vo-kitty-width}, @code{vo-null-fps}, +@code{vo-sixel-alt-screen?}, @code{vo-sixel-buffered?}, +@code{vo-sixel-cols}, @code{vo-sixel-config-clear?}, +@code{vo-sixel-dither}, @code{vo-sixel-fixedpalette?}, +@code{vo-sixel-height}, @code{vo-sixel-left}, @code{vo-sixel-pad-x}, +@code{vo-sixel-pad-y}, @code{vo-sixel-reqcolors}, @code{vo-sixel-rows}, +@code{vo-sixel-threshold}, @code{vo-sixel-top}, @code{vo-sixel-width}, +@code{vo-tct-256?}, @code{vo-tct-algo}, @code{vo-tct-buffering}, +@code{vo-tct-height}, @code{vo-tct-width}, @code{vo-vaapi-scaled-osd?}, +@code{vo-vaapi-scaling}, @code{vo-vdpau-chroma-deint?}, +@code{vo-vdpau-colorkey}, @code{vo-vdpau-composite-detect?}, +@code{vo-vdpau-denoise}, @code{vo-vdpau-force-yuv?}, +@code{vo-vdpau-fps}, @code{vo-vdpau-hqscaling}, +@code{vo-vdpau-output-surfaces}, @code{vo-vdpau-pullup?}, +@code{vo-vdpau-queuetime-fs}, @code{vo-vdpau-queuetime-windowed}, +@code{vo-vdpau-sharpen}, @code{volume}, @code{volume-gain}, +@code{volume-gain-max}, @code{volume-gain-min}, @code{volume-max}, +@code{vulkan-async-compute?}, @code{vulkan-async-transfer?}, +@code{vulkan-device}, @code{vulkan-display-display}, +@code{vulkan-display-mode}, @code{vulkan-display-plane}, +@code{vulkan-queue-count}, @code{vulkan-swap-mode}, +@code{watch-later-directory}, @code{watch-later-options}, +@code{wayland-app-id}, @code{wayland-configure-bounds}, +@code{wayland-content-type}, @code{wayland-disable-vsync?}, +@code{wayland-edge-pixels-pointer}, @code{wayland-edge-pixels-touch}, +@code{wayland-present?}, @code{wid}, @code{window-dragging?}, +@code{window-maximized?}, @code{window-minimized?}, @code{window-scale}, +@code{write-filename-in-watch-later-config?}, +@code{x11-bypass-compositor}, @code{x11-name}, @code{x11-netwm}, +@code{x11-present}, @code{x11-wid-title?}, @code{xv-adaptor}, +@code{xv-buffers}, @code{xv-ck}, @code{xv-ck-method}, +@code{xv-colorkey}, @code{xv-port}, @code{ytdl?}, @code{ytdl-format}, +@code{ytdl-raw-options}, @code{zimg-dither}, @code{zimg-fast?}, +@code{zimg-scaler}, @code{zimg-scaler-chroma}, +@code{zimg-scaler-chroma-param-a}, @code{zimg-scaler-chroma-param-b}, +@code{zimg-scaler-param-a}, @code{zimg-scaler-param-b}, and +@code{zimg-threads}. + +@end deffn + @node Sway window manager @subsection Sway window manager diff --git a/gnu/home/services/mpv.scm b/gnu/home/services/mpv.scm new file mode 100644 index 0000000000..8d11fa03a3 --- /dev/null +++ b/gnu/home/services/mpv.scm @@ -0,0 +1,2751 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2024, 2025 Tomas Volf <~@wolfsden.cz> +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix 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 General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. + +(define-module (gnu home services mpv) + #:use-module ((gnu services configuration) #:select (%unset-value + maybe-value-set?)) + #:use-module (gnu home services) + #:autoload (guix diagnostics) (formatted-message) + #:autoload (guix i18n) (G_) + #:use-module (guix gexp) + #:use-module (ice-9 match) + #:use-module (ice-9 regex) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-2) + #:use-module (srfi srfi-9) + #:use-module (srfi srfi-26) + #:use-module (srfi srfi-71) + #:export (make-home-mpv-configuration + home-mpv-configuration? + home-mpv-configuration-global + home-mpv-configuration-profiles + home-mpv-configuration-extra-config + home-mpv-configuration-source-location + + serialize-home-mpv-configuration + + make-mpv-profile-configuration + mpv-profile-configuration? + ;; Field accessor procedures are exported by a syntax form when + ;; they are defined, so they are not listed here. + + home-mpv-service-type)) + + +;;; +;;; Basic types. +;;; +(define (serialize-mpv/boolean field-name value) + #~(string-append (string-trim-right #$(symbol->string field-name) #\?) + "=" + #$(if value "yes" "no") + "\n")) +(define mpv/boolean? boolean?) + +(define (serialize-mpv/integer field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(number->string value) + "\n")) +(define (mpv/integer? n) + ;; We assume integer is a signed 32bit number. + (and-let* (((integer? n)) + ((>= n (* -1 (expt 2 (1- 32))))) + ((<= n (1- (expt 2 (1- 32)))))))) + +(define (serialize-mpv/integer64 field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(number->string value) + "\n")) +(define (mpv/integer64? n) + ;; We assume integer is a signed 64bit number. + (and-let* (((integer? n)) + ((>= n (* -1 (expt 2 (1- 64))))) + ((<= n (1- (expt 2 (1- 64)))))))) + +(define (serialize-mpv/string field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$value + "\n")) +(define mpv/string? + string?) + +(define (serialize-mpv/float field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(number->string (exact->inexact value)) + "\n")) +(define mpv/float? + ;; I am not sure how to validate floats. + real?) + +(define (serialize-mpv/double field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(number->string (exact->inexact value)) + "\n")) +(define mpv/double? + ;; I am not sure how to validate doubles. + real?) + + + + +;;; +;;; Additional types (possible based on the basic ones). +;;; + +;;; Aspect seems to be treated as an integer, so define it in terms of it. +(define serialize-mpv/aspect serialize-mpv/integer) +(define mpv/aspect? mpv/integer?) + +;;; `Audio channels or channel map' seems to be basically a free form string +;;; with no way to validate. +(define serialize-mpv/audio-channels-or-channel-map serialize-mpv/string) +(define mpv/audio-channels-or-channel-map? mpv/string?) + +;;; Does not seem possible to validate. +(define serialize-mpv/audio-format serialize-mpv/string) +(define mpv/audio-format? mpv/string?) + +;;; While most options list 4.6116860184274e+18 as a maximum value, we will +;;; use integer64 here. That should be enough for everyone for few more +;;; years. +(define serialize-mpv/byte-size serialize-mpv/integer64) +(define mpv/byte-size? mpv/integer64?) + +(define (serialize-mpv/color field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(if (list? value) + (string-join (map number->string value) "/") + value) + "\n")) +(define (mpv/color? value) + (define (ok-num? n) + (and (number? n) + (>= n 0) + (<= n 1))) + (if (list? value) + ;; Either a list of 3(4) numbers encoding RGB(A) on range from 0 to 1... + (match value + (((? ok-num? r) (? ok-num? g) (? ok-num? b)) + #t) + (((? ok-num? r) (? ok-num? g) (? ok-num? b) (? ok-num? alpha)) + #t) + (_ + #f)) + ;; ... or RGB(A) hex encoding. + (string-match "^#([A-Fa-f0-9]{2})?[A-Fa-f0-9]{6}$" value))) + +;;; I do not see value mirroring fourcc.org's database here. It is further +;;; complicated by arbitrary hex being accepted as well. So string it is. +(define serialize-mpv/fourcc serialize-mpv/string) +(define mpv/fourcc? mpv/string?) + +;;; No way to validate. +(define serialize-mpv/image-format serialize-mpv/string) +(define mpv/image-format? mpv/string?) + +;;; Looking at the documentation for --start, there is no way to make this +;;; bullet-proof, especially since even chapter numbers are accepted. +(define serialize-mpv/relative-time-or-percent-position serialize-mpv/string) +(define mpv/relative-time-or-percent-position? mpv/string?) + +(define serialize-mpv/time serialize-mpv/string) +(define mpv/time? mpv/string?) + +(define serialize-mpv/video-rectangle serialize-mpv/string) +(define (mpv/video-rectangle? value) + (or (string-match "-?[0-9]+%?:-?[0-9]+%?" value) + (string-match + "^(-?[0-9]+%?(x-?[0-9]+%?)?)?([+-]-?[0-9]+%?[+-]-?[0-9]+%?)?$" + value))) + +(define serialize-mpv/window-geometry serialize-mpv/string) +(define (mpv/window-geometry? value) + (or (string-match "-?[0-9]+%?:-?[0-9]+%?" value) + (string-match + "^(-?[0-9]+%?(x-?[0-9]+%?)?)?([+-]-?[0-9]+%?[+-]-?[0-9]+%?)?(/[0-9]+)?$" + value))) + +(define serialize-mpv/window-size serialize-mpv/string) +(define (mpv/window-size? value) + (string-match "^([0-9]+%?(x[0-9]+%?)?)?$" value)) + +(define (serialize-mpv/enumeration field-name value) + #~(string-append #$(symbol->string field-name) + "=" + ;; This could be either symbol or (in case of enumerations + ;; with alternate type) anything. So just use `format'. + #$(format #f "~s" value) + "\n")) +(define (mpv/enumeration? value) + ;; There is no general way to check enumerations. The field always has to + ;; define custom sanitizer. + #t) + + + + +;;; +;;; List types. +;;; +(define (serialize-mpv/list-of-string field-name lst) + #~(string-append #$(symbol->string field-name) + "=" + #$(string-join lst ",") + "\n")) +(define (mpv/list-of-string? lst) + (every mpv/string? lst)) + +(define (serialize-mpv/list-of-key-value field-name lst) + #~(string-append #$(symbol->string field-name) + "=" + #$(string-join (map (match-lambda + ((k . v) (format #f "~a=~a" k v))) + lst) + ",") + "\n")) +(define (mpv/list-of-key-value? lst) + (every (match-lambda + (((? string?) . (? string?)) #t) + (_ #f)) + lst)) + +(define serialize-mpv/list-of-object-setting serialize-mpv/list-of-string) +(define mpv/list-of-object-setting? mpv/list-of-string?) + +(define serialize-mpv/list-of-output-verbosity serialize-mpv/list-of-key-value) +(define mpv/list-of-output-verbosity? mpv/list-of-key-value?) + + + + +;;; +;;; Actual configuration record. Contains a lot of generated code. +;;; + +(define-record-type <profile-option> + (make-profile-option name type-check serializer) + profile-option? + (name profile-option-name) + (type-check profile-option-type-check) + (serializer profile-option-serializer)) + +(define %opts (make-hash-table)) + +(define-syntax define-opt + (lambda (x) + (syntax-case x () + ((_ name type extra-checks ...) + (let* ((d/n (syntax->datum #'name)) + (d/t (syntax->datum #'type)) + (d/accessor (string->symbol + (format #f "mpv-profile-configuration-~a" d/n))) + (d/type-check (string->symbol + (format #f "mpv/~a?" d/t))) + (d/serializer (string->symbol + (format #f "serialize-mpv/~a" d/t)))) + (with-syntax + ((kw (datum->syntax x (symbol->keyword d/n))) + (accessor (datum->syntax x d/accessor)) + (type-check (datum->syntax x d/type-check)) + (serializer (datum->syntax x d/serializer)) + (val (datum->syntax x 'val))) + #'(begin + (hashq-set! %opts 'name + (make-profile-option (symbol->string 'name) + (lambda (val) + (and (type-check val) + extra-checks ...)) + serializer)) + (define-public (accessor cfg) + (let ((x (hashq-ref (%mpv-profile-configuration-data cfg) + 'name + %unset-value))) + (if (eq? x %unset-value) + %unset-value + (car x))))))))))) + +;;; Generated by: https://git.wolfsden.cz/guix/tree/etc/update-mpv-configuration +;;; Generated code - START. +(define-opt ab-loop-a time) +(define-opt ab-loop-b time) +(define-opt + ab-loop-count + enumeration + (or (memq val '(inf)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt access-references? boolean) +(define-opt ad string) +(define-opt + ad-lavc-ac3drc + float + (>= val 0) + (<= val 6)) +(define-opt ad-lavc-downmix? boolean) +(define-opt ad-lavc-o list-of-key-value) +(define-opt + ad-lavc-threads + integer + (>= val 0) + (<= val 16)) +(define-opt ad-queue-enable? boolean) +(define-opt + ad-queue-max-bytes + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + ad-queue-max-samples + integer64 + (>= val 0)) +(define-opt ad-queue-max-secs double (>= val 0)) +(define-opt af list-of-object-setting) +(define-opt + audio + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt alang list-of-string) +(define-opt allow-delayed-peak-detect? boolean) +(define-opt + alsa-buffer-time + integer + (>= val 0) + (<= val 2147483647)) +(define-opt alsa-ignore-chmap? boolean) +(define-opt alsa-mixer-device string) +(define-opt + alsa-mixer-index + integer + (>= val 0) + (<= val 99)) +(define-opt alsa-mixer-name string) +(define-opt alsa-non-interleaved? boolean) +(define-opt + alsa-periods + integer + (>= val 0) + (<= val 2147483647)) +(define-opt alsa-resample? boolean) +(define-opt ao list-of-object-setting) +(define-opt ao-null-broken-delay? boolean) +(define-opt ao-null-broken-eof? boolean) +(define-opt + ao-null-buffer + float + (>= val 0) + (<= val 100)) +(define-opt + ao-null-channel-layouts + audio-channels-or-channel-map) +(define-opt ao-null-format audio-format) +(define-opt + ao-null-latency + float + (>= val 0) + (<= val 100)) +(define-opt + ao-null-outburst + integer + (>= val 1) + (<= val 100000)) +(define-opt + ao-null-speed + float + (>= val 0) + (<= val 10000)) +(define-opt ao-null-untimed? boolean) +(define-opt ao-pcm-append? boolean) +(define-opt ao-pcm-file string) +(define-opt ao-pcm-waveheader? boolean) +(define-opt + audio-backward-batch + integer + (>= val 0) + (<= val 1024)) +(define-opt + audio-backward-overlap + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 0) (<= val 1024)))) +(define-opt + audio-buffer + double + (>= val 0) + (<= val 10)) +(define-opt + audio-channels + audio-channels-or-channel-map) +(define-opt audio-client-name string) +(define-opt audio-delay float) +(define-opt audio-demuxer string) +(define-opt audio-device string) +(define-opt + audio-display + enumeration + (memq val '(no embedded-first external-first))) +(define-opt audio-exclusive? boolean) +(define-opt audio-exts list-of-string) +(define-opt audio-fallback-to-null? boolean) +(define-opt + audio-file-auto + enumeration + (memq val '(no exact fuzzy all))) +(define-opt audio-file-paths list-of-string) +(define-opt audio-files list-of-string) +(define-opt audio-format audio-format) +(define-opt audio-normalize-downmix? boolean) +(define-opt audio-pitch-correction? boolean) +(define-opt + audio-resample-cutoff + double + (>= val 0) + (<= val 1)) +(define-opt + audio-resample-filter-size + integer + (>= val 0) + (<= val 32)) +(define-opt audio-resample-linear? boolean) +(define-opt + audio-resample-max-output-size + double) +(define-opt + audio-resample-phase-shift + integer + (>= val 0) + (<= val 30)) +(define-opt + audio-reversal-buffer + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + audio-samplerate + integer + (>= val 0) + (<= val 768000)) +(define-opt audio-spdif string) +(define-opt audio-stream-silence? boolean) +(define-opt audio-swresample-o list-of-key-value) +(define-opt + audio-wait-open + float + (>= val 0) + (<= val 60)) +(define-opt auto-window-resize? boolean) +(define-opt + autocreate-playlist + enumeration + (memq val '(no filter same))) +(define-opt autofit window-size) +(define-opt autofit-larger window-size) +(define-opt autofit-smaller window-size) +(define-opt autoload-files? boolean) +(define-opt + autosync + enumeration + (or (memq val '(no)) + (and (integer? val) (>= val 0) (<= val 10000)))) +(define-opt + background + enumeration + (memq val '(none color tiles))) +(define-opt background-color color) +(define-opt + blend-subtitles + enumeration + (memq val '(no yes video))) +(define-opt bluray-device string) +(define-opt border? boolean) +(define-opt + border-background + enumeration + (memq val '(none color tiles))) +(define-opt + brightness + float + (>= val -100) + (<= val 100)) +(define-opt + cache + enumeration + (memq val '(no auto yes))) +(define-opt cache-on-disk? boolean) +(define-opt cache-pause? boolean) +(define-opt cache-pause-initial? boolean) +(define-opt cache-pause-wait float (>= val 0)) +(define-opt cache-secs double (>= val 0)) +(define-opt cdda-cdtext? boolean) +(define-opt cdda-device string) +(define-opt + cdda-overlap + integer + (>= val 0) + (<= val 75)) +(define-opt + cdda-paranoia + integer + (>= val 0) + (<= val 2)) +(define-opt + cdda-sector-size + integer + (>= val 1) + (<= val 100)) +(define-opt cdda-skip? boolean) +(define-opt cdda-span-a integer) +(define-opt cdda-span-b integer) +(define-opt + cdda-speed + integer + (>= val 1) + (<= val 100)) +(define-opt cdda-toc-offset integer) +(define-opt + chapter-merge-threshold + integer + (>= val 0) + (<= val 10000)) +(define-opt chapter-seek-threshold double) +(define-opt chapters-file string) +(define-opt config? boolean) +(define-opt + container-fps-override + double + (>= val 0)) +(define-opt + contrast + float + (>= val -100) + (<= val 100)) +(define-opt cookies? boolean) +(define-opt cookies-file string) +(define-opt + corner-rounding + float + (>= val 0) + (<= val 1)) +(define-opt correct-downscaling? boolean) +(define-opt correct-pts? boolean) +(define-opt + cover-art-auto + enumeration + (memq val '(no exact fuzzy all))) +(define-opt cover-art-files list-of-string) +(define-opt cover-art-whitelist list-of-string) +(define-opt + cscale + enumeration + (memq val + '(bilinear + bicubic_fast + oversample + spline16 + spline36 + spline64 + sinc + lanczos + ginseng + bicubic + hermite + catmull_rom + mitchell + robidoux + robidouxsharp + box + nearest + triangle + gaussian + jinc + ewa_lanczos + ewa_hanning + ewa_ginseng + ewa_lanczossharp + ewa_lanczos4sharpest + ewa_lanczossoft + haasnsoft + ewa_robidoux + ewa_robidouxsharp + bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx))) +(define-opt + cscale-antiring + float + (>= val 0) + (<= val 1)) +(define-opt cscale-blur float) +(define-opt + cscale-clamp + float + (>= val 0) + (<= val 1)) +(define-opt cscale-param1 float) +(define-opt cscale-param2 float) +(define-opt + cscale-radius + float + (>= val 0.5) + (<= val 16)) +(define-opt + cscale-taper + float + (>= val 0) + (<= val 1)) +(define-opt + cscale-window + enumeration + (memq val + '(bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt cscale-wparam float) +(define-opt + cscale-wtaper + float + (>= val 0) + (<= val 1)) +(define-opt + cursor-autohide + enumeration + (or (memq val '(no always)) + (and (integer? val) (>= val 0) (<= val 30000)))) +(define-opt cursor-autohide-fs-only? boolean) +(define-opt deband? boolean) +(define-opt + deband-grain + float + (>= val 0) + (<= val 4096)) +(define-opt + deband-iterations + integer + (>= val 0) + (<= val 16)) +(define-opt + deband-range + float + (>= val 1) + (<= val 64)) +(define-opt + deband-threshold + float + (>= val 0) + (<= val 4096)) +(define-opt + deinterlace + enumeration + (memq val '(no yes auto))) +(define-opt + deinterlace-field-parity + enumeration + (memq val '(tff bff auto))) +(define-opt demuxer string) +(define-opt + demuxer-backward-playback-step + double + (>= val 0)) +(define-opt demuxer-cache-dir string) +(define-opt + demuxer-cache-unlink-files + enumeration + (memq val '(immediate whendone no))) +(define-opt demuxer-cache-wait? boolean) +(define-opt demuxer-donate-buffer? boolean) +(define-opt + demuxer-hysteresis-secs + double + (>= val 0)) +(define-opt demuxer-lavf-allow-mimetype? boolean) +(define-opt + demuxer-lavf-analyzeduration + float + (>= val 0) + (<= val 3600)) +(define-opt + demuxer-lavf-buffersize + integer + (>= val 1) + (<= val 10485760)) +(define-opt demuxer-lavf-format string) +(define-opt demuxer-lavf-hacks? boolean) +(define-opt + demuxer-lavf-linearize-timestamps + enumeration + (memq val '(no auto yes))) +(define-opt demuxer-lavf-o list-of-key-value) +(define-opt + demuxer-lavf-probe-info + enumeration + (memq val '(no yes auto nostreams))) +(define-opt + demuxer-lavf-probescore + integer + (>= val 1) + (<= val 100)) +(define-opt + demuxer-lavf-probesize + integer + (>= val 32) + (<= val 2147483647)) +(define-opt demuxer-lavf-propagate-opts? boolean) +(define-opt + demuxer-max-back-bytes + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + demuxer-max-bytes + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + demuxer-mkv-probe-start-time? + boolean) +(define-opt + demuxer-mkv-probe-video-duration + enumeration + (memq val '(no yes full))) +(define-opt + demuxer-mkv-subtitle-preroll + enumeration + (memq val '(no yes index))) +(define-opt + demuxer-mkv-subtitle-preroll-secs + double + (>= val 0)) +(define-opt + demuxer-mkv-subtitle-preroll-secs-index + double + (>= val 0)) +(define-opt + demuxer-rawaudio-channels + audio-channels-or-channel-map) +(define-opt + demuxer-rawaudio-format + enumeration + (memq val + '(u8 s8 + u16le + u16be + s16le + s16be + u24le + u24be + s24le + s24be + u32le + u32be + s32le + s32be + floatle + floatbe + doublele + doublebe + u16 + s16 + u24 + s24 + u32 + s32 + float + double))) +(define-opt + demuxer-rawaudio-rate + integer + (>= val 1000) + (<= val 384000)) +(define-opt demuxer-rawvideo-codec string) +(define-opt demuxer-rawvideo-format fourcc) +(define-opt + demuxer-rawvideo-fps + float + (>= val 0.001) + (<= val 1000)) +(define-opt + demuxer-rawvideo-h + integer + (>= val 1) + (<= val 8192)) +(define-opt + demuxer-rawvideo-mp-format + image-format) +(define-opt + demuxer-rawvideo-size + integer + (>= val 1) + (<= val 268435456)) +(define-opt + demuxer-rawvideo-w + integer + (>= val 1) + (<= val 8192)) +(define-opt + demuxer-readahead-secs + double + (>= val 0)) +(define-opt + demuxer-seekable-cache + enumeration + (memq val '(auto no yes))) +(define-opt demuxer-termination-timeout double) +(define-opt demuxer-thread? boolean) +(define-opt + directory-filter-types + list-of-string) +(define-opt + directory-mode + enumeration + (memq val '(auto lazy recursive ignore))) +(define-opt + display-fps-override + double + (>= val 0)) +(define-opt display-tags list-of-string) +(define-opt + dither + enumeration + (memq val '(fruit ordered error-diffusion no))) +(define-opt + dither-depth + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val -1) (<= val 16)))) +(define-opt + dither-size-fruit + integer + (>= val 2) + (<= val 8)) +(define-opt + drag-and-drop + enumeration + (memq val '(no auto replace append insert-next))) +(define-opt drm-connector string) +(define-opt drm-device string) +(define-opt + drm-draw-plane + enumeration + (or (memq val '(primary overlay)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt drm-draw-surface-size window-size) +(define-opt + drm-drmprime-video-plane + enumeration + (or (memq val '(primary overlay)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt + drm-format + enumeration + (memq val + '(xrgb8888 xrgb2101010 xbgr8888 xbgr2101010 yuyv))) +(define-opt drm-mode string) +(define-opt + drm-vrr-enabled + enumeration + (memq val '(no yes auto))) +(define-opt + dscale + enumeration + (memq val + '(bilinear + bicubic_fast + oversample + spline16 + spline36 + spline64 + sinc + lanczos + ginseng + bicubic + hermite + catmull_rom + mitchell + robidoux + robidouxsharp + box + nearest + triangle + gaussian + jinc + ewa_lanczos + ewa_hanning + ewa_ginseng + ewa_lanczossharp + ewa_lanczos4sharpest + ewa_lanczossoft + haasnsoft + ewa_robidoux + ewa_robidouxsharp + bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx))) +(define-opt + dscale-antiring + float + (>= val 0) + (<= val 1)) +(define-opt dscale-blur float) +(define-opt + dscale-clamp + float + (>= val 0) + (<= val 1)) +(define-opt dscale-param1 float) +(define-opt dscale-param2 float) +(define-opt + dscale-radius + float + (>= val 0.5) + (<= val 16)) +(define-opt + dscale-taper + float + (>= val 0) + (<= val 1)) +(define-opt + dscale-window + enumeration + (memq val + '(bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt dscale-wparam float) +(define-opt + dscale-wtaper + float + (>= val 0) + (<= val 1)) +(define-opt dump-stats string) +(define-opt + dvbin-card + integer + (>= val 0) + (<= val 15)) +(define-opt dvbin-channel-switch-offset integer) +(define-opt dvbin-file string) +(define-opt dvbin-full-transponder? boolean) +(define-opt dvbin-prog string) +(define-opt + dvbin-timeout + integer + (>= val 1) + (<= val 30)) +(define-opt + dvd-angle + integer + (>= val 1) + (<= val 99)) +(define-opt dvd-device string) +(define-opt dvd-speed integer) +(define-opt + edition + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt egl-config-id integer) +(define-opt + egl-output-format + enumeration + (memq val + '(auto rgb8 + rgba8 + rgb10 + rgb10_a2 + rgb16 + rgba16 + rgb16f + rgba16f + rgb32f + rgba32f))) +(define-opt embeddedfonts? boolean) +(define-opt + end + relative-time-or-percent-position) +(define-opt error-diffusion string) +(define-opt external-files list-of-string) +(define-opt fbo-format string) +(define-opt + focus-on + enumeration + (memq val '(never open all))) +(define-opt force-media-title string) +(define-opt force-render? boolean) +(define-opt force-rgba-osd-rendering? boolean) +(define-opt force-seekable? boolean) +(define-opt + force-window + enumeration + (memq val '(no yes immediate))) +(define-opt force-window-position? boolean) +(define-opt + framedrop + enumeration + (memq val '(no vo decoder decoder+vo))) +(define-opt + frames + enumeration + (or (memq val '(all)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt + fs-screen + enumeration + (or (memq val '(all current)) + (and (integer? val) (>= val 0) (<= val 32)))) +(define-opt fs-screen-name string) +(define-opt fullscreen? boolean) +(define-opt + gamma + float + (>= val -100) + (<= val 100)) +(define-opt gamma-auto? boolean) +(define-opt + gamma-factor + float + (>= val 0.1) + (<= val 2)) +(define-opt + gamut-mapping-mode + enumeration + (memq val + '(auto clip + perceptual + relative + saturation + absolute + desaturate + darken + warn + linear))) +(define-opt + gapless-audio + enumeration + (memq val '(no yes weak))) +(define-opt geometry window-geometry) +(define-opt glsl-shader-opts list-of-key-value) +(define-opt glsl-shaders list-of-string) +(define-opt gpu-api list-of-object-setting) +(define-opt gpu-context list-of-object-setting) +(define-opt gpu-debug? boolean) +(define-opt + gpu-dumb-mode + enumeration + (memq val '(auto yes no))) +(define-opt gpu-hwdec-interop string) +(define-opt gpu-shader-cache? boolean) +(define-opt gpu-shader-cache-dir string) +(define-opt gpu-sw? boolean) +(define-opt + gpu-tex-pad-x + integer + (>= val 0) + (<= val 4096)) +(define-opt + gpu-tex-pad-y + integer + (>= val 0) + (<= val 4096)) +(define-opt + hdr-compute-peak + enumeration + (memq val '(auto yes no))) +(define-opt + hdr-contrast-recovery + float + (>= val 0) + (<= val 2)) +(define-opt + hdr-contrast-smoothness + float + (>= val 1) + (<= val 100)) +(define-opt + hdr-peak-decay-rate + float + (>= val 0) + (<= val 1000)) +(define-opt + hdr-peak-percentile + float + (>= val 0) + (<= val 100)) +(define-opt + hdr-scene-threshold-high + float + (>= val 0) + (<= val 20)) +(define-opt + hdr-scene-threshold-low + float + (>= val 0) + (<= val 20)) +(define-opt hidpi-window-scale? boolean) +(define-opt + hls-bitrate + enumeration + (or (memq val '(no min max)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt + hr-seek + enumeration + (memq val '(no absolute yes always default))) +(define-opt hr-seek-demuxer-offset float) +(define-opt hr-seek-framedrop? boolean) +(define-opt http-header-fields list-of-string) +(define-opt http-proxy string) +(define-opt hue float (>= val -100) (<= val 100)) +(define-opt hwdec list-of-string) +(define-opt hwdec-codecs string) +(define-opt + hwdec-extra-frames + integer + (>= val 0) + (<= val 256)) +(define-opt hwdec-image-format image-format) +(define-opt icc-3dlut-size string) +(define-opt icc-cache? boolean) +(define-opt icc-cache-dir string) +(define-opt + icc-force-contrast + enumeration + (or (memq val '(no inf)) + (and (integer? val) (>= val 0) (<= val 1000000)))) +(define-opt icc-intent integer) +(define-opt icc-profile string) +(define-opt icc-profile-auto? boolean) +(define-opt icc-use-luma? boolean) +(define-opt + idle + enumeration + (memq val '(no once yes))) +(define-opt + ignore-path-in-watch-later-config? + boolean) +(define-opt + image-display-duration + double + (>= val 0)) +(define-opt image-exts list-of-string) +(define-opt image-lut string) +(define-opt + image-lut-type + enumeration + (memq val '(auto native normalized conversion))) +(define-opt image-subs-video-resolution? boolean) +(define-opt include string) +(define-opt + index + enumeration + (memq val '(default recreate))) +(define-opt initial-audio-sync? boolean) +(define-opt input-ar-delay integer) +(define-opt input-ar-rate integer) +(define-opt input-builtin-bindings? boolean) +(define-opt input-builtin-dragging? boolean) +(define-opt input-commands list-of-string) +(define-opt input-conf string) +(define-opt input-cursor? boolean) +(define-opt input-cursor-passthrough? boolean) +(define-opt input-default-bindings? boolean) +(define-opt + input-doubleclick-time + integer + (>= val 0) + (<= val 1000)) +(define-opt input-dragging-deadzone integer) +(define-opt input-ipc-client string) +(define-opt input-ipc-server string) +(define-opt + input-key-fifo-size + integer + (>= val 2) + (<= val 65000)) +(define-opt input-media-keys? boolean) +(define-opt input-preprocess-wheel? boolean) +(define-opt input-right-alt-gr? boolean) +(define-opt input-terminal? boolean) +(define-opt input-test? boolean) +(define-opt input-touch-emulate-mouse? boolean) +(define-opt input-vo-keyboard? boolean) +(define-opt interpolation? boolean) +(define-opt interpolation-preserve? boolean) +(define-opt interpolation-threshold float) +(define-opt inverse-tone-mapping? boolean) +(define-opt jack-autostart? boolean) +(define-opt jack-connect? boolean) +(define-opt jack-name string) +(define-opt jack-port string) +(define-opt + jack-std-channel-layout + enumeration + (memq val '(waveext any))) +(define-opt + keep-open + enumeration + (memq val '(no yes always))) +(define-opt keep-open-pause? boolean) +(define-opt keepaspect? boolean) +(define-opt keepaspect-window? boolean) +(define-opt lavfi-complex string) +(define-opt + length + relative-time-or-percent-position) +(define-opt libplacebo-opts list-of-key-value) +(define-opt linear-downscaling? boolean) +(define-opt linear-upscaling? boolean) +(define-opt + load-auto-profiles + enumeration + (memq val '(no yes auto))) +(define-opt load-osd-console? boolean) +(define-opt load-scripts? boolean) +(define-opt load-select? boolean) +(define-opt load-stats-overlay? boolean) +(define-opt load-unsafe-playlists? boolean) +(define-opt log-file string) +(define-opt + loop-file + enumeration + (or (memq val '(no inf yes)) + (and (integer? val) (>= val 0) (<= val 10000)))) +(define-opt + loop-playlist + enumeration + (or (memq val '(no inf yes force)) + (and (integer? val) (>= val 1) (<= val 10000)))) +(define-opt lut string) +(define-opt + lut-type + enumeration + (memq val '(auto native normalized conversion))) +(define-opt mc float (>= val 0) (<= val 100)) +(define-opt + media-controls + enumeration + (memq val '(no player yes))) +(define-opt merge-files? boolean) +(define-opt metadata-codepage string) +(define-opt mf-fps double) +(define-opt mf-type string) +(define-opt + monitoraspect + float + (>= val 0) + (<= val 9)) +(define-opt + monitorpixelaspect + float + (>= val 0.03125) + (<= val 32)) +(define-opt msg-color? boolean) +(define-opt msg-level list-of-output-verbosity) +(define-opt msg-module? boolean) +(define-opt msg-time? boolean) +(define-opt mute? boolean) +(define-opt native-fs? boolean) +(define-opt native-keyrepeat? boolean) +(define-opt native-touch? boolean) +(define-opt network-timeout double (>= val 0)) +(define-opt oac string) +(define-opt oacopts list-of-key-value) +(define-opt ocopy-metadata? boolean) +(define-opt of string) +(define-opt ofopts list-of-key-value) +(define-opt on-all-workspaces? boolean) +(define-opt ontop? boolean) +(define-opt + ontop-level + enumeration + (or (memq val '(window system desktop)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt opengl-check-pattern-a integer) +(define-opt opengl-check-pattern-b integer) +(define-opt + opengl-early-flush + enumeration + (memq val '(no yes auto))) +(define-opt + opengl-es + enumeration + (memq val '(auto yes no))) +(define-opt opengl-glfinish? boolean) +(define-opt opengl-pbo? boolean) +(define-opt opengl-rectangle-textures? boolean) +(define-opt opengl-swapinterval integer) +(define-opt opengl-waitvsync? boolean) +(define-opt orawts? boolean) +(define-opt ordered-chapters? boolean) +(define-opt ordered-chapters-files string) +(define-opt oremove-metadata list-of-string) +(define-opt osc? boolean) +(define-opt + osd-align-x + enumeration + (memq val '(left center right))) +(define-opt + osd-align-y + enumeration + (memq val '(top center bottom))) +(define-opt osd-back-color color) +(define-opt osd-bar? boolean) +(define-opt + osd-bar-align-x + float + (>= val -1) + (<= val 1)) +(define-opt + osd-bar-align-y + float + (>= val -1) + (<= val 1)) +(define-opt + osd-bar-h + float + (>= val 0.1) + (<= val 50)) +(define-opt + osd-bar-outline-size + float + (>= val 0) + (<= val 1000)) +(define-opt + osd-bar-w + float + (>= val 1) + (<= val 100)) +(define-opt + osd-blur + float + (>= val 0) + (<= val 20)) +(define-opt osd-bold? boolean) +(define-opt + osd-border-style + enumeration + (memq val + '(outline-and-shadow opaque-box background-box))) +(define-opt osd-color color) +(define-opt + osd-duration + integer + (>= val 0) + (<= val 3600000)) +(define-opt osd-font string) +(define-opt + osd-font-provider + enumeration + (memq val '(auto none fontconfig))) +(define-opt + osd-font-size + float + (>= val 1) + (<= val 9000)) +(define-opt osd-fonts-dir string) +(define-opt osd-fractions? boolean) +(define-opt osd-italic? boolean) +(define-opt + osd-justify + enumeration + (memq val '(auto left center right))) +(define-opt + osd-level + enumeration + (memq val '(#{0}# #{1}# #{2}# #{3}#))) +(define-opt + osd-margin-x + integer + (>= val 0) + (<= val 300)) +(define-opt + osd-margin-y + integer + (>= val 0) + (<= val 600)) +(define-opt osd-msg1 string) +(define-opt osd-msg2 string) +(define-opt osd-msg3 string) +(define-opt + osd-on-seek + enumeration + (memq val '(no bar msg msg-bar))) +(define-opt osd-outline-color color) +(define-opt osd-outline-size float) +(define-opt osd-playing-msg string) +(define-opt + osd-playing-msg-duration + integer + (>= val 0) + (<= val 3600000)) +(define-opt + osd-playlist-entry + enumeration + (memq val '(title filename both))) +(define-opt + osd-scale + float + (>= val 0) + (<= val 100)) +(define-opt osd-scale-by-window? boolean) +(define-opt osd-shadow-offset float) +(define-opt + osd-spacing + float + (>= val -10) + (<= val 10)) +(define-opt osd-status-msg string) +(define-opt oset-metadata list-of-key-value) +(define-opt ovc string) +(define-opt ovcopts list-of-key-value) +(define-opt panscan float (>= val 0) (<= val 1)) +(define-opt pause? boolean) +(define-opt + pipewire-buffer + enumeration + (or (memq val '(native)) + (and (integer? val) (>= val 1) (<= val 2000)))) +(define-opt pipewire-remote string) +(define-opt + pipewire-volume-mode + enumeration + (memq val '(channel global))) +(define-opt + pitch + double + (>= val 0.01) + (<= val 100)) +(define-opt + play-direction + enumeration + (memq val '(forward + backward -))) +(define-opt + player-operation-mode + enumeration + (memq val '(cplayer pseudo-gui))) +(define-opt + playlist-start + enumeration + (or (memq val '(auto no)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt prefetch-playlist? boolean) +(define-opt profile list-of-string) +(define-opt pulse-allow-suspended? boolean) +(define-opt + pulse-buffer + enumeration + (or (memq val '(native)) + (and (integer? val) (>= val 1) (<= val 2000)))) +(define-opt pulse-host string) +(define-opt pulse-latency-hacks? boolean) +(define-opt quiet? boolean) +(define-opt really-quiet? boolean) +(define-opt rebase-start-time? boolean) +(define-opt referrer string) +(define-opt + replaygain + enumeration + (memq val '(no track album))) +(define-opt replaygain-clip? boolean) +(define-opt + replaygain-fallback + float + (>= val -200) + (<= val 60)) +(define-opt + replaygain-preamp + float + (>= val -150) + (<= val 150)) +(define-opt reset-on-next-file list-of-string) +(define-opt resume-playback? boolean) +(define-opt resume-playback-check-mtime? boolean) +(define-opt + rtsp-transport + enumeration + (memq val '(lavf udp tcp http udp_multicast))) +(define-opt + saturation + float + (>= val -100) + (<= val 100)) +(define-opt save-position-on-quit? boolean) +(define-opt + scale + enumeration + (memq val + '(bilinear + bicubic_fast + oversample + spline16 + spline36 + spline64 + sinc + lanczos + ginseng + bicubic + hermite + catmull_rom + mitchell + robidoux + robidouxsharp + box + nearest + triangle + gaussian + jinc + ewa_lanczos + ewa_hanning + ewa_ginseng + ewa_lanczossharp + ewa_lanczos4sharpest + ewa_lanczossoft + haasnsoft + ewa_robidoux + ewa_robidouxsharp + bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx))) +(define-opt + scale-antiring + float + (>= val 0) + (<= val 1)) +(define-opt scale-blur float) +(define-opt + scale-clamp + float + (>= val 0) + (<= val 1)) +(define-opt scale-param1 float) +(define-opt scale-param2 float) +(define-opt + scale-radius + float + (>= val 0.5) + (<= val 16)) +(define-opt + scale-taper + float + (>= val 0) + (<= val 1)) +(define-opt + scale-window + enumeration + (memq val + '(bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt scale-wparam float) +(define-opt + scale-wtaper + float + (>= val 0) + (<= val 1)) +(define-opt scaler-resizes-only? boolean) +(define-opt + screen + enumeration + (or (memq val '(default)) + (and (integer? val) (>= val 0) (<= val 32)))) +(define-opt screen-name string) +(define-opt screenshot-avif-encoder string) +(define-opt + screenshot-avif-opts + list-of-key-value) +(define-opt screenshot-avif-pixfmt string) +(define-opt screenshot-directory string) +(define-opt + screenshot-format + enumeration + (memq val '(jpg jpeg png webp jxl avif))) +(define-opt screenshot-high-bit-depth? boolean) +(define-opt + screenshot-jpeg-quality + integer + (>= val 0) + (<= val 100)) +(define-opt + screenshot-jpeg-source-chroma? + boolean) +(define-opt + screenshot-jxl-distance + double + (>= val 0) + (<= val 15)) +(define-opt + screenshot-jxl-effort + integer + (>= val 1) + (<= val 9)) +(define-opt + screenshot-png-compression + integer + (>= val 0) + (<= val 9)) +(define-opt + screenshot-png-filter + integer + (>= val 0) + (<= val 5)) +(define-opt screenshot-sw? boolean) +(define-opt screenshot-tag-colorspace? boolean) +(define-opt screenshot-template string) +(define-opt + screenshot-webp-compression + integer + (>= val 0) + (<= val 6)) +(define-opt screenshot-webp-lossless? boolean) +(define-opt + screenshot-webp-quality + integer + (>= val 0) + (<= val 100)) +(define-opt script-opts list-of-key-value) +(define-opt scripts list-of-string) +(define-opt + secondary-sid + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt + secondary-sub-ass-override + enumeration + (memq val '(no yes scale force strip))) +(define-opt secondary-sub-delay float) +(define-opt + secondary-sub-pos + float + (>= val 0) + (<= val 150)) +(define-opt secondary-sub-visibility? boolean) +(define-opt sharpen float) +(define-opt show-in-taskbar? boolean) +(define-opt shuffle? boolean) +(define-opt + sub + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt + sigmoid-center + float + (>= val 0) + (<= val 1)) +(define-opt + sigmoid-slope + float + (>= val 1) + (<= val 20)) +(define-opt sigmoid-upscaling? boolean) +(define-opt slang list-of-string) +(define-opt snap-window? boolean) +(define-opt + speed + double + (>= val 0.01) + (<= val 100)) +(define-opt + spirv-compiler + enumeration + (memq val '(auto))) +(define-opt sstep double (>= val 0)) +(define-opt + start + relative-time-or-percent-position) +(define-opt + stop-playback-on-init-failure? + boolean) +(define-opt + stop-screensaver + enumeration + (memq val '(no yes always))) +(define-opt + stream-buffer-size + byte-size + (>= val 4096) + (<= val 536870912)) +(define-opt stream-dump string) +(define-opt stream-lavf-o list-of-key-value) +(define-opt stream-record string) +(define-opt stretch-dvd-subs? boolean) +(define-opt + stretch-image-subs-to-screen? + boolean) +(define-opt + sub-align-x + enumeration + (memq val '(left center right))) +(define-opt + sub-align-y + enumeration + (memq val '(top center bottom))) +(define-opt sub-ass? boolean) +(define-opt sub-ass-force-margins? boolean) +(define-opt + sub-ass-hinting + enumeration + (memq val '(none light normal native))) +(define-opt sub-ass-justify? boolean) +(define-opt + sub-ass-line-spacing + float + (>= val -1000) + (<= val 1000)) +(define-opt + sub-ass-override + enumeration + (memq val '(no yes scale force strip))) +(define-opt sub-ass-scale-with-window? boolean) +(define-opt + sub-ass-shaper + enumeration + (memq val '(simple complex))) +(define-opt + sub-ass-style-overrides + list-of-string) +(define-opt sub-ass-styles string) +(define-opt + sub-ass-use-video-data + enumeration + (memq val '(none aspect-ratio all))) +(define-opt + sub-ass-video-aspect-override + aspect + (>= val 0) + (<= val 10)) +(define-opt + sub-ass-vsfilter-color-compat + enumeration + (memq val '(no basic full force-601))) +(define-opt + sub-auto + enumeration + (memq val '(no exact fuzzy all))) +(define-opt sub-auto-exts list-of-string) +(define-opt sub-back-color color) +(define-opt + sub-blur + float + (>= val 0) + (<= val 20)) +(define-opt sub-bold? boolean) +(define-opt + sub-border-style + enumeration + (memq val + '(outline-and-shadow opaque-box background-box))) +(define-opt sub-clear-on-seek? boolean) +(define-opt sub-codepage string) +(define-opt sub-color color) +(define-opt sub-create-cc-track? boolean) +(define-opt sub-delay float) +(define-opt sub-demuxer string) +(define-opt sub-file-paths list-of-string) +(define-opt sub-files list-of-string) +(define-opt sub-filter-jsre list-of-string) +(define-opt sub-filter-regex list-of-string) +(define-opt sub-filter-regex-enable? boolean) +(define-opt sub-filter-regex-plain? boolean) +(define-opt sub-filter-regex-warn? boolean) +(define-opt sub-filter-sdh? boolean) +(define-opt sub-filter-sdh-enclosures string) +(define-opt sub-filter-sdh-harder? boolean) +(define-opt sub-fix-timing? boolean) +(define-opt sub-font string) +(define-opt + sub-font-provider + enumeration + (memq val '(auto none fontconfig))) +(define-opt + sub-font-size + float + (>= val 1) + (<= val 9000)) +(define-opt sub-fonts-dir string) +(define-opt sub-forced-events-only? boolean) +(define-opt sub-fps float) +(define-opt + sub-gauss + float + (>= val 0) + (<= val 3)) +(define-opt sub-gray? boolean) +(define-opt sub-italic? boolean) +(define-opt + sub-justify + enumeration + (memq val '(auto left center right))) +(define-opt sub-lavc-o list-of-key-value) +(define-opt + sub-margin-x + integer + (>= val 0) + (<= val 300)) +(define-opt + sub-margin-y + integer + (>= val 0) + (<= val 600)) +(define-opt sub-outline-color color) +(define-opt sub-outline-size float) +(define-opt sub-past-video-end? boolean) +(define-opt + sub-pos + float + (>= val 0) + (<= val 150)) +(define-opt + sub-scale + float + (>= val 0) + (<= val 100)) +(define-opt sub-scale-by-window? boolean) +(define-opt sub-scale-with-window? boolean) +(define-opt sub-shadow-offset float) +(define-opt + sub-spacing + float + (>= val -10) + (<= val 10)) +(define-opt sub-speed float) +(define-opt sub-stretch-durations? boolean) +(define-opt sub-use-margins? boolean) +(define-opt sub-visibility? boolean) +(define-opt sub-vsfilter-bidi-compat? boolean) +(define-opt + subs-fallback + enumeration + (memq val '(no default yes))) +(define-opt + subs-fallback-forced + enumeration + (memq val '(no yes always))) +(define-opt subs-match-os-language? boolean) +(define-opt + subs-with-matching-audio + enumeration + (memq val '(no forced yes))) +(define-opt + swapchain-depth + integer + (>= val 1) + (<= val 8)) +(define-opt sws-allow-zimg? boolean) +(define-opt sws-bitexact? boolean) +(define-opt + sws-cgb + float + (>= val 0) + (<= val 100)) +(define-opt sws-chs integer) +(define-opt + sws-cs + float + (>= val -100) + (<= val 100)) +(define-opt sws-cvs integer) +(define-opt sws-fast? boolean) +(define-opt + sws-lgb + float + (>= val 0) + (<= val 100)) +(define-opt + sws-ls + float + (>= val -100) + (<= val 100)) +(define-opt + sws-scaler + enumeration + (memq val + '(fast-bilinear + bilinear + bicubic + x + point + area + bicublin + gauss + sinc + lanczos + spline))) +(define-opt target-colorspace-hint? boolean) +(define-opt + target-contrast + enumeration + (or (memq val '(auto inf)) + (and (integer? val) (>= val 10) (<= val 1000000)))) +(define-opt + target-gamut + enumeration + (memq val + '(auto bt.601-525 + bt.601-625 + bt.709 + bt.2020 + bt.470m + apple + adobe + prophoto + cie1931 + dci-p3 + display-p3 + v-gamut + s-gamut + ebu3213 + film-c + aces-ap0 + aces-ap1))) +(define-opt target-lut string) +(define-opt + target-peak + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 10) (<= val 10000)))) +(define-opt + target-prim + enumeration + (memq val + '(auto bt.601-525 + bt.601-625 + bt.709 + bt.2020 + bt.470m + apple + adobe + prophoto + cie1931 + dci-p3 + display-p3 + v-gamut + s-gamut + ebu3213 + film-c + aces-ap0 + aces-ap1))) +(define-opt + target-trc + enumeration + (memq val + '(auto bt.1886 + srgb + linear + gamma1.8 + gamma2.0 + gamma2.2 + gamma2.4 + gamma2.6 + gamma2.8 + prophoto + pq + hlg + v-log + s-log1 + s-log2 + st428))) +(define-opt taskbar-progress? boolean) +(define-opt + teletext-page + integer + (>= val -1) + (<= val 999)) +(define-opt temporal-dither? boolean) +(define-opt + temporal-dither-period + integer + (>= val 1) + (<= val 128)) +(define-opt + term-osd + enumeration + (memq val '(force auto no))) +(define-opt term-osd-bar? boolean) +(define-opt term-osd-bar-chars string) +(define-opt term-playing-msg string) +(define-opt term-status-msg string) +(define-opt term-title string) +(define-opt terminal? boolean) +(define-opt title string) +(define-opt title-bar? boolean) +(define-opt tls-ca-file string) +(define-opt tls-cert-file string) +(define-opt tls-key-file string) +(define-opt tls-verify? boolean) +(define-opt + tone-mapping + enumeration + (memq val + '(auto clip + mobius + reinhard + hable + gamma + linear + spline + bt.2390 + bt.2446a + st2094-40 + st2094-10))) +(define-opt + tone-mapping-max-boost + float + (>= val 1) + (<= val 10)) +(define-opt tone-mapping-param float) +(define-opt tone-mapping-visualize? boolean) +(define-opt track-auto-selection? boolean) +(define-opt + tscale + enumeration + (memq val + '(oversample + linear + spline16 + spline36 + spline64 + sinc + lanczos + ginseng + bicubic + hermite + catmull_rom + mitchell + robidoux + robidouxsharp + box + nearest + triangle + gaussian + bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt + tscale-antiring + float + (>= val 0) + (<= val 1)) +(define-opt tscale-blur float) +(define-opt + tscale-clamp + float + (>= val 0) + (<= val 1)) +(define-opt tscale-param1 float) +(define-opt tscale-param2 float) +(define-opt + tscale-radius + float + (>= val 0.5) + (<= val 16)) +(define-opt + tscale-taper + float + (>= val 0) + (<= val 1)) +(define-opt + tscale-window + enumeration + (memq val + '(bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt tscale-wparam float) +(define-opt + tscale-wtaper + float + (>= val 0) + (<= val 1)) +(define-opt untimed? boolean) +(define-opt use-embedded-icc-profile? boolean) +(define-opt use-filedir-conf? boolean) +(define-opt user-agent string) +(define-opt vaapi-device string) +(define-opt vd string) +(define-opt vd-apply-cropping? boolean) +(define-opt vd-lavc-assume-old-x264? boolean) +(define-opt vd-lavc-bitexact? boolean) +(define-opt vd-lavc-check-hw-profile? boolean) +(define-opt + vd-lavc-dr + enumeration + (memq val '(auto no yes))) +(define-opt vd-lavc-fast? boolean) +(define-opt + vd-lavc-film-grain + enumeration + (memq val '(auto cpu gpu))) +(define-opt + vd-lavc-framedrop + enumeration + (memq val + '(none default nonref bidir nonkey all))) +(define-opt vd-lavc-o list-of-key-value) +(define-opt vd-lavc-show-all? boolean) +(define-opt + vd-lavc-skipframe + enumeration + (memq val + '(none default nonref bidir nonkey all))) +(define-opt + vd-lavc-skipidct + enumeration + (memq val + '(none default nonref bidir nonkey all))) +(define-opt + vd-lavc-skiploopfilter + enumeration + (memq val + '(none default nonref bidir nonkey all))) +(define-opt + vd-lavc-software-fallback + enumeration + (or (memq val '(no yes)) + (and (integer? val) + (>= val 1) + (<= val 2147483647)))) +(define-opt vd-lavc-threads integer (>= val 0)) +(define-opt vd-queue-enable? boolean) +(define-opt + vd-queue-max-bytes + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + vd-queue-max-samples + integer64 + (>= val 0)) +(define-opt vd-queue-max-secs double (>= val 0)) +(define-opt vf list-of-object-setting) +(define-opt + video + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt + video-align-x + float + (>= val -1) + (<= val 1)) +(define-opt + video-align-y + float + (>= val -1) + (<= val 1)) +(define-opt + video-aspect-method + enumeration + (memq val '(bitstream container))) +(define-opt + video-aspect-override + aspect + (>= val -1) + (<= val 10)) +(define-opt + video-backward-batch + integer + (>= val 0) + (<= val 1024)) +(define-opt + video-backward-overlap + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 0) (<= val 1024)))) +(define-opt video-crop video-rectangle) +(define-opt video-exts list-of-string) +(define-opt video-latency-hacks? boolean) +(define-opt + video-margin-ratio-bottom + float + (>= val 0) + (<= val 1)) +(define-opt + video-margin-ratio-left + float + (>= val 0) + (<= val 1)) +(define-opt + video-margin-ratio-right + float + (>= val 0) + (<= val 1)) +(define-opt + video-margin-ratio-top + float + (>= val 0) + (<= val 1)) +(define-opt video-osd? boolean) +(define-opt + video-output-levels + enumeration + (memq val '(auto limited full))) +(define-opt video-pan-x float) +(define-opt video-pan-y float) +(define-opt + video-reversal-buffer + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + video-rotate + enumeration + (or (memq val '(no)) + (and (integer? val) (>= val 0) (<= val 359)))) +(define-opt + video-scale-x + float + (>= val 0) + (<= val 10000)) +(define-opt + video-scale-y + float + (>= val 0) + (<= val 10000)) +(define-opt + video-sync + enumeration + (memq val + '(audio display-resample + display-resample-vdrop + display-resample-desync + display-tempo + display-adrop + display-vdrop + display-desync + desync))) +(define-opt + video-sync-max-audio-change + double + (>= val 0) + (<= val 1)) +(define-opt + video-sync-max-factor + integer + (>= val 1) + (<= val 10)) +(define-opt + video-sync-max-video-change + double + (>= val 0)) +(define-opt + video-timing-offset + double + (>= val 0) + (<= val 1)) +(define-opt + video-unscaled + enumeration + (memq val '(no yes downscale-big))) +(define-opt + video-zoom + float + (>= val -20) + (<= val 20)) +(define-opt vlang list-of-string) +(define-opt vo list-of-object-setting) +(define-opt vo-image-avif-encoder string) +(define-opt vo-image-avif-opts list-of-key-value) +(define-opt vo-image-avif-pixfmt string) +(define-opt + vo-image-format + enumeration + (memq val '(jpg jpeg png webp jxl avif))) +(define-opt vo-image-high-bit-depth? boolean) +(define-opt + vo-image-jpeg-quality + integer + (>= val 0) + (<= val 100)) +(define-opt vo-image-jpeg-source-chroma? boolean) +(define-opt + vo-image-jxl-distance + double + (>= val 0) + (<= val 15)) +(define-opt + vo-image-jxl-effort + integer + (>= val 1) + (<= val 9)) +(define-opt vo-image-outdir string) +(define-opt + vo-image-png-compression + integer + (>= val 0) + (<= val 9)) +(define-opt + vo-image-png-filter + integer + (>= val 0) + (<= val 5)) +(define-opt vo-image-tag-colorspace? boolean) +(define-opt + vo-image-webp-compression + integer + (>= val 0) + (<= val 6)) +(define-opt vo-image-webp-lossless? boolean) +(define-opt + vo-image-webp-quality + integer + (>= val 0) + (<= val 100)) +(define-opt vo-kitty-alt-screen? boolean) +(define-opt vo-kitty-cols integer) +(define-opt vo-kitty-config-clear? boolean) +(define-opt vo-kitty-height integer) +(define-opt vo-kitty-left integer) +(define-opt vo-kitty-rows integer) +(define-opt vo-kitty-top integer) +(define-opt vo-kitty-use-shm? boolean) +(define-opt vo-kitty-width integer) +(define-opt + vo-null-fps + double + (>= val 0) + (<= val 10000)) +(define-opt vo-sixel-alt-screen? boolean) +(define-opt vo-sixel-buffered? boolean) +(define-opt vo-sixel-cols integer) +(define-opt vo-sixel-config-clear? boolean) +(define-opt + vo-sixel-dither + enumeration + (memq val + '(auto none + atkinson + fs + jajuni + stucki + burkes + arithmetic + xor))) +(define-opt vo-sixel-fixedpalette? boolean) +(define-opt vo-sixel-height integer) +(define-opt vo-sixel-left integer) +(define-opt vo-sixel-pad-x integer) +(define-opt vo-sixel-pad-y integer) +(define-opt vo-sixel-reqcolors integer) +(define-opt vo-sixel-rows integer) +(define-opt vo-sixel-threshold integer) +(define-opt vo-sixel-top integer) +(define-opt vo-sixel-width integer) +(define-opt vo-tct-256? boolean) +(define-opt + vo-tct-algo + enumeration + (memq val '(plain half-blocks))) +(define-opt + vo-tct-buffering + enumeration + (memq val '(pixel line frame))) +(define-opt vo-tct-height integer) +(define-opt vo-tct-width integer) +(define-opt vo-vaapi-scaled-osd? boolean) +(define-opt + vo-vaapi-scaling + enumeration + (memq val '(default fast hq nla))) +(define-opt vo-vdpau-chroma-deint? boolean) +(define-opt vo-vdpau-colorkey color) +(define-opt vo-vdpau-composite-detect? boolean) +(define-opt + vo-vdpau-denoise + float + (>= val 0) + (<= val 1)) +(define-opt vo-vdpau-force-yuv? boolean) +(define-opt vo-vdpau-fps double) +(define-opt + vo-vdpau-hqscaling + integer + (>= val 0) + (<= val 9)) +(define-opt + vo-vdpau-output-surfaces + integer + (>= val 2) + (<= val 15)) +(define-opt vo-vdpau-pullup? boolean) +(define-opt vo-vdpau-queuetime-fs integer) +(define-opt vo-vdpau-queuetime-windowed integer) +(define-opt + vo-vdpau-sharpen + float + (>= val -1) + (<= val 1)) +(define-opt + volume + float + (>= val -1) + (<= val 1000)) +(define-opt + volume-gain + float + (>= val -150) + (<= val 150)) +(define-opt + volume-gain-max + float + (>= val 0) + (<= val 150)) +(define-opt + volume-gain-min + float + (>= val -150) + (<= val 0)) +(define-opt + volume-max + float + (>= val 100) + (<= val 1000)) +(define-opt vulkan-async-compute? boolean) +(define-opt vulkan-async-transfer? boolean) +(define-opt vulkan-device string) +(define-opt vulkan-display-display integer) +(define-opt vulkan-display-mode integer) +(define-opt vulkan-display-plane integer) +(define-opt + vulkan-queue-count + integer + (>= val 1) + (<= val 8)) +(define-opt + vulkan-swap-mode + enumeration + (memq val + '(auto fifo fifo-relaxed mailbox immediate))) +(define-opt watch-later-directory string) +(define-opt watch-later-options list-of-string) +(define-opt wayland-app-id string) +(define-opt + wayland-configure-bounds + enumeration + (memq val '(auto no yes))) +(define-opt + wayland-content-type + enumeration + (memq val '(auto none photo video game))) +(define-opt wayland-disable-vsync? boolean) +(define-opt + wayland-edge-pixels-pointer + integer + (>= val 0) + (<= val 2147483647)) +(define-opt + wayland-edge-pixels-touch + integer + (>= val 0) + (<= val 2147483647)) +(define-opt wayland-present? boolean) +(define-opt wid integer64) +(define-opt window-dragging? boolean) +(define-opt window-maximized? boolean) +(define-opt window-minimized? boolean) +(define-opt + window-scale + double + (>= val 0.001) + (<= val 100)) +(define-opt + write-filename-in-watch-later-config? + boolean) +(define-opt + x11-bypass-compositor + enumeration + (memq val '(no yes fs-only never))) +(define-opt x11-name string) +(define-opt + x11-netwm + enumeration + (memq val '(auto no yes))) +(define-opt + x11-present + enumeration + (memq val '(no auto yes))) +(define-opt x11-wid-title? boolean) +(define-opt xv-adaptor integer (>= val -1)) +(define-opt + xv-buffers + integer + (>= val 1) + (<= val 10)) +(define-opt + xv-ck + enumeration + (memq val '(use set cur))) +(define-opt + xv-ck-method + enumeration + (memq val '(none bg man auto))) +(define-opt xv-colorkey integer) +(define-opt xv-port integer (>= val 0)) +(define-opt ytdl? boolean) +(define-opt ytdl-format string) +(define-opt ytdl-raw-options list-of-key-value) +(define-opt + zimg-dither + enumeration + (memq val '(no ordered random error-diffusion))) +(define-opt zimg-fast? boolean) +(define-opt + zimg-scaler + enumeration + (memq val + '(point bilinear + bicubic + spline16 + spline36 + lanczos))) +(define-opt + zimg-scaler-chroma + enumeration + (memq val + '(point bilinear + bicubic + spline16 + spline36 + lanczos))) +(define-opt zimg-scaler-chroma-param-a double) +(define-opt zimg-scaler-chroma-param-b double) +(define-opt zimg-scaler-param-a double) +(define-opt zimg-scaler-param-b double) +(define-opt + zimg-threads + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 1) (<= val 64)))) +;;; Generated code - END. + +(define-record-type <mpv-profile-configuration> + (%make-mpv-profile-configuration data) + mpv-profile-configuration? + (data %mpv-profile-configuration-data)) + +(define (make-mpv-profile-configuration . args) + ;; I am not sure how can I copy a hash-map. Documentation does not mention + ;; anything. + (let ((new (make-hash-table))) + (let loop ((args args)) + (match args + ((#:inherit cfg . tail) + (hash-for-each (lambda (key val) + (hashq-set! new key val)) + (%mpv-profile-configuration-data cfg)) + (loop tail)) + (((? keyword? key) val . tail) + (let* ((key (keyword->symbol key)) + (opt (hashq-ref %opts key))) + (unless opt + (raise-exception + (formatted-message + (G_ "option ~a not found for mpv-profile-configuration") key))) + (if (maybe-value-set? val) + (if ((profile-option-type-check opt) val) + (hashq-set! new key (cons val + (profile-option-serializer opt))) + (raise-exception + (formatted-message + (G_ "invalid mpv configuration for ~a: ~a~%") + key val))) + (hashq-remove! new key))) + (loop tail)) + (() + (%make-mpv-profile-configuration new)))))) + +(define (serialize-mpv-profile-configuration _ cfg) + (let ((sorted (sort + (hash-map->list cons (%mpv-profile-configuration-data cfg)) + (lambda (a b) + (string<? (symbol->string (car a)) + (symbol->string (car b))))))) + #~(string-append + #$@(map (match-lambda + ((field-name . value) + ((cdr value) field-name (car value)))) + sorted)))) + + + + +;;; +;;; Configuration base. +;;; +(define (serialize-mpv/mpv-profile-configurations _ profiles) + #~(string-append + #$@(map (match-lambda + ((name . config) + #~(string-append + #$(format #f "[~a]~%" name) + #$(serialize-mpv-profile-configuration _ config)))) + profiles))) +(define (mpv/mpv-profile-configurations? alist) + (and (list? alist) + (every (match-lambda + (((? symbol?) . (? mpv-profile-configuration?)) #t) + (_ #f)) + alist))) + +(define (serialize-mpv/extra _ value) + (if value + #~(string-append #$value + ;; Ensure the extra content ends in a new line. + #$(if (string-suffix? "\n" value) + "" "\n")) + #~"")) +(define (mpv/extra? val) + (or (string? val) + (gexp? val))) + +(define-record-type <home-mpv-configuration> + (%make-home-mpv-configuration global profiles extra-config) + home-mpv-configuration? + (global home-mpv-configuration-global) + (profiles home-mpv-configuration-profiles) + (extra-config home-mpv-configuration-extra-config)) + +(define* (make-home-mpv-configuration + #:key + (inherit #f) + (global (if inherit + (home-mpv-configuration-global inherit) + (make-mpv-profile-configuration))) + (profiles (if inherit + (home-mpv-configuration-profiles inherit) + '())) + (extra-config (if inherit + (home-mpv-configuration-extra-config inherit) + #f))) + (unless (mpv-profile-configuration? global) + (raise-exception + (formatted-message + (G_ "global must satisfy mpv-profile-configuration?")))) + (unless (mpv/mpv-profile-configurations? profiles) + (raise-exception + (formatted-message + (G_ "profiles must be an alist of mpv-profile-configuration?")))) + (unless (or (not extra-config) (mpv/extra? extra-config)) + (raise-exception + (formatted-message + (G_ "extra-config must be a string or a gexp")))) + (%make-home-mpv-configuration global profiles extra-config)) + +(define (serialize-home-mpv-configuration cfg) + #~(string-append #$(serialize-mpv-profile-configuration + 'global + (home-mpv-configuration-global cfg)) + #$(serialize-mpv/mpv-profile-configurations + 'profiles + (home-mpv-configuration-profiles cfg)) + #$(serialize-mpv/extra + 'extra-config + (home-mpv-configuration-extra-config cfg)))) + +(define (mpv-configuration-files cfg) + `(("mpv/mpv.conf" ,(mixed-text-file "mpv.conf" + (serialize-home-mpv-configuration cfg))))) + +(define home-mpv-service-type + (service-type + (name 'home-mpv) + (extensions + (list (service-extension home-xdg-configuration-files-service-type + mpv-configuration-files))) + (description + "Install configuration files for mpv into XDG configuration directory."))) diff --git a/gnu/local.mk b/gnu/local.mk index e6ece8cc48..d132e79ad2 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -113,6 +113,7 @@ GNU_SYSTEM_MODULES = \ %D%/home/services/mail.scm \ %D%/home/services/media.scm \ %D%/home/services/messaging.scm \ + %D%/home/services/mpv.scm \ %D%/home/services/music.scm \ %D%/home/services/pm.scm \ %D%/home/services/shells.scm \ -- 2.49.0
guix-patches <at> gnu.org
:bug#74801
; Package guix-patches
.
(Fri, 09 May 2025 10:40:03 GMT) Full text and rfc822 format available.Message #38 received at 74801 <at> debbugs.gnu.org (full text, mbox):
From: Tomas Volf <~@wolfsden.cz> To: Ludovic Courtès <ludo <at> gnu.org> Cc: 74801 <at> debbugs.gnu.org Subject: Re: [bug#74801] [PATCH v2] gnu: home: services: Add home-mpv-service-type. Date: Fri, 09 May 2025 12:39:28 +0200
Ludovic Courtès <ludo <at> gnu.org> writes: > [..] > > Well, in that case, maybe just include the URL in the script in the > comment (“Generated by …”). Link included and v3 sent. :) Tomas -- There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors.
guix-patches <at> gnu.org
:bug#74801
; Package guix-patches
.
(Sun, 11 May 2025 02:47:01 GMT) Full text and rfc822 format available.Message #41 received at 74801 <at> debbugs.gnu.org (full text, mbox):
From: Andrew Tropin <andrew <at> trop.in> To: Ludovic Courtès <ludo <at> gnu.org>, Tomas Volf <~@wolfsden.cz> Cc: Tanguy Le Carrour <tanguy <at> bioneland.org>, Maxim Cournoyer <maxim.cournoyer <at> gmail.com>, Gabriel Wicki <gabriel <at> erlikon.ch>, Hilton Chain <hako <at> ultrarare.space>, 74801 <at> debbugs.gnu.org, Janneke Nieuwenhuizen <janneke <at> gnu.org> Subject: Re: [bug#74801] [PATCH v2] gnu: home: services: Add home-mpv-service-type. Date: Sun, 11 May 2025 09:45:59 +0700
[Message part 1 (text/plain, inline)]
On 2025-05-09 10:49, Ludovic Courtès wrote: > Hello, > > Tomas Volf <~@wolfsden.cz> writes: > >> Ludovic Courtès <ludo <at> gnu.org> writes: > > [...] > >>> Could you include the code you used to generate the options? >> >> I definitely *could* do that. While the code is maybe a bit ugly, it is >> not intended to be kept secret. Couple of questions though. >> >> 1. Where should I put it? Somewhere in etc directory? Or next to the >> service, so e.g. gnu/home/services/mpv-refresh.sh? >> >> 2. It has external dependencies, some of which are packaged in Guix >> (emacs, emacs-paredit) and some of them are not (guile-wolfsden). Is >> that a problem? Do I need to rewrite it to use just packaged >> libraries and programs? > > Well, in that case, maybe just include the URL in the script in the > comment (“Generated by …”). > > Had it been pure Scheme (possibly based on (guix read-print) rather than > Emacs), we could have included it straight in the code, as is done for > Dovecot IIRC. Someone updating it could use the relevant procedures at > the REPL to re-generate the option definitions. I would also suggest to keep auto-generated schemas and docs in separate files, so they can be easily re-generated without copy-pasting or other manual interventions. -- Best regards, Andrew Tropin
[signature.asc (application/pgp-signature, inline)]
guix-patches <at> gnu.org
:bug#74801
; Package guix-patches
.
(Sun, 11 May 2025 14:36:02 GMT) Full text and rfc822 format available.Message #44 received at 74801 <at> debbugs.gnu.org (full text, mbox):
From: Tomas Volf <~@wolfsden.cz> To: Andrew Tropin <andrew <at> trop.in> Cc: Ludovic Courtès <ludo <at> gnu.org>, 74801 <at> debbugs.gnu.org Subject: Re: [bug#74801] [PATCH v2] gnu: home: services: Add home-mpv-service-type. Date: Sun, 11 May 2025 16:35:51 +0200
Hi Andrew, Andrew Tropin <andrew <at> trop.in> writes: > I would also suggest to keep auto-generated schemas and docs in separate > files, so they can be easily re-generated without copy-pasting or other > manual interventions. Do not worry, I am a lazy creature, so the updater script takes care of that for you: --8<---------------cut here---------------start------------->8--- $ ./generate-mpv-configuration 0.39 src/guix/gnu/home/services/mpv.scm * Will update to version 0.39 * Will update file src/guix/gnu/home/services/mpv.scm Indenting region... Indenting region...done Mark set * Done. --8<---------------cut here---------------end--------------->8--- This takes care of updating both the mpv.scm file and the list of the options in the manual. No copy&pasting or manual interventions required. All you need to do is commit the result and send the patch. Tomas -- There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors.
guix-patches <at> gnu.org
:bug#74801
; Package guix-patches
.
(Mon, 12 May 2025 04:58:02 GMT) Full text and rfc822 format available.Message #47 received at 74801 <at> debbugs.gnu.org (full text, mbox):
From: Andrew Tropin <andrew <at> trop.in> To: Tomas Volf <~@wolfsden.cz> Cc: Ludovic Courtès <ludo <at> gnu.org>, 74801 <at> debbugs.gnu.org Subject: Re: [bug#74801] [PATCH v2] gnu: home: services: Add home-mpv-service-type. Date: Mon, 12 May 2025 11:56:55 +0700
[Message part 1 (text/plain, inline)]
On 2025-05-11 16:35, Tomas Volf wrote: > Hi Andrew, > > Andrew Tropin <andrew <at> trop.in> writes: > >> I would also suggest to keep auto-generated schemas and docs in separate >> files, so they can be easily re-generated without copy-pasting or other >> manual interventions. > > Do not worry, I am a lazy creature, so the updater script takes care of > that for you: 😄👍 > > --8<---------------cut here---------------start------------->8--- > $ ./generate-mpv-configuration 0.39 src/guix/gnu/home/services/mpv.scm > * Will update to version 0.39 > * Will update file src/guix/gnu/home/services/mpv.scm > Indenting region... > Indenting region...done > Mark set > * Done. > --8<---------------cut here---------------end--------------->8--- > > This takes care of updating both the mpv.scm file and the list of the > options in the manual. No copy&pasting or manual interventions > required. All you need to do is commit the result and send the patch. -- Best regards, Andrew Tropin
[signature.asc (application/pgp-signature, inline)]
guix-patches <at> gnu.org
:bug#74801
; Package guix-patches
.
(Mon, 12 May 2025 07:12:02 GMT) Full text and rfc822 format available.Message #50 received at 74801 <at> debbugs.gnu.org (full text, mbox):
From: Ludovic Courtès <ludo <at> gnu.org> To: Tomas Volf <~@wolfsden.cz> Cc: Tanguy Le Carrour <tanguy <at> bioneland.org>, Maxim Cournoyer <maxim.cournoyer <at> gmail.com>, Gabriel Wicki <gabriel <at> erlikon.ch>, Andrew Tropin <andrew <at> trop.in>, Hilton Chain <hako <at> ultrarare.space>, 74801 <at> debbugs.gnu.org, Janneke Nieuwenhuizen <janneke <at> gnu.org> Subject: Re: bug#74801: [PATCH] gnu: home: services: Add home-mpv-service-type. Date: Mon, 12 May 2025 09:10:58 +0200
Hi, Tomas Volf <~@wolfsden.cz> writes: > This commit adds a new service type to generate configuration file for the mpv > media player. > > * gnu/home/services/mpv.scm: New file. > * gnu/local.mk (GNU_SYSTEM_MODULES): Register it. > * doc/guix.texi (mpv Media Player): Document it. > > Change-Id: I2deb44799a28047cb5d67da97dc6007a9df873af [...] > v3: > - Drop majority of commit message. (I am not sold on this.) > - Use ? suffix for boolean options. > - Include link to the updater script. [...] > + #:global (make-mpv-profile-configuration > + #:fullscreen #t Are we missing a question mark? > + #:profiles `((fullscreen . ,(make-mpv-profile-configuration > + #:fullscreen #t)))) Here also. Otherwise LGTM. Thanks, Ludo’.
andrew <at> trop.in, gabriel <at> erlikon.ch, hako <at> ultrarare.space, janneke <at> gnu.org, ludo <at> gnu.org, maxim.cournoyer <at> gmail.com, tanguy <at> bioneland.org, guix-patches <at> gnu.org
:bug#74801
; Package guix-patches
.
(Mon, 12 May 2025 16:33:02 GMT) Full text and rfc822 format available.Message #53 received at 74801 <at> debbugs.gnu.org (full text, mbox):
From: Tomas Volf <~@wolfsden.cz> To: 74801 <at> debbugs.gnu.org Cc: Tomas Volf <~@wolfsden.cz> Subject: [PATCH v4] gnu: home: services: Add home-mpv-service-type. Date: Mon, 12 May 2025 18:31:21 +0200
This commit adds a new service type to generate configuration file for the mpv media player. Originally I attempted to use Guix Records (via define-configuration) for this, but ran into the bug #74748, so I had to switch to procedures instead. The usage is (hopefully) sufficiently described in the documentation. When the bug is resolved, I will update it to use define-configuration instead. The full list of supported options is documented, however I decided to *not* document types and purpose for each individual fields. While I had mostly working prototype to extract the documentation from mpv, once I realized it would be few 10k of lines added, I decided it is not worth it. It would bloat the .texi file (by more than 50%), be hard to maintain and, in my opinion, would not provide enough value to justify that. The current version seems like sane middle ground. * gnu/home/services/mpv.scm: New file. * gnu/local.mk (GNU_SYSTEM_MODULES): Register it. * doc/guix.texi (mpv Media Player): Document it. Change-Id: I2deb44799a28047cb5d67da97dc6007a9df873af --- v4: - Also add ? into the documentation. doc/guix.texi | 429 ++++++ gnu/home/services/mpv.scm | 2751 +++++++++++++++++++++++++++++++++++++ gnu/local.mk | 1 + 3 files changed, 3181 insertions(+) create mode 100644 gnu/home/services/mpv.scm diff --git a/doc/guix.texi b/doc/guix.texi index 889eab2ab3..ed823073e5 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -50747,6 +50747,435 @@ Media Home Services @end table @end deftp +@c This is ugly, but upstream does *not* capitalize the ``m'' even when +@c at the beginning of a sentence. So let us follow the branding. +@node mpv Media Player +@subsection mpv Media Player + +@cindex mpv, Home Service +@cindex mpv, configuration +Configuring the @uref{https://mpv.io/, mpv media player} can be somewhat +daunting task, due to the sheer amount of options available, especially +if one wants to be able to inherit the configuration in their code. The +@code{home-mpv-service-type} is provided to help with that problem. +When the service is added to your home environment, file based on the +passed configuration is generated and placed into the correct location. + +Due to the bug #74748, it does not use Guix Records to represent the +configuration, but uses keyword arguments to achieve similar result. +Example follows: + +@lisp +(service home-mpv-service-type + (make-home-mpv-configuration + #:global (make-mpv-profile-configuration + #:fullscreen? #t + #:alang '("jpn" "eng")))) +@end lisp + +@defvar home-mpv-service-type +This is the type of the mpv home service, whose value is a +@code{home-mpv-configuration} object. +@end defvar + +@deffn {Procedure} make-home-mpv-configuration +Return a new instance of @code{home-mpv-configuration}. Available +keyword arguments are: + +@table @asis +@item @code{inherit} (default: @code{#t}) +Inherit fields from an another instance. + +@item @code{global} (default: @code{(make-mpv-profile-configuration)}) +The global configuration preceding all profiles. + +@item @code{profiles} (default: @code{()}) +An alist containing configuration for any additional profiles to include +in the configuration file. + +@lisp +(make-home-mpv-configuration + #:profiles `((fullscreen . ,(make-mpv-profile-configuration + #:fullscreen? #t)))) +@end lisp + +@item @code{extra-config} (default: @code{#f}) +Additional content to include in the configuration file. It is placed +at the end of the file. + +@end table +@end deffn + +@deffn {Procedure} make-mpv-profile-configuration +Return a new instance of @code{mpv-profile-configuration}. As above, it +also supports the @code{#:inherit} argument. Additionally it supports +keyword arguments named after the options of @command{mpv}. Hence +@option{--fullscreen} (or @code{fullscreen} in the configuration file) +becomes @code{#:fullscreen?}. + +Few options are using their aliases instead. @option{audio} instead of +@option{aid}, @option{video} instead of @option{vid}, @option{sub} +instead of @option{sid}, @option{screenshot-directory} instead of +@option{screenshot-dir} and @option{watch-later-directory} instead of +@option{watch-later-dir}. + +Valid values for the fields depend on their type. + +@table @asis +@item Flags +The value should be @code{#f} or @code{#t}. + +@item Numerical fields +Integer and integer64 fields are validated by @code{integer?}, float and +double fields by @code{real?}. Ranges are checked when applicable. + +@item Aspect +Same as integer. + +@item ByteSize +Same as integer64. + +@item Choice +The value should be a symbol representing member of the enumeration. If +the choice has @samp{or ...} part, it can also be value of that +alternative type. + +@item @var{type} list +The value should be a list of the @var{type}. + +@end table + +Other types accept strings, with validation of the values where possible +(e.g. type @samp{Color} is validated, but type @samp{Audio channels or +channel map} is not). + +The full list of currently supported keyword arguments is below. For +the types, allowed values and full description please refer to the +@command{mpv --list-options} and +@uref{https://mpv.io/manual/stable/#options, mpv manual}. + +Only set fields are outputted to the configuration file. Accessors are +provided for every field, returning either their value or a sentinel +object @code{%unset-value} (from @code{(gnu services configuration)}). + +@code{ab-loop-a}, @code{ab-loop-b}, @code{ab-loop-count}, +@code{access-references?}, @code{ad}, @code{ad-lavc-ac3drc}, +@code{ad-lavc-downmix?}, @code{ad-lavc-o}, @code{ad-lavc-threads}, +@code{ad-queue-enable?}, @code{ad-queue-max-bytes}, +@code{ad-queue-max-samples}, @code{ad-queue-max-secs}, @code{af}, +@code{audio}, @code{alang}, @code{allow-delayed-peak-detect?}, +@code{alsa-buffer-time}, @code{alsa-ignore-chmap?}, +@code{alsa-mixer-device}, @code{alsa-mixer-index}, +@code{alsa-mixer-name}, @code{alsa-non-interleaved?}, +@code{alsa-periods}, @code{alsa-resample?}, @code{ao}, +@code{ao-null-broken-delay?}, @code{ao-null-broken-eof?}, +@code{ao-null-buffer}, @code{ao-null-channel-layouts}, +@code{ao-null-format}, @code{ao-null-latency}, @code{ao-null-outburst}, +@code{ao-null-speed}, @code{ao-null-untimed?}, @code{ao-pcm-append?}, +@code{ao-pcm-file}, @code{ao-pcm-waveheader?}, +@code{audio-backward-batch}, @code{audio-backward-overlap}, +@code{audio-buffer}, @code{audio-channels}, @code{audio-client-name}, +@code{audio-delay}, @code{audio-demuxer}, @code{audio-device}, +@code{audio-display}, @code{audio-exclusive?}, @code{audio-exts}, +@code{audio-fallback-to-null?}, @code{audio-file-auto}, +@code{audio-file-paths}, @code{audio-files}, @code{audio-format}, +@code{audio-normalize-downmix?}, @code{audio-pitch-correction?}, +@code{audio-resample-cutoff}, @code{audio-resample-filter-size}, +@code{audio-resample-linear?}, @code{audio-resample-max-output-size}, +@code{audio-resample-phase-shift}, @code{audio-reversal-buffer}, +@code{audio-samplerate}, @code{audio-spdif}, +@code{audio-stream-silence?}, @code{audio-swresample-o}, +@code{audio-wait-open}, @code{auto-window-resize?}, +@code{autocreate-playlist}, @code{autofit}, @code{autofit-larger}, +@code{autofit-smaller}, @code{autoload-files?}, @code{autosync}, +@code{background}, @code{background-color}, @code{blend-subtitles}, +@code{bluray-device}, @code{border?}, @code{border-background}, +@code{brightness}, @code{cache}, @code{cache-on-disk?}, +@code{cache-pause?}, @code{cache-pause-initial?}, +@code{cache-pause-wait}, @code{cache-secs}, @code{cdda-cdtext?}, +@code{cdda-device}, @code{cdda-overlap}, @code{cdda-paranoia}, +@code{cdda-sector-size}, @code{cdda-skip?}, @code{cdda-span-a}, +@code{cdda-span-b}, @code{cdda-speed}, @code{cdda-toc-offset}, +@code{chapter-merge-threshold}, @code{chapter-seek-threshold}, +@code{chapters-file}, @code{config?}, @code{container-fps-override}, +@code{contrast}, @code{cookies?}, @code{cookies-file}, +@code{corner-rounding}, @code{correct-downscaling?}, +@code{correct-pts?}, @code{cover-art-auto}, @code{cover-art-files}, +@code{cover-art-whitelist}, @code{cscale}, @code{cscale-antiring}, +@code{cscale-blur}, @code{cscale-clamp}, @code{cscale-param1}, +@code{cscale-param2}, @code{cscale-radius}, @code{cscale-taper}, +@code{cscale-window}, @code{cscale-wparam}, @code{cscale-wtaper}, +@code{cursor-autohide}, @code{cursor-autohide-fs-only?}, @code{deband?}, +@code{deband-grain}, @code{deband-iterations}, @code{deband-range}, +@code{deband-threshold}, @code{deinterlace}, +@code{deinterlace-field-parity}, @code{demuxer}, +@code{demuxer-backward-playback-step}, @code{demuxer-cache-dir}, +@code{demuxer-cache-unlink-files}, @code{demuxer-cache-wait?}, +@code{demuxer-donate-buffer?}, @code{demuxer-hysteresis-secs}, +@code{demuxer-lavf-allow-mimetype?}, +@code{demuxer-lavf-analyzeduration}, @code{demuxer-lavf-buffersize}, +@code{demuxer-lavf-format}, @code{demuxer-lavf-hacks?}, +@code{demuxer-lavf-linearize-timestamps}, @code{demuxer-lavf-o}, +@code{demuxer-lavf-probe-info}, @code{demuxer-lavf-probescore}, +@code{demuxer-lavf-probesize}, @code{demuxer-lavf-propagate-opts?}, +@code{demuxer-max-back-bytes}, @code{demuxer-max-bytes}, +@code{demuxer-mkv-probe-start-time?}, +@code{demuxer-mkv-probe-video-duration}, +@code{demuxer-mkv-subtitle-preroll}, +@code{demuxer-mkv-subtitle-preroll-secs}, +@code{demuxer-mkv-subtitle-preroll-secs-index}, +@code{demuxer-rawaudio-channels}, @code{demuxer-rawaudio-format}, +@code{demuxer-rawaudio-rate}, @code{demuxer-rawvideo-codec}, +@code{demuxer-rawvideo-format}, @code{demuxer-rawvideo-fps}, +@code{demuxer-rawvideo-h}, @code{demuxer-rawvideo-mp-format}, +@code{demuxer-rawvideo-size}, @code{demuxer-rawvideo-w}, +@code{demuxer-readahead-secs}, @code{demuxer-seekable-cache}, +@code{demuxer-termination-timeout}, @code{demuxer-thread?}, +@code{directory-filter-types}, @code{directory-mode}, +@code{display-fps-override}, @code{display-tags}, @code{dither}, +@code{dither-depth}, @code{dither-size-fruit}, @code{drag-and-drop}, +@code{drm-connector}, @code{drm-device}, @code{drm-draw-plane}, +@code{drm-draw-surface-size}, @code{drm-drmprime-video-plane}, +@code{drm-format}, @code{drm-mode}, @code{drm-vrr-enabled}, +@code{dscale}, @code{dscale-antiring}, @code{dscale-blur}, +@code{dscale-clamp}, @code{dscale-param1}, @code{dscale-param2}, +@code{dscale-radius}, @code{dscale-taper}, @code{dscale-window}, +@code{dscale-wparam}, @code{dscale-wtaper}, @code{dump-stats}, +@code{dvbin-card}, @code{dvbin-channel-switch-offset}, +@code{dvbin-file}, @code{dvbin-full-transponder?}, @code{dvbin-prog}, +@code{dvbin-timeout}, @code{dvd-angle}, @code{dvd-device}, +@code{dvd-speed}, @code{edition}, @code{egl-config-id}, +@code{egl-output-format}, @code{embeddedfonts?}, @code{end}, +@code{error-diffusion}, @code{external-files}, @code{fbo-format}, +@code{focus-on}, @code{force-media-title}, @code{force-render?}, +@code{force-rgba-osd-rendering?}, @code{force-seekable?}, +@code{force-window}, @code{force-window-position?}, @code{framedrop}, +@code{frames}, @code{fs-screen}, @code{fs-screen-name}, +@code{fullscreen?}, @code{gamma}, @code{gamma-auto?}, +@code{gamma-factor}, @code{gamut-mapping-mode}, @code{gapless-audio}, +@code{geometry}, @code{glsl-shader-opts}, @code{glsl-shaders}, +@code{gpu-api}, @code{gpu-context}, @code{gpu-debug?}, +@code{gpu-dumb-mode}, @code{gpu-hwdec-interop}, +@code{gpu-shader-cache?}, @code{gpu-shader-cache-dir}, @code{gpu-sw?}, +@code{gpu-tex-pad-x}, @code{gpu-tex-pad-y}, @code{hdr-compute-peak}, +@code{hdr-contrast-recovery}, @code{hdr-contrast-smoothness}, +@code{hdr-peak-decay-rate}, @code{hdr-peak-percentile}, +@code{hdr-scene-threshold-high}, @code{hdr-scene-threshold-low}, +@code{hidpi-window-scale?}, @code{hls-bitrate}, @code{hr-seek}, +@code{hr-seek-demuxer-offset}, @code{hr-seek-framedrop?}, +@code{http-header-fields}, @code{http-proxy}, @code{hue}, @code{hwdec}, +@code{hwdec-codecs}, @code{hwdec-extra-frames}, +@code{hwdec-image-format}, @code{icc-3dlut-size}, @code{icc-cache?}, +@code{icc-cache-dir}, @code{icc-force-contrast}, @code{icc-intent}, +@code{icc-profile}, @code{icc-profile-auto?}, @code{icc-use-luma?}, +@code{idle}, @code{ignore-path-in-watch-later-config?}, +@code{image-display-duration}, @code{image-exts}, @code{image-lut}, +@code{image-lut-type}, @code{image-subs-video-resolution?}, +@code{include}, @code{index}, @code{initial-audio-sync?}, +@code{input-ar-delay}, @code{input-ar-rate}, +@code{input-builtin-bindings?}, @code{input-builtin-dragging?}, +@code{input-commands}, @code{input-conf}, @code{input-cursor?}, +@code{input-cursor-passthrough?}, @code{input-default-bindings?}, +@code{input-doubleclick-time}, @code{input-dragging-deadzone}, +@code{input-ipc-client}, @code{input-ipc-server}, +@code{input-key-fifo-size}, @code{input-media-keys?}, +@code{input-preprocess-wheel?}, @code{input-right-alt-gr?}, +@code{input-terminal?}, @code{input-test?}, +@code{input-touch-emulate-mouse?}, @code{input-vo-keyboard?}, +@code{interpolation?}, @code{interpolation-preserve?}, +@code{interpolation-threshold}, @code{inverse-tone-mapping?}, +@code{jack-autostart?}, @code{jack-connect?}, @code{jack-name}, +@code{jack-port}, @code{jack-std-channel-layout}, @code{keep-open}, +@code{keep-open-pause?}, @code{keepaspect?}, @code{keepaspect-window?}, +@code{lavfi-complex}, @code{length}, @code{libplacebo-opts}, +@code{linear-downscaling?}, @code{linear-upscaling?}, +@code{load-auto-profiles}, @code{load-osd-console?}, +@code{load-scripts?}, @code{load-select?}, @code{load-stats-overlay?}, +@code{load-unsafe-playlists?}, @code{log-file}, @code{loop-file}, +@code{loop-playlist}, @code{lut}, @code{lut-type}, @code{mc}, +@code{media-controls}, @code{merge-files?}, @code{metadata-codepage}, +@code{mf-fps}, @code{mf-type}, @code{monitoraspect}, +@code{monitorpixelaspect}, @code{msg-color?}, @code{msg-level}, +@code{msg-module?}, @code{msg-time?}, @code{mute?}, @code{native-fs?}, +@code{native-keyrepeat?}, @code{native-touch?}, @code{network-timeout}, +@code{oac}, @code{oacopts}, @code{ocopy-metadata?}, @code{of}, +@code{ofopts}, @code{on-all-workspaces?}, @code{ontop?}, +@code{ontop-level}, @code{opengl-check-pattern-a}, +@code{opengl-check-pattern-b}, @code{opengl-early-flush}, +@code{opengl-es}, @code{opengl-glfinish?}, @code{opengl-pbo?}, +@code{opengl-rectangle-textures?}, @code{opengl-swapinterval}, +@code{opengl-waitvsync?}, @code{orawts?}, @code{ordered-chapters?}, +@code{ordered-chapters-files}, @code{oremove-metadata}, @code{osc?}, +@code{osd-align-x}, @code{osd-align-y}, @code{osd-back-color}, +@code{osd-bar?}, @code{osd-bar-align-x}, @code{osd-bar-align-y}, +@code{osd-bar-h}, @code{osd-bar-outline-size}, @code{osd-bar-w}, +@code{osd-blur}, @code{osd-bold?}, @code{osd-border-style}, +@code{osd-color}, @code{osd-duration}, @code{osd-font}, +@code{osd-font-provider}, @code{osd-font-size}, @code{osd-fonts-dir}, +@code{osd-fractions?}, @code{osd-italic?}, @code{osd-justify}, +@code{osd-level}, @code{osd-margin-x}, @code{osd-margin-y}, +@code{osd-msg1}, @code{osd-msg2}, @code{osd-msg3}, @code{osd-on-seek}, +@code{osd-outline-color}, @code{osd-outline-size}, +@code{osd-playing-msg}, @code{osd-playing-msg-duration}, +@code{osd-playlist-entry}, @code{osd-scale}, +@code{osd-scale-by-window?}, @code{osd-shadow-offset}, +@code{osd-spacing}, @code{osd-status-msg}, @code{oset-metadata}, +@code{ovc}, @code{ovcopts}, @code{panscan}, @code{pause?}, +@code{pipewire-buffer}, @code{pipewire-remote}, +@code{pipewire-volume-mode}, @code{pitch}, @code{play-direction}, +@code{player-operation-mode}, @code{playlist-start}, +@code{prefetch-playlist?}, @code{profile}, +@code{pulse-allow-suspended?}, @code{pulse-buffer}, @code{pulse-host}, +@code{pulse-latency-hacks?}, @code{quiet?}, @code{really-quiet?}, +@code{rebase-start-time?}, @code{referrer}, @code{replaygain}, +@code{replaygain-clip?}, @code{replaygain-fallback}, +@code{replaygain-preamp}, @code{reset-on-next-file}, +@code{resume-playback?}, @code{resume-playback-check-mtime?}, +@code{rtsp-transport}, @code{saturation}, @code{save-position-on-quit?}, +@code{scale}, @code{scale-antiring}, @code{scale-blur}, +@code{scale-clamp}, @code{scale-param1}, @code{scale-param2}, +@code{scale-radius}, @code{scale-taper}, @code{scale-window}, +@code{scale-wparam}, @code{scale-wtaper}, @code{scaler-resizes-only?}, +@code{screen}, @code{screen-name}, @code{screenshot-avif-encoder}, +@code{screenshot-avif-opts}, @code{screenshot-avif-pixfmt}, +@code{screenshot-directory}, @code{screenshot-format}, +@code{screenshot-high-bit-depth?}, @code{screenshot-jpeg-quality}, +@code{screenshot-jpeg-source-chroma?}, @code{screenshot-jxl-distance}, +@code{screenshot-jxl-effort}, @code{screenshot-png-compression}, +@code{screenshot-png-filter}, @code{screenshot-sw?}, +@code{screenshot-tag-colorspace?}, @code{screenshot-template}, +@code{screenshot-webp-compression}, @code{screenshot-webp-lossless?}, +@code{screenshot-webp-quality}, @code{script-opts}, @code{scripts}, +@code{secondary-sid}, @code{secondary-sub-ass-override}, +@code{secondary-sub-delay}, @code{secondary-sub-pos}, +@code{secondary-sub-visibility?}, @code{sharpen}, +@code{show-in-taskbar?}, @code{shuffle?}, @code{sub}, +@code{sigmoid-center}, @code{sigmoid-slope}, @code{sigmoid-upscaling?}, +@code{slang}, @code{snap-window?}, @code{speed}, @code{spirv-compiler}, +@code{sstep}, @code{start}, @code{stop-playback-on-init-failure?}, +@code{stop-screensaver}, @code{stream-buffer-size}, @code{stream-dump}, +@code{stream-lavf-o}, @code{stream-record}, @code{stretch-dvd-subs?}, +@code{stretch-image-subs-to-screen?}, @code{sub-align-x}, +@code{sub-align-y}, @code{sub-ass?}, @code{sub-ass-force-margins?}, +@code{sub-ass-hinting}, @code{sub-ass-justify?}, +@code{sub-ass-line-spacing}, @code{sub-ass-override}, +@code{sub-ass-scale-with-window?}, @code{sub-ass-shaper}, +@code{sub-ass-style-overrides}, @code{sub-ass-styles}, +@code{sub-ass-use-video-data}, @code{sub-ass-video-aspect-override}, +@code{sub-ass-vsfilter-color-compat}, @code{sub-auto}, +@code{sub-auto-exts}, @code{sub-back-color}, @code{sub-blur}, +@code{sub-bold?}, @code{sub-border-style}, @code{sub-clear-on-seek?}, +@code{sub-codepage}, @code{sub-color}, @code{sub-create-cc-track?}, +@code{sub-delay}, @code{sub-demuxer}, @code{sub-file-paths}, +@code{sub-files}, @code{sub-filter-jsre}, @code{sub-filter-regex}, +@code{sub-filter-regex-enable?}, @code{sub-filter-regex-plain?}, +@code{sub-filter-regex-warn?}, @code{sub-filter-sdh?}, +@code{sub-filter-sdh-enclosures}, @code{sub-filter-sdh-harder?}, +@code{sub-fix-timing?}, @code{sub-font}, @code{sub-font-provider}, +@code{sub-font-size}, @code{sub-fonts-dir}, +@code{sub-forced-events-only?}, @code{sub-fps}, @code{sub-gauss}, +@code{sub-gray?}, @code{sub-italic?}, @code{sub-justify}, +@code{sub-lavc-o}, @code{sub-margin-x}, @code{sub-margin-y}, +@code{sub-outline-color}, @code{sub-outline-size}, +@code{sub-past-video-end?}, @code{sub-pos}, @code{sub-scale}, +@code{sub-scale-by-window?}, @code{sub-scale-with-window?}, +@code{sub-shadow-offset}, @code{sub-spacing}, @code{sub-speed}, +@code{sub-stretch-durations?}, @code{sub-use-margins?}, +@code{sub-visibility?}, @code{sub-vsfilter-bidi-compat?}, +@code{subs-fallback}, @code{subs-fallback-forced}, +@code{subs-match-os-language?}, @code{subs-with-matching-audio}, +@code{swapchain-depth}, @code{sws-allow-zimg?}, @code{sws-bitexact?}, +@code{sws-cgb}, @code{sws-chs}, @code{sws-cs}, @code{sws-cvs}, +@code{sws-fast?}, @code{sws-lgb}, @code{sws-ls}, @code{sws-scaler}, +@code{target-colorspace-hint?}, @code{target-contrast}, +@code{target-gamut}, @code{target-lut}, @code{target-peak}, +@code{target-prim}, @code{target-trc}, @code{taskbar-progress?}, +@code{teletext-page}, @code{temporal-dither?}, +@code{temporal-dither-period}, @code{term-osd}, @code{term-osd-bar?}, +@code{term-osd-bar-chars}, @code{term-playing-msg}, +@code{term-status-msg}, @code{term-title}, @code{terminal?}, +@code{title}, @code{title-bar?}, @code{tls-ca-file}, +@code{tls-cert-file}, @code{tls-key-file}, @code{tls-verify?}, +@code{tone-mapping}, @code{tone-mapping-max-boost}, +@code{tone-mapping-param}, @code{tone-mapping-visualize?}, +@code{track-auto-selection?}, @code{tscale}, @code{tscale-antiring}, +@code{tscale-blur}, @code{tscale-clamp}, @code{tscale-param1}, +@code{tscale-param2}, @code{tscale-radius}, @code{tscale-taper}, +@code{tscale-window}, @code{tscale-wparam}, @code{tscale-wtaper}, +@code{untimed?}, @code{use-embedded-icc-profile?}, +@code{use-filedir-conf?}, @code{user-agent}, @code{vaapi-device}, +@code{vd}, @code{vd-apply-cropping?}, @code{vd-lavc-assume-old-x264?}, +@code{vd-lavc-bitexact?}, @code{vd-lavc-check-hw-profile?}, +@code{vd-lavc-dr}, @code{vd-lavc-fast?}, @code{vd-lavc-film-grain}, +@code{vd-lavc-framedrop}, @code{vd-lavc-o}, @code{vd-lavc-show-all?}, +@code{vd-lavc-skipframe}, @code{vd-lavc-skipidct}, +@code{vd-lavc-skiploopfilter}, @code{vd-lavc-software-fallback}, +@code{vd-lavc-threads}, @code{vd-queue-enable?}, +@code{vd-queue-max-bytes}, @code{vd-queue-max-samples}, +@code{vd-queue-max-secs}, @code{vf}, @code{video}, @code{video-align-x}, +@code{video-align-y}, @code{video-aspect-method}, +@code{video-aspect-override}, @code{video-backward-batch}, +@code{video-backward-overlap}, @code{video-crop}, @code{video-exts}, +@code{video-latency-hacks?}, @code{video-margin-ratio-bottom}, +@code{video-margin-ratio-left}, @code{video-margin-ratio-right}, +@code{video-margin-ratio-top}, @code{video-osd?}, +@code{video-output-levels}, @code{video-pan-x}, @code{video-pan-y}, +@code{video-reversal-buffer}, @code{video-rotate}, @code{video-scale-x}, +@code{video-scale-y}, @code{video-sync}, +@code{video-sync-max-audio-change}, @code{video-sync-max-factor}, +@code{video-sync-max-video-change}, @code{video-timing-offset}, +@code{video-unscaled}, @code{video-zoom}, @code{vlang}, @code{vo}, +@code{vo-image-avif-encoder}, @code{vo-image-avif-opts}, +@code{vo-image-avif-pixfmt}, @code{vo-image-format}, +@code{vo-image-high-bit-depth?}, @code{vo-image-jpeg-quality}, +@code{vo-image-jpeg-source-chroma?}, @code{vo-image-jxl-distance}, +@code{vo-image-jxl-effort}, @code{vo-image-outdir}, +@code{vo-image-png-compression}, @code{vo-image-png-filter}, +@code{vo-image-tag-colorspace?}, @code{vo-image-webp-compression}, +@code{vo-image-webp-lossless?}, @code{vo-image-webp-quality}, +@code{vo-kitty-alt-screen?}, @code{vo-kitty-cols}, +@code{vo-kitty-config-clear?}, @code{vo-kitty-height}, +@code{vo-kitty-left}, @code{vo-kitty-rows}, @code{vo-kitty-top}, +@code{vo-kitty-use-shm?}, @code{vo-kitty-width}, @code{vo-null-fps}, +@code{vo-sixel-alt-screen?}, @code{vo-sixel-buffered?}, +@code{vo-sixel-cols}, @code{vo-sixel-config-clear?}, +@code{vo-sixel-dither}, @code{vo-sixel-fixedpalette?}, +@code{vo-sixel-height}, @code{vo-sixel-left}, @code{vo-sixel-pad-x}, +@code{vo-sixel-pad-y}, @code{vo-sixel-reqcolors}, @code{vo-sixel-rows}, +@code{vo-sixel-threshold}, @code{vo-sixel-top}, @code{vo-sixel-width}, +@code{vo-tct-256?}, @code{vo-tct-algo}, @code{vo-tct-buffering}, +@code{vo-tct-height}, @code{vo-tct-width}, @code{vo-vaapi-scaled-osd?}, +@code{vo-vaapi-scaling}, @code{vo-vdpau-chroma-deint?}, +@code{vo-vdpau-colorkey}, @code{vo-vdpau-composite-detect?}, +@code{vo-vdpau-denoise}, @code{vo-vdpau-force-yuv?}, +@code{vo-vdpau-fps}, @code{vo-vdpau-hqscaling}, +@code{vo-vdpau-output-surfaces}, @code{vo-vdpau-pullup?}, +@code{vo-vdpau-queuetime-fs}, @code{vo-vdpau-queuetime-windowed}, +@code{vo-vdpau-sharpen}, @code{volume}, @code{volume-gain}, +@code{volume-gain-max}, @code{volume-gain-min}, @code{volume-max}, +@code{vulkan-async-compute?}, @code{vulkan-async-transfer?}, +@code{vulkan-device}, @code{vulkan-display-display}, +@code{vulkan-display-mode}, @code{vulkan-display-plane}, +@code{vulkan-queue-count}, @code{vulkan-swap-mode}, +@code{watch-later-directory}, @code{watch-later-options}, +@code{wayland-app-id}, @code{wayland-configure-bounds}, +@code{wayland-content-type}, @code{wayland-disable-vsync?}, +@code{wayland-edge-pixels-pointer}, @code{wayland-edge-pixels-touch}, +@code{wayland-present?}, @code{wid}, @code{window-dragging?}, +@code{window-maximized?}, @code{window-minimized?}, @code{window-scale}, +@code{write-filename-in-watch-later-config?}, +@code{x11-bypass-compositor}, @code{x11-name}, @code{x11-netwm}, +@code{x11-present}, @code{x11-wid-title?}, @code{xv-adaptor}, +@code{xv-buffers}, @code{xv-ck}, @code{xv-ck-method}, +@code{xv-colorkey}, @code{xv-port}, @code{ytdl?}, @code{ytdl-format}, +@code{ytdl-raw-options}, @code{zimg-dither}, @code{zimg-fast?}, +@code{zimg-scaler}, @code{zimg-scaler-chroma}, +@code{zimg-scaler-chroma-param-a}, @code{zimg-scaler-chroma-param-b}, +@code{zimg-scaler-param-a}, @code{zimg-scaler-param-b}, and +@code{zimg-threads}. + +@end deffn + @node Sway window manager @subsection Sway window manager diff --git a/gnu/home/services/mpv.scm b/gnu/home/services/mpv.scm new file mode 100644 index 0000000000..8d11fa03a3 --- /dev/null +++ b/gnu/home/services/mpv.scm @@ -0,0 +1,2751 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2024, 2025 Tomas Volf <~@wolfsden.cz> +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix 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 General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. + +(define-module (gnu home services mpv) + #:use-module ((gnu services configuration) #:select (%unset-value + maybe-value-set?)) + #:use-module (gnu home services) + #:autoload (guix diagnostics) (formatted-message) + #:autoload (guix i18n) (G_) + #:use-module (guix gexp) + #:use-module (ice-9 match) + #:use-module (ice-9 regex) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-2) + #:use-module (srfi srfi-9) + #:use-module (srfi srfi-26) + #:use-module (srfi srfi-71) + #:export (make-home-mpv-configuration + home-mpv-configuration? + home-mpv-configuration-global + home-mpv-configuration-profiles + home-mpv-configuration-extra-config + home-mpv-configuration-source-location + + serialize-home-mpv-configuration + + make-mpv-profile-configuration + mpv-profile-configuration? + ;; Field accessor procedures are exported by a syntax form when + ;; they are defined, so they are not listed here. + + home-mpv-service-type)) + + +;;; +;;; Basic types. +;;; +(define (serialize-mpv/boolean field-name value) + #~(string-append (string-trim-right #$(symbol->string field-name) #\?) + "=" + #$(if value "yes" "no") + "\n")) +(define mpv/boolean? boolean?) + +(define (serialize-mpv/integer field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(number->string value) + "\n")) +(define (mpv/integer? n) + ;; We assume integer is a signed 32bit number. + (and-let* (((integer? n)) + ((>= n (* -1 (expt 2 (1- 32))))) + ((<= n (1- (expt 2 (1- 32)))))))) + +(define (serialize-mpv/integer64 field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(number->string value) + "\n")) +(define (mpv/integer64? n) + ;; We assume integer is a signed 64bit number. + (and-let* (((integer? n)) + ((>= n (* -1 (expt 2 (1- 64))))) + ((<= n (1- (expt 2 (1- 64)))))))) + +(define (serialize-mpv/string field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$value + "\n")) +(define mpv/string? + string?) + +(define (serialize-mpv/float field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(number->string (exact->inexact value)) + "\n")) +(define mpv/float? + ;; I am not sure how to validate floats. + real?) + +(define (serialize-mpv/double field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(number->string (exact->inexact value)) + "\n")) +(define mpv/double? + ;; I am not sure how to validate doubles. + real?) + + + + +;;; +;;; Additional types (possible based on the basic ones). +;;; + +;;; Aspect seems to be treated as an integer, so define it in terms of it. +(define serialize-mpv/aspect serialize-mpv/integer) +(define mpv/aspect? mpv/integer?) + +;;; `Audio channels or channel map' seems to be basically a free form string +;;; with no way to validate. +(define serialize-mpv/audio-channels-or-channel-map serialize-mpv/string) +(define mpv/audio-channels-or-channel-map? mpv/string?) + +;;; Does not seem possible to validate. +(define serialize-mpv/audio-format serialize-mpv/string) +(define mpv/audio-format? mpv/string?) + +;;; While most options list 4.6116860184274e+18 as a maximum value, we will +;;; use integer64 here. That should be enough for everyone for few more +;;; years. +(define serialize-mpv/byte-size serialize-mpv/integer64) +(define mpv/byte-size? mpv/integer64?) + +(define (serialize-mpv/color field-name value) + #~(string-append #$(symbol->string field-name) + "=" + #$(if (list? value) + (string-join (map number->string value) "/") + value) + "\n")) +(define (mpv/color? value) + (define (ok-num? n) + (and (number? n) + (>= n 0) + (<= n 1))) + (if (list? value) + ;; Either a list of 3(4) numbers encoding RGB(A) on range from 0 to 1... + (match value + (((? ok-num? r) (? ok-num? g) (? ok-num? b)) + #t) + (((? ok-num? r) (? ok-num? g) (? ok-num? b) (? ok-num? alpha)) + #t) + (_ + #f)) + ;; ... or RGB(A) hex encoding. + (string-match "^#([A-Fa-f0-9]{2})?[A-Fa-f0-9]{6}$" value))) + +;;; I do not see value mirroring fourcc.org's database here. It is further +;;; complicated by arbitrary hex being accepted as well. So string it is. +(define serialize-mpv/fourcc serialize-mpv/string) +(define mpv/fourcc? mpv/string?) + +;;; No way to validate. +(define serialize-mpv/image-format serialize-mpv/string) +(define mpv/image-format? mpv/string?) + +;;; Looking at the documentation for --start, there is no way to make this +;;; bullet-proof, especially since even chapter numbers are accepted. +(define serialize-mpv/relative-time-or-percent-position serialize-mpv/string) +(define mpv/relative-time-or-percent-position? mpv/string?) + +(define serialize-mpv/time serialize-mpv/string) +(define mpv/time? mpv/string?) + +(define serialize-mpv/video-rectangle serialize-mpv/string) +(define (mpv/video-rectangle? value) + (or (string-match "-?[0-9]+%?:-?[0-9]+%?" value) + (string-match + "^(-?[0-9]+%?(x-?[0-9]+%?)?)?([+-]-?[0-9]+%?[+-]-?[0-9]+%?)?$" + value))) + +(define serialize-mpv/window-geometry serialize-mpv/string) +(define (mpv/window-geometry? value) + (or (string-match "-?[0-9]+%?:-?[0-9]+%?" value) + (string-match + "^(-?[0-9]+%?(x-?[0-9]+%?)?)?([+-]-?[0-9]+%?[+-]-?[0-9]+%?)?(/[0-9]+)?$" + value))) + +(define serialize-mpv/window-size serialize-mpv/string) +(define (mpv/window-size? value) + (string-match "^([0-9]+%?(x[0-9]+%?)?)?$" value)) + +(define (serialize-mpv/enumeration field-name value) + #~(string-append #$(symbol->string field-name) + "=" + ;; This could be either symbol or (in case of enumerations + ;; with alternate type) anything. So just use `format'. + #$(format #f "~s" value) + "\n")) +(define (mpv/enumeration? value) + ;; There is no general way to check enumerations. The field always has to + ;; define custom sanitizer. + #t) + + + + +;;; +;;; List types. +;;; +(define (serialize-mpv/list-of-string field-name lst) + #~(string-append #$(symbol->string field-name) + "=" + #$(string-join lst ",") + "\n")) +(define (mpv/list-of-string? lst) + (every mpv/string? lst)) + +(define (serialize-mpv/list-of-key-value field-name lst) + #~(string-append #$(symbol->string field-name) + "=" + #$(string-join (map (match-lambda + ((k . v) (format #f "~a=~a" k v))) + lst) + ",") + "\n")) +(define (mpv/list-of-key-value? lst) + (every (match-lambda + (((? string?) . (? string?)) #t) + (_ #f)) + lst)) + +(define serialize-mpv/list-of-object-setting serialize-mpv/list-of-string) +(define mpv/list-of-object-setting? mpv/list-of-string?) + +(define serialize-mpv/list-of-output-verbosity serialize-mpv/list-of-key-value) +(define mpv/list-of-output-verbosity? mpv/list-of-key-value?) + + + + +;;; +;;; Actual configuration record. Contains a lot of generated code. +;;; + +(define-record-type <profile-option> + (make-profile-option name type-check serializer) + profile-option? + (name profile-option-name) + (type-check profile-option-type-check) + (serializer profile-option-serializer)) + +(define %opts (make-hash-table)) + +(define-syntax define-opt + (lambda (x) + (syntax-case x () + ((_ name type extra-checks ...) + (let* ((d/n (syntax->datum #'name)) + (d/t (syntax->datum #'type)) + (d/accessor (string->symbol + (format #f "mpv-profile-configuration-~a" d/n))) + (d/type-check (string->symbol + (format #f "mpv/~a?" d/t))) + (d/serializer (string->symbol + (format #f "serialize-mpv/~a" d/t)))) + (with-syntax + ((kw (datum->syntax x (symbol->keyword d/n))) + (accessor (datum->syntax x d/accessor)) + (type-check (datum->syntax x d/type-check)) + (serializer (datum->syntax x d/serializer)) + (val (datum->syntax x 'val))) + #'(begin + (hashq-set! %opts 'name + (make-profile-option (symbol->string 'name) + (lambda (val) + (and (type-check val) + extra-checks ...)) + serializer)) + (define-public (accessor cfg) + (let ((x (hashq-ref (%mpv-profile-configuration-data cfg) + 'name + %unset-value))) + (if (eq? x %unset-value) + %unset-value + (car x))))))))))) + +;;; Generated by: https://git.wolfsden.cz/guix/tree/etc/update-mpv-configuration +;;; Generated code - START. +(define-opt ab-loop-a time) +(define-opt ab-loop-b time) +(define-opt + ab-loop-count + enumeration + (or (memq val '(inf)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt access-references? boolean) +(define-opt ad string) +(define-opt + ad-lavc-ac3drc + float + (>= val 0) + (<= val 6)) +(define-opt ad-lavc-downmix? boolean) +(define-opt ad-lavc-o list-of-key-value) +(define-opt + ad-lavc-threads + integer + (>= val 0) + (<= val 16)) +(define-opt ad-queue-enable? boolean) +(define-opt + ad-queue-max-bytes + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + ad-queue-max-samples + integer64 + (>= val 0)) +(define-opt ad-queue-max-secs double (>= val 0)) +(define-opt af list-of-object-setting) +(define-opt + audio + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt alang list-of-string) +(define-opt allow-delayed-peak-detect? boolean) +(define-opt + alsa-buffer-time + integer + (>= val 0) + (<= val 2147483647)) +(define-opt alsa-ignore-chmap? boolean) +(define-opt alsa-mixer-device string) +(define-opt + alsa-mixer-index + integer + (>= val 0) + (<= val 99)) +(define-opt alsa-mixer-name string) +(define-opt alsa-non-interleaved? boolean) +(define-opt + alsa-periods + integer + (>= val 0) + (<= val 2147483647)) +(define-opt alsa-resample? boolean) +(define-opt ao list-of-object-setting) +(define-opt ao-null-broken-delay? boolean) +(define-opt ao-null-broken-eof? boolean) +(define-opt + ao-null-buffer + float + (>= val 0) + (<= val 100)) +(define-opt + ao-null-channel-layouts + audio-channels-or-channel-map) +(define-opt ao-null-format audio-format) +(define-opt + ao-null-latency + float + (>= val 0) + (<= val 100)) +(define-opt + ao-null-outburst + integer + (>= val 1) + (<= val 100000)) +(define-opt + ao-null-speed + float + (>= val 0) + (<= val 10000)) +(define-opt ao-null-untimed? boolean) +(define-opt ao-pcm-append? boolean) +(define-opt ao-pcm-file string) +(define-opt ao-pcm-waveheader? boolean) +(define-opt + audio-backward-batch + integer + (>= val 0) + (<= val 1024)) +(define-opt + audio-backward-overlap + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 0) (<= val 1024)))) +(define-opt + audio-buffer + double + (>= val 0) + (<= val 10)) +(define-opt + audio-channels + audio-channels-or-channel-map) +(define-opt audio-client-name string) +(define-opt audio-delay float) +(define-opt audio-demuxer string) +(define-opt audio-device string) +(define-opt + audio-display + enumeration + (memq val '(no embedded-first external-first))) +(define-opt audio-exclusive? boolean) +(define-opt audio-exts list-of-string) +(define-opt audio-fallback-to-null? boolean) +(define-opt + audio-file-auto + enumeration + (memq val '(no exact fuzzy all))) +(define-opt audio-file-paths list-of-string) +(define-opt audio-files list-of-string) +(define-opt audio-format audio-format) +(define-opt audio-normalize-downmix? boolean) +(define-opt audio-pitch-correction? boolean) +(define-opt + audio-resample-cutoff + double + (>= val 0) + (<= val 1)) +(define-opt + audio-resample-filter-size + integer + (>= val 0) + (<= val 32)) +(define-opt audio-resample-linear? boolean) +(define-opt + audio-resample-max-output-size + double) +(define-opt + audio-resample-phase-shift + integer + (>= val 0) + (<= val 30)) +(define-opt + audio-reversal-buffer + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + audio-samplerate + integer + (>= val 0) + (<= val 768000)) +(define-opt audio-spdif string) +(define-opt audio-stream-silence? boolean) +(define-opt audio-swresample-o list-of-key-value) +(define-opt + audio-wait-open + float + (>= val 0) + (<= val 60)) +(define-opt auto-window-resize? boolean) +(define-opt + autocreate-playlist + enumeration + (memq val '(no filter same))) +(define-opt autofit window-size) +(define-opt autofit-larger window-size) +(define-opt autofit-smaller window-size) +(define-opt autoload-files? boolean) +(define-opt + autosync + enumeration + (or (memq val '(no)) + (and (integer? val) (>= val 0) (<= val 10000)))) +(define-opt + background + enumeration + (memq val '(none color tiles))) +(define-opt background-color color) +(define-opt + blend-subtitles + enumeration + (memq val '(no yes video))) +(define-opt bluray-device string) +(define-opt border? boolean) +(define-opt + border-background + enumeration + (memq val '(none color tiles))) +(define-opt + brightness + float + (>= val -100) + (<= val 100)) +(define-opt + cache + enumeration + (memq val '(no auto yes))) +(define-opt cache-on-disk? boolean) +(define-opt cache-pause? boolean) +(define-opt cache-pause-initial? boolean) +(define-opt cache-pause-wait float (>= val 0)) +(define-opt cache-secs double (>= val 0)) +(define-opt cdda-cdtext? boolean) +(define-opt cdda-device string) +(define-opt + cdda-overlap + integer + (>= val 0) + (<= val 75)) +(define-opt + cdda-paranoia + integer + (>= val 0) + (<= val 2)) +(define-opt + cdda-sector-size + integer + (>= val 1) + (<= val 100)) +(define-opt cdda-skip? boolean) +(define-opt cdda-span-a integer) +(define-opt cdda-span-b integer) +(define-opt + cdda-speed + integer + (>= val 1) + (<= val 100)) +(define-opt cdda-toc-offset integer) +(define-opt + chapter-merge-threshold + integer + (>= val 0) + (<= val 10000)) +(define-opt chapter-seek-threshold double) +(define-opt chapters-file string) +(define-opt config? boolean) +(define-opt + container-fps-override + double + (>= val 0)) +(define-opt + contrast + float + (>= val -100) + (<= val 100)) +(define-opt cookies? boolean) +(define-opt cookies-file string) +(define-opt + corner-rounding + float + (>= val 0) + (<= val 1)) +(define-opt correct-downscaling? boolean) +(define-opt correct-pts? boolean) +(define-opt + cover-art-auto + enumeration + (memq val '(no exact fuzzy all))) +(define-opt cover-art-files list-of-string) +(define-opt cover-art-whitelist list-of-string) +(define-opt + cscale + enumeration + (memq val + '(bilinear + bicubic_fast + oversample + spline16 + spline36 + spline64 + sinc + lanczos + ginseng + bicubic + hermite + catmull_rom + mitchell + robidoux + robidouxsharp + box + nearest + triangle + gaussian + jinc + ewa_lanczos + ewa_hanning + ewa_ginseng + ewa_lanczossharp + ewa_lanczos4sharpest + ewa_lanczossoft + haasnsoft + ewa_robidoux + ewa_robidouxsharp + bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx))) +(define-opt + cscale-antiring + float + (>= val 0) + (<= val 1)) +(define-opt cscale-blur float) +(define-opt + cscale-clamp + float + (>= val 0) + (<= val 1)) +(define-opt cscale-param1 float) +(define-opt cscale-param2 float) +(define-opt + cscale-radius + float + (>= val 0.5) + (<= val 16)) +(define-opt + cscale-taper + float + (>= val 0) + (<= val 1)) +(define-opt + cscale-window + enumeration + (memq val + '(bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt cscale-wparam float) +(define-opt + cscale-wtaper + float + (>= val 0) + (<= val 1)) +(define-opt + cursor-autohide + enumeration + (or (memq val '(no always)) + (and (integer? val) (>= val 0) (<= val 30000)))) +(define-opt cursor-autohide-fs-only? boolean) +(define-opt deband? boolean) +(define-opt + deband-grain + float + (>= val 0) + (<= val 4096)) +(define-opt + deband-iterations + integer + (>= val 0) + (<= val 16)) +(define-opt + deband-range + float + (>= val 1) + (<= val 64)) +(define-opt + deband-threshold + float + (>= val 0) + (<= val 4096)) +(define-opt + deinterlace + enumeration + (memq val '(no yes auto))) +(define-opt + deinterlace-field-parity + enumeration + (memq val '(tff bff auto))) +(define-opt demuxer string) +(define-opt + demuxer-backward-playback-step + double + (>= val 0)) +(define-opt demuxer-cache-dir string) +(define-opt + demuxer-cache-unlink-files + enumeration + (memq val '(immediate whendone no))) +(define-opt demuxer-cache-wait? boolean) +(define-opt demuxer-donate-buffer? boolean) +(define-opt + demuxer-hysteresis-secs + double + (>= val 0)) +(define-opt demuxer-lavf-allow-mimetype? boolean) +(define-opt + demuxer-lavf-analyzeduration + float + (>= val 0) + (<= val 3600)) +(define-opt + demuxer-lavf-buffersize + integer + (>= val 1) + (<= val 10485760)) +(define-opt demuxer-lavf-format string) +(define-opt demuxer-lavf-hacks? boolean) +(define-opt + demuxer-lavf-linearize-timestamps + enumeration + (memq val '(no auto yes))) +(define-opt demuxer-lavf-o list-of-key-value) +(define-opt + demuxer-lavf-probe-info + enumeration + (memq val '(no yes auto nostreams))) +(define-opt + demuxer-lavf-probescore + integer + (>= val 1) + (<= val 100)) +(define-opt + demuxer-lavf-probesize + integer + (>= val 32) + (<= val 2147483647)) +(define-opt demuxer-lavf-propagate-opts? boolean) +(define-opt + demuxer-max-back-bytes + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + demuxer-max-bytes + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + demuxer-mkv-probe-start-time? + boolean) +(define-opt + demuxer-mkv-probe-video-duration + enumeration + (memq val '(no yes full))) +(define-opt + demuxer-mkv-subtitle-preroll + enumeration + (memq val '(no yes index))) +(define-opt + demuxer-mkv-subtitle-preroll-secs + double + (>= val 0)) +(define-opt + demuxer-mkv-subtitle-preroll-secs-index + double + (>= val 0)) +(define-opt + demuxer-rawaudio-channels + audio-channels-or-channel-map) +(define-opt + demuxer-rawaudio-format + enumeration + (memq val + '(u8 s8 + u16le + u16be + s16le + s16be + u24le + u24be + s24le + s24be + u32le + u32be + s32le + s32be + floatle + floatbe + doublele + doublebe + u16 + s16 + u24 + s24 + u32 + s32 + float + double))) +(define-opt + demuxer-rawaudio-rate + integer + (>= val 1000) + (<= val 384000)) +(define-opt demuxer-rawvideo-codec string) +(define-opt demuxer-rawvideo-format fourcc) +(define-opt + demuxer-rawvideo-fps + float + (>= val 0.001) + (<= val 1000)) +(define-opt + demuxer-rawvideo-h + integer + (>= val 1) + (<= val 8192)) +(define-opt + demuxer-rawvideo-mp-format + image-format) +(define-opt + demuxer-rawvideo-size + integer + (>= val 1) + (<= val 268435456)) +(define-opt + demuxer-rawvideo-w + integer + (>= val 1) + (<= val 8192)) +(define-opt + demuxer-readahead-secs + double + (>= val 0)) +(define-opt + demuxer-seekable-cache + enumeration + (memq val '(auto no yes))) +(define-opt demuxer-termination-timeout double) +(define-opt demuxer-thread? boolean) +(define-opt + directory-filter-types + list-of-string) +(define-opt + directory-mode + enumeration + (memq val '(auto lazy recursive ignore))) +(define-opt + display-fps-override + double + (>= val 0)) +(define-opt display-tags list-of-string) +(define-opt + dither + enumeration + (memq val '(fruit ordered error-diffusion no))) +(define-opt + dither-depth + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val -1) (<= val 16)))) +(define-opt + dither-size-fruit + integer + (>= val 2) + (<= val 8)) +(define-opt + drag-and-drop + enumeration + (memq val '(no auto replace append insert-next))) +(define-opt drm-connector string) +(define-opt drm-device string) +(define-opt + drm-draw-plane + enumeration + (or (memq val '(primary overlay)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt drm-draw-surface-size window-size) +(define-opt + drm-drmprime-video-plane + enumeration + (or (memq val '(primary overlay)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt + drm-format + enumeration + (memq val + '(xrgb8888 xrgb2101010 xbgr8888 xbgr2101010 yuyv))) +(define-opt drm-mode string) +(define-opt + drm-vrr-enabled + enumeration + (memq val '(no yes auto))) +(define-opt + dscale + enumeration + (memq val + '(bilinear + bicubic_fast + oversample + spline16 + spline36 + spline64 + sinc + lanczos + ginseng + bicubic + hermite + catmull_rom + mitchell + robidoux + robidouxsharp + box + nearest + triangle + gaussian + jinc + ewa_lanczos + ewa_hanning + ewa_ginseng + ewa_lanczossharp + ewa_lanczos4sharpest + ewa_lanczossoft + haasnsoft + ewa_robidoux + ewa_robidouxsharp + bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx))) +(define-opt + dscale-antiring + float + (>= val 0) + (<= val 1)) +(define-opt dscale-blur float) +(define-opt + dscale-clamp + float + (>= val 0) + (<= val 1)) +(define-opt dscale-param1 float) +(define-opt dscale-param2 float) +(define-opt + dscale-radius + float + (>= val 0.5) + (<= val 16)) +(define-opt + dscale-taper + float + (>= val 0) + (<= val 1)) +(define-opt + dscale-window + enumeration + (memq val + '(bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt dscale-wparam float) +(define-opt + dscale-wtaper + float + (>= val 0) + (<= val 1)) +(define-opt dump-stats string) +(define-opt + dvbin-card + integer + (>= val 0) + (<= val 15)) +(define-opt dvbin-channel-switch-offset integer) +(define-opt dvbin-file string) +(define-opt dvbin-full-transponder? boolean) +(define-opt dvbin-prog string) +(define-opt + dvbin-timeout + integer + (>= val 1) + (<= val 30)) +(define-opt + dvd-angle + integer + (>= val 1) + (<= val 99)) +(define-opt dvd-device string) +(define-opt dvd-speed integer) +(define-opt + edition + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt egl-config-id integer) +(define-opt + egl-output-format + enumeration + (memq val + '(auto rgb8 + rgba8 + rgb10 + rgb10_a2 + rgb16 + rgba16 + rgb16f + rgba16f + rgb32f + rgba32f))) +(define-opt embeddedfonts? boolean) +(define-opt + end + relative-time-or-percent-position) +(define-opt error-diffusion string) +(define-opt external-files list-of-string) +(define-opt fbo-format string) +(define-opt + focus-on + enumeration + (memq val '(never open all))) +(define-opt force-media-title string) +(define-opt force-render? boolean) +(define-opt force-rgba-osd-rendering? boolean) +(define-opt force-seekable? boolean) +(define-opt + force-window + enumeration + (memq val '(no yes immediate))) +(define-opt force-window-position? boolean) +(define-opt + framedrop + enumeration + (memq val '(no vo decoder decoder+vo))) +(define-opt + frames + enumeration + (or (memq val '(all)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt + fs-screen + enumeration + (or (memq val '(all current)) + (and (integer? val) (>= val 0) (<= val 32)))) +(define-opt fs-screen-name string) +(define-opt fullscreen? boolean) +(define-opt + gamma + float + (>= val -100) + (<= val 100)) +(define-opt gamma-auto? boolean) +(define-opt + gamma-factor + float + (>= val 0.1) + (<= val 2)) +(define-opt + gamut-mapping-mode + enumeration + (memq val + '(auto clip + perceptual + relative + saturation + absolute + desaturate + darken + warn + linear))) +(define-opt + gapless-audio + enumeration + (memq val '(no yes weak))) +(define-opt geometry window-geometry) +(define-opt glsl-shader-opts list-of-key-value) +(define-opt glsl-shaders list-of-string) +(define-opt gpu-api list-of-object-setting) +(define-opt gpu-context list-of-object-setting) +(define-opt gpu-debug? boolean) +(define-opt + gpu-dumb-mode + enumeration + (memq val '(auto yes no))) +(define-opt gpu-hwdec-interop string) +(define-opt gpu-shader-cache? boolean) +(define-opt gpu-shader-cache-dir string) +(define-opt gpu-sw? boolean) +(define-opt + gpu-tex-pad-x + integer + (>= val 0) + (<= val 4096)) +(define-opt + gpu-tex-pad-y + integer + (>= val 0) + (<= val 4096)) +(define-opt + hdr-compute-peak + enumeration + (memq val '(auto yes no))) +(define-opt + hdr-contrast-recovery + float + (>= val 0) + (<= val 2)) +(define-opt + hdr-contrast-smoothness + float + (>= val 1) + (<= val 100)) +(define-opt + hdr-peak-decay-rate + float + (>= val 0) + (<= val 1000)) +(define-opt + hdr-peak-percentile + float + (>= val 0) + (<= val 100)) +(define-opt + hdr-scene-threshold-high + float + (>= val 0) + (<= val 20)) +(define-opt + hdr-scene-threshold-low + float + (>= val 0) + (<= val 20)) +(define-opt hidpi-window-scale? boolean) +(define-opt + hls-bitrate + enumeration + (or (memq val '(no min max)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt + hr-seek + enumeration + (memq val '(no absolute yes always default))) +(define-opt hr-seek-demuxer-offset float) +(define-opt hr-seek-framedrop? boolean) +(define-opt http-header-fields list-of-string) +(define-opt http-proxy string) +(define-opt hue float (>= val -100) (<= val 100)) +(define-opt hwdec list-of-string) +(define-opt hwdec-codecs string) +(define-opt + hwdec-extra-frames + integer + (>= val 0) + (<= val 256)) +(define-opt hwdec-image-format image-format) +(define-opt icc-3dlut-size string) +(define-opt icc-cache? boolean) +(define-opt icc-cache-dir string) +(define-opt + icc-force-contrast + enumeration + (or (memq val '(no inf)) + (and (integer? val) (>= val 0) (<= val 1000000)))) +(define-opt icc-intent integer) +(define-opt icc-profile string) +(define-opt icc-profile-auto? boolean) +(define-opt icc-use-luma? boolean) +(define-opt + idle + enumeration + (memq val '(no once yes))) +(define-opt + ignore-path-in-watch-later-config? + boolean) +(define-opt + image-display-duration + double + (>= val 0)) +(define-opt image-exts list-of-string) +(define-opt image-lut string) +(define-opt + image-lut-type + enumeration + (memq val '(auto native normalized conversion))) +(define-opt image-subs-video-resolution? boolean) +(define-opt include string) +(define-opt + index + enumeration + (memq val '(default recreate))) +(define-opt initial-audio-sync? boolean) +(define-opt input-ar-delay integer) +(define-opt input-ar-rate integer) +(define-opt input-builtin-bindings? boolean) +(define-opt input-builtin-dragging? boolean) +(define-opt input-commands list-of-string) +(define-opt input-conf string) +(define-opt input-cursor? boolean) +(define-opt input-cursor-passthrough? boolean) +(define-opt input-default-bindings? boolean) +(define-opt + input-doubleclick-time + integer + (>= val 0) + (<= val 1000)) +(define-opt input-dragging-deadzone integer) +(define-opt input-ipc-client string) +(define-opt input-ipc-server string) +(define-opt + input-key-fifo-size + integer + (>= val 2) + (<= val 65000)) +(define-opt input-media-keys? boolean) +(define-opt input-preprocess-wheel? boolean) +(define-opt input-right-alt-gr? boolean) +(define-opt input-terminal? boolean) +(define-opt input-test? boolean) +(define-opt input-touch-emulate-mouse? boolean) +(define-opt input-vo-keyboard? boolean) +(define-opt interpolation? boolean) +(define-opt interpolation-preserve? boolean) +(define-opt interpolation-threshold float) +(define-opt inverse-tone-mapping? boolean) +(define-opt jack-autostart? boolean) +(define-opt jack-connect? boolean) +(define-opt jack-name string) +(define-opt jack-port string) +(define-opt + jack-std-channel-layout + enumeration + (memq val '(waveext any))) +(define-opt + keep-open + enumeration + (memq val '(no yes always))) +(define-opt keep-open-pause? boolean) +(define-opt keepaspect? boolean) +(define-opt keepaspect-window? boolean) +(define-opt lavfi-complex string) +(define-opt + length + relative-time-or-percent-position) +(define-opt libplacebo-opts list-of-key-value) +(define-opt linear-downscaling? boolean) +(define-opt linear-upscaling? boolean) +(define-opt + load-auto-profiles + enumeration + (memq val '(no yes auto))) +(define-opt load-osd-console? boolean) +(define-opt load-scripts? boolean) +(define-opt load-select? boolean) +(define-opt load-stats-overlay? boolean) +(define-opt load-unsafe-playlists? boolean) +(define-opt log-file string) +(define-opt + loop-file + enumeration + (or (memq val '(no inf yes)) + (and (integer? val) (>= val 0) (<= val 10000)))) +(define-opt + loop-playlist + enumeration + (or (memq val '(no inf yes force)) + (and (integer? val) (>= val 1) (<= val 10000)))) +(define-opt lut string) +(define-opt + lut-type + enumeration + (memq val '(auto native normalized conversion))) +(define-opt mc float (>= val 0) (<= val 100)) +(define-opt + media-controls + enumeration + (memq val '(no player yes))) +(define-opt merge-files? boolean) +(define-opt metadata-codepage string) +(define-opt mf-fps double) +(define-opt mf-type string) +(define-opt + monitoraspect + float + (>= val 0) + (<= val 9)) +(define-opt + monitorpixelaspect + float + (>= val 0.03125) + (<= val 32)) +(define-opt msg-color? boolean) +(define-opt msg-level list-of-output-verbosity) +(define-opt msg-module? boolean) +(define-opt msg-time? boolean) +(define-opt mute? boolean) +(define-opt native-fs? boolean) +(define-opt native-keyrepeat? boolean) +(define-opt native-touch? boolean) +(define-opt network-timeout double (>= val 0)) +(define-opt oac string) +(define-opt oacopts list-of-key-value) +(define-opt ocopy-metadata? boolean) +(define-opt of string) +(define-opt ofopts list-of-key-value) +(define-opt on-all-workspaces? boolean) +(define-opt ontop? boolean) +(define-opt + ontop-level + enumeration + (or (memq val '(window system desktop)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt opengl-check-pattern-a integer) +(define-opt opengl-check-pattern-b integer) +(define-opt + opengl-early-flush + enumeration + (memq val '(no yes auto))) +(define-opt + opengl-es + enumeration + (memq val '(auto yes no))) +(define-opt opengl-glfinish? boolean) +(define-opt opengl-pbo? boolean) +(define-opt opengl-rectangle-textures? boolean) +(define-opt opengl-swapinterval integer) +(define-opt opengl-waitvsync? boolean) +(define-opt orawts? boolean) +(define-opt ordered-chapters? boolean) +(define-opt ordered-chapters-files string) +(define-opt oremove-metadata list-of-string) +(define-opt osc? boolean) +(define-opt + osd-align-x + enumeration + (memq val '(left center right))) +(define-opt + osd-align-y + enumeration + (memq val '(top center bottom))) +(define-opt osd-back-color color) +(define-opt osd-bar? boolean) +(define-opt + osd-bar-align-x + float + (>= val -1) + (<= val 1)) +(define-opt + osd-bar-align-y + float + (>= val -1) + (<= val 1)) +(define-opt + osd-bar-h + float + (>= val 0.1) + (<= val 50)) +(define-opt + osd-bar-outline-size + float + (>= val 0) + (<= val 1000)) +(define-opt + osd-bar-w + float + (>= val 1) + (<= val 100)) +(define-opt + osd-blur + float + (>= val 0) + (<= val 20)) +(define-opt osd-bold? boolean) +(define-opt + osd-border-style + enumeration + (memq val + '(outline-and-shadow opaque-box background-box))) +(define-opt osd-color color) +(define-opt + osd-duration + integer + (>= val 0) + (<= val 3600000)) +(define-opt osd-font string) +(define-opt + osd-font-provider + enumeration + (memq val '(auto none fontconfig))) +(define-opt + osd-font-size + float + (>= val 1) + (<= val 9000)) +(define-opt osd-fonts-dir string) +(define-opt osd-fractions? boolean) +(define-opt osd-italic? boolean) +(define-opt + osd-justify + enumeration + (memq val '(auto left center right))) +(define-opt + osd-level + enumeration + (memq val '(#{0}# #{1}# #{2}# #{3}#))) +(define-opt + osd-margin-x + integer + (>= val 0) + (<= val 300)) +(define-opt + osd-margin-y + integer + (>= val 0) + (<= val 600)) +(define-opt osd-msg1 string) +(define-opt osd-msg2 string) +(define-opt osd-msg3 string) +(define-opt + osd-on-seek + enumeration + (memq val '(no bar msg msg-bar))) +(define-opt osd-outline-color color) +(define-opt osd-outline-size float) +(define-opt osd-playing-msg string) +(define-opt + osd-playing-msg-duration + integer + (>= val 0) + (<= val 3600000)) +(define-opt + osd-playlist-entry + enumeration + (memq val '(title filename both))) +(define-opt + osd-scale + float + (>= val 0) + (<= val 100)) +(define-opt osd-scale-by-window? boolean) +(define-opt osd-shadow-offset float) +(define-opt + osd-spacing + float + (>= val -10) + (<= val 10)) +(define-opt osd-status-msg string) +(define-opt oset-metadata list-of-key-value) +(define-opt ovc string) +(define-opt ovcopts list-of-key-value) +(define-opt panscan float (>= val 0) (<= val 1)) +(define-opt pause? boolean) +(define-opt + pipewire-buffer + enumeration + (or (memq val '(native)) + (and (integer? val) (>= val 1) (<= val 2000)))) +(define-opt pipewire-remote string) +(define-opt + pipewire-volume-mode + enumeration + (memq val '(channel global))) +(define-opt + pitch + double + (>= val 0.01) + (<= val 100)) +(define-opt + play-direction + enumeration + (memq val '(forward + backward -))) +(define-opt + player-operation-mode + enumeration + (memq val '(cplayer pseudo-gui))) +(define-opt + playlist-start + enumeration + (or (memq val '(auto no)) + (and (integer? val) + (>= val 0) + (<= val 2147483647)))) +(define-opt prefetch-playlist? boolean) +(define-opt profile list-of-string) +(define-opt pulse-allow-suspended? boolean) +(define-opt + pulse-buffer + enumeration + (or (memq val '(native)) + (and (integer? val) (>= val 1) (<= val 2000)))) +(define-opt pulse-host string) +(define-opt pulse-latency-hacks? boolean) +(define-opt quiet? boolean) +(define-opt really-quiet? boolean) +(define-opt rebase-start-time? boolean) +(define-opt referrer string) +(define-opt + replaygain + enumeration + (memq val '(no track album))) +(define-opt replaygain-clip? boolean) +(define-opt + replaygain-fallback + float + (>= val -200) + (<= val 60)) +(define-opt + replaygain-preamp + float + (>= val -150) + (<= val 150)) +(define-opt reset-on-next-file list-of-string) +(define-opt resume-playback? boolean) +(define-opt resume-playback-check-mtime? boolean) +(define-opt + rtsp-transport + enumeration + (memq val '(lavf udp tcp http udp_multicast))) +(define-opt + saturation + float + (>= val -100) + (<= val 100)) +(define-opt save-position-on-quit? boolean) +(define-opt + scale + enumeration + (memq val + '(bilinear + bicubic_fast + oversample + spline16 + spline36 + spline64 + sinc + lanczos + ginseng + bicubic + hermite + catmull_rom + mitchell + robidoux + robidouxsharp + box + nearest + triangle + gaussian + jinc + ewa_lanczos + ewa_hanning + ewa_ginseng + ewa_lanczossharp + ewa_lanczos4sharpest + ewa_lanczossoft + haasnsoft + ewa_robidoux + ewa_robidouxsharp + bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx))) +(define-opt + scale-antiring + float + (>= val 0) + (<= val 1)) +(define-opt scale-blur float) +(define-opt + scale-clamp + float + (>= val 0) + (<= val 1)) +(define-opt scale-param1 float) +(define-opt scale-param2 float) +(define-opt + scale-radius + float + (>= val 0.5) + (<= val 16)) +(define-opt + scale-taper + float + (>= val 0) + (<= val 1)) +(define-opt + scale-window + enumeration + (memq val + '(bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt scale-wparam float) +(define-opt + scale-wtaper + float + (>= val 0) + (<= val 1)) +(define-opt scaler-resizes-only? boolean) +(define-opt + screen + enumeration + (or (memq val '(default)) + (and (integer? val) (>= val 0) (<= val 32)))) +(define-opt screen-name string) +(define-opt screenshot-avif-encoder string) +(define-opt + screenshot-avif-opts + list-of-key-value) +(define-opt screenshot-avif-pixfmt string) +(define-opt screenshot-directory string) +(define-opt + screenshot-format + enumeration + (memq val '(jpg jpeg png webp jxl avif))) +(define-opt screenshot-high-bit-depth? boolean) +(define-opt + screenshot-jpeg-quality + integer + (>= val 0) + (<= val 100)) +(define-opt + screenshot-jpeg-source-chroma? + boolean) +(define-opt + screenshot-jxl-distance + double + (>= val 0) + (<= val 15)) +(define-opt + screenshot-jxl-effort + integer + (>= val 1) + (<= val 9)) +(define-opt + screenshot-png-compression + integer + (>= val 0) + (<= val 9)) +(define-opt + screenshot-png-filter + integer + (>= val 0) + (<= val 5)) +(define-opt screenshot-sw? boolean) +(define-opt screenshot-tag-colorspace? boolean) +(define-opt screenshot-template string) +(define-opt + screenshot-webp-compression + integer + (>= val 0) + (<= val 6)) +(define-opt screenshot-webp-lossless? boolean) +(define-opt + screenshot-webp-quality + integer + (>= val 0) + (<= val 100)) +(define-opt script-opts list-of-key-value) +(define-opt scripts list-of-string) +(define-opt + secondary-sid + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt + secondary-sub-ass-override + enumeration + (memq val '(no yes scale force strip))) +(define-opt secondary-sub-delay float) +(define-opt + secondary-sub-pos + float + (>= val 0) + (<= val 150)) +(define-opt secondary-sub-visibility? boolean) +(define-opt sharpen float) +(define-opt show-in-taskbar? boolean) +(define-opt shuffle? boolean) +(define-opt + sub + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt + sigmoid-center + float + (>= val 0) + (<= val 1)) +(define-opt + sigmoid-slope + float + (>= val 1) + (<= val 20)) +(define-opt sigmoid-upscaling? boolean) +(define-opt slang list-of-string) +(define-opt snap-window? boolean) +(define-opt + speed + double + (>= val 0.01) + (<= val 100)) +(define-opt + spirv-compiler + enumeration + (memq val '(auto))) +(define-opt sstep double (>= val 0)) +(define-opt + start + relative-time-or-percent-position) +(define-opt + stop-playback-on-init-failure? + boolean) +(define-opt + stop-screensaver + enumeration + (memq val '(no yes always))) +(define-opt + stream-buffer-size + byte-size + (>= val 4096) + (<= val 536870912)) +(define-opt stream-dump string) +(define-opt stream-lavf-o list-of-key-value) +(define-opt stream-record string) +(define-opt stretch-dvd-subs? boolean) +(define-opt + stretch-image-subs-to-screen? + boolean) +(define-opt + sub-align-x + enumeration + (memq val '(left center right))) +(define-opt + sub-align-y + enumeration + (memq val '(top center bottom))) +(define-opt sub-ass? boolean) +(define-opt sub-ass-force-margins? boolean) +(define-opt + sub-ass-hinting + enumeration + (memq val '(none light normal native))) +(define-opt sub-ass-justify? boolean) +(define-opt + sub-ass-line-spacing + float + (>= val -1000) + (<= val 1000)) +(define-opt + sub-ass-override + enumeration + (memq val '(no yes scale force strip))) +(define-opt sub-ass-scale-with-window? boolean) +(define-opt + sub-ass-shaper + enumeration + (memq val '(simple complex))) +(define-opt + sub-ass-style-overrides + list-of-string) +(define-opt sub-ass-styles string) +(define-opt + sub-ass-use-video-data + enumeration + (memq val '(none aspect-ratio all))) +(define-opt + sub-ass-video-aspect-override + aspect + (>= val 0) + (<= val 10)) +(define-opt + sub-ass-vsfilter-color-compat + enumeration + (memq val '(no basic full force-601))) +(define-opt + sub-auto + enumeration + (memq val '(no exact fuzzy all))) +(define-opt sub-auto-exts list-of-string) +(define-opt sub-back-color color) +(define-opt + sub-blur + float + (>= val 0) + (<= val 20)) +(define-opt sub-bold? boolean) +(define-opt + sub-border-style + enumeration + (memq val + '(outline-and-shadow opaque-box background-box))) +(define-opt sub-clear-on-seek? boolean) +(define-opt sub-codepage string) +(define-opt sub-color color) +(define-opt sub-create-cc-track? boolean) +(define-opt sub-delay float) +(define-opt sub-demuxer string) +(define-opt sub-file-paths list-of-string) +(define-opt sub-files list-of-string) +(define-opt sub-filter-jsre list-of-string) +(define-opt sub-filter-regex list-of-string) +(define-opt sub-filter-regex-enable? boolean) +(define-opt sub-filter-regex-plain? boolean) +(define-opt sub-filter-regex-warn? boolean) +(define-opt sub-filter-sdh? boolean) +(define-opt sub-filter-sdh-enclosures string) +(define-opt sub-filter-sdh-harder? boolean) +(define-opt sub-fix-timing? boolean) +(define-opt sub-font string) +(define-opt + sub-font-provider + enumeration + (memq val '(auto none fontconfig))) +(define-opt + sub-font-size + float + (>= val 1) + (<= val 9000)) +(define-opt sub-fonts-dir string) +(define-opt sub-forced-events-only? boolean) +(define-opt sub-fps float) +(define-opt + sub-gauss + float + (>= val 0) + (<= val 3)) +(define-opt sub-gray? boolean) +(define-opt sub-italic? boolean) +(define-opt + sub-justify + enumeration + (memq val '(auto left center right))) +(define-opt sub-lavc-o list-of-key-value) +(define-opt + sub-margin-x + integer + (>= val 0) + (<= val 300)) +(define-opt + sub-margin-y + integer + (>= val 0) + (<= val 600)) +(define-opt sub-outline-color color) +(define-opt sub-outline-size float) +(define-opt sub-past-video-end? boolean) +(define-opt + sub-pos + float + (>= val 0) + (<= val 150)) +(define-opt + sub-scale + float + (>= val 0) + (<= val 100)) +(define-opt sub-scale-by-window? boolean) +(define-opt sub-scale-with-window? boolean) +(define-opt sub-shadow-offset float) +(define-opt + sub-spacing + float + (>= val -10) + (<= val 10)) +(define-opt sub-speed float) +(define-opt sub-stretch-durations? boolean) +(define-opt sub-use-margins? boolean) +(define-opt sub-visibility? boolean) +(define-opt sub-vsfilter-bidi-compat? boolean) +(define-opt + subs-fallback + enumeration + (memq val '(no default yes))) +(define-opt + subs-fallback-forced + enumeration + (memq val '(no yes always))) +(define-opt subs-match-os-language? boolean) +(define-opt + subs-with-matching-audio + enumeration + (memq val '(no forced yes))) +(define-opt + swapchain-depth + integer + (>= val 1) + (<= val 8)) +(define-opt sws-allow-zimg? boolean) +(define-opt sws-bitexact? boolean) +(define-opt + sws-cgb + float + (>= val 0) + (<= val 100)) +(define-opt sws-chs integer) +(define-opt + sws-cs + float + (>= val -100) + (<= val 100)) +(define-opt sws-cvs integer) +(define-opt sws-fast? boolean) +(define-opt + sws-lgb + float + (>= val 0) + (<= val 100)) +(define-opt + sws-ls + float + (>= val -100) + (<= val 100)) +(define-opt + sws-scaler + enumeration + (memq val + '(fast-bilinear + bilinear + bicubic + x + point + area + bicublin + gauss + sinc + lanczos + spline))) +(define-opt target-colorspace-hint? boolean) +(define-opt + target-contrast + enumeration + (or (memq val '(auto inf)) + (and (integer? val) (>= val 10) (<= val 1000000)))) +(define-opt + target-gamut + enumeration + (memq val + '(auto bt.601-525 + bt.601-625 + bt.709 + bt.2020 + bt.470m + apple + adobe + prophoto + cie1931 + dci-p3 + display-p3 + v-gamut + s-gamut + ebu3213 + film-c + aces-ap0 + aces-ap1))) +(define-opt target-lut string) +(define-opt + target-peak + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 10) (<= val 10000)))) +(define-opt + target-prim + enumeration + (memq val + '(auto bt.601-525 + bt.601-625 + bt.709 + bt.2020 + bt.470m + apple + adobe + prophoto + cie1931 + dci-p3 + display-p3 + v-gamut + s-gamut + ebu3213 + film-c + aces-ap0 + aces-ap1))) +(define-opt + target-trc + enumeration + (memq val + '(auto bt.1886 + srgb + linear + gamma1.8 + gamma2.0 + gamma2.2 + gamma2.4 + gamma2.6 + gamma2.8 + prophoto + pq + hlg + v-log + s-log1 + s-log2 + st428))) +(define-opt taskbar-progress? boolean) +(define-opt + teletext-page + integer + (>= val -1) + (<= val 999)) +(define-opt temporal-dither? boolean) +(define-opt + temporal-dither-period + integer + (>= val 1) + (<= val 128)) +(define-opt + term-osd + enumeration + (memq val '(force auto no))) +(define-opt term-osd-bar? boolean) +(define-opt term-osd-bar-chars string) +(define-opt term-playing-msg string) +(define-opt term-status-msg string) +(define-opt term-title string) +(define-opt terminal? boolean) +(define-opt title string) +(define-opt title-bar? boolean) +(define-opt tls-ca-file string) +(define-opt tls-cert-file string) +(define-opt tls-key-file string) +(define-opt tls-verify? boolean) +(define-opt + tone-mapping + enumeration + (memq val + '(auto clip + mobius + reinhard + hable + gamma + linear + spline + bt.2390 + bt.2446a + st2094-40 + st2094-10))) +(define-opt + tone-mapping-max-boost + float + (>= val 1) + (<= val 10)) +(define-opt tone-mapping-param float) +(define-opt tone-mapping-visualize? boolean) +(define-opt track-auto-selection? boolean) +(define-opt + tscale + enumeration + (memq val + '(oversample + linear + spline16 + spline36 + spline64 + sinc + lanczos + ginseng + bicubic + hermite + catmull_rom + mitchell + robidoux + robidouxsharp + box + nearest + triangle + gaussian + bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt + tscale-antiring + float + (>= val 0) + (<= val 1)) +(define-opt tscale-blur float) +(define-opt + tscale-clamp + float + (>= val 0) + (<= val 1)) +(define-opt tscale-param1 float) +(define-opt tscale-param2 float) +(define-opt + tscale-radius + float + (>= val 0.5) + (<= val 16)) +(define-opt + tscale-taper + float + (>= val 0) + (<= val 1)) +(define-opt + tscale-window + enumeration + (memq val + '(bartlett + cosine + hanning + tukey + hamming + quadric + welch + kaiser + blackman + sphinx + jinc))) +(define-opt tscale-wparam float) +(define-opt + tscale-wtaper + float + (>= val 0) + (<= val 1)) +(define-opt untimed? boolean) +(define-opt use-embedded-icc-profile? boolean) +(define-opt use-filedir-conf? boolean) +(define-opt user-agent string) +(define-opt vaapi-device string) +(define-opt vd string) +(define-opt vd-apply-cropping? boolean) +(define-opt vd-lavc-assume-old-x264? boolean) +(define-opt vd-lavc-bitexact? boolean) +(define-opt vd-lavc-check-hw-profile? boolean) +(define-opt + vd-lavc-dr + enumeration + (memq val '(auto no yes))) +(define-opt vd-lavc-fast? boolean) +(define-opt + vd-lavc-film-grain + enumeration + (memq val '(auto cpu gpu))) +(define-opt + vd-lavc-framedrop + enumeration + (memq val + '(none default nonref bidir nonkey all))) +(define-opt vd-lavc-o list-of-key-value) +(define-opt vd-lavc-show-all? boolean) +(define-opt + vd-lavc-skipframe + enumeration + (memq val + '(none default nonref bidir nonkey all))) +(define-opt + vd-lavc-skipidct + enumeration + (memq val + '(none default nonref bidir nonkey all))) +(define-opt + vd-lavc-skiploopfilter + enumeration + (memq val + '(none default nonref bidir nonkey all))) +(define-opt + vd-lavc-software-fallback + enumeration + (or (memq val '(no yes)) + (and (integer? val) + (>= val 1) + (<= val 2147483647)))) +(define-opt vd-lavc-threads integer (>= val 0)) +(define-opt vd-queue-enable? boolean) +(define-opt + vd-queue-max-bytes + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + vd-queue-max-samples + integer64 + (>= val 0)) +(define-opt vd-queue-max-secs double (>= val 0)) +(define-opt vf list-of-object-setting) +(define-opt + video + enumeration + (or (memq val '(no auto)) + (and (integer? val) (>= val 0) (<= val 8190)))) +(define-opt + video-align-x + float + (>= val -1) + (<= val 1)) +(define-opt + video-align-y + float + (>= val -1) + (<= val 1)) +(define-opt + video-aspect-method + enumeration + (memq val '(bitstream container))) +(define-opt + video-aspect-override + aspect + (>= val -1) + (<= val 10)) +(define-opt + video-backward-batch + integer + (>= val 0) + (<= val 1024)) +(define-opt + video-backward-overlap + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 0) (<= val 1024)))) +(define-opt video-crop video-rectangle) +(define-opt video-exts list-of-string) +(define-opt video-latency-hacks? boolean) +(define-opt + video-margin-ratio-bottom + float + (>= val 0) + (<= val 1)) +(define-opt + video-margin-ratio-left + float + (>= val 0) + (<= val 1)) +(define-opt + video-margin-ratio-right + float + (>= val 0) + (<= val 1)) +(define-opt + video-margin-ratio-top + float + (>= val 0) + (<= val 1)) +(define-opt video-osd? boolean) +(define-opt + video-output-levels + enumeration + (memq val '(auto limited full))) +(define-opt video-pan-x float) +(define-opt video-pan-y float) +(define-opt + video-reversal-buffer + byte-size + (>= val 0) + (<= val 4.6116860184274e18)) +(define-opt + video-rotate + enumeration + (or (memq val '(no)) + (and (integer? val) (>= val 0) (<= val 359)))) +(define-opt + video-scale-x + float + (>= val 0) + (<= val 10000)) +(define-opt + video-scale-y + float + (>= val 0) + (<= val 10000)) +(define-opt + video-sync + enumeration + (memq val + '(audio display-resample + display-resample-vdrop + display-resample-desync + display-tempo + display-adrop + display-vdrop + display-desync + desync))) +(define-opt + video-sync-max-audio-change + double + (>= val 0) + (<= val 1)) +(define-opt + video-sync-max-factor + integer + (>= val 1) + (<= val 10)) +(define-opt + video-sync-max-video-change + double + (>= val 0)) +(define-opt + video-timing-offset + double + (>= val 0) + (<= val 1)) +(define-opt + video-unscaled + enumeration + (memq val '(no yes downscale-big))) +(define-opt + video-zoom + float + (>= val -20) + (<= val 20)) +(define-opt vlang list-of-string) +(define-opt vo list-of-object-setting) +(define-opt vo-image-avif-encoder string) +(define-opt vo-image-avif-opts list-of-key-value) +(define-opt vo-image-avif-pixfmt string) +(define-opt + vo-image-format + enumeration + (memq val '(jpg jpeg png webp jxl avif))) +(define-opt vo-image-high-bit-depth? boolean) +(define-opt + vo-image-jpeg-quality + integer + (>= val 0) + (<= val 100)) +(define-opt vo-image-jpeg-source-chroma? boolean) +(define-opt + vo-image-jxl-distance + double + (>= val 0) + (<= val 15)) +(define-opt + vo-image-jxl-effort + integer + (>= val 1) + (<= val 9)) +(define-opt vo-image-outdir string) +(define-opt + vo-image-png-compression + integer + (>= val 0) + (<= val 9)) +(define-opt + vo-image-png-filter + integer + (>= val 0) + (<= val 5)) +(define-opt vo-image-tag-colorspace? boolean) +(define-opt + vo-image-webp-compression + integer + (>= val 0) + (<= val 6)) +(define-opt vo-image-webp-lossless? boolean) +(define-opt + vo-image-webp-quality + integer + (>= val 0) + (<= val 100)) +(define-opt vo-kitty-alt-screen? boolean) +(define-opt vo-kitty-cols integer) +(define-opt vo-kitty-config-clear? boolean) +(define-opt vo-kitty-height integer) +(define-opt vo-kitty-left integer) +(define-opt vo-kitty-rows integer) +(define-opt vo-kitty-top integer) +(define-opt vo-kitty-use-shm? boolean) +(define-opt vo-kitty-width integer) +(define-opt + vo-null-fps + double + (>= val 0) + (<= val 10000)) +(define-opt vo-sixel-alt-screen? boolean) +(define-opt vo-sixel-buffered? boolean) +(define-opt vo-sixel-cols integer) +(define-opt vo-sixel-config-clear? boolean) +(define-opt + vo-sixel-dither + enumeration + (memq val + '(auto none + atkinson + fs + jajuni + stucki + burkes + arithmetic + xor))) +(define-opt vo-sixel-fixedpalette? boolean) +(define-opt vo-sixel-height integer) +(define-opt vo-sixel-left integer) +(define-opt vo-sixel-pad-x integer) +(define-opt vo-sixel-pad-y integer) +(define-opt vo-sixel-reqcolors integer) +(define-opt vo-sixel-rows integer) +(define-opt vo-sixel-threshold integer) +(define-opt vo-sixel-top integer) +(define-opt vo-sixel-width integer) +(define-opt vo-tct-256? boolean) +(define-opt + vo-tct-algo + enumeration + (memq val '(plain half-blocks))) +(define-opt + vo-tct-buffering + enumeration + (memq val '(pixel line frame))) +(define-opt vo-tct-height integer) +(define-opt vo-tct-width integer) +(define-opt vo-vaapi-scaled-osd? boolean) +(define-opt + vo-vaapi-scaling + enumeration + (memq val '(default fast hq nla))) +(define-opt vo-vdpau-chroma-deint? boolean) +(define-opt vo-vdpau-colorkey color) +(define-opt vo-vdpau-composite-detect? boolean) +(define-opt + vo-vdpau-denoise + float + (>= val 0) + (<= val 1)) +(define-opt vo-vdpau-force-yuv? boolean) +(define-opt vo-vdpau-fps double) +(define-opt + vo-vdpau-hqscaling + integer + (>= val 0) + (<= val 9)) +(define-opt + vo-vdpau-output-surfaces + integer + (>= val 2) + (<= val 15)) +(define-opt vo-vdpau-pullup? boolean) +(define-opt vo-vdpau-queuetime-fs integer) +(define-opt vo-vdpau-queuetime-windowed integer) +(define-opt + vo-vdpau-sharpen + float + (>= val -1) + (<= val 1)) +(define-opt + volume + float + (>= val -1) + (<= val 1000)) +(define-opt + volume-gain + float + (>= val -150) + (<= val 150)) +(define-opt + volume-gain-max + float + (>= val 0) + (<= val 150)) +(define-opt + volume-gain-min + float + (>= val -150) + (<= val 0)) +(define-opt + volume-max + float + (>= val 100) + (<= val 1000)) +(define-opt vulkan-async-compute? boolean) +(define-opt vulkan-async-transfer? boolean) +(define-opt vulkan-device string) +(define-opt vulkan-display-display integer) +(define-opt vulkan-display-mode integer) +(define-opt vulkan-display-plane integer) +(define-opt + vulkan-queue-count + integer + (>= val 1) + (<= val 8)) +(define-opt + vulkan-swap-mode + enumeration + (memq val + '(auto fifo fifo-relaxed mailbox immediate))) +(define-opt watch-later-directory string) +(define-opt watch-later-options list-of-string) +(define-opt wayland-app-id string) +(define-opt + wayland-configure-bounds + enumeration + (memq val '(auto no yes))) +(define-opt + wayland-content-type + enumeration + (memq val '(auto none photo video game))) +(define-opt wayland-disable-vsync? boolean) +(define-opt + wayland-edge-pixels-pointer + integer + (>= val 0) + (<= val 2147483647)) +(define-opt + wayland-edge-pixels-touch + integer + (>= val 0) + (<= val 2147483647)) +(define-opt wayland-present? boolean) +(define-opt wid integer64) +(define-opt window-dragging? boolean) +(define-opt window-maximized? boolean) +(define-opt window-minimized? boolean) +(define-opt + window-scale + double + (>= val 0.001) + (<= val 100)) +(define-opt + write-filename-in-watch-later-config? + boolean) +(define-opt + x11-bypass-compositor + enumeration + (memq val '(no yes fs-only never))) +(define-opt x11-name string) +(define-opt + x11-netwm + enumeration + (memq val '(auto no yes))) +(define-opt + x11-present + enumeration + (memq val '(no auto yes))) +(define-opt x11-wid-title? boolean) +(define-opt xv-adaptor integer (>= val -1)) +(define-opt + xv-buffers + integer + (>= val 1) + (<= val 10)) +(define-opt + xv-ck + enumeration + (memq val '(use set cur))) +(define-opt + xv-ck-method + enumeration + (memq val '(none bg man auto))) +(define-opt xv-colorkey integer) +(define-opt xv-port integer (>= val 0)) +(define-opt ytdl? boolean) +(define-opt ytdl-format string) +(define-opt ytdl-raw-options list-of-key-value) +(define-opt + zimg-dither + enumeration + (memq val '(no ordered random error-diffusion))) +(define-opt zimg-fast? boolean) +(define-opt + zimg-scaler + enumeration + (memq val + '(point bilinear + bicubic + spline16 + spline36 + lanczos))) +(define-opt + zimg-scaler-chroma + enumeration + (memq val + '(point bilinear + bicubic + spline16 + spline36 + lanczos))) +(define-opt zimg-scaler-chroma-param-a double) +(define-opt zimg-scaler-chroma-param-b double) +(define-opt zimg-scaler-param-a double) +(define-opt zimg-scaler-param-b double) +(define-opt + zimg-threads + enumeration + (or (memq val '(auto)) + (and (integer? val) (>= val 1) (<= val 64)))) +;;; Generated code - END. + +(define-record-type <mpv-profile-configuration> + (%make-mpv-profile-configuration data) + mpv-profile-configuration? + (data %mpv-profile-configuration-data)) + +(define (make-mpv-profile-configuration . args) + ;; I am not sure how can I copy a hash-map. Documentation does not mention + ;; anything. + (let ((new (make-hash-table))) + (let loop ((args args)) + (match args + ((#:inherit cfg . tail) + (hash-for-each (lambda (key val) + (hashq-set! new key val)) + (%mpv-profile-configuration-data cfg)) + (loop tail)) + (((? keyword? key) val . tail) + (let* ((key (keyword->symbol key)) + (opt (hashq-ref %opts key))) + (unless opt + (raise-exception + (formatted-message + (G_ "option ~a not found for mpv-profile-configuration") key))) + (if (maybe-value-set? val) + (if ((profile-option-type-check opt) val) + (hashq-set! new key (cons val + (profile-option-serializer opt))) + (raise-exception + (formatted-message + (G_ "invalid mpv configuration for ~a: ~a~%") + key val))) + (hashq-remove! new key))) + (loop tail)) + (() + (%make-mpv-profile-configuration new)))))) + +(define (serialize-mpv-profile-configuration _ cfg) + (let ((sorted (sort + (hash-map->list cons (%mpv-profile-configuration-data cfg)) + (lambda (a b) + (string<? (symbol->string (car a)) + (symbol->string (car b))))))) + #~(string-append + #$@(map (match-lambda + ((field-name . value) + ((cdr value) field-name (car value)))) + sorted)))) + + + + +;;; +;;; Configuration base. +;;; +(define (serialize-mpv/mpv-profile-configurations _ profiles) + #~(string-append + #$@(map (match-lambda + ((name . config) + #~(string-append + #$(format #f "[~a]~%" name) + #$(serialize-mpv-profile-configuration _ config)))) + profiles))) +(define (mpv/mpv-profile-configurations? alist) + (and (list? alist) + (every (match-lambda + (((? symbol?) . (? mpv-profile-configuration?)) #t) + (_ #f)) + alist))) + +(define (serialize-mpv/extra _ value) + (if value + #~(string-append #$value + ;; Ensure the extra content ends in a new line. + #$(if (string-suffix? "\n" value) + "" "\n")) + #~"")) +(define (mpv/extra? val) + (or (string? val) + (gexp? val))) + +(define-record-type <home-mpv-configuration> + (%make-home-mpv-configuration global profiles extra-config) + home-mpv-configuration? + (global home-mpv-configuration-global) + (profiles home-mpv-configuration-profiles) + (extra-config home-mpv-configuration-extra-config)) + +(define* (make-home-mpv-configuration + #:key + (inherit #f) + (global (if inherit + (home-mpv-configuration-global inherit) + (make-mpv-profile-configuration))) + (profiles (if inherit + (home-mpv-configuration-profiles inherit) + '())) + (extra-config (if inherit + (home-mpv-configuration-extra-config inherit) + #f))) + (unless (mpv-profile-configuration? global) + (raise-exception + (formatted-message + (G_ "global must satisfy mpv-profile-configuration?")))) + (unless (mpv/mpv-profile-configurations? profiles) + (raise-exception + (formatted-message + (G_ "profiles must be an alist of mpv-profile-configuration?")))) + (unless (or (not extra-config) (mpv/extra? extra-config)) + (raise-exception + (formatted-message + (G_ "extra-config must be a string or a gexp")))) + (%make-home-mpv-configuration global profiles extra-config)) + +(define (serialize-home-mpv-configuration cfg) + #~(string-append #$(serialize-mpv-profile-configuration + 'global + (home-mpv-configuration-global cfg)) + #$(serialize-mpv/mpv-profile-configurations + 'profiles + (home-mpv-configuration-profiles cfg)) + #$(serialize-mpv/extra + 'extra-config + (home-mpv-configuration-extra-config cfg)))) + +(define (mpv-configuration-files cfg) + `(("mpv/mpv.conf" ,(mixed-text-file "mpv.conf" + (serialize-home-mpv-configuration cfg))))) + +(define home-mpv-service-type + (service-type + (name 'home-mpv) + (extensions + (list (service-extension home-xdg-configuration-files-service-type + mpv-configuration-files))) + (description + "Install configuration files for mpv into XDG configuration directory."))) diff --git a/gnu/local.mk b/gnu/local.mk index e6ece8cc48..d132e79ad2 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -113,6 +113,7 @@ GNU_SYSTEM_MODULES = \ %D%/home/services/mail.scm \ %D%/home/services/media.scm \ %D%/home/services/messaging.scm \ + %D%/home/services/mpv.scm \ %D%/home/services/music.scm \ %D%/home/services/pm.scm \ %D%/home/services/shells.scm \ -- 2.49.0
guix-patches <at> gnu.org
:bug#74801
; Package guix-patches
.
(Mon, 12 May 2025 16:34:02 GMT) Full text and rfc822 format available.Message #56 received at 74801 <at> debbugs.gnu.org (full text, mbox):
From: Tomas Volf <~@wolfsden.cz> To: Ludovic Courtès <ludo <at> gnu.org> Cc: Tanguy Le Carrour <tanguy <at> bioneland.org>, Maxim Cournoyer <maxim.cournoyer <at> gmail.com>, Gabriel Wicki <gabriel <at> erlikon.ch>, Andrew Tropin <andrew <at> trop.in>, Hilton Chain <hako <at> ultrarare.space>, 74801 <at> debbugs.gnu.org, Janneke Nieuwenhuizen <janneke <at> gnu.org> Subject: Re: bug#74801: [PATCH] gnu: home: services: Add home-mpv-service-type. Date: Mon, 12 May 2025 18:33:14 +0200
Ludovic Courtès <ludo <at> gnu.org> writes: >> + #:global (make-mpv-profile-configuration >> + #:fullscreen #t > > Are we missing a question mark? > >> + #:profiles `((fullscreen . ,(make-mpv-profile-configuration >> + #:fullscreen #t)))) > > Here also. Yes, you are right. I forgot to add the ? into the documentation as well. Fixed in v4. Sorry. :/ Tomas -- There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors.
Maxim Cournoyer <maxim.cournoyer <at> gmail.com>
:Tomas Volf <~@wolfsden.cz>
:Message #61 received at 74801-done <at> debbugs.gnu.org (full text, mbox):
From: Maxim Cournoyer <maxim.cournoyer <at> gmail.com> To: Tomas Volf <~@wolfsden.cz> Cc: Tanguy Le Carrour <tanguy <at> bioneland.org>, Ludovic Courtès <ludo <at> gnu.org>, Gabriel Wicki <gabriel <at> erlikon.ch>, Andrew Tropin <andrew <at> trop.in>, Hilton Chain <hako <at> ultrarare.space>, Janneke Nieuwenhuizen <janneke <at> gnu.org>, 74801-done <at> debbugs.gnu.org Subject: Re: [bug#74801] [PATCH] gnu: home: services: Add home-mpv-service-type. Date: Tue, 13 May 2025 10:57:12 +0900
Hi, Tomas Volf <~@wolfsden.cz> writes: > Ludovic Courtès <ludo <at> gnu.org> writes: > >>> + #:global (make-mpv-profile-configuration >>> + #:fullscreen #t >> >> Are we missing a question mark? >> >>> + #:profiles `((fullscreen . ,(make-mpv-profile-configuration >>> + #:fullscreen #t)))) >> >> Here also. > > Yes, you are right. I forgot to add the ? into the documentation as > well. Fixed in v4. Sorry. :/ Applied, at last! Thanks to everyone involved. -- Maxim
guix-patches <at> gnu.org
:bug#74801
; Package guix-patches
.
(Fri, 23 May 2025 11:28:01 GMT) Full text and rfc822 format available.Message #64 received at 74801 <at> debbugs.gnu.org (full text, mbox):
From: Sergey Trofimov <sarg <at> sarg.org.ru> To: Tomas Volf <~@wolfsden.cz> Cc: 74801 <at> debbugs.gnu.org Subject: Re: [bug#74801] [PATCH v4] gnu: home: services: Add home-mpv-service-type. Date: Fri, 23 May 2025 13:27:21 +0200
Hi Tomas, Tomas Volf <~@wolfsden.cz> writes: > This commit adds a new service type to generate configuration file for the mpv > media player. > I've just noticed this got merged and tried to use it in my config. I've mostly translated the config, but stumbled on the scripts settings: --8<---------------cut here---------------start------------->8--- (service home-mpv-service-type (make-home-mpv-configuration #:global (make-mpv-profile-configuration #:scripts (list (file-append #$mpv-mpris "/lib/mpris.so") (file-append #$mpv-thumbfast "/share/mpv/scripts/thumbfast.lua") (file-append #$mpv-uosc "/share/mpv/scripts/uosc"))))) --8<---------------cut here---------------end--------------->8--- Such config doesn't work as `scripts` option is of `list-of-string` type. I've also tried to workaround with `#:extra-config #~(...)`, but this didn't work either, raising an error in `string-suffix?`. To make it work, I think a new "file" type is necessary, which would allow gexps. Options that are marked as "[file]" (`mpv --list-options | grep -F "[file]"`) should assume this new type.
guix-patches <at> gnu.org
:bug#74801
; Package guix-patches
.
(Fri, 23 May 2025 12:51:02 GMT) Full text and rfc822 format available.Message #67 received at 74801 <at> debbugs.gnu.org (full text, mbox):
From: Tomas Volf <~@wolfsden.cz> To: Sergey Trofimov <sarg <at> sarg.org.ru> Cc: 74801 <at> debbugs.gnu.org Subject: Re: [bug#74801] [PATCH v4] gnu: home: services: Add home-mpv-service-type. Date: Fri, 23 May 2025 14:50:47 +0200
Hi Sergey, Sergey Trofimov <sarg <at> sarg.org.ru> writes: > Hi Tomas, > > Tomas Volf <~@wolfsden.cz> writes: > >> This commit adds a new service type to generate configuration file for the mpv >> media player. >> > > I've just noticed this got merged and tried to use it in my config. I've > mostly translated the config, but stumbled on the scripts settings: > > (service home-mpv-service-type > (make-home-mpv-configuration > #:global (make-mpv-profile-configuration > #:scripts > (list > (file-append #$mpv-mpris "/lib/mpris.so") > (file-append #$mpv-thumbfast "/share/mpv/scripts/thumbfast.lua") > (file-append #$mpv-uosc "/share/mpv/scripts/uosc"))))) > > Such config doesn't work as `scripts` option is of `list-of-string` > type. I've also tried to workaround with `#:extra-config #~(...)`, but > this didn't work either, raising an error in `string-suffix?`. > > To make it work, I think a new "file" type is necessary, which would > allow gexps. Options that are marked as "[file]" (`mpv --list-options | > grep -F "[file]"`) should assume this new type. I agree. Could you please report this as a separate bug and CC me on it? I will take a look, hopefully over the weekend. Thanks, Tomas -- There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.