Меню

настройка http сервера видео

Кирилл Антонов

Тема 1: Базовые понятия, которые нам пригодятся
Модель OSI 7 простыми словами: эталонная модель взаимодействия открытых систем
Модель TCP/IP и ее отличия от эталонной модель OSI
Иерархическая модель
Что такое сервер: серверный компьютер и серверное приложение.
Что такое клиент: клиентский компьютер и клиентское приложение.
Модель взаимодействия клиент-сервер. Архитектура и особенности модели клиент-сервер.
Что такое LAMP, MAMP, XAMP, WAMP?

Тема 2: Основы передачи данных в сетях TCP/IP
Что такое MAC-адрес и зачем он нужен? Устройства второго уровня модели OSI
Что такое IP-адрес и зачем он нужен? Устройства третьего уровня модели OSI
Структура и типы IP-адресов
Маска подсети (сети) и ее назначение в протоколе IP
Классы IP-сетей и чем они отличаются?
Бесклассовая адресация в IP-сети
Специальные и частные (приватные) IP-адреса
Настройка IP-адресов
TCP порт и его назначение. Что такое сокет?
Чем полезна технология NAT и принципы ее работы?
Что такое TTL и за что отвечает данный показатель?
Зачем нужен DNS-сервер и его принцип работы
Типы DNS записей
Что такое URI, URL, URN и их отличия

Тема 3: Полезные Windows утилиты для работы в сети Интернет
ipconfig — утилита командной строки Windows и как ею пользоваться
ping — утилита командной строки Windows и как ею пользоваться
tracert — утилита командной строки Windows и как ею пользоваться
netstat — утилита командной строки Windows и как ею пользоваться
Проверка и мониторинг портов при помощи TCPView
Тестирование пропускной способности канала и генерация трафика при помощи iperf
Анализ трафика компьютерных сетей при помощи Wireshark
Простейший DNS сервер в Windows – файл host
Пишем DNS-запросы в утилите командной строки nslookup
TELNET – протокол текстового интерфейса и одноименная утилита командной строки Windows свернуть

Тема 1: Базовые понятия, которые нам пригодятся
Модель OSI 7 простыми словами: эталонная модель взаимодействия открытых систем
Модель TCP/IP и ее отличия от эталонной модель OSI
Иерархическая модель
Что такое сервер: сервер. ещё

источник

Развертывание многопользовательской WebRTC трансляции с web-камеры через сервер за 3 минуты

В данной статье мы расскажем как разработать многопользовательскую WebRTC видео трансляцию из браузера через свой сервер ретранслятор. Трансляция будет идти из браузера Google Chrome и обычной USB вебкамеры. Для трансляции видео будет создана отдельная HTML — страница Streamer, а воспроизведением будет заниматься HTML-страница Player.

Схема трансляции

Browser1 — транслирующий. Подключается к серверу и транслирует видео с веб камеры.
Browser2, Browser3, Browser4 — зрители. Подключаются и получают видео для воспроизведения. Для ре-трансляции видеопотоков по WebRTC будет использоваться Web Call Server.

Принцип понятен и можно переходить к написанию кода. Создадим две HTML-страницы. Первая будет называться streamer.html и будет отправлять видеопоток на сервер. Вторая будет называться player.html и играть видеопоток с сервера.

Streamer — HTML

В заготовке html-страницы Streamer мы использовали следующие вещи:

Этот скрипт является основным скриптом JavaScript API и его можно найти в последней сборке Web SDK.

2) Div элемент localVideo — это блок, в котором будет размещено видео, захваченное с вебкамеры.

3) Кнопка Start, по которой будет происходить запуск трансляции с вызовом функции start().

4) Обратите внимание, что в body добавлена обработка события onLoad c вызовом функции инициализации.

5) Элемент с используется для отображения статусов.

Streamer — JavaScript

Переходим к написанию JavaScript — кода. Мы намеренно не используем JQuery, Bootstrap или какие-либо другие фреймворки чтобы оставить код минимальным:

В этом примере всего четыре функции:

Отвечает за инициализацию JavaScript API и берет ссылку на div — элемент localVideo.

Эта функция создает подключение к серверу по протоколу websockets. Адрес подключения: wss://domain:8443. На месте domain должен быть домен вашего WCS сервера (предполагаем, что сервер уже установлен, настроен и имеет выделенный домен, например webrtc.mycompany.com. Порт TCP 8443 должен быть открыт для входящих подключений).

