ВКонтакте / [Из песочницы] Bash-script с gui для проигрывания видео из Vkontakte в обычном плеере

в 10:41, , рубрики: bash, yad, видео, метки: , , ,

Часто, занимаясь своими делами, я люблю открыть какие-нибудь фильмы/клипы/сериалы, которые не требуют никакого внимания, повесив плеер где-нибудь в углу экрана. В наш век быстрого интернета и большого количества свободного видео в социальных сетях(например 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  

Собрав это все вместе, я получил не очень сложный скрипт, для просмотра видео. Но для добавления каждого файла необходимо было

  1. Скопировать ссылку на него
  2. Открыть консоль
  3. Вызвать скрипт
  4. Передать ему ссылку
  5. Выбрать действия с файлом(сохранить/проиграть)

Не самое короткая последовательность действий, особенно. когда добавляешь целый сезон какого-нибудь сериала. Поэтому, немного подумав, я сел искать возможности по облегчению процесса, без его существенного усложнения.

Упрощение процесса

Первым пунктом в этом стало использование очень полезной утилиты xsel, которая позволяет обращаться к буферу системы. Так команда была сокращена от «vkvid http ://csNNNNNN.vk.com/uNNNNNN/video/nnnnnnnnn.mov», где всегда присутствовала необходимость менять ссылку, до постоянной vkvid "$(xsel -o)", которую можно было брать из истории команд не задумываясь.

Графический интерфейс

Следующим, вполне ожидаемым шагом, стало добавление какого-никакого, а GUI. Сложные варианты даже не рассматривались, так как для них, было бы необходимо переписывать основную часть скрипта. Поэтому, после непродолжительного поиска, были найдены несколько вариантов: Xdialog и более широкий в плане возможностей Zeniti.

Но ни один, ни другой не позволяют реализовывать хоть сколько-нибудь сложные окна, считающие в себе несколько вариантов выбора, как, например, Radiobutton, checklist и текстовая форма.

Поэтому, поиск был продолжен, пока не был найден еще один вариант GUI для Bash-скриптов — YAD. Этот еще довольно молодой, развивающийся проект почти полностью подходил для поставленной задачи.

Создание не утяжеленного ничем лишним окна не отняло много времени:

ВКонтакте / [Из песочницы] Bash script с gui для проигрывания видео из Vkontakte в обычном плеере

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-х:

  1. Скопировать ссылку из поиска видео Vkontakte
  2. Нажать сочетание клавиш и выбрать сохраниение или добавление в 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

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js