CLI utility to search and view/download YouTube videos












0















Is there a utility that can search YouTube from the command line, and then either view or download the search results according to user input?



$ youtube-search madonna

1 Madonna - Hung Up (Official Music Video)
madonna ♩ 180M views 9 years ago
https://www.youtube.com/watch?v=EDwb9jOVRtU
"Hung Up" by Madonna from Confessions On A Dance Floor, available now.

2 Madonna - Like A Prayer (Official Music Video)
madonna ♩ 69M views 9 years ago
https://www.youtube.com/watch?v=79fzeNUqQbQ
2006 WMG Like A Prayer.

etc.


And then you can enter:




  • "v1" to view video 1 (with VLC, etc.)

  • "d1-3" to download videos 1-3 (with youtube-dl, etc.)

  • "n" to view next page of search results


What I tried so far:



googler works partially with YouTube, but for some reason only shows two search results when searching for "Madonna". Also there is not the choice between view and download.



youtube-dl has a search function, but doesn't seem to print the search results nor accept user input. youtube-dl -j ytsearch:madonna lists metadata about search results, but doesn't seem to contain the video link, title and description that would be desired.










share|improve this question























  • Take a look at github.com/mps-youtube/mps-youtube. You can do all three things you mentioned with it.

    – ritiek
    Jan 23 at 15:22











  • @ritiek: I heard about it, but refrained from installing it due to the insane number of dependencies: libpng, frei0r, glib, pixman, cairo, graphite2, icu4c, harfbuzz, libvpx, opencore-amr, opus, sdl2, snappy, theora, x264, x265, ffmpeg, libtiff, little-cms2, lua@5.1, mujs, openjpeg, webp, leptonica, tesseract, zimg, vapoursynth and mpv. Maybe it's a great utility, but seems like way overkill for my needs.

    – forthrin
    Jan 23 at 20:15













  • So... the answer to your question is, "yes", but your response is, "I don't want to install that."

    – roaima
    Jan 23 at 21:16
















0















Is there a utility that can search YouTube from the command line, and then either view or download the search results according to user input?



$ youtube-search madonna

1 Madonna - Hung Up (Official Music Video)
madonna ♩ 180M views 9 years ago
https://www.youtube.com/watch?v=EDwb9jOVRtU
"Hung Up" by Madonna from Confessions On A Dance Floor, available now.

2 Madonna - Like A Prayer (Official Music Video)
madonna ♩ 69M views 9 years ago
https://www.youtube.com/watch?v=79fzeNUqQbQ
2006 WMG Like A Prayer.

etc.


And then you can enter:




  • "v1" to view video 1 (with VLC, etc.)

  • "d1-3" to download videos 1-3 (with youtube-dl, etc.)

  • "n" to view next page of search results


What I tried so far:



googler works partially with YouTube, but for some reason only shows two search results when searching for "Madonna". Also there is not the choice between view and download.



youtube-dl has a search function, but doesn't seem to print the search results nor accept user input. youtube-dl -j ytsearch:madonna lists metadata about search results, but doesn't seem to contain the video link, title and description that would be desired.










share|improve this question























  • Take a look at github.com/mps-youtube/mps-youtube. You can do all three things you mentioned with it.

    – ritiek
    Jan 23 at 15:22











  • @ritiek: I heard about it, but refrained from installing it due to the insane number of dependencies: libpng, frei0r, glib, pixman, cairo, graphite2, icu4c, harfbuzz, libvpx, opencore-amr, opus, sdl2, snappy, theora, x264, x265, ffmpeg, libtiff, little-cms2, lua@5.1, mujs, openjpeg, webp, leptonica, tesseract, zimg, vapoursynth and mpv. Maybe it's a great utility, but seems like way overkill for my needs.

    – forthrin
    Jan 23 at 20:15













  • So... the answer to your question is, "yes", but your response is, "I don't want to install that."

    – roaima
    Jan 23 at 21:16














0












0








0








Is there a utility that can search YouTube from the command line, and then either view or download the search results according to user input?



$ youtube-search madonna

1 Madonna - Hung Up (Official Music Video)
madonna ♩ 180M views 9 years ago
https://www.youtube.com/watch?v=EDwb9jOVRtU
"Hung Up" by Madonna from Confessions On A Dance Floor, available now.

2 Madonna - Like A Prayer (Official Music Video)
madonna ♩ 69M views 9 years ago
https://www.youtube.com/watch?v=79fzeNUqQbQ
2006 WMG Like A Prayer.

etc.


And then you can enter:




  • "v1" to view video 1 (with VLC, etc.)

  • "d1-3" to download videos 1-3 (with youtube-dl, etc.)

  • "n" to view next page of search results


What I tried so far:



googler works partially with YouTube, but for some reason only shows two search results when searching for "Madonna". Also there is not the choice between view and download.



youtube-dl has a search function, but doesn't seem to print the search results nor accept user input. youtube-dl -j ytsearch:madonna lists metadata about search results, but doesn't seem to contain the video link, title and description that would be desired.










share|improve this question














Is there a utility that can search YouTube from the command line, and then either view or download the search results according to user input?



$ youtube-search madonna

1 Madonna - Hung Up (Official Music Video)
madonna ♩ 180M views 9 years ago
https://www.youtube.com/watch?v=EDwb9jOVRtU
"Hung Up" by Madonna from Confessions On A Dance Floor, available now.

2 Madonna - Like A Prayer (Official Music Video)
madonna ♩ 69M views 9 years ago
https://www.youtube.com/watch?v=79fzeNUqQbQ
2006 WMG Like A Prayer.

etc.


And then you can enter:




  • "v1" to view video 1 (with VLC, etc.)

  • "d1-3" to download videos 1-3 (with youtube-dl, etc.)

  • "n" to view next page of search results


What I tried so far:



googler works partially with YouTube, but for some reason only shows two search results when searching for "Madonna". Also there is not the choice between view and download.



youtube-dl has a search function, but doesn't seem to print the search results nor accept user input. youtube-dl -j ytsearch:madonna lists metadata about search results, but doesn't seem to contain the video link, title and description that would be desired.







search youtube youtube-dl






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jan 22 at 15:34









forthrinforthrin

8901121




