company_banner

Говорим и показываем: как мы создали сервис синхронного просмотра видео ITSkino на основе VLC



    О том, что самоизоляция — это не только «тук-тук-тук» в крышку гроба экономики, но и новые «горизонты возможностей», уже написано немало статей. Правда, многие из них вызывают в памяти басню Крылова про лису и виноград. Но всё же в одном карантинные коучи правы: вся эта ситуация заставляет изобретать — не обязательно какие-то глобальные штуки, которые изменят новый мировой порядок. Иногда — просто небольшие продукты, которые помогли сделать самоизоляцию чуть более выносимой. Об одном из них, плеере ITSkino, мы уже вкратце писали. А сейчас хотим рассказать, как и что мы делали, чтобы наделить VLC функцией синхронного просмотра потокового или локального видео у неограниченного количества человек одновременно.

    У нас сейчас есть две сборки — под Windows и под MacOS. Исходные коды можно найти по этой ссылке. Два наших разработчика рассказывают о нюансах, с которыми столкнулись в процессе создания сборок.

    Windows


    Сборка как самого приложения, так и окружения описана здесь. Мы использовали метод сборки MinGW on Linux (ОС – Ubuntu 16.04.6 LTS).

    Во время сборки могут приключиться разного рода сложности. Что-то можно нагуглить сходу, что-то не сразу, что-то можно найти у наших китайских братьев по ссылкам, например, www.cnblogs.com/johnsen/p/11721632.html или blog.csdn.net/DANFBAORE/article/details/95188935. В конечном итоге, всё получится!

    Идеологически правильно было бы сделать отдельный модуль, но хотелось побыстрее собрать mvp, посмотреть и «пощупать», что получится. Поэтому решили немного допилить уже имеющийся модуль интерфейса (/modules/gui/qt). Версия qt, которая собирается «из коробки», не имела на борту поддержки сети (QNetwork), https (openSSL), а также был выключен плагин поддержки gif. Чтобы добавить необходимую функциональность, нужно было:

    • Собрать openSSL

    git clone https://github.com/openssl/openssl.git
    cd openssl  
    git checkout OpenSSL_1_0_2-stable   
    ./Configure --cross-compile-prefix=x86_64-w64-mingw32- mingw64   
    make  
    sudo make install

    • Добавить поддержку необходимых сетевых подсистем и плагинов, изменив файлы configure.ac и contrib/src/qt/rules.mak.

    • Собрать (пересобрать) qt.

    «Центр» всей системы — ShareService — синглтон, который инициализируется вместе с модулем интерфейса.

    Его основная функциональность:

    • «перехват» и обработка элементов списка воспроизведения, использующих в качестве источника адреса, начинающиеся с itsshare://
    • обработка изменения состояния элементов списка воспроизведения (play/pause/stop);
    • обработка события «поделиться»;
    • регистрация плейера как обработчика протокола itsshare.

    Второстепенные функции:

    • установка директории для синхронизации локальных видеофайлов;
    • проигрывание видеоинструкции при первом запуске;
    • сохранение и загрузка параметров, необходимых для работы сервиса.

    API вызовы:

    1. Создание сеанса — api/stream/create
    2. Получить источник сеанса по хэшу — api/session/get
    3. Play — api/stream/play
    4. Pause — api/session/pause
    5. Stop — api/session/stop

    При первом запуске приложения генерируется уникальный идентификатор пользователя и происходит регистрация плеера как обработчика протокола itsshare.

    Если во время воспроизведения видео, которое не участвует в сеансе совместного просмотра, пользователь нажал на кнопку «поделиться» (выбрал соответствующий пункт в меню ITSKino), то на эндпойнт api/stream/create отправляется запрос, содержащий источник (имя локального файла или ссылка на потоковое видео) и текущее время воспроизведения. В ответ мы получаем хэш созданного сеанса и ссылку на него, которая автоматически копируется в буфер обмена. Данный хэш сеанса, ассоциированный с источником, мы храним для последующего использования при взаимодействии с API.

    При открытии в браузере ссылки
    https://itskino.ru/join?stream=<hash>
    происходит редирект на
    itsshare://<hash>
    Далее открывается плеер VLC (так как он является обработчиком данного протокола), в который передается соответствующий URL. ShareService перехватывает данный URL, извлекает хэш сессии и обращается с ним на эндпойнт api/session/get для получения источника воспроизведения. Источник связывается с хэшем сеанса для последующего использования при взаимодействии с API.

    При изменении статуса элемента списка воспроизведения (play/pause/stop) идёт проверка, имеется ли связанный с ним хэш сеанса — и если есть, то он отсылается на соответствующий событию эндпойнт — api/stream/play, api/session/pause, api/session/stop. Запрос на api/stream/play возвращает текущее время воспроизведения сеанса совместного просмотра.

    Если все участники сеанса отослали запрос api/session/pause, то сеанс приостанавливается и возобновляется только при первом запросе api/stream/play. При переключении элементов списка воспроизведения, источники которых связаны с хэшем сеанса, происходит обращение на api/session/stop. Сеанс перестает существовать, если все участники процесса отослали api/session/stop.

    Публичный репозиторий

    macOS


    Билд:

    Обнаружилась проблема с libiconv: если есть libiconv в /usr/local/ lib, надо временно переименовать папку lib, чтобы подсосался дефолтный libiconv из usr/lib.

    Юнит:

    1. Сделан класс ItsUnit (фактически, аналог ShareService в виндовой сборке) и добавлен в мейк modules/gui/macosx/Makefile.am: юнит обрабатывает 5 эндпойнтов API (play, pause, stop, create, connect) и дополнительные методы (реакция на изменение элемента в плейлисте, проигрывание видеоинструкции, добавление, выбор папки синхронизации и т.д.)
    2. Чтобы приложение в macOS открывалось по кастомному протоколу, нужно следовать инструкции.
    3. Методы класса интегрированы в нужных местах модуля macOS GUI (в основном — modules/gui/macosx/playlist/VLCPlayerController, а также modules/gui/macosx/os-integration/applescript.m, modules/gui/macosx/library/VLCLibraryWindow.m и modules/gui/macosx/menus/VLCMainMenu.m/
    4. Инициализирован юнит в классе modules/gui/macosx/main/VLCMain.m

    Публичный репозиторий — github.com/itsumma/itskino_mac

    Вместо вывода


    Тут, в общем, и нет никакого вывода: +\- какие-то похожие решения существовали и раньше. Просто мы сильно скучали по офису и друг другу. И решили, что раз мы айтишники, то можем себе позволить потратить немного времени, чтобы сделать штуку, которая объединит классные функции других решений и будет при этом open source, как мы любим. Ребята, которые писали выше про сборки, чуток поскромничали: не всё элементарно (и упорядочено) в исходниках VLC, и поразбираться всё-таки пришлось. Но на выходе получилось и красиво, и полезно — потому что самоизоляция закончится (ну, рано или поздно), а наше решение пригодится и дальше. И не только тем, кто хочет посмотреть вместе кино, но и, например, в дистанционном обучении.

    Ну, а пока — вы знаете, чем занять себя вечером этой пятницы :-)
    ITSumma
    Собираем безумных людей и вместе спасаем интернет

    Комментарии 3

      0

      Как насчёт поддержки Linux?

        0
        Можете подсказать, почему у меня VLC пропускает часть аудиокниги, скаченной на комп? Слушаю-слушаю, и вдруг понимаю, что речь уже идёт о чём-то, чего я не понимаю. Смотрю, а книга на 5-10 мин вперёд проскочила. Ручная прокрутка не помогает :(
          0
          А можно чуть больше тех подробностей? Какой протокол вещания выбрали? Какая задержка была между людьми? Что происходит при нажатии на паузу? Вещали только на десктоп?

          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

          Самое читаемое