Versions Compared

Key

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

...

Flashphoner.init() код

Code Block
languagejs
themeRDark
 Flashphoner.init({
            flashMediaProviderSwfLocation: '../../../../media-provider.swf',
            mediaProvidersReadyCallback: function (mediaProviders) {
                //hide remote video if current media provider is Flash
                if (mediaProviders[0] == "Flash") {
                    $("#fecForm").hide();
$("#stereoForm"                    $("#stereoForm").hide();
                    $("#sendAudioBitrateForm").hide();
                    $("#cpuOveruseDetectionForm").hide();
                }
                if (Flashphoner.isUsingTemasys()) {
                    $("#audioInputForm").hide();
                    $("#videoInputForm").hide();
                }
            }
        })


2. Получение списка доступных медиа-устройств. код

...

При получении списка медиа-устройств заполняются выпадающие списки на странице клиента.

Code Block
languagejs
themeRDark
  Flashphoner.getMediaDevices(null, true).then(function (list) {
        list.audio.forEach(function (device) {
var audio =           var audio = document.getElementById("audioInput");
            var i;
            var deviceInList = false;
            for (i = 0; i < audio.options.length; i++) {
                if (audio.options[i].value == device.id) {
                    deviceInList = true;
break;
}
}
                    break;
                }
            }
            if (!deviceInList) {
                var option = document.createElement("option");
option.text   = device.label || device.id;
           option.text = device.label || device.id;
                option.value = device.id;
                audio.appendChild(option);
            }
        });
        list.video.forEach(function (device) {
console.log            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);
}
}
});


$("#url").val(setURL() + "/" + createUUID(8));

//set initial button callback
onStopped();

if (list.audio.length === 0) {
$("#sendAudio").prop('checked', false).prop('disabled', true);
}
if (list.video.length === 0) {
$("#sendVideo").prop('checked', false).prop('disabled', true);
}
}).catch(function (error) {
$("#notifyFlash").text("Failed to get media devices");
});

3. Получение граничных параметров для аудио и видео со страницы клиента

getConstraints() код

Code Block
languagejs
function getConstraints() {
constraints = {
audio: $("#sendAudio").is(':checked'),
video: $("#sendVideo").is(':checked'),
customStream: $("#sendCanvasStream").is(':checked')
};

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());
}

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());
}
}

return constraints;
}

4. Получение доступа к медиаустройствам для локального тестирования

Flashphoner.getMediaAccess() код

В метод передаются граничные параметры для аудио и видео (constrains), а также localVideo - div-элемент, в котором будет отображаться видео с выбранной камеры.

Code Block
languagejs
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) {
var stream = localVideo.children[i].srcObject;
audioContextForTest = new AudioContext();
var microphone = audioContextForTest.createMediaStreamSource(stream);
var javascriptNode = audioContextForTest.createScriptProcessor(1024, 1, 1);
microphone.connect(javascriptNode);
javascriptNode.connect(audioContextForTest.destination);
javascriptNode.onaudioprocess = function (event) {
var inpt_L = event.inputBuffer.getChannelData(0);
var sum_L = 0.0;
for (var i = 0; i < inpt_L.length; ++i) {
sum_L += inpt_L[i] * inpt_L[i];
}
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);
                }
            }
        });


        $("#url").val(setURL() + "/" + createUUID(8));

        //set initial button callback
        onStopped();

        if (list.audio.length === 0) {
            $("#sendAudio").prop('checked', false).prop('disabled', true);
        }
        if (list.video.length === 0) {
            $("#sendVideo").prop('checked', false).prop('disabled', true);
        }
    }).catch(function (error) {
        $("#notifyFlash").text("Failed to get media devices");
    });


3. Получение граничных параметров для аудио и видео со страницы клиента

getConstraints() код

Code Block
languagejs
themeRDark
function getConstraints() {
    constraints = {
        audio: $("#sendAudio").is(':checked'),
        video: $("#sendVideo").is(':checked'),
        customStream: $("#sendCanvasStream").is(':checked')
    };

    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());
    }

    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());
        }
    }

    return constraints;
}


4. Получение доступа к медиаустройствам для локального тестирования

Flashphoner.getMediaAccess() код

В метод передаются граничные параметры для аудио и видео (constrains), а также localVideo - div-элемент, в котором будет отображаться видео с выбранной камеры.

Code Block
languagejs
themeRDark
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) {
                    var stream = localVideo.children[i].srcObject;
                    audioContextForTest = new AudioContext();
                    var microphone = audioContextForTest.createMediaStreamSource(stream);
                    var javascriptNode = audioContextForTest.createScriptProcessor(1024, 1, 1);
                    microphone.connect(javascriptNode);
                    javascriptNode.connect(audioContextForTest.destination);
                    javascriptNode.onaudioprocess = function (event) {
                        var inpt_L = event.inputBuffer.getChannelData(0);
                        var sum_L = 0.0;
                        for (var i = 0; i < inpt_L.length; ++i) {
                            sum_L += inpt_L[i] * inpt_L[i];
                        }
                        $("#micLevel").text(Math.floor(Math.sqrt(sum_L / inpt_L.length) * 100));
                    }
}
}
}
}                }
            }
        } else if (Flashphoner.getMediaProviders()[0] == "Flash") {
            micLevelInterval = setInterval(function () {
                $("#micLevel").text(disp.children[0].getMicrophoneLevel());
            }, 500);
        }
        testStarted = true;
    }).catch(function (error) {
        $("#testBtn").prop('disabled', false);
        testStarted = false;

    });


5. Подключение к серверу.

Flashphoner.createSession() код

Code Block
languagejs
themeRDark
 Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function (session) {
        //session connected, start streaming
        startStreaming(session);
    }).on(SESSION_STATUS.DISCONNECTED, function () {
        setStatus(SESSION_STATUS.DISCONNECTED);
        onStopped();
    }).on(SESSION_STATUS.FAILED, function () {
        setStatus(SESSION_STATUS.FAILED);
        onStopped();
    });


6. Получение от сервера события, подтверждающего успешное соединение.

ConnectionStatusEvent ESTABLISHED код

Code Block
languagejs
themeRDark
 Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function (session) {
        //session connected, start streaming
        startStreaming(session);

    }).on(SESSION_STATUS.DISCONNECTED, function () {
        setStatus(SESSION_STATUS.DISCONNECTED);
        onStopped();
    }).on(SESSION_STATUS.FAILED, function () {
        setStatus(SESSION_STATUS.FAILED);
        onStopped();
    });


7. Публикация видеопотока

session.createStream(), publishStream.publish() код

Code Block
languagejs
themeRDark
  publishStream = session.createStream({
        name: streamName,
        display: localVideo,
        cacheLocalResources: true,
constraints: constraints,
        constraints: constraints,
        mediaConnectionConstraints: mediaConnectionConstraints
    }).on(STREAM_STATUS.PUBLISHING, function (publishStream) {
        $("#testBtn").prop('disabled', true);
        var video = document.getElementById(publishStream.id());
        //resize local if resolution is available
        if (video.videoWidth > 0 && video.videoHeight > 0) {
            resizeLocalVideo({target: video});
        }
        enableMuteToggles(true);
        if ($("#muteVideoToggle").is(":checked")) {
)) {
            muteVideo();
        }
        if ($("#muteAudioToggle").is(":checked")) {
            muteAudio();
        }
        //remove resize listener in case this video was cached earlier
        video.removeEventListener('resize', resizeLocalVideo);
        video.addEventListener('resize', resizeLocalVideo);
        setStatus(STREAM_STATUS.PUBLISHING);

//play preview
        //play preview
        var constraints = {
            audio: $("#playAudio").is(':checked'),
            video: $("#playVideo").is(':checked')
        };
        if (constraints.video) {
            constraints.video = {
                width: (!$("#receiveDefaultSize").is(":checked")) ? parseInt($('#receiveWidth').val()) : 0,
val()) : 0,
                height: (!$("#receiveDefaultSize").is(":checked")) ? parseInt($('#receiveHeight').val()) : 0,
                bitrate: (!$("#receiveDefaultBitrate").is(":checked")) ? $("#receiveBitrate").val() : 0,
                quality: (!$("#receiveDefaultQuality").is(":checked")) ? $('#quality').val() : 0
            };
        }
previewStream = session.createStream({

        previewStream = session.createStream({
            name: streamName,
            display: remoteVideo,
            constraints: constraints
        }).on(STREAM_STATUS.PLAYING, function (previewStream) {
            document.getElementById(previewStream.id()).addEventListener('resize', function (event) {
                $("#playResolution").text(event.target.videoWidth + "x" + event.target.videoHeight);
 event.target.videoHeight);
                resizeVideo(event.target);
            });
            //enable stop button
            onStarted(publishStream, previewStream);
            //wait for incoming stream
            if (Flashphoner.getMediaProviders()[0] == "WebRTC") {
0] == "WebRTC") {
                setTimeout(function () {
                    detectSpeech(previewStream);
                }, 3000);
            }

            drawSquare();
        }).on(STREAM_STATUS.STOPPED, function () {
            publishStream.stop();
        }).on(STREAM_STATUS.FAILED, function () {
            //preview failed, stop publishStream
            if (publishStream.status() == STREAM_STATUS.PUBLISHING) {
                setStatus(STREAM_STATUS.FAILED);
                publishStream.stop();
            }
});
        });
        previewStream.play();
    }).on(STREAM_STATUS.UNPUBLISHED, function () {
        setStatus(STREAM_STATUS.UNPUBLISHED);
        //enable start button
        onStopped();
    }).on(STREAM_STATUS.FAILED, function () {
        setStatus(STREAM_STATUS.FAILED);
        //enable start button
        onStopped();
    });
    publishStream.publish();