8901121













  • Take a look at github.com/mps-youtube/mps-youtube. You can do all three things you mentioned with it.

    – ritiek
    Jan 23 at 15:22











  • @ritiek: I heard about it, but refrained from installing it due to the insane number of dependencies: libpng, frei0r, glib, pixman, cairo, graphite2, icu4c, harfbuzz, libvpx, opencore-amr, opus, sdl2, snappy, theora, x264, x265, ffmpeg, libtiff, little-cms2, lua@5.1, mujs, openjpeg, webp, leptonica, tesseract, zimg, vapoursynth and mpv. Maybe it's a great utility, but seems like way overkill for my needs.

    – forthrin
    Jan 23 at 20:15













  • So... the answer to your question is, "yes", but your response is, "I don't want to install that."

    – roaima
    Jan 23 at 21:16



















  • Take a look at github.com/mps-youtube/mps-youtube. You can do all three things you mentioned with it.

    – ritiek
    Jan 23 at 15:22











  • @ritiek: I heard about it, but refrained from installing it due to the insane number of dependencies: libpng, frei0r, glib, pixman, cairo, graphite2, icu4c, harfbuzz, libvpx, opencore-amr, opus, sdl2, snappy, theora, x264, x265, ffmpeg, libtiff, little-cms2, lua@5.1, mujs, openjpeg, webp, leptonica, tesseract, zimg, vapoursynth and mpv. Maybe it's a great utility, but seems like way overkill for my needs.

    – forthrin
    Jan 23 at 20:15













  • So... the answer to your question is, "yes", but your response is, "I don't want to install that."

    – roaima
    Jan 23 at 21:16

















Take a look at github.com/mps-youtube/mps-youtube. You can do all three things you mentioned with it.

– ritiek
Jan 23 at 15:22





Take a look at github.com/mps-youtube/mps-youtube. You can do all three things you mentioned with it.

– ritiek
Jan 23 at 15:22













@ritiek: I heard about it, but refrained from installing it due to the insane number of dependencies: libpng, frei0r, glib, pixman, cairo, graphite2, icu4c, harfbuzz, libvpx, opencore-amr, opus, sdl2, snappy, theora, x264, x265, ffmpeg, libtiff, little-cms2, lua@5.1, mujs, openjpeg, webp, leptonica, tesseract, zimg, vapoursynth and mpv. Maybe it's a great utility, but seems like way overkill for my needs.

– forthrin
Jan 23 at 20:15







@ritiek: I heard about it, but refrained from installing it due to the insane number of dependencies: libpng, frei0r, glib, pixman, cairo, graphite2, icu4c, harfbuzz, libvpx, opencore-amr, opus, sdl2, snappy, theora, x264, x265, ffmpeg, libtiff, little-cms2, lua@5.1, mujs, openjpeg, webp, leptonica, tesseract, zimg, vapoursynth and mpv. Maybe it's a great utility, but seems like way overkill for my needs.

– forthrin
Jan 23 at 20:15















So... the answer to your question is, "yes", but your response is, "I don't want to install that."

– roaima
Jan 23 at 21:16





So... the answer to your question is, "yes", but your response is, "I don't want to install that."

– roaima
Jan 23 at 21:16










3 Answers
3






active

oldest

votes


















2














Firstly, you need ytsearchN: to ask for N results. Secondly, make sure that you have the latest youtube-dl (I had some issues with an old version).



The following basic script will get 5 results, display their titles and urls, and ask which to download. Making it respond to the commands "vN" and "dN" would be simple ("dN" is effectively already implemented); I'm not sure how you could get the next page of results, though.



#!/bin/bash

tempfile=$(mktemp)
youtube_dl_log=$(mktemp)

youtube-dl -j "ytsearch5:$*" > $tempfile

# workaround for lack of mapfile in bash < 4
# https://stackoverflow.com/a/41475317/6598435
while IFS= read -r line
do
youtube_urls+=("$line")
done < <(cat $tempfile | jq '.webpage_url' | tr -d '"' )
# # for bash >= 4
# mapfile -t youtube_urls < <(cat $tempfile | jq '.webpage_url' | tr -d '"' )

cat $tempfile | jq '.fulltitle, .webpage_url'

while :
do
echo "Enter video number to download."
read i
# don't download anything if you just press enter
if [ ! x"$i" == x"" ]
then
# to make numbering of videos more intuitive (start from 1 not 0)
youtube-dl --no-progress ${youtube_urls[$i - 1]} &
fi
done


You might, perhaps, want to redirect the output from youtube-dl to a file (or /dev/null), though it could also be considered useful.






share|improve this answer


























  • A very lightweight and nice suggestion. However, macOS Unix doesn't have mapfile and jq. jq seems available in Homebrew, but how do I get mapfile? Or can your script be rewritten for compatibility? stackoverflow.com/questions/41475261/…

    – forthrin
    Jan 23 at 20:21











  • mapfile is a built-in (like help, while, alias etc.), in bash ≥ 4; by default macOS ships with lower versions of bash, as they're allergic to GPLv3 (the version they ship is the last that was under GPLv2). You can install the latest bash with homebrew. I'll modify the script to avoid use of mapfile, but bash 4 has many great features (among other things "bracketed paste" and nicer customisation of keybindings) so it might be worth installing anyway.

    – aplaice
    Jan 23 at 20:53











  • I tried installing Homebrew bash (5.0.0), but there's no mapfile there. Thanks for the modification! I'll try it out. Also, I think many people will benefit from this script.

    – forthrin
    Jan 23 at 21:37



















1














A selenium based solution:



#!/usr/bin/env python

from pyvirtualdisplay import Display
from selenium import webdriver
import time
import argparse
import re
import subprocess


class bcolors:
BLUE = '33[94m'
GREEN = '33[92m'
ENDC = '33[0m'
BOLD = '33[1m'

pattern1=re.compile("v:[0-9]");
pattern2=re.compile("d:[0-9](-[0-9])?$")

parser = argparse.ArgumentParser()
parser.add_argument("query", help="enter the youtube search query here")
args = parser.parse_args()
query=args.query

display = Display(visible=0, size=(800, 600))
display.start()

driver = webdriver.Chrome() # Optional argument, if not specified will search path.
driver.get('https://youtube.com');
search_box = driver.find_element_by_name('search_query')
search_box.send_keys(query)
search_box.submit()

i=1
page = driver.find_elements_by_css_selector("ytd-video-renderer.ytd-item-section-renderer")
link_list=;
for video in page:
a1=video.find_element_by_id('thumbnail').get_attribute('href')
a2=video.find_element_by_id('video-title').text
a3=video.find_elements_by_css_selector('yt-formatted-string[has-link-only_]:not([force-default-style]) a.yt-simple-endpoint.yt-formatted-string')[0].text
a4=video.find_elements_by_css_selector('#metadata-line.ytd-video-meta-block span.ytd-video-meta-block')[0].text
a5=video.find_elements_by_css_selector('#metadata-line.ytd-video-meta-block span.ytd-video-meta-block')[1].text
a6=video.find_elements_by_css_selector('#description-text.ytd-video-renderer')[0].text
#ink=video.get_attribute('innerHTML')
print i,a2
print a3+" "+a4+" "+a5
print a1
print a6
print
i+=1
link_list.append(a1)


driver.quit()
display.stop()

print bcolors.BOLD+bcolors.GREEN+"Available options- v: open video in VLC media player, d: download video by number, q: quit"+bcolors.ENDC
print bcolors.BOLD+bcolors.BLUE+"Usage - option:number or option:beginning-end"+bcolors.ENDC
print
entry="y"
while entry!="q":
entry=raw_input(">")
if pattern1.match(entry):
link=entry.split(":")[1]
bashCommand="vlc "+link_list[int(link)]
pass
elif pattern2.match(entry):
nums=entry.split(":")[1]
b=int(nums.split("-")[0])
e=int(nums.split("-")[1])
bashCommand="youtube-dl "+" ".join(link_list[b:e])
print bashCommand
process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE)
output, error = process.communicate()
pass


I haven't tried running the actual commands (Popen) but I think this should do it.






share|improve this answer


























  • Nice try, however I think it would be better to use a lightweight HTML scraper such as BeautifulSoup. Not everyone has Chrome installed.

    – forthrin
    Jan 23 at 20:17











  • The same thing can be done for firefox also right? And I have never used BeautifulSoup, so probably I will look into that, thanks

    – Yuki.kuroshita
    Jan 23 at 23:08



















1














Not quite pure CLI but why not use yad or zenity to ease the selection process?



Register as a developer and get an API key for youtube then this works 'as is'.



If you don't want to use the API then uncomment and comment the lines as noted and it will use 'youtube-dl' instead, though the search is slower.



#!/bin/bash

APIKEY="GET YOUR OWN API KEY!"
APIURL="https://www.googleapis.com/youtube/v3/search"
NORESULTS=25
DOWNURL="https://www.youtube.com/watch?v="

function down { youtube-dl "$DOWNURL$1"; }
function watch { xdg-open "$DOWNURL$1"; }

SEARCH=$( yad --center --title="Search for clip" --text="Enter search term" --entry 2>/dev/null)
SEARCH=$(echo $SEARCH | sed 's/ /%20/g')

#uncomment the 2 lines below to use youtube-dl
#youtube-dl -j "ytsearch$NORESULTS:$SEARCH" | jq '.id, .title' > yt.search
#SELECTION=$(cat yt.search | sed 's/^""$/"No entry"/' | sed 's/&/+/g' | sed '/^[^ ]*$/ i "FALSE"' | yad --center --checklist --list --width=1000 --height=800 --column=Check --column=ID --column=Title --button='gtk-cancel':0 --button='Download':2 --button='watch':4)

#comment out the following 3 lines if using youtube-dl
QUERY="part=snippet&maxResults=$NORESULTS&q=$SEARCH&type=video&key=$APIKEY"
curl -i -G -d "$QUERY" "$APIURL" | sed '1,15d' | jq '.items | .id.videoId, .snippet.title, .snippet.description' > yt.search
SELECTION=$(cat yt.search | sed 's/^""$/"No entry"/' | sed 's/&/+/g' | sed '/^[^ ]*$/ i "FALSE"' | yad --center --checklist --list --width=1000 --height=800 --column=Check --column=ID --column=Title --column=Description --button='gtk-cancel':0 --button='Download':2 --button='watch':4)

ACTION=$?
case $ACTION in
0)
echo "cancelled"
exit
;;
*)
for i in $(echo $SELECTION | sed 's/|/n/g' | grep -P "^"[^ ]*"$" | sed 's/"//g'); do
if [ $ACTION -eq "2" ]; then #the download button was pressed
down "$i"
else #the watch button was pressed
watch "$i"
fi
done
;;
esac





share|improve this answer


























  • It's good you let the user choose not to use the API, so downloads can be done anonymously. What's yad? I'm on macOS Unix. Can it be replaced with something more generic?

    – forthrin
    Jan 23 at 20:23











  • yad is a tool for generating gui for scripts, another is zenity. According to apple.stackexchange there is a utility called cocoadialogfor macOS.

    – bu5hman
    Jan 24 at 2:57













  • How many seconds does ytsearch10 take on your machine? Here it takes 20 seconds, which makes it unusable.

    – forthrin
    Jan 27 at 17:08











  • ytsearch takes forever for me too. That's why I had a look at the API. It's like lightning compared to ytsearch.

    – bu5hman
    Jan 27 at 17:13











Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f495998%2fcli-utility-to-search-and-view-download-youtube-videos%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














Firstly, you need ytsearchN: to ask for N results. Secondly, make sure that you have the latest youtube-dl (I had some issues with an old version).



The following basic script will get 5 results, display their titles and urls, and ask which to download. Making it respond to the commands "vN" and "dN" would be simple ("dN" is effectively already implemented); I'm not sure how you could get the next page of results, though.



#!/bin/bash

tempfile=$(mktemp)
youtube_dl_log=$(mktemp)

youtube-dl -j "ytsearch5:$*" > $tempfile

# workaround for lack of mapfile in bash < 4
# https://stackoverflow.com/a/41475317/6598435
while IFS= read -r line
do
youtube_urls+=("$line")
done < <(cat $tempfile | jq '.webpage_url' | tr -d '"' )
# # for bash >= 4
# mapfile -t youtube_urls < <(cat $tempfile | jq '.webpage_url' | tr -d '"' )

cat $tempfile | jq '.fulltitle, .webpage_url'

while :
do
echo "Enter video number to download."
read i
# don't download anything if you just press enter
if [ ! x"$i" == x"" ]
then
# to make numbering of videos more intuitive (start from 1 not 0)
youtube-dl --no-progress ${youtube_urls[$i - 1]} &
fi
done


You might, perhaps, want to redirect the output from youtube-dl to a file (or /dev/null), though it could also be considered useful.






share|improve this answer


























  • A very lightweight and nice suggestion. However, macOS Unix doesn't have mapfile and jq. jq seems available in Homebrew, but how do I get mapfile? Or can your script be rewritten for compatibility? stackoverflow.com/questions/41475261/…

    – forthrin
    Jan 23 at 20:21











  • mapfile is a built-in (like help, while, alias etc.), in bash ≥ 4; by default macOS ships with lower versions of bash, as they're allergic to GPLv3 (the version they ship is the last that was under GPLv2). You can install the latest bash with homebrew. I'll modify the script to avoid use of mapfile, but bash 4 has many great features (among other things "bracketed paste" and nicer customisation of keybindings) so it might be worth installing anyway.

    – aplaice
    Jan 23 at 20:53











  • I tried installing Homebrew bash (5.0.0), but there's no mapfile there. Thanks for the modification! I'll try it out. Also, I think many people will benefit from this script.

    – forthrin
    Jan 23 at 21:37
















2














Firstly, you need ytsearchN: to ask for N results. Secondly, make sure that you have the latest youtube-dl (I had some issues with an old version).



The following basic script will get 5 results, display their titles and urls, and ask which to download. Making it respond to the commands "vN" and "dN" would be simple ("dN" is effectively already implemented); I'm not sure how you could get the next page of results, though.



#!/bin/bash

tempfile=$(mktemp)
youtube_dl_log=$(mktemp)

youtube-dl -j "ytsearch5:$*" > $tempfile

# workaround for lack of mapfile in bash < 4
# https://stackoverflow.com/a/41475317/6598435
while IFS= read -r line
do
youtube_urls+=("$line")
done < <(cat $tempfile | jq '.webpage_url' | tr -d '"' )
# # for bash >= 4
# mapfile -t youtube_urls < <(cat $tempfile | jq '.webpage_url' | tr -d '"' )

cat $tempfile | jq '.fulltitle, .webpage_url'

while :
do
echo "Enter video number to download."
read i
# don't download anything if you just press enter
if [ ! x"$i" == x"" ]
then
# to make numbering of videos more intuitive (start from 1 not 0)
youtube-dl --no-progress ${youtube_urls[$i - 1]} &
fi
done


You might, perhaps, want to redirect the output from youtube-dl to a file (or /dev/null), though it could also be considered useful.






share|improve this answer


























  • A very lightweight and nice suggestion. However, macOS Unix doesn't have mapfile and jq. jq seems available in Homebrew, but how do I get mapfile? Or can your script be rewritten for compatibility? stackoverflow.com/questions/41475261/…

    – forthrin
    Jan 23 at 20:21











  • mapfile is a built-in (like help, while, alias etc.), in bash ≥ 4; by default macOS ships with lower versions of bash, as they're allergic to GPLv3 (the version they ship is the last that was under GPLv2). You can install the latest bash with homebrew. I'll modify the script to avoid use of mapfile, but bash 4 has many great features (among other things "bracketed paste" and nicer customisation of keybindings) so it might be worth installing anyway.

    – aplaice
    Jan 23 at 20:53











  • I tried installing Homebrew bash (5.0.0), but there's no mapfile there. Thanks for the modification! I'll try it out. Also, I think many people will benefit from this script.

    – forthrin
    Jan 23 at 21:37














2












2








2







Firstly, you need ytsearchN: to ask for N results. Secondly, make sure that you have the latest youtube-dl (I had some issues with an old version).



The following basic script will get 5 results, display their titles and urls, and ask which to download. Making it respond to the commands "vN" and "dN" would be simple ("dN" is effectively already implemented); I'm not sure how you could get the next page of results, though.



#!/bin/bash

tempfile=$(mktemp)
youtube_dl_log=$(mktemp)

youtube-dl -j "ytsearch5:$*" > $tempfile

# workaround for lack of mapfile in bash < 4
# https://stackoverflow.com/a/41475317/6598435
while IFS= read -r line
do
youtube_urls+=("$line")
done < <(cat $tempfile | jq '.webpage_url' | tr -d '"' )
# # for bash >= 4
# mapfile -t youtube_urls < <(cat $tempfile | jq '.webpage_url' | tr -d '"' )

cat $tempfile | jq '.fulltitle, .webpage_url'

while :
do
echo "Enter video number to download."
read i
# don't download anything if you just press enter
if [ ! x"$i" == x"" ]
then
# to make numbering of videos more intuitive (start from 1 not 0)
youtube-dl --no-progress ${youtube_urls[$i - 1]} &
fi
done


You might, perhaps, want to redirect the output from youtube-dl to a file (or /dev/null), though it could also be considered useful.






share|improve this answer















Firstly, you need ytsearchN: to ask for N results. Secondly, make sure that you have the latest youtube-dl (I had some issues with an old version).



The following basic script will get 5 results, display their titles and urls, and ask which to download. Making it respond to the commands "vN" and "dN" would be simple ("dN" is effectively already implemented); I'm not sure how you could get the next page of results, though.



#!/bin/bash

tempfile=$(mktemp)
youtube_dl_log=$(mktemp)

youtube-dl -j "ytsearch5:$*" > $tempfile

# workaround for lack of mapfile in bash < 4
# https://stackoverflow.com/a/41475317/6598435
while IFS= read -r line
do
youtube_urls+=("$line")
done < <(cat $tempfile | jq '.webpage_url' | tr -d '"' )
# # for bash >= 4
# mapfile -t youtube_urls < <(cat $tempfile | jq '.webpage_url' | tr -d '"' )

cat $tempfile | jq '.fulltitle, .webpage_url'

while :
do
echo "Enter video number to download."
read i
# don't download anything if you just press enter
if [ ! x"$i" == x"" ]
then
# to make numbering of videos more intuitive (start from 1 not 0)
youtube-dl --no-progress ${youtube_urls[$i - 1]} &
fi
done


You might, perhaps, want to redirect the output from youtube-dl to a file (or /dev/null), though it could also be considered useful.







share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 23 at 21:54

























answered Jan 22 at 18:28









aplaiceaplaice

20613




20613













  • A very lightweight and nice suggestion. However, macOS Unix doesn't have mapfile and jq. jq seems available in Homebrew, but how do I get mapfile? Or can your script be rewritten for compatibility? stackoverflow.com/questions/41475261/…

    – forthrin
    Jan 23 at 20:21











  • mapfile is a built-in (like help, while, alias etc.), in bash ≥ 4; by default macOS ships with lower versions of bash, as they're allergic to GPLv3 (the version they ship is the last that was under GPLv2). You can install the latest bash with homebrew. I'll modify the script to avoid use of mapfile, but bash 4 has many great features (among other things "bracketed paste" and nicer customisation of keybindings) so it might be worth installing anyway.

    – aplaice
    Jan 23 at 20:53











  • I tried installing Homebrew bash (5.0.0), but there's no mapfile there. Thanks for the modification! I'll try it out. Also, I think many people will benefit from this script.

    – forthrin
    Jan 23 at 21:37



















  • A very lightweight and nice suggestion. However, macOS Unix doesn't have mapfile and jq. jq seems available in Homebrew, but how do I get mapfile? Or can your script be rewritten for compatibility? stackoverflow.com/questions/41475261/…

    – forthrin
    Jan 23 at 20:21











  • mapfile is a built-in (like help, while, alias etc.), in bash ≥ 4; by default macOS ships with lower versions of bash, as they're allergic to GPLv3 (the version they ship is the last that was under GPLv2). You can install the latest bash with homebrew. I'll modify the script to avoid use of mapfile, but bash 4 has many great features (among other things "bracketed paste" and nicer customisation of keybindings) so it might be worth installing anyway.

    – aplaice
    Jan 23 at 20:53











  • I tried installing Homebrew bash (5.0.0), but there's no mapfile there. Thanks for the modification! I'll try it out. Also, I think many people will benefit from this script.

    – forthrin
    Jan 23 at 21:37

















A very lightweight and nice suggestion. However, macOS Unix doesn't have mapfile and jq. jq seems available in Homebrew, but how do I get mapfile? Or can your script be rewritten for compatibility? stackoverflow.com/questions/41475261/…

– forthrin
Jan 23 at 20:21





A very lightweight and nice suggestion. However, macOS Unix doesn't have mapfile and jq. jq seems available in Homebrew, but how do I get mapfile? Or can your script be rewritten for compatibility? stackoverflow.com/questions/41475261/…

– forthrin
Jan 23 at 20:21













