YouTube View — скрипт для просмотра видео без Flash
7 февраля 2011
Мне не нравится Flash. Очень не нравится. Потому что ничего полезного, кроме баннеров и игр, на нем не делают. Потому что Adobe не беспокоится о выпуске флэш-плагина для 64-х разрядных браузеров. К тому же, все мы прекрасно знаем, насколько он дырявый и тормознутый.
Недавно я попробовал установить Flash, и инстяллятор за каким-то хреном дополнительно установил мне антивирус McAfee. Даже не пытаясь попросить у меня разрешения. Просто взял и поставил! Хотя, в общем-то, понятно за каким хреном он это сделал. Должна же Adobe на чем-то зарабатывать?
Гуру юзабилити Якоб Нильсен пишет о Flash следующее:
About 99% of the time, the presence of Flash on a website constitutes a usability disease.
И самое главное — все, что умеет Flash, можно реализовать средствами HTML5 и jQuery! Нужно отдать ему должное, благодаря флэшу (по крайней мере, точно не без его помощи) сегодня мы имеем потоковое видео и аудио в сети. Но никто же не пользуется Mosaic, просто потому что он был первым графическим браузером?
Понимая вышесказанное и силу открытых технологий, Google ведет работы по внедрению HTML5 на YouTube. К сожалению, релиз Firefox под номером 4 еще не состоялся, а переходить на Оперу только ради Ютуба как-то не хочется. Я мог бы смотреть видео с помощью Flash, но под любимой FreeBSD для этого нужно прибегнуть к использованию linux_base.
Честно говоря, меня в последнее время мало волнует, ставлю я программу, использующую QT или GTK, нужен ли ей для работы linux_base или не нужен. Главное — чтобы работало. Но, в силу старой привычки, наверное, я предпочел написать небольшой скрипт для скачивания и просмотра видео.
# YouTube View Script v 0.9.8
# (c) Alexandr A Alexeev 2011 | http://eax.me/
use strict;
use constant VERSION => "0.9.8";
# куда сохраняем ролики (слэш на конце!)
use constant DEFAULT_PATH => '/tmp/';
# удаляем после просмотра?
use constant DEFAULT_DELETE => 1;
use List::MoreUtils qw/uniq/;
use utf8;
#### проверяем наличие всех необходимых утилит ####
{
my @depends = qw/date wget mplayer youtube-dl/;
my $not_found;
for(@depends) {
print "ERROR: $_ not found" and ++$not_found
if system("which $_ > /dev/null");
}
exit 1 if $not_found;
}
my $url = shift;
$url =~ s/(^\s+|\s+$)//g;
die "YouTube View Script ver ".VERSION.
"\nUsage:\n$0 <url>\n$0 --dialog\n" unless($url);
if($url eq "--dialog") {
print "Dialog mode, enter url(s) or 'exit'\nytview> ";
while($url = <STDIN>) {
chomp($url);
if(length($url)) {
last if(("\L$url" eq "exit")or("\L$url" eq "quit"));
$url =~ s/'/\'/g;
system("$0 '$url'") unless($url eq "--dialog");
print "\n";
}
print "ytview> ";
}
exit;
}
my $delete = $ENV{YOUTUBE_VIEW_DELETE};
$delete = DEFAULT_DELETE unless(defined($delete));
my $path = $ENV{YOUTUBE_VIEW_PATH};
$path = DEFAULT_PATH unless(defined($path));
print qq{
delete = $delete
path = $path
};
my @ids;
my $data;
my $q_url = $url;
$q_url =~ s/'/\'/g;
if($url =~ m#^(?:https?://)?(?:www\.)?(?:youtube\.com/watch\?v=|youtu\.be/)([^\&]+)#i) {
# некоторое видео (например, с пометкой 18+) может требовать
# от пользователя авторизации. youtube-dl успешно это обходит
# так что если ссылка прямо на ролик, не нужно ничего скачивать
push @ids, $1;
} else {
# скачиваем веб-страничку
print "Downloading $url...\n";
$data = `wget -q '$q_url' -O -`;
if(my @ljurls = $data =~ /(http:\/\/(?:www\.)?lj-toys\.com\/[^'" ]+)/ig) {
print "LJ Toys detected, ".scalar(@ljurls)." frames found...\n";
$data = "";
for my $url(@ljurls) {
$url =~ s/&/&/gi;
print "url = $url\n";
$data .= `wget -q '$url' -O -`;
}
}
# пытаемся выдрать из нее id ролика (роликов?)
@ids = $data =~ /http:\/\/(?:www\.)?youtube\.com\/(?:watch)?\??(?:v|video|embed)(?:=|\/)([a-zA-Z0-9\-\_]+)/gi;
@ids = uniq @ids;
}
my $id;
# сколько роликов на странице?
if((scalar @ids <= 1)or($url =~ /(http:\/\/)?(www\.)?youtu(\.be|be\.com)\//i)) {
$id = $ids[0];
} else {
# на странице более одного ролика
# выводим их id и названия, выбор должен сделать юзер
my $n;
print "\nIt was found more than one video:\n";
for my $vid(@ids) {
$data = `wget -q 'http://youtu.be/$vid' -O -`;
utf8::decode($data);
my ($title) = $data =~ /<meta name="title" content="([^"]+)">/;
$title = "Undefined title" unless $title;
$title = substr($title, 0, 30)."..."
if length($title) > 32;
utf8::encode($title);
print $n++.". $vid :: $title\n";
}
while($n > $#ids) {
print "Your choice (0..$#ids): ";
chomp($n = <STDIN>);
$n = scalar @ids unless($n =~ /^[0-9]+$/);
}
$id = $ids[$n];
unless($id) {
die "Failed to parse $url\n".
"wget returns $?\n".
"length(\$data) = ".length($data)."\n";
}
}
print "id = $id, downloading video...\n";
# имя файла для воспроизведения
my $fname;
# проверяем наличие ролика в кэше
my $cached_found = 0;
if(!$delete) {
my @flist = glob "$path*.flv";
for my $curr_fname (@flist) {
if($curr_fname =~ /\d{4}-\d{2}-\d{2}-([a-z0-9_-]+)\.flv$/i) {
if($1 eq $id) {
$fname = $curr_fname;
$cached_found = 1;
print "Found cached file: $fname\n";
last;
}
}
}
}
# скачиваем видео с помощью youtube-dl
if(!$cached_found) {
chomp(my $date = `date +%Y-%m-%d`);
$fname = "$path$date-$id.flv";
print "fname = $fname\n";
system("youtube-dl 'http://youtube.com/watch?v=$id' -o $fname");
if($?) {
unlink "$fname.part";
die "youtube-dl returns $?\n"
}
print "done!\n";
}
# запускаем проигрыватель
system("mplayer -zoom $fname");
print qq{
EMBED CODE:
--------8<--------8<--------
<iframe class="youtube-player" type="text/html"
width="640" height="385"
src="http://www.youtube.com/embed/$id" frameborder="0">
</iframe>
<div style="font-size: 0.8em">Posted via <a href="http://eax.me/youtube-view/">YouTube View</a> script.</div>
--------8<--------8<--------
SHORT LINK: http://youtu.be/$id
};
unlink $fname if $delete;
Идея простая — берем код страницы, содержащей видео, и выдираем из нее ID ролика. Затем скачиваем этот ролик с помощью youtube-dl (/usr/ports/www/youtube_dl) и просматриваем в mplayer. Плюс к этому, скрипт выводит embed-код и короткую ссылку на видео (http://youtu.be/…). Есть возможность работать со страницами, содержащими несколько роликов.
По умолчанию видео сохраняется скриптом в каталог /tmp и удаляется после просмотра. Изменить такое поведение можно с помощью переменных окружения:
# алиас к скрипту
alias ytview="~/scripts/perl/ytview.pl"
# не удаляем ролики после просмотра
export YOUTUBE_VIEW_DELETE=0
# каталог для сохранения роликов (слэш на конце!)
export YOUTUBE_VIEW_PATH=~/nodump/youtube/
Мне такое решение нравится намного больше, чем скачивание пол-линукса и установка флэш-плагина. Костыль, конечно, но поможет дождаться повсеместного внедрения HTML5 Video. Надеюсь, вам этот скрипт тоже пригодится.
Дополнение: Также вас могут заинтересовать скрипты для загрузки видео с RuTube и Vimeo.com, а также для скачивания mp3 из ВКонтакта.
Метки: Perl.
Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.