Из кода этой функции понятно, следующим действием после получения статуса ESTABLISHED, будет вызов функции startStreaming и отправка потока на сервер.

Здесь мы создаем новый объект Stream, используя функцию API: session.createStream();. При создании стрима в качестве основных параметров передаются:

● streamName — имя видеопотока
● display — это элемент div, в котором будет отображаться захваченное для данного видеопотока видео с веб-камеры

Читайте также:  настройки iptv модеме acorp

Имя потока желательно генерировать уникальное, но мы для теста используем просто stream222.

Данная функция отображает статус сессии (session) или потока (stream) на HTML-странице.

Выносим наш скрипт в отдельный файл streamer.js. Код страницы streamer.html будет выглядеть так:

Streamer — тестирование

В итоге у нас получилось мини стриминг-приложение, состоящее из трех скриптов:

● streaming.html
● streaming.js
● flashphoner.js

Копируем наши скрипты на web-сервер чтобы начать тестирование. В качестве веб-сервера мы используем Apache 2 со стандартным /var/www/html

В результате наш рабочий стример выглядит так, как показано на скриншоте ниже. После нажатия на кнопку Start, с сервером устанавливается соединение и на сервер отправляется WebRTC видеопоток:

Чтобы убедиться в том, что поток действительно отправляется, переходим во вкладку chrome://webrtc-internals. Здесь можно в режиме реального времени наблюдать что происходит с видеопотоком и отслеживать такие параметры как битрейт, разрешение, фреймрейт, количество отправленных пакетов, RTT и многое другое.

Таким образом, наш стример заработал и WebRTC видеопоток корректно отправляется на сервер, откуда осталось его забрать. Для того чтобы забрать и воспроизвести поток, создадим новую страницу player.html

Player — HTML

Страницу плеера копипастим из стримера, с той лишь разницей, что будем использовать скрипт: player.js вместо streamer.js, и вместо localVideo, зададим id = remoteVideo для нашего div — элемента.

Player — JavaScript

В скрипте плеера также есть некоторые отличия, но подход остается прежним: инициализируется Flashphoner API, по кнопке Start открывается соединение с сервером через websocket, ждет события ESTABLISHED и начинает воспроизведение потока.

Список отличий скрипта player.js от скрипта streamer.js:

● Используется remoteVideo вместо localVideo
● После установки соединения вызываем startPlayback вместо startStreaming
● При создании стрима методом createStream(), передаются параметры receiveAudio=true и receiveVideo=true
● Вызывается метод play() вместо publish()

В результате получаем WebRTC-плеер, состоящий из двух скриптов:

Не забываем, что для работы плеера также необходим файл API flashphoner.js, поэтому копируем файлы плеера в ту же папку на web-сервере.

В итоге наше окончательное приложение для WebRTC онлайн трансляций состоит из пяти файлов:

● streamer.html
● streamer.js
● player.html
● player.js
● flashphoner.js

Приступим к тестированию и снова отправим видеопоток через streamer.html. После этого откроем новую вкладку браузера с player.html и нажмем Start.

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

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

3 минуты

Попробуем развернуть трансляцию за 3 минуты, учитывая следующее:

1) Уже установлен Web Call Server 5 для ретрансляции видеопотоков и настроен SSL. Без настройки SSL / HTTPS, трансляция в Google Chrome работать не будет, так как для доступа к веб камере и микрофону соединение должно быть безопасным и страница, на которой вы тестируете трансляцию должна быть открыта по HTTPS. Порт TCP 8443 открыт и готов принимать соединения по протоколу wss://

2) Уже установлен и сконфигурирован HTTP сервер, например Apache. Web-сервер настроен для работы через HTTPS и имеет FTP/SFTP/SSH доступ, через который можно залить / скачать тестовые скрипты.

WCS5 и Apache могут быть установлены на одной системе либо разнесены по разным серверам. Apache в данном случае просто отдает контент в виде HTML-страниц и скриптов, а WCS5 обслуживает подключения с видео.

Чтобы провести тестирование без установки, можно воспользоваться демо-сервером wss://wcs5-eu.flashphoner.com:8443 — он открыт для коннектов и тестирования.

Минута 1

Загружаем тестовые скрипты и распаковываем в папке /var/www/html на веб-сервере.

Минута 2

Открываем скрипты streamer.js и player.js на редактирование, находим и меняем:

здесь domain.com — доменное имя вашего сервера, на котором установлен WCS5

Минута 3

Открываем streamer.html в браузере по https:// и нажимаем Start. Открываем в новой вкладке player.html и нажимаем Start.

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

Ссылки

Web Call Server 5 — это стриминг медиасервер с поддержкой WebRTC, RTMP и других протоколов для разработки web приложений и мобильных приложений с низкой задержкой видео. Сервер включает в себя Web SDK, Android SDK и iOS SDK для разработки кросс-платформенных видеочатов, онлайн видеотрансляций, трансляций с IP-камер и других приложений потокового видео для браузеров и мобильных устройств.

Читайте также:  настройка доступа в групповых политиках

источник

Создаем сервер для потокового видео: глава из книги по PHP от нашего разработчика

У нас в Skyeng работают весьма талантливые люди. Вот, например, бэкенд-разработчик Words Сергей Жук написал книгу про событийно-ориентированный PHP на ReactPHP, основанную на публикациях его блога. Книга англоязычная, мы решили перевести одну самодостаточную главу в надежде, что кому-то она сможет пригодиться. Ну и дать скидочную ссылку на всю работу.

В этой главе мы рассмотрим создание элементарного асинхронного сервера для видео-стриминга на ReactPHP Http Component. Это компонент высокого уровня, предоставляющий простой асинхронный интерфейс для обработки входящих соединений и HTTP-запросов.

Для поднятия сервера нам потребуются две вещи:
— инстанс сервера (React\Http\Server) для обработки входящих запросов;
— сокет (React\Socket\Server) для обнаружения входящих соединений.

Для начала давайте сделаем очень простой Hello world сервер, чтобы понять, как все это работает.

Основная логика этого сервера заключена в функции обратного вызова, передающейся конструктору сервера. Обратный вызов осуществляется в ответ на каждый входящий запрос. Он принимает инстанс объекта Request и возвращает объект Response . Конструктор класса Response принимает код ответа, заголовки и тело ответа. В нашем случае в ответ на каждый запрос мы возвращаем одну и ту же статическую строчку Hello world.

Если мы запустим этот скрипт, он будет выполняться бесконечно. Работающий сервер отслеживает входящие запросы. Если мы откроем адрес 127.0.0.1:8000 в нашем браузере, мы увидим строку Hello world. Отлично!

Простой стриминг видео

Давайте теперь попробуем сделать что-нибудь поинтереснее. Конструктор React\Http\Response может принять читаемый поток (инстанс класса ReadableStreamInterface ) в качестве тела ответа, что позволяет нам передавать поток данных непосредственно в тело. Например, мы можем открыть файл bunny.mp4 (его можно скачать с Github) в режиме чтения, создать с ним поток ReadableResourseStream и предоставить этот поток в качестве тела ответа:

Для создания инстанса ReadableResponseStream нам нужен цикл событий, мы должны передать его в замыкание. Кроме того, мы поменяли заголовок Content-Type на video/mp4 , чтобы браузер понимал, что в ответе мы посылаем ему видео.

Заголовок Content-Length объявлять не нужно, поскольку ReactPHP автоматически использует chunked transfer и отправляет соответствующий заголовок Transfer_Encoding: chunked .

Давайте теперь обновим окно браузера и посмотрим потоковое видео:

Супер! Мы сделали стриминговый видео-сервер с помощью нескольких строк кода!

Важно создать инстанс ReadableResourseStream непосредственно в функции обратного вызова сервера. Помните об асинхронности нашего приложения. Если мы создадим поток вне обратного вызова и просто передадим его, никакого стриминга не случится. Почему? Потому что процесс чтения видеофайла и обработка входящих запросов сервера работают асинхронно. Это значит, что пока сервер ждет новые соединения мы также начинаем читать видеофайл.

Чтобы убедиться в этом, мы можем использовать события потока. Каждый раз, когда читаемый поток получает данные из своего источника, он запускает событие data . Мы можем присвоить этому событию обработчик, который будет выдавать сообщение каждый раз, когда мы читаем данные из файла:

Когда интерпретатор доходит до последней строки $loop->run(); , сервер начинает ожидать входящие запросы, и одновременно мы начинаем читать файл.

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

Улучшения

Дальше мы попробуем улучшить наш маленький сервер. Допустим, мы хотим дать пользователю возможность указывать имя файла для стриминга непосредственно в строке запроса. Например, при вводе в адресной строке браузере 127.0.0.1/?video=bunny.mp4 сервер начнет стримить файл bunny.mp4. Хранить файлы для стриминга мы будем в директории media. Теперь нам надо каким-то образом получить параметры из запроса. Объект запроса, который мы получаем в обработчике запроса, содержит метод getQueryParams() , возвращающий массив GET, аналогично глобальной переменной $_GET :

Теперь, чтобы посмотреть видео bunny.mp4, мы должны зайти на 127.0.0.1:8000?video=bunny.mp4. Сервер проверяет входящий запрос на параметры GET. Если мы находим параметр video , мы считаем, что это название видеофайла, который хочет увидеть пользователь. Затем мы выстраиваем путь к этому файлу, открываем читаемый поток и передаем его в ответе.

Читайте также:  настройка датчика давления zse30a

Но здесь есть проблемы. Видите их?

— Что если на сервере нет такого файла? Мы должны в этом случае вернуть страницу 404.
— Теперь у нас есть жестко заданное в заголовке значение Content-Type . Нам надо определять его в соответствии с указанным файлом.
— Пользователь может запросить любой файл на сервере. Мы должны ограничить запрос только теми файлами, которые мы готовы ему отдать.

Проверка наличия файла

Прежде чем открыть файл и создать поток, мы должны проверить, существует ли вообще этот файл на сервере. Если нет – возвращаем 404:

Теперь наш сервер не будет падать, если пользователь запросил неверный файл. Мы выдаем правильный ответ:

Определение MIME-типа файла

В PHP есть отличная функция mime_content_type() , возвращающая MIME-тип файла. С ее помощью мы можем определить MIME-тип запрошенного видеофайла и заменить им заданное в заголовке значение Content-Type :

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

Ограничение на запрос файлов

Осталась проблема с запросом файлов. Пользователь может задать любой файл на сервере в строке запроса. Например, если код нашего сервера находится в server.php и мы укажем такой запрос в адресной строке браузера: 127.0.0.1:8000/?video=../server.php, то в результате получим следующее:


Не очень безопасно… Чтобы это исправить, мы можем использовать функцию basename() , чтобы брать только имя файла из запроса, отрезая путь к файлу, если он был указан:

Теперь тот же запрос выдаст страницу 404. Исправлено!

Рефакторинг

Вообще, наш сервер уже готов, но его основная логика, размещенная в обработчике запроса, выглядит не очень. Разумеется, если вы не собираетесь ее менять или расширять, можно оставить и так, непосредственно в обратном вызове. Но если логика сервера будет меняться, например, вместо простого текста мы захотим строить HTML-страницы, этот обратный вызов будет расти и быстро станет слишком путаным для понимания и поддержки. Давайте сделаем небольшой рефакторинг, вынесем логику в собственный класс VideoStreaming . Чтобы иметь возможность использовать этот класс в качестве вызываемого обработчика запроса, мы должны встроить в него волшебный метод __invoke() . После этого нам будет достаточно просто передать инстанс этого класса в качестве обратного вызова конструктору Server :

Теперь можно строить класс VideoStreaming . Он требует одну зависимость – инстанс цикла событий, который будет встроен через конструктор. Для начала можно просто скопировать код из обратного вызова запроса в метод __invoke() , а затем заняться его рефакторингом:

Далее мы будем рефакторить метод __invoke() . Давайте разберемся, что тут происходит:
1. Мы парсим строку запроса и определяем, какой файл нужен пользователю.
2. Создаем поток из этого файла и отправляем его в качестве ответа.

Получается, мы можем здесь выделить два метода:

Первый, getFilePath() , очень прост. Мы получаем параметры запроса с помощью метода $request->getQueryParams() . Если в них нет ключа file , мы просто возвращаем простую строку, показывающую, что пользователь открыл сервер без параметров GET. В этом случае мы можем показать статичную страницу или что-то в этом духе. Здесь мы возвращаем простое текстовое сообщение Video streaming server. Если пользователь указал file в запросе GET, мы создаем путь к этому файлу и возвращаем его:

Метод makeResponseFromFile() также очень прост. Если по указанному пути нет файла, мы сразу же возвращаем ошибку 404. В противном случае мы открываем запрошенный файл, создаем читаемый поток и возвращаем его в теле ответа:

Вот код класса VideoStreaming целиком:

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

Примеры из этой главы можно найти на GitHub.

У Сергея также есть полезный регулярно обновляемый англоязычный блог.

Наконец, напоминаем, что мы всегда находимся в поиске талантливых разработчиков! Приходите, у нас весело.

источник