mapfile is a built-in (like help, while, alias etc.), in bash ≥ 4; by default macOS ships with lower versions of bash, as they're allergic to GPLv3 (the version they ship is the last that was under GPLv2). You can install the latest bash with homebrew. I'll modify the script to avoid use of mapfile, but bash 4 has many great features (among other things "bracketed paste" and nicer customisation of keybindings) so it might be worth installing anyway.

– aplaice
Jan 23 at 20:53





mapfile is a built-in (like help, while, alias etc.), in bash ≥ 4; by default macOS ships with lower versions of bash, as they're allergic to GPLv3 (the version they ship is the last that was under GPLv2). You can install the latest bash with homebrew. I'll modify the script to avoid use of mapfile, but bash 4 has many great features (among other things "bracketed paste" and nicer customisation of keybindings) so it might be worth installing anyway.

– aplaice
Jan 23 at 20:53













I tried installing Homebrew bash (5.0.0), but there's no mapfile there. Thanks for the modification! I'll try it out. Also, I think many people will benefit from this script.

– forthrin
Jan 23 at 21:37





I tried installing Homebrew bash (5.0.0), but there's no mapfile there. Thanks for the modification! I'll try it out. Also, I think many people will benefit from this script.

– forthrin
Jan 23 at 21:37













1














A selenium based solution:



#!/usr/bin/env python

from pyvirtualdisplay import Display
from selenium import webdriver
import time
import argparse
import re
import subprocess


class bcolors:
BLUE = '33[94m'
GREEN = '33[92m'
ENDC = '33[0m'
BOLD = '33[1m'

pattern1=re.compile("v:[0-9]");
pattern2=re.compile("d:[0-9](-[0-9])?$")

parser = argparse.ArgumentParser()
parser.add_argument("query", help="enter the youtube search query here")
args = parser.parse_args()
query=args.query

display = Display(visible=0, size=(800, 600))
display.start()

driver = webdriver.Chrome() # Optional argument, if not specified will search path.
driver.get('https://youtube.com');
search_box = driver.find_element_by_name('search_query')
search_box.send_keys(query)
search_box.submit()

i=1
page = driver.find_elements_by_css_selector("ytd-video-renderer.ytd-item-section-renderer")
link_list=;
for video in page:
a1=video.find_element_by_id('thumbnail').get_attribute('href')
a2=video.find_element_by_id('video-title').text
a3=video.find_elements_by_css_selector('yt-formatted-string[has-link-only_]:not([force-default-style]) a.yt-simple-endpoint.yt-formatted-string')[0].text
a4=video.find_elements_by_css_selector('#metadata-line.ytd-video-meta-block span.ytd-video-meta-block')[0].text
a5=video.find_elements_by_css_selector('#metadata-line.ytd-video-meta-block span.ytd-video-meta-block')[1].text
a6=video.find_elements_by_css_selector('#description-text.ytd-video-renderer')[0].text
#ink=video.get_attribute('innerHTML')
print i,a2
print a3+" "+a4+" "+a5
print a1
print a6
print
i+=1
link_list.append(a1)


driver.quit()
display.stop()

print bcolors.BOLD+bcolors.GREEN+"Available options- v: open video in VLC media player, d: download video by number, q: quit"+bcolors.ENDC
print bcolors.BOLD+bcolors.BLUE+"Usage - option:number or option:beginning-end"+bcolors.ENDC
print
entry="y"
while entry!="q":
entry=raw_input(">")
if pattern1.match(entry):
link=entry.split(":")[1]
bashCommand="vlc "+link_list[int(link)]
pass
elif pattern2.match(entry):
nums=entry.split(":")[1]
b=int(nums.split("-")[0])
e=int(nums.split("-")[1])
bashCommand="youtube-dl "+" ".join(link_list[b:e])
print bashCommand
process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE)
output, error = process.communicate()
pass


I haven't tried running the actual commands (Popen) but I think this should do it.






share|improve this answer


























  • Nice try, however I think it would be better to use a lightweight HTML scraper such as BeautifulSoup. Not everyone has Chrome installed.

    – forthrin
    Jan 23 at 20:17











  • The same thing can be done for firefox also right? And I have never used BeautifulSoup, so probably I will look into that, thanks

    – Yuki.kuroshita
    Jan 23 at 23:08
















1














A selenium based solution:



#!/usr/bin/env python

from pyvirtualdisplay import Display
from selenium import webdriver
import time
import argparse
import re
import subprocess


class bcolors:
BLUE = '33[94m'
GREEN = '33[92m'
ENDC = '33[0m'
BOLD = '33[1m'

pattern1=re.compile("v:[0-9]");
pattern2=re.compile("d:[0-9](-[0-9])?$")

parser = argparse.ArgumentParser()
parser.add_argument("query", help="enter the youtube search query here")
args = parser.parse_args()
query=args.query

display = Display(visible=0, size=(800, 600))
display.start()

driver = webdriver.Chrome() # Optional argument, if not specified will search path.
driver.get('https://youtube.com');
search_box = driver.find_element_by_name('search_query')
search_box.send_keys(query)
search_box.submit()

i=1
page = driver.find_elements_by_css_selector("ytd-video-renderer.ytd-item-section-renderer")
link_list=;
for video in page:
a1=video.find_element_by_id('thumbnail').get_attribute('href')
a2=video.find_element_by_id('video-title').text
a3=video.find_elements_by_css_selector('yt-formatted-string[has-link-only_]:not([force-default-style]) a.yt-simple-endpoint.yt-formatted-string')[0].text
a4=video.find_elements_by_css_selector('#metadata-line.ytd-video-meta-block span.ytd-video-meta-block')[0].text
a5=video.find_elements_by_css_selector('#metadata-line.ytd-video-meta-block span.ytd-video-meta-block')[1].text
a6=video.find_elements_by_css_selector('#description-text.ytd-video-renderer')[0].text
#ink=video.get_attribute('innerHTML')
print i,a2
print a3+" "+a4+" "+a5
print a1
print a6
print
i+=1
link_list.append(a1)


driver.quit()
display.stop()

print bcolors.BOLD+bcolors.GREEN+"Available options- v: open video in VLC media player, d: download video by number, q: quit"+bcolors.ENDC
print bcolors.BOLD+bcolors.BLUE+"Usage - option:number or option:beginning-end"+bcolors.ENDC
print
entry="y"
while entry!="q":
entry=raw_input(">")
if pattern1.match(entry):
link=entry.split(":")[1]
bashCommand="vlc "+link_list[int(link)]
pass
elif pattern2.match(entry):
nums=entry.split(":")[1]
b=int(nums.split("-")[0])
e=int(nums.split("-")[1])
bashCommand="youtube-dl "+" ".join(link_list[b:e])
print bashCommand
process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE)
output, error = process.communicate()
pass


I haven't tried running the actual commands (Popen) but I think this should do it.






share|improve this answer


























  • Nice try, however I think it would be better to use a lightweight HTML scraper such as BeautifulSoup. Not everyone has Chrome installed.

    – forthrin
    Jan 23 at 20:17











  • The same thing can be done for firefox also right? And I have never used BeautifulSoup, so probably I will look into that, thanks

    – Yuki.kuroshita
    Jan 23 at 23:08














