From 9d1f4cc53bffdd832c81141c0fa88efcf54f7a01 Mon Sep 17 00:00:00 2001 From: James Magahern Date: Fri, 29 May 2026 10:21:25 -0700 Subject: [PATCH] Make JPEG quality configurable --- AGENTS.md | 3 ++- README.md | 2 +- docker-compose-example.yml | 1 + server/index.js | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index a556b6b..23f92b0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -176,6 +176,7 @@ Runtime: - `RECENT_URL_LIMIT`: recent URL count, default `12`. - `FAVORITES_PATH`: favorites JSON path. - `FAVORITES_LIMIT`: favorites count, default `50`. +- `JPEG_QUALITY`: default JPEG quality, fallback `7`, clamped `2..18`; lower is better for ffmpeg `-q:v`. - `MAX_WS_BUFFER_BYTES`: server-side WebSocket JPEG frame backlog cap, default `2097152`. - `MAX_AUDIO_QUEUE_BYTES`: single-mode audio output queue cap, default `16777216`. - `MAX_RELAY_BRANCH_QUEUE_BYTES`: relay per-branch compressed-input queue cap, default `16777216`. @@ -184,7 +185,7 @@ Session playback options are accepted by `POST /api/session` even though the UI - `fps`: default `24`, clamped `1..30`. - `width`: default `960`, clamped `160..1920`. -- `quality`: default `5`, clamped `2..18`; lower is better for ffmpeg `-q:v`. +- `quality`: defaults to `JPEG_QUALITY`, clamped `2..18`; lower is better for ffmpeg `-q:v`. - `audioBitrate`: default `160k`, accepts two or three digits followed by `k`. ## Docker Notes diff --git a/README.md b/README.md index e83c91d..65b58e9 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ The UI intentionally hides these settings, but the backend still supports them t - Frame rate defaults to `24fps`. Lower it if the client cannot keep up. - Max width defaults to `960px`. Lower it first if bandwidth or image decode is the bottleneck. -- JPEG quality uses ffmpeg's `-q:v` scale, where lower is better. `5` is the default, `2` is high quality, and `18` is rough but lighter. +- JPEG quality uses ffmpeg's `-q:v` scale, where lower is better. Set the default with `JPEG_QUALITY`; `7` is the fallback, `2` is high quality, and `18` is rough but lighter. - Audio defaults to MP3 at `160k`. ## Tradeoffs diff --git a/docker-compose-example.yml b/docker-compose-example.yml index d051fd2..dfd3218 100644 --- a/docker-compose-example.yml +++ b/docker-compose-example.yml @@ -15,6 +15,7 @@ services: PLAYBACK_CONNECTION_MODE: relay FFMPEG_LOG_LEVEL: warning FFMPEG_INPUT_SEEKABLE: "0" + JPEG_QUALITY: "7" MAX_WS_BUFFER_BYTES: "2097152" MAX_AUDIO_QUEUE_BYTES: "16777216" MAX_RELAY_BRANCH_QUEUE_BYTES: "16777216" diff --git a/server/index.js b/server/index.js index 021cfe8..411e2f8 100644 --- a/server/index.js +++ b/server/index.js @@ -39,7 +39,7 @@ const JPEG_EOI = Buffer.from([0xff, 0xd9]); const defaults = { fps: 24, width: 960, - quality: 5, + quality: clampInteger(process.env.JPEG_QUALITY, 7, 2, 18), audioBitrate: '160k', };