Play YouTube audio directly from Neovim using mpv + yt-dlp. No browser, no Node.js — just pure Lua talking to mpv over a local IPC socket.
mpv and yt-dlp.:YT ui) animated player layout featuring a custom bounding-box grid, bouncy audio visualizer, interactive progress slidebar, and built-in queue alignment.dd to remove tracks or J/K to reorder them (:YT queue_edit).:YT queue_playlist).lualine| Dependency | Install |
|---|---|
| Neovim 0.9+ | — |
| mpv | sudo apt install mpv or brew install mpv |
| yt-dlp | pip install yt-dlp or binary release |
{
"sanjay-np/nvim-yt-player",
config = function()
require("yt-player").setup()
end,
}
use {
"sanjay-np/nvim-yt-player",
config = function()
require("yt-player").setup()
end,
}
:YT play https://www.youtube.com/watch?v=dQw4w9WgXcQ
Or search directly from Neovim (opens in a custom interactive floating window!):
:YT search lofi hip hop
In the interactive search window:
<CR> (Enter): Play result (replaces current track)<C-a> (Ctrl+A) or a / A (in Normal mode): Append result to the queueAll functionality is grouped under a single :YT command with auto-completion (press Tab!).
| Command | Description |
|---|---|
:YT play [url] |
Play URL / search, or resume |
:YT search [query] |
🔍 Search YouTube and pick a result |
:YT queue <url> |
Append a single URL to the playlist |
:YT queue_playlist <url> |
Fetch and append an entire playlist |
:YT queue_edit |
Open interactive queue editor |
:YT pause |
Pause |
:YT toggle |
Toggle play/pause |
:YT stop |
Stop playback |
:YT next / :YT prev |
Next / previous track |
:YT seek <sec> |
Seek to absolute position |
:YT seek_rel <±sec> |
Seek relative |
:YT volume <0-100> |
Set volume |
:YT vol_up / :YT vol_down |
Volume ±5 |
:YT mute |
Toggle mute |
:YT speed <rate> |
Set speed (0.25–3.0) |
:YT speed_up / :YT speed_down |
Speed ±0.25 |
:YT shuffle / :YT repeat_toggle |
Shuffle / repeat |
:YT ui |
Toggle the dedicated player side-panel |
:YT info |
Toggle the floating player window |
:YTInfo opens an interactive floating window:
| Key | Action |
|---|---|
p / s / t |
Play / Pause / Toggle |
n / b |
Next / Previous |
m |
Mute |
> / < |
Speed ±0.25 |
+ / - |
Volume ±5 |
l / h |
Seek ±5s |
L / H |
Seek ±30s |
q / <Esc> |
Close |
All options with defaults:
require("yt-player").setup({
statusline = {
enabled = true,
format = "{icon} {title} - {artist} [{position}/{duration}]",
icon_playing = "▶",
icon_paused = "⏸",
truncate_title = 30,
progress_width = 10,
},
-- Search settings
search = {
limit = 10, -- number of results to fetch
},
notifications = {
enabled = true,
notify_on_track_change = true,
notify_on_command = false,
},
player = {
queue_display_limit = 5, -- Number of upcoming tracks to show in the `:YT ui` side-panel
},
keymaps = {
enabled = false,
prefix = "<leader>y",
},
sponsorblock = false, -- Set to true to automatically skip embedded sponsor segments
})
{icon} {title} {artist} {album} {position} {duration} {volume} {progress} {speed}
Example output: ▶ Song Name ▓▓▓▓░░░░░░ [2:30/5:00] 1.5x
require("lualine").setup({
sections = {
lualine_x = { "yt-player" }
}
})
Neovim (Lua) ←─ IPC pipe ─→ mpv ←── yt-dlp ←── YouTube
The plugin spawns a headless mpv --no-video process and communicates through a UNIX domain socket using mpv's JSON IPC protocol. yt-dlp is used by mpv internally to resolve YouTube URLs into streamable media.
mpv --no-video <youtube-url> directly to verify mpv + yt-dlp workyt-dlp -U to update/tmp/nvim-yt-player-ipc-<pid>, unique per Neovim instanceMIT