Автозамена ссылок на видео Youtube на код ролика + плеер Uppod или модальное окно

+19
4.22K
Автоматическое преобразование ссылки на видео с ютуба, которая вставлена в посте блога, на стене, на форуме в плеер с этим видео.
Также рассмотрим вывод этого видеоролика в своем стилизованном плеере на базе Uppod плеера и вывод этого ролика в модальном окне используя имеющийся в коробке Инстанта Colorbox.

0. Бэкап файлов.
1. includes/bbcode/bbcode.lib.php
в функции autoLink

Это

  1. $search = array(
  2. "~(\s|^)((?:http|https|ftp)://[^<\s]+[^<\.,:;?!\"»'+\-\s])~uim",
  3. "~(\s|^)(www\.[^<\s]+[^<\.,:;?!\"»'+\-\s])~uim",
  4. "'([^\w\d-\.]|^)([\w\d-\.]+@[\w\d-\.]+\.[\w]+[^.,;\s<\"\'\)]+)'usi"
  5. );
  6. $replace = array(
  7. '$1<a href="/redirect?url=$2">$2</a>',
  8. '$1<a href="/redirect?url=http://$2">$2</a>',
  9. '$1<a href="mailto:$2">$2</a>'
  10. );
Заменил на это

  1. $search = array(
  2. "/\s*[a-zA-Z\/\/:\.]*youtu(be.com\/watch\?v=|.be\/)([a-zA-Z0-9\-_]+)([a-zA-Z0-9\/\*\-\_\?\&\;\%\=\.]*)/i",
  3. "~(\s|^)((?:http|https|ftp)://[^<\s]+[^<\.,:;?!\"»'+\-\s])~uim",
  4. "~(\s|^)(www\.[^<\s]+[^<\.,:;?!\"»'+\-\s])~uim",
  5. "'([^\w\d-\.]|^)([\w\d-\.]+@[\w\d-\.]+\.[\w]+[^.,;\s<\"\'\)]+)'usi"
  6.  
  7. );
  8. $replace = array(
  9. '<youtube>$2</youtube>',
  10. '$1<a href="/redirect?url=$2">$2</a>',
  11. '$1<a href="/redirect?url=http://$2">$2</a>',
  12. '$1<a href="mailto:$2">$2</a>'
  13.  
  14. );
Можно было бы конечно сразу здесь же заменять ссылку на полный код видеоролика с ютуба. Но я решил на этом этапе извлекать только Идентификатор видеоролика и в базу вместе с постом записывать только его обрамляя тегом <youtube></youtube>

Это оставляет больше возможностей для маневра на будущее. Например можно будет менять в любое время во врех роликах стандартный плеер Ютуб на свой, размер плеера, ну и если на самом Ютубе что то изменится, идентификатор ролика всё равно останется тот же скорее всего. Поэтому в базу пишется только ИД видео, а дальше придется в каждом компоненте описывать преобразование ИД ролика в плеер.

На примере стены пользователя я сделал это так:

2. core/classes/user.class.php

после
  1. while($record = $inDB->fetch_assoc($result)){
  2. $record['is_today'] = time() - strtotime($record['pubdate']) < 86400;
  3. $record['fpubdate'] = $record['is_today'] ? cmsCore::dateDiffNow($record['pubdate']) : cmsCore::dateFormat($record['pubdate']);
  4. $record['avatar'] = cmsUser::getUserAvatarUrl($record['author_id'], 'small', $record['imageurl'], $record['is_deleted']);
а) вставил это
  1.  
  2. $record['content'] = preg_replace('|<youtube>(.*)</youtube>|isU', '<iframe width="560" height="315" src="https://www.youtube.com/embed/$1" frame allowfullscreen></iframe>', $record['content']);
для вывода плеера ютуб в его стандартном виде

******

б) или это

  1. $record['content'] = preg_replace('|<youtube>(.*)</youtube>|isU', ' <a class="iframe cboxElement" href="https://www.youtube.com/embed/$1"><img src="/images/play_video.png" style="width:300px; height:auto;" /></a>', $record['content']);
для вывода вместо плеера картинки иконки, при нажатии на которую видео откроется в Colorbox

******

в) или это

  1. $record['content'] = preg_replace('|<youtube>(.*)</youtube>|isU', '<div class="player" id="$1"></div><script type="text/javascript">this.player = new Uppod({m:"video",uid:"$1",file:"https://www.youtube.com/embed/$1"});</script>', $record['content']);

