Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MPVonCrack

An mpv build that upscales with neural nets, interpolates to 120fps, streams torrents through Real-Debrid without downloading them, and renders live Twitch/Kick chat with real emotes inside the video window.

output.mp4

Double-click a .torrent file → it plays. Paste a magnet → it plays. Open a Twitch link → chat appears next to the video. Hit F1 → the anime you're watching gets run through a GAN in real time.

Built on hooke007's mpv_PlayKit / MPV_lazy with a pile of custom Lua on top.


⬇️ Download

The entire player lives here — mpv.exe, yt-dlp.exe, a bundled Python, every plugin, shader and script, and all 56 AI models. No installer, nothing written to your registry, nothing to install alongside it. Fully portable; a USB stick is fine.

Two ways to get it:

Everything, including the NVIDIA CUDA runtime. Grab all three MPVonCrack-FULL parts into one folder, right-click the .001, extract, run mpv.exe. AI upscaling works immediately, nothing else to set up.

(It's in parts because GitHub caps one file at 2 GB — 7-Zip rejoins them on its own. Windows 11 opens .7z natively; otherwise get 7-Zip.)

⚪ Or clone the repo (~1.2 GB)

git clone https://github.com/Kristijan1001/MPVonCrack.git

Same player, minus the CUDA runtime. Everything works except neural upscaling and RIFE — for those, add the MPVonCrack-vsmlrt-cuda parts from Releases as described in Setup.


Table of contents


What's in the box

Feature Where it lives
🧲 Play .torrent files and magnet links via Real-Debrid or TorBox — no download, no torrent client scripts/Custom_Torrent_*.lua
🔀 Switch debrid provider from the menu, persists across restarts scripts/Custom_Debrid_Provider.lua
💬 Live Twitch and Kick chat rendered inside mpv, with animated 7TV/BTTV/FFZ emotes scripts/twitch_chat/
🔍 Real-time neural upscaling — Real-ESRGAN, AnimeJaNai, Real-CUGAN, ArtCNN vs/Upscale/
🎞️ Real-time frame interpolation — RIFE 4.6 / 4.25 / 4.26, 2× and 3× vs/FrameInterpolation/
30+ GLSL shaders — Anime4K, FSRCNNX, NNEDI3, AMD FSR, adaptive sharpening shaders/
🖥️ NVIDIA RTX Video Super Resolution + RTX True HDR (SDR→HDR) input_uosc.conf, Custom_NVIDIA_RTX_HDR.lua
🧹 Denoise, deinterlace, grain removal, anti-aliasing presets vs/Cleaning/
📺 .strm bulk playlists with smart episode sorting (Jellyfin-friendly) scripts/Custom_Bulk_STRM_Files_Player.lua
🥽 360° / VR video with mouse-look scripts/mpv360.lua
📱 Picture-in-Picture / vertical phone mode with edge snapping scripts/Custom_Phone_PiP_Mode.lua
🖱️ Scroll-wheel playlist navigation that skips folder headers and saves resume points scripts/Custom_Torrent_Unified_Navigation.lua
🎛️ uosc UI + right-click mega-menu with every preset one click away scripts/uosc/, input_uosc.conf

Requirements

OS Windows 10/11 (x64)
Just watching video Any GPU. Works out of the box.
GLSL shaders (Anime4K, FSR, NNEDI3) Any modern GPU — AMD, Intel or NVIDIA
AI upscaling + RIFE NVIDIA only, RTX 20-series or newer. The .vpy presets use TensorRT.
VRAM 6 GB minimum for 1080p→4K ESRGAN, 8 GB+ comfortable
RTX VSR / True HDR RTX 20-series+, enabled in the NVIDIA Control Panel
Torrent streaming A paid Real-Debrid or TorBox account + API token. Free tiers can't stream.

On AMD or Intel? Everything works except the vs/ AI presets. Use the GLSL shaders instead — Anime4K AIO (Ctrl+0) is genuinely excellent and costs a fraction of the performance.


Setup

  1. Extract anywhere and run mpv.exe.
  2. Right-click for the menu — every preset lives there.
  3. For torrent streaming, add a Real-Debrid or TorBox token.

That's it. Playback, GLSL shaders, live chat, PiP and VR all work immediately.

Adding the CUDA runtime

Only needed if you cloned the repo instead of taking the full build, and only if you want the neural upscaling or RIFE interpolation.

  1. Download MPVonCrack-vsmlrt-cuda.7z.001 and .002 from Releases into the same folder.
  2. Right-click the .001 and extract.
  3. Move the vsmlrt-cuda folder into vs-plugins/, so you have vs-plugins/vsmlrt-cuda/nvinfer_10.dll.
  4. Restart mpv and press F1 on a video.

The first press of any AI preset looks like a freeze — mpv is compiling a TensorRT engine for your specific GPU. It happens once per preset, then it's instant forever.


Debrid setup — Real-Debrid & TorBox

Both services are supported. Set up whichever you have (or both, and switch between them).

Real-Debrid

  1. Log in and open https://real-debrid.com/apitoken
  2. Copy the token.
  3. In portable_config/script-opts/, copy realdebrid.conf.examplerealdebrid.conf
  4. Set api_key=YOUR_TOKEN_HERE
  5. Restart mpv.

TorBox

  1. Log in and open https://torbox.app/settings
  2. Copy the API key.
  3. In portable_config/script-opts/, copy torbox.conf.exampletorbox.conf
  4. Set api_key=YOUR_TOKEN_HERE
  5. Switch the provider (below), then restart mpv.

Switching between them

.torrent files are handled by one provider at a time — whichever script-opts/debrid.conf names:

provider=realdebrid    # or: torbox

You don't have to edit that by hand:

Ctrl+Shift+D Toggle Real-Debrid ⇄ TorBox
Menu → Streaming → Switch Provider Same thing
Menu → Streaming → Use Real-Debrid / Use TorBox Pick one directly
Menu → Streaming → Show Current Provider Check which is live

The choice is written to disk the moment you switch, so the next time you double-click a .torrent — even after a reboot — it uses the provider you picked. No "apply" step, no restart needed for the switch itself.

Only one provider can be active at a time — running both at once makes them fight over the same .torrent.

Magnet links always go through Real-Debrid, whatever this is set to. That's the only magnet streamer here, so switching to TorBox doesn't take magnets away from you.

Tokens are never in the .lua files

Each script calls a load_*_api_key() that reads its script-opts/*.conf, then falls back to an environment variable (REALDEBRID_API_KEY / TORBOX_API_KEY), then gives up with an on-screen error. Both conf files are gitignored, so you can fork this and push without leaking anything.

⚠️ If you ever paste a token directly into a .lua file and push it anywhere, revoke it. Real-Debrid tokens don't expire on their own — go back to the API token page and generate a new one.


Streaming torrents & magnets

Two scripts, one account, two entry points. Neither downloads anything to your disk — Real-Debrid holds the files and serves them over HTTP, and mpv seeks into them like a local file.

.torrent files — Custom_Torrent_Real_Derbid_Streaming.lua

Just double-click a .torrent file. That's the whole workflow.

What happens under the hood:

  1. Read the folder. Every .torrent in the same directory is picked up, not just the one you clicked — so a season folder becomes one playlist.
  2. Cache check. _cache/rdcache/rd_torrent_cache.json is consulted first. A hit means playback starts instantly with zero API calls.
  3. On a miss, the torrent is PUT to torrents/addTorrent, video/audio files are selected via torrents/selectFiles (filtered by extension, trailer excluded), and the resulting links are stored.
  4. A session .m3u8 is written, with each torrent name as a header row and its episodes nested under it.
  5. On playback, the on_load hook calls unrestrict/link to turn the RD link into a real streamable URL.
  6. The torrent is deleted from your RD account once links are extracted, so your RD torrent list doesn't fill up.

Expired-link auto-recovery (v21): Real-Debrid /d/ links go stale. When one fails to unrestrict, the script re-adds that torrent to mint fresh links. If RD still has the content cached it recovers instantly and keeps playing; if not, it queues the caching and skips ahead to the episodes that are ready, so the playlist doesn't stall on one dead file. The on-disk cache is rewritten with the new links.

Key Action
Ctrl+Shift+F8 Add a whole folder of torrents to your RD cloud (pre-cache a season before bed)
Ctrl+Shift+Alt+Z Clear the torrent link cache
Menu → Streaming Show cache info

Magnet links — Custom_Torrent_Magnet_Streaming.lua

Four ways in:

  1. Paste it like a YouTube link. Ctrl+Shift+V loads whatever's on your clipboard. Fastest path.
  2. Ctrl+Shift+M — "Paste & Play Magnet". Handles several magnets at once.
  3. A .magnet text file — one magnet per line, open it in mpv.
  4. A raw magnet:?xt=... URI from the command line or a browser handler.

Because RD doesn't dedupe magnets by infohash, this script does extra work:

  • find_existing_torrent(hash) queries GET /torrents before adding anything. If you already started caching this magnet in a previous session, it reattaches to that download instead of starting a duplicate from 0%.
  • Non-blocking resolution. Caching runs on a timer-driven state machine polling every 2s for up to ~10 minutes. mpv stays fully responsive and shows Caching on RD… 47% (12 seeders) on screen. The seeder count is displayed so a dead magnet is obvious immediately.
  • It never deletes a torrent mid-download. Only on success or a fatal status. A partially-cached magnet is left on RD so re-pasting later is instant.
  • Results don't hijack playback. Start a normal video while a magnet caches in the background and the magnet won't steal the window when it finishes.
Key Action
Ctrl+Shift+M Paste & play magnet from clipboard
Ctrl+Shift+V Load clipboard URL (magnets, YouTube, anything)
Menu → Streaming Show / clear magnet cache

TorBox — Custom_Torrent_TorBox_Streaming.lua

Set provider=torbox (or hit Ctrl+Shift+D) and .torrent files go through TorBox instead. Same workflow: double-click a torrent, the whole folder becomes a playlist.

It uploads the torrent via torrents/createtorrent, polls torrents/mylist until TorBox reports it cached, and resolves each file through torrents/requestdl at playback time (with 3 retries). Playlist entries use a torbox://<torrent_id>/<file_id> virtual scheme so it never collides with the Real-Debrid hooks. Cache lives in _cache/tbcache/.

If TorBox doesn't already have the torrent cached, it fetches it first — you get live Caching on TorBox… 47% (12 seeders) progress on screen, and it gives up quickly on dead torrents rather than hanging.

Key Action
Ctrl+Shift+D Switch provider
Menu → Streaming Show / clear TorBox cache

Scroll-wheel navigation

Both scripts build playlists with header rows (the torrent/folder name) above their episodes. Custom_Torrent_Unified_Navigation.lua binds the mouse wheel to skip those headers automatically and forces a watch-later save before every jump — so your resume position in episode 3 survives scrolling to episode 4 and back.

Input Action
Wheel Up / Wheel Down Previous / next item (skips headers)
Mouse Back / Forward Previous / next

.strm bulk playlists

Custom_Bulk_STRM_Files_Player.lua — for Jellyfin/Emby .strm libraries.

Open any .strm file and every .strm in that folder is expanded into one playlist, with each file's URLs sorted by a priority scoring pass:

Score Matches Result
1 S01E05, 1x05, EP12, 001 Real episodes — first
2 everything else Movies / specials
4 trailer, sample, promo, NCOP, NCED, bonus, featurette, interview, preview, OVA Junk — pushed down
5 .flac, .mp3, .jpg, .nfo, .srt Non-video — last

Within a bucket it sorts naturally, so Episode 2 comes before Episode 10.

It runs in isolation mode: it keeps a whitelist of URLs it created and refuses to touch any path it doesn't own, so it can never interfere with the torrent scripts.


Live chat overlay — Twitch & Kick

scripts/twitch_chat/ — live chat rendered inside the video window, with real emote images.

Open twitch.tv/<channel> or kick.com/<channel> in mpv and chat appears down the right side. Works fullscreen. Works on a second monitor. No browser.

Nothing to install — the Python runtime, Pillow and websocket-client all ship in the bundle.

Why it's an image and not text

libass (mpv's subtitle renderer) cannot inline images. Any ASS-based chat overlay is text-only, which means no emotes — and on Twitch that's most of the conversation.

So this doesn't use ASS. chat_render.py connects to chat, composites the whole visible chat column — bold coloured usernames, white outlined text, inline emote bitmaps — into a raw BGRA buffer with Pillow, and main.lua blits it with mpv's overlay-add (the same mechanism thumbfast uses for its thumbnails).

Two details that matter if you ever modify it:

  • overlay-add with bgra expects premultiplied alpha. Feeding straight alpha makes every semi-transparent emote edge glow magenta. Every RGB channel is multiplied by alpha before writing.
  • Overwriting a .bgra file while mpv is reading it crashes the player. Each frame is written to a fresh filename; only frame n−2 is deleted.

Overlay ID is 63 (thumbfast owns 42; mpv rejects IDs above 63).

Twitch

Connects to Twitch IRC as an anonymous justinfan guest — read-only, no token, no login, nothing to leak. Native emotes come from the IRC emotes tag; 7TV, BetterTTV and FrankerFaceZ are fetched globally at startup and per-channel once the room-id arrives.

Kick

Kick chat isn't IRC. The script resolves the chatroom via kick.com/api/v2/channels/<slug>, then connects to Kick's public Pusher WebSocket and subscribes to chatrooms.<id>.v2. Native Kick emotes arrive inline as [emote:<id>:<name>] tokens. Third-party support on Kick is 7TV only — BTTV and FFZ return 404 there.

Rendering

  • 2× supersampled text — the text layer renders at double size and downscales with LANCZOS, so outlines are clean instead of crunchy.
  • Animated emotes — the .gif variant is pulled from 7TV/BTTV for true frame timings. A cached static base is composited with only the moving emote frames at 12fps, so animation stays cheap.
  • Full-height column, bottom-anchored — new messages push up, old ones scroll off the top. Height re-pushes on window resize and fullscreen toggle.
  • Live resizing with no reconnect — Python watches the options file's mtime and rebuilds the renderer in place.
  • Changes persist. Every live tweak rewrites the matching line in script-opts/twitch_chat.conf, so your sizing survives a restart.

Configuration — script-opts/twitch_chat.conf

Option Default Meaning
enabled yes Auto-show when a stream loads
channel (blank) Force a channel; blank = auto-detect from URL
platform (blank) twitch / kick; blank = auto-detect
position right Which side the column sits on
margin 24 Gap from the screen edge, px
width 420 Column width, px
font_px 20 Text size, px
emote_scale 1.8 Emote height as a multiple of text size
height_frac 1.0 Column height as a fraction of the player (1.0 = full)
line_ratio 1.5 Line height = font_px × this
outline 0 Outline thickness; 0 = auto-scale
max_messages 60 Message buffer
bg_opacity 0.0 Panel behind the text; 0 = fully transparent (OLED-safe)
supersample 2 Text render scale; set 1 to save CPU
anim_fps 12 Animated emote frame rate
emotes yes 7TV/BTTV/FFZ on/off (native emotes always render)
font_regular / font_bold Segoe UI Point at a Roobert .ttf for the exact Twitch look
python (blank) Blank = use the bundled Python. Leave it blank.
Key Action
Alt+C Toggle chat overlay
Menu → Live Chat Bigger/smaller text, bigger/smaller emotes, wider/narrower column, swap side, auto-show, reconnect
Menu → Live Chat → Show Status Diagnostics — detected channel, whether frames are generating, dump of error.log

If chat doesn't appear, run Show Status first. Nine times out of ten mpv just needs a restart.


AI upscaling & frame interpolation — how the models actually work

This is the part people get confused by, so here's the whole chain.

The pipeline

video frame
   ↓
mpv decodes it (hwdec=auto-copy)
   ↓
vf=vapoursynth  ──►  a .vpy script  ──►  k7sfunc  ──►  vsmlrt  ──►  TensorRT
   ↓                                                                   ↓
   └───────────────── upscaled/interpolated frame ◄──────── your NVIDIA GPU
   ↓
GLSL shaders (glsl-shaders) run on the result
   ↓
screen
Layer What it is
vf=vapoursynth mpv's video filter that hands frames to a VapourSynth script. Bound to keys via vf toggle vapoursynth="~~/vs/…​.vpy".
.vpy A tiny Python script — the files in vs/. Sets resolution limits, GPU index, thread count, picks the model. This is the file you edit to tune things.
k7sfunc hooke007's helper library. Wraps the messy parts: FMT_CTRL (format/resolution guards), UAI_NV_TRT (generic ONNX upscaler), CUGAN_NV, RIFE_NV, FPS_CTRL.
vsmlrt The ML runtime bridge. Takes an .onnx model and runs it through a backend — here, TensorRT.
TensorRT NVIDIA's inference engine. Compiles the ONNX graph into a hardware-specific .engine file.

The .engine files — why the first run is slow

An .onnx file is a portable description of a neural network. TensorRT doesn't run it directly; it compiles it into an .engine optimised for one specific combination of:

  • your exact GPU model
  • your driver version
  • your TensorRT version
  • the input resolution range
  • fp16 / int8 quantisation settings

That compile takes minutes. The first time you press F1, mpv will appear to hang. It's building an engine. It gets cached in vs-plugins/models/ as a hash-named .engine, and every subsequent run is instant.

This is exactly why .engine files aren't in the download. Mine total 1.2 GB and are worthless on your machine. Yours build themselves.

If you update your GPU driver, engines may be invalidated and rebuild once. Normal.

Static vs dynamic engines (St_Eng in the .vpy files):

  • St_Eng = False (default) — a dynamic engine handling a range of resolutions. One build covers everything. Slightly slower, roughly double the VRAM budget.
  • St_Eng = True — a static engine locked to one resolution. Faster and leaner, but rebuilds per source resolution. Use this if you're VRAM-starved, then tune Ws_Size.

Upscaling models — vs/Upscale/

All of these are already in the download. Nothing to fetch.

Preset Model Best for
ESRGAN_FAST_AnimeJaNaiV3L1 animejanaiV3-HD-L1.onnx Anime, fastest
ESRGAN_MEDIUM_AnimeJaNaiV3L2 animejanaiV3-HD-L2.onnx Anime, balanced
ESRGAN_HEAVY_AnimeJaNaiV3L3 animejanaiV3-HD-L3.onnx Anime, best quality — the main one
ESRGAN_HEAVY_AnimeJaNaiV3L3_4K / _8K same model, higher H_Max Chained for 4K/8K output
ESRGAN_*_AnimeJaNaiV2L1/2/3 animejanaiV2L*.onnx V2 line — softer, sometimes kinder to bad sources
ESRGAN_Light_RealESRGANv2_animevideo_xsx2 RealESRGANv2-animevideo-xsx2.onnx Anime video, 2×, light
ESRGAN_HEAVY_RealESRGANv2_animevideo_xsx4 …xsx4.onnx Anime video, 4×
ESRGAN_HEAVIEST_realesr_animevideov3 realesr-animevideov3.onnx Heaviest anime preset
CUSTOM_ESRGAN_REAL_realesr_RealESRGAN_x2plus / x4plus RealESRGAN_x2plus.onnx / RealESRGAN-x4plus.onnx Live action / real footage
CUGAN_HEAVY_pro_nodenoise_up2x pro-no-denoise-up2x.onnx Anime, clean sources
CUGAN_HEAVIEST_pro_denoise3x_up2x pro-denoise3x-up2x.onnx Anime, noisy/compressed sources
CUGAN_PSYCHO_pro_denoise3x_up3x pro-denoise3x-up3x.onnx 3× — will melt your GPU
CUSTOM_Adore 2x_Adore_renarchi_fp16.onnx General-purpose 2×

Picking one: anime → AnimeJaNai V3 L3. Anime that's noisy or a bad rip → CUGAN with denoise. Live action → RealESRGAN x2plus/x4plus. Anything that stutters → drop to L1/L2, or use GLSL shaders instead.

Tuning a preset

Every .vpy in vs/Upscale/ has its settings in a plain block at the top. Open one in Notepad, change a number, save, restart mpv. There's nothing to compile.

H_Pre — the performance dial

This is the one you'll actually change. The frame is downscaled to this height before the network sees it, and the network then upscales it back up.

H_Pre = 720

Cost scales with pixel count, not height — so halving the height quarters the work. Going 1080720 leaves the GPU doing about 45% as much; 720540 roughly halves it again. The catch is you're throwing away real source detail before the model ever sees it, and the network invents it back, which is not the same thing.

  • Dropping frames or fans screaming? Lower it. 720540 buys a lot.
  • GPU coasting? Raise it to 1080. Noticeably sharper on good sources.
  • Anime is forgiving here (flat colour, hard lines). Live action is not.

H_Max — set this once, to your monitor

H_Max = 1440

Caps output height. Rendering 4K for a 1440p screen is pure waste. Set it to your actual screen height — 1080, 1440, 2160 — and forget it.

The rest

Option What it does When to touch it
Model Which .onnx in vs-plugins/models/ to run Swapping in a different model — filename must match exactly
Lt_Hd False squashes anything above 720p first. True raises the working resolution to 1080p Turn True for HD live-action where pre-squashing is visibly destructive. Costs roughly 2×
Gpu_T How many frames the GPU chews on at once 2 is right for most cards. 34 if you have VRAM spare and still drop frames. Above 4 does nothing
St_Eng False = one engine handling any resolution. True = locked to a single resolution: faster, less VRAM, but rebuilds whenever the source resolution changes Turn True if you're VRAM-starved and mostly watch one resolution
Ws_Size VRAM ceiling in MiB while building the engine. 0 = no limit Set 20484096 if the engine build runs you out of memory, or you're gaming on the same GPU
Gpu Which GPU, 0 = first Only if you have more than one
Lk_Fmt Forces 8-bit 4:2:0 Leave False. True only for a compatibility problem — it throws away 10-bit precision

CUGAN only

Nr_Lv    = -1    # denoise: -1 off, 0, 1, 2, 3
Sharp_Lv = 1.0   # 0.0 - 2.0

Nr_Lv is the whole reason to pick CUGAN. Compressed or noisy anime rips want 3. Clean Blu-ray sources want -1 — denoising something that isn't noisy just smears detail away. Sharp_Lv above about 1.3 starts to look crunchy and haloed.


Frame interpolation — vs/FrameInterpolation/

RIFE turns 24fps into 48/60/72fps by generating intermediate frames from optical flow, not by duplicating them.

Preset Model Multiplier
RIFE_LIGHT_4_6 RIFE 4.6
RIFE_LIGHT_x3_4_6 RIFE 4.6
RIFE_MEDIUM_4_25_Lite RIFE 4.25 Lite
RIFE_MEDIUM_x3_4_25_Lite RIFE 4.25 Lite
RIFE_HEAVY_4_26 RIFE 4.26
RIFE_HEAVY_x3_4_26 RIFE 4.26

Tuning RIFE

Option What it does When to touch it
Fps_Num The multiplier. 2 doubles the framerate (24 → 48), 3 triples it (24 → 72) Match your monitor. 24fps content on a 144 Hz screen looks best at 3; on a 60 Hz screen 2 is plenty, since anything above 60 gets thrown away
H_Pre Downscales before interpolating — the performance dial, same as upscaling Set it to your monitor height. Lower it if you drop frames
Sc_Mode Scene-change detection Leave it at 1. With 0, every hard cut gets a frame interpolated between two unrelated shots — a smeared mess for a fraction of a second, on every cut in the film
Model 46 (4.6), 4251 (4.25 Lite), 426 / 4262 (4.26) Newer isn't automatically better. 4.6 is the fast, reliable default; the Lite model is cheaper; 4.26 is slowest and only sometimes cleaner
Gpu_T Frames in flight on the GPU 2 suits most cards; raise to 3 if you have VRAM spare and still drop frames

Interpolation is much heavier than it looks. It runs on every frame and has to hit your target framerate in real time — if it can't, you get stutter that's worse than not using it at all. If a preset can't keep up, drop H_Pre first, then Fps_Num from 3 to 2, then move to the Lite model.

A warning about the look. RIFE gives you the "soap opera effect". On animation it usually looks great; on 24fps live-action film a lot of people hate it. That's taste, not a bug.

VFR sources are detected and converted to constant framerate first, snapping to 23.976 / 29.97 / 59.94. Without that step RIFE judders badly on variable-framerate files.

mpv.conf sets video-sync = display-resample with interpolation = yes, and the [vsync_auto] profile in profiles.conf automatically turns mpv's own interpolation off above 32fps or at non-1× speed — so mpv and RIFE don't fight each other. Leave that alone.

Cleaning presets — vs/Cleaning/

Preset Key What it does
MIX_UVR_MAD_NGU_AA_Artifact_Removal Ctrl+Shift+! Anti-aliasing and artifact removal
NR_BM3D_NV_HighestQuality_Denoise Ctrl+Shift+@ BM3D denoise — very heavy, very good
NR_CCD_STD_ColorFilm_Grain_Removal Ctrl+Shift+# Colour/film grain removal
ETC_DEINT_EX_Super_Deinterlacing Ctrl+Shift+$ Deinterlacing for old broadcast sources

Adding your own models

Drop an .onnx into vs-plugins/models/, copy any vs/Upscale/*.vpy, and change the Model = "…" line to your filename. Good hunting grounds: OpenModelDB, the-database/AnimeJaNai, xinntao/Real-ESRGAN, Artoriuz/ArtCNN.


GLSL shaders

Shaders run after the VapourSynth stage, on the GPU, in mpv's own render pipeline. They cost far less than the AI models and work on any GPU — this is your path if you're not on NVIDIA.

Key Shader Type
Ctrl+` Clear all shaders
Ctrl+1 Ani4Kv2 ArtCNN C4F32 Luma upscale
Ctrl+2 AniSD ArtCNN C4F32 Luma upscale (SD sources)
Ctrl+3 FSRCNNX x2 16 Luma upscale
Ctrl+4 NNEDI3 nns128 Luma upscale (classic, heavy)
Ctrl+5 CfL Prediction RT Chroma
Ctrl+6 AMD FSR EASU RGB RT Main scaler
Ctrl+7 Anime4K Restore CNN L Main
Ctrl+8 Anime4K Upscale GAN x2 M Main
Ctrl+9 Adaptive Sharpen RT Output sharpening
Ctrl+0 Anime4K AIO optQ All-in-one — start here
Ctrl+[ / Ctrl+] Anime4K Clamp Highlights + Restore CNN VL chains Main

mpv.conf loads hdeband.glsl (debanding) and adaptive_sharpen_RT.glsl on every file by default.

glsl-shaders and volume are persisted by save_global_props.lua. If a shader change doesn't seem to take, delete saved-props.json.


NVIDIA RTX VSR & True HDR

Driver-level features exposed through mpv's d3d11vpp filter. RTX 20-series or newer, enabled in the NVIDIA Control Panel. No CUDA runtime needed for these.

Key Action
, RTX Video Super Resolution (d3d11vpp=scale=2:scaling-mode=nvidia)
. RTX True HDR — converts SDR content to HDR (d3d11vpp=nvidia-true-hdr)

Custom_NVIDIA_RTX_HDR.lua exists because True HDR must be the last filter in the chain or the output is wrong. The script watches the vf property and silently moves d3d11vpp=nvidia-true-hdr back to the end whenever anything else is added. You never have to think about ordering.

HDR handling

profiles.conf has an [HDR_generic] profile that auto-applies when video-params/sig-peak > 1:

hdr-reference-white  = 100
hdr-peak-percentile  = 99.99
blend-subtitles      = no

Ctrl+Wheel Up/Down adjusts target peak brightness in 250-nit steps — commented out by default, uncomment lines 173–174 in input_uosc.conf to enable.


VR / 360° video

scripts/mpv360.lua. Options in script-opts/mpv360.conf.

Key Action
Ctrl+E Toggle 360 / VR mode
Ctrl+Shift+P Cycle projection (equirectangular, fisheye, …)
Ctrl+Shift+E Switch eye — left / right / both (stereoscopic)
Ctrl+Shift+S Cycle sampling quality
Ctrl+R Reset view
Ctrl+Click Toggle mouse-look
Ctrl+T Show controls help
Esc Exit mouse-look

The non-toggle bindings only exist while 360 mode is on. By design.


Picture-in-Picture / phone mode

scripts/Custom_Phone_PiP_Mode.lua — for vertical video and always-on-top corner playback.

Key Action
Ctrl+A Toggle PiP / phone mode (auto-orient)
Ctrl+S Snap to left edge
Ctrl+D Snap to right edge

input_plus.lua also provides a pip_dummy binding that shrinks the window to a percentage of the screen (default 20%).


Full hotkey reference

Everything below is also in the right-click menu, organised into submenus. If you remember one thing, remember right-click.

Loading & navigation

Key Action
Ctrl+Shift+V Load clipboard URL — YouTube, magnet, direct link, anything
Ctrl+Shift+M Paste & play magnet from clipboard
Wheel Up / Wheel Down Previous / next playlist item (skips headers)
Mouse Back / Forward Previous / next
Middle click / Right click uosc menu
Ctrl+Right click Native context menu
Double click Fullscreen

Playback

Key Action
, / . Previous / next frame
l Set / clear A-B loop
[ / ] Cycle speed down / up (2 → 1.5 → 1.2 → 1)
{ / } Speed ∓0.1
- / = Volume ∓1
c / v Audio delay ∓100ms
z / x Subtitle delay ∓100ms
Shift+Backspace Reset audio & subtitle sync

Frame interpolation

Key Preset
! Light — RIFE 4.6 (2×)
@ Medium — RIFE 4.25 Lite (2×)
# Heavy — RIFE 4.26 (2×)
$ Light ×3
% Medium ×3
^ Heavy ×3

Super resolution

Key Preset
& * ( AnimeJaNai V2 — Lite / Medium / Heavy
) _ + AnimeJaNai V3 — Lite / Medium / Heavy
N / M AnimeJaNai V3 Heavy — 4K / 8K
{ / } / | RealESRGAN AnimeVideo — Light x2 / Heaviest v3 / Heavy x4
? / Z RealESRGAN x4plus / x2plus (live action)
: / " CUGAN Heavy (no denoise) / Heaviest (denoise 3×)

Combined presets — the good stuff

Key Stack
F1 AnimeJaNaiV3L3 ×1 + Ani4Kv2 ArtCNN + Anime4K AIO + FSR RT + adaptive sharpen
F2 AnimeJaNaiV3L3 ×2 (for <1080p) + same shader stack
F3 AnimeJaNaiV3L3 4K ×2 (for <1080p) + same
F4 AnimeJaNaiV3L3 ×3 (for <1080p) + ArtCNN + FSR + sharpen
F5 AnimeJaNaiV3L3 ×1 + RIFE ×2 + full shader stack
F6 AnimeJaNaiV3L3 ×1 + RIFE ×3 + full shader stack
F7 AnimeJaNaiV3L3 ×2 + RIFE ×2 + full stack
F8 AnimeJaNaiV3L3 4K ×2 + RIFE ×2 + full stack
Ctrl+Shift+~ General 1080p — ESRGANv2 x2 + Anime4K AIO (good default for non-anime)
Ctrl+Alt+Shift+A AnimeJaNaiV3 + RIFE 4.6 + Anime4K AIO
Ctrl+Alt+Shift+S RIFE 4.6 + Anime4K AIO
Ctrl+Alt+Shift+D RIFE 4.6 ×3
Ctrl+Alt+Shift+F ESRGAN 8K ×4
Ctrl+Alt+Shift+G ESRGAN 4K ×2
Ctrl+Alt+Shift+Z RIFE + NVIDIA RTX VSR + AMD FSR

Every one of these is a toggle — press again to turn it off. Ctrl+` clears all shaders.

Everything else

Key Action
Alt+C Toggle live chat overlay
Ctrl+E Toggle VR / 360 mode
Ctrl+A / Ctrl+S / Ctrl+D PiP toggle / snap left / snap right
, / . (menu → NVIDIA) RTX VSR / RTX True HDR
Alt+Wheel Cursor-centric zoom
Alt+Left drag Pan image
Ctrl+Shift+D Switch debrid provider (Real-Debrid ⇄ TorBox)
Ctrl+Shift+F8 Add torrent folder to RD cloud
Ctrl+Shift+Alt+Z Clear RD cache

File map

MPVonCrack/
├── mpv.exe                        The player
├── yt-dlp.exe                     Stream extractor
├── python.exe  Lib/               Bundled Python + Pillow + numpy + websocket-client
├── vs-plugins/
│   ├── models/                    All 56 .onnx models (engines build here)
│   ├── vstrt.dll  vsort.dll       TensorRT / ONNX Runtime backends
│   └── vsmlrt-cuda/               NVIDIA CUDA/TensorRT runtime
│
└── portable_config/
    ├── mpv.conf                       Core config — gpu-next, hwdec, OSD, subs, screenshots
    ├── profiles.conf                  Conditional auto-profiles (HDR, deband, vsync, debrid)
    ├── script-opts.conf               Options for uosc, thumbfast, console, stats
    ├── input_uosc.conf                THE hotkey + right-click menu file
    ├── input_contextmenu_plus.conf    Native context menu definition
    │
    ├── fonts/                         LXGW WenKai Mono, Material Icons, uosc textures
    │
    ├── script-opts/
    │   ├── debrid.conf                Which provider handles .torrent files
    │   ├── realdebrid.conf.example    ← copy to realdebrid.conf, add your token
    │   ├── torbox.conf.example        ← copy to torbox.conf, add your token
    │   ├── twitch_chat.conf           Chat overlay settings
    │   └── mpv360.conf                VR / 360 settings
    │
    ├── scripts/
    │   ├── uosc/                              The UI
    │   ├── twitch_chat/                       Live chat (main.lua + chat_render.py)
    │   ├── Custom_Debrid_Provider.lua                 RD ⇄ TorBox switch
    │   ├── Custom_Torrent_Real_Derbid_Streaming.lua   .torrent → Real-Debrid
    │   ├── Custom_Torrent_TorBox_Streaming.lua        .torrent → TorBox
    │   ├── Custom_Torrent_Magnet_Streaming.lua        magnet → Real-Debrid
    │   ├── Custom_Torrent_Unified_Navigation.lua      wheel nav + header skipping
    │   ├── Custom_Bulk_STRM_Files_Player.lua          .strm playlists
    │   ├── Custom_NVIDIA_RTX_HDR.lua                  keeps True HDR last in the vf chain
    │   ├── Custom_Phone_PiP_Mode.lua                  PiP / vertical mode
    │   ├── Custom_Hide_uosc_In_Jellyfin_Browser.lua   hides uosc in the Jellyfin shim
    │   ├── mpv360.lua                                 VR / 360
    │   ├── thumbfast.lua                              seekbar thumbnails
    │   ├── contextmenu_plus.lua                       native menu
    │   ├── input_plus.lua                             extra commands
    │   └── save_global_props.lua                      persists volume + shader state
    │
    ├── shaders/                       30+ GLSL — Anime4K/, QCOM/, Disabled/, root
    │
    ├── vs/
    │   ├── Upscale/                   ESRGAN, AnimeJaNai, CUGAN, Adore
    │   ├── FrameInterpolation/        RIFE 4.6 / 4.25 / 4.26, 2× and 3×
    │   ├── Images/                    Still-image upscaling
    │   ├── Cleaning/                  Denoise, deinterlace, grain, AA
    │   └── Disabled/                  Alternate backends (DML, MIGX) — AMD/Intel paths
    │
    └── Turned Off Scritps/            Parking lot — includes an unfinished TorBox streamer

Auto-profiles in profiles.conf

These fire on their own, no key needed:

Profile Trigger Effect
[HDR_generic] sig-peak > 1 HDR reference white 100, peak percentile 99.99
[deband_bitrate] bitrate ≤ 3000 kbps Auto-enable debanding on low-bitrate files
[vsync_auto] fps > 32, or speed ≠ 1× Disables mpv interpolation so it doesn't fight RIFE
[save_props_auto] ≥90% watched, or ≤5 min long Don't save a resume position
[audio_DolbyAtmos] filename contains .Atmos. Passthrough eac3,truehd
[debrid_resilience] https path that isn't Twitch/Kick/.m3u8 ffmpeg reconnect options for flaky debrid links
[speed_limit1/2] speed <0.1 or >8 Clamps playback speed

⚠️ [debrid_resilience] is deliberately scoped. Putting those ffmpeg reconnect=1 options globally in mpv.conf breaks live HLS — Twitch and Kick streams die with hls: Failed to reload playlist, because a normal CDN connection close triggers a reconnect-at-byte-0 loop. Keep the profile condition intact.


Troubleshooting

AI upscaling does nothing / errors out First check you actually have the CUDA runtime: there should be a vs-plugins/vsmlrt-cuda/ folder containing nvinfer_10.dll. If it's missing you took the repo download — grab the vsmlrt-cuda parts from Releases and drop that folder into vs-plugins/. See Setup.

If it is there: are you on an NVIDIA RTX card? And are you out of VRAM — lower H_Pre, or set St_Eng = True and cap Ws_Size.

mpv freezes the first time I press F1 It's compiling a TensorRT engine. Takes minutes. Once per preset. Explanation.

Stuttering with an upscale preset on Your GPU can't keep up. Lower H_Pre, drop to a Lite model, or use GLSL shaders (Ctrl+0) instead.

"Real-Debrid: no API token set" script-opts/realdebrid.conf is missing or still says YOUR_TOKEN_HERE. See Debrid setup.

A torrent double-click does nothing / Unsupported URL: real-debrid.com/d/… Expired RD links. v21 recovers automatically — give it a moment. If it persists, Ctrl+Shift+Alt+Z to clear the cache and reopen.

A magnet sits at "Fetching metadata… (0 seeders)" Dead magnet. No seeders means Real-Debrid can't cache it either. That's the seeder counter doing its job.

I switched to TorBox but torrents still go to Real-Debrid (or nothing happens) Check Menu → Streaming → Show Current Provider. If it disagrees with script-opts/debrid.conf, the conf wasn't writable — check file permissions. Also confirm torbox.conf exists and isn't still YOUR_TOKEN_HERE.

TorBox says "still caching - skipping" TorBox didn't finish caching within ~5 minutes. The torrent stays on your TorBox account and keeps downloading — reopen it in a few minutes and it'll be instant. Raise POLL_MAX in the script if you want it to wait longer.

Chat overlay doesn't show Menu → Live Chat → Show Status. Usually mpv just needs a restart. Check the error.log path that Status prints.

Emotes have magenta/glowing edges Premultiplied-alpha bug — should be fixed. If you've modified chat_render.py, check to_bgra_premult() is still applied.

Twitch stream dies partway through Twitch URLs from yt-dlp expire when ad-break tokens rotate. Only re-resolving via yt-dlp recovers it; no config option fixes this. Reload the file.

Shader changes don't stick save_global_props.lua persists volume and glsl-shaders. Delete saved-props.json to reset.

A right-click menu entry does nothing uosc only picks up commented-out menu lines when the key is exactly # (one character) and the comment starts with #!. A ## prefix is ignored by both mpv and uosc.


Credits

Nearly all the groundwork here is other people's, and it's very good work:

The custom Lua — Real-Debrid streaming, magnet streaming, the live chat overlay, unified navigation, .strm handling, PiP, RTX HDR ordering — is mine.

mpv is GPLv2+; the bundled components keep their own licenses.


A note on the config

This is a personal setup that grew organically. Some of it is opinionated, some of it is held together with tape, and there's a folder literally named Turned Off Scritps. It's shared because people asked, not because it's a polished product.

Two things worth changing on day one: H_Max in the .vpy files to your monitor height, and H_Pre to whatever your GPU can survive.

If something breaks, the right-click menu and input_uosc.conf are where everything is defined — it's all readable plain text.

About

Real-time AI upscaling (ESRGAN/AnimeJaNai/CUGAN) + RIFE frame interpolation + TorrBox + Real-Debrid torrent & magnet streaming + live Twitch/Kick chat with emotes, inside mpv

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages