1 Νοεμβρίου 2025 / Lefteris Iliadis (SomniusX)
Bash | playyt: Εναλλακτική του yeetube για το terminal
1 Νοεμβρίου 2025
Έχεις ακούσει για το yeetube του thanosapollo; Είναι ένα Emacs package που σου επιτρέπει να αναπαράγεις YouTube βίντεο με mpv και yt-dlp απευθείας από το Emacs. Το πρόβλημα είναι ό
playyt: Το yeetube για το terminal (χωρίς Emacs)
Έχεις ακούσει για το yeetube του thanosapollo; Είναι ένα Emacs package που σου επιτρέπει να αναπαράγεις YouTube βίντεο με mpv και yt-dlp απευθείας από το Emacs. Το πρόβλημα είναι ότι αν δεν χρησιμοποιείς Emacs, δεν μπορείς να το χρησιμοποιήσεις.
Επειδή ήθελα να έχω την ίδια λειτουργικότητα χωρίς να χρειάζεται Emacs, έφτιαξα ένα bash script που κάνει ακριβώς αυτό που κάνει το yeetube, αλλά απευθείας από το terminal. Το λέω playyt.
edit: 2025-11-01 16:30 προσθήκη ascii video player και αλλαγή του άρθρου..
Τι κάνει
Το playyt είναι ένα bash script που παίρνει ένα YouTube URL (ή οποιοδήποτε URL που υποστηρίζει το yt-dlp) και το αναπαράγει με mpv ή ffplay. Ίδια λειτουργικότητα με το yeetube, αλλά χωρίς Emacs. Απλά τρέχεις μια εντολή στο terminal και παίζει το βίντεο.
Η βασική ιδέα είναι να μην χρειάζεται να ανοίγεις browser για να δεις YouTube βίντεο. Μπορείς να δώσεις ένα URL στο terminal και να παίξει απευθείας, ή ακόμα και να κάνεις αναζήτηση και να παίξεις το πρώτο αποτέλεσμα.
Πως λειτουργεί
Η βασική χρήση είναι απλούστατη:
playyt "https://www.youtube.com/watch?v=XXXX"
Αν θες να χρησιμοποιήσεις ffplay αντί για mpv:
playyt "https://www.youtube.com/watch?v=XXXX" ffplay
Αν δεν θες να ανοίξεις browser για να βρεις το URL, μπορείς να κάνεις αναζήτηση απευθείας:
playyt --search "linux tutorial"
Το script θα βρει το πρώτο αποτέλεσμα και θα το παίξει αυτόματα.
ASCII Video Mode
Ένα από τα πιο ενδιαφέρον features είναι η δυνατότητα να δεις τα βίντεο ως ASCII art απευθείας στο terminal. Αυτό είναι χρήσιμο αν θέλεις να μην ανοίγεις κανένα window ή αν απλά θες να δεις πως φαίνεται.
playyt "https://www.youtube.com/watch?v=XXXX" ascii
Το script θα ψάξει αυτόματα για διαθέσιμο ASCII player. Υποστηρίζει:
- mplayer με caca support (συνήθως το πιο διαθέσιμο)
- mpv με caca support
- vtap (Python-based, εύκολο να το βάλεις με pip install vtap)
- tplay (Rust-based)
Αν δεν βρει κάποιο, θα σου δώσει ακριβείς οδηγίες πως να το εγκαταστήσεις. Το vtap είναι συνήθως η πιο εύκολη επιλογή αν δεν έχεις ήδη mplayer:
pip install --user vtap
Μετά μπορείς να το χρησιμοποιήσεις κανονικά. Το ASCII mode λειτουργεί και με search:
playyt --search "linux tutorial" ascii
Εγκατάσταση
Το script υποστηρίζει όλες τις κύριες Linux διανομές. Αρκεί να το κάνεις executable:
chmod +x playyt
Θα χρειαστείς mpv (ή ffplay) και yt-dlp. Το καλό με το playyt είναι ότι κάνει αυτόματα check αν έχεις τα dependencies και αν κάτι λείπει, σου δίνει ακριβείς οδηγίες εγκατάστασης ανάλογα με τη διανομή σου. Υποστηρίζει Arch, Fedora/Nobara, Debian/Ubuntu, openSUSE, Gentoo, Alpine, Void, Solus, NixOS, RHEL/CentOS και άλλες.
Για Fedora/Nobara για παράδειγμα:
python3 -m pip install --user -U yt-dlp
sudo dnf install mpv ffmpeg
Αλλά το script θα σου πει ακριβώς τι να κάνεις αν λείπει κάτι, οπότε δεν χρειάζεται να θυμάσαι τις εντολές.
Χρήση σε άλλα scripts και GUI
Επειδή είναι απλό bash script, μπορείς να το ενσωματώσεις παντού. Αν έχεις ένα GUI script που θέλει να παίξει YouTube βίντεο, μπορείς να καλέσεις το playyt:
playyt "$youtube_url" &
Ή αν θες να δημιουργήσεις ένα custom launcher που παίρνει URLs από το clipboard:
#!/bin/bash
url=$(xclip -o)
playyt "$url"
Αυτό είναι ιδιαίτερα χρήσιμο αν δεν θέλεις να ανοίγεις browser tabs για YouTube. Μπορείς να έχεις ένα keyboard shortcut ή ένα GUI button που καλεί το playyt και παίζει το βίντεο απευθείας.
Είναι αρκετά ευέλικτο γιατί απλά παίρνει ένα URL και το τρέχει. Δεν έχει dependencies σε Emacs, browser extensions, ή τίποτα άλλο.
Γιατί playyt αντί για yeetube
Το yeetube είναι ωραίο αν ήδη χρησιμοποιείς Emacs. Αλλά αν δεν χρησιμοποιείς Emacs, δεν μπορείς να το χρησιμοποιήσεις. Το playyt δίνει την ίδια λειτουργικότητα σε όσους δεν θέλουν ή δεν χρησιμοποιούν Emacs:
- Δεν χρειάζεται Emacs. Απλά bash script που τρέχει σε οποιοδήποτε terminal.
- Λειτουργεί σε όλες τις διανομές. Το script έχει built-in detection για όλες τις κύριες Linux διανομές και σου λέει πως να εγκαταστήσεις dependencies.
- Εύκολη ενσωμάτωση. Μπορείς να το χρησιμοποιήσεις σε οποιοδήποτε script, GUI application, ή keyboard shortcut.
- Lightweight. Είναι ένα bash script, όχι full package ecosystem.
Η βασική ιδέα είναι να έχεις την ίδια λειτουργικότητα με το yeetube, αλλά για όλες τις διανομές και χωρίς Emacs dependency.
Τεχνικές λεπτομέρειες
Το script έχει ένα σημαντικό πλεονέκτημα: χρησιμοποιεί πολλαπλά fallback mechanisms για να βεβαιωθεί ότι θα λειτουργήσει. Πρώτα προσπαθεί να χρησιμοποιήσει το mpv απευθείας με το URL (που συχνά “απλά δουλεύει” αν το mpv έχει ytdl support). Αν αυτό αποτύχει, δοκιμάζει με explicit ytdl format. Αν και αυτό αποτύχει, παίρνει το direct media URL μέσω yt-dlp και το τρέχει στο mpv.
Αυτό σημαίνει ότι λειτουργεί ακόμα και αν το mpv δεν έχει compiled-in ytdl support, αρκεί να έχεις το yt-dlp στο PATH.
Το ίδιο ισχύει και για το ASCII mode. Το script ελέγχει αυτόματα ποια ASCII players είναι διαθέσιμα και χρησιμοποιεί αυτό που βρίσκει. Αν δεν βρει τίποτα, σου λέει ακριβώς τι να εγκαταστήσεις για τη διανομή σου.
Συμπέρασμα
Το playyt είναι η λύση για όσους θέλουν την ίδια λειτουργικότητα με το yeetube, αλλά χωρίς Emacs. Είναι ένα bash script που λειτουργεί σε όλες τις Linux διανομές, με αυτόματες οδηγίες εγκατάστασης dependencies, και με τη δυνατότητα ενσωμάτωσης σε άλλα scripts ή GUI applications.
Αν ήδη χρησιμοποιείς Emacs και σου αρέσει το yeetube, μείνε εκεί. Αλλά αν θέλεις να μην ανοίγεις browser tabs για YouTube και δεν χρησιμοποιείς Emacs, το playyt είναι η λύση. Απλά δίνεις ένα URL στο terminal και παίζει το βίντεο με mpv. Αν θες κάτι πιο retro, μπορείς να το δεις και ως ASCII art απευθείας στο terminal.
Το script είναι διαθέσιμο στο GitHub αλλά το έχω σε private repo, οπότε θα σας το postάρω εδώ…
#!/usr/bin/env bash
# playyt - play a youtube (or other yt-dlp supported) URL using yt-dlp + mpv/ffplay
# Alternative to yeetube (Emacs Lisp package) for terminal/CLI usage
# Usage: playyt <url> [player]
# Example: playyt "https://www.youtube.com/watch?v=..." mpv
# playyt "https://www.youtube.com/watch?v=..." ffplay
# Use set -e but allow fallback logic with || operators
set -u
# Function to check if a command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Function to detect system and package manager
detect_system() {
if [ -f /etc/os-release ]; then
. /etc/os-release
OS=$NAME
else
OS=$(uname -s)
fi
case $OS in
"Arch Linux"|"CachyOS"|"EndeavourOS"|"Manjaro Linux"|"Garuda Linux"|"ArcoLinux"|"Artix Linux")
echo "arch"
;;
"Fedora Linux"|"Fedora"|"Nobara Linux"|"Nobara")
echo "fedora"
;;
"Ubuntu"|"Debian GNU/Linux"|"Linux Mint"|"Pop!_OS"|"Zorin OS"|"elementary OS"|"Kali GNU/Linux"|"Parrot OS")
echo "debian"
;;
"openSUSE"*|"SUSE"*)
echo "opensuse"
;;
"Gentoo")
echo "gentoo"
;;
"Alpine Linux")
echo "alpine"
;;
"Void")
echo "void"
;;
"Solus")
echo "solus"
;;
"Clear Linux"*)
echo "clearlinux"
;;
"NixOS")
echo "nixos"
;;
"Red Hat"*|"CentOS"*|"Rocky Linux"|"AlmaLinux"|"Oracle Linux")
echo "rhel"
;;
*)
echo "unknown"
;;
esac
}
# Function to get installation command for a dependency
get_install_command() {
local dep=$1
local system=$2
case $dep in
yt-dlp)
case $system in
arch)
echo "sudo pacman -S --noconfirm yt-dlp"
;;
fedora|rhel)
echo "sudo dnf install -y yt-dlp"
;;
debian)
echo "sudo apt update && sudo apt install -y yt-dlp"
;;
opensuse)
echo "sudo zypper install -y yt-dlp"
;;
gentoo)
echo "sudo emerge -av net-misc/yt-dlp"
;;
alpine)
echo "sudo apk add yt-dlp"
;;
void)
echo "sudo xbps-install -y yt-dlp"
;;
solus)
echo "sudo eopkg install -y yt-dlp"
;;
clearlinux)
echo "sudo swupd bundle-add media-processing"
;;
nixos)
echo "nix-env -iA nixos.yt-dlp"
;;
*)
echo "pip install --user yt-dlp # or: sudo pip install yt-dlp"
;;
esac
;;
mpv)
case $system in
arch)
echo "sudo pacman -S --noconfirm mpv"
;;
fedora|rhel)
echo "sudo dnf install -y mpv"
;;
debian)
echo "sudo apt update && sudo apt install -y mpv"
;;
opensuse)
echo "sudo zypper install -y mpv"
;;
gentoo)
echo "sudo emerge -av media-video/mpv"
;;
alpine)
echo "sudo apk add mpv"
;;
void)
echo "sudo xbps-install -y mpv"
;;
solus)
echo "sudo eopkg install -y mpv"
;;
clearlinux)
echo "sudo swupd bundle-add media"
;;
nixos)
echo "nix-env -iA nixos.mpv"
;;
*)
echo "Please install mpv using your distribution's package manager"
;;
esac
;;
ffmpeg|ffplay)
case $system in
arch)
echo "sudo pacman -S --noconfirm ffmpeg"
;;
fedora|rhel)
echo "sudo dnf install -y ffmpeg"
;;
debian)
echo "sudo apt update && sudo apt install -y ffmpeg"
;;
opensuse)
echo "sudo zypper install -y ffmpeg"
;;
gentoo)
echo "sudo emerge -av media-video/ffmpeg"
;;
alpine)
echo "sudo apk add ffmpeg"
;;
void)
echo "sudo xbps-install -y ffmpeg"
;;
solus)
echo "sudo eopkg install -y ffmpeg"
;;
clearlinux)
echo "sudo swupd bundle-add media-processing"
;;
nixos)
echo "nix-env -iA nixos.ffmpeg"
;;
*)
echo "Please install ffmpeg using your distribution's package manager"
;;
esac
;;
esac
}
# Function to check dependency and provide helpful error message
check_dependency() {
local dep=$1
local system=$2
if ! command_exists "$dep"; then
echo "ERROR: $dep is not installed." >&2
echo "" >&2
echo "To install $dep, run:" >&2
local install_cmd
install_cmd=$(get_install_command "$dep" "$system")
echo " $install_cmd" >&2
echo "" >&2
# Special note for yt-dlp - pip is universal and often more up-to-date
if [ "$dep" = "yt-dlp" ]; then
if [ "$system" = "fedora" ] || [ "$system" = "rhel" ]; then
echo "" >&2
echo "For Fedora/Nobara, recommended installation via pip:" >&2
echo " python3 -m pip install --user -U yt-dlp" >&2
elif [ "$system" = "unknown" ]; then
echo "" >&2
echo "Alternatively, install via pip (universal):" >&2
echo " python3 -m pip install --user -U yt-dlp" >&2
echo " # or download standalone binary from: https://github.com/yt-dlp/yt-dlp/releases" >&2
fi
fi
return 1
fi
return 0
}
# Function to search YouTube and get first result URL
search_youtube() {
local query="$1"
local count="${2:-1}"
# Use yt-dlp's ytsearch functionality
# We want the webpage URL (like https://www.youtube.com/watch?v=...) so mpv can handle it
local result
local url
local title
# Get both title and URL in one call
result=$(yt-dlp "ytsearch${count}:${query}" --print "%(title)s" --print "%(webpage_url)s" --no-warnings 2>/dev/null | head -n2)
if [ -z "$result" ]; then
echo "ERROR: No results found for: $query" >&2
return 1
fi
# Parse result: first line is title, second is URL
title=$(echo "$result" | head -n1)
url=$(echo "$result" | tail -n1)
if [ -n "$title" ]; then
echo "Found: $title" >&2
fi
if [ -z "$url" ]; then
echo "ERROR: Could not extract URL from search results" >&2
return 1
fi
echo "$url"
}
# Main script
# Handle special flags
SEARCH_MODE=false
SEARCH_COUNT=1
URL=""
PLAYER=""
QUERY=""
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--search|-s)
SEARCH_MODE=true
if [ -z "${2:-}" ] || [[ "$2" == -* ]]; then
echo "ERROR: --search requires a query string" >&2
exit 2
fi
QUERY="$2"
shift 2
;;
--search-count|-n)
if [ -z "${2:-}" ] || [[ "$2" == -* ]]; then
echo "ERROR: --search-count requires a number" >&2
exit 2
fi
SEARCH_COUNT="$2"
shift 2
;;
--help|-h)
echo "Usage: $0 <url> [player: mpv|ffplay|ascii]" >&2
echo " $0 --search \"query\" [player]" >&2
echo "" >&2
echo "Options:" >&2
echo " --search, -s <query> Search YouTube and play first result" >&2
echo " --search-count, -n <n> When searching, get top N results (default: 1)" >&2
echo " --help, -h Show this help message" >&2
echo "" >&2
echo "Players:" >&2
echo " mpv - Default video player (best quality)" >&2
echo " ffplay - Alternative player" >&2
echo " ascii - Play video as ASCII art in terminal" >&2
echo "" >&2
echo "Examples:" >&2
echo " $0 'https://www.youtube.com/watch?v=...' mpv" >&2
echo " $0 'https://www.youtube.com/watch?v=...' ffplay" >&2
echo " $0 'https://www.youtube.com/watch?v=...' ascii" >&2
echo " $0 --search 'linux tutorial' ascii" >&2
echo "" >&2
echo "Notes:" >&2
echo " - For Fedora/Nobara, install yt-dlp via: python3 -m pip install --user -U yt-dlp" >&2
echo " - For ASCII mode, install mplayer with caca support or vtap (pip install vtap)" >&2
echo " - For a full TUI experience with search, consider: ytfzf (https://github.com/pystardust/ytfzf)" >&2
exit 0
;;
*)
# If this looks like a flag, it's an error
if [[ "$1" == -* ]]; then
echo "ERROR: Unknown option: $1" >&2
echo "Use --help for usage information." >&2
exit 2
fi
# First non-flag argument is URL (if not in search mode) or player (if in search mode)
if [ "$SEARCH_MODE" = true ]; then
# In search mode, any remaining argument is the player
if [ -z "$PLAYER" ]; then
PLAYER="$1"
else
echo "WARNING: Ignoring extra argument: $1" >&2
fi
else
# Normal mode: first is URL, second is player
if [ -z "$URL" ]; then
URL="$1"
elif [ -z "$PLAYER" ]; then
PLAYER="$1"
else
echo "WARNING: Ignoring extra argument: $1" >&2
fi
fi
shift
;;
esac
done
# Set default player if not specified
PLAYER="${PLAYER:-mpv}"
# Handle search mode
if [ "$SEARCH_MODE" = true ]; then
if [ -z "$QUERY" ]; then
echo "ERROR: --search requires a query string" >&2
echo "Usage: $0 --search 'your query here' [player]" >&2
exit 2
fi
echo "Searching YouTube for: $QUERY" >&2
URL=$(search_youtube "$QUERY" "$SEARCH_COUNT")
if [ -z "$URL" ]; then
exit 1
fi
fi
if [ -z "$URL" ]; then
echo "Usage: $0 <url> [player: mpv|ffplay|ascii]" >&2
echo " $0 --search \"query\" [player]" >&2
echo "" >&2
echo "Use --help for more options." >&2
exit 2
fi
# Detect system for dependency checks
SYSTEM=$(detect_system)
# Check required dependencies
MISSING_DEPS=()
# Always check for yt-dlp (required)
if ! check_dependency "yt-dlp" "$SYSTEM"; then
MISSING_DEPS+=("yt-dlp")
fi
# Function to check for ASCII player tools
check_ascii_player() {
local system=$1
# Check for vtap first (Python-based, best YouTube support, easy to install)
if command_exists vtap; then
echo "vtap"
return 0
fi
# Check for tplay (Rust-based, good YouTube support)
if command_exists tplay; then
echo "tplay"
return 0
fi
# Check for mplayer with caca support
if command_exists mplayer; then
if mplayer -vo help 2>/dev/null | grep -q caca; then
echo "mplayer"
return 0
fi
fi
# Check for mpv with caca support
if command_exists mpv; then
if mpv --vo=help 2>/dev/null | grep -q caca; then
echo "mpv"
return 0
fi
fi
return 1
}
# Check for player-specific dependencies
case "$PLAYER" in
mpv)
if ! check_dependency "mpv" "$SYSTEM"; then
MISSING_DEPS+=("mpv")
fi
;;
ffplay)
if ! check_dependency "ffmpeg" "$SYSTEM"; then
MISSING_DEPS+=("ffmpeg")
fi
# Also check if ffplay exists (part of ffmpeg package)
if ! command_exists "ffplay"; then
echo "ERROR: ffplay not found (should be part of ffmpeg package)." >&2
MISSING_DEPS+=("ffmpeg")
fi
;;
ascii)
ASCII_PLAYER=$(check_ascii_player "$SYSTEM")
if [ -z "$ASCII_PLAYER" ]; then
echo "ERROR: No ASCII video player found." >&2
echo "" >&2
echo "To use ASCII mode, install one of the following (vtap is recommended for best YouTube support):" >&2
echo "" >&2
echo " 1. vtap (Python-based, RECOMMENDED - best YouTube support):" >&2
echo " pip install --user vtap" >&2
echo " # or: python3 -m pip install --user vtap" >&2
echo "" >&2
echo " 2. tplay (Rust-based, good YouTube support):" >&2
echo " See: https://github.com/maxcurzi/tplay" >&2
echo "" >&2
echo " 3. mplayer with caca support:" >&2
case $SYSTEM in
arch)
echo " sudo pacman -S --noconfirm mplayer" >&2
;;
fedora|rhel)
echo " sudo dnf install -y mplayer" >&2
;;
debian)
echo " sudo apt update && sudo apt install -y mplayer" >&2
;;
*)
echo " Install mplayer package from your distribution" >&2
;;
esac
echo "" >&2
echo "Note: vtap is the easiest to install and has the best YouTube compatibility." >&2
MISSING_DEPS+=("ascii-player")
else
# If using mplayer or mpv (legacy tools), suggest vtap for better experience
if [ "$ASCII_PLAYER" = "mplayer" ] || [ "$ASCII_PLAYER" = "mpv" ]; then
echo "Note: Using $ASCII_PLAYER for ASCII playback." >&2
echo " For better YouTube support, consider installing vtap: pip install --user vtap" >&2
fi
fi
;;
*)
# Custom player - just check if it exists
if ! command_exists "$PLAYER"; then
echo "ERROR: Player '$PLAYER' not found." >&2
exit 1
fi
# Still need yt-dlp for custom players
;;
esac
# Exit if dependencies are missing
if [ ${#MISSING_DEPS[@]} -ne 0 ]; then
echo "" >&2
echo "Please install the missing dependencies and try again." >&2
exit 1
fi
# Play the video
case "$PLAYER" in
mpv)
# mpv has built-in ytdl:// protocol support and can use yt-dlp automatically
# Strategy: Try simplest approach first, then fallback to more explicit methods
if command_exists mpv; then
# First: Try mpv directly (often "just works" if mpv has ytdl support and yt-dlp is in PATH)
# Suppress stderr for first attempt (may show warnings we can ignore if it works)
if mpv "$URL" 2>/dev/null; then
exit 0
fi
# Second: Try with explicit ytdl format (mpv will use yt-dlp if available)
if mpv --ytdl-format=best "$URL" 2>/dev/null; then
exit 0
fi
# Third: Fallback - get direct media URL using yt-dlp and feed to mpv (most portable)
# This method works even if mpv doesn't have ytdl support compiled in
STREAM_URL="$(yt-dlp -f best -g "$URL" 2>/dev/null | head -n1)"
if [ -n "$STREAM_URL" ]; then
mpv "$STREAM_URL"
exit $?
else
echo "ERROR: Could not resolve stream URL with yt-dlp." >&2
echo "Make sure yt-dlp is installed and the URL is valid." >&2
echo "Try running: yt-dlp '$URL' to debug." >&2
exit 1
fi
fi
;;
ffplay)
# stream via stdout into ffplay using ffmpeg (ffplay)
if command_exists ffplay; then
# use yt-dlp to output raw media to stdout, pipe to ffplay
yt-dlp -f best -o - "$URL" 2>/dev/null | ffplay -autoexit -nodisp -i -
exit $?
fi
;;
ascii)
# ASCII video playback in terminal
ASCII_PLAYER=$(check_ascii_player "$SYSTEM")
if [ -z "$ASCII_PLAYER" ]; then
echo "ERROR: No ASCII player found." >&2
exit 1
fi
case "$ASCII_PLAYER" in
mplayer)
# mplayer with caca output
# mplayer doesn't handle HLS well, so try to get non-HLS format first
echo "Getting stream URL with yt-dlp..." >&2
STREAM_URL="$(yt-dlp -f 'best[ext=mp4][protocol!=m3u8]/best[ext=webm][protocol!=m3u8]/best[protocol!=m3u8]' -g "$URL" 2>/dev/null | head -n1)"
if [ -z "$STREAM_URL" ]; then
# Fallback: try best non-HLS format
STREAM_URL="$(yt-dlp -f 'best[protocol!=m3u8]' -g "$URL" 2>/dev/null | head -n1)"
fi
# Check if we got HLS anyway
if echo "$STREAM_URL" | grep -q '\.m3u8\|manifest\|/hls_'; then
echo "WARNING: Got HLS stream which mplayer doesn't handle well." >&2
echo "Try using mpv instead or install vtap for better YouTube support." >&2
# Still try it but with warning
fi
if [ -n "$STREAM_URL" ]; then
# Use -really-quiet, -nolirc, -nomouseinput to avoid conflicts
# -framedrop helps with performance
# -cache 8192 for better buffering
timeout 30 mplayer -really-quiet -vo caca -nolirc -nomouseinput -noconfig all -framedrop -cache 8192 "$STREAM_URL" 2>/dev/null
EXIT_CODE=$?
if [ $EXIT_CODE -eq 124 ]; then
echo "mplayer timed out or had issues. The stream format may not be compatible." >&2
fi
exit $EXIT_CODE
else
echo "ERROR: Could not extract compatible stream URL for mplayer." >&2
echo "YouTube may only provide HLS streams for this video." >&2
exit 1
fi
;;
mpv)
# mpv with caca output
# mpv handles HLS better, but still try non-HLS first for better compatibility
STREAM_URL="$(yt-dlp -f 'best[protocol!=m3u8]/best' -g "$URL" 2>/dev/null | head -n1)"
if [ -n "$STREAM_URL" ]; then
mpv --quiet --vo=caca "$STREAM_URL" 2>/dev/null
exit $?
else
mpv --quiet --vo=caca "$URL" 2>/dev/null
exit $?
fi
;;
vtap)
# vtap supports YouTube URLs but needs -u flag
# vtap uses pytube which sometimes has API issues, so try it first but fallback if it fails
echo "Attempting to play with vtap..." >&2
# Try vtap, suppress verbose traceback output (we know it has pytube issues)
if ! vtap -u "$URL" 2>/dev/null; then
VTAP_ERROR=$?
# vtap failed, try fallback
echo "" >&2
echo "WARNING: vtap failed (pytube library may have YouTube API issues)." >&2
echo "Falling back to alternative ASCII player..." >&2
echo "" >&2
# Download video to temp file first (most reliable for ASCII playback)
echo "Downloading video temporarily for ASCII playback..." >&2
TEMP_DIR=$(mktemp -d)
TEMP_FILE="$TEMP_DIR/video.%(ext)s"
trap "rm -rf '$TEMP_DIR'" EXIT
# Download video (limit to 720p for faster download, ASCII doesn't need high quality)
yt-dlp -f 'best[height<=720]' -o "$TEMP_FILE" "$URL" --no-warnings 2>&1
# Find downloaded file (yt-dlp adds extension automatically)
DOWNLOADED_FILE=$(find "$TEMP_DIR" -type f -size +100k 2>/dev/null | head -n1)
if [ -n "$DOWNLOADED_FILE" ] && [ -s "$DOWNLOADED_FILE" ]; then
echo "Download successful. Playing with ASCII player..." >&2
# Prefer mpv, fallback to mplayer
if command_exists mpv && mpv --vo=help 2>/dev/null | grep -q caca; then
mpv --quiet --vo=caca --framedrop=decoder "$DOWNLOADED_FILE" 2>/dev/null
EXIT_CODE=$?
rm -rf "$TEMP_DIR"
exit $EXIT_CODE
elif command_exists mplayer && mplayer -vo help 2>/dev/null | grep -q caca; then
mplayer -really-quiet -vo caca -nolirc -nomouseinput -noconfig all -framedrop "$DOWNLOADED_FILE" 2>/dev/null
EXIT_CODE=$?
rm -rf "$TEMP_DIR"
exit $EXIT_CODE
else
rm -rf "$TEMP_DIR"
echo "ERROR: No ASCII player found." >&2
exit 1
fi
else
echo "Download failed or incomplete. File not found or too small." >&2
rm -rf "$TEMP_DIR"
fi
# Final fallback: try mpv with stream (it handles HLS better)
if command_exists mpv && mpv --vo=help 2>/dev/null | grep -q caca; then
echo "Attempting direct stream with mpv as last resort..." >&2
STREAM_URL="$(yt-dlp -f 'best[height<=480]' -g "$URL" 2>/dev/null | head -n1)"
if [ -n "$STREAM_URL" ]; then
mpv --quiet --vo=caca --framedrop=decoder "$STREAM_URL" 2>/dev/null
exit $?
fi
fi
echo "ERROR: All ASCII players failed." >&2
echo "vtap has YouTube API issues (pytube library). Try updating: pip install --upgrade --user vtap" >&2
exit $VTAP_ERROR
fi
exit 0
;;
tplay)
# tplay supports YouTube URLs directly
tplay "$URL"
exit $?
;;
*)
echo "ERROR: Unknown ASCII player: $ASCII_PLAYER" >&2
exit 1
;;
esac
;;
*)
# custom player passed by user
if command_exists "$PLAYER"; then
STREAM_URL="$(yt-dlp -f best -g "$URL" 2>/dev/null | head -n1)"
if [ -n "$STREAM_URL" ]; then
"$PLAYER" "$STREAM_URL"
exit $?
else
echo "ERROR: Could not resolve stream URL." >&2
exit 1
fi
fi
;;
esac
echo "ERROR: No suitable player found (mpv/ffplay)." >&2
exit 1
έγινε edit πάλι 2025-11-01 @ 16:45 γιατί ήθελα καλύτερο fallback αν δε μπορεί με ascii σωστά να το δείξει, το κάνει λήψη και αναπαραγωγή, παραθέτω και το αποτέλεσμα..
