Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

7. Графики chrome://webrtc-internals для второго потока:

Воспроизведение потока по WebRTC в стороннем плеере

Поток, опубликованный на WCS сервере, можно воспроизвести по WebRTC в стороннем плеере, например, в VR-плеере. Для этого видеоэлемент страницы, в котором будет воспроизводиться поток, передается параметром remoteVideo в функцию WebSDK session.createStream()

session.ceateStream() код

Code Block
languagejs
themeRDark
			session.createStream({
				name: document.getElementById('playStream').value,
				display: display,
				remoteVideo: video
			})
			...

Тестирование

1. Для теста возьмем:

  • WCS сервер
  • веб-приложение Two Way Streaming для публикации потока
  • VR-плеер Delight для воспроизведения потока

2. Публикуем поток на WCS сервере

Image Removed

3. Воспроизводим поток в VR-плеере

Image Removed

Пример кода страницы с плеером

1. Объявление видеоэлемента для воспроизведения потока, поля ввода имени потока и кнопок запуска и остановки воспроизведения

Автозапуск воспроизведения

Примеры Player и Embed Player поддерживают автозапуск воспроизведения при помощи параметра

Code Block
themeRDark
autoplay=true

например

Code Block
themeRDark
https://hostname:8888/embed_player?urlServer=wss://hostname:8443&streamName=stream1&autoplay=true&mediaProviders=WebRTC

Здесь

  • hostname - имя WCS-сервера
  • stream1 - имя потока на сервере

Особенности автозапуска воспроизведения в браузерах

Chrome

В последних версиях браузера Chrome (71 и выше) была изменена политика автозапуска воспроизведения контента на веб-страницах. Теперь для запуска воспроизведения видео необходимо, чтобы пользователь совершил какое-либо действие, например, нажатие на кнопку.

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

В связи с этим, в Chrome 71, а также в других браузерах на базе Chromium, поддерживающих изменение политики автозапуска, видео при автозапуске может проигрываться без звука. Для того, чтобы включить звук, пользователь должен переместить регулятор громкости в окне Embed Player.

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

Code Block
languagexml
themeRDark
<iframe        <div style="width: 50%;src="silence.mp3" allow="autoplay" id="displayaudio">
            <dl8-live-video id="remoteVideo" format="STEREO_TERPON">
                <source>
            </dl8-live-video>
        </div>
		<input class="form-control" type="text" id="playStream" placeholder="Stream Name"> 
		<button id="playBtn" type="button" class="btn btn-default" disabled>Play</button>
		<button id="stopBtn" type="button" class="btn btn-default" disabled>Stop</button>

2. Обработка события готовности плеера к воспроизведению

Code Block
languagejs
themeRDark
            document.addEventListener('x-dl8-evt-ready', function () {
				dl8video = document.getElementById('remoteVideo');
				$('#playBtn').prop('disabled', false).click(function() {
					playStream();
				});
            });

3. Установка соединения с сервером и создание потока

Code Block
languagejs
themeRDark
			var video = dl8video.contentElement;
			Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function (session) {
			var session = Flashphoner.getSessions()[0];
			session.createStream({
				name: document.getElementById('playStream').value,
				display: display,
				remoteVideo: video
			}).on(STREAM_STATUS.PLAYING, function (stream) {
                ...
			}).play();
			})	

4. Запуск воспроизведения в VR-плеере и обработка нажатия кнопки остановки воспроизведения

Code Block
languagejs
themeEclipse
			...
			}).on(STREAM_STATUS.PLAYING, function (stream) {
				dl8video.start();
				$('#stopBtn').prop('disabled', false).click(function() {
					$('#playBtn').prop('disabled', false);
					$('#stopBtn').prop('disabled', true);
					stream.stop();
					dl8video.exit();
				});
			}).play();
			})	

Полный код примера страницы с VR-плеером

Code Block
languagexml
themeRDark
titleCode
collapsetrue
<!DOCTYPE html>
<html>
    <head>
        <title>WebRTC Delight</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
		   <script type="text/javascript" src="../../../../flashphoner.js"></script>
		   <script type="text/javascript" src="../../dependencies/jquery/jquery-1.12.0.js"></script>
		   <script type="text/javascript" src="../../dependencies/js/utils.js"></script>
		   <script src="dl8-66b250447635476d123a44a391c80b09887e831e.js" async></script>
 style="display:none"></iframe>

и разместить в одном каталоге со страницей файл silence.mp3, содержащий 0.25 секунды тишины.

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

iOS Safari

Автозапуск воспроизведения работает, начиная с iOS 12.2. При этом политика автозапуска, как и в Chrome, требует, чтобы пользователь переместил регулятор громкости для воспроизведения звука.

В версиях iOS 12.2-12.3 звук может не начать воспроизводиться и при движении регулятора громкости. В таких случаях необходимо повторно запустить воспроизведение видео, не обновляя страницу.

При включенном Low Power Mode автозапуск воспроизведения в iOS Safari не работает.

Тонкая настройка воспроизведения звука в iOS Safari

В случае воспроизведения и последующей публикации видео на одной странице (например, видеочат) в iOS Safari уровень звука для проигрываемого потока может меняться. Избежать этого можно двумя способами:

1. Запрашивать доступ к медиаустройствам при создании сессии перед проигрыванием

Code Block
languagejs
themeRDark
    Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function (session) {
        ...
        if (Browser.isSafariWebRTC() && Browser.isiOS() && Flashphoner.getMediaProviders()[0] === "WebRTC") {
            Flashphoner.playFirstVideo(localVideo, true, PRELOADER_URL).then(function () {
                Flashphoner.getMediaAccess(null, localVideo).then(function (disp) {
            <meta name="dl8-custom-format" content='{"name": "STEREO_TERPON","base":"STEREO_MESH","params":{"uri": "03198702.json"}}'>
});
        </head>
    <body>});
        }
        <div style="width: 50%;" id="display">
    ...
    });

2. Через 1-1.5 секунды после получения статуса потока PLAYING, отключить и снова включить звук и/или видео

Code Block
languagejs
themeRDark
    session.createStream({
        <dl8-live-video id="remoteVideo" format="STEREO_TERPON">name: streamName,
        display: remoteVideo
       <source>
    }).on(STREAM_STATUS.PENDING, function (stream) {
        </dl8-live-video>...
    }).on(STREAM_STATUS.PLAYING, function (stream)  </div>
		<input class="form-control" type="text" id="playStream" placeholder="Stream Name"> 
		<button id="playBtn" type="button" class="btn btn-default" disabled>Play</button>
		<button id="stopBtn" type="button" class="btn btn-default" disabled>Stop</button>
{
        setStatus("#playStatus", stream.status());
        onPlaying(stream);
         <script>
			Flashphoner.init({flashMediaProviderSwfLocation: '../../../../media-provider.swf'});
			var SESSION_STATUS = Flashphoner.constants.SESSION_STATUS;
			var STREAM_STATUS = Flashphoner.constants.STREAM_STATUS;
			var STREAM_STATUS_INFO = Flashphoner.constants.STREAM_STATUS_INFO;
			var playBtn = document.getElementById('playBtn');
			var display = document.getElementById('display');
			var dl8video = null;
			var url = setURL();
  if (Browser.isSafariWebRTC() && Browser.isiOS() && Flashphoner.getMediaProviders()[0] === "WebRTC") {
            setTimeout(function () {
                muteVideo();
          document.addEventListener('x-dl8-evt-ready', function () {
				dl8video = document.getElementById('remoteVideo');
				$('#playBtn').prop('disabled', false).click(function() {
					playStream();
				});
       unmuteVideo();
            }, 1500);
        }
        });
			function playStream() {
			$('#playBtn').prop('disabled', true);
			$('#stopBtn').prop('disabled', false);
			var video = dl8video.contentElement;
			Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function (session) {
			var session = Flashphoner.getSessions()[0];
			session.createStream({
				name: document.getElementById('playStream').value,
				display: display,
				remoteVideo: video
			}).on(STREAM_STATUS.PLAYING, function (stream) {
				dl8video.start();
				$('#stopBtn').prop('disabled', false).click(function() {
					$('#playBtn').prop('disabled', false);
					$('#stopBtn').prop('disabled', true);
					stream.stop();
					dl8video.exit();
				});
			}).play();
			})	
			}
        </script>
    </body>
</html>

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

1. Возможный баг в браузере Safari на iOS приводит к фризам при воспроизведении WebRTC

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

...

...
    }).play();

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

1. Возможный баг в браузере Safari на iOS приводит к фризам при воспроизведении WebRTC

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

Решение:
а) включить транскодер на сервере, указав в файле flashphoner.properties

Code Block
languagebash
themeRDark
disable_streaming_proxy=true

б) при воспроизведении потока с iOS Safari явно указать ширину и высоту, например:

Code Block
languagejs
themeRDark
session.createStream({constraints:{audio:true,video:{width:320,height:240}}}).play();

2. При публикации потока по RTMP и воспроизведении в браузере по WebRTC вместо аудиокодека Opus используется PCMU

Симптомы: в chrome://webrtc-internals отображается кодек PCMU

Решение: отключить алгоритм избегания транскодинга (Avoid Transcoding Alhorithm) при помощи опции в файле flashphoner.properties

Code Block
languagebash
themeRDark
disable_rtc_avoid_transcoding_alg=true

3. При публикации потока при помощи Flash Streaming, воспроизведении этого потока в iOS Safari по WebRTC и одновременной публикации потока по WebRTC из Safari перестает воспроизводиться звук.

Симптомы:

а) Публикация потока stream1 из приложения Flash Streaming в браузере Chrome под Windows
б) Воспроизведение потока stream1 на iOS Safari в приложении Two Way Streaming. Звук и видео воспроизводятся нормально.
в) Публикация потока из iOS Safari в приложении Two Way Streaming. Воспроизведение звука пропадает.
г) Остановка публикации в iOS Safari. Воспроизведение звука восстанавливается.

