
Есть ли утилита, которая может искать на YouTube из командной строки, а затем либовидилискачатьрезультаты поиска в соответствии с введенными пользователем данными?
$ 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.
И затем вы можете ввести:
- «v1» для просмотра видео 1 (с VLC и т. д.)
- «d1-3» для загрузки видео 1-3 (с помощью youtube-dl и т. д.)
- «n» для просмотра следующей страницы результатов поиска
Что я уже попробовал:
гуглёрЧастично работает с YouTube, но почему-то при поиске "Мадонна" показывает только два результата. Также нет выбора между просмотром и скачиванием.
youtube-dlимеет функцию поиска, но, похоже, не выводит результаты поиска и не принимает вводимые пользователем данные. youtube-dl -j ytsearch:madonna
перечисляет метаданные о результатах поиска, но, похоже, не содержит желаемой ссылки на видео, названия и описания.
решение1
Во-первых, вам нужно ytsearchN:
запросить N
результаты. Во-вторых, убедитесь, что у вас последняя версия youtube-dl
(у меня были некоторые проблемы со старой версией).
Следующий базовый скрипт получит 5 результатов, отобразит их заголовки и URL-адреса и спросит, какой из них загрузить. Заставить его реагировать на команды "vN" и "dN" будет просто ("dN" фактически уже реализован); хотя я не уверен, как можно получить следующую страницу результатов.
#!/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
Возможно, вы захотите перенаправить вывод из youtube-dl
в файл (или /dev/null
), хотя это также может быть полезно.
решение2
Раствор на основе селена:
#!/usr/bin/env python
from pyvirtualdisplay import Display
from selenium import webdriver
import time
import argparse
import re
import subprocess
class bcolors:
BLUE = '\033[94m'
GREEN = '\033[92m'
ENDC = '\033[0m'
BOLD = '\033[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
Я не пробовал выполнять сами команды ( Popen
), но думаю, что это должно сработать.
решение3
Не совсем чистый CLI, но почему бы не использовать yad
или zenity
для упрощения процесса выбора?
Зарегистрируйтесь как разработчик и получитеAPI-ключдля youtube это работает «как есть».
Если вы не хотите использовать API, то раскомментируйте и закомментируйте строки, как указано, и вместо этого будет использоваться «youtube-dl», хотя поиск будет медленнее.
#!/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
решение4
Здесьэто терминальный инструмент: ytfzf
. Найдено о немздесь.
Протестировав его в 2022 K/ubuntu, я обнаружил, что он менее глючный и менее сложный, чем mps-youtube.
Введите ytfzf
в терминале, чтобы начать. Смотрите ytfzf -h
для опций, таких как только аудио и загрузка.
Поиск выполняется после установки переменной, например
- чтобы получить только аудио:
ytfzf -m <search_term>
- для того, чтобы скачать видео:
ytfzf -d <search_term>
Мы можем добавить это в средство запуска приложений с помощью строки Exec=konsole -e ytfzf -m
, например, под названием «Youtube audio...» — и аналогично для других опций.
Прокрутите вверх-вниз и нажмите Enter или дважды щелкните, чтобы выбрать заголовок.
Плеер по умолчанию — mpv
, загрузка выполняется curl
, настройки — в ~/.config/ytfzf/conf.sh
.