#!/bin/sh ## Do things with a YouTube URL. ## Config: TERMINAL=alacritty DOWNLOAD_DIR=~/videos/youtube PAGER="rofi -location 2 -width 41 -e" YOUTUBE_REGEX=".*((https?\:\/\/)?(www\.)?(youtube\.com|youtu\.?be)\/.+)$" ## Exit codes NO_YOUTUBE_URL=3 NO_ACTION=4 ## Get action for a single URL get_action_single() { action=$(dmenu -p "yt-player" << EOF 1. watch in player 2. listen in player 3. download video 4. download audio 5. print info EOF ) echo "$action" | cut -d'.' -f1 } ## Get action for multiple URLs get_action_multi() { # TODO: implement } ## Check if url is a youtube url check_if_youtube() { url="$1" echo $url | grep -qE "$YOUTUBE_REGEX" && return 0 || return 1 } ## Prompts user for URL prompt_url() { dmenu -p "YouTube URL" } ## Grab url from clipboard/primary selection, else get via prompt grab_url() { if url=$(xclip -o -selection clipboard 2>/dev/null || echo) && check_if_youtube $url; then elif url=$(xclip -o 2>/dev/null || echo) && check_if_youtube $url; then elif url=$(grab_url_stdin) && check_if_youtube $url; then elif url=$(prompt_url) && check_if_youtube $url; then else exit $NO_YOUTUBE_URL fi echo $url } ## Extract URL from stdin grab_url_stdin() { sed -nE "s/$YOUTUBE_REGEX/\1/p" } ## Get title, description, and duration of URL get_info() { url="$1" info=$(youtube-dl --get-title --get-description --get-duration $url) title=$(echo "$info" | head -n 1) description=$(echo "$info" | sed '1d;$d') duration=$(echo "$info" | tail -n 1) printf "(%s) %s\n\n%s" "$duration" "$title" "$description" } ## Download video download_video() { url="$1" info=$(get_info $url) notify-send "Downloading video..." "$info" & youtube-dl \ -q \ --add-metadata \ -o "$DOWNLOAD_DIR/%(title)s_%(id)s.%(ext)s" \ $url && notify-send "Video download done." "$info" & } ## Download audio download_audio() { url="$1" info=$(get_info $url) notify-send "Downloading audio..." "$info" youtube-dl \ -q \ --add-metadata \ -o "$DOWNLOAD_DIR/%(title)s_%(id)s.%(ext)s" \ -x \ --audio-format flac \ --audio-quality 0 \ $url && notify-send "Audio download done." "$info" & } ## Play video play_video() { url="$1" notify-send "Playing video..." "$(get_info $url)" & mpv --no-terminal --geometry=25%-10-40 --title="Streaming from YouTube" $url & } ## Play audio play_audio() { url="$1" notify-send "Playing audio..." "$(get_info $url)" & $TERMINAL -t "Streaming from YouTube" -e mpv --no-video $url & } ## Print info with specified pager print_info() { url="$1" info=$(get_info $url) $PAGER "$info" } ## Main mkdir -p "$DOWNLOAD_DIR" url=$(grab_url) case "$(get_action_single)" in 5) print_info $url ;; 1) play_video $url ;; 2) play_audio $url ;; 3) download_video $url ;; 4) download_audio $url ;; *) exit $NO_ACTION esac