Last active
May 15, 2026 04:15
-
-
Save brokosz/dc29ff9a0627ffb1bb19dff4929c4369 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/zsh | |
| # YouTube Stream Aliases | |
| # Requires IINA and yt-dlp | |
| # Save as ~/.config/zsh/youtube-streams.zsh or ~/.zsh_youtube_streams | |
| # Then source in ~/.zshrc with: source ~/.config/zsh/youtube-streams.zsh | |
| # Help | |
| streams_help() { | |
| cat <<'EOF' | |
| YouTube Streams - background music via IINA | |
| <alias> Play a saved stream (e.g. lofi, jazz, deephouse) | |
| stop_stream Stop the current stream | |
| list_streams List all saved stream aliases | |
| find_stream <keywords> Search and play top live result | |
| find_streams <keywords> Search and list top 10 live results | |
| play_result <n> Play result #n from last search | |
| open_result <n> Open result #n in browser | |
| add_result <n> <name> Save result #n as a permanent alias | |
| add_stream <name> <url> Save a new stream alias | |
| remove_stream <name> Remove a saved stream alias | |
| check_streams Validate all streams, remove dead ones | |
| streams_help This help | |
| EOF | |
| } | |
| # Play a stream in IINA music mode (kills previous stream instance to avoid stacking) | |
| _play_stream() { | |
| local url="$1" | |
| local stream_url | |
| stream_url=$(yt-dlp -g -f "worst" --no-warnings "$url" 2>/dev/null | head -1) | |
| if [[ -z "$stream_url" ]]; then | |
| echo "Failed to resolve stream: $url" | |
| return 1 | |
| fi | |
| [[ -n "$_IINA_STREAM_PID" ]] && kill "$_IINA_STREAM_PID" 2>/dev/null | |
| iina --music-mode --no-stdin "$stream_url" | |
| _IINA_STREAM_PID=$(pgrep -n -x IINA) | |
| } | |
| # Stop the current stream | |
| stop_stream() { | |
| if [[ -n "$_IINA_STREAM_PID" ]]; then | |
| kill "$_IINA_STREAM_PID" 2>/dev/null | |
| unset _IINA_STREAM_PID | |
| echo "Stream stopped." | |
| else | |
| echo "No stream playing." | |
| fi | |
| } | |
| # Search for a live stream by keyword and play it (or list results) | |
| find_stream() { | |
| if [[ $# -eq 0 ]]; then | |
| echo "Usage: find_stream <keywords> [--list]" | |
| echo " play_result <number>" | |
| return 1 | |
| fi | |
| local list_only=false | |
| local count=10 | |
| local query="$*" | |
| if [[ "${@[-1]}" == "--list" ]]; then | |
| list_only=true | |
| query="${*[1,-2]}" | |
| fi | |
| if [[ "${query%% *}" =~ ^[0-9]+$ ]]; then | |
| count="${query%% *}" | |
| query="${query#* }" | |
| fi | |
| echo "Searching for live streams: $query" | |
| _STREAM_RESULTS=() | |
| local results | |
| local encoded_query=$(python3 -c "import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1]))" "$query") | |
| results=$(yt-dlp --no-warnings --flat-playlist --playlist-end "$count" \ | |
| --print "%(id)s|%(title)s|%(channel)s" \ | |
| "https://www.youtube.com/results?search_query=${encoded_query}&sp=EgJAAQ%3D%3D" 2>/dev/null) | |
| if [[ -z "$results" ]]; then | |
| echo "No live streams found." | |
| return 1 | |
| fi | |
| local i=1 | |
| echo "$results" | while IFS='|' read -r id title channel; do | |
| _STREAM_RESULTS+=("https://www.youtube.com/watch?v=$id") | |
| if $list_only; then | |
| echo " $i) $title [$channel]" | |
| fi | |
| ((i++)) | |
| done | |
| if ! $list_only; then | |
| local first_title=$(echo "$results" | head -1 | cut -d'|' -f2) | |
| local first_channel=$(echo "$results" | head -1 | cut -d'|' -f3) | |
| echo "Playing: $first_title [$first_channel]" | |
| _play_stream "${_STREAM_RESULTS[1]}" | |
| fi | |
| } | |
| # Play a result from the last find_stream --list | |
| play_result() { | |
| if [[ -z "${_STREAM_RESULTS[$1]}" ]]; then | |
| echo "No result #$1. Run find_streams <keywords> first." | |
| return 1 | |
| fi | |
| _play_stream "${_STREAM_RESULTS[$1]}" | |
| } | |
| # Search and list (shorthand for find_stream --list) | |
| find_streams() { find_stream "$@" --list; } | |
| # Save a result from the last find_streams as a permanent alias | |
| add_result() { | |
| if [[ $# -ne 2 ]]; then | |
| echo "Usage: add_result <number> <alias_name>" | |
| return 1 | |
| fi | |
| if [[ -z "${_STREAM_RESULTS[$1]}" ]]; then | |
| echo "No result #$1. Run find_streams <keywords> first." | |
| return 1 | |
| fi | |
| add_stream "$2" "${_STREAM_RESULTS[$1]}" | |
| } | |
| # Open a result's YouTube page in the browser | |
| open_result() { | |
| if [[ -z "${_STREAM_RESULTS[$1]}" ]]; then | |
| echo "No result #$1. Run find_streams <keywords> first." | |
| return 1 | |
| fi | |
| open "${_STREAM_RESULTS[$1]}" | |
| } | |
| # Lo-fi Hip Hop streams | |
| alias lofi='_play_stream "https://www.youtube.com/watch?v=jfKfPfyJRdk"' | |
| alias chillhop='_play_stream "https://www.youtube.com/watch?v=5yx6BWlEVcY"' | |
| alias chill='_play_stream "https://www.youtube.com/watch?v=28KRPhVzCus"' | |
| # Jazz streams | |
| alias jazz='_play_stream "https://www.youtube.com/watch?v=Dx5qFachd3A"' | |
| alias lofijazz='_play_stream "https://www.youtube.com/watch?v=HuFYqnbVbzY"' | |
| # Ambient/Study streams | |
| alias ambient='_play_stream "https://www.youtube.com/watch?v=xORCbIptqcc"' | |
| alias study='_play_stream "https://www.youtube.com/watch?v=1oDrJba2PSs"' | |
| # Cafe/Coffee shop ambience | |
| alias cafe='_play_stream "https://www.youtube.com/watch?v=h2zkV-l_TbY"' | |
| # Classical streams | |
| alias classical='_play_stream "https://www.youtube.com/watch?v=jgpJVI3tDbY"' | |
| # Electronic/Synthwave | |
| alias synthwave='_play_stream "https://www.youtube.com/watch?v=4xDzrJKXOOY"' | |
| alias chillwave='_play_stream "https://www.youtube.com/watch?v=_WoqCd57AP0"' | |
| # Helper function to add new streams easily | |
| add_stream() { | |
| if [[ $# -ne 2 ]]; then | |
| echo "Usage: add_stream alias_name youtube_url" | |
| return 1 | |
| fi | |
| local alias_name="$1" | |
| local youtube_url="$2" | |
| local file=~/.config/zsh/youtube-streams.zsh | |
| if [[ ! "$alias_name" =~ ^[a-z0-9_]+$ ]]; then | |
| echo "Invalid alias name. Use lowercase letters, numbers, and underscores only." | |
| return 1 | |
| fi | |
| if grep -q "^alias $alias_name=" "$file"; then | |
| echo "Alias '$alias_name' already exists." | |
| return 1 | |
| fi | |
| if grep -q "$youtube_url" "$file"; then | |
| local existing=$(grep "$youtube_url" "$file" | sed 's/alias \([^=]*\)=.*/\1/') | |
| echo "Stream already saved as: $existing" | |
| return 1 | |
| fi | |
| if ! yt-dlp --simulate --no-warnings "$youtube_url" &>/dev/null; then | |
| echo "Stream not found or not live: $youtube_url" | |
| return 1 | |
| fi | |
| echo "alias $alias_name='_play_stream \"$youtube_url\"'" >> "$file" | |
| echo "Added stream alias: $alias_name" | |
| source ~/.config/zsh/youtube-streams.zsh | |
| } | |
| # Remove a saved stream alias | |
| remove_stream() { | |
| if [[ $# -ne 1 ]]; then | |
| echo "Usage: remove_stream <alias_name>" | |
| return 1 | |
| fi | |
| local file=~/.config/zsh/youtube-streams.zsh | |
| if ! grep -q "^alias $1=" "$file"; then | |
| echo "No stream alias '$1' found." | |
| return 1 | |
| fi | |
| sed -i '' "/^alias $1=/d" "$file" | |
| unalias "$1" 2>/dev/null | |
| echo "Removed: $1" | |
| } | |
| # List all available stream aliases | |
| list_streams() { | |
| echo "Available YouTube stream aliases:" | |
| grep "^alias" ~/.config/zsh/youtube-streams.zsh | sed 's/alias / /' | sed "s/=.*//" | |
| } | |
| # Check streams and remove dead ones | |
| check_streams() { | |
| local file=~/.config/zsh/youtube-streams.zsh | |
| local dead=() | |
| echo "Checking streams..." | |
| grep "^alias" "$file" | while IFS= read -r line; do | |
| local name=$(echo "$line" | sed "s/alias \([^=]*\)=.*/\1/") | |
| local url=$(echo "$line" | grep -o 'https://www.youtube.com/watch?v=[^"]*') | |
| if [[ -n "$url" ]] && ! yt-dlp --simulate --no-warnings "$url" &>/dev/null; then | |
| dead+=("$name") | |
| echo " ✗ $name ($url)" | |
| sed -i '' "/^alias ${name}=/d" "$file" | |
| else | |
| echo " ✓ $name" | |
| fi | |
| done | |
| if [[ ${#dead[@]} -eq 0 ]]; then | |
| echo "All streams valid." | |
| else | |
| echo "Removed ${#dead[@]} dead stream(s). Re-source with: source $file" | |
| fi | |
| } | |
| # added streams | |
| alias bladerunner='_play_stream "https://www.youtube.com/watch?v=RrkrdYm3HPQ"' | |
| alias darkambient='_play_stream "https://www.youtube.com/watch?v=S_MOd40zlYU"' | |
| alias asian='_play_stream "https://www.youtube.com/watch?v=Na0w3Mz46GA"' | |
| alias anjunadeep='_play_stream "https://www.youtube.com/watch?v=D4MdHQOILdw"' | |
| alias deephouse2='_play_stream "https://www.youtube.com/watch?v=-k_LwBgZQQ0"' | |
| alias trance='_play_stream "https://www.youtube.com/watch?v=IvuwTft-0cM"' | |
| alias ibiza='_play_stream "https://www.youtube.com/watch?v=spbdBNDqrzA"' | |
| alias deepmood='_play_stream "https://www.youtube.com/watch?v=Cf0GbE7s-Qw"' | |
| # Completions | |
| _stream_aliases() { compadd $(grep "^alias" ~/.config/zsh/youtube-streams.zsh | sed 's/alias \([^=]*\)=.*/\1/') } | |
| compdef _stream_aliases remove_stream |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
YouTube Stream Aliases for Zsh
Background music streams via IINA in music mode. One command, one instance.
Requirements
Install
Usage
Switching streams automatically kills the previous one. Only one IINA instance runs at a time.
How it works
yt-dlpresolves the YouTube live stream URL (lowest quality since we only need audio)add_streamvalidates alias names (lowercase/numbers/underscores) and confirms the stream is live before savingcheck_streamsusesyt-dlp --simulateto verify each URL is still live