Fix video codec, aspect and placement

Three problems visible at once on a running instance: the picture
stuttered and drifted behind the sound, it was letterboxed oddly, and it
appeared as a separate tile instead of coming from the bot.

- YouTube handed us AV1 (format 398). Software-decoding AV1 at 720p does
  not sustain real time on a small server, which explains both the
  stutter and the drift; H.264 is now requested first, VP9 second.
- The frame was padded into a fixed box, so a clip whose proportions
  differed got black bars baked in and then more from the client. Size is
  now a bounding box and the frame keeps the clip's own proportions.
- Video was published as a screen share, which every client renders as
  its own tile. VIDEO_SOURCE=camera (the new default) puts it inside the
  bot's tile; "screen" keeps the old behaviour.

VIDEO_SYNC_OFFSET_MS is there for the residual drift, since audio and
video travel as two separately published tracks. Measured loudnorm first
to rule it out as the cause of the desync: it adds 0 ms.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Leonid Pershin
2026-09-09 02:29:29 +03:00
co-authored by Claude Opus 5
parent 9285fd7fbd
commit 0b17b880d6
7 changed files with 113 additions and 25 deletions
+12
View File
@@ -83,10 +83,22 @@ YTDLP_JS_RUNTIME=node
# Это лишь разрешение: сам показ включается тумблером в панели или командой
# !video, и по умолчанию выключен. При false тумблер в панели не показывается.
VIDEO_ENABLED=false
# Рамка, в которую вписывается кадр: пропорции клипа сохраняются, чёрные поля
# не добавляются. 640x360 выбрано из осторожности — видео грузит CPU.
VIDEO_WIDTH=640
VIDEO_HEIGHT=360
VIDEO_FPS=24
# camera — картинка внутри плитки бота; screen — отдельной плиткой,
# как демонстрация экрана.
VIDEO_SOURCE=camera
# Подстройка синхронизации, мс. Плюс задерживает видео, минус — торопит.
# Звук и картинка публикуются двумя дорожками, поэтому идеального совпадения
# «из коробки» не гарантируется.
VIDEO_SYNC_OFFSET_MS=0
DEFAULT_VOLUME=60
MAX_QUEUE_SIZE=500