Как создания видео потока php
Перейти к содержимому

Как создания видео потока php

  • автор:

Потоковая трансляция видео — как правильно?

Необходимо передавать видео-потоки из клиента C++ на сервер с возможностью просматривать видео в браузере. Текущая «самодельная» реализация выглядит так: Клиент захватывает кадр с веб-камеры, сжимает в jpeg и отправляет POST запросом на HTTP-сервер (в заголовках ID клиента и Content-Type: image/jpeg\r\nContent-Transfer-Encoding: binary ). Серверный скрипт PHP записывает кадр ( file_get_contents(‘php://input’) ) по числовому ID в область разделяемой памяти ( shmop_open / shmop_write ). Такая перезапись по ID происходит каждый кадр — 20-25 раз в секунду. Страничка просмотра также запрашивает каждый кадр при помощи onload тега img — как только кадр обновился идёт запрос следующего. То есть по одному клиенту получается до 50 запросов в секунду! А клиентов около 60 и просматривать их могут около 30 пользователей одновременно. Проблема в следующем: Сервер Apache на Windows через некоторое время работы грузит выделенные ему 4 виртуальных ядра Xeon-а 3.7 гГц на 100% и просмотр становится просто невозможным. И ещё иногда апач крашится. Подскажите пожалуйста, как правильно реализовать данную задачу по прямой трансляции с веб-камер, чтобы сервер не «задыхался» и был приемлемый ФПС при просмотре многих клиентов многими пользователями? Как делается потоковая передача видео-файлов (чтобы не jpeg-и слать, а дописывать/обновлять видео-файл)? Какие технологии для этого подходят лучше? Как, например, реализованы лайв-стримы в том же ю-тубе или тв-каналах? PS: в клиенте используется OpenCV со всеми зависимостями (статическая линковка), и динамическая библиотека ffpmeg в рамках её необходимости для OpenCV — наращивать количество зависимостей и dll не желательно.

Отслеживать

задан 10 апр 2017 в 7:15

2,273 1 1 золотой знак 16 16 серебряных знаков 27 27 бронзовых знаков

Изучите ffmpeg и gstreamer.

10 апр 2017 в 8:22

Websockets? socketo.me/docs ?

10 апр 2017 в 23:53

@E_p, да перейти на веб-сокеты и отказаться от разделяемой памяти было бы здорово. Но я с ними никогда не работал и не могу сложить в голове всю картину взаимодействия клиента C++, сервера и браузера на веб-сокетах. Может есть небольшой пример хотя бы для связки сервер-браузер, чисто как отправная точка для дальнейшего изучения?

Как сделать потоковое видео на сайте.

Видео на сайте
Как организовать потоковое видео на своем сайте или проигрывание mp3 файлов?
Как транслировать онлайн вещания (rtmp потоки), а так же ролики из Youtube?

В этой статье я расскажу как установить на сайте плеер и показывать видео прямо с вашего сайта.
Разговор пойдет только об установке и настройке плеера, а уж как вы будете грузить файлы на свой сайт, это уже другая тема.

Воспроизведение видео на сайте делится на две основных части, трансляция RTMP потока и воспроизведение обычного файла.

1.
RTMP поток. Чаще всего используется для трансляции видео с вебкамер и трансляции телевидения в реальном времени. Иногда используется и для воспроизведения видеофайлов. RTMP канал транслирует информацию со скоростью воспроизведения, поэтому даже при воспроизведении файла его нельзя скачать целиком, можно только записать трансляцию со скоростью воспроизведения.

2.
Потоковое воспроизведение файла.
Обычный стандартный вариант воспроизведения видео. Файл скачивается частями (с вашего сервера или чужого) в буфер и показывается в плеере, то что скачалось.

Вот об этих двух вариантах и расскажу.
Некоторые используют встроенные в систему плееры, и вызывают их с использованием специальной команды, но если кто-то посетит ваш сайт с другой операционной системой, то не увидит уже видео, так как в другой операционке этого плеера может и не быть.
Поэтому я рекомендую использовать плееры JW FLV Media Player или TarantinovFLV.
Будет работать под любой операционной системой и в любом браузере.
Главное, чтобы в браузере был flash и javascript.
Плеер будет загружаться в браузер посетителя с вашего сайта.
JW FLV Media Player способен воспроизводить не только видео, но еще музыку и картинки.
На сайте разработчиков вы найдете всю необходимую информацию на английском, а так же разные версии проигрывателей.

JW FLV Player способен воспроизводить потоковое видео в формате FLV или MP4, а так же RTMP каналы.
FLV достаточно распространный формат для воспроизведения потокового видео в интернете, очень подходит для наших целей.

Воспроизведение видеофайлов.
Как создать FLV.
Для создания flv или MP4, вам потребуется конвертер.
В интернете можно найти большое количество конвертеров, например Total Video Converter.
Очень простой в работе конвертер, открываете любое видео в нем и выбираете в какой формат конвертировать, дальше он все сделает сам.
Если хотите, можете настроить качество конвертируемого видео в настройках.

Итак, видео сконвертировали, теперь скачивайте плеер JW FLV Media Player.
Из всех файлов нужны только player.swf и swfobject.js.
Все остальное можно выбросить.
Загружайте эти два файла и видео куда-то на свой сервер.

Теперь просто втыкаете в нужном месте на странице такой html

Здесь можно написать что то, если вдруг не будет грузится плеер. Возможно не включен flash в браузере.

Пример локального воспроизведения файла

Здесь можно написать что то, если вдруг не будет грузится плеер. Возможно не включен flash в браузере.

Пример воспроизведения ролика youtube

Здесь можно написать что то, если вдруг не будет грузится плеер. Возможно не включен flash в браузере.

Пример воспроизведения RTMP

Здесь можно написать что то, если вдруг не будет грузится плеер. Возможно не включен flash в браузере.

Если вы все сделали правильно, то вы увидите черное окно плеера, при нажатии на воспроизведение начнет показывать видео.

Разбор этого кода.


Загрузка вспомогательного класса, который упрощает использование флеш на сайте. Указывайте путь где лежит этот файл.

var so = new SWFObject(‘player.swf’,’mpl’,’400′,’250′,’8′);
Указываем теперь этому классу где лежит плеер и задаем настройки флеш.

Краткий синтаксис класса SWFObject:

var so = new SWFObject(swf, id, width, height, version, background-color);
swf — Путь к плееру.
id — ID вашего объекта (что угодно можно указать).
width — Ширина плеера.
height — Высота плеера.
version — Требуемая версия флеш.
background-color — Цвет фона.

so.write(‘player’);
Здесь указываем в каком месте загрузить плеер.
В конкретном примере плеер грузится между тегами

so.addParam(‘allowfullscreen’,’true’);
Разрешить использовать полноэкранный режим.
Для выключения нужно установить false.

so.addParam(‘flashvars’,’file=video.flv’);
А это вызов самого видео файла, может быть не только локальный, можно указать удаленный файл через http://.

so.addParam(‘flashvars’,’file=http://www.youtube.com/watch?v=O6ExAru7s58′);
А вот так можно вызвать ролик youtube. Вместо имени файла указываете страницу youtube где размещен ролик.

so.addParam(‘flashvars’,’file=2×2.sdp&provider=rtmp&streamer=rtmp://213.21.0.16/2×2′);
А вот так вызывается RTMP поток. Тут добавлены две переменные provider и streamer. О них ниже.

А сейчас об остальных настройках плеера.
Все настройки плееру передаются через so.addParam(‘flashvars’,'[. ]’);
Передача параметров происходит по принципу переменных в ссылках.
Например, если вам нужно чтобы при загрузке страницы видео начинало воспроизводится автоматически, нужно изменить наш пример так:
so.addParam(‘flashvars’,’file=video.flv&autostart=true’);
То есть за автоматическое воспроизведение отвечает параметр autostart=true.
Параметры указываются через &.
Если в параметрах встречаются данные символы, их нужно заменять.
? > %3F
= > %3D
& > %26
Все файлы, которые можно вызывать в параметрах могут быть удаленными, то есть можно указывать полный адрес через http://

Переменные плеера JW FLV:

Название Описание Возможные значения
Общие переменные
image Путь к файлу изображения, которое показывается в плеере, когда не идет показ видео(превью для видео)
start( 0 ) С какой секунды начинать воспроизведение
duration( 0 ) Максимальная продолжительность в секундах. Если не указать, воспроизводится до конца.
link Ссылка. Если указать ссылку, то в панели плеера появится значек ссылки, при нажатии откроется указанная страница в браузере.
file Файл для показа в плеере(музыка mp3, изображение или видео). Либо плейлист. Про плейлисты ниже.
provider Указывает, какой тип данных будет обрабатываться. По умолчанию определяет тип по расширению файла, но если плеер не может опознать тип содержимого, можно указать вручную. video — стандартный видео файл FLV / MP4.
sound — музыкальный MP3 файл.
image — JPG/GIF/PNG изображение.
youtube — видео из YouTube.
http — FLV/MP4 видео файл, воспроизводимый в псевдопотоке.
rtmp — воспроизведение RTMP потока.
streamer Указывается RTMP канал для воспроизведения, например
file=2×2.sdp&provider=rtmp&streamer=rtmp://213.21.0.16/2×2
указан файл, тип содержимого и адрес канала
Цвета
backcolor Цвет контрольной панели, на которой находятся кнопочки управления, а так же фон плейлиста.
frontcolor Цвет содержимого контрольной панели(кнопочки, тексты и т.д.), а так же цвет текстов в плейлисте
lightcolor Цвет некоторых элементов, например цвет громкости звука(включенного), цвет строки, показывающей пройденное время ролика после ползунка
screencolor Цвет фона дисплея плеера
Расположение
controlbar ( bottom ) Расположение панели. bottom -снизу
over -наложено на видео и исчезает при воспроизведении
none -нет панели.
playlist ( none ) Расположение плейлиста. bottom -снизу
over -располагается на дисплее, при начале воспроизведения исчезает до остановки видео,
right -справа,
none -нет плейлиста.
playlistsize ( 180 ) Размер плейлиста. Если плейлист расположен справа, то это ширина плейлиста, если плейлист расположен снизу, тогда это высота
skin Путь к скину плеера. не много скинов можно скачать здесь http://www.longtailvideo.com/addons/skins
Действие
autostart ( false ) Автоматическое воспроизведение после загрузки страницы false -нет
true -да
bufferlength ( 1 ) Буферизация перед стартом. Количество секунд, которые нужно скачать перед тем, как начать воспроизведение
displayclick ( play ) Действие, выполняемое при нажатии на дисплей плеера play -воспроизведение/пауза
link -переход по ссылке указанной в параметре link
fullscreen -переход в полноэкранный режим
none -ничего не делать
mute -выключить звук
next -следующий ролик в плейлисте.
icons ( true ) Показывать в центре экрана значек воспризведения и буферизации. true -да
false -нет
item ( 0 ) Номер ролика в плейлисте, который воспроизводится по умолчанию. отсчет начинается с нуля.
logo Картинка-логотип jpg, png или gif. В скине по умолчанию крепится в верхний правый угол, но в разных скинах это расположение может меняться
mute ( false ) Загрузка плеера с изначально выключенным звуком. false -звук включен
true -звук выключен.
quality ( true ) Включает улучшеное качество воспроизведения видео при загрузке. Можно переключать правой кнопкой мыши через меню. true -включено
false -выключено
repeat ( none ) Повтор роликов list -показывает поочереди ролики в плейлисте и остановится при окончании плейлиста.
always -крутит все ролики в плейлисте по кругу без конца.
single -повторяет один ролик по кругу.
none -нет повтора
resizing ( true ) Разрешить изменять размер видео в зависимости от размеров плеера. true -да
false -нет
stretching ( uniform ) Подгоняет размеры видео exactfit -не пропорционально, заполняет весь экран по ширине и высоте.
uniform -пропорционально заполняет экран плеера, показывая всю картинку видео(заполняя большие стороны фоном).
fill -пропорционально заполняет весь экран по минимальным сторонам, уводя часть видео за пределы экрана.
none -не меняет размеры видео.
volume ( 90 ) уровень звука плеера при старте. от 0 до 100
Внешние переменные
abouttext При нажатии правой кнопкой мыши будет виден этот тект, как владельца. Вносить сюда свой текст разрешается только при использовании коммерческой лицензии.
aboutlink Ссылка которая срабатывает при нажатии на тексте abouttext. Тоже менять запрещено без коммерческой лицензии.

Это почти все настройки, осталось несколько мелких переменных, о них не стал писать, так как не смог протестировать их.
Все переменные описаны здесь http://developer.longtailvideo.com/trac/wiki/FlashVars

Так же можно воспользоваться онлайн конструктором плеера.
Заполняя необходимые поля формы вы в онлайне создаете готовый код плеера для установки на своем сайте.
Конструктор http://www.longtailvideo.com/support/jw-player-setup-wizard

А сейчас не много о плейлисте.
Очень удобная вещь.
Можно загрузить не один ролик, а сразу несколько в пределах одного плеера.
Вот пример вывода плеера с плейлистом
so.addParam(‘flashvars’,’ file=pl.xml&playlist=right ‘);
Здесь уже в переменной file указывается не файл с видео, а xml файл плейлиста.

Пример xml файла плейлиста:

Этот плеер понимает много форматов xml, я взял самый понятный и простой.
В данном примере два ролика, можете пихать сюда больше.
Как видите в плейлисте все понятно без лишних комментариев.
Самое главное, кодировка файла должна быть UTF-8.

Вот и все.
Установили и настроили видео.

Программа успеха

Всем понятно, что защитить свое видео от скачивания невозможно. Тот, кто хочет все равно скачает. Но, можно затруднить данное действие. Если ориентироваться на обычных пользователей, которые просто смотрят, достаточно будет превратить свое видео в поток. Это закроет доступ к нему всем качалкам, таким как Mediaget или Internet Download Manager.
Итак, превратить видео файл в потоковое видео довольно просто. Достаточно сделать следующее:

Шаг 1. Создаем файл потока

Файл потока представляет собой обычный PHP файл. Назовем его streamer.php

Шаг 2. Заголовки

Понятно, что если подсунуть плееру файл PHP, то он не поймет, что с ним делать и, скорее всего, Вы не получите никакого результата. Для того, что бы плеер понял, что это не просто PHP файл, а видео, нужно сказать об этом. Делается при помощи оператора header .

header('Content-type: video/mp4');

Это еще не все. Мы сказали, что мы не PHP файл, а мы видео файл в формате mp4. Теоретически, этого достаточно, но как показывает практика, для нормальной работы нужно еще отправить размер файла.

$file = 'myvideo.mp4'; $file_length = filesize($file); header('Content-Length: ' . $file_length);

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

header('Cache-Control: no-store, no-cache, must-revalidate'); header('Cache-Control: post-check=0, pre-check=0', false); header('Pragma: no-cache');

Шаг 3. Вывод

Осталась самая простая часть. По сути нужно всего лишь вывеси содержимое файла.

$fh = fopen($file, 'rb'); while (!feof($fh))  print (fread($fh, filesize($file))); > fclose($fh);

Шаг 4. Использование

Использование довольно простое. В качестве ресурса видео нужно указать ссылку на файл потока.

Шаг 5. Защита

Защита, конечно же, не совершенна, но используя поток вместо основного файла, есть смысл закрыть прямой доступ к видеофайлу. Сделать это можно при помощи директив Apache в файле .htaccess.

Files ~ «\.(flv|mp4)»> order allow,deny deny from all Files>

Известные проблемы

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

Поделиться

  • Получить ссылку
  • Facebook
  • Twitter
  • Pinterest
  • Электронная почта
  • Другие приложения

Видеосервис своими руками и организация псевдостримминга

Сегодня я расскажу как работают «видеохостинги» и мы разработаем свой «видеосервис» для закачивания видео-файлов, с последующим конвертирование и созданием картинки для превью. Далее организуем показ во флеш-плеере и эмулируем стримминг (для перемотки на не загруженные части видео-файла).

Для всего этого нам понадобиться:

  • Флеш-плеер для проигрывания видео-файлов — flowplayer
  • Программа для конвертирования видео-файлов — ffmpeg
  • Расширение PHP для получения превью-изображения — php-ffmpeg и библиотека для работы с графикой — GD
  • Эмуляция потокового видео (псевдостримминг) с помощью утилиты yamdi, модуля для nginx — http_flv_module и плагина для flowplayer — flowplayer.pseudostreamming

scheme-medium

Серверная ОСь по традиции — FreeBSD.

Установка необходимых нам утилит

ffmpeg

Для того чтобы конвертировать видео, нам необходимо установить утилиту ffmpeg. Есть еще аналогичная утилита — mencoder, тоже очень хорошая, но ffmpeg более популярен, поэтому именно его буду сейчас использовать. Эти утилиты с переменным успехом конкурируют между собой, поэтому также рекомендую посмотреть на mencoder в свободное время.

# cd /usr/ports/multimedia/ffmpeg # make config 

и выбираем LAME (lame MP3 codec)

# make install 
yamdi

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

# cd /usr/ports/multimedia/yamdi # make install 
nginx

Теперь подошло время для nginx, который будет отдавать индексируемый (с помощью yamdi) видео-файл. На его месте может быть и lighttpd или еще какой-нибудь другой веб-сервер. Но я поддержу отечественного производителя! 🙂

# cd /usr/ports/www/nginx # make config 

и выбираем HTTP_FLV_MODULE, далее

# make install 

Ну или просто при установке укажите опцию "--with-http_flv_module".

Можно конечно использовать в качестве бекенда - PHP, например с помощью такого кода:

$start = (int) @$_GET['position']; if ($start < 0) die("You fucking idiot"); // open file for reading $fp = fopen($file, 'r+'); $fsize = filesize($file); if ($start >0) < // seek to requested position fseek($fp, $start); // FLV header for the movie part. Magic. Just trust me. // Header code is completely taken from flv4php project $header = "FLV" . pack('C', 1 ) . pack('C', 5 ) . pack('N', 9 ) . pack('N', 9 ); header("Content-Length: " . (strlen($header) + $fsize - $start)); echo $header; >else < header("Content-Length: " . $fsize); >set_time_limit(0); while(!feof($fp)) < print(fread($fp, 1024)); usleep(1000);// limit download speed >fclose($fp); 

Но мне удобнее использовать для этого модуль nginx'а, да и быстрее будет.

php5-ffmpeg

Это расширение PHP нам понадобиться для того чтобы получать информацию о видео-файле, а также для получения видео-фрейма для превью. Также необходимо установить библиотеку GD и сам PHP в частности.

# cd /usr/ports/graphics/php5-ffmpeg # make install 

Можно конечно получать информацию путем обращения к

# ffmpeg -i /path/filename.flv

и делать превью

# ffmpeg -i /path/filename.flv -an -ss ВРЕМЯ_ПОЗИЦИИ_В_СЕКУНДАХ -r 1 -vframes 1 -s 320x240 -y -f mjpeg /path/filename.jpg

Но мне нравиться использовать расширение, это удобнее.

И перегрузите apache или nginx, смотря как вы используете PHP.

Конвертирование видео и получение изображения для превью

Для начала нам надо указать путь до исходного и результирующего файлов, прописать пути до превью-файлов, а также указать минимальную позицию фрейма для создания превью.

// Путь до залитого видео-файла, например временный файл полученный по $_FILES['tmp_file'] $inputPath = $_FILES['tmp_file']; //Путь до результирующего файла, то есть отконвертированный и прошитый мета-данными видео-файл $outputPath = "/path/video/filename.flv"; // Указываем минимальную позицию фрейма для захвата превью $previewFrameMin = '3'; // Путь до превью-файла $previewPath = "/path/preview/filename.jpg"; // Путь до мини-превью $previewMiniPath = "/path/preview/filename_mini.jpg"; // Массив для сбора ошибок $errorInfo = array(); 

Конвертируем исходный файл во временный, в формате FLV и разрешением 320x240, использую в качестве аудио-кодека mp3lame с частотой 44100, остальные настройки по умолчанию. Временный файл нужен для того, чтобы yamdi смог вшить мета-данные, так как он не может вшить в исходный файл.

/* * Конвертируем FLV во временный файл ($outputPath . '_temp'). */ passthru( '/usr/local/bin/ffmpeg -i ' . escapeshellarg($inputPath) . ' -f flv '. ' -s 320x240 '. ' -acodec libmp3lame '. ' -ar 44100 '. escapeshellarg($outputPath . '_temp'), $errorInfo['ffmpeg'] ); 

Прошиваем в видео-файл мета-данные для индексирования. Утилита yamdi написана на Си и работает очень быстро! А также удаляем временный файл.

/* * Прошиваем metadata (позиции ключевых фреймов) для перемотки */ passthru( '/usr/local/bin/yamdi -i ' . escapeshellarg($outputPath . '_temp') . ' -o ' . escapeshellarg($outputPath), $errorInfo['yamdi']); /* * Удаление временного файла, он нам уже не нужен. */ unlink($outputPath . '_temp'); 

Теперь получаем информацию о видео-файле и получаем объект фрейма для превью.

/* * С помощью расширения php5-ffmpeg получаем информацию о видео-файле */ $movie = new ffmpeg_movie($outputPath); /* * Вычисляем время воспроизведения видеофайла */ $duration = $movie->getDuration(); /* * Вычисляем количество кадров */ $frameCount = $movie->getFrameCount(); /* * Вычисляем позицию фрейма для его захвата */ $framePosition = ($frameCount > $previewFrameMin) ? $frameCount / 2 : $previewFrameMin; /* * Получаем объект фрейма для превью */ $preview = $movie->getFrame($framePosition); 

А теперь получим и сохраним наши превьюшки.

/* * Записываем в файл - Превью (320x240) */ imagejpeg ($preview->toGDImage(), $previewPath); /* * Записываем в файл - Мини-превью (160x120) */ $previewMini = imagecreatetruecolor(160, 120); $r = imagecopyresized( $previewMini, $preview->toGDImage(), 0, 0, 0, 0, 160, 120, 320, 240 ); imagejpeg($previewMini, $previewMiniPath); 

Все, файл отконвертирован в FLV и прошит мета-данными, также созданы превью, теперь займемся выводом видео-файла - клиенту.

Плеер и показ видео

Почему flowplayer?

Сначала нам понадобится флеш-плеер, умеющий проигрывать видео в формате FLV и показывать картинки в формате JPEG (для превью).

Из всех аналогов (смотрите ниже, в "Полезные ссылки -> Видео-плееры") мне больше всего понравился flowplayer, он:

  • Кроссбраузерный и очень гибкий, и удобный в настройке
  • Бесплатный для некоммерческого использования, а коммерческая версия стоит его возможностей!
  • Имеет Flash и Javascript API, также поддерживает библиотеку JQuery (там доп. фишки какие-то)
  • Имеет кучу полезных плагинов
  • Умеет работать со стриммингом и псевдостриммингом
  • Легко поменять шаблоны оформления и языковые шаблоны для настройки локализованного интерфейса
  • Обширная документация, имеет достаточно большое сообщество в собственном форуме, а также оказывает бесплатную поддержку для коммерческой версии
  • Поддерживает плейлисты и имеет полноэкранный режим
  • Поддерживаемые форматы: FLV, SWF, MP3, MP4, H.264 video, JPG, PNG
  • Сырцы открыты!

flowplayer

Настройка flowplayer

С плеером мы определились, теперь надо его настроить для показа видео. В дистрибутив плеера входит:

  • flowplayer-3.1.1.swf - сам плеер
  • flowplayer.controls-3.1.1.swf - flash-controls
  • flowplayer-3.1.1.min.js - это так называемый js-api

Итак, приступим:

    
Настройка http_flv_module

Теперь настроим nginx на отдачу файла со смещением, для эмуляции стримминга.

location ~ \.flv$ < flv; root /path/video; >

То есть, говорим nginx'у чтобы он для расширения "flv" использовал модуль http_flv_module и указываем в root путь до видео-файлов. Документация по http_flv_module: Директивы модуля ngx_http_flv_module

Ну вот и все, теперь у вас полноценный "видеосервис"!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *