Превью-изображения с YouTube, Vimeo и ruTube

Строю очень интересный сайт, на котором можно создавать ресурсы и указывать ссылку на видео с одного из 3х популярных видео-хостингов: YouTube, Vimeo и ruTube.

Созданные страницы должны выводиться плиткой, с показом картинки от видео, причем, со своего сервера - чтобы не ждать ответа от удалённого. Задача осложняется тем, что существует минимум 8 вариантов указания ссылок на эти 3 сервиса:

https://www.youtube.com/watch?v=ITwNkwoc4J0
http://youtu.be/ITwNkwoc4J0
https://www.youtube.com/embed/ITwNkwoc4J0?rel=0

http://vimeo.com/55028438
http://player.vimeo.com/video/55028438?title=0&byline=0&portrait=0&badge=0&color=e1a931

http://rutube.ru/video/6fd81c1c212c002673280850a1c56415/#.UMQYln9yTWQ
http://rutube.ru/tracks/6032725.html
http://rutube.ru/video/embed/6032725

Это всё ссылки на один и тот же клип Rammstein - Mein Herz brennt (Piano Version). Не стоит забывать еще и про юзеров, которые обязательно вставят в форму "ссылку для блога", то есть - прям тег iframe со всеми свойствами, который отдаст сервис.

Вот исходный код моего класса, пользуйтесь на здоровье. Он абсолютно самодостаточен и не завязан на MODX, требуется только cUrl.

В ответ приходит массив содержащий или ключ error с ошибкой, или ключи со ссылками image и video.

Если картинку достать не получается - будет подставлен дефолтный url. Все ссылки на видео-хостинги приводятся к единому виду.

Обращаю ваше внимание на то, что превью-картинки сохраняются на сервер, то есть достаются ровно один раз, затем можно использовать их как угодно. При инициализации класса можно указать пути для работы.

Пример использования:

require 'videothumb.class.php';

$url = isset($_GET['url']) ? trim($_GET['url']) : '';

$class = new videoThumb(array(
    'imagesPath' => dirname(__FILE__) . '/images/',
    'imagesUrl' => '/assets/video/images/',
    'emptyImage' => 'assets/_empty.png',
));
$video = $class->process($url);

print_r($video);

Отправите ссылку через $_GET и в ответ получите массив с результатом и картинку в указанной директории.

Обновлено 17.08.13

Какое то время назад парсинг с rutube.ru поломался, видимо там что-то поменяли.

← Предыдущая заметка
Новое сообщество MODX
Следующая заметка →
Обсуждаем miniShop 2.0
Комментарии (42)
it-developeВиталий Воропаев
09.12.2012 17:27

Прекрасная работа. Я думаю многие оценят.

it-developeВиталий Воропаев
09.12.2012 17:32

Думаю было бы не плохо дописать еще один тип работы класса. Создание серии превью, для последующего формирования слайдшоу видео.

inetloverАлександр Наумов
09.12.2012 19:05

Круто! Спасибо.

Заметил что ссылки начинающиеся с https парсер не понимает, а Youtube в основном все такие.

bezumkinВасилий Наумкин
09.12.2012 20:21

Добавил поддержку https в регулярки.

Добряков Алексей
10.12.2012 00:59

шикарно мужик

dr_Deldr Del
13.12.2012 16:33

Полезная вещь.

