Система для отображения главного экрана докладов, экран для докладчика и поддержка оператора. Позволяет показывать презентации, заставку и по кругу карусель различные ролики и рекламу спонсоров.
  • Go 65.4%
  • HTML 22.3%
  • TypeScript 10.5%
  • JavaScript 1.2%
  • Dockerfile 0.4%
  • Other 0.2%
Find a file
Ymnuk 2a847c5c95
All checks were successful
ci/woodpecker/tag/woodpecker Pipeline was successful
feat: Cross-fade для слайдов в Проекторе
2026-07-08 19:40:22 +03:00
.vscode fix: Протокол с RC 2026-07-08 13:25:24 +03:00
cmd/display feat: Включение таймера на проекторе 2026-07-08 15:50:59 +03:00
docs feat: Включение таймера на проекторе 2026-07-08 15:50:59 +03:00
internal feat: Включение таймера на проекторе 2026-07-08 15:50:59 +03:00
test/e2e feat: Тесты 2026-07-01 08:47:05 +03:00
timers feat: Включение таймера на проекторе 2026-07-08 15:50:59 +03:00
web feat: Cross-fade для слайдов в Проекторе 2026-07-08 19:40:22 +03:00
.dockerignore fix: Приведение в порядок config.go 2026-07-07 12:51:21 +03:00
.gitignore fix: Протокол с RC 2026-07-08 13:25:24 +03:00
.woodpecker.yml fix: CI 2026-07-08 08:38:14 +03:00
display.service feat: Переходы и предпросмотры 2026-06-30 23:09:03 +03:00
docker-compose.yml feat: Переходы и предпросмотры 2026-06-30 23:09:03 +03:00
Dockerfile fix: Приведение в порядок config.go 2026-07-07 12:51:21 +03:00
Dockerfile.ci fix: CI 2026-07-08 08:38:14 +03:00
go.mod feat: Переходы и предпросмотры 2026-06-30 23:09:03 +03:00
go.sum feat: Переходы и предпросмотры 2026-06-30 23:09:03 +03:00
LICENSE first commit 2026-06-30 21:15:09 +03:00
README.md fix: Протокол с RC 2026-07-08 13:25:24 +03:00

presentation-display

Сервис для профессионального показа презентаций на конференциях. Управляет отображением контента на нескольких экранах (проектор, экран докладчика) и интегрируется с reception-conference по WebSocket-протоколу.

Быстрый старт

# Сборка
go build -o display ./cmd/display

# Запуск (флаги)
./display \
  --reception-base-url=https://reception.example.com \
  --service-token=<hex-token> \
  --venue-id=<uuid-зала> \
  --operator-password=<пароль-пульта>

# или через .env
export RECEPTION_BASE_URL=https://reception.example.com
export SERVICE_TOKEN=<hex-token>
export VENUE_ID=<uuid-зала>
export OPERATOR_PASSWORD=<пароль-пульта>
./display

Открыть в браузере:

  • http://localhost:3000/projector/ — проектор
  • http://localhost:3000/speaker/ — экран докладчика
  • http://localhost:3000/operator/ — пульт оператора

Звук в BREAK: браузер блокирует автоматическое воспроизведение со звуком без действия пользователя. Чтобы включить звук, достаточно один раз кликнуть по странице проектора или экрана докладчика. При загрузке страницы видео запускается с нулевой громкостью, после клика громкость восстанавливается.

Конфигурация

Обязательные параметры

Флаг Переменная окружения Описание
--reception-base-url RECEPTION_BASE_URL Адрес сервера reception-conference
--service-token SERVICE_TOKEN ServiceToken для аутентификации (hex)
--venue-id VENUE_ID UUID зала
--operator-password OPERATOR_PASSWORD Пароль для доступа к пульту оператора

Опциональные параметры

Флаг Переменная окружения По умолчанию Описание
--prefix PREFIX "" URL path prefix (например /display)
--listen-addr LISTEN_ADDR :3000 Адрес и порт HTTP-сервера
--reconnect-interval RECONNECT_INTERVAL 5 Интервал реконнекта к RC (сек)
--max-retries MAX_RETRIES 0 Лимит попыток реконнекта к RC (0 = без лимита)
--file-retry-interval FILE_RETRY_INTERVAL 5 Интервал повторной загрузки ZIP (сек)
--cleanup-delay CLEANUP_DELAY 30 Задержка удаления показанных слайдов (мин)
--default-duration DEFAULT_DURATION 15 Длительность доклада по умолчанию (мин)
--break-image-duration BREAK_IMAGE_DURATION 10 Длительность показа картинки в режиме BREAK (сек)
--transition-mode TRANSITION_MODE instant Режим переходов: instant / crossfade
--crossfade-duration CROSSFADE_DURATION 300 Длительность crossfade (мс)
--log-level LOG_LEVEL off Уровень логирования: off / debug / info / warn / error
--log-file LOG_FILE "" Путь к лог-файлу (stderr если пусто)
--data-dir DATA_DIR ./data Корневая папка для данных
--config CONFIG_FILE "" Путь к YAML/JSON файлу конфигурации

Приоритет

CLI-флаги > переменные окружения > config-файл > значения по умолчанию.

