#!/usr/bin/perl # Filename: myfilm # Original Author: David Ljung Madison <DaveSource.com> # See License: http://MarginalHacks.com/License/ # Description: For use with the Nokia 770. The basic idea is to # browse youtube and bookmark videos you are interested in. # Drop to osso-xterm and run the script to batch download! my $VERSION= '1.02'; # # Requires that youtube's obfuscation doesn't change drastically. # # youtube: http://youtube.com/watch?v=[video_id] # video at: http://youtube.com/get_video.php?l=165&video_id=[video_id]&t=[??] # Need to find &t=[c0de] in HTML # # # Also see: http://javimoya.com/blog/youtube_en.php ################################################## # CHANGELOG ################################################## # 2007/8/16 # ---------------- # Haxxed for the 770 by gogol. Somebody with # better perl skillz should really clean it up! # # 1.02 2006/05/13 # ---------------- # + Updated for new youtube obfuscation (&t=[c0de]) # # 1.01 2006/04/08 # ---------------- # + Released as myfilm # + Now handles youtube as well as iFilm # # 1.00 2005/12/08 # ---------------- # + Released as diFilm # ################################################## #use strict; ################################################## # Setup the variables ################################################## my $PROGNAME = $0; $PROGNAME =~ s|.*/||; my ($BASENAME,$PROGNAME) = ($0 =~ m|(.*)/(.+)|) ? ($1?$1:'/',$2) : ('.',$0); # This will probably change.. my $YOUTUBE = "http://youtube.com/get_video.php?l=165&video_id="; # How to fetch web files - pick one # Actual Safari agent example: # Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/416.12 (KHTML, like Gecko) Safari/416.13 my $GET = "GET --header 'user agent: Mozilla/4.0 (compatible; MSIE 6.0; ; Linux armv5tejl; U) Opera 8.02 [en_US] Maemo browser 0.4.34 N770/SU-18' "; my $wgetter = "wget -O -"; my $GET_URL = $wgetter; #default save dir for youtube my $defdir = "/home/user/MyDocs/.videos"; #note no trailing slash #bookmarks are where? my $BMARKS = "/home/user/.bookmarks/MyBookmarks.xml"; ################################################## # Usage ################################################## sub fatal { foreach my $msg (@_) { print STDERR "[$PROGNAME] ERROR: $msg\n"; } exit(-1); } sub usage { foreach my $msg (@_) { print STDERR "ERROR: $msg\n"; } print STDERR <<USAGE; Usage:\t$PROGNAME [-d] <youtube url> Download an ifilm movie -o <file> Save to file -bw <56,200,300> Force a bandwidth other than your iFilm settings -d Set debug mode -s Scan /home/user/.bookmarks/MyBookmarks.xml for youtube video links. It will then download any that don't already exist in ~/MyDocs/.videos USAGE exit -1; } sub parse_args { my $opt = {}; while (my $arg=shift(@ARGV)) { if ($arg =~ /^-s$/) {$opt->{bmfile} = 1; next;} if ($arg =~ /^-h$/) { usage(); } if ($arg =~ /^-d$/) { $MAIN::DEBUG=3; next; } if ($arg =~ /^-bg$/) { $opt->{bg} = 1; next; } if ($arg =~ /^-bw$/) { $opt->{bw} = shift @ARGV; next; } if ($arg =~ /^-o$/) { $opt->{save} = shift @ARGV; next; } if ($arg =~ /^-/) { usage("Unknown option: $arg"); } if ($arg =~ m|^http://([^/]+)/.*?([^/]+)$|) { ($opt->{url}, $opt->{dom}, $opt->{film}) = ($arg, $1, $2); next; } usage("Unknown film id. I need an iFilm or youtube URL"); } usage("No film URL specified.") unless $opt->{film} || $opt->{bmfile}; $opt; } sub debug { return unless $MAIN::DEBUG; foreach my $msg (@_) { print STDERR "[$PROGNAME] $msg\n"; } } ################################################## # Deobfuscation ################################################## sub title_embed { my ($opt, $url) = @_; debug("URL: $url"); my $open = "$GET_URL $url"; debug("GET: $open"); open(FILM,"$open |") || usage("Couldn't get URL: $url\nMake sure [$GET_URL] is installed"); # Find the film location my $dl; my $title; my $bw = $opt->{bw}; my $embed; my $and_t; while(<FILM>) { $dl = $1 if /var\s+dl\s*=\s*"?(-?\d+)"?/; $bw = $1 if !$bw && /var\s+bw\s*=\s*"?(\d+)"?/; $embed = $1 if /<embed.*(http:[^>"]+)/i; $title = $1 if /span class="title">([^<]+)/; $title = $1 if /<title>(.*)<\/title>/; $and_t = $1 if /video_id=.*&t=([^&"]+)/; } close(FILM); ($title,$embed,$dl,$bw,$and_t); } ################################################# #Bookmark Parsing ################################################# sub getbookmarks { open BMARKS, "<$BMARKS" or die "Can't open bookmarks for reading: $!"; while (<BMARKS>) { chomp; if ($_ = m|(http://(?:www\.)?youtube\.com/watch\?v=[^"]+)|i){ push @youtube_vids, $1; } } print "Found ",($#youtube_vids + 1)," bookmarked videos:\n"; while ($ourcount < ($#youtube_vids+1) ) { print "$ourcount : $youtube_vids[$ourcount]\n"; if ($MAIN::DEBUG == "3") { @args = ($PROGNAME, "-d", $youtube_vids[$ourcount]); } else { @args = ($PROGNAME, $youtube_vids[$ourcount]); } print "$args[0] $args[1] $args[2]\n"; $ourcount++; system(@args) == 0 or die "failed: $!\n"; } } ################################################## # youtube ################################################## sub youtube { my ($opt, $film) = @_; print STDERR "Fetching youtube ID: $film\n"; # Get name my ($save,undef,undef,undef,$and_t) = title_embed($opt, $opt->{url}); fatal("No '&t=' code found for youtube [$opt->{url}]") unless $and_t; if ($opt->{save}) { $save = $opt->{save}; } else { fatal("No title found for youtube [$opt->{url}]") unless $save; $save =~ s/youtube( - )?(.+)/$2/ig; print STDERR "Found film '$save'\n"; $save =~ s/[:\s]+/_/g; } $save =~ s/(\.flv)?$/.flv/; $save =~ s|/|_of_|g; $save =~ s/[\*\?\'\"\&\,]//g; # Get rid of troublesome characters.. $save =~ s/\(//g; $save =~ s/\)//g; #..including parentheses. debug("save: $save"); # Get video my $video = $YOUTUBE.$film."&t=$and_t"; debug("Video: $video"); $filename = join "/", $defdir, $save; debug("filename: $filename"); if (-e $filename) { print "File $defdir/$save already exists, skipping.\n"; #WOW the bookmarks xml SUCKS. Eventually we'll delete old links... #open BMARKS, "<$BMARKS"; @all = <BMARKS>; #foreach (@all) { #if(m|$film|i) { print; $_ = ""; print "Erased bookmark to already downloaded file.\n";} #} #open BMARKS, ">$BMARKS"; #foreach(@all) { # #print; # } #return; } print "Saving to: $defdir/$save\n"; system("$GET_URL \Q$video\E > $filename"); } ################################################## # Main code ################################################## sub main { my $opt = parse_args(); if ($opt->{dom} =~ /youtube/i) { $opt->{film} = "watch?v=$opt->{film}" if $opt->{url} =~ s|www.youtube.com/v/|www.youtube.com/watch?v=|; usage("Couldn't find youtube video (URL must contain 'v=[video_id]')") unless $opt->{film} =~ /v=([a-z0-9_-]+)/i; return youtube($opt, $1); } if (defined $opt->{bmfile}) {&getbookmarks;} } main();