Skip to content

Benexl/yt-x

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

505 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

📺 yt-x

Browse YouTube and other yt-dlp supported sites directly from your terminal or app launcher.

GitHub Issues or Pull Requests GitHub License GitHub file size in bytes GitHub Release GitHub commit activity

recording_20260509_095830.mp4
View Demos & Previews

Full Demo:

yt-x-full-github-demo.webm

Riced/Customized Previews:

image image image image image image image image image image image image image image image image image image image

Table of Contents

Features

  • Multiple Launcher Support: with fzf, rofi all 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
  • Search History & Recall: Automatically saves search history. Allows quick recall of previous searches using bang syntax (e.g., !1 for the most recent search, !2 for 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 .ui extensions
  • Theming & Styling: theming support through .theme extensions with tokyo night as the default theme.
  • Multi-language Support: Loadable language files (.lang) to easily localize the UI prompts and messages(currently es and br. 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, and tplay.
  • Playlist Actions: Play individual videos, queue/play entire playlists, or queue "Listen to All" for audio-only
  • Auto-Mix Generation: Dynamically generates .m3u8 playlist 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-archive opt) to track previously downloaded media and prevent duplicate downloads.
  • Organized File Structure: Automatically routes downloads into structured directories (e.g., video/individual/ChannelName/ or audio/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_BROWSER passes 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-dlp options (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 .desktop file, 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 start intents 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.

Installation

Linux macOS Windows Android Arch Linux NixOS

Prerequisites

Required:

  • yt-dlp - For fetching the data and downloading media.
  • fzf - Main launcher
  • jq - For parsing json
  • curl - For fetching script updates and preview images. (version 7.6+; that supports --parallel downloads)
  • 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:
    • kitty personal favourite; started the great terminal era lol
    • ghostty
    • wezterm
  • 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).
    • bat to show update diffs in a nicer way

Universal Installation

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-x

To 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.


Platform-Specific Instructions

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-git
Nix / NixOS

1. Imperative:

nix profile install github:Benexl/yt-x

2. 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 ];

Usage

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]

Quick Start

To launch the interactive terminal interface with your default settings, run:

yt-x

Command‑Line Options

Search

If 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.

Access saved items

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

Ui

  • -l, --launcher <fzf|rofi> : Override the default menu launcher.
  • --preview : Enable the preview window (images/text)
  • --no-preview Disable the preview window
  • --preview-images Enable the image preview
  • --no-preview-images Disable 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.).

Media Action Shortcuts (skip the media action menu)

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)

Player & Playback

  • -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).

Direct Shortcuts (skip the main or miscellaneous menus)

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.

Rofi

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>

Others

  • -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 the yt-x configuration file in your $EDITOR.
  • -U, --update : Check for and apply the latest script update from GitHub.
  • -E, --generate-desktop-entry : Print a .desktop application entry to stdout; 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

