Несколько западных клиентов обратились с вопросом: как сделать возможность вставки видео при публикации новостей на сайте? На первый взгляд это может показаться сложно, но фактически легко реализуемо. Думаю, русскоговорящим разработчикам задача тоже может быть интересна.
[spoiler]
Идея состоит в том, чтобы для прикреплённого к новости файла подключать компонент "медиа плеер". Для отображения новости будет использоваться компонент news.detail.
1. Для начала заведём свойство типа "Файл" в инфоблоке новостей. Я его назвал movie.
2. Затем скопируем шаблон компонента news.detail в шаблон сайта (я предпочитаю использовать для этого соответствующую кнопку управления компонентом в режиме разработки). Сам компонент менять не придётся.
3. Теперь нам нужен будет код для подключения видео. Для этого я создал новую страницу в визуальном редакторе и кинул на неё нужный компонент и указал базовые настройки (путь к видео файлу пока не заполняем). Копируем следующий код:
<?$APPLICATION->IncludeComponent "bitrix:player" "" Array( "PLAYER_TYPE" => "auto", "USE_PLAYLIST" => "N", "PATH" => "", "WIDTH" => "400", "HEIGHT" => "300", "FULLSCREEN" => "Y", "SKIN_PATH" => "/bitrix/components/bitrix/player/mediaplayer/skins", "SKIN" => "bitrix.swf", "CONTROLBAR" => "bottom", "WMODE" => "transparent", "HIDE_MENU" => "N", "SHOW_CONTROLS" => "Y", "SHOW_STOP" => "N", "SHOW_DIGITS" => "Y", "CONTROLS_BGCOLOR" => "FFFFFF", "CONTROLS_COLOR" => "000000", "CONTROLS_OVER_COLOR" => "000000", "SCREEN_COLOR" => "000000", "AUTOSTART" => "N", "REPEAT" => "N", "VOLUME" => "90", "DISPLAY_CLICK" => "play", "MUTE" => "N", "HIGH_QUALITY" => "Y", "ADVANCED_MODE_SETTINGS" => "N", "BUFFER_LENGTH" => "10", "DOWNLOAD_LINK_TARGET" => "_self" ));?> |
4. Простой путь: в шаблоне компонента вместо свойства movie будем подключать медиа плеер. Находим строки вывода свойств:
<?foreach($arResult["DISPLAY_PROPERTIES"] as $pid=>$arProperty):?> <?=$arProperty["NAME"]?>: <?if(is_array($arProperty["DISPLAY_VALUE"])):?> 34 <?=implode(" / ", $arProperty["DISPLAY_VALUE"]);?> 35 <?else:?> <?=$arProperty["DISPLAY_VALUE"];?> <?endif?> <br /> <?endforeach;?> |
Вставляем проверку и замену, получается:
as $pid=>$arProperty):?> <?if ($arProperty["CODE"]=='movie' && $arProperty["DISPLAY_VALUE"]) {?> <?$APPLICATION->IncludeComponent("bitrix:player", "", Array( "PLAYER_TYPE" => "auto", "USE_PLAYLIST" => "N", "PATH" => CFile::GetPath($arProperty["VALUE"]) "WIDTH" => "400", "HEIGHT" => "300", "FULLSCREEN" => "Y", "SKIN_PATH" => "/bitrix/components/bitrix/player/mediaplayer/skins", "SKIN" => "bitrix.swf", "CONTROLBAR" => "bottom", "WMODE" => "transparent", "HIDE_MENU" => "N", "SHOW_CONTROLS" => "Y", "SHOW_STOP" => "N", "SHOW_DIGITS" => "Y", "CONTROLS_BGCOLOR" => "FFFFFF", "CONTROLS_COLOR" => "000000", "CONTROLS_OVER_COLOR" => "000000", "SCREEN_COLOR" => "000000", "AUTOSTART" => "N", "REPEAT" => "N", "VOLUME" => "90", "DISPLAY_CLICK" => "play", "MUTE" => "N", "HIGH_QUALITY" => "Y", "ADVANCED_MODE_SETTINGS" => "N", "BUFFER_LENGTH" => "10", "DOWNLOAD_LINK_TARGET" => "_self" ), $component );?> <? } else {?> <?=$arProperty["NAME"]?>: <?if(is_array($arProperty["DISPLAY_VALUE"])):?> <?=implode(" / ", $arProperty["DISPLAY_VALUE"]);?> <?else:?> <?=$arProperty["DISPLAY_VALUE"];?> <?endif?> <?}?> <br / <?endforeach;?> |
Здесь следует обратить внимание на следующие моменты:
* для получения пути к файлу из ID используется системный вызов CFile::GetPath (
* при подключении компонентов указан четвёртый параметр $component для того чтобы из публичной части случайно не изменить его параметры (
Собственно всё. Так будет работать.
Оформим красиво!
Если мы хотим чтобы решение не было похоже на "костыли", необходимо:
1. вынести замену свойства в result_modifier.php
Тогда шаблон компонента будет стандартный, а result_modifier.php примет вид:
<?// передадим значение свойства по ссылке:$arProperty = &$arResult['DISPLAY_PROPERTIES'][$arParams['PROPERTY_VIDEO']];if ($arProperty['DISPLAY_VALUE']) // проверим, установлено ли свойство global $APPLICATION ob_start(); // включим буферизацию чтобы отловить вывод компонент $APPLICATION->IncludeComponent "bitrix:player" "" Array "PLAYER_TYPE" => "auto", "USE_PLAYLIST" => "N", "PATH" => CFile::GetPath($arProperty["VALUE"]) "WIDTH" => "400", "HEIGHT" => "300", "FULLSCREEN" => "Y", "SKIN_PATH" => "/bitrix/components/bitrix/player/mediaplayer/skins", "SKIN" => "bitrix.swf", "CONTROLBAR" => "bottom", "WMODE" => "transparent", "HIDE_MENU" => "N", "SHOW_CONTROLS" => "Y", "SHOW_STOP" => "N", "SHOW_DIGITS" => "Y", "CONTROLS_BGCOLOR" => "FFFFFF", "CONTROLS_COLOR" => "000000", "CONTROLS_OVER_COLOR" => "000000", "SCREEN_COLOR" => "000000", "AUTOSTART" => "N", "REPEAT" => "N", "VOLUME" => "90", "DISPLAY_CLICK" => "play", "MUTE" => "N", "HIGH_QUALITY" => "Y", "ADVANCED_MODE_SETTINGS" => "N", "BUFFER_LENGTH" => "10", "DOWNLOAD_LINK_TARGET" => "_self" ); $arProperty['DISPLAY_VALUE'] = ob_get_contents(); // подменим $arResul ob_clean(); // очистим наш буфер чтобы плеер не появился дважд ob_end_clean(); // закроем буфер}?> |
2. символьный код свойства сделать параметром компонента чтобы не привязываться жёстко к конкретному инфоблоку. Для этого доработаем файл .parameters.php, расположенный в шаблоне компонента. У меня он принял вид:
<?if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();$arProps = array(); $rs=CIBlockProperty::GetList(array(),array("IBLOCK_ID"=>$arCurrentValues['IBLOCK_ID'],"ACTIVE"=>"Y"));while($f = $rs->Fetch() $arProps[$f['CODE']] = $f['NAME'];$arTemplateParameters = array "DISPLAY_DATE" => Array "NAME" => GetMessage("T_IBLOCK_DESC_NEWS_DATE") "TYPE" => "CHECKBOX" "DEFAULT" => "Y" ) "DISPLAY_NAME" => Array "NAME" => GetMessage("T_IBLOCK_DESC_NEWS_NAME") "TYPE" => "CHECKBOX" "DEFAULT" => "Y" ) "DISPLAY_PICTURE" => Array "NAME" => GetMessage("T_IBLOCK_DESC_NEWS_PICTURE") "TYPE" => "CHECKBOX" "DEFAULT" => "Y" ) "DISPLAY_PREVIEW_TEXT" => Array "NAME" => GetMessage("T_IBLOCK_DESC_NEWS_TEXT") "TYPE" => "CHECKBOX" "DEFAULT" => "Y" ) "PROPERTY_VIDEO" => Array "NAME" => "Свойство, в котором хранится видео" "TYPE" => "LIST" "VALUES" => $arProp ),);?> |
Вот что получилось:
Не забудьте в параметрах подключения компонента указать свойство, в котором хранится видео, иначе оно выводиться не будет.
Может есть варианты развития идеи? Пишите!
Тогда в $arProperty["DISPLAY_VALUE"] будет приходить уже код подключения плеера, шаблон можно использовать стандартный. Соответственно, в дальнейшем если системный шаблон обновится - можно просто скопировать его поверх своего.
Ход мыслей абсолютно не понятен.
Опишите идею детально.
Вот попробуйте сделать такой юзертайп, с сохранением дополнительных мета-полей (для плеера, видеофайла и т.д.), и при этом не влазя в код ни одной из перечисленных форм и с сохранением возможности фильтрации по значению свойства, тогда ход мыслей сразу станет понятен...
А потом представьте, что на каждый проект требуется по несколько штук подобных юзертайпов делать.
Видео - это частный случай свойства типа "файл". Типов файлов, как известно, много. Сделать для каждого типа свой тип свойства?
Свойство типа "изображение" возвращать в компоненте фотогалерея,
Свойство типа "архив" - обернуть в механизм контролируемого скачивания...
Всё это частные задачи, которые решаются довольно просто. Вот решение одной такой задачи здесь предлагается.
Свойство типа "архив" - обернуть в механизм контролируемого скачивания...
Текущее решение на мой взгляд волне полноценно и логично.
представьте, что чтобы поймать новую радиостанцию радиоприёмником, завод изготовитель выкладывал бы электрические схемы для модернизации оного..
пример не очень удачный, но намёк думаю ясен
Только вот если говорить метафорами, то радиостанций конечное число, а задач с индивидуальной логикой бесконечное.
Не смешите мои клавиши.. Разработчики давно уже написали нечто подобное.. И писать то там особо нечего..
"матерые волки" вон на Старте социальные сети пишут, им конечно это не надо.
Будут интересные идеи и время - буду писать ещё.
Мы на Старте дописали компоненты для публикации ветки обсуждения, для внутренней переписки между пользователями и так далее. Некоторые проекты нуждаются в каком-то ньюансе. ради которого заказчик не согласен на более дорогую версию ))
Здесь я пытался показать саму идею, а не то, как надо выполнять кастомизацию.
В связи с этим возникает вопрос, как можно выполнить постобработку видео файла, после попадания на сервер (закодировать в flv по средствам ffmpeg)
Как кодировать я знаю, вопрос, как заставить битрикс самому это выполнять, запускать кодировщик?
Есть мысли?
Если бы передо мной стояла такая задача, я бы использовал cron.
Через определённые промежутки времени стартует скрипт, который проверяет наличие неперекодированных файлов в папке, перекодирует их в другую папку (далее можно для автоматизации добавлять элемент в инфоблок для нового файла), затем очищает папку от исходных файлов.
Я думаю, тут не должно быть проблем.
Вот концепуия моей реализации:
Имеем: Статический файл в котором сохраняем последний ID обработки, дабы каждый раз не нагружать базу
0) Проверяем блокировку на выполнение, если ее нет, то ставим блок и начинаем выполнение
1) Ищем последние добавленные файлы по расширению, в базе
2) Выполняем перекодировку, в тойже папке что и сам файл, т.к. у файла поменяется расширение на flv
3) Удаляем старый файл
4) Апдейтим базу
5) Сохраняем ID последнего обработанного запроса
6) Снимаем блок
Выполняем в кроне раз в 5 мин, или через агент в битриксе
Но как вы понимаете, это кастыли, хотелось в принципе тоже самое, только чтобы этот скрипт запускался самим битриксом
На мой взгляд второй вариант более правильный (о нём я и говорил) т.к. перекодировка может занять продолжительное время: а значит процесс может быть "пристрелен" по ресурсам.
Если видео файлы не большие и проблем со временем выполнения скриптов нет (и в системе разрешён вызов внешних программ), то самое простое - повесить на событие добавления элемента (OnAfterIBlockElementAdd) обработчик, который будет собственно выполнять перекодировку а затем апдейтить элемент уже новым файлом. Старый можно удалить.
Но! Не допустите ошибку: когда обработчик на добавление элемента сам добавляет элемент может произойти зацикливание процесса. Определите константу при первой обработке, перед началом обработки проверяйте, не "взведена" ли эта константа.
Мне не очень понятно, в чём преимущество такого сложно процесса, который вы описали, против описанного здесь.
Пока кое-что криво, но работа идет полным ходом
P.S. Мне показалось не очень удобным, что нигде не видно, какое видео проигрывает в данный момент.
<?if ($arProperty["NAME"]=='movie' это условие не сможет выполнится ибо равно оно Dbltj yjdjcnb, а не коду? <?if ($arProperty["CODE"]=='movie' && $arProperty["DISPLAY_VALUE"]) Разве не так должно быть?
В тексте поправил.
Но это всё настолько индивидуально, что я бы не стал опираться на эти цифры.
В любом случае всегда есть ftp, там проблем с этим нет.
Ну, да ладно. Допустим, клиент умеет делать и то, и другое. Но мы уже получаем букет:
1) надо уметь выдавать корректное сообщение об ошибке при превышении допустимого размера файла, когда он заливается через форму
2) иметь поле и обработкчик для заливки файла через форму (как раз то, что тут обсуждается)
3) иметь альтернативное поле выбора файла на сервере
В общем, всё реализуемо, но не так просто и радостно, как может представиться.
Да, решение требует доработки под конкретный проект, конкретного пользователя, конкретные условия хостинга.
Не совсем понял про изменения в result_modifier.php.
Неужели можно таким кодом подключить проигрыватель, не изменяя шаблон вывода компонента? (у меня не получилось)? И для чего нужна буферизация?
Буду очень признателен за ссылки и еще больше за объяснения.
Неверный тип файла, либо превышен максимальный размер файла!
Где можно задать размер файла?
Надо разбираться, возможно срабатывают ограничения на хостинге.
Вроде как выполнил Ваши рекомендации, НО не работает.
В конкретной новости, в Битриксе, если в значинии свойств, прописываешь путь к видеоролику вида:
ТО новость просто не сохраняется (нажатие кнопки сохранить не приводит ни к какому результату)...
Если же вместо типа "Файл" использовать "Строка" то сохраняется, но эффекта нет (видео не видно)...
Точна ли Ваша рекомендация?
С уважением, Игорь
Как правильно вставить ролик (ролики) с YouTube (НЕ физические файлы, расположенные на сайте, а именно ссылки на ролики, вида:
Есть ли у кого готовые найденные решения (понятно, что стандартными средствами - никак - только какая-то модификация шаблона сайта)?
Информация в Блоге:
Мне не помогла Либо я что-то делаю не так...
С уважением, Игорь
Результат отрицательный
Если данные читаются из кеша, то плеер не подгружается..Браузер ругается на JS-код вставки плеера. В чем может быть причина? Не грузиться JS-фреймворк плеера?
Без кеша все отлично работает.
Единственный вариант чтобы работало с кешированием - в средине новости делать метку, вроде #VIDEO_ITEM#, потом парсить этот текст и заменять его на видеоплеер.
Их можно вручную подключить.
Например, если написать в result_modifier.php
то если мы используем комплексный компонент bitrix:news, то система не найдет шаблон mytemplate если он будет лежать в папке с шаблоном для комплексного компонента.
Это сработает только если шаблон будет желать в папке /bitrix/templates/site_template/components/bitrix/player/
или в /bitrix/templates/.default/components/bitrix/player/
а если его (что логично) положить в шаблон комплексного компонента /bitrix/templates/site_template/components/bitrix/news/news_template/bitrix/player/ то тогда система шаблон не найдет.
обратите внимание на параметр parentComponent.
Только уже в самом шаблоне компонента, включенного в состав комплексного, нужно передавать $this->__component->__parent вместо $component.
Это для случая с комплексным компонентом.
А вообще я бы избегал подключение подобных компонентов в шаблонах.
таки работает.
+1.
Как лучше и красивее всего обойти эту проблему?
спасибо автору!
и сразу после
<?
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php");
$APPLICATION->SetPageProperty("keywords", "Новости");
$APPLICATION->SetPageProperty("description", "Новости, АО ...");
$APPLICATION->SetTitle("Название сайта, страницы...");
?>
ставите эту строчку:
<script src="/bitrix/components/bitrix/player/mediaplayer/flvscript.js" type="text/javascript"></script>
пока она у меня нормально работает, может быть есть еще другие варианты
ставите эту строчку:
<script src="/bitrix/components/bitrix/player/mediaplayer/flvscript.js" type="text/javascript"></script>
лучше
Делаю так:
1. Добавляю в инфоблок свойство (movie);
2. Создаю элемент инфоблока с указанием файла, файл загружается на сайт;
3. Копирую шаблон компонента и создаю в нем result_modifier.php (рядом с template.php) указанного содержания;
4. Правлю в скопированном шаблоне .parameters.php как указано в "рецепте";
5. В параметрах компонента указываю св-во, в котором хранится видео;
6. В файле детального вывода новости подключаю js плеера.
Пробовал даже на демосайте сделать - все равно не работает! Что я забыл/перепутал?
В default нужно добавить? Путь закачанного файла /upload/iblock/fd6/mvi_0020.avi. В каком виде его внести?
а что нужно прописать?
Чтобы имя свойства с видео передалось в простой компонент.
Задача: есть страница с новостью, в ней вставлен ролик. Если он один, то всё понятно, а как сделать, что б был список, как в видеотеке?
<?=$arResult["DISPLAY_PROPERTIES"]["fail_video"] ["DISPLAY_VALUE"]?>
Но плеер не появляется. Вывожу массив arResult для просмотра - в массиве плеер есть и видео показывается. что может быть?
Элементарный пример - в тексте новости может быть несколько видеороликов, или же нам нужно вставить один видеоролик - но в определенном месте в средине текста.
Щас уже картинками в текст новости никого не удивишь, все хотят видео.
Все права уже проверил где только мог.
4. Простой путь: в шаблоне компонента вместо свойства movie будем подключать медиа плеер. Находим строки вывода свойств:
30 <?foreach($arResult["DISPLAY_PROPERTIES"] as $pid=>$arProperty):?>
31
32 <?=$arProperty["NAME"]?>:
33 <?if(is_array($arProperty["DISPLAY_VALUE"])):?>
34 <?=implode(" / ", $arProperty["DISPLAY_VALUE"]);?>
35 <?else:?>
36 <?=$arProperty["DISPLAY_VALUE"];?>
37 <?endif?>
38 <br />
39 <?endforeach;?> не нашел ни в шаблоне news.list ни в шаблоне компонента news.detail... Я уже не спрашиваю где именно надо копировать шаблон компонента news.detail в шаблон сайта?..
Лично я с трудом прочитал данную инструкцию... Понимаю я может быть чайник в этом деле, но настоятельно рекомендую Вам, Шаромов Денис, писать более подробные инструкции!!!
P.S. Новую страницу создать где угодно из публичного или администраторского интерфейса.
Можно даже вручную ее создать (хотя это явно не ваш вариант).
Нужный компонент выбрать с списке компонентов в визуальном редакторе.
Копировать код необходимо при редактировании страницы как php.