1












1








1







A selenium based solution:



#!/usr/bin/env python

from pyvirtualdisplay import Display
from selenium import webdriver
import time
import argparse
import re
import subprocess


class bcolors:
BLUE = '33[94m'
GREEN = '33[92m'
ENDC = '33[0m'
BOLD = '33[1m'

pattern1=re.compile("v:[0-9]");
pattern2=re.compile("d:[0-9](-[0-9])?$")

parser = argparse.ArgumentParser()
parser.add_argument("query", help="enter the youtube search query here")
args = parser.parse_args()
query=args.query

display = Display(visible=0, size=(800, 600))
display.start()

driver = webdriver.Chrome() # Optional argument, if not specified will search path.
driver.get('https://youtube.com');
search_box = driver.find_element_by_name('search_query')
search_box.send_keys(query)
search_box.submit()

i=1
page = driver.find_elements_by_css_selector("ytd-video-renderer.ytd-item-section-renderer")
link_list=;
for video in page:
a1=video.find_element_by_id('thumbnail').get_attribute('href')
a2=video.find_element_by_id('video-title').text
a3=video.find_elements_by_css_selector('yt-formatted-string[has-link-only_]:not([force-default-style]) a.yt-simple-endpoint.yt-formatted-string')[0].text
a4=video.find_elements_by_css_selector('#metadata-line.ytd-video-meta-block span.ytd-video-meta-block')[0].text
a5=video.find_elements_by_css_selector('#metadata-line.ytd-video-meta-block span.ytd-video-meta-block')[1].text
a6=video.find_elements_by_css_selector('#description-text.ytd-video-renderer')[0].text
#ink=video.get_attribute('innerHTML')
print i,a2
print a3+" "+a4+" "+a5
print a1
print a6
print
i+=1
link_list.append(a1)


driver.quit()
display.stop()

print bcolors.BOLD+bcolors.GREEN+"Available options- v: open video in VLC media player, d: download video by number, q: quit"+bcolors.ENDC
print bcolors.BOLD+bcolors.BLUE+"Usage - option:number or option:beginning-end"+bcolors.ENDC
print
entry="y"
while entry!="q":
entry=raw_input(">")
if pattern1.match(entry):
link=entry.split(":")[1]
bashCommand="vlc "+link_list[int(link)]
pass
elif pattern2.match(entry):
nums=entry.split(":")[1]
b=int(nums.split("-")[0])
e=int(nums.split("-")[1])
bashCommand="youtube-dl "+" ".join(link_list[b:e])
print bashCommand
process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE)
output, error = process.communicate()
pass


I haven't tried running the actual commands (Popen) but I think this should do it.






share|improve this answer















A selenium based solution:



#!/usr/bin/env python

from pyvirtualdisplay import Display
from selenium import webdriver
import time
import argparse
import re
import subprocess


class bcolors:
BLUE = '33[94m'
GREEN = '33[92m'
ENDC = '33[0m'
BOLD = '33[1m'

pattern1=re.compile("v:[0-9]");
pattern2=re.compile("d:[0-9](-[0-9])?$")

parser = argparse.ArgumentParser()
parser.add_argument("query", help="enter the youtube search query here")
args = parser.parse_args()
query=args.query

display = Display(visible=0, size=(800, 600))
display.start()

driver = webdriver.Chrome() # Optional argument, if not specified will search path.
driver.get('https://youtube.com');
search_box = driver.find_element_by_name('search_query')
search_box.send_keys(query)
search_box.submit()

i=1
page = driver.find_elements_by_css_selector("ytd-video-renderer.ytd-item-section-renderer")
link_list=;
for video in page:
a1=video.find_element_by_id('thumbnail').get_attribute('href')
a2=video.find_element_by_id('video-title').text
a3=video.find_elements_by_css_selector('yt-formatted-string[has-link-only_]:not([force-default-style]) a.yt-simple-endpoint.yt-formatted-string')[0].text
a4=video.find_elements_by_css_selector('#metadata-line.ytd-video-meta-block span.ytd-video-meta-block')[0].text
a5=video.find_elements_by_css_selector('#metadata-line.ytd-video-meta-block span.ytd-video-meta-block')[1].text
a6=video.find_elements_by_css_selector('#description-text.ytd-video-renderer')[0].text
#ink=video.get_attribute('innerHTML')
print i,a2
print a3+" "+a4+" "+a5
print a1
print a6
print
i+=1
link_list.append(a1)


driver.quit()
display.stop()

print bcolors.BOLD+bcolors.GREEN+"Available options- v: open video in VLC media player, d: download video by number, q: quit"+bcolors.ENDC
print bcolors.BOLD+bcolors.BLUE+"Usage - option:number or option:beginning-end"+bcolors.ENDC
print
entry="y"
while entry!="q":
entry=raw_input(">")
if pattern1.match(entry):
link=entry.split(":")[1]
bashCommand="vlc "+link_list[int(link)]
pass
elif pattern2.match(entry):
nums=entry.split(":")[1]
b=int(nums.split("-")[0])
e=int(nums.split("-")[1])
bashCommand="youtube-dl "+" ".join(link_list[b:e])
print bashCommand
process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE)
output, error = process.communicate()
pass


I haven't tried running the actual commands (Popen) but I think this should do it.







share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 22 at 19:51

























answered Jan 22 at 19:44









Yuki.kuroshitaYuki.kuroshita

199110




199110













  • Nice try, however I think it would be better to use a lightweight HTML scraper such as BeautifulSoup. Not everyone has Chrome installed.

    – forthrin
    Jan 23 at 20:17











  • The same thing can be done for firefox also right? And I have never used BeautifulSoup, so probably I will look into that, thanks

    – Yuki.kuroshita
    Jan 23 at 23:08



















  • Nice try, however I think it would be better to use a lightweight HTML scraper such as BeautifulSoup. Not everyone has Chrome installed.

    – forthrin
    Jan 23 at 20:17











  • The same thing can be done for firefox also right? And I have never used BeautifulSoup, so probably I will look into that, thanks

    – Yuki.kuroshita
    Jan 23 at 23:08

















Nice try, however I think it would be better to use a lightweight HTML scraper such as BeautifulSoup. Not everyone has Chrome installed.

– forthrin
Jan 23 at 20:17





Nice try, however I think it would be better to use a lightweight HTML scraper such as BeautifulSoup. Not everyone has Chrome installed.

– forthrin
Jan 23 at 20:17













The same thing can be done for firefox also right? And I have never used BeautifulSoup, so probably I will look into that, thanks

– Yuki.kuroshita
Jan 23 at 23:08





The same thing can be done for firefox also right? And I have never used BeautifulSoup, so probably I will look into that, thanks

– Yuki.kuroshita
Jan 23 at 23:08











1














Not quite pure CLI but why not use yad or zenity to ease the selection process?



Register as a developer and get an API key for youtube then this works 'as is'.



If you don't want to use the API then uncomment and comment the lines as noted and it will use 'youtube-dl' instead, though the search is slower.



#!/bin/bash

APIKEY="GET YOUR OWN API KEY!"
APIURL="https://www.googleapis.com/youtube/v3/search"
NORESULTS=25
DOWNURL="https://www.youtube.com/watch?v="

function down { youtube-dl "$DOWNURL$1"; }
function watch { xdg-open "$DOWNURL$1"; }

SEARCH=$( yad --center --title="Search for clip" --text="Enter search term" --entry 2>/dev/null)
SEARCH=$(echo $SEARCH | sed 's/ /%20/g')

#uncomment the 2 lines below to use youtube-dl
#youtube-dl -j "ytsearch$NORESULTS:$SEARCH" | jq '.id, .title' > yt.search
#SELECTION=$(cat yt.search | sed 's/^""$/"No entry"/' | sed 's/&/+/g' | sed '/^[^ ]*$/ i "FALSE"' | yad --center --checklist --list --width=1000 --height=800 --column=Check --column=ID --column=Title --button='gtk-cancel':0 --button='Download':2 --button='watch':4)

#comment out the following 3 lines if using youtube-dl
QUERY="part=snippet&maxResults=$NORESULTS&q=$SEARCH&type=video&key=$APIKEY"
curl -i -G -d "$QUERY" "$APIURL" | sed '1,15d' | jq '.items | .id.videoId, .snippet.title, .snippet.description' > yt.search
SELECTION=$(cat yt.search | sed 's/^""$/"No entry"/' | sed 's/&/+/g' | sed '/^[^ ]*$/ i "FALSE"' | yad --center --checklist --list --width=1000 --height=800 --column=Check --column=ID --column=Title --column=Description --button='gtk-cancel':0 --button='Download':2 --button='watch':4)

ACTION=$?
case $ACTION in
0)
echo "cancelled"
exit
;;
*)
for i in $(echo $SELECTION | sed 's/|/n/g' | grep -P "^"[^ ]*"$" | sed 's/"//g'); do
if [ $ACTION -eq "2" ]; then #the download button was pressed
down "$i"
else #the watch button was pressed
watch "$i"
fi
done
;;
esac





share|improve this answer


























  • It's good you let the user choose not to use the API, so downloads can be done anonymously. What's yad? I'm on macOS Unix. Can it be replaced with something more generic?

    – forthrin
    Jan 23 at 20:23











  • yad is a tool for generating gui for scripts, another is zenity. According to apple.stackexchange there is a utility called cocoadialogfor macOS.

    – bu5hman
    Jan 24 at 2:57













  • How many seconds does ytsearch10 take on your machine? Here it takes 20 seconds, which makes it unusable.

    – forthrin
    Jan 27 at 17:08











  • ytsearch takes forever for me too. That's why I had a look at the API. It's like lightning compared to ytsearch.

    – bu5hman
    Jan 27 at 17:13
















1














Not quite pure CLI but why not use yad or zenity to ease the selection process?



Register as a developer and get an API key for youtube then this works 'as is'.



If you don't want to use the API then uncomment and comment the lines as noted and it will use 'youtube-dl' instead, though the search is slower.



#!/bin/bash

APIKEY="GET YOUR OWN API KEY!"
APIURL="https://www.googleapis.com/youtube/v3/search"
NORESULTS=25
DOWNURL="https://www.youtube.com/watch?v="

function down { youtube-dl "$DOWNURL$1"; }
function watch { xdg-open "$DOWNURL$1"; }

SEARCH=$( yad --center --title="Search for clip" --text="Enter search term" --entry 2>/dev/null)
SEARCH=$(echo $SEARCH | sed 's/ /%20/g')

#uncomment the 2 lines below to use youtube-dl
#youtube-dl -j "ytsearch$NORESULTS:$SEARCH" | jq '.id, .title' > yt.search
#SELECTION=$(cat yt.search | sed 's/^""$/"No entry"/' | sed 's/&/+/g' | sed '/^[^ ]*$/ i "FALSE"' | yad --center --checklist --list --width=1000 --height=800 --column=Check --column=ID --column=Title --button='gtk-cancel':0 --button='Download':2 --button='watch':4)

#comment out the following 3 lines if using youtube-dl
QUERY="part=snippet&maxResults=$NORESULTS&q=$SEARCH&type=video&key=$APIKEY"
curl -i -G -d "$QUERY" "$APIURL" | sed '1,15d' | jq '.items | .id.videoId, .snippet.title, .snippet.description' > yt.search
SELECTION=$(cat yt.search | sed 's/^""$/"No entry"/' | sed 's/&/+/g' | sed '/^[^ ]*$/ i "FALSE"' | yad --center --checklist --list --width=1000 --height=800 --column=Check --column=ID --column=Title --column=Description --button='gtk-cancel':0 --button='Download':2 --button='watch':4)

ACTION=$?
case $ACTION in
0)
echo "cancelled"
exit
;;
*)
for i in $(echo $SELECTION | sed 's/|/n/g' | grep -P "^"[^ ]*"$" | sed 's/"//g'); do
if [ $ACTION -eq "2" ]; then #the download button was pressed
down "$i"
else #the watch button was pressed
watch "$i"
fi
done
;;
esac





share|improve this answer


























  • It's good you let the user choose not to use the API, so downloads can be done anonymously. What's yad? I'm on macOS Unix. Can it be replaced with something more generic?

    – forthrin
    Jan 23 at 20:23











  • yad is a tool for generating gui for scripts, another is zenity. According to apple.stackexchange there is a utility called cocoadialogfor macOS.

    – bu5hman
    Jan 24 at 2:57













  • How many seconds does ytsearch10 take on your machine? Here it takes 20 seconds, which makes it unusable.

    – forthrin
    Jan 27 at 17:08











  • ytsearch takes forever for me too. That's why I had a look at the API. It's like lightning compared to ytsearch.

    – bu5hman
    Jan 27 at 17:13














1












1








1







Not quite pure CLI but why not use yad or zenity to ease the selection process?



Register as a developer and get an API key for youtube then this works 'as is'.



If you don't want to use the API then uncomment and comment the lines as noted and it will use 'youtube-dl' instead, though the search is slower.



#!/bin/bash

APIKEY="GET YOUR OWN API KEY!"
APIURL="https://www.googleapis.com/youtube/v3/search"
NORESULTS=25
DOWNURL="https://www.youtube.com/watch?v="

function down { youtube-dl "$DOWNURL$1"; }
function watch { xdg-open "$DOWNURL$1"; }

SEARCH=$( yad --center --title="Search for clip" --text="Enter search term" --entry 2>/dev/null)
SEARCH=$(echo $SEARCH | sed 's/ /%20/g')

