Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 6 Next »

Пример стримера c доступом к медиа-устройствам

Данный стример может использоваться для публикации следующих типов потоков с Web Call Server

  • WebRTC
  • RTMFP
  • RTMP

и позволяет выбрать медиа-устройства и параметры для публикуемого видео

  • камера
  • микрофон
  • FPS (Frames Per Second)
  • разрешение (ширина, высота)

На скриншоте ниже представлен пример во время публикации потока.


На странице вопроизводятся два видео:

  • 'Local' - видео с камеры
  • 'Preview' - видео, которое приходит с сервера

Код примера

Код данного примера находится на WCS-сервере по следующему пути:

/usr/local/FlashphonerWebCallServer/client2/examples/demo/streaming/media_devices_manager

manager.css - файл стилей
media_device_manager.html - страница стримера
manager.js - скрипт, обеспечивающий работу стримера

Тестировать данный пример можно по следующему адресу:

https://host:8888/client2/examples/demo/streaming/media_devices_manager/media_device_manager.html

Здесь host - адрес WCS-сервера.

Работа с кодом примера

Для разбора кода возьмем версию файла manager.js, которая находится здесь и доступна для скачивания в соответствующей сборке 0.5.28.2747.

1. Инициализация API.

Flashphoner.init() код

       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").hide();
                    $("#sendAudioBitrateForm").hide();
                    $("#cpuOveruseDetectionForm").hide();
                }
                if (Flashphoner.isUsingTemasys()) {
                    $("#audioInputForm").hide();
                    $("#videoInputForm").hide();
                }
            }
        })


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

Flashphoner.getMediaDevices() код

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

    Flashphoner.getMediaDevices(null, true).then(function (list) {
        list.audio.forEach(function (device) {
            ...
        });
        list.video.forEach(function (device) {
            ...
        });
        ...
    }).catch(function (error) {
        $("#notifyFlash").text("Failed to get media devices");
    });


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

getConstraints() код

Источники публикации:

  • камера (sendVideo)
  • микрофон (sendAudio)
  • HTML5 Canvas (sendCanvasStream)
    constraints = {
        audio: $("#sendAudio").is(':checked'),
        video: $("#sendVideo").is(':checked'),
        customStream: $("#sendCanvasStream").is(':checked')
    };

Параметры аудио:

  • выбор микрофона (deviceId)
  • коррекция ошибок для кодека Opus (fec)
  • режим стерео (stereo)
  • битрейт аудио (bitrate)
    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());
    }

Параметры видео:

  • выбор камеры (deviceId)
  • размеры при публикации (width, height)
  • минимальный и максимальный битрейт видео (minBitrate, maxBitrate)
  • FPS (frameRate)
            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());


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

Flashphoner.getMediaAccess() код

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

    Flashphoner.getMediaAccess(getConstraints(), localVideo).then(function (disp) {
        $("#testBtn").text("Release").off('click').click(function () {
            $(this).prop('disabled', true);
            stopTest();
        }).prop('disabled', false);
        ...
        testStarted = true;
    }).catch(function (error) {
        $("#testBtn").prop('disabled', false);
        testStarted = false;
    });


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

Flashphoner.createSession() код

    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 код

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


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

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

    publishStream = session.createStream({
        name: streamName,
        display: localVideo,
        cacheLocalResources: true,
        constraints: constraints,
        mediaConnectionConstraints: mediaConnectionConstraints
        ...
    });
    publishStream.publish();


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

StreamStatusEvent PUBLISHING код

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

    publishStream = session.createStream({
        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});
        }
        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
        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
            };
        }
        previewStream = session.createStream({
            name: streamName,
            display: remoteVideo,
            constraints: constraints
            ...
        });
        previewStream.play();
    }).on(STREAM_STATUS.UNPUBLISHED, function () {
        ...
    }).on(STREAM_STATUS.FAILED, function () {
        ...
    });
    publishStream.publish();


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

previewStream.stop() код

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


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

StreamStatusEvent STOPPED код

        previewStream = session.createStream({
            name: streamName,
            display: remoteVideo,
            constraints: constraints
        }).on(STREAM_STATUS.PLAYING, function (previewStream) {
            ...
        }).on(STREAM_STATUS.STOPPED, function () {
            publishStream.stop();
        }).on(STREAM_STATUS.FAILED, function () {
            ...
        });
        previewStream.play();


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

publishStream.stop() код

        previewStream = session.createStream({
            name: streamName,
            display: remoteVideo,
            constraints: constraints
        }).on(STREAM_STATUS.PLAYING, function (previewStream) {
            ...
        }).on(STREAM_STATUS.STOPPED, function () {
            publishStream.stop();
        }).on(STREAM_STATUS.FAILED, function () {
            ...
        });
        previewStream.play();


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

StreamStatusEvent UNPUBLISHED код

    publishStream = session.createStream({
        name: streamName,
        display: localVideo,
        cacheLocalResources: true,
        constraints: constraints,
        mediaConnectionConstraints: mediaConnectionConstraints
    }).on(STREAM_STATUS.PUBLISHING, function (publishStream) {
        ...
    }).on(STREAM_STATUS.UNPUBLISHED, function () {
        setStatus(STREAM_STATUS.UNPUBLISHED);
        //enable start button
        onStopped();
    }).on(STREAM_STATUS.FAILED, function () {
        ...
    });
    publishStream.publish();
  • No labels