Можно еще в докрутить чтобы проглатывала адреса из мобильной версий (http://m.youtube.com/)

Seigiardseigiard@gmail.com
09.01.2013 23:27
http://www.youtube.com/user/SilkRoadTheatre#p/a/u/2/6dwqZw0j_jY 
http://youtu.be/6dwqZw0j_jY
http://www.youtube.com/watch?v=6dwqZw0j_jY&feature=youtu.be
http://youtu.be/afa-5HQHiAs
http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo
http://www.youtube.com/watch?v=cKZDdG9FTKY&feature=channel
http://www.youtube.com/watch?v=yZ-K7nCVnBI&playnext_from=TL&videos=osPknwzXEas&feature=sub
http://www.youtube.com/ytscreeningroom?v=NRHVzbJVx8I

Вот варианты ссылок, которые я нашел для YouTube.

Регулярка простая:

^https?\:\/\/(www\.)?youtu(\.be|be\.com).*(\/|\?|=)([\w-]{11})((&|\?).+)?$

Но у меня по проекту условие, что один урл в одной строке, поэтому где-то может не работать.

d start
12.01.2013 13:27

Обращаю ваше внимание на то, что превью-картинки сохраняются на сервер, то есть достаются ровно один раз, затем можно использовать их как угодно. При инициализации класса можно указать пути для работы.

Странно, но у меня не создаются картинки категорически, путь возвращает, а картинки нет в папке. Права на директории 777 выставил, всё равно пусто.

d start
12.01.2013 13:52

Нашёл в чём дело конкретно в моей ситуации

$class = new videoThumb(array(
    'imagesPath' => dirname(__FILE__) . '/images/'
    ,'imagesUrl' => 'assets/video/images/'
   ,'emptyImage' => 'assets/_empty.png'
));

при указании пути вида 'imagesPath' => dirname(__FILE__) . '/images/' Картинка записывается в core/cache/includes/elements/modsnippet/images, а путь возвращается как будто она записана в правильный каталог.

bezumkinВасилий Наумкин
12.01.2013 14:02

Да, всё верно.

Лучше указывать

'imagesPath' => MODX_ASSETS_PATH . '/images/'
d start
13.01.2013 14:04

В результате у меня получился вот такой вот сниппет:

<?php
require_once MODX_ASSETS_PATH.'components/videothumb/videothumb.class.php';

// можно передавать и как параметр и через запрос 
if(empty($url))
    {
        $vurl = trim(@$_REQUEST['vurl']);  
    }
else{
        $vurl = $url;
    }

$class = new videoThumb(array(
    'imagesPath' => 'assets/video/images/'
    ,'imagesUrl' => 'assets/video/images/'
));

$result = $class->process($vurl);
$modx->setPlaceholders(array(
   'video'	=> $result['video']
   ,'image'	=> $result['image']
),'v.');
//Эту конструкцию пришлось сделать для того, что бы в чанках при листинге через getResources не "залипали" картинки. Почему то для всех постов кроме первого картинка выводилась одинаковая 0_о
if($return)
    {
        switch($return)
            {
                case 'video': return $result['video'];
                break;
                case 'image': return $result['image'];
                break;
            }
    }

У меня оно работает, насчёт красоты исполнения и\или ресурсоёмкости - увы и ах, пока ничего не тестировал, в данны момент учитывалась только работоспособность, что бы поднять проект до альфа-версии. Если у Вас есть какие то советы по оптимизации, с радостью учту.

bezumkinВасилий Наумкин
13.01.2013 15:10

Не понятно, что делает этот сниппет? Зачем он и выставляет плейсхолдеры, и возвращает url картинки\видео?

У меня, например, через форму отправлялся урл, для него получалась картинка и сохранялась на сервер, записывая свой адрес в ТВ ресурса. Ну а потом уже обычный вывод страниц, через getResources, с этими картинками.

А тут какая задача?

d start
13.01.2013 15:54

У меня задача: есть раздел с мастерклассами, они в частности состоят из видео и тестового описания. Т.е. надо выводить видео с ютубы на самой странице и картинку в анонсе, для завлекухи. Сниппет я обозвал getVideo, он из TV получает ссылку на ютубное видео. Сниппет сохраняет резултаты в плейсхолдеры, что бы удобнее было на странице/в шаблоне пользоваться этими результатами. В разделе выводится листинг анонсов. При этом случился трабл: почему то при вызове сниппета в чанке анонса картинка выставлялась только для первого анонса, а для всех последующих - назначалась картинка последнего поста. Т.е. плейсхолдеры закешировались, хотя я и вызывал плейсхолдер некешируемо - [[!+v.image]] и сам сниппет тоже [[!getVideo?url=\[\[+tv.studioVideo\]\]]] Потому я сделал так, что бы сниппет мог возращать требуемое значение, а не сохранять его в плейсхолдер. Теперь вызов в чанке делается так:

[[!getVideo?url=`[[+tv.studioVideo]]`&return=`image`]]

и всё заработало.

bezumkinВасилий Наумкин
13.01.2013 16:30

Выходит, у тебя каждый раз запускается сниппет, обрабатывает ссылку и потом клиент тянет картинку с youtube?

При том, что сниппет, на самом деле, сохраняет эти картинки на твой сервер. В общем, я бы добавил ТВ studioImage и переделал так:


// В чанке вывода списка указываем фильтр для пустого ТВ image
<img src="" alt="" title="" />

Пишем сниппет, getImage:

<?php
// Инициализируем videoThumb один раз, в переменную класса MODX
if (empty($modx->videoThumb) || !is_object($modx->videoThumb)) {
    require_once MODX_ASSETS_PATH.'components/videothumb/videothumb.class.php';

    $modx->videoThumb = new videoThumb(array(
        'imagesPath' => MODX_ASSETS_PATH . 'video/images/'
        ,'imagesUrl' => '/assets/video/images/'
        ,'emptyImage' => 'assets/_empty.png'
    ));
}
// Получаем ресурс, у которого нет картинки в ТВ, он достанется из кэша, ибо его только что получал getResources
if ($res = $modx->getObject('modResource', $input)) {
    // Получаем ТВ с адресом видео
    $url = $res->getTVValue('studioVideo');
    // Получаем картинку
    $result = $modx->videoThumb->process($url);
    // Если нам вернулась картинка - сохраняем в ТВ и возвращаем
    if (!empty($result['image'])) {
        $res->setTVValue('videoImage', $result['image']);
        return $result['image'];
    }
    // Иначе пишем ошибку в лог и возвращаем картинку по умолчанию
    else {
        $modx->log(modX::LOG_LEVEL_ERROR, 'Не могу получить картинку по адресу ' .$url.', ошибка: '.$result['error']);
        return '/assets/video/images/_empty.png';
    }
}

Таким образом, класс videoThumb инициализируется только раз и сниппет запускается только на те записи, у которых нет ТВ с картинкой. Ну а картинки потом получаются с твоего сервера. Так быстрее и логичнее.

Писал в браузере, не проверял - могут быть опечатки.

d start
13.01.2013 17:00

Понял, спасибо. Сегодня попробую. Подумал вот ещ сделать кастом Tv - Video. Как считаешь надо оно?

bezumkinВасилий Наумкин
13.01.2013 17:01

Я бы сделал - чтобы хранить и выводить ссылки на видео в одном формате, а не как юзер ввёл.

d start
14.01.2013 12:54
// В чанке вывода списка указываем фильтр для пустого ТВ image
<img src="" alt="" title="" />

Эээ, а фильтр тут где?

Вот так вызывать:

<img src="[[+tv.studioImage:empty=`studioImage:getImage`]]" alt="" title="" />

Пральна?

d start
14.01.2013 13:08

Почитал сниппет повнимательнее и сделал вот так:

[[+tv.studioVideoImage:empty=`[[+id:getStudioImage]]`]]

Завелось =) Спасибо за такое интересное решение

