📜 ⬆️ ⬇️

Bash-script with gui for playing video from Vkontakte in a regular player

Often, doing my own thing, I like to open some movies / clips / series that do not require any attention, hanging the player somewhere in the corner of the screen. In our age of fast Internet and a large number of free videos on social networks (for example, Vkontakte), it is in many ways convenient to watch them in the stream without cluttering up the hard disk with unnecessary files ... But, trying to implement the scheme described above, we are faced with the fact that the browser window hangs with player "somewhere" in the corner of the screen so as to do something useful, no longer distracting video playback, is not so simple. In addition, flash usually eats more resources than a regular player in the system, which is somewhat critical for low-power netbooks.

Therefore (and also because there is no playlist in the Vkontakte player, and this makes it distracting from the main occupation when the series ends), after weighing all the pros and cons and looking at the source code of the video pages, I realized that for the most part, they are not are very different, and bash is quite enough to implement a born idea — all that is required to get a link to a video from a page is to pick up the necessary regular expressions and parse the data obtained by wget using standard commands such as grep, sed and tr.

Getting Video

The first, and, probably, the only problem was the need for authorization in the contact, to get the majority of pages. Using wget, it was not possible to use cookies from the browser and, because of this, it became necessary to create a file with cookies directly for wget:

wget -O- -q --save-cookies .vk-cookie.txt "http://vk.com/login.php?act=login&email=$mail&pass=$pass" >>/dev/null

Further it seemed not very difficult to find patterns and phrases from which you can push off and, using the capabilities of the sed editor, get a link to the video. But here, too, some problems were waiting: one of the biggest surprises was the difference in the values ​​obtained in such cases as
')
 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` 
In the first and third cases, the command is not executed, reporting a syntax error somewhere in the middle of the line. In the fifth case, the command does nothing with the string being transmitted. And only using the second and fourth options - we get the desired result (replacing "/" with "\ /").
Before adding a file to the playlist or downloading it, it was necessary to implement a check for its presence on the server - which was very easy to do with the standard wget features:
 wget --spider $addr >>/dev/null # checking if [ $? -ne 0 ]; then #if file not exist else fi 


Putting it all together, I got a not very complicated script to watch the video. But to add each file was necessary
  1. Copy link to it
  2. Open console
  3. Call the script
  4. Send him a link
  5. Select file actions (save / play)

Not the shortest sequence of actions, especially. when you add the whole season of some series. Therefore, after some thought, I sat down to look for opportunities to facilitate the process, without its substantial complication.

Process simplification


The first point was the use of a very useful utility xsel , which allows you to access the system buffer. So the team was shortened from “vkvid http: //csNNNNNN.vk.com/uNNNNNN/video/nnnnnnnnnnn.mn”, where there was always a need to change the link, to the constant vkvid "$ (xsel -o)", which could be taken from team history without thinking.

Graphical interface

The next, quite expected step was the addition of some kind, and a GUI. Difficult options were not even considered, since for them it would be necessary to rewrite the main part of the script. Therefore, after a brief search, several options were found: Xdialog and wider in terms of Zeniti capabilities.

But neither one nor the other does not allow to implement at least some complicated windows that consider several options in themselves, such as Radiobutton, checklist and text form.

Therefore, the search was continued until another version of the GUI for Bash scripts was found - YAD . This still quite young, developing project was almost completely suitable for the task.

Creating a window that was not overloaded did not take much time:



 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") 

The result of executing the form is a string separated by "|", in disassembling which again the sed editor came in handy.

  tres=`echo $action | sed -es/'|.*|'/''/` tname=`echo $action | sed -es/"$tres"'|'/''/ | sed -es/"|.*"/''/` tfolder=`echo $action | sed -es/"$tres"'|'"$tname"'|'/''/ | sed -es/"|.*"/''/` 

As an added bonus, the implementation of the file upload process when downloading a file was very simple. In Zeniti and very similar to it Yad, it only took one line
  wget $addr -O "$tfolder/$tname.$tres.mov" 2>&1 |sed -u 's/.* \([0-9]\+%\)\ \+\([0-9.]\+.\) \(.*\)/\1\n# Downloading at \2\/s, time left: \3/'| yad --width=500 --center --title="Downloading progress" \ --text="Downloading '$tname.$tres.mov' " --progress --auto-close --auto-kill & 


After writing, the command was attached to a keyboard shortcut. Thus, the number of operations required to add a file has been reduced to 2:
  1. Copy link from Vkontakte video search
  2. Press the key combination and select to save or add to the playlist


For correct work you need:


Code:
 #!/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 -es/'|.*|'/''/` password=`echo $action1 | sed -es/"$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 recieved" enconv -x=UTF-8 -L ru .tempf grep -i ltag .tempf| egrep -o "http:\\\/\\\/cs[0-9]*.vkontakte.ru\\\/[az][0-9]*\\\/"| sed -es/'http:\\\/\\\/cs'/'http:\/\/cs'/ | sed -es/'vkontakte.ru\\\/'/'vk.com\/'/| sed -es/'\\'/''/ >> .tempama #get server and owner names echo video/>> .tempama if [ "$tname" == "" ]; then #echo `cat .tempf` egrep -o "md_title.*md_author" .tempf | sed -es/'md_title\\\"\:\\\"'/''/ |sed -es/'\\\"\,\\\"md_author.*'/''/>>.tempnam tname=`cat .tempnam|sed s#' | '#' '#g|sed s#'[|,/,\]'#' '#g|tr --squeeze-repeats ' '| tr '[]{}' '()()'|sed s#' \([(,)]\)'#'\1'#g|sed s#'\([(,)]\) '#'\1'#g` rm .tempnam fi addr=`cat .tempama` addr=`echo $addr | tr -d ' '` if [ $addr == "video/" ]; then tadr=$(yad --width 500 --center --title="Bad address" --text="Bad address. Reenter please" --entry --button="gtk-cancel:1" ) 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 -es/'|.*|'/''/` tname=`echo $action | sed -es/"$tres"'|'/''/ | sed -es/"|.*"/''/` tfolder=`echo $action | sed -es/"$tres"'|'"$tname"'|'/''/ | sed -es/"|.*"/''/` echo $tfolder | sed "s$\/$\\\/$"g>>tvar tvar=`cat tvar` keep=`echo $action | sed -es/"$tres"'|'"$tname"'|'"$tvar"'|'/''/ | tr -d '|'` rm tvar grep -i ltag .tempf| egrep -o 'vtag\\\"\:\\\"[a-z0-9]*\\'| sed 's/vtag\\\"\:\\\"//'|sed -es/'\\'/'\.'"$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 -es/"${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 rand="$RANDOM `date`" pipe="/tmp/pipe.`echo '$rand' | md5sum | tr -d ' -'`" mkfifo $pipe tdown=0 tnamesp=`echo "$tname" |tr -d '|'| tr ' ' '_'` wget -c $addr -O "$tfolder/$tnamesp.$tres.mov" 2>&1 | while read data; do if [ "`echo $data | grep '^Length:'`" ]; then total_size=`echo $data | grep "^Length:" | sed 's/.*\((.*)\).*/\1/' | tr -d '()'` fi if [ "`echo $data | grep '[0-9]*%' `" ];then percent=`echo $data | grep -o "[0-9]*%" | tr -d '%'` current=`echo $data | grep "[0-9]*%" | sed 's/\([0-9BKMG.]\+\).*/\1/' ` echo $percent echo "#Name: $tnamesp \nVideo size: $tres \nFrom: $1\n$current of $total_size ($percent%)\n" fi if [ "$current" != "$total_size" ];then tdown=fail fi done > $pipe & wget_info=`ps ax |grep "wget.*$addr" |awk '{print $1"|"$2}'` wget_pid=`echo $wget_info|cut -d'|' -f1 ` zenity --progress --auto-close --text="Connecting to $addr\n\n\n" --width="350" --title="Downloading"< $pipe if [ "`ps -A |grep "$wget_pid"`" ];then kill $wget_pid rm $tnamesp.$tres.mov tdown=fail fi rm -f $pipe if [ "$tdown" != "fail" ] then case $RtD in 2) echo "Resolution change. File "$tnamesp"."$tres".mov successfully saved" yad --center --text-align=center --height=25 --title="File Saved" --no-buttons --timeout=8 --text="Resolution change. File $tnamesp.$tres.mov successfully saved";; 1) yad --center --text-align=center --height=25 --title="File Saved" --no-buttons --timeout=8 --text="File $tnamesp.$tres.mov successfully saved" echo "File "$tnamesp"."$tres".mov successfully saved";; esac else yad --center --text-align=center --height=25 --title="ERROR" --no-buttons --timeout=8 --text="File $tname.$tres.mov has NOT been saved" fi;; 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 -es/"${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" & smplayer -minigui -add-to-playlist $addr & sleep 5 echo "File is playing";; esac exit 


UPD: The ease of implementation of the progress bar was somewhat exaggerated. Download GUI was disabled when the size of the saved part of the file exceeded 100 Mb. Therefore, with the help of Google and Ubuntuforums , minor adjustments were made:
 rand="$RANDOM `date`" pipe="/tmp/pipe.`echo '$rand' | md5sum | tr -d ' -'`" mkfifo $pipe wget -c $addr -O "$tfolder/$tname.$tres.mov" 2>&1 | while read data; do if [ "`echo $data | grep '^Length:'`" ]; then total_size=`echo $data | grep "^Length:" | sed 's/.*\((.*)\).*/\1/' | tr -d '()'` fi if [ "`echo $data | grep '[0-9]*%' `" ];then percent=`echo $data | grep -o "[0-9]*%" | tr -d '%'` current=`echo $data | grep "[0-9]*%" | sed 's/\([0-9BKMG.]\+\).*/\1/' ` echo $percent echo "#Name: $tname \nVideo size: $tres \nFrom: $1\n$current of $total_size ($percent%)\n" fi if [ "$current" != "$total_size" ];then tdown=fail fi done > $pipe & wget_info=`ps ax |grep "wget.*$addr" |awk '{print $1"|"$2}'` wget_pid=`echo $wget_info|cut -d'|' -f1 ` zenity --progress --auto-close --text="Connecting to $addr\n\n\n" --width="350" --title="Downloading"< $pipe 

UPD2: corrected a bug that manifests itself when saved, if the title contains special characters: [,], {.}, |

The full version of the code is fixed.

Source: https://habr.com/ru/post/138932/


All Articles