Este script sirve para descargar videos de YouTube por CLI ;)
Lo único que tienen que hacer es ejecutar el script y pasarle como argumento el ID del video, luego el script preguntará el formato y resolución y... listo!
Enjoy!
#!/usr/bin/perl
use strict;
use HTTP::Lite;
use Data::Dumper;
#####################################################
#
# Desarrollado por: Zort
# Fecha: 16 de Septiembre de 2011
#
# Descripcion:
# Este script descarga un video de YouTube especificado por
# el ID, el cual es entregado como parametro en la ejecucion.
# A su vez, es posible elegir el formato y la resolucion
# del video segun la disponibilidad de YouTube de entregar el
# video con dichas caracteristicas.
#
# Anexo:
# Se omitieron todos los acentos en el codigo, para que no se
# vean caracteres erroneos en el caso de que el equipo donde
# se corra este codigo permita ver solo caracteres gringos.
# Se ha detectado que en ciertas ocasiones no se descarga
# el video. En estos casos se debe intentar nuevamente.
#
#####################################################
my $debug = 0;
my $video_id = $ARGV[0];
die "Usage: $0 video_id\n\n" if ($video_id eq '');
my $http = HTTP::Lite->new;
$http->http11_mode(1);
my $req = $http->request("http://www.youtube.com/get_video_info?video_id=$video_id&eurl=http%3A%2F%2Flocalhost%2F&hl=en_US")
or die "Unable to get document: $!";
&showResponse($http) if ($debug);
if ($http->status() != 200) {
print "The return code is not valid!\n";
exit;
}
my $seconds = 0;
my $fmt_stream_map = '';
my $fmt_list = '';
my $title = '';
my $token = '';
my $formats = ();
my @infos = split(/&/, $http->body());
foreach my $info (@infos) {
my ($name, $value) = split(/=/, $info);
$seconds = $value if ($name eq 'length_seconds');
$fmt_stream_map = urlDecode($value) if ($name eq 'url_encoded_fmt_stream_map');
$fmt_list = urlDecode($value) if ($name eq 'fmt_list');
$title = urlDecode($value) if ($name eq 'title');
$token = $value if ($name eq 'token');
}
my @formats_list = split(/,/, $fmt_list);
foreach my $format_list (@formats_list) {
$format_list =~ /^([^\/]+)\/([^\/]+)\//;
$formats->{$1}->{'resolution'} = $2;
}
my @formats_map = split(/,/, $fmt_stream_map);
foreach my $format_map (@formats_map) {
my $url = '';
my $quality = '';
my $fallback_host = '';
my $type = '';
my $itag = '';
my @variables = split(/&/, $format_map);
foreach my $variable (@variables) {
my ($name, $value) = split(/=/, $variable);
$url = urlDecode($value) if ($name eq 'url');
$quality = urlDecode($value) if ($name eq 'quality');
$fallback_host = urlDecode($value) if ($name eq 'fallback_host');
$type = urlDecode($value) if ($name eq 'type');
$itag = $value if ($name eq 'itag');
}
$formats->{$itag}->{'url'} = $url;
$formats->{$itag}->{'quality'} = $quality;
$formats->{$itag}->{'fallback_host'} = $fallback_host;
$formats->{$itag}->{'type'} = $type;
}
print "Titulo: $title\n";
print "Formatos:\n";
foreach my $format (sort { $formats->{$a}->{'type'} cmp $formats->{$b}->{'type'} } keys %{$formats}) {
print " - (" . sprintf("%2d", $format) . ") " . $formats->{$format}->{'type'} . " (" . $formats->{$format}->{'quality'} . ") [" . $formats->{$format}->{'resolution'} . "]\n";
}
print "Opcion: ";
my $option = <STDIN>;
chomp($option);
print "Descargando numero $option...\n";
$http->reset();
$req = $http->request($formats->{$option}->{'url'});
my $output = $title;
$output .= '.mp4' if ($formats->{$option}->{'type'} =~ /video\/mp4/);
$output .= '.flv' if ($formats->{$option}->{'type'} =~ /video\/x-flv/);
$output .= '.webm' if ($formats->{$option}->{'type'} =~ /video\/webm/);
open(FH, '>', $output);
binmode(FH);
print FH $http->body();
close(FH);
print "Done!\n";
print "Archivo: '$output'\n";
#################
## FUNCTIONS ##
#################
sub showResponse() {
my $http = shift;
my $status = $http->status();
my $status_msg = $http->status_message();
my @headers = $http->headers_array();
$status_msg =~ s/[\n\r]//g;
print "Return Code:\n";
print " $status ($status_msg)\n";
print "Headers:\n";
foreach my $header (@headers) {
print " $header\n";
}
print "---------------------------\n";
return 0;
}
sub urlDecode() {
$_ = shift;
s/\+/ /g;
s/\%([0-9A-F]{2})/@{[chr hex $1]}/g;
return $_;
}
use strict;
use HTTP::Lite;
use Data::Dumper;
#####################################################
#
# Desarrollado por: Zort
# Fecha: 16 de Septiembre de 2011
#
# Descripcion:
# Este script descarga un video de YouTube especificado por
# el ID, el cual es entregado como parametro en la ejecucion.
# A su vez, es posible elegir el formato y la resolucion
# del video segun la disponibilidad de YouTube de entregar el
# video con dichas caracteristicas.
#
# Anexo:
# Se omitieron todos los acentos en el codigo, para que no se
# vean caracteres erroneos en el caso de que el equipo donde
# se corra este codigo permita ver solo caracteres gringos.
# Se ha detectado que en ciertas ocasiones no se descarga
# el video. En estos casos se debe intentar nuevamente.
#
#####################################################
my $debug = 0;
my $video_id = $ARGV[0];
die "Usage: $0 video_id\n\n" if ($video_id eq '');
my $http = HTTP::Lite->new;
$http->http11_mode(1);
my $req = $http->request("http://www.youtube.com/get_video_info?video_id=$video_id&eurl=http%3A%2F%2Flocalhost%2F&hl=en_US")
or die "Unable to get document: $!";
&showResponse($http) if ($debug);
if ($http->status() != 200) {
print "The return code is not valid!\n";
exit;
}
my $seconds = 0;
my $fmt_stream_map = '';
my $fmt_list = '';
my $title = '';
my $token = '';
my $formats = ();
my @infos = split(/&/, $http->body());
foreach my $info (@infos) {
my ($name, $value) = split(/=/, $info);
$seconds = $value if ($name eq 'length_seconds');
$fmt_stream_map = urlDecode($value) if ($name eq 'url_encoded_fmt_stream_map');
$fmt_list = urlDecode($value) if ($name eq 'fmt_list');
$title = urlDecode($value) if ($name eq 'title');
$token = $value if ($name eq 'token');
}
my @formats_list = split(/,/, $fmt_list);
foreach my $format_list (@formats_list) {
$format_list =~ /^([^\/]+)\/([^\/]+)\//;
$formats->{$1}->{'resolution'} = $2;
}
my @formats_map = split(/,/, $fmt_stream_map);
foreach my $format_map (@formats_map) {
my $url = '';
my $quality = '';
my $fallback_host = '';
my $type = '';
my $itag = '';
my @variables = split(/&/, $format_map);
foreach my $variable (@variables) {
my ($name, $value) = split(/=/, $variable);
$url = urlDecode($value) if ($name eq 'url');
$quality = urlDecode($value) if ($name eq 'quality');
$fallback_host = urlDecode($value) if ($name eq 'fallback_host');
$type = urlDecode($value) if ($name eq 'type');
$itag = $value if ($name eq 'itag');
}
$formats->{$itag}->{'url'} = $url;
$formats->{$itag}->{'quality'} = $quality;
$formats->{$itag}->{'fallback_host'} = $fallback_host;
$formats->{$itag}->{'type'} = $type;
}
print "Titulo: $title\n";
print "Formatos:\n";
foreach my $format (sort { $formats->{$a}->{'type'} cmp $formats->{$b}->{'type'} } keys %{$formats}) {
print " - (" . sprintf("%2d", $format) . ") " . $formats->{$format}->{'type'} . " (" . $formats->{$format}->{'quality'} . ") [" . $formats->{$format}->{'resolution'} . "]\n";
}
print "Opcion: ";
my $option = <STDIN>;
chomp($option);
print "Descargando numero $option...\n";
$http->reset();
$req = $http->request($formats->{$option}->{'url'});
my $output = $title;
$output .= '.mp4' if ($formats->{$option}->{'type'} =~ /video\/mp4/);
$output .= '.flv' if ($formats->{$option}->{'type'} =~ /video\/x-flv/);
$output .= '.webm' if ($formats->{$option}->{'type'} =~ /video\/webm/);
open(FH, '>', $output);
binmode(FH);
print FH $http->body();
close(FH);
print "Done!\n";
print "Archivo: '$output'\n";
#################
## FUNCTIONS ##
#################
sub showResponse() {
my $http = shift;
my $status = $http->status();
my $status_msg = $http->status_message();
my @headers = $http->headers_array();
$status_msg =~ s/[\n\r]//g;
print "Return Code:\n";
print " $status ($status_msg)\n";
print "Headers:\n";
foreach my $header (@headers) {
print " $header\n";
}
print "---------------------------\n";
return 0;
}
sub urlDecode() {
$_ = shift;
s/\+/ /g;
s/\%([0-9A-F]{2})/@{[chr hex $1]}/g;
return $_;
}
No hay comentarios:
Publicar un comentario