для вывода видео в html5 плеере от uppod uppod.ru/help/html5

******

г) а если плеер будет со своим и стилями то вот так
  1.  
  2. $record['content'] = preg_replace('|<youtube>(.*)</youtube>|isU', '<div class="player" id="$1"></div><script type="text/javascript">this.player = new Uppod({m:"video",uid:"$1",file:"https://www.youtube.com/embed/$1",st:"uppodvideo"});</script>', $record['content']);
******


core/classes/blog.class.php
после

  1. $post['content_html'] = preg_replace('/\[(cut=)\s*(.*?)\]/ui', '', $post['content_html']);
вставить

  1. $post['content_html'] = preg_replace('|<youtube>(.*)</youtube>|isU', '<div class="player" id="$1"></div><script type="text/javascript">this.player = new Uppod({m:"video",uid:"$1",file:"https://www.youtube.com/embed/$1",st:"uppodvideo"});</script>', $post['content_html']);
(это в плеере Uppod со своими стилями, другие примеры выше)


При этом для uppod в <head> секцию сайта нужно добавить js вызова плеера Uppod и js вызова стилей для плеера Uppod (если они используются). О подключении стилей Uppod html5 читайте здесь uppod.ru/help/q=styles-html5


Действия из пункта 2 придется повторить для блогов, комментов, форума.

Вот что получается

Ссылка вставленная на стену превратилась в плеер

Иллюстрация


Оно же но с использованием Uppod

Иллюстрация

Вместо ссылки картинка со ссылкой на видео.

Иллюстрация

по клику на картинку открывается видео в колорбоксе.

Иллюстрация



P.S. в файле стилей можно задать стиль для блока <youtube>
например скрыть там где еще не работает преобразование или вывести там фон с текстом что видео скоро появится)

body youtube{
display:none;
}

P.P.S — если после этого внедрения нужно в посте опубликовать ссылку на видео что бы она осталась в виде ссылке, это можно сделать через bbcode тег url. Не проверял, но по идее там ссылки не будут заменяться на плеер.

Пока всё. Кто хочет дополнить, улучшить, вэлкам.
0
letsgo letsgo 7 лет назад #
Отличное решение.
0
Erwin Erwin 7 лет назад #
Радует что первая ветка жива и такие хорошие поправки делаете. Их прям нужно в коробку вносить сразу.
0
surfixx surfixx 7 лет назад #
Спасибо за это решение. Поставил плюс. Но есть недостаток, нет резиновости (извиняюсь за каламбур). Я решил это так: в user.class.php добавил диви

Код PHP:
  1. $record['content'] = preg_replace('|<youtube>(.*)</youtube>|isU', '[b]<div class="videoframe"><div class="videocontainer">[/b]<iframe width="560" height="315" src="https://www.youtube.com/embed/$1" frameborder="0" allowfullscreen></iframe>[b]</div></div>[/b]', $record['content']);
И в стилях добавил вот это.
Код PHP:
  1. .videoframe {
  2. display:block;
  3. max-width:560px;
  4. margin:0px auto;
  5. float:none
  6. }
  7. .videocontainer {
  8. display:block;
  9. position: relative;
  10. padding-bottom: 56.25%;
  11. padding-top: 30px;
  12. height: 0;
  13. overflow: hidden;
  14. }
  15. .videocontainer iframe,
  16. .videocontainer object,
  17. .videocontainer embed {
  18. position: absolute;
  19. top: 0;
  20. left: 0;
  21. width: 100%;
  22. height: 100%;
  23. }
Ваш <youtube></youtube> в скрипте чтото не нашол. Пришлось делать по простому.
+1
Нил™ Нил™ 7 лет назад #
<youtube></youtube> это я сделал обёртку идентификатора с видео, что бы потом на выводе искать ИД видео по тегу <youtube>, оно хранится только в базе с этими тегами а при отрисовке html страницы вырезается и меняется на сам код видеоролика.
И кстати, заметил после опубликования поста, что при размещении видеоролика на стене пользователя, в ленте активности потом это выглядит вот так


Это связано с тем, что при записи в ленту активности события "Добавления поста на стену" из описания события вырезаются все теги, ну и наш тоже вырезался и в результате в ленте активности отображаются загадочные символы которые мы не можем преобразовать в видеоролик, потому что они не обернуты в тег <youtube>