#uncomment the 2 lines below to use youtube-dl
#youtube-dl -j "ytsearch$NORESULTS:$SEARCH" | jq '.id, .title' > yt.search
#SELECTION=$(cat yt.search | sed 's/^""$/"No entry"/' | sed 's/&/+/g' | sed '/^[^ ]*$/ i "FALSE"' | yad --center --checklist --list --width=1000 --height=800 --column=Check --column=ID --column=Title --button='gtk-cancel':0 --button='Download':2 --button='watch':4)

#comment out the following 3 lines if using youtube-dl
QUERY="part=snippet&maxResults=$NORESULTS&q=$SEARCH&type=video&key=$APIKEY"
curl -i -G -d "$QUERY" "$APIURL" | sed '1,15d' | jq '.items | .id.videoId, .snippet.title, .snippet.description' > yt.search
SELECTION=$(cat yt.search | sed 's/^""$/"No entry"/' | sed 's/&/+/g' | sed '/^[^ ]*$/ i "FALSE"' | yad --center --checklist --list --width=1000 --height=800 --column=Check --column=ID --column=Title --column=Description --button='gtk-cancel':0 --button='Download':2 --button='watch':4)

ACTION=$?
case $ACTION in
0)
echo "cancelled"
exit
;;
*)
for i in $(echo $SELECTION | sed 's/|/n/g' | grep -P "^"[^ ]*"$" | sed 's/"//g'); do
if [ $ACTION -eq "2" ]; then #the download button was pressed
down "$i"
else #the watch button was pressed
watch "$i"
fi
done
;;
esac





share|improve this answer















Not quite pure CLI but why not use yad or zenity to ease the selection process?



Register as a developer and get an API key for youtube then this works 'as is'.



If you don't want to use the API then uncomment and comment the lines as noted and it will use 'youtube-dl' instead, though the search is slower.



#!/bin/bash

APIKEY="GET YOUR OWN API KEY!"
APIURL="https://www.googleapis.com/youtube/v3/search"
NORESULTS=25
DOWNURL="https://www.youtube.com/watch?v="

function down { youtube-dl "$DOWNURL$1"; }
function watch { xdg-open "$DOWNURL$1"; }

SEARCH=$( yad --center --title="Search for clip" --text="Enter search term" --entry 2>/dev/null)
SEARCH=$(echo $SEARCH | sed 's/ /%20/g')

#uncomment the 2 lines below to use youtube-dl
#youtube-dl -j "ytsearch$NORESULTS:$SEARCH" | jq '.id, .title' > yt.search
#SELECTION=$(cat yt.search | sed 's/^""$/"No entry"/' | sed 's/&/+/g' | sed '/^[^ ]*$/ i "FALSE"' | yad --center --checklist --list --width=1000 --height=800 --column=Check --column=ID --column=Title --button='gtk-cancel':0 --button='Download':2 --button='watch':4)

#comment out the following 3 lines if using youtube-dl
QUERY="part=snippet&maxResults=$NORESULTS&q=$SEARCH&type=video&key=$APIKEY"
curl -i -G -d "$QUERY" "$APIURL" | sed '1,15d' | jq '.items | .id.videoId, .snippet.title, .snippet.description' > yt.search
SELECTION=$(cat yt.search | sed 's/^""$/"No entry"/' | sed 's/&/+/g' | sed '/^[^ ]*$/ i "FALSE"' | yad --center --checklist --list --width=1000 --height=800 --column=Check --column=ID --column=Title --column=Description --button='gtk-cancel':0 --button='Download':2 --button='watch':4)

ACTION=$?
case $ACTION in
0)
echo "cancelled"
exit
;;
*)
for i in $(echo $SELECTION | sed 's/|/n/g' | grep -P "^"[^ ]*"$" | sed 's/"//g'); do
if [ $ACTION -eq "2" ]; then #the download button was pressed
down "$i"
else #the watch button was pressed
watch "$i"
fi
done
;;
esac






share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 23 at 14:45

























answered Jan 23 at 7:03









bu5hmanbu5hman

1,282214




1,282214













  • It's good you let the user choose not to use the API, so downloads can be done anonymously. What's yad? I'm on macOS Unix. Can it be replaced with something more generic?

    – forthrin
    Jan 23 at 20:23











  • yad is a tool for generating gui for scripts, another is zenity. According to apple.stackexchange there is a utility called cocoadialogfor macOS.

    – bu5hman
    Jan 24 at 2:57













  • How many seconds does ytsearch10 take on your machine? Here it takes 20 seconds, which makes it unusable.

    – forthrin
    Jan 27 at 17:08











  • ytsearch takes forever for me too. That's why I had a look at the API. It's like lightning compared to ytsearch.

    – bu5hman
    Jan 27 at 17:13



















  • It's good you let the user choose not to use the API, so downloads can be done anonymously. What's yad? I'm on macOS Unix. Can it be replaced with something more generic?

    – forthrin
    Jan 23 at 20:23











  • yad is a tool for generating gui for scripts, another is zenity. According to apple.stackexchange there is a utility called cocoadialogfor macOS.

    – bu5hman
    Jan 24 at 2:57













  • How many seconds does ytsearch10 take on your machine? Here it takes 20 seconds, which makes it unusable.

    – forthrin
    Jan 27 at 17:08











  • ytsearch takes forever for me too. That's why I had a look at the API. It's like lightning compared to ytsearch.

    – bu5hman
    Jan 27 at 17:13

















It's good you let the user choose not to use the API, so downloads can be done anonymously. What's yad? I'm on macOS Unix. Can it be replaced with something more generic?

– forthrin
Jan 23 at 20:23





It's good you let the user choose not to use the API, so downloads can be done anonymously. What's yad? I'm on macOS Unix. Can it be replaced with something more generic?

– forthrin
Jan 23 at 20:23













yad is a tool for generating gui for scripts, another is zenity. According to apple.stackexchange there is a utility called cocoadialogfor macOS.

– bu5hman
Jan 24 at 2:57







yad is a tool for generating gui for scripts, another is zenity. According to apple.stackexchange there is a utility called cocoadialogfor macOS.

– bu5hman
Jan 24 at 2:57















How many seconds does ytsearch10 take on your machine? Here it takes 20 seconds, which makes it unusable.

– forthrin
Jan 27 at 17:08





How many seconds does ytsearch10 take on your machine? Here it takes 20 seconds, which makes it unusable.

– forthrin
Jan 27 at 17:08













ytsearch takes forever for me too. That's why I had a look at the API. It's like lightning compared to ytsearch.

– bu5hman
Jan 27 at 17:13





ytsearch takes forever for me too. That's why I had a look at the API. It's like lightning compared to ytsearch.

– bu5hman
Jan 27 at 17:13


















draft saved

draft discarded




















































Thanks for contributing an answer to Unix & Linux Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f495998%2fcli-utility-to-search-and-view-download-youtube-videos%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

How to reconfigure Docker Trusted Registry 2.x.x to use CEPH FS mount instead of NFS and other traditional...

is 'sed' thread safe

How to make a Squid Proxy server?