vp

git clone git://oldgit.suckless.org/vp/
Log | Files | Refs | README

commit 60f51219374592f565abe1aca79c855e9555c56f
Author: Kris Maglione <kris@suckless.org>
Date:   Sun, 15 Aug 2010 05:00:06 -0400

Initial checkin.

Diffstat:
.hgignore | 3+++
README | 36++++++++++++++++++++++++++++++++++++
config.mk | 3+++
mkfile | 41+++++++++++++++++++++++++++++++++++++++++
vp | 29+++++++++++++++++++++++++++++
vp-base | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vp-patterns | 6++++++
vp-revision3 | 20++++++++++++++++++++
vp-youtube | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vp-ytlogin | 16++++++++++++++++
10 files changed, 294 insertions(+), 0 deletions(-)

diff --git a/.hgignore b/.hgignore @@ -0,0 +1,3 @@ +test.html +config.local.mk +.*.sw? diff --git a/README b/README @@ -0,0 +1,36 @@ +This is a simple set of scripts to make it easy to play and +download videos from online video services. The main program, +vp, checks a given URL against a list of known video sites and +attempts to convert it to the URL of a video stream. If it +doesn't recognize the pattern, it assumes that it is an +ordinary media URL and procedes as normal. If no url is +provided, it is read from the X11 clipboard. It accepts the +following options: + + -e Echo the resulting URL and exit. + -f Fetch the resulting stream rather than playing + it. + -F Override the default video format. + -o <file> Output the stream to the given file rather than + guessing it automatically. + +The additional script vp-ytlogin should be run to login to +YouTube and enable access to age-restricted videos. + +Requirements: + 9base or plan9port + curl (in the default configuration) + +To install, edit config.mk or config.local.mk and run, + + 9 mk install + +Configuration is stored in $home/.config/vp.conf and can be +used to override the configuration values in vp-base. +Specialized configuration for any of the site-specific +subscripts can be placed in a function called +config-<script-name> where <script-name> is the name of the +sub-script. Additionally, most sub-scripts come with a set of +configuration variables which may be set directly. See the +individual sub-scripts for documentation. + diff --git a/config.mk b/config.mk @@ -0,0 +1,3 @@ +PREFIX = /usr/local +BIN = $PREFIX/$BIN + diff --git a/mkfile b/mkfile @@ -0,0 +1,41 @@ +MKSHELL=rc + +SUBSCRIPTS = \ + vp-revision3\ + vp-youtube\ + +SCRIPTS = \ + vp\ + vp-base\ + vp-patterns\ + $SUBSCRIPTS\ + +<config.mk +<`{test -f config.local.mk && echo config.local.mk || echo /dev/null} + +default:V: all +all:V: $SCRIPTS + +install:V: ${SCRIPTS:%=$BIN/%} + +uninstall:V: + rm -f ${SCRIPTS:%=$BIN/%} + +$BIN/%: % + cp -f $stem $target + chmod 0755 $target + +vp-patterns: $SUBSCRIPTS mkfile + { + cat <<'!' + for(s in $SUBSCRIPTS) { + sed 's,/,\\/,g' $s | + sed -n 's,.*Pattern: (.*), /\1/ { print "'$s'"; exits=0; exit },p' + } + echo '''}' + } >$target + fn vp_findscript { + echo $* | awk -v 'exits=1' ' + END { exit exits } + ! + diff --git a/vp b/vp @@ -0,0 +1,29 @@ +#!/usr/bin/env rc +. vp-patterns +. vp-base $0 $* + +vp_subscript = 1 +getflags 'e,f,F format,o output-file' +vp_format = $flagF + +vp_result = $argv(1) +vp_default vp_result `{vp_paste} +vp_orig = $vp_result + +if(vp_script = `{vp_findscript $vp_result}) + . $vp_script $vp_result + +if(! ~ $flage '') { + echo $vp_result + exit +} + +if(~ $flagf '') + vp_play $vp_result +if not { + if(~ $flago '') + flago = `{vp_autoname $vp_orig $vp_result}) + if(~ $flago '') $vp_hget_loud $vp_hget_autoname $vp_result + if not $vp_hget_loud >$flago $vp_result +} + diff --git a/vp-base b/vp-base @@ -0,0 +1,81 @@ + +vp_script=`{basename $1}; shift + +if(~ $vp_base_loaded '') { + vp_base_loaded=1 + + . 9.rc + fn vp_default { if (~ $$1 '') $1 = $2 } + + vp_default XDG_CONFIG_HOME $home ^ /.config + vp_default PLAYER mplayer + + args=$* + vp_cookie_jar=$XDG_CONFIG_HOME ^ /cookies.txt + vp_temppat=/tmp/vp.html.XXXXXX + vp_user_agent='Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2a1pre) Gecko/20081203 Firefox/3.2a1pre' + vp_vidtemp=$home ^ /vp-out.mpg + + vp_savevideo=() + + fn vp_checkmedia { /usr/bin/file -i $* | grep -s '(video|audio)/' } + + vp_hget_autoname=-OJ + vp_hget = (curl -L -b $vp_cookie_jar -c $vp_cookie_jar -A $vp_user_agent) + vp_hget_loud=($vp_hget '-#') + vp_hget_silent=($vp_hget -s) + + fn vp_paste { xsel -o || sselp } + fn vp_player { $PLAYER $* } + fn vp_autoname { true } + + # If you prefer: + # fn js { kjs /dev/stdin } + + # Plan 9's sed doesn't work with long lines + fn sed { /bin/sed -r $* || /usr/bin/sed -E $* } + + fn vp_data { + if (~ $1 '') cat + if not $vp_hget_silent $1 + } + fn vp_getdata { + data=`{mktemp $vp_temppat} + $$1 = $data + vp_data $1 >data + } + + fn getflags { + ifs=() flagfmt=$"* { eval `{builtin getflags $args; echo ';argv=$*'} } + } + + fn vp_play { + hget = () + if(test -n $"vp_need_cookies -a -z $"vp_have_player_cookies) + vp_savevideo = $vp_vidtemp + if(test -n $"vp_savevideo) { + $vp_hget_silent $1 >$vp_savevideo & + hget = $apid + * = $vp_savevideo + while(! vp_checkmedia $vp_savevideo) + sleep 1 + } + vp_player $* + if(test -n $"hget) + kill $hget + } + + fn vp_result { + if(~ $vp_subscript '') + echo $* + if not + vp_result = $* + } + + config=$XDG_CONFIG_HOME ^ /vp.conf + test -f $config && . $config +} + +if (rc -c 'which config-' ^ $vp_script >/dev/null >[2=1]) + config- ^ $vp_script + diff --git a/vp-patterns b/vp-patterns @@ -0,0 +1,6 @@ +fn vp_findscript { + echo $* | awk -v 'exits=1' ' + END { exit exits } + /^http:\/\/revision3.com\// { print "vp-revision3"; exits=0; exit } + /^http:\/\/(www\d*\.)?youtube\.com\/(v\/|(watch(\.php|_videos)?))(\?|#!|#%21)/ { print "vp-youtube"; exits=0; exit } +'} diff --git a/vp-revision3 b/vp-revision3 @@ -0,0 +1,20 @@ +#!/usr/bin/env rc +# +# Pattern: ^http://revision3.com/ +# +# Formats: +# hd.h264 MP4 High Definitiond +# hd720p30.h264 MP4 High Definition (30fps) +# large.h264 MP4 Larged +# small.h264 MP4 Smalld +# large.wmv9 WMV Larged +# small.wmv9 WMV Smalld +# large.xvid Xvid Larged +# small.xvid Xvid Smalld + +vp_revision3_formats = (hd.h264) + +. vp-base $0 $* + +vp_result `{vp_data $* | sed -n -e's/.*href="([^"]*--' ^ $vp_revision3_formats ^ '\.[^"]*).*/\1/p' | sed 1q} + diff --git a/vp-youtube b/vp-youtube @@ -0,0 +1,59 @@ +#!/usr/bin/env rc +# +# Pattern: ^http://(www\d*\.)?youtube\.com/(v/|(watch(\.php|_videos)?))(\?|#!|#%21) +# +# Formats: +# Resolution Ext Video / Audio Rate Title +# 0: 320x240 flv (flv1) / mp3 22KHz +# 5: 320x240 flv (flv1) / mp3 22KHz "Small" +# 13: 176x144 3gp (H263) / AMR 8KHz +# 17: 176x144 3gp (mpg4) / AAC 22KHz +# 18: 480x360 mp4 (H264) / AAC 44KHz "Large" +# 22: 1280x720 mp4 (H264) / AAC 44KHz "HD720" +# 34: 640x480 flv (H264) / AAC 44KHz "Medium" (default) +# 35: 854x640 flv (H264) / AAC 44KHz "Large" +# 36: 320x240 3gp (mpg4) / AAC 22KHz +# 37: 1920x1080 mp4 (H264) / AAC 44KHz "HD1080" +# 43: 480x360 webm (VP8 ) / Vorbis "Medium" +# 45: 1280x720 webm (VP8 ) / Vorbis "HD720" + +vp_youtube_formats = '22, 45, 18, 35, 34, 5' +vp_need_cookies = 1 + +. vp-base $0 $* + +vp_getdata data `{echo $"* | sed 's/#(!|%21)v=/?v=/'} + +swfargs=`{ { echo ""; sed <$data -n 's/.*flashvars=\\"(([^\\]|\\[^"])+).*/"\1"/p' } | tail -1 } +formats=`{ sed <$data -n 's/.*setAvailableFormat\((.*)\);.*/[\1],/p' } +rm $data + +vp_result `{ cat <<! | js } + function safe(fn) { + return function () { try { return fn.apply(null, arguments) } catch(e) { return null } } + } + function dict(ary) { + var obj = {}; + ary.forEach(function (item) { obj[item[0]] = item[1]; }); + return obj; + } + function params(s, l1, l2) { + return dict(s.split(l1 || "&").map( + function(s) { return s.split(l2 || "=", 2).map(safe(decodeURIComponent))} )); + } + + var swfargs = params($swfargs); + var fmt_url_map = params(swfargs.fmt_url_map || "", ",", "|"); + [$formats].forEach(function (a) { + fmt_url_map[a[3]] = a[0]; + }); + + var fmts=[$vp_format].concat([$vp_youtube_formats]); + fmts.forEach(function (f) { + if(f in fmt_url_map) { + print(fmt_url_map[f]); + quit(); + } + }); +! + diff --git a/vp-ytlogin b/vp-ytlogin @@ -0,0 +1,16 @@ +#!/usr/bin/env rc + +echo -n 'User: '; user=`{read} +stty -echo +echo -n 'Pass: '; pass=`{read}; echo +stty echo + +curl >/dev/null 'http://www.youtube.com/signup?next=/&gl=US&hl=en' \ + -F'current_form=loginForm' \ + -F'next=/' \ + -F'action_login=Log In' \ + -F'username='$"user \ + -F'password='$"pass +curl >/dev/null 'http://www.youtube.com/verify_age?next_url=/&gl=US&hl=en' \ + -F'next_url=/' \ + -F'action_confirm=Confirm'