В Web SDK отсутствует возможность указать атрибуты video-тега

Axel

Member
Здравствуйте.

WebRTC использует video-тег, у которого есть атрибут "controls", наличие которого включает отображение различных кнопок: play\pause, ползунок громкости, кнопка fullscreen и так далее. Не нашёл способа как-либо управлять атрибутами этого video-тега посредством Web SDK. Для упомянутых выше целей у Web SDK есть специальное API, которое позволяет управлять громкостью, воспроизведением и так далее, однако, это делается лишь программно, а задача стоит показать пользователю эти элементы управления.

Можно нарисовать самостоятельно такие кнопки, внедрить в контейнер с плеером, обвешать слушателями событий и подвязать упомянутое выше API. Но это создаёт слишком много трудностей, к тому же, стандартные элементы управления из video-тега отображаются иначе в разных браузерах или ОС, улучшая UX, чего ещё сложнее добиться в случае самостоятельной реализации таких элементов управления.

Второй способ - пытаться достучаться до video-тега посредством CSS-селекторов и навешивать нужны атрибут на него. Делается, фактически, одной строкой. Но тут опять всплывают вопросы о том, что надо контролировать появление и исчезание этого тега (остановка и запуск плеера), что тоже требует написания некой минимальной обвязки в коде и её поддержки. Такой путь выглядт как хак в обход Web SDK, к чему он может привести (сейчас или в будущем) - сказать сложно.

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

Есть ли возможность включать эти кнопки посредством передачи некоего флага? В документации ничего полезного не нашёл, наличие такой опции сняло большое количество проблем. Возможно, не лишним будет предусмотреть возможность указывать атрибуты вообще (списком), а не только лишь "controls", а так же, методы API для управления этим программно.
 

Axel

Member
Добавлю, что существует так же новый атрибут "controlsList", который позволяет управлять точечно тем, какие элементы будет отрисовывать встроенный плеер. Тут есть примеры его применения. Пока что этот атрибут довольно сырой, но уже работает и имеет смысл заложить и его поддержку.
 

Max

Administrator
Staff member
Добрый день.
Вы можете использовать свой тэг video с атрибутом controls, достучаться до него можно, передав его в опцию remoteVideo при создании потока для воспроизведения. Немного изменим стандартный пример Two Way Streaming:
1. Указываем на странице two_way_streaming.html тэг video для плеера
Code:
...
           <div class="col-sm-6">
                <div class="text-center text-muted">Player</div>
                <div class="fp-Video">
                    <div id="remoteVideo" class="display"><video id="videoControls" controls="controls"></video></div>
                </div>
...
2. Передаем наш тэг в функцию создания потока для воспроизведения
Code:
var videoControls = document.getElementById("videoControls");
...
function playStream() {
    var session = Flashphoner.getSessions()[0];
    var streamName = $('#playStream').val();

    session.createStream({
        name: streamName,
        display: remoteVideo,
        remoteVideo: videoControls
    }).on(STREAM_STATUS.PENDING, function (stream) {
        var video = videoControls;
        if (!video.hasListeners) {
            video.hasListeners = true;
            video.addEventListener('resize', function (event) {
                resizeVideo(event.target);
            });
        }
    ...
    }).play();
}
...
Результат на скриншоте. Все контролы работают, кроме перемотки.
upload_2020-2-10_11-13-39.png
 

Axel

Member
Спасибо. Весьма неявная логика, стоило бы её где-нибудь задокументировать.
 

Max

Administrator
Staff member
Мы создали внутренний тикет WCS-2516 по добавлению описания и примера использования опции в доки, о результах сообщим здесь.
Отметим, что пример использования в документации все же есть, но он касается специфичного случая интеграции VR-плеера, и атрибут controls в этом примере не используется.
 

Axel

Member
@Max а есть ли возможность сделать то же самое - кастомный video-тег - для случая публикации потока, а не его проигрывания? Опция "remoteVideo" работает только для плеера, а вот при публикации попытки как-либо затолкать кастомный video-тег внутрь контейнера, который указывается в опции "display", к успеху не привели: SDK всегда создаёт новый video-тег.

Нашёлся грязный хак, состоящий в том, что можно внутри контейнера создать video-тег с ID, соответствующем маске "myVideoTag-LOCAL_CACHED_VIDEO", и задать ему кастомные атрибуты. Тогда, при старте публикации, ID этого тега подменится на UUID-образный, но атрибуты будут сохранены. Но это совсем уж костыльный вариант.
 
Last edited:

Max

