diff --git a/VERSION.properties b/VERSION.properties index 0c239cdf..6e74ebe8 100644 --- a/VERSION.properties +++ b/VERSION.properties @@ -1,2 +1,2 @@ -client.version=1.5.21 +client.version=1.5.22 server.version=1.4.9 diff --git a/shine-UI/js/services/call-service.js b/shine-UI/js/services/call-service.js index df2e154c..b25dedd0 100644 --- a/shine-UI/js/services/call-service.js +++ b/shine-UI/js/services/call-service.js @@ -1668,6 +1668,7 @@ async function ensurePeerConnection(call) { call.videoSender = sender; call.videoTransceiver = (pc.getTransceivers?.() || []).find((tr) => tr?.sender === sender) || null; bindVideoSenderStream(call, sender); + await applyVideoSenderEncodingProfile(sender, 'placeholder'); } else { ensureReservedVideoTransceiver(call); } @@ -2008,8 +2009,8 @@ function ensureBlackVideoTrack(call) { return existingTrack; } const canvas = document.createElement('canvas'); - canvas.width = 640; - canvas.height = 360; + canvas.width = 160; + canvas.height = 90; const ctx = canvas.getContext('2d'); if (!ctx || typeof canvas.captureStream !== 'function') { return null; @@ -2025,6 +2026,32 @@ function ensureBlackVideoTrack(call) { return track; } +async function applyVideoSenderEncodingProfile(sender, mode = 'camera') { + if (!sender || typeof sender.getParameters !== 'function' || typeof sender.setParameters !== 'function') { + return; + } + try { + const params = sender.getParameters() || {}; + const encodings = Array.isArray(params.encodings) && params.encodings.length > 0 + ? [...params.encodings] + : [{}]; + const nextEncoding = { ...encodings[0] }; + if (mode === 'placeholder') { + nextEncoding.maxBitrate = 12000; + nextEncoding.maxFramerate = 1; + nextEncoding.scaleResolutionDownBy = 1; + nextEncoding.active = true; + } else { + delete nextEncoding.maxBitrate; + delete nextEncoding.maxFramerate; + delete nextEncoding.scaleResolutionDownBy; + nextEncoding.active = true; + } + params.encodings = [nextEncoding]; + await sender.setParameters(params); + } catch {} +} + async function disableCameraTrack(call) { const videoTrack = call?.localVideoTrack || null; if (videoTrack) { @@ -2068,10 +2095,12 @@ async function applyCameraState(call) { await videoTransceiver.sender.replaceTrack(videoTrack); call.videoSender = videoTransceiver.sender; bindVideoSenderStream(call, videoTransceiver.sender); + await applyVideoSenderEncodingProfile(videoTransceiver.sender, 'camera'); } else { const sender = pc.addTrack(videoTrack, call.localStream); call.videoSender = sender; bindVideoSenderStream(call, sender); + await applyVideoSenderEncodingProfile(sender, 'camera'); } videoTrack.enabled = true; } else { @@ -2096,6 +2125,7 @@ async function applyCameraState(call) { try { await videoTransceiver.sender.replaceTrack(blackTrack || null); } catch {} call.videoSender = videoTransceiver.sender; bindVideoSenderStream(call, videoTransceiver.sender); + await applyVideoSenderEncodingProfile(videoTransceiver.sender, 'placeholder'); } await disableCameraTrack(call); }