Table of Contents |
---|
Описание
...
Видеопоток захватывается с RTSP-источника, отдающего аудио и видео в поддерживаемых кодеках. Далее видеопоток трансформируется на стороне сервера для воспроизведения в браузерах и мобильных устройствах.
RTSP-источники
- IP камеры
- Медиасерверы
- Системы наблюдения
- Конференц-серверы
Поддерживаемые кодеки
- H.264
- VP8
- AAC
- G.711
- Speex
Поддерживаемые платформы и браузеры
Chrome | Firefox | Safari 11 | Internet Explorer | Edge | |
---|---|---|---|---|---|
Windows | + | + | + | + | |
Mac OS | + | + | + | ||
Android | + | + | |||
iOS | - | - | + |
Схема работы
- Браузер соединяется с сервером по протоколу Websocket и отправляет команду play.
- Сервер соединяется с RTSP-источником и отправляет команду play.
- RTSP-источник передает на сервер RTSP-поток.
- Сервер трансформирует поток в WebRTC и отдает поток браузеру.
Настройка
В некоторых случаях, например, если подключение к IP-камере для захвата потока по RTSP производится через VPN, RTSP-клиент должен быть привязан к определенному адресу. Адрес указывается при помощи опции rtsp_client_address в файле настроек flashphoner.properties, например
Code Block | ||||
---|---|---|---|---|
| ||||
rtsp_client_address=172.16.0.3 |
Краткое руководство по тестированию
Захват видеопотока с IP-камеры и трансляция в браузер
1. Для теста используем:
- демо-сервер demo.flashphoner.com;
- веб-приложение Player для захвата и воспроизведения потока
2. Откройте веб-приложение Player, укажите в поле "Stream" URL веб-камеры:
3. Нажмите кнопку "Start". Начнется трансляция захваченного потока.
4. Графики WebRTC internals:
Управление захватом видеопотока с IP-камеры при помощи REST API
Как правило, для захвата потока с IP-камеры достаточно указать URL-камеры в качестве имени потока при его создании. Однако, при необходимости, возможно управлять захватом RTSP-потока при помощи REST API.
Тестирование
1. Для теста используем:
- демо-сервер demo.flashphoner.com;
- браузер Chrome и REST-клиент для отправки запросов на сервер;
- веб-приложение Player для воспроизведения захваченного потока в браузере.
2. Откройте REST-клиент. Отправьте запрос /rtsp/startup, указав в параметрах URL веб-камеры:
3. Убедитесь, что поток захвачен сервером. Для этого отправьте запрос /rtsp/find_all:
4. Откройте веб-приложение Player, укажите в поле "Stream" URL веб-камеры и нажмите Start. Начнется воспроизведение потока в браузере:
5. Отправьте запрос /rtsp/terminate, указав в параметрах URL веб-камеры:
6. Воспроизведение потока прервется с ошибкой:
REST-вызовы
REST-запрос должен быть HTTP/HTTPS POST запросом в таком виде:
- HTTP: http://test.flashphoner.com:8081/rest-api/rtsp/startup
- HTTPS: https://test.flashphoner.com:8444/rest-api/rtsp/startup
Здесь:
- test.flashphoner.com - адрес WCS-сервера
- 8081 - стандартный REST / HTTP порт WCS-сервера
- 8444 - стандартный HTTPS порт
- rest-api - обязательная часть URL
- /rtsp/startup - используемый REST-метод
REST-методы и статусы ответа
REST-метод | Пример тела REST-запроса | Пример тела REST-ответа | Статусы ответа | Описание | |||||||
---|---|---|---|---|---|---|---|---|---|---|---|
/rtsp/startup |
| 409 - Conflict 500 - Internal error | Извлечь RTMP-поток по указанному URL | ||||||||
/rtsp/find_all |
| 200 – потоки найдены 404 – потоки не найдены | Найти все извлеченные RTMP-потоки | ||||||||
/rtsp/terminate |
| 200 - поток завершен 404 - поток не найден | Завершить извлеченный RTMP-поток |
Параметры
Имя параметра | Описание | Пример |
---|---|---|
uri | URL RTSP-потока | |
status | Текущий статус потока | PLAYING |
Последовательность выполнения операций (Call Flow)
Ниже описана последовательность вызовов при использовании примера Player
1. Установка соединения с сервером.
Flashphoner.createSession(); code
Code Block | ||||
---|---|---|---|---|
| ||||
Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function(session){
setStatus(session.status());
//session connected, start playback
playStream(session);
}).on(SESSION_STATUS.DISCONNECTED, function(){
setStatus(SESSION_STATUS.DISCONNECTED);
onStopped();
}).on(SESSION_STATUS.FAILED, function(){
setStatus(SESSION_STATUS.FAILED);
onStopped();
}); |
2. Получение от сервера события, подтверждающего успешное соединение.
ConnectionStatusEvent ESTABLISHED code
Code Block | ||||
---|---|---|---|---|
| ||||
Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function(session){
setStatus(session.status());
//session connected, start playback
playStream(session);
}).on(SESSION_STATUS.DISCONNECTED, function(){
...
}).on(SESSION_STATUS.FAILED, function(){
...
}); |
3. Запрос на воспроизведение потока.
session.createStream(), stream.play(); code
URL IP-камеры передается в метод createStream() как имя потока
Code Block | ||||
---|---|---|---|---|
| ||||
function playStream(session) {
var streamName = $('#streamName').val();
var options = {
name: streamName,
display: remoteVideo,
flashShowFullScreenButton: true
};
...
stream = session.createStream(options).on(STREAM_STATUS.PENDING, function(stream) {
...
});
stream.play();
} |
4. Запрос от WCS к RTSP-источнику на трансляцию потока.
5. Трансляция RTSP-потока
6. Получение от сервера события, подтверждающего успешный захват и проигрывание потока.
StreamStatusEvent, статус PLAYING code
Code Block | ||||
---|---|---|---|---|
| ||||
stream = session.createStream(options).on(STREAM_STATUS.PENDING, function(stream) {
...
}).on(STREAM_STATUS.PLAYING, function(stream) {
$("#preloader").show();
setStatus(stream.status());
onStarted(stream);
...
});
stream.play();
|
7. Отправка аудио-видео потока по WebRTC
8. Остановка воспроизведения потока.
stream.stop(); code
Code Block | ||||
---|---|---|---|---|
| ||||
function onStarted(stream) {
$("#playBtn").text("Stop").off('click').click(function(){
$(this).prop('disabled', true);
stream.stop();
}).prop('disabled', false);
$("#fullScreenBtn").off('click').click(function(){
stream.fullScreen();
}).prop('disabled', false);
$("#volumeControl").slider("enable");
stream.setVolume(currentVolumeValue);
} |
9. Получение от сервера события, подтверждающего остановку воспроизведения потока.
StreamStatusEvent, статус STOPPED code
Code Block | ||||
---|---|---|---|---|
| ||||
stream = session.createStream(options).on(STREAM_STATUS.PENDING, function(stream) {
...
}).on(STREAM_STATUS.PLAYING, function(stream) {
...
}).on(STREAM_STATUS.STOPPED, function() {
setStatus(STREAM_STATUS.STOPPED);
onStopped();
}).on(STREAM_STATUS.FAILED, function(stream) {
...
}).on(STREAM_STATUS.NOT_ENOUGH_BANDWIDTH, function(stream){
...
});
stream.play(); |
Повторное использование подключения к камере
Если к потоку, захваченному с RTSP IP-камеры, присоединяются другие подписчики, будет использовано ранее установленное подключение к камере, при условии, что все подписчики указали одинаковый адрес камеры. Например, запросы к одной и той же камере
Code Block | ||||
---|---|---|---|---|
| ||||
rtsp://host:554/live.sdp |
и
Code Block | ||||
---|---|---|---|---|
| ||||
rtsp://host:554/live.sdp?p=1 |
отличаются, поэтому будет создано два RTSP-подключения, если запросить оба этих потока.
Аутентификация при захвате потока
WCS поддерживает аутентификацию по имени и паролю при захвате RTSP-потока. данные пользователя должны быть указаны в URL потока, например
Code Block | ||||
---|---|---|---|---|
| ||||
rtsp://user:password@hostname/stream |
Если в имени или пароле есть какие-либо спецсимволы, они должны быть экранированы. например
Code Block | ||||
---|---|---|---|---|
| ||||
rtsp://user:p%40ssword@hostname/stream |
Здесь
- user - имя пользователя
- p@ssword - пароль, символ '@' экранирован при указании URL.
Известные проблемы
Excerpt Include | ||||||
---|---|---|---|---|---|---|
|
5. Соединение с IP-камерой разрывается при ошибке в любом из треков (аудио или видео)
Симптомы: соединение с IP-камерой разрывается, если один из треков вернул ошибку 4**.
Решение: данное поведение включено по умолчанию. Однако, если единичные ошибки не являются критичными и не требуют прекращения трансляции, в файле flashphoner.properties необходимо указать
Code Block | ||||
---|---|---|---|---|
| ||||
rtsp_fail_on_error_track=false
rtp_force_synchronization=true |
6. Символы в имени потока, недопустимые в URI, должны быть экранированы
Симптомы: RTSP-поток не воспроизводится с признаком ошибки 'Bad URI'
Решение: любые символы, недопустимые при указании URI, должны быть экранированы в имени потока, например
Code Block | ||||
---|---|---|---|---|
| ||||
rtsp://hostname/c@@lstream/channel1 |
должен быть записан как
Code Block | ||||
---|---|---|---|---|
| ||||
rtsp://hostname/c%40%40lstream/channel1 |
7. Некоторые камеры не поддерживают поле cnonce
в заголовке сообщения при установке RTSP-соединения.
Симптомы: RTSP-поток играется в VLC, но не играется в WCS.
Решение: в файле flashphoner.properties установить настройку
Code Block | ||||
---|---|---|---|---|
| ||||
rtsp_auth_cnonce= |
с пустым значением.