Что бы этого избежать, можно
а) использовать вместо тегов <youtube></youtube> набор символов типа YTBcode endYTBcode,
б) на самом делее более вменяемый вариант, в components/users/model.php

вместо
Код PHP:
  1. $message = strip_tags($item['content']);
вставить
Код PHP:
  1. $message = strip_tags($item['content'],'<youtube>');
то есть внести тег ютуб в список исключений и не вырезать его при постинге события в ленту активности.

И тогда в ленте активности событие "Надпись на стене" если эта надпись одно только видео будет выглядеть вот так



Как собственно оно и выглядело всегда на Instantcms первой ветки, если надпись на стене это тупо видеоролик то в ленте активности пустое сообщение.

Что бы все таки указать в ленте активности на видеоролик размещенный на стену в файле core/classes/action.class.php

где то перед
Код PHP:
  1. $actions[] = $action;
вставил ту же замену тега ютуб что и выше для стены и для блогов. Вариант для ленты активности получается такой

Код PHP:
  1. $action['description'] = preg_replace('|<youtube>(.*)</youtube>|isU', '<iframe width="560" height="315" src="https://www.youtube.com/embed/$1" frameborder="0" allowfullscreen></iframe>', $action['description']);
и тогда уже сообщение о том что пользователь написал на стене с видеороликом выглядит вот так



(вывод в плеере ютуб)

Ну мне не нравится вывод самого видеоролика в саму ленту активности, поэтому я сделаю вот так

$action['description'] = preg_replace('|<youtube>(.*)</youtube>|isU', '<img src="/images/icons/youtubevideo.jpg" style="max-width:200px; height:auto; width:100%; border:1px solid silver; box-sizing:border-box;"/>', $action['description']);

и результат выглядит вот так









Что бы этого избежать,
0
Нил™ Нил™ 7 лет назад #
Блин можно уже дать возможность редактировать комменты хотя бы в течении 10 минут hoho
0
surfixx surfixx 7 лет назад #
Спасибо за ответ. Хорошее решение, но по мне, много действий в скриптах. Всё это в плагин - вот Би да. Всё равно спас за ваш труд. Молодец.
0
sibroy sibroy 6 лет назад #
Как бы сделать такой вывод в комментариях?
+1
Нил™ Нил™ 6 лет назад #
1 пункт из этого поста ( в файле bbcode.lib.php)

+

components/comments/model.php

перед

Код PHP:
  1. $comments[] = $comment;
+ uppod

Код PHP:
  1. $comment['content'] = preg_replace('|<youtube>(.*)</youtube>|isU', '<div class="player" id="$1"></div><script type="text/javascript">this.player = new Uppod({m:"video",uid:"$1",file:"https://www.youtube.com/embed/$1"});</script>', $comment['content']);
или +плеер youtube

Код PHP:
  1. $comment['content'] = preg_replace('|<youtube>(.*)</youtube>|isU', '<iframe width="100%" height="315" src="https://www.youtube.com/embed/$1" frameborder="0" allowfullscreen></iframe>', $comment['content']);
как то так. не проверял, но должно работать
+1
Нил™ Нил™ 6 лет назад #
но после изменения в bbcode.lib.php часть, которая касается блогов и форума и стены тоже надо выполнить, как описано выше
0
sibroy sibroy 6 лет назад #
Работает...спасибо
0
sibroy sibroy 4 года назад #
На instantcms1.10.7 в модуле Записи блогов режет тег <youtube>... что можно сделать?
+2
Нил™ Нил™ 4 года назад #
В оригинальном виде в модуле содержимое поста вроде не должно выводиться, у вас какая то модификация, может быть там предусмотрено вырезание тегов?

Кстати, я сейчас не заморачиваюсь с тегом <youtube>

На примере поста в блоге, я бы сделал так. 1 пункт из основного поста не выполняю вообще. Вместо второго пункта

после $post['content_html'] = preg_replace('/\[(cut=)\s*(.*?)\]/ui', '', $post['content_html']);

вставил бы (тут заодно твиттер, инста, вимео)