8. Получение от сервера события, подтверждающего успешную публикацию потока

...

При получении данного события создается превью-видеопоток при помощи createStream() и вызывается play() для его воспроизведения.

Code Block
languagejs
themeRDark
publishStream = session.createStream({
name: streamName,
        name: streamName,
        display: localVideo,
        cacheLocalResources: true,
        constraints: constraints,
        mediaConnectionConstraints: mediaConnectionConstraints
    }).on(STREAM_STATUS.PUBLISHING, function (publishStream) {
        $("#testBtn").prop('disabled', true);
        var video = document.getElementById(publishStream.id());
        //resize local if resolution is available
        if (video.videoWidth > 0 && video.videoHeight > 0) {
            resizeLocalVideo({target: video});
}
: video});
        }
        enableMuteToggles(true);
        if ($("#muteVideoToggle").is(":checked")) {
            muteVideo();
        }
        if ($("#muteAudioToggle").is(":checked")) {
            muteAudio();
        }
        //remove resize listener in case this video was cached earlier
 this video was cached earlier
        video.removeEventListener('resize', resizeLocalVideo);
        video.addEventListener('resize', resizeLocalVideo);
        setStatus(STREAM_STATUS.PUBLISHING);

        //play preview
        var constraints = {
            audio: $("#playAudio").is(':checked'),
            video: $("#playVideo").is(':checked')
        };
        if (constraints.video) {
 {
            constraints.video = {
                width: (!$("#receiveDefaultSize").is(":checked")) ? parseInt($('#receiveWidth').val()) : 0,
                height: (!$("#receiveDefaultSize").is(":checked")) ? parseInt($('#receiveHeight').val()) : 0,
                bitrate: (!$("#receiveDefaultBitrate").is(":checked")) ? $("#receiveBitrate").val() : 0,
                quality: (!$("#receiveDefaultQuality").is(":checked")) ? $('#quality').val() : 0
};
}
 : 0
            };
        }
        previewStream = session.createStream({
            name: streamName,
            display: remoteVideo,
            constraints: constraints
        }).on(STREAM_STATUS.PLAYING, function (previewStream) {
            document.getElementById(previewStream.id()).addEventListener('resize', function (event) {
'resize', function (event) {
                $("#playResolution").text(event.target.videoWidth + "x" + event.target.videoHeight);
                resizeVideo(event.target);
            });
            //enable stop button
            onStarted(publishStream, previewStream);
//wait for incoming stream
            //wait for incoming stream
            if (Flashphoner.getMediaProviders()[0] == "WebRTC") {
                setTimeout(function () {
                    detectSpeech(previewStream);
                }, 3000);
}, 3000);
}

            }

            drawSquare();
        }).on(STREAM_STATUS.STOPPED, function () {
            publishStream.stop();
        }).on(STREAM_STATUS.FAILED, function () {
            //preview failed, stop publishStream
            if (publishStream.status() == STREAM_STATUS.PUBLISHING) {
                setStatus(STREAM_STATUS.FAILED);
;
                publishStream.stop();
            }
        });
        previewStream.play();
    }).on(STREAM_STATUS.UNPUBLISHED, function () {
        setStatus(STREAM_STATUS.UNPUBLISHED);
        //enable start button
        onStopped();
    }).on(STREAM_STATUS.FAILED, function () {
        setStatus(STREAM_STATUS.FAILED);
        //enable start button
        onStopped();

    });
    publishStream.publish();


9. Остановка воспроизведения превью-видеопотока.

previewStream.stop() код

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

...

StreamStatusEvent STOPPED код

Code Block
languagejs
themeRDark
previewStream = session.createStream({
            name: streamName,
            display: remoteVideo,
            constraints: constraints
        }).on(STREAM_STATUS.PLAYING, function (previewStream) {

            document.getElementById(previewStream.id()).addEventListener('resize', function (event) {
                $("#playResolution").text(event.target.videoWidth + "x" + event.target.videoHeight);
                resizeVideo(event.target);
            });
            //enable stop button
onStarted(publishStream, previewStream);
 stop button
            onStarted(publishStream, previewStream);
            //wait for incoming stream
            if (Flashphoner.getMediaProviders()[0] == "WebRTC") {
                setTimeout(function () {
                    detectSpeech(previewStream);
}, 3000);
}

);
                }, 3000);
            }

            drawSquare();
        }).on(STREAM_STATUS.STOPPED, function () {
            publishStream.stop();
        }).on(STREAM_STATUS.FAILED, function () {
            //preview failed, stop publishStream
            if (publishStream.status() == STREAM_STATUS.PUBLISHING) {
.PUBLISHING) {
                setStatus(STREAM_STATUS.FAILED);
                publishStream.stop();
            }
        });
        previewStream.play();


