recording_20260509_095830.mp4
- Features
- Installation
- Usage
- Configuration
- Extensions
- Frequently Asked Questions (FAQ)
- Contribution
- Support
- Multiple Launcher Support: with
fzf,rofiall supporting previews - Search For Media: videos, playlists, channels, shorts or movies.
- Search Filters: Apply colon-prefixed quick filters directly to search queries:
- Time:
:hour,:today,:week,:month,:year - Type:
:video,:movie,:live,:short,:long - Features:
:4k,:hd,:hdr,:subtitles,:360,:vr,:3d,:local - Sort by:
:newest,:views,:rating
- Time:
- Search History & Recall: Automatically saves search history. Allows quick recall of previous searches using bang syntax (e.g.,
!1for the most recent search,!2for the second, etc.). - YouTube Feeds: Access personal feeds including the Home Feed, Trending, Watch Later, Liked Videos, Watch History, and Clips.
- Channel Browsing: access a channel's Videos, Featured content, Playlists, Shorts, Live Streams, Podcasts, and search pages.
- Customizable Menus: Reorder, add, or filter out menu entries using
.uiextensions - Theming & Styling: theming support through
.themeextensions with tokyo night as the default theme. - Multi-language Support: Loadable language files (
.lang) to easily localize the UI prompts and messages(currentlyesandbr. Contributions for additional languages are welcome. - Pagination: browse through massive lists with Next/Previous pagination controls (default is 30).
- scriptable Shortcuts: Bypass menus and jump straight to specific feeds, searches, or actions using direct command-line flags . See usage
- Multiple Player Support: with
mpv,vlc, andtplay. - Playlist Actions: Play individual videos, queue/play entire playlists, or queue "Listen to All" for audio-only
- Auto-Mix Generation: Dynamically generates
.m3u8playlist mixes based on a single video (YouTube "Mix" feature replication). - Background Playback: Option to disown the media player process (
CONFIG_DISOWN_PLAYER) - Granular Downloads: Download single videos, entire playlists, or extract audio-only (MP3 format).
- Smart Archiving: Utilizes a download archive directory(yt-dlp's
--download-archiveopt) to track previously downloaded media and prevent duplicate downloads. - Organized File Structure: Automatically routes downloads into structured directories (e.g.,
video/individual/ChannelName/oraudio/PlaylistName/ChannelName/). - Enumeration Toggle: Easily toggle file prefix enumeration (
01 -,02 -) to keep downloaded playlist items in order. - Local Subscriptions Sync: Syncs your actual YouTube subscriptions locally by passing browser cookies to
yt-dlp - Local Watch History (Recent): Automatically tracks recently watched media in a local JSON file to resume or re-watch easily.
- Saved Videos & Playlists: Create local "Saved Videos" and "Custom Playlists for watching later without having to download them
- Browser Cookies: optionally configure a browser (
CONFIG_BROWSERpasses to yt-dlp's--cookies-from-browser) to access age-restricted or account-specific content. - Custom Commands: Create custom cmds that execute specific URLs and
yt-dlpoptions (e.g., setting up a command to browse a completely different streaming site that yt-dlp supports). - Extensions: extend yt-x with custom scripts, sites, themes, and commands placed in
$HOME/.config/yt-x/extensions/. - Stateful Sub-Shell Execution: Drop into a shell pre-loaded with the environment variables of your current session (current video title, URL, channel info, etc.) for custom scripting
- Desktop Integration: generate a
.desktopfile, to be launched natively from application menus (Linux). - Cache Management: Automatically cleans up stale preview images, auto-generated playlists, and logs older than a set period (Default: 3 days)
- OS Support: Works across Linux, macOS, Windows (via WSL/MSYS/Cygwin), and Android (uses
am startintents to open media natively in Android apps like VLC or MPV). - Auto-Updater: update checker that securely pulls the latest version from GitHub and shows you the changes diff so you can decide whether to apply the update or not.
- Shell Completions: currently supports for fish shell with tab complete for some options (e.g., channel names, custom cmd names, etc.), Contributions for bash and zsh completions are welcome.
Required:
yt-dlp- For fetching the data and downloading media.fzf- Main launcherjq- For parsing jsoncurl- For fetching script updates and preview images. (version 7.6+; that supports--paralleldownloads)sh- Any POSIX-compliant shell (Bash, Zsh, Dash, etc.).- Nerd Font - For the icons (Recommended JetBrains Mono Nerd Font).
Optional:
- Media Players:
mpv(default),vlc, or `tplay - Modern Terminal That Supports True Color:
kittypersonal favourite; started the great terminal era lolghosttywezterm
- Terminal Image Viewers:
chafa(Cross-terminal)icat(Recommended for Kitty and Ghostty)imgcat(For iTerm2/WezTerm)
- Alternate Launcher:
rofi(Great if you want a desktop app launcher, you could even keybind the command, its really cool). - Terminal QoL:
gum(Better terminal ui; loaders, prompts etc).batto show update diffs in a nicer way
Ensure ~/.local/bin exists and is added to your system's $PATH.
curl -sL "https://raw.githubusercontent.com/Benexl/yt-x/refs/heads/master/yt-x" -o ~/.local/bin/yt-x
chmod +x ~/.local/bin/yt-xTo uninstall ,just run: rm ~/.local/bin/yt-x, then to remove its related data folders rm -r ~/.config/yt-x and rm -r ~/.cache/yt-x.
Note am not the one who maintains any of this packages and you should probably turn off auto updates if using them
Arch Linux (AUR)
yay -S yt-x-git
# or if you prefer paru
paru -S yt-x-gitNix / NixOS
1. Imperative:
nix profile install github:Benexl/yt-x2. Declarative:
First, add the repository to your flake.nix inputs:
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
yt-x = {
url = "github:Benexl/yt-x";
inputs.nixpkgs.follows = "nixpkgs";
};
}-
For system-wide installation (in
configuration.nix):environment.systemPackages = [ inputs.yt-x.packages."${system}".default ];
-
For user-level installation (via Home Manager in
home.nix):nix home.packages = [ inputs.yt-x.packages."${system}".default ];
You can opt to either us it via menus or cmdline shortcuts for purposes of scripting or keybinding
yt-x [OPTIONS]
yt-x [OPTIONS] channels [CHANNEL OPTIONS]
yt-x completions [--fish | --bash | --zsh | --help]To launch the interactive terminal interface with your default settings, run:
yt-xIf you don't pass an argument to any of this options you will be prompted for the term
-s, --search <term>: Immediately execute a video search and bypass the main menu. (supports search history completion)-sp, --search-playlist <term>: Immediately execute a playlist search.-sc, --search-channel <term>: Immediately execute a channel search.-ss, --search-short <term>: Immediately execute a short search.-sm, --search-movie <term>: Immediately execute a movie search.
The values must be exact to the ones in the respective json files, completions make this easy All of them support tab completion for the saved items
-cp, --custom-playlist <name>: Open a specific custom playlist by its saved name-cc, --custom-cmd <name>: Execute a specific custom command by its saved name-sv, --saved-video <title>: Open a specific saved video by its title
-l, --launcher <fzf|rofi>: Override the default menu launcher.--preview: Enable the preview window (images/text)--no-previewDisable the preview window--preview-imagesEnable the image preview--no-preview-imagesDisable the image preview-ce, --cmd-exit: Exit after shortcut menu command‑line options (useful for scripting).-ps, --playlist-skip: Skip the playlist selection menu and automatically pick the first entry in a playlist.-me, --media-exit: Exit after performing a media action (watch, listen, download, etc.).
All this options can be paired with --media-exit and after the media cmd is executed the cli terminates
--play: Immediately watch the selected video (you still choose from the list).--play-all: Immediately play the whole playlist (implies--playlist-skip).--listen: Immediately listen to the audio of the selected video.--listen-all: Immediately listen to the whole playlist ( implies--playlist-skip).--download: Download the selected video.--download-all: Download the whole playlist (implies--playlist-skip).--download-audio: Download only the audio of the selected video.--download-audio-all: Download the whole playlist as audio (implies--playlist-skip).--save: Save the selected video to your local saved videos list so you can watch it later without needing to download it.--save-playlist: Save the current playlist to your custom playlists for the same reasons as above without needing an acc (implies--playlist-skip).--shell: Open a subshell with the current state variables. (you can use it run custom cmds on the results yt-x has gotten)
-p, --player <mpv|vlc|tplay>: Specify the media player--mpv-args: Pass custom mpv args at runtime--vlc-args: Pass custom vlc args at runtime--tplay-args: Pass custom tplay args at runtime--disown-player: Detach the player process from the terminal (allows you to keep browsing while watching).--no-disown-player: Keep the player attached to the terminal session (default).
All this options can be paired with --cmd-exit so that the start of the menus changes to the shortcuts
so going back will exit the cli
--feed: Open your personalised feed immediately.--subscriptions-feed: Open the subscriptions feed.--watch-later: Open your Watch Later playlist.--playlists: Browse saved YouTube playlists.--custom-playlists: Browse custom playlists you've saved.--saved: Open saved videos.--recent: Show recently watched videos.--liked: Open your Liked Videos playlist.--watch-history: Show your watch history.--clips: Browse your clips.--new-custom-cmd: Jump straight to creating a custom command.--custom-cmds: Execute an existing custom command.--search-history: Browse your search history.--edit-search-history: Edit the search history file.--edit-custom-playlists: Edit the custom playlists JSON file.--edit-mpv-config: Edit mpv’s configuration.--edit-yt-dlp-config: Edit yt‑dlp’s configuration.--edit-custom-cmds: Edit the custom commands JSON file.
Note there are rofi themes in repo which you can use i customized them to make the experience just cool At least thats what i think you be the judge lol
--rofi-theme-main <path>--rofi-theme-preview <path>--rofi-theme-prompt <path>--rofi-theme-confirm <path>--rofi-theme-pager <path>
-x, --extension <ext>: Load a specific extension file (absolute path or relative to~/.config/yt-x/extensions/; supports fish tab complete).-e, --edit-config: Open theyt-xconfiguration file in your$EDITOR.-U, --update: Check for and apply the latest script update from GitHub.-E, --generate-desktop-entry: Print a.desktopapplication entry tostdout; its pretty cool esp with the rofi theme in github repo for example.-v, --version: Print version information and exit.-h, --help: Show the help message and exit.--config-write: Write the current runtime config to the config file
Works only for subscribed to channels Its pretty useful for creating shortcuts and aliases to your favourite channels
yt-x [OPTIONS] channels [OPTIONS]Options:
-n, --name <channel>: Specify the channel name (exact match, case‑sensitive; tab complete supported).-s, --search <query>: Search within the channel’s uploads.-v, --videos: List the channel’s uploaded videos.-f, --featured: Show the channel’s featured playlists.-p, --playlists: List the channel’s playlists.-sh, --shorts: Show the channel’s shorts.-st, --streams: Show live streams & past broadcasts.-po, --podcasts: Show the channel’s podcasts.
Examples:
yt-x channels # Pick from subscriptions interactively
yt-x channels -n "Linus Tech Tips" -v # Browse latest videos
yt-x channels -n "iambenexl" -s "Top linux tools" # Search inside a channel
yt-x channels -n "StarTalk" -p # Show channel playlists
yt-x channels -n "The PrimeTime" -st # Show channel streams
yt-x --cmd-exit channels -n 'freeCodeCamp.org' -p # Browse freecodecamp playlists and immediately exit on back
yt-x --cmd-exit channels -n 'freeCodeCamp.org' # useful for setting aliases eg a shortcut to always go to freecodecamp channel `freecodecamp`
yt-x --launcher rofi --cmd-exit channels -n 'freeCodeCamp.org' # or as an app eg `freecodecamp-app`When entering a search query (either via the -s flag or within the interactive prompt)
Currently only one at a time is supported
- Time:
:hour,:today,:week,:month,:year - Format:
:video,:movie,:live,:short,:long - Quality/Features:
:4k,:hd,:hdr,:360,:vr,:3d,:local,:subtitles - Sorting:
:newest,:views,:rating
Example: :4k pbs eons or at the end news :today
History Recall is also supported for both (Bang Syntax)
!1: Re‑run your most recent search.!2: Re‑run your second most recent search, etc.
Almost all CLI options can be permanently set in ~/.config/yt-x/config or overridden using environment variables.
YT_X_LAUNCHER(e.g.,fzforrofi)YT_X_PLAYER(e.g.,mpv)YT_X_ENABLE_PREVIEW(trueorfalse)YT_X_ENABLE_PREVIEW_IMAGES(trueorfalse)YT_X_IMAGE_RENDERER(chafa,icat,imgcat)YT_X_BROWSER(e.g.,firefox,brave)
Hello world
# always put --config-write at the end
# it will first save the runtime config and proceed with normal execution of the command
YT_X_IMAGE_RENDERER=icat YT_X_BROWSER=firefox yt-x --preview --preview-images --config-writeDesktop app launcher
Launch yt-x as a graphical application using Rofi
Its really cool esp with the custom themes in the repo, so be sure to try
# allowing the player to run in the background when using rofi
# is a bad idea since the player will launch and rofi will launch again and block it
yt-x --launcher rofi --preview --preview-images --no-disown-playerAudio only background music
yt-x -l fzf -p mpv --disown-player --listen-all -sp "lofi hip hop radio" # skip playlist results menu
# or
yt-x -l fzf -p mpv --disown-player --listen -sp "lofi hip hop radio" # choose specific video to listen toBinge your watch later
yt-x --play-all --watch-laterSave the playlist and exit
yt-x --save-playlist --media-exit --search-playlist "anatomy"Download playlist and exit
yt-x --download-all --media-exit --search-playlist "general relativity"Search a channel and play a video
# though i already think its obvious lol
yt-x channels -n "Linus Tech Tips" -s "linux or mac" --playcreate a desktop entry
yt-x -E > ~/.local/share/applications/yt-x.desktopShell completions
# NOTE: incase of updates the completions may change or more maybe added
yt-x completions --fish > ~/.config/fish/completions/yt-x.fishlisten to a saved video
yt-x --listen --media-exit -sv "podcast"listen to a custom playlist
# you could easily keybind this
yt-x --launcher rofi --no-disown-player --listen-all --media-exit -cp "study music"Explore a custom sites playlist and play the video
# you could easily keybind this
yt-x --launcher rofi --no-disown-player --play --media-exit -cc "my custom cmd for exploring a different streaming site that yt-dlp supports"search for shorts and download
yt-x --download --media-exit -ss "linux meme"Explore the latest news and play on selection
# you could easily keybind this
yt-x --launcher rofi --no-disown-player --play --media-exit -s ":today world news"create convinience aliases
function play
yt-x --play --media-exit $argv
end
funcsave play
play -s "Top Movies"
# you could do sth similar for zsh or bash
# if you want auto complete for play just dump the completions to play.fish and find and replace yt-x with play
# also do channel aliases
function freecodecamp
yt-x --launcher fzf channel -n "freeCodeCamp.org" $argv
end
function freecodecamp-app
yt-x --launcher rofi --no-disown-player channel -n "freeCodeCamp.org" $argv
end
funcsave freecodecamp
freecodecamp --search "how llms work"By default, the main configuration file is located at:
~/.config/yt-x/config(Note: It respects the $XDG_CONFIG_HOME environment variable if set).
You can open it using the cli
yt-x --edit-config| Variable | Default | Description |
|---|---|---|
CONFIG_LAUNCHER |
fzf |
The menu launcher tool to use. Options: fzf or rofi. |
CONFIG_ENABLE_COLORS |
true |
Enable or disable ANSI true-color (24-bit) formatting in the UI. |
CONFIG_PER_PAGE |
30 |
Maximum number of search/list results to fetch and display per page. |
CONFIG_EDITOR |
vi (or $EDITOR) |
Text editor used for editing config files, histories, and extensions. |
CONFIG_NOTIFICATION_DURATION |
5 |
Duration (in seconds) for desktop/CLI notifications to remain visible. |
| Variable | Default | Description |
|---|---|---|
CONFIG_ENABLE_PREVIEW |
false |
Enable or disable the preview window (metadata & descriptions). |
CONFIG_ENABLE_PREVIEW_IMAGES |
false |
whether to render thumbnails in the preview window. |
CONFIG_IMAGE_RENDERER |
chafa |
Tool used to render images in the terminal. Options: chafa, icat, imgcat. |
CONFIG_CHAFA_ARGS |
"" |
Pass custom arguments to chafa (e.g., --polite on). |
CONFIG_ICAT_ARGS |
"" |
Pass custom arguments to icat / kitty +kitten icat. |
CONFIG_IMGCAT_ARGS |
"" |
Pass custom arguments to imgcat. |
For configuring a player prefer its config file which you can also edit from why yt-x in the misc menu They exist purely for convinience and is more useful when passing from cmdline or env vars
| Variable | Default | Description |
|---|---|---|
CONFIG_PLAYER |
mpv |
Preferred media player. Options: mpv, vlc, tplay. |
CONFIG_DISOWN_PLAYER |
false |
Set to true to run the player in the background without blocking the UI. |
CONFIG_MPV_ARGS |
"" |
Custom arguments passed directly to mpv. |
CONFIG_VLC_ARGS |
"" |
Custom arguments passed directly to vlc. |
CONFIG_TPLAY_ARGS |
"" |
Custom arguments passed directly to tplay. |
| Variable | Default | Description |
|---|---|---|
CONFIG_BROWSER |
"" |
Which browser yt-dlp should use to get browser cookies to access private playlists etc |
CONFIG_YT_DLP_ARGS |
"" |
pass custom arguments though prefer yt-dlp config file |
| Variable | Default | Description |
|---|---|---|
CONFIG_DOWNLOAD_DIR |
~/Videos/yt-x |
Base directory where all downloaded videos and audio files are saved. |
CONFIG_DOWNLOADS_ENUMERATE |
false |
Set to true to prepend numbers (01 -, 02 -) to downloaded playlist items. |
| Variable | Default | Description |
|---|---|---|
CONFIG_ENABLE_SEARCH_HISTORY |
true |
Save local search history to track and quickly recall past queries. |
CONFIG_NO_OF_RECENT |
10 |
The number of recent "Watch History" items to retain locally. |
CONFIG_CACHE_RETENTION_DAYS |
3 |
Auto-clean stale preview images, autogen playlists, and logs older than this duration. |
Check the repo for pre-configured rofi themes
| Variable | Default | Description |
|---|---|---|
CONFIG_FZF_HEADER |
(logo) | A custom header string displayed at the top of the fzf menu (defaults to the yt-x ASCII logo). |
CONFIG_FZF_OPTS |
(see config) | Fine‑tune fzf layout, colors, pointers, and keybindings. Defaults to "Tokyo Night" . |
CONFIG_GUM_FILTER_OPTS |
(see config) | Fine‑tune gum filter layout, colors, prompt, indicator, match highlighting, and placeholder. Defaults to Tokyo Night. |
CONFIG_GUM_INPUT_OPTS |
(see config) | Fine‑tune gum input prompt, cursor, placeholder, and header colors. Defaults to Tokyo Night. |
CONFIG_GUM_PAGER_OPTS |
(see config) | Fine‑tune gum pager foreground, line numbers, match highlights, and soft‑wrap behavior. Defaults to Tokyo Night. |
CONFIG_GUM_SPIN_OPTS |
(see config) | Fine‑tune gum spin spinner type, foreground, title color, and alignment. Defaults to Tokyo Night. |
CONFIG_GUM_CONFIRM_OPTS |
(see config) | Fine‑tune gum confirm prompt, selected/unselected colors, and affirmative/negative labels. Defaults to Tokyo Night. |
CONFIG_ROFI_THEME_MAIN |
"" |
Path to a custom Rofi .rasi theme for the main menu. |
CONFIG_ROFI_THEME_PREVIEW |
"" |
Path to a custom Rofi .rasi theme for the preview menu. |
CONFIG_ROFI_THEME_PROMPT |
"" |
Path to a custom Rofi .rasi theme for prompt dialogs. |
CONFIG_ROFI_THEME_CONFIRM |
"" |
Path to a custom Rofi .rasi theme for confirmation dialogs. |
CONFIG_ROFI_THEME_PAGER |
"" |
Path to a custom Rofi .rasi theme for the pager. |
| Variable | Default | Description |
|---|---|---|
CONFIG_AUTOLOADED_EXTENSIONS |
"" |
Comma-separated list of extension scripts to load automatically on startup. |
CONFIG_CHECK_FOR_UPDATES |
true |
Periodically check the GitHub repository for updates and prompt to install. |
yt-x supports extensions to add or override functionality without modifying the core script.
Extensions are shell scripts placed in ~/.config/yt-x/extensions/ and can be loaded on demand or automatically.
The following extensions are maintained and included in the repository.
downloads by Benexl
Replaces the main menu with a local media browser.
Lets you explore and play videos/audio files already downloaded to CONFIG_DOWNLOAD_DIR.
Features:
- Browse by individual files, playlists (subfolders), or channels (nested folders).
- Previews with
ffmpegthumbnailer(if installed). - Play, play all, listen, listen all – supports the same media actions as online content.
Load with:
yt-x -x cmd/downloads
br.lang by aglairdev
Brazilian Portuguese translation for all UI texts, prompts, and messages.
Overrides the default English strings.
Load with:
yt-x -x langs/br.lang
es.lang by Benexl
Spanish translation for all UI texts, prompts, and messages.
Load with:
yt-x -x langs/es.lang
dailymotion.site by Benexl
Adds a Dailymotion entry to the main menu.
Allows you to:
- Search Dailymotion videos.
- Explore a user’s uploads.
- Browse a specific playlist.
Uses the same playlist explorer and media actions as YouTube.
Load with:
yt-x -x sites/dailymotion.site
catppuccin-mocha.theme by Benexl
Applies the Catppuccin Mocha color scheme to fzf and the terminal output.
Includes custom fzf options (border, colors, preview window) and ANSI escape codes for primary/secondary/accent/error colors.
Requirements: True‑color terminal support (COLORTERM=truecolor).
Load with:
yt-x -x themes/catppuccin-mocha.theme
Temporary (single session)
yt-x -x sites/dailymotion.site
yt-x -x langs/es.lang
yt-x -x themes/catppuccin-mocha.theme
yt-x -x cmd/downloads # replaces main menu with a local media browserPermanent
Add to ~/.config/yt-x/config:
CONFIG_AUTOLOADED_EXTENSIONS="themes/catppuccin-mocha.theme,langs/es.lang"- Create the appropriate subdirectory (if missing) inside
~/.config/yt-x/extensions/. - Write a POSIX‑compliant shell script.
- The script is sourced by
yt-x, so you can:- Override any function (e.g.,
menu_main,_menu_playlist_actions). - Add new menu items by appending to the
actionsvariable. - Define new helper functions.
- Use all internal variables and functions (prefixed with
_or public likeui_prompt).
- Override any function (e.g.,
- Extensions are sourced, not executed – they run inside the main script’s context.
- Avoid
exitorexecunless you really want to terminateyt-x. - Use
returninstead ofexitto stop processing the extension. - You can combine multiple extensions; load order is the order they appear in
CONFIG_AUTOLOADED_EXTENSIONS(or the order of-xflags). - For commands (
cmds/), your script must define a functionmenu_mainthat replaces the default main menu (seecmds/downloads).
Check the extensions/ folder in the repository for examples.
Reporting Bugs
yt-x is just a wrapper over amazing cmdline tools. (yt-dlp,fzf,rofi,mpv etc)
Before opening an issue on GitHub, please determine if the bug is actually related to yt-x or one this tools
For example:
- Media Fetching/Downloading fails: This is handled by
yt-dlp. If a specific site breaks or videos refuse to download, try updatingyt-dlpfirst (yt-dlp -U). - State management, navigation, or UI/preview logic fails: This is handled by
yt-x. Please open an issue!
How do I access age-restricted or members-only videos?
You need to pass your browser cookies to yt-dlp.
You can do this natively in yt-x by editing your config (~/.config/yt-x/config)
and setting the CONFIG_BROWSER variable to your a supported browser by yt-dlp (e.g., firefox, chrome, brave).
Note: you can also configure your media player to use these cookies (see the MPV optimization tip below).
How can I optimize MPV playback (Quality, Cookies, Hardware Decoding)?
By default, mpv handles streaming via yt-dlp under the hood.
To ensure mpv uses your browser cookies and defaults to 1080p hardware-accelerated playback, add something like this to your ~/.config/mpv/mpv.conf:
You can also do it from the miscellaneous menu
# Pass cookies to yt-dlp inside mpv
# Force highest quality 1080p video + best audio
# plus handle subs
# you could also add sponsor block and chapters
# by adding --embed-chapters --sponsorblock-mark all to the list
ytdl-raw-options=format-sort="res:1080,vcodec:vp9,acodec:opus,fps",sub-lang="en,eng,enUS,en-US",write-sub=,write-auto-sub=,cookies-from-browser=firefox
ytdl-format=bestvideo+bestaudio/best
# if you know the exact decoder specify it vaapi for intel gpus or i think *nvdec for nvidia gpus
hwdec=auto
vo=gpu
# subs
slang=en,eng,enUS,en-US
sub-auto=fuzzyWhat yt-dlp config do you use?
Something like this
# though format sort would be better just recently discovered it lol check the mpv faq above to see how or the official readme
-f bestvideo[height=1080][fps=60][vcodec^=vp9]+bestaudio/best[height=1080][fps=60][vcodec^=hevc]+bestaudio/best[height=1080][fps=60][vcodec^=avc1]/bestvideo[height=1080][fps<=30][vcodec^=vp9]+bestaudio/best[height=1080][fps<=30][vcodec^=hevc]+bestaudio/best[height=1080][fps<=30][vcodec^=avc1]/bestvideo[height>=720][height<1080][fps=60][vcodec^=vp9]+bestaudio/best[height>=720][height<1080][fps=60][vcodec^=hevc]+bestaudio/best[height>=720][height<1080][fps=60][vcodec^=avc1]/bestvideo[height>=720][height<1080][fps<=30][vcodec^=vp9]+bestaudio/best[height>=720][height<1080][fps<=30][vcodec^=hevc]+bestaudio/best[height>=720][height<1080][fps<=30][vcodec^=avc1]/bestvideo[height>=720]+bestaudio/best
--embed-chapters
--sponsorblock-mark all
--embed-metadata
--embed-thumbnail
--add-metadata
--embed-subs
--sub-lang en
--merge-output-format mkv
--no-warnings
--quiet
--reject-title "\[Deleted video\]|\[Private video\]"
--progress
How do i filter out deleted or private videos?
Add something like this to yt-dlp config
--reject-title "\[Deleted video\]|\[Private video\]"
How can I reorder, add, or remove menu entries? (Customizing menus)
yt-x menus are built from simple lists of actions. You can customize them without touching the main script by using extensions (see the Extensions section).
All menu functions accept optional parameters that let you filter, reorder, or add extra actions. The key functions are:
_menu_main– Main menu (Your Feed, Search, Channels, etc.)_menu_miscellaneous– Misc menu (Explore Channels, Custom Commands, etc.)_menu_channel_actions– Actions inside a channel (Videos, Playlists, Subscribe, etc.)_menu_playlist_actions– Media action menu (Watch, Listen, Download, etc.)
Each of these functions supports the same four optional arguments:
_menu_main [sort] [filter_regex] [extra_actions] [handler_function]| Argument | Purpose |
|---|---|
sort |
Comma‑separated list of line numbers to reorder menu items. |
filter_regex |
grep pattern to remove matching lines. |
extra_actions |
Newline‑separated string of extra menu entries. |
handler_function |
Function name to call when an extra action is selected. |
# override menu_main with a filter
menu_main() {
_menu_main "" "Clips"
}The sort argument expects line numbers (1‑based, from the default menu order).
To see the current order, run yt-x and count the entries, or inspect the actions variable inside the function.
Assuming default main menu order: 1=Your Feed, 2=Search, 3=Subscriptions Feed, …
menu_main() {
_menu_main "2,1" # Search first, then Feed
}my_custom_handler() {
case "$1" in
"My Favourites") yt-x -cp "My Favourites" ;;
*) return 1 ;;
esac
}
menu_main() {
extra=" My Favourites"
_menu_main "" "" "$extra" my_custom_handler
}menu_main() {
_state_init
# Remove "Clips", reorder (Search #2 first), add a "Daily Mix" entry
_menu_main "2,1" "Clips" " Daily Mix" my_custom_handler
}Remove "Mix" and "Save Playlist", add a custom "Convert to MP3" action:
convert_to_mp3() {
# your conversion logic using STATE_CURRENT_VIDEO_URL
notify-send "Converting..."
}
menu_playlist_actions() {
_menu_playlist_actions "" "Mix\\|Save Playlist" " Convert to MP3" convert_to_mp3
}- The
filter_regexuses extended regular expressions. Separate multiple patterns with|. You can reference$TXT_MENU_VARSto make this easier. - Extra entries must include an icon and the text exactly as you want it to appear.
- Your custom handler receives the selected action text as
$1. Return0if handled,1if not (so the default handler can process it). - To make changes permanent, add the overrides to an extension and autoload it via
CONFIG_AUTOLOADED_EXTENSIONS.
Check the Extensions section for more details on loading and writing extensions.
I don't like (or can't use) Nerd Font icons. How do I disable or replace them?
The icons are stored in language variables like TXT_ICON_MENU_MAIN_FEED, TXT_ICON_MENU_PLAYLIST_ACTIONS_WATCH, etc.
Create an extension that overrides these variables with empty strings or simple ASCII symbols.
Example: ~/.config/yt-x/extensions/ui/no-icons.ui
TXT_ICON_MENU_MAIN_FEED=""
TXT_ICON_MENU_MAIN_SEARCH=""
TXT_ICON_MENU_PLAYLIST_ACTIONS_WATCH=""
# Or replace them with simple ASCII prefixes
TXT_ICON_MENU_MAIN_FEED="[F]"
TXT_ICON_MENU_MAIN_SEARCH="[S]"
TXT_ICON_MENU_PLAYLIST_ACTIONS_WATCH="[W]"
# ... add more as neededLoad it with -x ui/no-icons.ui or add to CONFIG_AUTOLOADED_EXTENSIONS.
If your terminal displays empty squares or missing characters, you're missing a Nerd Font.
Install a Nerd Font (e.g., JetBrainsMono Nerd Font, Cascadia Code NF) and set your terminal to use it – all icons will appear correctly.
I think they are cool lol
Why are my image previews not showing up?
Image previews require a few components to work together:
- Ensure you have enabled them in your config:
CONFIG_ENABLE_PREVIEW=trueandCONFIG_ENABLE_PREVIEW_IMAGES=true. - Ensure you have a supported image renderer installed (e.g.,
chafa,icat, orimgcat). - Set the correct renderer in your config:
CONFIG_IMAGE_RENDERER="chafa". - Ensure your terminal emulator actually supports image rendering (sixel, kitty graphics protocol, or iTerm2 protocol). If it doesn't, stick with
chafa, which falls back to excellent ASCII/block character rendering.
How do I fix "Cannot decrypt v11 cookies", Flatpak, or unsupported browser errors?
yt-x passes the CONFIG_BROWSER variable directly to yt-dlp.
- Chromium v11+ / Brave / Edge: Modern Chromium browsers encrypt cookies via your OS keyring (GNOME Keyring, KWallet).
yt-dlpneeds access to this keyring to decrypt them. - Flatpaks / Snaps:
yt-dlpcannot easily read cookies from containerized browsers due to sandboxing. Use natively installed browsers (deb/rpm/AUR/Homebrew) for the best cookie compatibility. - Alternative: If your browser (like Zen) isn't supported natively, use an extension like "Get cookies.txt LOCALLY", save the file, and pass it via your config:
CONFIG_YT_DLP_ARGS="--cookies /path/to/cookies.txt".
How do i set qute-browser in my config?
CONFIG_BROWSER="chromium:~/.local/share/qutebrowser"Previews overlap text or look distorted. How do I fix this?
If your images are overlapping with UI text, your terminal may not properly support the image clearing sequences used by chafa.
- Kitty / Ghostty: Set
CONFIG_IMAGE_RENDERER="icat". - iTerm2 / WezTerm: Try
CONFIG_IMAGE_RENDERER="imgcat". - Other Terminals: Stick to
CONFIG_IMAGE_RENDERER="chafa", but ensure your terminal supports Sixel or true-color ASCII. If overlaps persist, disable image previews (CONFIG_ENABLE_PREVIEW_IMAGES=false) and use text-only previews.
also make sure to delete the ~/.cache/yt-x/previews/text/fzf-preview.sh file to clear out old cached values that may have been generated with the wrong renderer settings
How do I add Vim motions (j/k) or change menu keybindings?
Since the UI is driven by fzf, you can easily customize keybindings by modifying the CONFIG_FZF_OPTS variable in your ~/.config/yt-x/config file.
Add --bind flags to map your preferred keys. For example, to add Vim motions and page scrolling:
CONFIG_FZF_OPTS="...your existing options... --bind 'j:down,k:up,ctrl-u:half-page-up,ctrl-d:half-page-down'"How do I return to the menu while a video is playing?
By default, yt-x blocks the terminal until the media player is closed. To browse while watching, enable background playback by setting CONFIG_DISOWN_PLAYER=true in your config, or launch the script with the --disown-player flag.
Why is a video playing in the wrong quality (e.g., 4K instead of 1080p) or throwing "Requested Format not available"?
Configure your media player. Add something like this to your ~/.config/mpv/mpv.conf:
ytdl-format="bestvideo[height<=?1080]+bestaudio/best"
I have no audio when playing videos on Termux / Android.
On Android, yt-x does not play the media inside the terminal. Instead, it uses Android am start intents to pass the stream URL to an installed GUI application (like the VLC or MPV Android apps).
Since you can't directly use the mpv command in termux unless you have installed a window manager so apps like mpv and vlc android are used through android intents api and there it only supports giving it one url
the script uses --get-url yt-dlp opt inorder to get the url but only picks the top one for video where the second maybe the audio file if the video has a separate audio file
so to 'fix' this you only need to specify --format yt-dlp opt in your config where you specify merged formats like best --format 'best'
in case someone figures out how to also pass an audio file(more than one url) using android intents this will always limit what you can stream to only merged files and incase you do please share :)
I'm getting "Malformed State" or "Invalid Action" errors constantly.
Its either a bug or you pressed ctrl+c too fast and it triggered the state dir to be wiped by trap cmd
I customized my colors and now the script crashes with "Invalid color specification".
This is an fzf error especially in debian systems where the fzf version maybe older.
So just update it using more upto date ppa's or use Homebrew its what i used to use when i first started using linux (ubuntu)
works supprisingly well
How do I populate the Channels/Subscriptions tab? It says my JSON is empty.
You need to sync your subscriptions first.
- Ensure
CONFIG_BROWSERis set to the browser where you are logged into YouTube. - Go to the Main Menu -> Miscellaneous -> Sync YouTube Subscriptions.
yt-dlpwill use your browser cookies to fetch your subscriptions and populate the~/.config/yt-x/subscriptions.jsonfile.
How can I get my system to display media metadata (title, artist) when using the "Listen" action?
This is actually a feature of your media player rather than yt-x.
Integrating this directly into yt-x would require intercepting mpv's output using Lua scripts or enforcing playerctl + MPRIS ,
which i don't want to do nor think its a good idea
The Solution: The cleanest way to achieve this is by enabling MPRIS support directly in your media player.
- For
mpv: Install thempv-mprisplugin. This allowsmpvto broadcast the current track's metadata to your OS, exactly like a web browser does for YouTube. - For other players: Search for similar MPRIS or D-Bus integration plugins/settings.
Once configured, any compatible desktop widget or notification daemon will automatically pick it up and display what's playing. For example, this is how it looks in myNoctalia setup on Niri:
How can I play or download something without any interactive menus? (Non‑interactive mode)
yt-x now supports several flags that let you bypass all menus and run actions non‑interactively – perfect for scripting, keybindings, or quick one‑off commands.
--playlist-skip(-ps) : Automatically picks the first item in any list (search results, playlist, etc.) without showing the selection menu.--play-all,--listen-all,--download-all,--download-audio-all,--save-playlist: These implicitly enable--playlist-skipand act on the whole playlist immediately.--media-exit(-me) : After performing a media action (play, download, save, etc.), exit the script.--cmd-exit(-ce) : After processing any shortcut menu command (e.g.,--feed,--subscriptions-feed), exit.
Examples:
# Play the first video from a search and exit
yt-x --playlist-skip --media-exit --play -s "Dota"
# Download the whole Watch Later playlist without any prompts
yt-x --download-all --watch-later
# Save the current playlist as a custom playlist and exit
yt-x --save-playlist --media-exitread usage for more examples and cmdline docs
What is the `--shell` flag and when should I use it?
--shell(media action) drops you into a subshell that is pre‑loaded with all the current session’s state variables.
Its useful for running custom cmds on the current results
Available variables in the subshell include:
STATE_CURRENT_VIDEO,STATE_CURRENT_VIDEO_URL,STATE_CURRENT_VIDEO_TITLESTATE_CURRENT_PLAYLIST_RESULTS,STATE_CURRENT_PLAYLIST_URL,STATE_CURRENT_PLAYLIST_TITLE- Channel info, pagination indices, etc.
You can use this to, for example, manually run yt-dlp commands on the current video, extract metadata, or automate custom post‑processing.
Note some are json so use jq to parse and inspect them or interactive ones like ijq and jnv
How do I override configuration settings using environment variables?
Every config variable can be overridden by an environment variable prefixed with YT_X_. This is useful for scripting or one‑off changes without touching the config file.
Examples:
# Use rofi as launcher for this session
YT_X_LAUNCHER=rofi yt-x
# Enable previews and use chafa for images
YT_X_ENABLE_PREVIEW=true YT_X_IMAGE_RENDERER=chafa yt-x
# Change download directory temporarily
YT_X_DOWNLOAD_DIR="$HOME/Downloads/temp" yt-x --download-allSee the config file for all available variables (e.g., YT_X_PLAYER, YT_X_BROWSER, YT_X_PER_PAGE, etc.).
How can i get mpv to look like the one in the demos (just look nicer)?
I personaly use uosc which in my opinion its by far the best ui for mpv. They have even implemented rendering yt's heatmap in the timeline. You can even also install thumbfast which will add timeline previews.
Pull requests are highly welcome :)
If you enjoy using yt-x and want to support its ongoing development, consider leaving a Star on GitHub!


















