restore browser video codec defaults
Build and Publish / Metadata (push) Successful in 2s
Build and Publish / BuildAndDeployAmd64 (push) Successful in 11m6s

This commit is contained in:
mats committed 2026-09-22 17:37:47 +02:00
1 parent 2888a54259
commit 25bc94a3a1
3 files changed
+19 -21

No files matched your search

+2
View File
@@ -24,6 +24,8 @@ PORT=8081 npm start
and periodic packet-loss, jitter, and RTT quality diagnostics.
- Audio input has manual gain control and a live signal/clipping meter in the
settings dialog; microphone processing is split into `public/audio-manager.js`.
- Screen sharing uses the browser's default codec negotiation, with selectable
`detail` (text/UI) or `motion` (gameplay) content hints.
## ICE configuration (server side)
+9 -21
View File
@@ -37,6 +37,7 @@ const FALLBACK_ICE = { iceServers: [{ urls: ['stun:turn.k6n.net:3478', 'stun:stu
const LS_NAME = 'voicepoc.nick';
const LS_ICE = 'voicepoc.iceOverride';
const LS_AUDIO_INPUT = 'voicepoc.audioInput';
const LS_SCREEN_HINT = 'voicepoc.screenHint';
const S = {
ws: null,
@@ -159,26 +160,6 @@ function preferOpus(pc) {
}
}
function preferH264(pc) {
const capabilities = globalThis.RTCRtpReceiver?.getCapabilities?.('video');
const codecs = capabilities?.codecs || [];
const rank = (codec) => {
const mime = codec.mimeType?.toLowerCase() || '';
if (mime === 'video/h264') return 0;
if (mime === 'video/vp8') return 1;
if (mime === 'video/vp9') return 2;
return 3;
};
const ordered = [...codecs].sort((a, b) => rank(a) - rank(b));
for (const transceiver of pc.getTransceivers()) {
if (transceiver.receiver?.track?.kind === 'video' || transceiver.sender?.track?.kind === 'video') {
try { transceiver.setCodecPreferences(ordered); } catch (err) {
captureRumIssue('Could not prefer H.264 video codec', 'WARNING', { error: err?.message || String(err) });
}
}
}
}
function monitorPeerQuality(peer) {
if (peer.qualityTimer) clearInterval(peer.qualityTimer);
peer.qualityTimer = setInterval(async () => {
@@ -1035,6 +1016,8 @@ async function startScreenShare() {
for (const peer of S.peers.values()) addScreenToPeer(peer);
const videoTrack = stream.getVideoTracks()[0];
if (videoTrack) {
const screenHint = localStorage.getItem(LS_SCREEN_HINT) || '';
if ('contentHint' in videoTrack) videoTrack.contentHint = screenHint;
videoTrack.addEventListener('ended', () => stopScreenShare(stream));
}
renderScreens();
@@ -1057,7 +1040,6 @@ function addScreenToPeer(peer) {
}
peerSenders.set(streamId, senders);
}
preferH264(peer.pc);
S.screenSenders.set(peer.id, peerSenders); // renegotiation fires automatically
}
@@ -2199,6 +2181,8 @@ function openSettings() {
const gain = $('#mic-gain');
if (gain) gain.value = S.audioManager.gain;
updateMicGainUi();
const screenHint = $('#screen-hint');
if (screenHint) screenHint.value = localStorage.getItem(LS_SCREEN_HINT) || '';
const override = localStorage.getItem(LS_ICE);
$('#override-enabled').checked = !!override;
const current = override ? JSON.parse(override) : effectiveIce();
@@ -2220,6 +2204,10 @@ $('#mic-gain').oninput = (ev) => {
S.audioManager.setGain(ev.target.value);
updateMicGainUi();
};
$('#screen-hint').onchange = (ev) => {
localStorage.setItem(LS_SCREEN_HINT, ev.target.value);
toast('Screen-share hint saved — applies next time you share', 'ok');
};
$('#audio-input').onchange = (ev) => switchAudioInput(ev.target.value);
$('#ice-cancel').onclick = () => $('#modal-backdrop').classList.add('hidden');
$('#modal-backdrop').onclick = (ev) => {
+8
View File
@@ -150,6 +150,14 @@
</div>
<p id="mic-clipping" class="hint hidden">Clipping detected — reduce microphone gain.</p>
<p class="hint">Changes apply immediately when connected, or the next time you join.</p>
<h3>Screen sharing</h3>
<label class="field-label" for="screen-hint">Optimization</label>
<select id="screen-hint" class="settings-select">
<option value="">Browser default</option>
<option value="detail">Details / text editor / terminal</option>
<option value="motion">Gameplay / motion</option>
</select>
<p class="hint">Details favors sharp text; motion favors smoother movement.</p>
<p class="hint">Overrides the server-provided ICE configuration (stored in <code>localStorage</code>, applied on next join).</p>
<label class="toggle-row">
<input type="checkbox" id="override-enabled" />