Код PHP:
  1. $search = array(
  2. '%https://twitter.com/([a-zA-Z0-9\-_]+)/status/([a-zA-Z0-9\-_]+)%',
  3. '%https://www.instagram.com/p/([a-zA-Z0-9\-_]+)/%',
  4. '%https://vimeo.com/([a-zA-Z0-9\-_]+)%',
  5. "/\s*[a-zA-Z\/\/:\.]*youtu(be.com\/watch\?v=|.be\/)([a-zA-Z0-9\-_]+)([a-zA-Z0-9\/\*\-\_\?\&\;\%\=\.]*)/i"
  6. );
  7. $replace = array(
  8. '<blockquote class="twitter-tweet" data-lang="ru"><a href="https://twitter.com/$1/status/$2?ref_src=twsrc%5Etfw"><i style="color:#00acee;" class="fa fa-twitter fa-spin" aria-hidden="true"></i> загрузка содержимого твита</a></blockquote>
  9. <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>',
  10. '<embed style="width:100%; max-width:400px; height:500px;" src="https://www.instagram.com/p/$1/embed/captioned/"/>',
  11. '<iframe src="https://player.vimeo.com/video/$1" width="640" height="352" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>',
  12. '<div style="padding:10px 0 10px 0;"><iframe width="100%" height="450" style="padding:10px; border:1px solid silver; box-sizing:border-box; width:100%; height:450px;" src="https://www.youtube.com/embed/$2" frameborder="0" allowfullscreen></iframe></div>'
  13. );
$post['content_html'] = preg_replace($search, $replace, $post['content_html']);

если уже до этого использовался рецепт из основного поста с тегом <youtube> можно либо отменив действия из основного поста пересохранить посты либо просто добавить код который приводится в этом комментарии перед рекомендованным в основном посте для блога
Код PHP:
  1. $post['content_html'] = preg_replace('|<youtube>(.*)</youtube>|isU', '<div class="player" id="$1"></div><script type="text/javascript">this.player = new Uppod({m:"video",uid:"$1",file:"https://www.youtube.com/embed/$1",st:"uppodvideo"});</script>', $post['content_html']);
Не проверял, но должно работать)
+1
Нил™ Нил™ 4 года назад #
<i style="color:#00acee;" class="fa fa-twitter fa-spin" aria-hidden="true"></i> это иконка из набора font-awesome если не используете, можно удалить
0
sibroy sibroy 4 года назад #
Модуль стандартный...пользуюсь вашим способом с тегом <youtube> уже больше года...вставленных роликов в блоги и комментарии порядочно) Новый способ работает...спасибо)
+1
Нил™ Нил™ 3 года назад #
Тут напомнили про эту тему. Дополню список + автозамена ссылки из телеграм и автозамена ссылки из тик ток.

