A premium, lightweight, asynchronous YouTube audio player built directly inside Neovim. Powered by mpv and yt-dlp, it plays audio seamlessly in the background without freezing your editor or requiring complex Node.js/browser extensions.
- β‘ Zero-Freeze Asynchronous Playback: Stream fetching and caching run entirely in the background. Neovim remains 100% responsive.
- ποΈ Zero-Dependency Backend: Pure Lua talking to a local
mpvprocess over a UNIX domain IPC socket. No bloated servers or external daemons needed. - π¨ Premium Player Layouts:
:YT playerβ Toggles a dedicated side-panel buffer featuring a beautiful custom ASCII bounding-box, a live bouncing music visualizer, an interactive progress slidebar, and volume/speed tracking.:YT miniβ Toggles a gorgeous floating window with the same premium visual player layout.
- π Interactive Search Picker (
:YT search): Query YouTube and pick a result using a beautiful floating picker displaying channel names and track durations. - π Local Playlists (
:YT playlists): Save tracks instantly withsand manage them inside a split-pane local playlist manager. - π Interactive Queue Editor (
:YT queue_edit): Reorder tracks withJ/Kor delete them withddin real-time. - π΅ Seamless Playlist Ingestion (
:YT queue_playlist): Rapidly ingest and parse YouTube playlists containing 100+ tracks without blocking the UI. - β© Auto SponsorBlock: Automatically skip sponsors, intros, and non-music off-topic segments (enable in config).
- π» Autoplay Radio Mode (
:YT radio): Endless recommendation stream (enabled by default). Spawns the YouTube Mix playlist matching your active song, deduplicates against active queue and history, and seamlessly appends fresh tracks before your queue ends. - π Lualine & Statusline Integration: Formats playing state, volume, speed, and real-time progress bars smoothly for statuslines.
- π Persistent Play History (
:YT history): Stores recently played tracks so you can jump back or queue them later.
Before installing, ensure the following commands are available in your system path:
- Neovim 0.9+
- mpv (configured with Lua support)
- yt-dlp
Install using your favorite package manager:
{
"sanjay-np/nvim-yt-player",
dependencies = { "nvim-lualine/lualine.nvim" }, -- optional, for statusline component
config = function()
require("yt-player").setup({
-- your configuration options here (see Configuration section)
})
end,
}use {
"sanjay-np/nvim-yt-player",
requires = { "nvim-lualine/lualine.nvim" }, -- optional
config = function()
require("yt-player").setup()
end,
}- Start playing a URL immediately:
:YT play https://www.youtube.com/watch?v=dQw4w9WgXcQ
- Search and select tracks interactively:
In the search picker window:
:YT search lofi hip hop<CR>(Enter): Play selected track (replaces active playlist)a/A/<C-a>: Append selected track to the active queues: Save selected track to a Local Playlistgg: Jump to first resultG: Jump to last resulti: Re-enter insert mode to refine your queryq/<Esc>: Close the picker
All functions are available under the master command :YT with rich autocomplete (press <Tab>!).
| Subcommand | Description |
|---|---|
:YT play [url] |
Play a URL/search query, or resume playback |
:YT pause |
Pause playback |
:YT toggle |
Toggle play/pause |
:YT stop |
Stop playback entirely |
:YT next / :YT prev |
Skip to next or previous track |
:YT seek <seconds> |
Seek to an absolute position (e.g. :YT seek 90 jumps to 1m 30s) |
:YT seek_rel <Β±seconds> |
Seek relatively (e.g. :YT seek_rel -10 seeks back 10 seconds) |
:YT volume <0-100> |
Set playback volume |
:YT vol_up / :YT vol_down |
Increase/decrease volume by 5% |
:YT mute |
Toggle playback mute state |
:YT speed [value] |
Adjust speed absolutely or relatively (Forms listed below) |
:YT player |
Toggle the premium player side-panel |
:YT mini |
Toggle the premium player floating window |
:YT search [query] |
Open the interactive search picker |
:YT queue <url> |
Append a track to the active queue |
:YT queue_playlist <url> |
Parse and append all tracks from a YouTube playlist URL |
:YT queue_edit |
Open the interactive queue editor |
:YT playlists |
Open the split-pane local playlist manager |
:YT radio |
Toggle autoplay radio mode (ON by default) |
:YT history |
Open the persistent play history picker |
:YT history_clear |
Clear play history |
:YT resume |
Resume the last persistent playback session |
:YT speedβ Display current speed in a notification:YT speed 1.25β Set absolute speed (supports values between0.25and3.0):YT speed up/downβ Adjust speed by+0.25/-0.25:YT speed +0.5/-0.5β Adjust speed by a custom offset
When either the side-panel (:YT player) or floating window (:YT mini) is focused, you can control playback instantly using the following keymaps:
| Keymap | Action |
|---|---|
p / s / t |
Play / Pause / Toggle |
n / b |
Next / Previous track |
m |
Mute toggle |
+ / - |
Volume Β±5% |
> / < |
Speed Β±0.25x |
l / h |
Seek Β±5s (relative) |
L / H |
Seek Β±30s (relative) |
0 to 9 |
Seek to absolute percentage (0% to 90% of track) |
G |
Seek to 100% (ends track) |
R |
Cycle Repeat Mode (Track π β Playlist π β Off) |
r |
Toggle Autoplay Radio Mode |
q / <Esc> |
Close player window |
Override defaults by passing options into setup():
require("yt-player").setup({
statusline = {
enabled = true,
format = "{icon} {title} - {artist} [{position}/{duration}]",
icon_playing = "βΆ",
icon_paused = "βΈ",
truncate_title = 30,
progress_width = 10,
},
search = {
limit = 10, -- default number of results returned per search query
},
notifications = {
enabled = true,
notify_on_track_change = true, -- notify when a new song starts playing
},
player = {
queue_display_limit = 5, -- number of upcoming tracks to show in the player layout
},
keymaps = {
enabled = false, -- set to true to enable global keymaps
prefix = "<leader>y",
play = "p",
pause = "s",
toggle = "t",
next = "n",
prev = "b",
mute = "m",
volume_up = "+",
volume_down = "-",
seek_forward = "f",
seek_backward = "r",
speed_up = ">",
speed_down = "<",
},
radio = {
enabled = true, -- set to false to disable autoplay radio by default
limit = 5, -- number of related tracks to fetch at a time
},
sponsorblock = false, -- set to true to automatically skip YouTube sponsor segments
})Use these placeholders to customize your statusline:
{icon}β Play/Pause status icon (βΆ/βΈ){title}β Current track title{artist}β Channel / Uploader name{position}β Current playback position (e.g.2:45){duration}β Total track duration (e.g.4:10){progress}β Interactive progress bar (e.g.ββββββββββ){volume}β Volume percentage{speed}β Speed multiplier (e.g.1.25x){radio}β Autoplay radio status icon (rendersπ»when enabled)
Add yt-player directly to your lualine configuration sections:
require("lualine").setup({
sections = {
lualine_x = { "yt-player" }
}
})Neovim (Lua) ββ UNIX Socket βββ mpv βββ yt-dlp βββ YouTube Stream
The plugin spawns a headless, detached background mpv process with IPC enabled. Multiple Neovim instances safely share the same mpv process via standard client process registration. The socket is automatically cleaned up when the last client closes.
- No Audio? Check that both
mpvandyt-dlpare functioning correctly on your system by playing a URL directly:mpv --no-video "https://www.youtube.com/watch?v=dQw4w9WgXcQ" - Outdated yt-dlp? If YouTube streams fail to parse, update
yt-dlpto get the latest decoders:yt-dlp -U
- Warning: mpv exited? Ensure
mpvis compiled with Lua support. Most native distribution package managers compile it with Lua support by default. - Searching Fails? Ensure Neovim has internet access and your geographic region is not blocked or rate-limited by YouTube's API filters.
Q: Does this download videos to my computer?
A: No. It streams only the audio tracks in real-time, saving disk space and bandwidth.
Q: Can multiple Neovim instances control the same audio?
A: Yes! A shared client registry coordinates instances. When you start audio in one instance, others can view the statusline or control the active player.
Distributed under the MIT License.