Channels Subcommand

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`

Inline Search Syntax & Filters

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.

Environment Variables

Almost all CLI options can be permanently set in ~/.config/yt-x/config or overridden using environment variables.

  • YT_X_LAUNCHER (e.g., fzf or rofi)
  • YT_X_PLAYER (e.g., mpv)
  • YT_X_ENABLE_PREVIEW (true or false)
  • YT_X_ENABLE_PREVIEW_IMAGES (true or false)
  • YT_X_IMAGE_RENDERER (chafa, icat, imgcat)
  • YT_X_BROWSER (e.g., firefox, brave )

Examples & Workflows

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-write

Desktop 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-player

Audio 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 to

Binge your watch later

yt-x --play-all --watch-later

Save 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" --play

create a desktop entry

yt-x -E > ~/.local/share/applications/yt-x.desktop

Shell completions

# NOTE: incase of updates the completions may change or more maybe added
yt-x completions --fish > ~/.config/fish/completions/yt-x.fish

listen 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"

Configuration

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

Configuration Variables

Display & Interface

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.

Media Previews

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.

Playback & Media Handling

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.

yt-dlp

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

Downloading

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.

History & Caching

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.

Fzf, gum and Rofi

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.

Others

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.

Extensions

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.

Official Extensions

The following extensions are maintained and included in the repository.

Command Extensions (cmds/)

downloads by Benexl image image image image

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


Language Extensions (langs/)

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


Site Extensions (sites/)

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


Theme Extensions (themes/)

catppuccin-mocha.theme by Benexl image image image image image image

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


Loading Extensions

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 browser

Permanent
Add to ~/.config/yt-x/config:

CONFIG_AUTOLOADED_EXTENSIONS="themes/catppuccin-mocha.theme,langs/es.lang"

Creating Your Own Extension

  1. Create the appropriate subdirectory (if missing) inside ~/.config/yt-x/extensions/.
  2. Write a POSIX‑compliant shell script.
  3. 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 actions variable.
    • Define new helper functions.
    • Use all internal variables and functions (prefixed with _ or public like ui_prompt).

Important Notes

  • Extensions are sourced, not executed – they run inside the main script’s context.
  • Avoid exit or exec unless you really want to terminate yt-x.
  • Use return instead of exit to stop processing the extension.
  • You can combine multiple extensions; load order is the order they appear in CONFIG_AUTOLOADED_EXTENSIONS (or the order of -x flags).
  • For commands (cmds/), your script must define a function menu_main that replaces the default main menu (see cmds/downloads).

Check the extensions/ folder in the repository for examples.

Frequently Asked Questions (FAQ)

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 updating yt-dlp first (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=fuzzy
What 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.

Examples (put these in an extension file, e.g., ~/.config/yt-x/extensions/ui/zen.ui)

1. Remove an entry (e.g., hide "Clips" from main menu)

# override menu_main with a filter
menu_main() {
  _menu_main "" "Clips"
}

2. Reorder menu entries (show Search first, then Feed)

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
}

3. Add a custom entry that launches your favourite playlist

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
}

4. Combine filtering, reordering, and adding

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
}

5. Customize the media action menu (playlist actions)

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
}

Important Notes

  • The filter_regex uses extended regular expressions. Separate multiple patterns with |. You can reference $TXT_MENU_VARS to 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. Return 0 if handled, 1 if 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?

Method 1: Disable all icons (plain text fallback)

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 needed

Load it with -x ui/no-icons.ui or add to CONFIG_AUTOLOADED_EXTENSIONS.

Method 2: Use a font that bundles icons (recommended)

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.

Why are icons used?

I think they are cool lol

Why are my image previews not showing up?

Image previews require a few components to work together:

  1. Ensure you have enabled them in your config: CONFIG_ENABLE_PREVIEW=true and CONFIG_ENABLE_PREVIEW_IMAGES=true.
  2. Ensure you have a supported image renderer installed (e.g., chafa, icat, or imgcat).
  3. Set the correct renderer in your config: CONFIG_IMAGE_RENDERER="chafa".
  4. 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-dlp needs access to this keyring to decrypt them.
  • Flatpaks / Snaps: yt-dlp cannot 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.

  1. Kitty / Ghostty: Set CONFIG_IMAGE_RENDERER="icat".
  2. iTerm2 / WezTerm: Try CONFIG_IMAGE_RENDERER="imgcat".
  3. 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.

  1. Ensure CONFIG_BROWSER is set to the browser where you are logged into YouTube.
  2. Go to the Main Menu -> Miscellaneous -> Sync YouTube Subscriptions. yt-dlp will use your browser cookies to fetch your subscriptions and populate the ~/.config/yt-x/subscriptions.json file.
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 the mpv-mpris plugin. This allows mpv to 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:

Noctalia MPRIS Example 1 Noctalia MPRIS Example 2 Noctalia MPRIS Example 3
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-skip and 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-exit

read 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_TITLE
  • STATE_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-all

See 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.

Contribution

Pull requests are highly welcome :)

Supporting the Project

If you enjoy using yt-x and want to support its ongoing development, consider leaving a Star on GitHub!

About

Posix script to browse youtube plus other yt-dlp supported sites from your terminal (fzf) or app launcher (rofi) with optional previews. (supports bash, zsh and dash)

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

  •  

Contributors