#!/usr/bin/perl # Universal Streamer v0.2.5 # # A command line tool to stream videos, # from embed flash players, with MPlayer # # Coded by Trizen under the GPL. # http://trizen.go.ro # Latest edit on 15 April 2012 # Email: echo dHJpemVueEBnbWFpbC5jb20K | base64 -d use strict; my $bred = "\e[1;31m"; my $bgreen = "\e[1;32m"; my $reset = "\e[0m"; my $download = 0; my $videos_to_play = 0; my $videos_counter = 0; my $cache = 15000; my $cache_min = 3; my $lower_cache = 2500; my $lower_cache_min = 2; my $no_video = 0; my $fullscreen = 0; sub help { print "usage : universal-streamer \noptions: \t-d, -download : save video to disk \t-[number] : how many videos to play (ex: -1 means 1) \t-n, --novideo : play only the audiotrack of videos \t-l, -lower-cache : set a lower cache for MPlayer ($lower_cache; $lower_cache_min) \t-cache= : set cache value for MPlayer (default: $cache) \t-cache-min= : set minim cache value for MPlayer (default: $cache_min) \t-mplayer= : add some extra options for mplayer\n\n"; exit 0; } foreach my $arg (@ARGV) { next unless chr ord $arg eq '-'; if ($arg =~ /^-+(?:h|help|usage|\?)$/) { help; } elsif ($arg =~ /^-+(?:d|download)$/) { $download = 1; } elsif ($arg =~ /^-+(\d+)/) { $videos_to_play = $1; } elsif ($arg =~ /^-+cache=(\d+)/) { $cache = $1; } elsif ($arg =~ /^-+(?:l|lower.?cache)$/) { $cache = $lower_cache; $cache_min = $lower_cache_min; } elsif ($arg =~ /^-+cache.?min=(\d+)/) { $cache_min = $1; } elsif ($arg =~ /^-+(?:n|no.?video)$/) { $no_video = 1; } elsif ($arg =~ /^-+(?:fs?|fullscreen)$/) { $fullscreen = 1; } } my $mplayer_settings = "-prefer-ipv4 -cache $cache -cache-min $cache_min"; my $MPlayerLine; if ($^O eq 'MSWin32') { my $MPlayer_exe = $ENV{'ProgramFiles'} . '\\SMPlayer\\mplayer\\mplayer.exe'; unless (-e $MPlayer_exe) { warn "\n\n!!! Please install SMPlayer to stream videos.\n\n"; } $MPlayerLine = qq["$MPlayer_exe" $mplayer_settings]; } else { $MPlayerLine = "mplayer $mplayer_settings"; } if ($no_video) { $MPlayerLine =~ s/mplayer /mplayer -novideo /; $MPlayerLine =~ s/mplayer\.exe"/mplayer.exe" -novideo/; } if ($fullscreen) { $MPlayerLine =~ s/mplayer /mplayer -fs /; $MPlayerLine =~ s/mplayer.exe"/mplayer.exe" -fs/; } foreach my $arg (@ARGV) { next unless chr ord $arg eq '-'; if ($arg =~ /^-+(?:T|tty|M|mplayer)=(.+)/) { $MPlayerLine .= " $1"; last; } } unless (scalar @ARGV) { print $bgreen . "\n$bred=>>$reset ${bgreen}Insert an URL (youtube, break, vimeo, bofunk, ...)\n>$reset "; chomp(my $url = ); $url =~ s/%3D/=/g; push @ARGV, $url; } require LWP::UserAgent; my $lwp = 'LWP::UserAgent'->new('env_proxy' => 1); sub get_vimeo { my $vimeo_id = shift(); $lwp->agent('NaN'); my ($title, $timestamp, $request_signature, $isHD); foreach my $line (split(/\n/, $lwp->get("http://www.vimeo.com/moogaloop/load/clip:$vimeo_id")->content, 0)) { if ($line =~ m[^\s*(.+?)\s*$]) { $timestamp = $1; } elsif ($line =~ m[^\s*(.+?)\s*$]) { $request_signature = $1; } elsif ($line =~ m[^\s*(\d)\s*$]) { $isHD = $1; } } my $q = $isHD ? 'hd' : 'sd'; return "http://www.vimeo.com/moogaloop/play/clip:$vimeo_id/$request_signature/$timestamp/?q=$q"; } my $ok = 0; my $formats = qr/mp\d|f\wv|avi|wmv|mpe?g4?|mov|m4a|og\w+|mj\d|3gp/i; my $valid_url = qr{^ ################# This regex will validate an HTTP URL ################# https?:// # http or https followed by :// [[:alnum:]] # first character must be a-zA-Z0-9 (?:(?:(?:\w*-+\w+|\w+)* # words, dash, words OR only words \.(?=\w))+? # point if followed by word char | # OR (validates http://x.yz) \.) # a single dot \w{2,6} # domain (words between 2 and 6 chars) (?:[#/?!] # characters after domain [#-)+-;=?\\~\w]*)* # the rest characters of the string $}x; my ($urlbk, @parsed_urls, @youtube_codes); foreach my $url (@ARGV) { next if chr ord $url eq '-'; $url = "http://$url" unless $url =~ /^https?:/i; next unless $url =~ /$valid_url/o; print "\n=>> Loading URL: $url\n\n"; print $bgreen . "[...] Working... Please wait... $reset\n"; $urlbk = $url; my $content; unless ($url =~ m[\bvimeo\.com/\d+\b]i) { $lwp->agent('Mozilla/5.0 (Windows NT 5.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1'); $content = $lwp->get($url)->content; if (not $url =~ /\byoutu(?:be\.com|\.be)/i and $content =~ m[\byoutube\.com\S+?(?:v|embed)(?:[=/]|%3D)([\w\-]{11})]i) { push @youtube_codes, $1; $url = "http://www.youtube.com/watch?v=$1"; print "\n$bgreen** Found:$reset $url\n"; } } if ($content =~ /=http([^&'"]+)\.mp4([^&'"]+)\&/i) { $url = "http$1.mp4$2"; stream($url); } if ($url =~ m[(?:%3F|\b)(?:v|embed|youtu[.]be)(?:[=/]|%3D)([\w\-]{11})\b]i) { push @youtube_codes, $1; my $url = "http://www.youtube.com/get_video_info?&video_id=$1&el=detailpage&ps=default&eurl=&gl=US&hl=en"; if ($lwp->get($url)->content =~ /url_encoded_fmt_stream_map=([^&]+)&/i) { $url = $1; stream($url); } } if ($url =~ m[\bvimeo\.com/([\d]+)]i) { $url = get_vimeo($1); stream($url); } if ($content =~ /\bvimeo\.com[^&]+clip_id=(\d+)\b/i) { stream(get_vimeo($1)); } if ($content =~ /url="([^"]+?\.(?:$formats))"/io) { stream($1); } if ($content =~ /so\.addVariable\((['"])file(['"])\,(['"]{1})http([^']+)\.([\w]{3})([\W]+)/i) { $url = "http$4.$5"; stream($url); } if ($content =~ /\.swf\?(.*)videoUrl([\\\w]+)http:([^\\]+)/i) { $url = "http:$3"; stream($url); } if ($content =~ m[file:\s*['"]+(http://[^'"]+\.(?:$formats))['"]+]io) { stream($1); } if ($content =~ /=(http[^=]+\.(?:$formats))\%3F([^\&]+)/io) { stream("$1?$2"); } if ($url =~ /\bstupidvideos\.com\b/i and $content =~ /\bvideoID\s*=\s*['"]+([\d]+)/i) { my $id = $1; my $count = length $id; my $id1 = $id; if ($count == 5) { $id1 =~ s/^([\d]{1})(.+)/0$1/; } else { $id1 =~ s/^([\d]{2})(.+)/$1/g; } my $id2 = $id; if ($count == 5) { $id2 =~ s/^([\d]{1})([\d]{2})(.+)/$2/; } else { $id2 =~ s/^([\d]{2})([\d]{2})(.+)/$2/; } my $id3 = $id; $id3 =~ s/(.+)([\d]{2})$/$2/; stream("http://videos.stupidvideos.com/2/00/$id1/$id2/$id3/$id.flv"); } if ($url =~ /\b(tare|apropo)\.ro\b/i) { my $id; my $name = $1; if ($content =~ m[\bhttp://cache\.(?:tare|apropo)\.ro/(?:thumb/)?(\w+)]i) { $id = $1; } if ($content =~ /\?key=(\w+)/) { if ($lwp->get("http://cache.$name.ro/xml/playlist.xml/$1")->content =~ / url="([^"]+)" title="/i) { my $url = $1; $url =~ /^http/i ? stream($url) : stream("http://cache.$name.ro/$id$1"); } } } elsif ($content =~ m[(http://cache\.(?:tare|apropo)\.ro/\w+)]i) { stream($1); } if ($content =~ /=(http[^&'"]+\.(?:$formats)[^&'"]+)\&/io) { stream($1); } if ($content =~ /config=([^"&]+)\.xml\b/i) { if ($lwp->get("$1.xml")->content =~ /['"]([^"']+\.(?:$formats))\b/io) { stream($1); } } if ($content =~ m[get($url)->content =~ m[title=.+?\s+href=["'](/rss/flash/\d+)["']]s) { my $code = $1; my $rss_url = $url; $rss_url =~ s[^(https?://[^/]+).*][$1]; $rss_url .= $code; $content = $lwp->get($rss_url)->content; } } if ($url =~ m{\bvideolog\.tv/.*?id=(\d+)}i) { my $url = "http://embed-video.videolog.tv/api/player/video.php?id=$1&format=xml"; if ($lwp->get($url)->content =~ m{(\bhttps?://[^<>\[\]]+\.(?:$formats)\b[\w&=+-?.,/%]+)}i) { stream($1); } } if ($url =~ m{[./]cinemassacre\.com[/?]}i) { if ($lwp->get($url)->content =~ m{\bvalue="https?://.*?\b(\d+)/?"}) { stream("http://cinemassacre.springboardplatform.com/storage/cinemassacre/conversion/$1.mp4"); } } while ($content =~ m{"(https?://.*?\.(?:$formats)\b.*?)"}ig) { stream($1); } while ($content =~ m{'(https?://.*?\.(?:$formats)\b.*?)'}ig) { stream($1); } while ($content =~ /\b['"]?(http\S+?\.(?:$formats))\b/giop or $content =~ /\bvalue=["']+video[-_.]?URL=([^&]+)/gip) { substr $content, index($content, ${^MATCH}), length ${^MATCH}, ''; stream($1); } while ($content =~ m[\byoutube\.com\S+?(?:v|embed)(?:[=/]|%3D)([\w\-]{11})]gip) { next if $1 ~~ \@youtube_codes; push @youtube_codes, $1; substr $content, index($content, ${^MATCH}), length ${^MATCH}, ''; if ($lwp->get("http://www.youtube.com/get_video_info?&video_id=$1&el=detailpage&ps=default&eurl=&gl=US&hl=en")->content =~ /url_encoded_fmt_stream_map=([^&]+)&/) { stream($1); } } unless ($ok) { print "\n(x_x) There is no video to stream...\n\n=>> Should be added support for this website? (y/N)\n> "; my $yn = ; if ($yn =~ /^y/i) { print "\n[...] Submitting website...\n"; require HTTP::Cookies; my $cookie = 'HTTP::Cookies'->new; $lwp->cookie_jar($cookie); my $gb_url = 'http://www.freeguestbooks.org/guestbooks/sign/9788'; $lwp->agent('Opera/9.80 (X11; Linux i686; U; Edition Next; en) Presto/2.9.196 Version/12.00'); $lwp->get($gb_url)->content =~ /(\d+) + \d/; my $validation = $1 * 2; $lwp->post( $gb_url, ['data[Entry][guestbook_id]', '9788', 'data[Entry][name]', 'Universal Streamer', 'data[Entry][location]', 'Earth', 'data[Entry][homepage]', '', 'data[Entry][email]', 'anonymous_user@gmail.com', 'data[Entry][message]', "Required support for: $url", 'data[Entry][sum]', $validation, '', 'Sign' ] ); print "\n[*] Thank you! If it's possible, the support for '${url}' will be added in a short time...\n\n"; next; } next; } } sub stream { my $url = shift() // return; return if $url ~~ \@parsed_urls; if ($url =~ m{^(.+?)\.(?:$formats)\b(.*?)}i) { my $aprox_url = quotemeta $1; my $after = quotemeta $2; return if grep { /^$aprox_url\.(?:$formats)\b$after$/i; } @parsed_urls; } push @parsed_urls, $url; if ($url =~ /\byoutube\.com\b/i) { $url =~ s/^url%3D//; $url =~ s/%253A/:/gio; $url =~ s[%252F][/]gio; $url =~ s/%2526/&/go; $url =~ s/%253D/=/gio; $url =~ s/%253F/?/gio; $url =~ s/%25252C/,/gio; $url =~ s/%.*//; } $url =~ s/(.+)=http(.+)/http$2/; $url =~ s[http://http][http]gi; $url =~ s[%2f][/]gi; $url =~ s/%5C//gi; $url =~ s/%25/%/g; $url =~ s/%3a/:/gi; $url =~ s/%3D/=/gi; $url =~ s/%3F/?/gi; $url =~ s/%26/&/g; $url =~ s/\&/-TRIZEN-/; $url =~ s/^(.+)-TRIZEN-(.*)/$1/; $url =~ s/^[=]+//; if ($url =~ /\bbofunk\.com/i) { $url =~ s[http://([\\w\.]*)][http://media.]g; $url =~ s[video([^/]+)/(.)/][media/flvs/]g; $url =~ s[/(.)/][/media/flvs/]g; } unless ($url =~ /^https?:/i) { if ($urlbk =~ m[^(https?://[^/]+)]) { $url = $1 . "/$url"; } else { $url = "http://$url"; } } return unless $url =~ $valid_url; print $bgreen, "\n[*] ", $download ? 'Downloading' : 'Streaming', " URL:$reset $url\n"; if (not $download) { system "$MPlayerLine \Q$url\E"; } elsif ($download) { print "\n$bgreen** Choose a video name:$reset "; chomp(my $video_name = ); $video_name = 'Video name.flv' unless $video_name; if (not $url =~ /\bvimeo\.com\b/) { system "wget \Q$url\E -O \Q$video_name\E"; } else { $lwp->agent('NaN'); $lwp->show_progress(1); $lwp->mirror($url, $video_name); $lwp->show_progress(0); } } if ($? == 0) { $ok = 1; ++$videos_counter; exit if $videos_counter == $videos_to_play; } }