bezumkinВасилий Наумкин
14.01.2013 16:20

Да, верно. Не знаю, куда у меня там вызов в чанке делся =(

Чикин Артур
08.03.2013 14:36

На основе этого кода будет написан полноценный снипет? было бы не плохо. В репозитории модекса нету подобных дополнений. А установка из коробки была бы кстати.

Roman Galaktionov
10.05.2013 19:47

Помогите, как быть? Я переделал немного скрипт, чтобы url видео брался из текстового поля. В итоге мне выдает:

Array ( [video] => http://www.youtube.com/embed/yn6AovshrzE [image] => /assets/video/images/edb556c74bbe09be4b0bc93346fae53e.jpg ) 
bezumkinВасилий Наумкин
10.05.2013 20:38

И в чем заключается вопрос?

Ты не можешь взять из массива то, что тебе нужно?

Роман Шоу
18.08.2013 00:10

А не знаете есть ли что-то подобное для джумла или подскажите, как сделать, чтобы превьюшки генерировались автоматически?

bezumkinВасилий Наумкин
18.08.2013 00:29

Это самостоятельный класс, он не привязан к MODX.

Его можно использовать где угодно.

Роман Шоу
18.08.2013 01:33

А как сделать, чтобы класс при загрузке страниц сразу загружался и генерировал превьюшки?

ew.bolgowболгов евгений
24.03.2014 00:39

Здравствуйте.Это сайт только для программистов?

Чикин Артур
24.03.2014 00:44

Это блог им. Василия Наумкина. Так что этот блог для абсолютно всех желающих его читать.

bezumkinВасилий Наумкин
24.03.2014 00:54

Вы зарегистрировались и можете читать и писать. Включаем логику:

1. Если этот сайт только для программистов - то вы программист и вас не должен интересовать этот вопрос. 2. Вы не программист, но вы здесь общаетесь, а значит сайт не только для программистов. 3. Вы программист и ищите сайт только для программистов, и не можете понять - такой ли этот сайт? Учитывая, как легко вы зарегистрировались - нет, не такой.

Задача решена - этот сайт не только для программистов.

ВолодянВолодя
24.03.2014 01:00

Повеселил)))

ew.bolgowболгов евгений
24.03.2014 01:02

OK! Я и есть "кто угодно". Данный класс очень удобный, но хотелось бы более разжёванной документации. Потому как не являясь программистом, довольно сложно понять глубокие мысли г.Безумкина.Не понятно как передать $Get['url'].например,И что её вообще надо передовать. Закинул класс в файл. В другом файле подключил. И что далее. Как вывести всё это дело "на экран".

Чикин Артур
24.03.2014 01:10

Куда еще разжованее?! И так постоянно документацию пополняем да вылизываем до супер доступного состояния. Читайте и просвещайтесь: http://docs.modx.pro

bezumkinВасилий Наумкин
24.03.2014 01:12

Если не понятно, что такое $_GET, то нужно нанять программиста или купить книжку по PHP.

Такой детcкий сад никто объяснять не будет.

ew.bolgowболгов евгений
24.03.2014 01:13

Я так и думал, что програмисты.

Чикин Артур
24.03.2014 01:17

Я не программист, скорее сетевик по профессии (будущей) и верстальщик (хобби) который знает основы почти всех основных языков программирования.

Но знать основы != быть программистом.

ew.bolgowболгов евгений
24.03.2014 01:24

Я рад за тебя. Всё таки правильно говорят о вашем сообществе в инете. Одно большое раздутое тщеславие и самолюбие.

Чикин Артур
24.03.2014 01:30

Тебя тут никто не держит.

В нашей группе есть минимальный порог, 1-ое это знание основ PHP и 2-ое это желание познавать MODX Revo. У тебя нет ни 1 ни 2 пункта. И еще и желание как то оскорбить. Так что можете не задерживаться. И в любой другой подобной группе вам скажут тоже самое.

bezumkinВасилий Наумкин
24.03.2014 10:33

Спасибо, что зашел - а то я тут уже больше месяца никого не банил.

Чикин Артур
24.03.2014 10:55

Кстати на счет банов. Я так понимаю система банов будет для каждого ресурса своя, но для id.modx.pro так как он на своем движке работает то у него будет общий бан на все домены?

bezumkinВасилий Наумкин
24.03.2014 11:27

Верно.

Если накосячишь на modx.pro - отключен будешь от всего.

Михаил
18.04.2014 19:23

Василий есть код на вывод видео на экран по ссылке?

bezumkinВасилий Наумкин
18.04.2014 21:30

Обычно достаточно просто обернуть ссылку в iframe - специальный класс для этого не нужен.

Это сообщение было удалено
born2slip
pishnaa istntome
22.11.2022 14:06
огромное спасибо! )
inetlover
Александр Наумов
14.11.2022 10:19
посмотри документацию. Спасибо, что-то она мне не нагуглилась. Это просто функции объединения для о...
bezumkin
Василий Наумкин
10.11.2022 05:46
Спасибо за поздравления!
inetlover
Александр Наумов
09.11.2022 17:08
Посмотрел в ДевТулсе свойство overscroll-behavior: none; присутствует, проверил в Chrome и Chromium ...
bezumkin
Василий Наумкин
03.11.2022 20:57
Поискать в исходниках ссылки на её адрес и поменять - скорее всего только nuxt.config.js. А зачем эт...
ni.kolokol@mail.ru
Николай Каленников
03.11.2022 19:43
Спасибо. Попробую тоже с нуля переставить
inetlover
Александр Наумов
03.11.2022 19:24
Спасибо!!! Все заработало!
bezumkin
Василий Наумкин
28.10.2022 05:23
В тексте есть подсказка // Контроллер требует новое разрешение protected $scope = &#x27;ord...
bezumkin
Василий Наумкин
27.10.2022 13:25
Понял, спасибо!
inetlover
Александр Наумов
23.10.2022 13:33
Понял, спасибо!