Решение: отключить алгоритм избегания транскодинга (Avoid Transcoding Alhorithm) на сервере при помощи опции в файле flashphoner.properties

Code Block
languagebash
themeRDark
disable_rtc_avoid_transcoding_alg=true

4. При публикации потока по RTMP и отключении Keep Alive для всех протоколов воспроизведение в браузере по WebRTC останавливается по истечению WebSocket-таймаута

Симптомы: при публикации потока по RTMP воспроизведение в браузере по WebRTC останавливается без явного указания ошибки

Решение: если Keep Alive отключен для всех протоколов при помощи настройки в файле flashphoner.properties

Code Block
languagebash
themeRDark
keep_alive.algorithm=NONE

необходимо также отключить таймаут на чтение WebSocket настройкой

Code Block
languagebash
themeRDark
disable_streaming_proxy=true

б) при воспроизведении потока с iOS Safari явно указать ширину и высоту, например:

Code Block
languagejs
themeRDark
session.createStream({constraints:{audio:true,video:{width:320,height:240}}}).play();

2. При публикации потока по RTMP и воспроизведении в браузере по WebRTC вместо аудиокодека Opus используется PCMU

Симптомы: в chrome://webrtc-internals отображается кодек PCMU

Решение: отключить алгоритм избегания транскодинга (Avoid Transcoding Alhorithm) при помощи опции в файле flashphoner.properties

Code Block
languagebash
themeRDark
disable_rtc_avoid_transcoding_alg=true

3. При публикации потока при помощи Flash Streaming, воспроизведении этого потока в iOS Safari по WebRTC и одновременной публикации потока по WebRTC из Safari перестает воспроизводиться звук.

Симптомы:

а) Публикация потока stream1 из приложения Flash Streaming в браузере Chrome под Windows
б) Воспроизведение потока stream1 на iOS Safari в приложении Two Way Streaming. Звук и видео воспроизводятся нормально.
в) Публикация потока из iOS Safari в приложении Two Way Streaming. Воспроизведение звука пропадает.
г) Остановка публикации в iOS Safari. Воспроизведение звука восстанавливается.

Решение: отключить алгоритм избегания транскодинга (Avoid Transcoding Alhorithm) на сервере при помощи опции в файле flashphoner.properties

Code Block
languagebash
themeRDark
disable_rtc_avoid_transcoding_alg=true

4. При публикации потока по RTMP и отключении Keep Alive для всех протоколов воспроизведение в браузере по WebRTC останавливается по истечению WebSocket-таймаута

Симптомы: при публикации потока по RTMP воспроизведение в браузере по WebRTC останавливается без явного указания ошибки

Решение: если Keep Alive отключен для всех протоколов при помощи настройки в файле flashphoner.properties

Code Block
languagebash
themeRDark
keep_alive.algorithm=NONE

необходимо также отключить таймаут на чтение WebSocket настройкой

Code Block
languagebash
themeRDark
ws_read_socket_timeout=falsews_read_socket_timeout=false

5. Кодек G722 не работает в браузере Edge

Симптомы: поток со звуком G722 не воспроизводится в браузере Edge или воспроизводится без звука, с фризами

Решение: использовать другой кодек или другой браузер. В случае, если использование другого браузера невозможно, исключить кодек G722 при помощи настройки

Code Block
themeRDark
codecs_exclude_streaming=g722,telephone-event

6. Некоторые браузеры, основанные на Chromium, например Opera, Yandex, в зависимости от версии и ОС не поддерживают кодек H264

Симптомы: не работает публикация, не работает воспроизведение частично (только звук) или полностью при трансляции WebRTC потока H264

Решение: разрешить поддержку vp8 на стороне сервера

Code Block
themeRDark
codecs=opus,...,h264,vp8,...

исключить H264 для трансляции или воспроизведения на стороне клиента

Code Block
languagejs
themeRDark
publishStream = session.createStream({
    ...
    stripCodecs: "h264,H264"
}).on(STREAM_STATUS.PUBLISHING, function (publishStream) {
    ...
});
publishStream.publish();

Необходимо отметить, что при трансляции H264 потока и воспроизведении его как VP8 на сервере включается транскодинг.

7. Если в настройках браузера Chrome 71 и выше для сайта разрешен Flash, при воспроизведении по WebRTC в консоль браузера может выводиться ошибка "Cross-origin content must have visible size large than 400 x 300 pixels, or it will be blocked"

Симптомы: при воспроизведении по WebRTC в консоль браузера Chrome выводится сообщение "Cross-origin content must have visible size large than 400 x 300 pixels, or it will be blocked", при этом воспроизведение работает

Решение: использовать WebSDK без поддержки Flash

Code Block
themeRDark
flashphoner-no-flash.js