Table of Contents |
---|
Описание
Видеопоток захватывается с RTSP-источника, отдающего аудио и видео в поддерживаемых кодеках. Далее видеопоток трансформируется на стороне сервера для воспроизведения в браузерах и мобильных устройствах.
RTSP-источники
- IP камеры
- Медиасерверы
- Системы наблюдения
- Конференц-серверы
Поддерживаемые кодеки
- H.264
- VP8
- AAC
- G.711
- Speex
Поддерживаемые платформы и браузеры
...
Chrome
...
Firefox
...
Safari 11
...
Internet Explorer
...
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
...
Code Block | ||||
---|---|---|---|---|
| ||||
{
"uri":"rtsp://myserver.com/live/myStream"
} |
409 - Conflict
500 - Internal error
Извлечь RTMP-поток по указанному URL
...
/rtsp/find_all
...
Code Block | ||||
---|---|---|---|---|
| ||||
{
"uri": "rtsp://myserver.com/live/myStream",
"status": "PLAYING"
} |
...
200 – потоки найдены
404 – потоки не найдены
...
Найти все извлеченные RTMP-потоки
...
/rtsp/terminate
...
Code Block | ||||
---|---|---|---|---|
| ||||
{
"uri":"rtsp://myserver.com/live/myStream"
} |
...
200 - поток завершен
404 - поток не найден
...
Завершить извлеченный RTMP-поток
Параметры
...
Имя параметра
...
Описание
...
Пример
...
uri
...
URL RTSP-потока
...
rtsp://myserver.com/live/myStream
...
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.
Известные проблемы
...
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= |
с пустым значением.
Include Page | ||||
---|---|---|---|---|
|