Administrator
Staff member
Нашёлся грязный хак, состоящий в том, что можно внутри контейнера создать video-тег с ID, соответствующем маске "myVideoTag-LOCAL_CACHED_VIDEO", и задать ему кастомные атрибуты.
Мы предлагали другим клиентам похожий хак для работы с VR стримером и использованием кастомного video - элемента.

Создаем кастомный плеер
Code:
<video></video>
Создаем контейнер, которому при публикации будет проставлен srcObject
Code:
var mockLocalDisplay = $('<div></div>');
var mockLocalVideo = $('<video></video>',{id:'mock-LOCAL_CACHED_VIDEO'});
mockLocalDisplay.append(mockLocalVideo);
При публикации, копируем srcObject в кастомный плеер
Code:
session.createStream({
                name: $('#streamName').val(),
                display: mockLocalDisplay.get(0)
            }).on(STREAM_STATUS.PUBLISHING, function (stream) {
                var srcObject = mockLocalVideo.get(0).srcObject;
                video.srcObject = srcObject;              
                mockLocalVideo.get(0).pause();
                mockLocalVideo.get(0).srcObject = null;
             });
а есть ли возможность сделать то же самое - кастомный video-тег - для сдучая публикации потока, а не его проигрывания?
Создан тикет WCS-2747. Остановили работы по нему, т.к. не понравилась реализация, и ограничились "костылем".
Переоткроем, посмотрим, что можно сделать.
 

Axel

Member
var mockLocalVideo = $('<video></video>',{id:'mock-LOCAL_CACHED_VIDEO'});
Спасибо, фактически, то же самое, что и в моём варианте. Очень ждём WCS-2747.
 

Max

Administrator
Staff member
Добрый день.
Мы подготовили патч, который Вы можете применить к исходным текстам WebSDK и собрать их с поддержкой опции localVideo
Code:
    session.createStream({
        name: streamName,
        display: localVideo,
        cacheLocalResources: true,
        receiveVideo: false,
        receiveAudio: false,
        localVideo: customLocalVideo
Чтобы кастомный видео элемент работал при публикации в Safari, необходимо его передавать в функцию playFirstVideo
Code:
        if (Browser.isSafariWebRTC()) {
            Flashphoner.playFirstVideo(customLocalVideo, true, PRELOADER_URL).then(function() {
                publishStream();
            });
            return;
        }
Также мы добавили в документацию описание использования опции remoteVideo для кастомного видео элемента при проигрывании видео на странице.
 

Attachments

Axel

Member
Здорово, спасибо! А почему изменения не вмержены в полноценную версию, а представлены в виде патча? Этот функционал не планируется сохранить в будущем и он "разовый"?
 

Max

Administrator
Staff member
А почему изменения не вмержены в полноценную версию, а представлены в виде патча?
Очень уж костыльный вариант получился. Поэтому в основной ветке он нежелателен. Сейчас он работает во всех браузерах, тесты это подтверждают, но может и сломаться.
Этот функционал не планируется сохранить в будущем и он "разовый"?
В будущем планируется серьезная переработка WebSDK, в частности, будет поддерживаться только WebRTC как наиболее перспективная технология, без Flash (который находится накануне официальной отмены) и WSPlayer (который вымирает естественным образом вместе с устаревшими iOS устройствами). И есть планы почистить код и найти менее костыльный вариант реализации.
 

Axel

Member
Дело в том, что патч потом поддерживать кому-то придётся (видимо, мне), при мерже его с более свежими версиями WebSDK, что может весьма существенные сложности при очередном обновлении. Может, всё же стоит его таки вмержить, поскольку WebSDK и так будет рефакториться весьма существенно, а этот функционал вполне себе рабочий, как показали ваши тесты?
 

Max

Administrator
Staff member
Может, всё же стоит его таки вмержить, поскольку WebSDK и так будет рефакториться весьма существенно, а этот функционал вполне себе рабочий, как показали ваши тесты?
К сожалению, мы пока не можем оценить время до рефакторинга. Поэтому решили, что будет патч, с соответствующими рисками, и костыль в доках. Можно пользоваться либо тем, либо другим.
 

gekz

New Member
За незнанием о существовании данной темы раньше, мы "выкрутились" добавляя кнопки "на лету" уже после публикации видео:
JavaScript:
$('video').on('playing', function (e) {
    if (!this.hasAttribute("controls")) {
       this.setAttribute("controls","controls")
    }
});
 

Max

Administrator
Staff member
За незнанием о существовании данной темы раньше, мы "выкрутились" добавляя кнопки "на лету" уже после публикации видео:
Тоже вариант. Но кастомный видеоэлемент для воспроизведения работает и без костылей, как описано в документации.
 
Top