Часто, занимаясь своими делами, я люблю открыть какие-нибудь фильмы/клипы/сериалы, которые не требуют никакого внимания, повесив плеер где-нибудь в углу экрана. В наш век быстрого интернета и большого количества свободного видео в социальных сетях(например Vkontakte) во многом удобно смотреть их в потоке, не захламляя ненужными файлами жесткий диск… Но, попытавшись реализовать описанную выше схему, мы сталкиваемся с тем, что повесить окно браузера с плеером «где-нибудь» в углу экрана так, чтобы делать что-то полезное, больше не отвлекаясь проигрывание видео, не так уж просто. Кроме того, flash обычно есть больше ресурсов, чем обычный плеер в системе, что несколько критично для маломощных нетбуков.
Поэтому ( а еще потому, что в плеере Vkontakte отсутствует playlist, и это заставляет отвлекаться от основного занятия, когда заканчивается серия), взвесив все плюсы и минусы и посмотрев на исходный код страниц с видео, я понял, что в большинстве своем, они не сильно отличаются, и возможностей bash вполне достаточно, для реализации родившейся идеи — всё, что требуется для получения со страницы ссылки на видео — подобрать необходимые регулярные выражения и разобрать полученные wget-ом данные с помощью стандартных команд, таких как grep, sed и tr.
Получение Видео
Первой, да и, наверное, единственной проблемой стала необходимость авторизации в контакте, для получения большинства страниц. С помощью wget не было найдено возможности воспользоваться cookies из браузера и, из-за этого возникла необходимость предварительного создания файла с cookies непосредственно для wget:
wget -O- -q --save-cookies .vk-cookie.txt "http://vk.com/login.php?act=login&email=$mail&pass=$pass" >>/dev/null
Дальнейшее казалось не очень сложным — найти закономерность и фразы от которых можно оттолкнуться и, воспользовавшись возможностями редактора sed, получить ссылку на видео. Но и здесь поджидали некоторые проблемы: одной из самых больших неожиданностей стало различие в получаемых значениях в таких случаях как
echo "/me/" | sed "s///\//"g>>var echo "/me/" | sed s/'/'/'\/'/g >>var var=`echo "/me/" | sed s/'/'/'\/'/g` var=`echo "/me/" | sed s#'/'#'\/'#g` var=`echo "/me/" | sed "s///\//"g`
В первом и третьем случае — команда не выполняется, сообщая о синтаксической ошибке в где-то в середине строки. В пятом случае команда ничего не выполняет никаких действий с передаваемой строкой. И только воспользовавшись вторым и четвертым вариантами — мы получим желаемый результат( замену "/" на "/").
Перед добавлением файла в плейлист или его скачиванием необходимо было реализовать проверку на его наличие на сервере — что было очень просто сделать при помощи стандартных возможностей wget:
wget --spider $addr >>/dev/null # checking if [ $? -ne 0 ]; then #if file not exist else fi
Собрав это все вместе, я получил не очень сложный скрипт, для просмотра видео. Но для добавления каждого файла необходимо было
- Скопировать ссылку на него
- Открыть консоль
- Вызвать скрипт
- Передать ему ссылку
- Выбрать действия с файлом(сохранить/проиграть)
Не самое короткая последовательность действий, особенно. когда добавляешь целый сезон какого-нибудь сериала. Поэтому, немного подумав, я сел искать возможности по облегчению процесса, без его существенного усложнения.
Упрощение процесса
Первым пунктом в этом стало использование очень полезной утилиты xsel, которая позволяет обращаться к буферу системы. Так команда была сокращена от «vkvid http ://csNNNNNN.vk.com/uNNNNNN/video/nnnnnnnnn.mov», где всегда присутствовала необходимость менять ссылку, до постоянной vkvid "$(xsel -o)", которую можно было брать из истории команд не задумываясь.
Графический интерфейс
Следующим, вполне ожидаемым шагом, стало добавление какого-никакого, а GUI. Сложные варианты даже не рассматривались, так как для них, было бы необходимо переписывать основную часть скрипта. Поэтому, после непродолжительного поиска, были найдены несколько вариантов: Xdialog и более широкий в плане возможностей Zeniti.
Но ни один, ни другой не позволяют реализовывать хоть сколько-нибудь сложные окна, считающие в себе несколько вариантов выбора, как, например, Radiobutton, checklist и текстовая форма.
Поэтому, поиск был продолжен, пока не был найден еще один вариант GUI для Bash-скриптов — YAD. Этот еще довольно молодой, развивающийся проект почти полностью подходил для поставленной задачи.
Создание не утяжеленного ничем лишним окна не отняло много времени:
action=$(yad --center --width=400 --title="Vkvideo Save" --text="Simple video downloader" --form --field="Select Resolution::CB" --field="Name" --field="Folder:DIR" --field="Keep Cookies:CHK" "720!480!360!240" "$tname" "$HOME" TRUE --button="Open File:2" --button="Save File:0" --button="gtk-cancel:1")
Результат выполнения формы — это строка разделенная "|", в разборке которой опят же пригодился редактор sed.
tres=`echo $action | sed -e s/'|.*|'/''/` tname=`echo $action | sed -e s/"$tres"'|'/''/ | sed -e s/"|.*"/''/` tfolder=`echo $action | sed -e s/"$tres"'|'"$tname"'|'/''/ | sed -e s/"|.*"/''/`
Как дополнительный бонус, очень простой оказалась реализация процесса загрузки файла при скачивании файла. В Zeniti и очень похожем на неё Yad для этого потребовалась всего одна строчка
wget $addr -O "$tfolder/$tname.$tres.mov" 2>&1 |sed -u 's/.* ([0-9]+%) +([0-9.]+.) (.*)/1n# Downloading at 2/s, time left: 3/'| yad --width=500 --center --title="Downloading progress" --text="Downloading '$tname.$tres.mov' " --progress --auto-close --auto-kill &
После написания, команда была прикреплена к сочетанию клавиш на клавиатуре. Таким образом, количество операций, необходимых для добавления файла, сократилось до 2-х:
- Скопировать ссылку из поиска видео Vkontakte
- Нажать сочетание клавиш и выбрать сохраниение или добавление в playlist
Для корректной работы необходимы:
- enco
- YAD
- Player — написано для двух вариантов — SMPlayer и VLC
Код:
#!/bin/bash #$1 link name #$2 resolution #$3 save file name #checking for existing cookies res=(720 480 360 240) tadr=$1 tres=$2 tname=$3 if [ -z "$tres" ]; then echo "$tres" tres=720 fi if [ ! -f "$HOME/.vk-cookie.txt" ]; then action1=$(yad --center --title="Lost cookies" --text="You need to enter mail and password" --form --field='Mail' --field='Password':H --button="gtk-ok:0" --button="gtk-cancel:1") mail=`echo $action1 | sed -e s/'|.*|'/''/` password=`echo $action1 | sed -e s/"$mail|"/''/ | tr -d '|'` echo "Getting cookies" wget -O- -q --save-cookies .vk-cookie.txt "http://vk.com/login.php?act=login&email=$mail&pass=$pass" >>/dev/null echo "Cookies saved" fi while [ "$SoD" != "finishdone" ] do echo "Page downloading...." LANG=ru_RU.CP1251 wget -q --load-cookies .vk-cookie.txt "$tadr" -O .tempf #download the page echo "Page resived" enconv -x=UTF-8 -L ru .tempf grep -i ltag .tempf| egrep -o "http:\/\/cs[0-9]*.vkontakte.ru\/[a-z][0-9]*\/"| sed -e s/'http:\/\/cs'/'http://cs'/ | sed -e s/'vkontakte.ru\/'/'vk.com/'/| sed -e s/'\'/''/ >> .tempama #get server and owner names echo video/>> .tempama if [ "$tname" == "" ]; then #echo `cat .tempf` egrep -o "md_title.*md_author" .tempf | sed -e s/'md_title\":\"'/''/ |sed -e s/'\",\"md_author.*'/''/>>.tempnam tname=`cat .tempnam` echo "tname=$tname" rm .tempnam fi addr=`cat .tempama` addr=`echo $addr | tr -d ' '` if [ $addr == "video/" ]; then tadr=$(yad --width 500 --center --title="Bad adress" --text="Bad adress. Reenter please" --entry) rm .tempama rm .tempf else SoD=finishdone fi done echo "Ready for downloading" action=$(yad --center --width=400 --title="Vkvideo Save" --text="Simple video downloader" --form --field="Select Resolution::CB" --field="Name" --field="Folder:DIR" --field="Keep Cookies:CHK" "720!480!360!240" "$tname" "$HOME" TRUE --button="Open File:2" --button="Save File:0" --button="gtk-cancel:1") SO=$? tres=`echo $action | sed -e s/'|.*|'/''/` tname=`echo $action | sed -e s/"$tres"'|'/''/ | sed -e s/"|.*"/''/` tfolder=`echo $action | sed -e s/"$tres"'|'"$tname"'|'/''/ | sed -e s/"|.*"/''/` echo $tfolder | sed "s$/$\/$"g>>tvar tvar=`cat tvar` keep=`echo $action | sed -e s/"$tres"'|'"$tname"'|'"$tvar"'|'/''/ | tr -d '|'` rm tvar grep -i ltag .tempf| egrep -o 'vtag\":\"[a-z0-9]*\'| sed 's/vtag\":\"//'|sed -e s/'\'/'.'"$tres"'.mov'/ >>.tempam #get video file name addr=`cat .tempama .tempam` #recover full link addr=`echo $addr | tr -d ' '` #remove spaces rm .tempama rm .tempam rm .tempf case $keep in TRUE) ;; FALSE) rm $HOME/.vk-cookie.txt;; esac case $SO in 0) wget --spider $addr >>/dev/null if [ $? -ne 0 ]; then rm "$tname.$tres.mov" for ((i=0; i <= 3 ; i++)) do if [ $i -ne 0 ];then let "j = $i - 1" else j=0; fi if [ ${res[$i]} -le $tres ]; then addr=`echo $addr | sed -e s/"${res[$j]}"/"${res[$i]}"/` if [ ${res[$i]} -ne $tres ];then wget --spider $addr >>/dev/null if [ $? -eq 0 ]; then RtD=2 tres=${res[$i]} i=10 fi fi fi done else RtD=1 fi wget $addr -O "$tfolder/$tname.$tres.mov" 2>&1 |sed -u 's/.* ([0-9]+%) +([0-9.]+.) (.*)/1n# Downloading at 2/s, time left: 3/'| yad --width=500 --center --title="Downloading progress" --text="Downloading '$tname.$tres.mov' " --progress --auto-close --auto-kill & trun=0 while [ $trun -eq 0 ] do if [ -z "$(pidof yad)" ] && [ ! -z "$(pidof wget)" ] then pkill wget trun=1 rm $tname.$tres.mov fi if [ -z "$(pidof wget)" ] then trun=1 case $RtD in 2) echo "Resolutuion change. File "$tname"."$tres".mov successfully saved" yad --center --text-align=center --height=25 --title="File Saved" --no-buttons --timeout=8 --text="Resolutuion change. File $tname.$tres.mov successfully saved";; 1) yad --center --text-align=center --height=25 --title="File Saved" --no-buttons --timeout=8 --text="File $tname.$tres.mov successfully saved" echo "File "$tname"."$tres".mov successfully saved";; esac i=10; fi sleep 1 done;; # downlodaing 2) wget --spider $addr >>/dev/null # checking if [ $? -ne 0 ]; then for ((i=0; i <= 3 ; i++)) do if [ $i -ne 0 ];then let "j = $i - 1" else j=0; fi if [ ${res[$i]} -le $tres ]; then addr=`echo $addr | sed -e s/"${res[$j]}"/"${res[$i]}"/` if [ ${res[$i]} -ne $tres ];then wget --spider $addr >>/dev/null # checking if [ $? -eq 0 ]; then i=10; fi fi fi done fi echo "Playing file" echo "$tname" vlc --started-from-file --playlist-enqueu "$addr" & #for VLC #smplayer -minigui -add-to-playlist $addr & #for SMPlayer sleep 5 echo "File is playing";; esac exit
Автор: Xanfer