11. Остановка публикации видеопотока после остановки воспроизведения превью-потока.

publishStream.stop() код

Code Block
languagejs
themeRDark
 previewStream = session.createStream({
            name: streamName,
            display: remoteVideo,
            constraints: constraints
        }).on(STREAM_STATUS.PLAYING, function (previewStream) {
            document.getElementById(previewStream.id()).addEventListener('resize', function (event) {
                $("#playResolution").text(event.target.videoWidth + "x" + event.target.videoHeight);
                resizeVideo(event.target);
            });
//enable stop button
            //enable stop button
            onStarted(publishStream, previewStream);
            //wait for incoming stream
            if (Flashphoner.getMediaProviders()[0] == "WebRTC") {
                setTimeout(function () {
detectSpeech(previewStream);
 () {
                    detectSpeech(previewStream);
                }, 3000);
            }

            drawSquare();
        }).on(STREAM_STATUS.STOPPED, function () {
            publishStream.stop();
        }).on(STREAM_STATUS.FAILED, function () {
//preview failed, stop publishStream
            //preview failed, stop publishStream
            if (publishStream.status() == STREAM_STATUS.PUBLISHING) {
                setStatus(STREAM_STATUS.FAILED);
                publishStream.stop();
            }
        });
        previewStream.play();


12. Получение от сервера события, подтверждающего успешную остановку публикации

StreamStatusEvent UNPUBLISHED код

Code Block
languagejs
themeRDark
publishStream = session.createStream({
name: streamName,
        name: streamName,
        display: localVideo,
        cacheLocalResources: true,
        constraints: constraints,
        mediaConnectionConstraints: mediaConnectionConstraints
    }).on(STREAM_STATUS.PUBLISHING, function (publishStream) {
        $("#testBtn").prop('disabled', true);
        var video = document.getElementById(publishStream.id());
        //resize local if resolution is available
        if (video.videoWidth > 0 && video.videoHeight > 0) {
            resizeLocalVideo({target: video});
}
: video});
        }
        enableMuteToggles(true);
        if ($("#muteVideoToggle").is(":checked")) {
            muteVideo();
        }
        if ($("#muteAudioToggle").is(":checked")) {
            muteAudio();
        }
        //remove resize listener in case this video was cached earlier
 this video was cached earlier
        video.removeEventListener('resize', resizeLocalVideo);
        video.addEventListener('resize', resizeLocalVideo);
        setStatus(STREAM_STATUS.PUBLISHING);

        //play preview
        var constraints = {
            audio: $("#playAudio").is(':checked'),
            video: $("#playVideo").is(':checked')
        };
        if (constraints.video) {
 {
            constraints.video = {
                width: (!$("#receiveDefaultSize").is(":checked")) ? parseInt($('#receiveWidth').val()) : 0,
                height: (!$("#receiveDefaultSize").is(":checked")) ? parseInt($('#receiveHeight').val()) : 0,
                bitrate: (!$("#receiveDefaultBitrate").is(":checked")) ? $("#receiveBitrate").val() : 0,
                quality: (!$("#receiveDefaultQuality").is(":checked")) ? $('#quality').val() : 0
};
}
 : 0
            };
        }
        previewStream = session.createStream({
            name: streamName,
            display: remoteVideo,
            constraints: constraints
        }).on(STREAM_STATUS.PLAYING, function (previewStream) {
            document.getElementById(previewStream.id()).addEventListener('resize', function (event) {
'resize', function (event) {
                $("#playResolution").text(event.target.videoWidth + "x" + event.target.videoHeight);
                resizeVideo(event.target);
            });
            //enable stop button
            onStarted(publishStream, previewStream);
//wait for incoming stream
            //wait for incoming stream
            if (Flashphoner.getMediaProviders()[0] == "WebRTC") {
                setTimeout(function () {
                    detectSpeech(previewStream);
                }, 3000);
}, 3000);
}

            }

            drawSquare();
        }).on(STREAM_STATUS.STOPPED, function () {
            publishStream.stop();
        }).on(STREAM_STATUS.FAILED, function () {
            //preview failed, stop publishStream
            if (publishStream.status() == STREAM_STATUS.PUBLISHING) {
                setStatus(STREAM_STATUS.FAILED);
                publishStream.stop();
            }
        });
        previewStream.play();
    }).on(STREAM_STATUS.UNPUBLISHED, function () {
        setStatus(STREAM_STATUS.UNPUBLISHED);
        //enable start button
        onStopped();
    }).on(STREAM_STATUS.FAILED, function () {
        setStatus(STREAM_STATUS.FAILED);
        //enable start button
        onStopped();
    });
    publishStream.publish();