Код PHP:
  1. $search = array(
+

Код PHP:
  1. %https://www.tiktok.com/([@a-zA-Z0-9\-_]+)/video/([a-zA-Z0-9\-_]+)%',
  2. "%https://t.me/([a-zA-Z0-9\-_]+)/([a-zA-Z0-9\-_]+)%",
Код PHP:
  1. $replace = array(
+ в соответствующем порядке

Код PHP:
  1. '<blockquote class="tiktok-embed" cite="https://www.tiktok.com/$1/video/$2" data-video-id="$2" style="max-width: 605px;min-width: 325px;" > <section> <a target="_blank" title="$1" href="https://www.tiktok.com/$1">$1</a></section> </blockquote> <script async src="https://www.tiktok.com/embed.js"></script>',
  2. '<div style="padding:10px 0 10px 0;"><iframe width="100%" height="450" style="padding:10px; border:1px solid silver; box-sizing:border-box; width:100%; height:450px;" src="https://www.youtube.com/embed/$2" frameborder="0" allowfullscreen></iframe></div>',
  3. '<div align="left"><script async src="https://telegram.org/js/telegram-widget.js?14" data-telegram-post="$1/$2" data-width="100%"></script></div>',
+1
Нил™ Нил™ 3 года назад #
Строка 2. с Youtube здесь лишняя, копировал упустил, строка 1. с tiktok во втором выделенном блоке Код PHP - коде там кавычка ' вначале потерялась. Не могу отредактировать или удалить коммент с ошибкой))
0
sibroy sibroy 3 года назад #

Вот код модуля mod_blogs

<?php<br-->/******************************************************************************/
// //
// InstantCMS v1.10.6 //
// www.instantcms.ru/ //
// //
// written by InstantCMS Team, 2007-2015 //
// produced by InstantSoft, (www.instantsoft.ru) //
// //
// LICENSED BY GNU/GPL v2 //
// //
/******************************************************************************/

function mod_blogs($mod, $cfg){

$inDB = cmsDatabase::getInstance();

$default_cfg = array (
'sort' => 'pubdate',
'owner' => 'user',
'shownum' => 5,
'minrate' => 0,
'blog_id' => 0,
'showrss' => 1
);
$cfg = array_merge($default_cfg, $cfg);

cmsCore::loadClass('blog');
$inBlog = cmsBlogs::getInstance();
$inBlog->owner = $cfg['owner'];

if($cfg['owner'] == 'club'){
cmsCore::loadModel('clubs');
$model = new cms_model_clubs();
$inDB->addSelect('b.user_id as bloglink');
} else {
cmsCore::loadModel('blogs');
$model = new cms_model_blogs();
}

// получаем аватары владельцев
$inDB->addSelect('up.imageurl, img.fileurl');
$inDB->addJoin('LEFT JOIN cms_user_profiles up ON up.user_id = u.id');
$inDB->addJoin(«LEFT JOIN cms_upload_images img ON img.target_id = p.id AND img.target = 'blog_post' AND img.component = 'blogs'»);

$inBlog->whereOnlyPublic();

if($cfg['minrate']){
$inBlog->ratingGreaterThan($cfg['minrate']);
}

if($cfg['blog_id']){
$inBlog->whereBlogIs($cfg['blog_id']);
}

$inDB->orderBy('p.'.$cfg['sort'], 'DESC')->groupBy('p.id');
$inDB->limit($cfg['shownum']);

$posts = $inBlog->getPosts(false, $model);
if(!$posts){ return false; }

cmsPage::initTemplate('modules', $cfg['tpl'])->
assign('posts', $posts)->
assign('cfg', $cfg)->
display($cfg['tpl']);

return true;

}

куда нужно вставить Ваш код 

+1
Нил™ Нил™ 3 года назад #

Если вы делали включали автозамену и у в теле развернутого поста она работает, то для модуля нет необходимости править файл который вы приводите здесь. Это в файле шаблона mod_blogs.tpl там добавьте {$post.content_html} — 'nj это вывод содержимого поста в модуле. Если имеется но html контент не отображается возможно там у вас strip_tags стоит — придется убрать

+1
Нил™ Нил™ 3 года назад #

Перечитал немного. Как я понял, выводить видеоплеер в посте вы не планируете и проблема в том, что в списке постов в модуле выводиться id ролика?

Чтобы полностью удалить тег из модуля можете там же где добавляли автозамену задать отдельно для модуля.

$post['content_module']  = preg_replace('|

|isU', '', $post['content_html']);

и в шаблоне модуля вместо {$post.content_html} использовать {$post.content_module}

+1
Нил™ Нил™ 3 года назад #

Короче я не знаю, что тут делает этот плеер, вот содержимое моего предыдущего комментария

видимо на офф сайте тоже работает автозамена, пытался обернуть в тег code но что-то не получилось.

0
Нил™ Нил™ 3 года назад #

Прошу прощения, это уже похоже на флуд, но...

Всё же лучше перейти на способ когда простая ссылка на видоролик youtube преобразовывается в ролик без специального тега, я пользуюсь теперь этим вариантом, это удобнее и в том же модуле у вас просто выведется не активная ссылка — понятное содержимое.

Если же уже МНОГО постов с тегом и не вариант в них что то менять, можно старый код автозамены обернуть в условие с максимальным id поста для которых он будет применяться.

if($post['id'] < 1000){

здесь старая автозамена, сработает для постов с ид не выше 1000

} else {

здесь вариант из комментария https://instantcms.ru/blogs/sekretnye-materialy/av...

}

0
sibroy sibroy 3 года назад #

Спасибо за ответ… будем пробовать

sibroy sibroy 3 года назад #
Комментарий удален

Еще от автора

Капча на сайт или разделы сайта
Если нужно, закрыть весь сайт или некоторые его разделы каптчей.
Пинг поисковых систем для первой ветки
Небольшая интеграция инструментов для пингования, чтобы сделать его чуть удобнее
Генератор карты сайта в формате txt на лету без крона
Вообще то где то тут уже есть вполне рабочие генераторы карты для первой ветки, но этот вариант тоже имеет право быть.
Используя этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.