View Single Post
gogol's Avatar
Posts: 177 | Thanked: 57 times | Joined on Aug 2007 @ Washington State, USA
#8
Another update.
Uses wget now, much faster.
Updated the handling of odd characters to fix stuff I was coming across.
-d debug switch actually works now.
removed all the iFilm and ffmpeg stuff.
You only need wget to use this script! perl is installed, no other dependencies..
Again, the basic premise is:
1 go to youtube and browse.
2 when you find a movie you are interested in, right-click and bookmark the link.
3 once you have all you want, drop to the shell and run the script.
4 open up mplayer on the train/bus/right now and watch!

Code:
#!/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();

Last edited by gogol; 2007-08-18 at 05:27.