...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
Flashphoner.getMediaDevices(null, true).then(function (list) { list.audio.forEach(function (device) { var audio = document.getElementById("audioInput");... var i}); ... }).catch(function (error) { var deviceInList = false; $("#notifyFlash").text("Failed to get media devices"); for (i = 0; i < audio.options.length; i++) }); |
2. Регулировка усиления микрофона (работает только в браузере Chrome)
код:
Code Block | ||||
---|---|---|---|---|
| ||||
$("#micGainControl").slider({ range: "min", if (audio.options[i].value == device.id) { min: 0, max: 100, value: currentGainValue, deviceInList = true;step: 10, animate: true, slide: function (event, ui) break;{ currentGainValue = ui.value; } }if(previewStream) { if (!deviceInList) { publishStream.setMicrophoneGain(currentGainValue); } var } option = document.createElement("option"); }); |
3. Включение коррекции ошибок (только для кодека Opus)
код:
Code Block | ||||
---|---|---|---|---|
| ||||
if (constraints.audio) { optionconstraints.textaudio = device.label || device.id;{ option.value = device.id; deviceId: $('#audioInput').val() }; audio.appendChild(option);if ($("#fec").is(':checked')) } constraints.audio.fec = $("#fec").is(':checked'); }); ... }).catch(function (error |
4. Установка стерео / моно режима.
код:
Code Block | ||||
---|---|---|---|---|
| ||||
if (constraints.audio) { $("#notifyFlash").text("Failed to get media devices"); }); |
...
код:
Code Block | ||||
---|---|---|---|---|
| ||||
$("#micGainControl").slider({constraints.audio = { deviceId: $('#audioInput').val() range: "min",}; min: 0, ... max: 100,if ($("#sendStereoAudio").is(':checked')) value: currentGainValue, constraints.audio.stereo step: 10,= $("#sendStereoAudio").is(':checked'); animate: true,... slide: function (event, ui} |
5. Установка битрейта звука в кбит/с
код:
Code Block | ||||
---|---|---|---|---|
| ||||
if (constraints.audio) { currentGainValueconstraints.audio = ui.value;{ if(previewStream) {deviceId: $('#audioInput').val() }; publishStream.setMicrophoneGain(currentGainValue);... if (parseInt($('#sendAudioBitrate').val()) > 0) } } constraints.audio.bitrate }); |
3. Включение коррекции ошибок (только для кодека Opus)
= parseInt($('#sendAudioBitrate').val());
} |
6. Отключение микрофона.
код:
Code Block | ||||
---|---|---|---|---|
| ||||
if (constraints.audio$("#muteAudioToggle").is(":checked")) { constraints.audio = {muteAudio(); } |
Настройки камеры
1. Выбор камеры
код:
Code Block | ||||
---|---|---|---|---|
| ||||
deviceId: $('#audioInput').val()Flashphoner.getMediaDevices(null, true).then(function (list) { };... iflist.video.forEach(function ($("#fec").is(':checked'))device) { constraints..audio.fec = $("#fec").is(':checked'); }); if ($("#sendStereoAudio").is(':checked'))}).catch(function (error) { constraints.audio.stereo = $("#sendStereoAudio#notifyFlash").is(':checked'); text("Failed to get media devices"); if (parseInt($('#sendAudioBitrate').val()) > 0) }); |
2. Переключение камер.
код:
Code Block | ||||
---|---|---|---|---|
| ||||
$("#switchBtn").text("Switch").off('click').click(function () { constraints.audio.bitrate = parseInt($('#sendAudioBitrate').val())publishStream.switchCam(); } |
...
код:
Code Block | ||||
---|---|---|---|---|
| ||||
if (constraints.audio) {
constraints.audio = {
deviceId: $('#audioInput').val()
};
if ($("#fec").is(':checked'))
constraints.audio.fec = $("#fec").is(':checked');
if ($("#sendStereoAudio").is(':checked'))
constraints.audio.stereo = $("#sendStereoAudio").is(':checked');
if (parseInt($('#sendAudioBitrate').val()) > 0)
constraints.audio.bitrate = parseInt($('#sendAudioBitrate').val());
} |
...
код:
Code Block | ||||
---|---|---|---|---|
| ||||
if (constraints.audio) {
constraints.audio = {
deviceId: $('#audioInput').val()
};
if ($("#fec").is(':checked'))
constraints.audio.fec = $("#fec").is(':checked');
if ($("#sendStereoAudio").is(':checked'))
constraints.audio.stereo = $("#sendStereoAudio").is(':checked');
if (parseInt($('#sendAudioBitrate').val()) > 0)
constraints.audio.bitrate = parseInt($('#sendAudioBitrate').val());
} |
6. Отключение микрофона.
код:
Code Block | ||||
---|---|---|---|---|
| ||||
if ($("#muteAudioToggle").is(":checked")) {
muteAudio();
} |
Настройки камеры
1. Выбор камеры
код:
Code Block | ||||
---|---|---|---|---|
| ||||
Flashphoner.getMediaDevices(null, true).then(function (list) {
...
list.video.forEach(function (device) {
console.log(device);
var video = document.getElementById("videoInput");
var i;
var deviceInList = false;
for (i = 0; i < video.options.length; i++) {
if (video.options[i].value == device.id) {
deviceInList = true;
break;
}
}
if (!deviceInList) {
var option = document.createElement("option");
option.text = device.label || device.id;
option.value = device.id;
if (option.text.toLowerCase().indexOf("back") >= 0 && video.children.length > 0) {
video.insertBefore(option, video.children[0]);
} else {
video.appendChild(option);
}
}
});
}).catch(function (error) {
$("#notifyFlash").text("Failed to get media devices");
}); |
2. Переключение камер.
код:
Code Block | ||||
---|---|---|---|---|
| ||||
$("#switchBtn").text("Switch").off('click').click(function () {
publishStream.switchCam();
}).prop('disabled', $('#sendCanvasStream').is(':checked')); |
Переключение камеры может осуществляться "на лету", во время трансляции потока. Переключение работает в следующем порядке:
- На ПК камеры переключаются в том порядке, в каком они определены в менеджере устройств операционной системы.
- На Android при использовании браузера Chrome по умолчанию выбирается фронтальная камера, при использовании браузера Firefox - тыловая камера
- На iOS в браузере Safari по умолчанию выбирается фронтальная камера, но в выпадающем списке при выборе камеры первой указана тыловая камера.
3. Установка разрешения видео
код:
Code Block | ||||
---|---|---|---|---|
| ||||
function resizeLocalVideo(event) {
var requested = constraints.video;
if (requested.width != event.target.videoWidth || requested.height != event.target.videoHeight) {
console.warn("Camera does not support requested resolution, actual resolution is " + event.target.videoWidth + "x" + event.target.videoHeight);
}
$("#publishResolution").text(event.target.videoWidth + "x" + event.target.videoHeight);
resizeVideo(event.target);
} |
4. Установка FPS
код:
Code Block | ||||
---|---|---|---|---|
| ||||
if (constraints.video) {
if (constraints.customStream) {
constraints.customStream = canvas.captureStream(30);
constraints.video = false;
} else {
constraints.video = {
deviceId: {exact: $('#videoInput').val()},
width: parseInt($('#sendWidth').val()),
height: parseInt($('#sendHeight').val())
};
if (Browser.isSafariWebRTC() && Browser.isiOS() && Flashphoner.getMediaProviders()[0] === "WebRTC") {
constraints.video.width = {min: parseInt($('#sendWidth').val()), max: 640};
constraints.video.height = {min: parseInt($('#sendHeight').val()), max: 480};
}
if (parseInt($('#sendVideoMinBitrate').val()) > 0)
constraints.video.minBitrate = parseInt($('#sendVideoMinBitrate').val());
if (parseInt($('#sendVideoMaxBitrate').val()) > 0)
constraints.video.maxBitrate = parseInt($('#sendVideoMaxBitrate').val());
if (parseInt($('#fps').val()) > 0)
constraints.video.frameRate = parseInt($('#fps').val());
}
} |
...
код:
Code Block | ||||
---|---|---|---|---|
| ||||
if (constraints.video) {
if (constraints.customStream) {
constraints.customStream = canvas.captureStream(30);
constraints.video = false;
} else {
constraints.video = {
deviceId: {exact: $('#videoInput').val()},
width: parseInt($('#sendWidth').val()),
height: parseInt($('#sendHeight').val())
};
if (Browser.isSafariWebRTC() && Browser.isiOS() && Flashphoner.getMediaProviders()[0] === "WebRTC") {
constraints.video.width = {min: parseInt($('#sendWidth').val()), max: 640};
constraints.video.height = {min: parseInt($('#sendHeight').val()), max: 480};
}
if (parseInt($('#sendVideoMinBitrate').val()) > 0)
constraints.video.minBitrate = parseInt($('#sendVideoMinBitrate').val());
if (parseInt($('#sendVideoMaxBitrate').val()) > 0)
constraints.video.maxBitrate = parseInt($('#sendVideoMaxBitrate').val());
if (parseInt($('#fps').val()) > 0)
constraints.video.frameRate = parseInt($('#fps').val());
}
} |
6. Установка CPU Overuse Detection
код:
Code Block | ||||
---|---|---|---|---|
| ||||
if (!$("#cpuOveruseDetection").is(':checked')) {
mediaConnectionConstraints = {
"mandatory": {
googCpuOveruseDetection: false
}
}
} |
7. Отключение камеры
код:
Code Block | ||||
---|---|---|---|---|
| ||||
if ($("#muteVideoToggle").is(":checked")) {
muteVideo();
} |
Тестирование захвата с камеры и микрофона локально
Локальное тестирование захвата с микрофона и камеры предназначено для того, чтобы проверить работоспособность микрофона и камеры в браузере, не отправляя поток на сервер.
код:
Code Block | ||||
---|---|---|---|---|
| ||||
function startTest() { if (Browser.isSafariWebRTC()) { Flashphoner.playFirstVideo(localVideo, true); Flashphoner.playFirstVideo(remoteVideo, false); } Flashphoner.getMediaAccess(getConstraints(), localVideo).then(function (disp) { $("#testBtn").text("Release").off('click').click(function () { $(this).prop('disabled', true); stopTest(); }).prop('disabled', false); window.AudioContext = window.AudioContext || window.webkitAudioContext; if (Flashphoner.getMediaProviders()[0] == "WebRTC" && window.AudioContext) { for (i = 0; i < localVideo.children.length; i++) { if (localVideo.children[i] && localVideo.children[i].id.indexOf("-LOCAL_CACHED_VIDEO") != -1).prop('disabled', $('#sendCanvasStream').is(':checked')); |
Переключение камеры может осуществляться "на лету", во время трансляции потока. Переключение работает в следующем порядке:
- На ПК камеры переключаются в том порядке, в каком они определены в менеджере устройств операционной системы.
- На Android при использовании браузера Chrome по умолчанию выбирается фронтальная камера, при использовании браузера Firefox - тыловая камера
- На iOS в браузере Safari по умолчанию выбирается фронтальная камера, но в выпадающем списке при выборе камеры первой указана тыловая камера.
3. Установка разрешения видео
код:
Code Block | ||||
---|---|---|---|---|
| ||||
function resizeLocalVideo(event) { var requested = constraints.video; if (requested.width != event.target.videoWidth || var stream requested.height != localVideo.children[i].srcObject; event.target.videoHeight) { console.warn("Camera does audioContextForTestnot =support new AudioContext(); requested resolution, actual resolution is " + event.target.videoWidth + "x" + event.target.videoHeight); } $("#publishResolution").text(event.target.videoWidth + var"x" microphone = audioContextForTest.createMediaStreamSource(stream+ event.target.videoHeight); resizeVideo(event.target); } |
4. Установка FPS
код:
Code Block | ||||
---|---|---|---|---|
| ||||
if (constraints.video) { if (constraints.customStream) { var javascriptNode = audioContextForTest.createScriptProcessor(1024, 1, 1); ... } microphone.connect(javascriptNode);else { ... javascriptNode.connect(audioContextForTest.destination); if (parseInt($('#fps').val()) > 0) javascriptNode.onaudioprocessconstraints.video.frameRate = function (event) {parseInt($('#fps').val()); } } |
5. Установка битрейта видео в кбит/с
код:
Code Block | ||||
---|---|---|---|---|
| ||||
if (constraints.video) { var inpt_L =if event.inputBuffer.getChannelData(0);(constraints.customStream) { ... var sum_L = 0.0; } else { ... forif (var i = 0; i < inpt_L.length; ++i) { (parseInt($('#sendVideoMinBitrate').val()) > 0) constraints.video.minBitrate = parseInt($('#sendVideoMinBitrate').val()); if sum_L += inpt_L[i] * inpt_L[i];(parseInt($('#sendVideoMaxBitrate').val()) > 0) constraints.video.maxBitrate } = parseInt($('#sendVideoMaxBitrate').val()); $("#micLevel").text(Math.floor(Math.sqrt(sum_L / inpt_L.length) * 100)); } } |
6. Установка CPU Overuse Detection
код:
Code Block | ||||
---|---|---|---|---|
| ||||
if }(!$("#cpuOveruseDetection").is(':checked')) { mediaConnectionConstraints = { } "mandatory": { } } else if (Flashphoner.getMediaProviders()[0] == "Flash") { googCpuOveruseDetection: false } micLevelInterval = setInterval(function () { } } |
7. Отключение камеры
код:
Code Block | ||||
---|---|---|---|---|
| ||||
if ($("#micLevel#muteVideoToggle").text(disp.children[0].getMicrophoneLevel());is(":checked")) { }, 500muteVideo(); } testStarted = true; }).catch(function (error} |
Тестирование захвата с камеры и микрофона локально
Локальное тестирование захвата с микрофона и камеры предназначено для того, чтобы проверить работоспособность микрофона и камеры в браузере, не отправляя поток на сервер.
код:
Code Block | ||||
---|---|---|---|---|
| ||||
function startTest() { if $("#testBtn").prop('disabled', false);(Browser.isSafariWebRTC()) { testStarted = falseFlashphoner.playFirstVideo(localVideo, true); }); drawSquare(); } |
Установка используемых кодеков
При публикации потока предусмотрена возможность убрать из WebRTC SDP кодеки, которые не должны использоваться при публикации данного потока, например:
Code Block | ||||
---|---|---|---|---|
| ||||
publishStream = session.createStream(Flashphoner.playFirstVideo(remoteVideo, false); } Flashphoner.getMediaAccess(getConstraints(), localVideo).then(function (disp) { name: streamName, $("#testBtn").text("Release").off('click').click(function () { display: localVideo, $(this).prop('disabled', true); cacheLocalResources: true, stopTest(); constraints: constraints,}).prop('disabled', false); mediaConnectionConstraints: mediaConnectionConstraints, window.AudioContext = window.AudioContext || window.webkitAudioContext; if stripCodecs: "h264,H264,flv,mpv" }).on(STREAM_STATUS.PUBLISHING, function (publishStream(Flashphoner.getMediaProviders()[0] == "WebRTC" && window.AudioContext) { $("#testBtn").prop('disabled', true); for (i = var video = document.getElementById(publishStream.id()); 0; i < localVideo.children.length; i++) { //resize local if resolution is available if (video.videoWidth > 0localVideo.children[i] && video.videoHeight > 0localVideo.children[i].id.indexOf("-LOCAL_CACHED_VIDEO") != -1) { resizeLocalVideo({target: video}); var } stream enableMuteToggles(true); = localVideo.children[i].srcObject; if ($("#muteVideoToggle").is(":checked")) { audioContextForTest = new muteVideoAudioContext(); } if ($("#muteAudioToggle").is(":checked")) { var microphone = muteAudioaudioContextForTest.createMediaStreamSource(stream); } //remove resize listener in casevar thisjavascriptNode video was cached earlier= audioContextForTest.createScriptProcessor(1024, 1, 1); video.removeEventListener('resize', resizeLocalVideo); videomicrophone.addEventListener('resize', resizeLocalVideoconnect(javascriptNode); setStatus(STREAM_STATUS.PUBLISHING); //play preview javascriptNode.connect(audioContextForTest.destination); var constraints = { audio: $("#playAudio").is(':checked'), javascriptNode.onaudioprocess = function (event) { video: $("#playVideo").is(':checked') }; if (constraints.video) {... constraints.video = { } width: (!$("#receiveDefaultSize").is(":checked")) ? parseInt($('#receiveWidth').val()) : 0, } } height: } else if (!$("#receiveDefaultSize").is(":checked")) ? parseInt($('#receiveHeight').val()) : 0, Flashphoner.getMediaProviders()[0] == "Flash") { micLevelInterval = setInterval(function () { bitrate: (!$("#receiveDefaultBitrate#micLevel").is(":checked")) ? $("#receiveBitrate").val() : 0, text(disp.children[0].getMicrophoneLevel()); }, 500); } testStarted = true; }).catch(function (error) { quality: (!$("#receiveDefaultQuality#testBtn").is(":checked")) ? $prop('#qualitydisabled').val() : 0, false); testStarted = }false; } }).on(STREAM_STATUS.UNPUBLISHED, function () { }); drawSquare(); } |
Установка используемых кодеков
При публикации потока предусмотрена возможность убрать из WebRTC SDP кодеки, которые не должны использоваться при публикации данного потока, например:
Code Block | ||||
---|---|---|---|---|
| ||||
publishStream setStatus(STREAM_STATUS.UNPUBLISHED);= session.createStream({ //enable start button ... onStopped();stripCodecs: "h264,H264,flv,mpv" }).on(STREAM_STATUS.FAILEDPUBLISHING, function (publishStream) { setStatus(STREAM_STATUS.FAILED); //enable start button onStopped();... }); publishStream.publish(); |
...