HTTP-эндпоинты

WebSocket

Метод Путь Описание
GET /ws?role={role} WebSocket-хаб для клиентов (projector / speaker / operator)

Статика

Метод Путь Описание
GET /projector/ Клиент проектора (vanilla JS)
GET /speaker/ Экран докладчика (vanilla JS)
GET /operator/ Пульт оператора (Angular)
GET /sw.js Service Worker

Слайды

Метод Путь Описание
GET /slides/{participant_id}/{filename} Раздача изображений слайдов

Логотип

Метод Путь Описание
GET /logo Показ загруженного логотипа
POST /api/logo Загрузка логотипа (multipart, поле file)

Джинглы (BREAK)

Метод Путь Описание
GET /breaks/{filename} Раздача файлов джинглов
POST /api/breaks/upload Загрузка джингла (multipart, поле file)
GET /api/breaks/list Список джинглов
DELETE /api/breaks/{filename} Удаление джингла
POST /api/breaks/reorder Изменение порядка плейлиста (JSON-массив имён)
GET /api/breaks/volume Получить громкость
POST /api/breaks/volume Установить громкость ({"volume": 50})

Таймер

Метод Путь Описание
GET /api/timer/template Получить активный HTML-шаблон таймера
GET /api/timer/template/list Список загруженных шаблонов
POST /api/timer/template/upload Загрузить HTML-шаблон (multipart, поле file)
POST /api/timer/template/select Выбрать активный шаблон ({"name": "..."})

Preview

Метод Путь Описание
GET /preview/{participant_id}?base_url=...&token=... Предпросмотр слайдов участника

Мониторинг

Метод Путь Описание
GET /health Health-check (ok)
GET /metrics Prometheus-метрики

URL Prefix

Все маршруты монтируются под опциональный префикс (--prefix). Например, при --prefix=/display:

  • /display/ws → WS-хаб
  • /display/operator/ → пульт оператора

Клиенты получают префикс через runtime-подстановку в HTML: {{PREFIX}}, {{WS_URL}}, {{BASE_HREF}}.

Метрики Prometheus

Доступны по /metrics:

Метрика Тип Описание
display_clients_connected Gauge Клиенты по ролям (label: role)
display_current_mode Gauge 0=IDLE, 1=BREAK, 2=PRESENTATION
display_slides_total Counter Всего показано слайдов
display_break_duration_seconds Counter Время в BREAK
display_presentation_duration_seconds Counter Время в PRESENTATION
display_errors_total Counter Ошибки по кодам (label: code)

Протокол с reception-conference

Подключение

GET /api/v1/display/ws
Authorization: Bearer <service-token>

После upgrade сервер отправляет welcome:

{"type":"welcome","venue_id":"...","current_state":{"mode":"idle","participant_id":"...","name":"...","topic":"...","duration_minutes":15}}

reception не отправляет current_slide, total_slides, timer_remaining, slides и другие локально управляемые поля — display хранит их самостоятельно.

Команды от RC

Тип Описание
presentation_start Начать доклад (participant_id, name, topic, duration_minutes). total_slides не приходит — display берёт из ZIP
presentation_stop Остановить доклад
queue_next Предзагрузить следующего участника (participant_id, name, topic, duration_minutes)
pong Ответ на ping

Команды от display

Тип Описание
ping Keepalive (каждые 30 сек)
error Ошибка выполнения (code, message)

Внутренний WebSocket-протокол (хаб ↔ клиенты)

Подключение

GET {prefix}/ws?role=projector|speaker|operator

После upgrade сервер отправляет current_state с полным состоянием.

Команды сервера → клиент

Тип Описание
current_state Текущее состояние (mode, слайд, таймер, плейлист)
presentation_started Начат доклад (participant_id, name, topic, total_slides, slide_base_url)
presentation_stopped Доклад завершён
slide_changed Смена слайда (current_slide, total_slides, annotation)
show_idle Показать IDLE-заставку
show_break Показать BREAK-плейлист
play_break Воспроизвести конкретный файл из BREAK-плейлиста (filename, url, media_type, volume, duration_sec)
volume_changed Изменение громкости (volume)
logo_changed Логотип обновлён — перезапросить /logo
timer_update Обновление таймера (remaining_seconds, paused)
display_error Ошибка (code, message)

Команды клиент → сервер

Тип Описание
auth Аутентификация оператора ({"password":"..."})
next_slide Следующий слайд
prev_slide Предыдущий слайд
set_mode Смена режима ({"mode":"idle"|"break"})
pause_timer Пауза/возобновление таймера ({"paused":true|false})
break_ended Уведомление, что воспроизведение брейка завершено ({"filename":"..."})
set_volume Установка громкости ({"volume":50})

Сборка

# Сервер
go build -o display ./cmd/display

# Angular-клиент оператора
cd web/operator && npm i && npm run build

Тестирование

go test ./...
go test -tags=integration ./...

Docker

docker build -t display .
docker run -p 3000:3000 \
  -e RECEPTION_BASE_URL=... \
  -e SERVICE_TOKEN=... \
  -e VENUE_ID=... \
  -e OPERATOR_PASSWORD=... \
  display

Смотрите также: