Skip to content

Instantly share code, notes, and snippets.

@GoesuZuegs
Last active November 18, 2018 09:53
Show Gist options
  • Save GoesuZuegs/45c8da1e8f14c2187cb59e827ae1bf2e to your computer and use it in GitHub Desktop.
Save GoesuZuegs/45c8da1e8f14c2187cb59e827ae1bf2e to your computer and use it in GitHub Desktop.
YouTube in the terminal
#!/bin/sh
if [ $EUID -ne 0 ]
then
echo "This script must be run as root!"
exit 1
fi
INSTALL_DIR=/opt/ytgo/
mkdir -p $INSTALL_DIR
cd $INSTALL_DIR
curl -L https://gist.github.com/GoesuZuegs/45c8da1e8f14c2187cb59e827ae1bf2e/raw/ytgo.sh > ytgo
chmod +x ytgo
if ! [[ "$PATH" =~ (^|:)"${INSTALL_DIR}"(:|$) ]]
then
echo -e "\n" >> /etc/profile
echo $"export PATH=\$PATH:${INSTALL_DIR}" >> /etc/profile
source /etc/profile
fi
# yay -Syu html-xml-utils
echo "The script was sucessfully installed!"
#!/bin/sh
# YouTube in the terminal
VIDEOS_FOLDER=~/Videos/
MUSIC_FOLDER=~/Music/
youtube_audio () {
if [ -z "$1" ]
then
exit 1
fi
tmpdir=$( mktemp -d )
youtube-dl --no-check-certificate --no-playlist --format bestaudio --extract-audio --audio-format mp3 --o "$tmpdir/%(title)s.%(id)s.%(ext)s" "$1"
( cd "$tmpdir" && find . -name \*.mp3 -exec mv "{}" "$MUSIC_FOLDER" \; )
rm -rf "$tmpdir"
echo -e "\n"
}
if [ "$1" = audio ]
then
youtube_audio "$2"
fi
youtube_video () {
if [ -z "$1" ]
then
exit 1
fi
tmpdir=$( mktemp -d )
youtube-dl --no-check-certificate --no-playlist --recode-video mkv --o "$tmpdir/%(title)s.%(id)s.%(ext)s" "$1"
( cd "$tmpdir" && find . -name \*.mkv -exec mv "{}" "$VIDEOS_FOLDER" \; )
rm -rf "$tmpdir"
echo -e "\n"
}
if [ "$1" = video ]
then
youtube_video "$2"
fi
youtube_playlist () {
if [ -z "$2" ]
then
echo -e "No URL given!\n"
exit 1
fi
if [ -n "$1" ]
then
mode="$1"
else
read -rp "Mode [v = video | a = audio]: " -n 1 mode
fi
if [ "$mode" = v ]
then
tmpdir=$( mktemp -d )
youtube-dl --no-check-certificate --yes-playlist --recode-video mkv --o "$tmpdir/%(playlist_title)s %(playlist_id)s/%(playlist_index)s %(title)s.%(id)s.%(ext)s" "$2"
( cd "$tmpdir" && find . -name \*.mkv -exec mv "{}" "$VIDEOS_FOLDER" \; )
rm -rf "$tmpdir"
elif [ "$mode" = a ]
then
tmpdir=$( mktemp -d )
youtube-dl --no-check-certificate --yes-playlist --format bestaudio --extract-audio --audio-format mp3 --o "$tmpdir/%(playlist_title)s %(playlist_id)s/%(playlist_index)s %(title)s.%(id)s.%(ext)s" "$2"
( cd "$tmpdir" && find . -name \*.mp3 -exec mv "{}" "$MUSIC_FOLDER" \; )
rm -rf "$tmpdir"
else
echo -e "Invalid mode!\n"
exit 1
fi
echo -e "\n"
exit 0
}
if [ "$1" = playlist ]
then
youtube_playlist "$2"
fi
youtube_search_handle_result () {
kind="$1"
if [ -z "$kind" ]
then
echo -e "No kind given!\n"
exit 1
fi
url="$2"
if [ -z "$url" ]
then
echo -e "No URL given!\n"
exit 1
fi
if [ "$kind" = video ]
then
read -rp "Mode [a = audio | s = stream | v = video | b = both | f = firefox]: " -n 1 mode
echo -e "\n"
if [ "$mode" = a ]
then
youtube_audio "$url"
read -rp "Play now? (y/n) " -n 1 play_now
echo -e "\n"
if [ "$play_now" = y ]
then
audio_file=$( find $MUSIC_FOLDER -name *.$3.mp3 -print -quit )
mpv "$audio_file"
exit 0
fi
elif [ "$mode" = s ]
then
mpv "$url"
elif [ "$mode" = v ]
then
youtube_video "$url"
read -rp "Play now? (y/n) " -n 1 play_now
echo -e "\n"
if [ "$play_now" = y ]
then
video_file=$( find $VIDEOS_FOLDER -name *.$3.mkv -print -quit )
mpv "$video_file"
exit 0
fi
elif [ "$mode" = b ]
then
youtube_audio "$url"
youtube_video "$url"
elif [ "$mode" = f ]
then
(firefox "$url" &)
else
echo -e "Invalid mode!\n"
exit 1
fi
elif [ "$kind" = playlist ]
then
read -rp "Mode [f = firefox | v = video | a = audio]: " -n 1 mode
echo -e "\n"
if [ "$mode" = f ]
then
(firefox "$url" &)
elif [ "$mode" = v ]
then
youtube_playlist v "$url"
elif [ "$mode" = a ]
then
youtube_playlist a "$url"
else
echo -e "Invalid mode!\n"
exit 1
fi
elif [ "$kind" = channel ]
then
read -rp "Mode [f = firefox]: " -n 1 mode
echo -e "\n"
if [ "$mode" = f ]
then
(firefox "$url" &)
else
echo -e "Invalid mode!\n"
exit 1
fi
else
echo -e "Invalid kind!\n"
exit 1
fi
exit 0
}
# https://www.w3.org/Tools/HTML-XML-utils/
youtube_search () {
echo -e "\nSearching on YouTube...\n"
page=$( curl -s -G \
--data-urlencode "search_query=$1" \
"https://www.youtube.com/results" \
)
tmpfile=$( mktemp )
echo "$page" > "$tmpfile"
normalized=$( hxnormalize -l 64 -x "$tmpfile" )
rm "$tmpfile"
num_results=$( echo "$normalized" | hxselect -c ".num-results" )
echo -e "There are ${num_results,,}\n"
tmpfile=$( mktemp )
echo "$normalized" | hxselect \
"#results ol.item-section > li > .yt-lockup" \
> "$tmpfile"
items=$( hxnormalize -x "$tmpfile" )
rm "$tmpfile"
declare -a kinds
declare -a urls
declare -a ids
for c in `seq 1 5`;
do
tmpfile=$( mktemp )
echo "$items" | hxselect "body > :nth-child($c)" > "$tmpfile"
item=$( hxnormalize -l 256 -x "$tmpfile" )
rm "$tmpfile"
kind=""
classes=$( echo "$item" | hxselect -c "body > div::attr(class)" )
if [[ "$classes" = *"yt-lockup-video"* ]]
then
kind="video"
elif [[ "$classes" = *"yt-lockup-playlist"* ]]
then
kind="playlist"
elif [[ "$classes" = *"yt-lockup-channel"* ]]
then
kind="channel"
fi
if [ -z "$kind" ]
then
continue
fi
kinds[$c]="$kind"
urls[$c]=$( echo "$item" | hxselect -c ".yt-lockup-title a::attr(href)" )
title=$( echo "$item" | hxselect -c ".yt-lockup-title a::attr(title)" )
title=${title//[^[:ascii:]]/}
title=$( echo "$title" | recode html..utf-8 )
if [ "$kind" = "video" ] || [ "$kind" = "playlist" ]
then
by=$( echo "$item" | hxselect -c ".yt-lockup-byline a" )
verified=$( echo "$item" | hxselect -c ".yt-lockup-byline span::attr(title)" )
elif [ "$kind" = "channel" ]
then
verified=$( echo "$item" | hxselect -c ".yt-lockup-title > a > span::attr(title)" )
fi
if [ "$verified" = "Verified" ]
then
verified=" \e[95m[V]\e[0m"
else
verified=""
fi
if [ "$kind" = "video" ]
then
ids[$c]=$( echo "$item" | hxselect -c ".yt-lockup-video::attr(data-context-item-id)" )
when=$( echo "$item" | hxselect -c ".yt-lockup-meta-info > :first-child" )
when=${when,,}
num_views=$( echo "$item" | hxselect -c ".yt-lockup-meta-info > :last-child" )
num_views="${num_views% views}"
duration=$( echo "$item" | hxselect -c ".video-time" )
echo -e "\e[4m$c.\e[0m \e[93m${title}\e[0m\n Video by \e[96m${by}\e[0m${verified} ${when} \e[96m${num_views}\e[0m views ${duration}"
elif [ "$kind" = "playlist" ]
then
ids[$c]=$( echo "$item" | hxselect -c "li[data-action=play-now]::attr(data-list-id)" )
by=$( echo "$item" | hxselect -c ".yt-lockup-byline a" )
if [ -z "$by" ]
then
by="YouTube"
fi
num_videos=$( echo "$item" | hxselect -c ".formatted-video-count-label > b" )
echo -e "\e[4m$c.\e[0m \e[93m${title}\e[0m\n Playlist by \e[96m${by}\e[0m${verified} with \e[96m${num_videos}\e[0m videos"
elif [ "$kind" = "channel" ]
then
ids[$c]=$( echo "$item" | hxselect -c "button[data-channel-external-id]::attr(data-channel-external-id)" )
num_videos=$( echo "$item" | hxselect -c ".yt-lockup-meta-info > :first-child" )
num_videos="${num_videos% videos}"
num_subscribers=$( echo "$item" | hxselect -c ".yt-subscriber-count::attr(title)" )
echo -e "\e[4m$c.\e[0m \e[93m${title}\e[0m\n Channel${verified} with \e[96m${num_videos}\e[0m videos and \e[96m${num_subscribers}\e[0m subscribers"
fi
echo -e "\n"
done
read -rp "Choose [1 - 5]: " -n 1 choice
echo -e "\n"
if [ -n "$choice" ] && [ $choice -gt 0 ] && [ $choice -lt 6 ]
then
if [ -n "${ids[$choice]}" ]
then
if [ "${kinds[$choice]}" = video ]
then
url="https://www.youtube.com/watch?v=${ids[$choice]}"
elif [ "${kinds[$choice]}" = playlist ]
then
url="https://www.youtube.com/playlist?list=${ids[$choice]}"
elif [ "${kinds[$choice]}" = channel ]
then
url="https://www.youtube.com/channel/${ids[$choice]}/"
fi
else
url="https://www.youtube.com${urls[$choice]}"
fi
echo -e "${kinds[$choice]^}: ${ids[$choice]}\n\n${url}\n"
youtube_search_handle_result "${kinds[$choice]}" "$url" "${ids[$choice]}"
fi
unset urls
}
if [ "$1" = search ] || [ "$1" = s ]
then
if [ -n "$2" ]
then
youtube_search "$2"
else
read -erp "Query: " -n 64 query
youtube_search "$query"
fi
fi
if [ $# -eq 0 ] || [ "$1" = help ] ; then
echo "Usage:"
echo "s | search = Seach youtube"
echo "video [URL] = Download video"
echo "audio [URL] = Download audio"
echo "playlist [URL] = Download playlist"
echo "You need 'html-xml-utils', 'youtube-dl', 'recode' and 'mpv' from the AUR for this to work."
echo "Install with: yay -Syu html-xml-utils youtube-dl recode mpv"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment