Versions Compared

Key

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

...

Code Block
themeRDark
rtp_activity_video=false

Если браузер Chrome публикует пустое видео при занятой веб-камере

Некоторые версии браузера Chrome не возвращают ошибку в случае, если веб-камера занята другим процессом, а публикуют поток с пустым видео (черный экран). Остановить публикацию в этом случае можно двумя способами: при помощи JavaScript и HTML5 на клиенте, или при помощи настройки на сервере.

Остановка публикации потока на стороне клиента

Видеодорожка, созданная браузером Chrome для занятой камеры, останавливается в пределах первой секунды публикации, затем поток публикуется уже без видео. При этом состояние видеодорожки (переменная readyState) меняется на ended, и генерируется соответствующее событие onended, которое может быть перехвачено веб-приложением. Для того, чтобы использовать это событие:

1. Добавляем в скрипт веб-приложения функцию регистрации обработчика события onended, в котором завершаем публикацию при помощи stream.stop()

...

languagejs
themeRDark

...

Контроль наличия медиа трафика работает только при публикации, но не при проигрывании потоков.

Отключение контроля активности видео и аудио дорожек по имени потока

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

Code Block
themeRDark
rtp_activity_audio_exclude=stream1
rtp_activity_video_exclude=stream1

Это может быть полезно для потоков, трафик в которых может останавливаться на длительное время, например, для потоков с экрана или окна приложения:

Code Block
themeRDark
rtp_activity_audio_exclude=.*-screen$
rtp_activity_video_exclude=.*-screen$

В данном случае контроль активности не будет применяться к потокам с именами conference-123-user-456-screen 

Если браузер Chrome публикует пустое видео при занятой веб-камере

Некоторые версии браузера Chrome не возвращают ошибку в случае, если веб-камера занята другим процессом, а публикуют поток с пустым видео (черный экран). Остановить публикацию в этом случае можно двумя способами: при помощи JavaScript и HTML5 на клиенте, или при помощи настройки на сервере.

Остановка публикации потока на стороне клиента

Видеодорожка, созданная браузером Chrome для занятой камеры, останавливается в пределах первой секунды публикации, затем поток публикуется уже без видео. При этом состояние видеодорожки (переменная readyState) меняется на ended, и генерируется соответствующее событие onended, которое может быть перехвачено веб-приложением. Для того, чтобы использовать это событие:

1. Добавляем в скрипт веб-приложения функцию регистрации обработчика события onended, в котором завершаем публикацию при помощи stream.stop()

Code Block
languagejs
themeRDark
function addVideoTrackEndedListener(localVideo, stream) {
    var videoTrack = extractVideoTrack(localVideo);
    if (videoTrack && videoTrack.readyState == 'ended') {
        console.error("Video source error. Disconnect...");
        stream.stop();
    } else if (videoTrack) {
        videoTrack.onended = function (event) {
            console.error("Video source error. Disconnect...");
            stream.stop();
        };
    }
}

2. Добавляем функцию удаления обработчика события при завершении публикации

Code Block
languagejs
themeRDark
function removeVideoTrackEndedListener(localVideo) {
    var videoTrack = extractVideoTrack(localVideo);
    if(videoTrack) {
        videoTrack.onended = null;
    }
}

3. Добавляем функцию извлечения видеодорожки

Code Block
languagejs
themeRDark
function extractVideoTrack(localVideo) {
    return localVideo.firstChild.srcObject.getVideoTracks()[0];
}

4. При публикации потока регистрируем обработчик события

Code Block
languagejs
themeRDark
    session.createStream({
        name: streamName,
        display: localVideo,
        ...
    }).on(STREAM_STATUS.PUBLISHING, function (stream) {
        addVideoTrackEndedListener(localVideo, stream);
        setStatus("#publishStatus", STREAM_STATUS.PUBLISHING);
        onPublishing(stream);
        ...
    }).publish();

5. При завершении публикации потока удаляем обработчик события

Code Block
languagejs
themeRDark
function onPublishing(stream) {
    $("#publishBtn").text("Stop").off('click').click(function () {
        $(this).prop('disabled', true);
        removeVideoTrackEndedListener(localVideo);
        stream.stop();
    }).prop('disabled', false);
    $("#publishInfo").text("");
}

Контроль активности видеодорожки в потоке на стороне сервера

Контроль активности видео в публикуемых потоках на сервере включается при помощи следующей настройки в файле flashphoner.properties

Code Block
themeRDark
rtp_activity_video=true

В этом случае, если в публикуемом потоке нет видео, публикация остановится через 60 секунд.

Публикация только видео при помощи ограничений

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

Code Block
languagejs
themeRDark
    session.createStream({
        name: streamName,
        display: localVideo,
        constraints: {video: true, audio: false}
        ...
    }).publish();

Публикация только аудио

В большинстве случаев, для публикации только аудио достаточно установить ограничения:

Code Block
languagejs
themeRDark
    session.createStream({
        name: streamName,
        console.error("Video source error. Disconnect...");display: localVideo,
        stream.stop();
    } else if (videoTrack) {constraints: {video: false, audio: true}
        videoTrack...onended
  = function }).publish(event) {
);

Публикация только аудио в браузере Safari

При попытке опубликовать аудио поток из браузера iOS Safari при помощи ограничений, браузер не высылает аудио пакеты. Для того, чтобы обойти это ограничение, необходимо опубликовать поток с видео, а затем заглушить видео в потоке

Code Block
languagejs
themeRDark
    session.createStream({
        name: streamName,
      console.error("Video source error. Disconnect...");display: localVideo,
        constraints: {video: true,  stream.stop();audio: true}
        };...
    }
}

2. Добавляем функцию удаления обработчика события при завершении публикации

Code Block
languagejs
themeRDark
function removeVideoTrackEndedListener(localVideo).on(STREAM_STATUS.PUBLISHING, function (stream) {
     var videoTrack = extractVideoTrackstream.muteVideo(localVideo);
    if(videoTrack) {
        videoTrack.onended = null;...
    }
}

3. Добавляем функцию извлечения видеодорожки

Code Block
languagejs
themeRDark
function extractVideoTrack(localVideo) {
    return localVideo.firstChild.srcObject.getVideoTracks()[0];
}

4. При публикации потока регистрируем обработчик события

Code Block
languagejs
themeRDark
    session.createStream({
        name: streamName,
        display: localVideo,
        ...
    }).on(STREAM_STATUS.PUBLISHING, function (stream) {
        addVideoTrackEndedListener(localVideo, stream);
        setStatus("#publishStatus", STREAM_STATUS.PUBLISHING);
        onPublishing(stream);
).publish();

В этом случае браузер iOS Safari будет высылать в потоке пустые видео пакеты (темнота) и аудио пакеты.

Отключение нормализации ограничений по разрешению в браузере Safari

По умолчанию, WebSDK нормализует разрешение, указанное в ограничениях при публикации видеопотока из браузера Safari. При этом проверяется, не задана ли ширина либо высота картинки равной 0 и, если да, разрешение принудительно устанавливается в 320x240 или 640x480. Начиная со сборки WebSDK 0.5.28.2753.109 (хэш 149855cc050bf7512817104fd0104e9cce760ac4), существует возможность отключить нормализацию и передавать ограничения в браузер как есть, например:

Code Block
languagejs
themeRDark
publishStream = session.createStream({
    ...
    disableConstraintsNormalization: true,
    constraints: {
        video: ...{
     }).publish();

5. При завершении публикации потока удаляем обработчик события

Code Block
languagejs
themeRDark
function onPublishing(stream) {
    $("#publishBtn").text("Stop").off('click').click(function () {
 width: {ideal: 1024},
             $(this).prop('disabled', true);height: {ideal: 768}
        removeVideoTrackEndedListener(localVideo);},
        stream.stop(); audio: true
    }).prop('disabled', false);
    $("#publishInfo").text("");
}

Контроль активности видеодорожки в потоке на стороне сервера

Контроль активности видео в публикуемых потоках на сервере включается при помощи следующей настройки в файле flashphoner.properties

Code Block
themeRDark
rtp_activity_video=true

В этом случае, если в публикуемом потоке нет видео, публикация остановится через 60 секунд.

Публикация только видео при помощи ограничений

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

Code Block
languagejs
themeRDark
    session.createStream({
        name: streamName,
        display: localVideo,
        constraints: {video: true, audio: false}
        ...
    }).publish();

Публикация только аудио

В большинстве случаев, для публикации только аудио достаточно установить ограничения:

Code Block
languagejs
themeRDark
    session.createStream({
        name: streamName,
        display: localVideo,
        constraints: {video: false, audio: true}
        ...
    }).publish();

Публикация только аудио в браузере Safari

...


}).on(STREAM_STATUS.PUBLISHING, function (publishStream) {
    ...
});
publishStream.publish();

Исключение профилей кодирования H264

В сборке 5.2.620 добавлена возможность исключения определенных профилей кодирования H264 из SDP, отправляемого сервером браузеру. Исключаемые профили должны быть перечислены в настройке

Code Block
themeRDark
webrtc_sdp_h264_exclude_profiles=4d,64

В данном случае из SDP будут исключены профили Main (4d) и High (64), останется только Baseline (42):

Code Block
themeRDark
a=rtpmap:102 H264/90000
a=fmtp:102 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f
a=rtpmap:125 H264/90000
a=fmtp:125 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
a=rtpmap:127 H264/90000
a=fmtp:127 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f
a=rtpmap:108 H264/90000
a=fmtp:108 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f

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

По умолчанию, профили не исключаются из SDP  в том случае, если они поддерживаются браузером

Code Block
themeRDark
webrtc_sdp_h264_exclude_profiles=

Управление типом публикуемого контента в Chromium браузерах

В некоторых случаях Chromium браузеры, основанные на сборке Chromium 91, агрессивно оценивают качество канала публикации, и сбрасывают разрешение ниже заданного, даже если канал подходит для публикации потока 720p или 1080p. В связи с этим, в сборке WebSDK 2.0.180 добавлена опция videoContentHint:

Code Block
languagejs
themeRDark
    session.createStream({
        name: streamName,
        display: localVideo,
        constraints: {videocacheLocalResources: true,
 audio:  true}
     receiveVideo: false,
  ...
    }).on(STREAM_STATUS.PUBLISHING, function (stream) {
receiveAudio: false,
         stream.muteVideo();videoContentHint: "detail"
        ...
    }).publish();

В этом случае браузер iOS Safari будет высылать в потоке пустые видео пакеты (темнота) и аудио пакеты.

...

По умолчанию, WebSDK нормализует эта опция установлена в detail и указывает браузеру удерживать разрешение, указанное заданное в ограничениях constraints при публикации видеопотока из браузера Safari. При этом проверяется, не задана ли ширина либо высота картинки равной 0 и, если да, разрешение принудительно устанавливается в 320x240 или 640x480. Начиная со сборки WebSDK 0.5.28.2753.109 (хэш 149855cc050bf7512817104fd0104e9cce760ac4), существует возможность отключить нормализацию и передавать ограничения в браузер как есть, например:. Однако, при публикации с некоторых веб камер, подключаемых по USB,  браузер может в этом случае сбрасывать FPS. Если необходимо удерживать FPS, но разрешение публикации при этом не важно, необходимо установить опцию в motion

Code Block
languagejs
themeRDark
publishStream   = session.createStream({
    ...
    disableConstraintsNormalizationname: truestreamName,
    constraints: {
        videodisplay: {localVideo,
            widthcacheLocalResources: {ideal: 1024}true,
            height: {idealreceiveVideo: 768}false,
        receiveAudio: }false,
        audiovideoContentHint: true"motion"
     }
}).on(STREAM_STATUS.PUBLISHING, function (publishStream) { ...
    ...
});
publishStream.publish();

Исключение профилей кодирования H264

В сборке 5.2.620 добавлена возможность исключения определенных профилей кодирования H264 из SDP, отправляемого сервером браузеру. Исключаемые профили должны быть перечислены в настройке

Code Block
themeRDark
webrtc_sdp_h264_exclude_profiles=4d,64

В данном случае из SDP будут исключены профили Main (4d) и High (64), останется только Baseline (42):

Code Block
themeRDark
a=rtpmap:102 H264/90000
a=fmtp:102 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f
a=rtpmap:125 H264/90000
a=fmtp:125 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
a=rtpmap:127 H264/90000
a=fmtp:127 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f
a=rtpmap:108 H264/90000
a=fmtp:108 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f

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

По умолчанию, профили не исключаются из SDP  в том случае, если они поддерживаются браузером

Code Block
themeRDark
webrtc_sdp_h264_exclude_profiles=

Управление типом публикуемого контента в Chromium браузерах

...

В сборке WebSDK 2.0.204 в пример Media Devices добавлен пример установки опции videoContentHint 

Image Added

Управление FPS в браузере Firefox

По умолчанию, Firefox публикует видео с максимальным FPS, который ему показывает драйвер используемой камеры при заданном разрешении. Для большинства современных камер это 30 FPS. При необходимости, можно более точно указать FPS при публикации. Для этого нормализация ограничений должна быть отключена:

Code Block
languagejs
themeRDark
session.createStream({
    ...
    disableConstraintsNormalization: true,
    constraints: {
        video: {
            width: 640,
            height: 360,
            frameRate: { max: 15 }
        },
        audio: true
    }
}).on(STREAM_STATUS.PUBLISHING, function (publishStream) {
    ...
}).publish();

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

Публикация стерео звука в браузере

Для публикации стерео звука в браузере битрейт аудио должен быть установлен не ниже 60000 бит/с. Этого можно добиться настройкой параметров кодека Opus на стороне клиента

Code Block
languagejs
themeRDark
    session.createStream({
        name: streamName,
        display: localVideoremoteVideo,
    constraints: {
   cacheLocalResources: true,
    audio: {
   receiveVideo: false,
        receiveAudiobitrate: false,64000
        videoContentHint: "detail"},
        ...
    }
    ...
}).publish();

...

;

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

Code Block
themeRDark
opus_formats = maxaveragebitrate=64000;stereo=1;sprop-stereo=1;

В этом случае браузер Firefox публикует стерео звук.

Публикация стерео звука в браузерах на основе Chrome

Для публикации стерео звука из Chrome, кроме настройки сервера, необходимы также изменения в коде клиента. В зависимости от реализации клиента, способы публикации будут разными

С использованием Web SDK

При использовании Web SDK, необходимо при публикации указать следующую опцию в ограничениях:

Code Block
languagejs
themeRDark
    session.createStream({
        name: streamName,
    display: localVideo,
    displayconstraints: localVideo,{
        cacheLocalResourcesaudio: true,{
           receiveVideo stereo: false,true
        receiveAudio: false},
        videoContentHint: "motion"...
    }
    ...
    }).publish();

Управление FPS в браузере Firefox

...

С использованием Websocket API

Если в проекте используется только Websocket API, необходимо отключить эхоподавление

Code Block
languagejs
themeRDark
session.createStream({
    ...
     var constraints = {
   disableConstraintsNormalization: true,
    constraintsaudio: {
             video echoCancellation: {false,
            widthgoogEchoCancellation: 640,false
        },
       height: 360, ...
    };
    ...
    frameRate: { max: 15 }navigator.getUserMedia(constraints, function (stream) {
        },...
    }, reject);

При включенном эхоподавлении Chrome публикует моно звук, даже если в настройках кодека Opus заданы параметры стерео.

Обход блокировки шифрованного UDP трафика

В некоторых случаях шифрованный UDP медиатрафик может блокироваться на стороне провайдера. При этом публикация WebRTC потока с использованием UDP транспорта не будет работать и завершится с ошибкой Failed by RTP activity . В таких случаях рекомендуется использовать TCP транспорт на стороне клиента

Code Block
languagejs
themeRDark
session.createStream({
    audioname: truestreamName,
    display: }
}).on(STREAM_STATUS.PUBLISHING, function (publishStream) {localVideo,
    transport: "TCP"
    ...
}).publish();

Отметим, что в этом случае Firefox может исключить камеру из списка при запросе доступа к ней, если драйвер камеры при запросе браузером сведений о ней не предоставляет требуемую комбинацию разрешения и FPS. Также Firefox может изменить разрешение публикации, если в сведениях о камере, предоставляемых драйвером, заданному FPS соответствует только одно разрешениеТакже можно использовать внешний или встроенный TURN сервер либо RTMP или RTSP для публикации потока.

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

1. Если веб-приложение расположено внутри iframe элемента, публикация видеопотока может не пройти.

...