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

+19
3.13K
Автоматическое преобразование ссылки на видео с ютуба, которая вставлена в посте блога, на стене, на форуме в плеер с этим видео.
Также рассмотрим вывод этого видеоролика в своем стилизованном плеере на базе 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
Реклама Реклама #
0
letsgo letsgo 4 года назад #
Отличное решение.
0
Erwin Erwin 4 года назад #
Радует что первая ветка жива и такие хорошие поправки делаете. Их прям нужно в коробку вносить сразу.
0
surfixx surfixx 4 года назад #
Спасибо за это решение. Поставил плюс. Но есть недостаток, нет резиновости (извиняюсь за каламбур). Я решил это так: в 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
Нил™ Нил™ 4 года назад #
<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
Нил™ Нил™ 4 года назад #
Блин можно уже дать возможность редактировать комменты хотя бы в течении 10 минут hoho
0
surfixx surfixx 4 года назад #
Спасибо за ответ. Хорошее решение, но по мне, много действий в скриптах. Всё это в плагин - вот Би да. Всё равно спас за ваш труд. Молодец.
0
sibroy sibroy 3 года назад #
Как бы сделать такой вывод в комментариях?
+1
Нил™ Нил™ 3 года назад #
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
Нил™ Нил™ 3 года назад #
но после изменения в bbcode.lib.php часть, которая касается блогов и форума и стены тоже надо выполнить, как описано выше
0
sibroy sibroy 3 года назад #
Работает...спасибо
0
sibroy sibroy 1 год назад #
На instantcms1.10.7 в модуле Записи блогов режет тег <youtube>... что можно сделать?
+2
Нил™ Нил™ 1 год назад #
В оригинальном виде в модуле содержимое поста вроде не должно выводиться, у вас какая то модификация, может быть там предусмотрено вырезание тегов?

Кстати, я сейчас не заморачиваюсь с тегом <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
Нил™ Нил™ 1 год назад #
<i style="color:#00acee;" class="fa fa-twitter fa-spin" aria-hidden="true"></i> это иконка из набора font-awesome если не используете, можно удалить
0
sibroy sibroy 1 год назад #
Модуль стандартный...пользуюсь вашим способом с тегом <youtube> уже больше года...вставленных роликов в блоги и комментарии порядочно) Новый способ работает...спасибо)
+1
Нил™ Нил™ 6 месяцев назад #
Тут напомнили про эту тему. Дополню список + автозамена ссылки из телеграм и автозамена ссылки из тик ток.

Код 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
Нил™ Нил™ 6 месяцев назад #
Строка 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 месяца назад #
Комментарий удален
Используя этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.