Watch Twitch and Kick streams in mpv. The script automatically routes livestream
URLs through Streamlink instead of yt-dlp, so ads are skipped and playback
doesn't break on stream discontinuities. Just run mpv <url> — no wrapper
script, no second window.
mpv's built-in ytdl_hook resolves Twitch URLs with yt-dlp and hands mpv a raw
HLS playlist. Streamlink instead filters out Twitch's embedded ad segments
(mandatory since Streamlink 7.5.0) and handles the resulting stream
discontinuities, reconnects and live-edge behaviour.
The usual workaround is to run streamlink -p mpv <url> best by hand. This
script makes plain mpv <url> do it.
- mpv with Lua support
- Streamlink in
PATH(8.0 or newer recommended;--kick-low-latencyis not available in older releases)
The repository mirrors mpv's config layout, so its folders merge into an existing config without touching your other files.
Download ZIP: GitHub wraps everything in a mpv-streamlink-hook-main/
folder. Open it, then copy the scripts and script-opts folders from inside
it into your mpv config directory — not the wrapper folder itself.
Or with git:
git clone https://github.com/adr1enette/mpv-streamlink-hook
cp -r mpv-streamlink-hook/scripts mpv-streamlink-hook/script-opts <mpv config>/
Result:
<mpv config>/
├── scripts/
│ └── streamlink-hook.lua required
└── script-opts/
└── streamlink_hook.conf optional, defaults are built in
Only scripts/streamlink-hook.lua is required — mpv autoloads every .lua in
scripts/. The .conf file exists only so you can change defaults; without it
the script uses the values listed under Options.
Existing scripts/ and script-opts/ folders are merged, not replaced. This
repository deliberately ships no mpv.conf or input.conf, so nothing of
yours gets overwritten.
Where is the config directory? ~/.config/mpv/ on Linux/macOS,
%APPDATA%\mpv\ on Windows — unless a portable_config folder sits next to
mpv.exe, in which case mpv reads that one and ignores %APPDATA%\mpv
entirely. Check with mpv --idle -v and look for the Reading config file
line.
Then just play a stream:
mpv https://www.twitch.tv/CHANNEL
- The script registers an
on_loadhook with priority1. mpv's built-inytdl_hookuses priority10, so this runs first. - On a matching URL it starts Streamlink in
--player-external-httpmode: Streamlink serves the stream over127.0.0.1:<random port>and does not launch a player of its own. - The hook rewrites
stream-open-filenameto that local address, so the already-running mpv instance plays it — one process, one window.ytdl_hookthen sees a plain HTTP URL and ignores it; YouTube and everything else keep working normally. hook:defer()pauses loading until the server is up, thenhook:cont()releases it.- The subprocess is started with
playback_only=true, so mpv terminates Streamlink when playback ends or the window is closed.
Set in script-opts/streamlink_hook.conf.
| Option | Default | Description |
|---|---|---|
domains |
twitch%.tv/|kick%.com/ |
Lua patterns, |-separated |
quality |
best |
Stream quality passed to Streamlink |
low_latency |
yes |
Prefetch segments and reduce player buffering |
codecs |
h264,h265,av1 |
Codecs announced to Twitch |
wait |
2.0 |
Seconds to wait for Streamlink's server |
port_min / port_max |
20000 / 45000 |
Local port range |
loglevel |
warning |
Streamlink log level |
extra_args |
(empty) | Any further Streamlink arguments |
Low latency. Enabled by default. On the Streamlink side this prefetches
upcoming HLS segments and lowers the live edge; on the mpv side it applies a
subset of mpv's built-in low-latency profile as file-local options, so the
settings revert afterwards instead of leaking into the next file. Both halves
are needed — prefetching alone is cancelled out by the player's own cache.
Low latency has to be enabled by the broadcaster, and there is no way to tell
in advance whether a channel uses it. On a regular stream the reduced live edge
can cause buffering instead. If playback stutters, set low_latency=no.
Codecs. Twitch defaults to h264 only. Announcing h265 and av1 unlocks
higher quality streams on channels using enhanced broadcasting, at the cost of
heavier decoding. Set codecs=h264 to opt out.
Windows port ranges. Hyper-V and WSL reserve large TCP blocks above 49152.
Picking a port there fails with WinError 10013. Check yours with:
netsh interface ipv4 show excludedportrange protocol=tcp
Slow connections. If mpv reports it cannot open http://127.0.0.1:<port>,
raise wait.