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'