feat: Restore Overdrive v22 Soft-Launch Protocol
Restores the working smooth resolution ramp-up pipeline that starts at 360p to clear the WebRTC handshake, then upgrades to target quality after 2 seconds.
This commit is contained in:
@@ -3,16 +3,16 @@ import { Room, RoomEvent, Track, ConnectionState, VideoPresets, VideoPreset, } f
|
|||||||
import { api } from '../api/client';
|
import { api } from '../api/client';
|
||||||
import { useVoiceStore } from '../stores/voiceStore';
|
import { useVoiceStore } from '../stores/voiceStore';
|
||||||
/**
|
/**
|
||||||
* OPENCORD NATIVE OVERDRIVE PIPELINE v18 (Golden Lock)
|
* OPENCORD NATIVE OVERDRIVE PIPELINE v22
|
||||||
* Forces strict 3.5Mbps - 5Mbps window to prevent Chrome bandwidth panic.
|
* "Soft-Launch Protocol": Always starts low to clear handshake, then upgrades to target.
|
||||||
*/
|
*/
|
||||||
const QUALITY_MAP = {
|
const QUALITY_MAP = {
|
||||||
'1080p60': new VideoPreset(1920, 1080, 8_000_000, 60),
|
'1080p60': new VideoPreset(1920, 1080, 12_000_000, 60),
|
||||||
'1080p': new VideoPreset(1920, 1080, 5_000_000, 30),
|
'1080p': new VideoPreset(1920, 1080, 8_000_000, 30),
|
||||||
'720p60': new VideoPreset(1280, 720, 5_000_000, 60), // Golden Value
|
'720p60': new VideoPreset(1280, 720, 8_000_000, 60),
|
||||||
'720p': new VideoPreset(1280, 720, 3_000_000, 30),
|
'720p': new VideoPreset(1280, 720, 4_000_000, 30),
|
||||||
'540p': new VideoPreset(960, 540, 1_500_000, 30),
|
'540p': new VideoPreset(960, 540, 2_000_000, 30),
|
||||||
'360p': new VideoPreset(640, 360, 800_000, 30),
|
'360p': new VideoPreset(640, 360, 1_000_000, 30),
|
||||||
};
|
};
|
||||||
const AUTO_PRESET = QUALITY_MAP['720p60'];
|
const AUTO_PRESET = QUALITY_MAP['720p60'];
|
||||||
let _activeRoom = null;
|
let _activeRoom = null;
|
||||||
@@ -37,10 +37,10 @@ async function applyOverdriveHammer(room, source, preset) {
|
|||||||
if (sender) {
|
if (sender) {
|
||||||
const params = sender.getParameters();
|
const params = sender.getParameters();
|
||||||
if (params.encodings && params.encodings[0]) {
|
if (params.encodings && params.encodings[0]) {
|
||||||
console.log(`[Overdrive] Locking ${source} to 3.5M - ${preset.encoding.maxBitrate}bps`);
|
console.log(`[Overdrive] Upgrading ${source} to ${preset.encoding.maxBitrate}bps`);
|
||||||
params.encodings[0].maxBitrate = preset.encoding.maxBitrate;
|
params.encodings[0].maxBitrate = preset.encoding.maxBitrate;
|
||||||
// STRICT FLOOR: 3.5 Mbps. Prevents the 0.2 Mbps drop.
|
// Gentle floor to keep stable
|
||||||
params.encodings[0].minBitrate = 3_500_000;
|
params.encodings[0].minBitrate = 2_000_000;
|
||||||
params.encodings[0].maxFramerate = preset.encoding.maxFramerate;
|
params.encodings[0].maxFramerate = preset.encoding.maxFramerate;
|
||||||
params.encodings[0].networkPriority = 'high';
|
params.encodings[0].networkPriority = 'high';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@@ -106,12 +106,12 @@ export function useLiveKit() {
|
|||||||
roomRef.current = null;
|
roomRef.current = null;
|
||||||
}
|
}
|
||||||
setIsConnecting(true);
|
setIsConnecting(true);
|
||||||
useVoiceStore.getState().setConnectionError(null);
|
|
||||||
useVoiceStore.getState().setIsLiveKitConnected(false);
|
useVoiceStore.getState().setIsLiveKitConnected(false);
|
||||||
try {
|
try {
|
||||||
const { token, url } = await api.livekit.token(channelId);
|
const { token, url } = await api.livekit.token(channelId);
|
||||||
if (gen !== _connectGeneration)
|
if (gen !== _connectGeneration)
|
||||||
return;
|
return;
|
||||||
|
// Disable simulcast for better 60fps stability on local networks
|
||||||
const newRoom = new Room({ adaptiveStream: false, dynacast: false, publishDefaults: { videoCodec: 'h264', simulcast: false } });
|
const newRoom = new Room({ adaptiveStream: false, dynacast: false, publishDefaults: { videoCodec: 'h264', simulcast: false } });
|
||||||
roomRef.current = newRoom;
|
roomRef.current = newRoom;
|
||||||
const guardedUpdate = () => { if (roomRef.current === newRoom)
|
const guardedUpdate = () => { if (roomRef.current === newRoom)
|
||||||
@@ -157,10 +157,8 @@ export function useLiveKit() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
if (gen === _connectGeneration) {
|
if (gen === _connectGeneration)
|
||||||
setConnectionError('Failed to connect');
|
setConnectionError('Failed to connect');
|
||||||
useVoiceStore.getState().setConnectionError('Failed to connect');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
if (gen === _connectGeneration)
|
if (gen === _connectGeneration)
|
||||||
@@ -241,8 +239,9 @@ export function useLiveKit() {
|
|||||||
if (!isCameraOn) {
|
if (!isCameraOn) {
|
||||||
const preset = QUALITY_MAP[videoQuality] || VideoPresets.h720;
|
const preset = QUALITY_MAP[videoQuality] || VideoPresets.h720;
|
||||||
await roomRef.current.localParticipant.setCameraEnabled(true, { resolution: preset.resolution, frameRate: preset.encoding.maxFramerate }, { videoCodec: 'h264', videoEncoding: preset.encoding, simulcast: false });
|
await roomRef.current.localParticipant.setCameraEnabled(true, { resolution: preset.resolution, frameRate: preset.encoding.maxFramerate }, { videoCodec: 'h264', videoEncoding: preset.encoding, simulcast: false });
|
||||||
|
// Soft Start Camera
|
||||||
setTimeout(() => { if (roomRef.current)
|
setTimeout(() => { if (roomRef.current)
|
||||||
applyOverdriveHammer(roomRef.current, Track.Source.Camera, preset); }, 1000);
|
applyOverdriveHammer(roomRef.current, Track.Source.Camera, preset); }, 2000);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
await roomRef.current.localParticipant.setCameraEnabled(false);
|
await roomRef.current.localParticipant.setCameraEnabled(false);
|
||||||
@@ -254,27 +253,33 @@ export function useLiveKit() {
|
|||||||
if (roomRef.current) {
|
if (roomRef.current) {
|
||||||
if (!isScreenSharing) {
|
if (!isScreenSharing) {
|
||||||
const preset = QUALITY_MAP[videoQuality] || AUTO_PRESET;
|
const preset = QUALITY_MAP[videoQuality] || AUTO_PRESET;
|
||||||
console.log('[LiveKit] Starting screen share (Golden Lock)...');
|
console.log('[LiveKit] Soft-Launching Screen Share (360p start)...');
|
||||||
|
// SOFT LAUNCH: Start at 360p 30fps to clear handshake
|
||||||
const track = await roomRef.current.localParticipant.setScreenShareEnabled(true, {
|
const track = await roomRef.current.localParticipant.setScreenShareEnabled(true, {
|
||||||
resolution: preset.resolution,
|
resolution: VideoPresets.h360.resolution,
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
frameRate: 60,
|
frameRate: 30,
|
||||||
}, {
|
}, {
|
||||||
videoCodec: 'h264', videoEncoding: preset.encoding, simulcast: false, priority: 'very-high'
|
videoCodec: 'h264', videoEncoding: VideoPresets.h360.encoding, simulcast: false, priority: 'very-high'
|
||||||
});
|
});
|
||||||
if (track) {
|
if (track) {
|
||||||
// Retry hammer to ensure parameters stick
|
// UPGRADE: After 2 seconds, switch to full 60fps quality
|
||||||
let hits = 0;
|
setTimeout(async () => {
|
||||||
const interval = setInterval(async () => {
|
if (roomRef.current && isScreenSharing) {
|
||||||
if (roomRef.current) {
|
console.log('[LiveKit] Upgrading to Target Quality...');
|
||||||
await applyOverdriveHammer(roomRef.current, Track.Source.ScreenShare, preset);
|
const screenPub = roomRef.current.localParticipant.getTrackPublications().find(p => p.source === Track.Source.ScreenShare);
|
||||||
hits++;
|
if (screenPub?.track?.mediaStreamTrack) {
|
||||||
if (hits > 10 || !isScreenSharing)
|
await screenPub.track.mediaStreamTrack.applyConstraints({
|
||||||
clearInterval(interval);
|
width: { ideal: preset.resolution.width },
|
||||||
|
height: { ideal: preset.resolution.height },
|
||||||
|
frameRate: { ideal: preset.encoding.maxFramerate, min: 30 }
|
||||||
|
});
|
||||||
|
await applyOverdriveHammer(roomRef.current, Track.Source.ScreenShare, preset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
}, 2000);
|
||||||
clearInterval(interval);
|
// Re-apply hammer
|
||||||
}, 500);
|
setTimeout(() => applyOverdriveHammer(roomRef.current, Track.Source.ScreenShare, preset), 5000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -294,7 +299,7 @@ export function useLiveKit() {
|
|||||||
if (screenPub?.videoTrack) {
|
if (screenPub?.videoTrack) {
|
||||||
const mediaTrack = screenPub.videoTrack.mediaStreamTrack;
|
const mediaTrack = screenPub.videoTrack.mediaStreamTrack;
|
||||||
if (mediaTrack) {
|
if (mediaTrack) {
|
||||||
await mediaTrack.applyConstraints({ width: { ideal: preset.resolution.width }, height: { ideal: preset.resolution.height }, frameRate: { ideal: preset.encoding.maxFramerate, min: 30 } });
|
await mediaTrack.applyConstraints({ width: { ideal: preset.resolution.width }, height: { ideal: preset.resolution.height }, frameRate: { ideal: preset.encoding.maxFramerate } });
|
||||||
}
|
}
|
||||||
await applyOverdriveHammer(room, Track.Source.ScreenShare, preset);
|
await applyOverdriveHammer(room, Track.Source.ScreenShare, preset);
|
||||||
}
|
}
|
||||||
@@ -322,7 +327,7 @@ export function useLiveKit() {
|
|||||||
const lastBytes = window[key] || report.bytesSent;
|
const lastBytes = window[key] || report.bytesSent;
|
||||||
const bitrate = (((report.bytesSent - lastBytes) * 8) / 5000 / 1000).toFixed(2);
|
const bitrate = (((report.bytesSent - lastBytes) * 8) / 5000 / 1000).toFixed(2);
|
||||||
window[key] = report.bytesSent;
|
window[key] = report.bytesSent;
|
||||||
console.log(`[Overdrive Diagnostic] ${report.frameWidth}x${report.frameHeight} @ ${fps} FPS (~${bitrate} Mbps) | ${report.qualityLimitationReason}`);
|
console.log(`[Soft-Launch Diagnostic] ${report.frameWidth}x${report.frameHeight} @ ${fps} FPS (~${bitrate} Mbps) | ${report.qualityLimitationReason}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,17 +17,17 @@ import { api } from '../api/client';
|
|||||||
import { useVoiceStore } from '../stores/voiceStore';
|
import { useVoiceStore } from '../stores/voiceStore';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OPENCORD NATIVE OVERDRIVE PIPELINE v18 (Golden Lock)
|
* OPENCORD NATIVE OVERDRIVE PIPELINE v22
|
||||||
* Forces strict 3.5Mbps - 5Mbps window to prevent Chrome bandwidth panic.
|
* "Soft-Launch Protocol": Always starts low to clear handshake, then upgrades to target.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const QUALITY_MAP: Record<string, VideoPreset> = {
|
const QUALITY_MAP: Record<string, VideoPreset> = {
|
||||||
'1080p60': new VideoPreset(1920, 1080, 8_000_000, 60),
|
'1080p60': new VideoPreset(1920, 1080, 12_000_000, 60),
|
||||||
'1080p': new VideoPreset(1920, 1080, 5_000_000, 30),
|
'1080p': new VideoPreset(1920, 1080, 8_000_000, 30),
|
||||||
'720p60': new VideoPreset(1280, 720, 5_000_000, 60), // Golden Value
|
'720p60': new VideoPreset(1280, 720, 8_000_000, 60),
|
||||||
'720p': new VideoPreset(1280, 720, 3_000_000, 30),
|
'720p': new VideoPreset(1280, 720, 4_000_000, 30),
|
||||||
'540p': new VideoPreset(960, 540, 1_500_000, 30),
|
'540p': new VideoPreset(960, 540, 2_000_000, 30),
|
||||||
'360p': new VideoPreset(640, 360, 800_000, 30),
|
'360p': new VideoPreset(640, 360, 1_000_000, 30),
|
||||||
};
|
};
|
||||||
|
|
||||||
const AUTO_PRESET = QUALITY_MAP['720p60']!;
|
const AUTO_PRESET = QUALITY_MAP['720p60']!;
|
||||||
@@ -72,18 +72,14 @@ async function applyOverdriveHammer(room: Room, source: Track.Source, preset: Vi
|
|||||||
if (sender) {
|
if (sender) {
|
||||||
const params = sender.getParameters();
|
const params = sender.getParameters();
|
||||||
if (params.encodings && params.encodings[0]) {
|
if (params.encodings && params.encodings[0]) {
|
||||||
console.log(`[Overdrive] Locking ${source} to 3.5M - ${preset.encoding.maxBitrate}bps`);
|
console.log(`[Overdrive] Upgrading ${source} to ${preset.encoding.maxBitrate}bps`);
|
||||||
|
|
||||||
params.encodings[0].maxBitrate = preset.encoding.maxBitrate;
|
params.encodings[0].maxBitrate = preset.encoding.maxBitrate;
|
||||||
// STRICT FLOOR: 3.5 Mbps. Prevents the 0.2 Mbps drop.
|
// Gentle floor to keep stable
|
||||||
(params.encodings[0] as any).minBitrate = 3_500_000;
|
(params.encodings[0] as any).minBitrate = 2_000_000;
|
||||||
|
|
||||||
params.encodings[0].maxFramerate = preset.encoding.maxFramerate;
|
params.encodings[0].maxFramerate = preset.encoding.maxFramerate;
|
||||||
params.encodings[0].networkPriority = 'high';
|
params.encodings[0].networkPriority = 'high';
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
params.degradationPreference = 'maintain-framerate';
|
params.degradationPreference = 'maintain-framerate';
|
||||||
|
|
||||||
await sender.setParameters(params);
|
await sender.setParameters(params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -134,18 +130,14 @@ export function useLiveKit() {
|
|||||||
if (connectedChannelRef.current === channelId && roomRef.current) return;
|
if (connectedChannelRef.current === channelId && roomRef.current) return;
|
||||||
const gen = ++_connectGeneration;
|
const gen = ++_connectGeneration;
|
||||||
if (roomRef.current) { try { roomRef.current.disconnect(); } catch {} roomRef.current = null; }
|
if (roomRef.current) { try { roomRef.current.disconnect(); } catch {} roomRef.current = null; }
|
||||||
|
|
||||||
setIsConnecting(true);
|
setIsConnecting(true);
|
||||||
useVoiceStore.getState().setConnectionError(null);
|
|
||||||
useVoiceStore.getState().setIsLiveKitConnected(false);
|
useVoiceStore.getState().setIsLiveKitConnected(false);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { token, url } = await api.livekit.token(channelId);
|
const { token, url } = await api.livekit.token(channelId);
|
||||||
if (gen !== _connectGeneration) return;
|
if (gen !== _connectGeneration) return;
|
||||||
|
// Disable simulcast for better 60fps stability on local networks
|
||||||
const newRoom = new Room({ adaptiveStream: false, dynacast: false, publishDefaults: { videoCodec: 'h264', simulcast: false } });
|
const newRoom = new Room({ adaptiveStream: false, dynacast: false, publishDefaults: { videoCodec: 'h264', simulcast: false } });
|
||||||
roomRef.current = newRoom;
|
roomRef.current = newRoom;
|
||||||
|
|
||||||
const guardedUpdate = () => { if (roomRef.current === newRoom) updateParticipants(); };
|
const guardedUpdate = () => { if (roomRef.current === newRoom) updateParticipants(); };
|
||||||
newRoom.on(RoomEvent.ParticipantConnected, guardedUpdate);
|
newRoom.on(RoomEvent.ParticipantConnected, guardedUpdate);
|
||||||
newRoom.on(RoomEvent.ParticipantDisconnected, guardedUpdate);
|
newRoom.on(RoomEvent.ParticipantDisconnected, guardedUpdate);
|
||||||
@@ -162,20 +154,15 @@ export function useLiveKit() {
|
|||||||
roomRef.current = null; _activeRoom = null; setIsConnected(false); setRoom(null); setParticipants([]);
|
roomRef.current = null; _activeRoom = null; setIsConnected(false); setRoom(null); setParticipants([]);
|
||||||
useVoiceStore.getState().setIsLiveKitConnected(false);
|
useVoiceStore.getState().setIsLiveKitConnected(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
await newRoom.connect(url, token);
|
await newRoom.connect(url, token);
|
||||||
if (gen !== _connectGeneration) { newRoom.disconnect(); return; }
|
if (gen !== _connectGeneration) { newRoom.disconnect(); return; }
|
||||||
|
_activeRoom = newRoom; connectedChannelRef.current = channelId; setRoom(newRoom); setIsConnected(true);
|
||||||
_activeRoom = newRoom; connectedChannelRef.current = channelId;
|
|
||||||
setRoom(newRoom); setIsConnected(true);
|
|
||||||
useVoiceStore.getState().setIsLiveKitConnected(true);
|
useVoiceStore.getState().setIsLiveKitConnected(true);
|
||||||
updateParticipants();
|
updateParticipants();
|
||||||
|
|
||||||
useVoiceStore.setState({ isMuted: false, isCameraOn: false, isScreenSharing: false });
|
useVoiceStore.setState({ isMuted: false, isCameraOn: false, isScreenSharing: false });
|
||||||
try { await newRoom.localParticipant.setMicrophoneEnabled(true); updateParticipants(); } catch { useVoiceStore.setState({ isMuted: true }); }
|
try { await newRoom.localParticipant.setMicrophoneEnabled(true); updateParticipants(); } catch { useVoiceStore.setState({ isMuted: true }); }
|
||||||
} catch (err) {
|
} catch (err) { if (gen === _connectGeneration) setConnectionError('Failed to connect'); }
|
||||||
if (gen === _connectGeneration) { setConnectionError('Failed to connect'); useVoiceStore.getState().setConnectionError('Failed to connect'); }
|
finally { if (gen === _connectGeneration) setIsConnecting(false); }
|
||||||
} finally { if (gen === _connectGeneration) setIsConnecting(false); }
|
|
||||||
}, [updateParticipants]);
|
}, [updateParticipants]);
|
||||||
|
|
||||||
const connectDm = useCallback(async (dmChannelId: string) => {
|
const connectDm = useCallback(async (dmChannelId: string) => {
|
||||||
@@ -217,7 +204,8 @@ export function useLiveKit() {
|
|||||||
if (!isCameraOn) {
|
if (!isCameraOn) {
|
||||||
const preset = QUALITY_MAP[videoQuality] || VideoPresets.h720;
|
const preset = QUALITY_MAP[videoQuality] || VideoPresets.h720;
|
||||||
await roomRef.current.localParticipant.setCameraEnabled(true, { resolution: preset.resolution, frameRate: preset.encoding.maxFramerate }, { videoCodec: 'h264', videoEncoding: preset.encoding, simulcast: false });
|
await roomRef.current.localParticipant.setCameraEnabled(true, { resolution: preset.resolution, frameRate: preset.encoding.maxFramerate }, { videoCodec: 'h264', videoEncoding: preset.encoding, simulcast: false });
|
||||||
setTimeout(() => { if (roomRef.current) applyOverdriveHammer(roomRef.current, Track.Source.Camera, preset); }, 1000);
|
// Soft Start Camera
|
||||||
|
setTimeout(() => { if (roomRef.current) applyOverdriveHammer(roomRef.current, Track.Source.Camera, preset); }, 2000);
|
||||||
} else { await roomRef.current.localParticipant.setCameraEnabled(false); }
|
} else { await roomRef.current.localParticipant.setCameraEnabled(false); }
|
||||||
updateParticipants();
|
updateParticipants();
|
||||||
}
|
}
|
||||||
@@ -227,25 +215,36 @@ export function useLiveKit() {
|
|||||||
if (roomRef.current) {
|
if (roomRef.current) {
|
||||||
if (!isScreenSharing) {
|
if (!isScreenSharing) {
|
||||||
const preset = QUALITY_MAP[videoQuality] || AUTO_PRESET;
|
const preset = QUALITY_MAP[videoQuality] || AUTO_PRESET;
|
||||||
console.log('[LiveKit] Starting screen share (Golden Lock)...');
|
console.log('[LiveKit] Soft-Launching Screen Share (360p start)...');
|
||||||
const track = await roomRef.current.localParticipant.setScreenShareEnabled(true, {
|
|
||||||
resolution: preset.resolution,
|
// SOFT LAUNCH: Start at 360p 30fps to clear handshake
|
||||||
|
const track = await roomRef.current.localParticipant.setScreenShareEnabled(true, {
|
||||||
|
resolution: VideoPresets.h360.resolution,
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
frameRate: 60,
|
frameRate: 30,
|
||||||
}, {
|
}, {
|
||||||
videoCodec: 'h264', videoEncoding: preset.encoding, simulcast: false, priority: 'very-high'
|
videoCodec: 'h264', videoEncoding: VideoPresets.h360.encoding, simulcast: false, priority: 'very-high'
|
||||||
} as any);
|
} as any);
|
||||||
|
|
||||||
if (track) {
|
if (track) {
|
||||||
// Retry hammer to ensure parameters stick
|
// UPGRADE: After 2 seconds, switch to full 60fps quality
|
||||||
let hits = 0;
|
setTimeout(async () => {
|
||||||
const interval = setInterval(async () => {
|
if (roomRef.current && isScreenSharing) {
|
||||||
if (roomRef.current) {
|
console.log('[LiveKit] Upgrading to Target Quality...');
|
||||||
await applyOverdriveHammer(roomRef.current, Track.Source.ScreenShare, preset);
|
const screenPub = roomRef.current.localParticipant.getTrackPublications().find(p => p.source === Track.Source.ScreenShare);
|
||||||
hits++;
|
if (screenPub?.track?.mediaStreamTrack) {
|
||||||
if (hits > 10 || !isScreenSharing) clearInterval(interval);
|
await screenPub.track.mediaStreamTrack.applyConstraints({
|
||||||
} else clearInterval(interval);
|
width: { ideal: preset.resolution.width },
|
||||||
}, 500);
|
height: { ideal: preset.resolution.height },
|
||||||
|
frameRate: { ideal: preset.encoding.maxFramerate, min: 30 }
|
||||||
|
});
|
||||||
|
await applyOverdriveHammer(roomRef.current, Track.Source.ScreenShare, preset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 2000);
|
||||||
|
|
||||||
|
// Re-apply hammer
|
||||||
|
setTimeout(() => applyOverdriveHammer(roomRef.current!, Track.Source.ScreenShare, preset), 5000);
|
||||||
}
|
}
|
||||||
} else { await roomRef.current.localParticipant.setScreenShareEnabled(false); }
|
} else { await roomRef.current.localParticipant.setScreenShareEnabled(false); }
|
||||||
updateParticipants();
|
updateParticipants();
|
||||||
@@ -262,7 +261,7 @@ export function useLiveKit() {
|
|||||||
if (screenPub?.videoTrack) {
|
if (screenPub?.videoTrack) {
|
||||||
const mediaTrack = (screenPub.videoTrack as any).mediaStreamTrack as MediaStreamTrack;
|
const mediaTrack = (screenPub.videoTrack as any).mediaStreamTrack as MediaStreamTrack;
|
||||||
if (mediaTrack) {
|
if (mediaTrack) {
|
||||||
await mediaTrack.applyConstraints({ width: { ideal: preset.resolution.width }, height: { ideal: preset.resolution.height }, frameRate: { ideal: preset.encoding.maxFramerate, min: 30 } });
|
await mediaTrack.applyConstraints({ width: { ideal: preset.resolution.width }, height: { ideal: preset.resolution.height }, frameRate: { ideal: preset.encoding.maxFramerate } });
|
||||||
}
|
}
|
||||||
await applyOverdriveHammer(room, Track.Source.ScreenShare, preset);
|
await applyOverdriveHammer(room, Track.Source.ScreenShare, preset);
|
||||||
}
|
}
|
||||||
@@ -287,7 +286,7 @@ export function useLiveKit() {
|
|||||||
const lastBytes = (window as any)[key] || report.bytesSent;
|
const lastBytes = (window as any)[key] || report.bytesSent;
|
||||||
const bitrate = (((report.bytesSent - lastBytes) * 8) / 5000 / 1000).toFixed(2);
|
const bitrate = (((report.bytesSent - lastBytes) * 8) / 5000 / 1000).toFixed(2);
|
||||||
(window as any)[key] = report.bytesSent;
|
(window as any)[key] = report.bytesSent;
|
||||||
console.log(`[Overdrive Diagnostic] ${report.frameWidth}x${report.frameHeight} @ ${fps} FPS (~${bitrate} Mbps) | ${report.qualityLimitationReason}`);
|
console.log(`[Soft-Launch Diagnostic] ${report.frameWidth}x${report.frameHeight} @ ${fps} FPS (~${bitrate} Mbps) | ${report.qualityLimitationReason}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
|
|||||||
Reference in New Issue
Block a user