8 800 555-91-99
#

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

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

Один из них — плеер 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. Чтобы добавить необходимую функциональность, нужно было:

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


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

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


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


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=

происходит редирект на

itsshare://

Далее открывается плеер VLC (так как он является обработчиком данного протокола), в который передается соответствующий URL. ShareService перехватывает данный URL, извлекает хэш сессии и обращается с ним на эндпойнт api/session/get для получения источника воспроизведения. Источник связывается с хэшем сеанса для последующего использования при взаимодействии с API.

При изменении статуса элемента списка воспроизведения (play/pause/stop) идёт проверка, имеется ли связанный с ним хэш сеанса — и если есть, то он отсылается на соответствующий событию эндпойнт — api/stream/playapi/session/pauseapi/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.mmodules/gui/macosx/library/VLCLibraryWindow.m 
    и modules/gui/macosx/menus/VLCMainMenu.m/
  4. Инициализирован юнит в классе modules/gui/macosx/main/VLCMain.m


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

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


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

Ну, а пока — вы знаете, чем занять себя сегодняшним вечером :-)

Мы используем cookies для быстрой и удобной работы сайта. Продолжая пользоваться сайтом, вы даёте согласие и принимаете политику обработки персональных данных