Tune frame queue and viewport sizing
This commit is contained in:
@@ -70,8 +70,8 @@ Relay mode uses bounded per-worker input queues so one branch can briefly lag wi
|
||||
The UI intentionally hides these settings, but the backend still supports them through `POST /api/session`.
|
||||
|
||||
- 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. Set the default with `JPEG_QUALITY`; `7` is the fallback, `2` is high quality, and `18` is rough but lighter.
|
||||
- Max width defaults to `960px`, and the client now caps each session to its viewport width. Lower `DEFAULT_FRAME_WIDTH` first if bandwidth or image decode is the bottleneck.
|
||||
- JPEG quality uses ffmpeg's `-q:v` scale, where lower is better/larger. Set the default with `JPEG_QUALITY`; `7` is the fallback, `2` is high quality, and `18` is rough but much lighter.
|
||||
- Audio defaults to stereo MP3 at `160k`. Tune with `DEFAULT_AUDIO_BITRATE`, `DEFAULT_AUDIO_CHANNELS`, and `DEFAULT_AUDIO_SAMPLE_RATE`.
|
||||
|
||||
## Tradeoffs
|
||||
|
||||
@@ -95,7 +95,7 @@ elements.form.addEventListener('submit', async (event) => {
|
||||
const response = await fetch('/api/session', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ url: elements.url.value }),
|
||||
body: JSON.stringify({ url: elements.url.value, width: getViewportFrameWidth() }),
|
||||
});
|
||||
|
||||
const payload = await response.json();
|
||||
@@ -752,7 +752,7 @@ function trimPendingFrameQueue() {
|
||||
if (overflow > 0) {
|
||||
noteClientTelemetry('pendingQueueOverflowFrames', overflow);
|
||||
noteClientTelemetryMax('pendingQueuePeakFrames', state.pendingFrames.length);
|
||||
state.pendingFrames.splice(0, overflow);
|
||||
state.pendingFrames.splice(maxQueuedFrames, overflow);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -766,7 +766,7 @@ function trimFrameQueue() {
|
||||
return;
|
||||
}
|
||||
|
||||
const removed = state.frames.splice(0, overflow);
|
||||
const removed = state.frames.splice(maxQueuedFrames, overflow);
|
||||
noteClientTelemetry('decodedQueueOverflowFrames', overflow);
|
||||
noteClientTelemetryMax('decodedQueuePeakFrames', state.frames.length + overflow);
|
||||
|
||||
@@ -816,6 +816,15 @@ function getFrameQueueLimit(seconds, minimum) {
|
||||
return Math.max(minimum, Math.ceil(fps * seconds));
|
||||
}
|
||||
|
||||
function getViewportFrameWidth() {
|
||||
const width = Math.ceil(Math.max(
|
||||
document.documentElement.clientWidth || 0,
|
||||
window.innerWidth || 0,
|
||||
));
|
||||
|
||||
return clampNumber(width, 160, 1920);
|
||||
}
|
||||
|
||||
function isLateFrame(timestamp) {
|
||||
if (!state.session || state.isSeeking || elements.audio.paused || elements.audio.readyState === 0) {
|
||||
return false;
|
||||
|
||||
@@ -133,6 +133,8 @@ app.post('/api/session', async (request, response) => {
|
||||
lastUsedAt: Date.now(),
|
||||
});
|
||||
|
||||
logInfo(`session created id=${shortId(id)} mode=${getSessionPlaybackConnectionMode(sessions.get(id))} fps=${options.fps} width=${options.width} quality=${options.quality}`);
|
||||
|
||||
if (METADATA_PROBE_ENABLED) {
|
||||
startSessionMetadataProbe(sessions.get(id));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user