I am using and learning Svelte. So I am creating a video player with help of hls.js library (because I did not found any readymade video players which worked properly and had the functionality I wanted). When I try to change the volume of the video, frame drop occurs.
function handleVolume(event) {
volume = event.target.value;
if (volume === 0) { isMuted = true; }
else { isMuted = false; }
}
function debounce(func, delay) {
let timeoutId;
return function (...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
function updateVideoVolume() {
video.volume = volume / maxVolume;
}
const updateVideoVolumeDebounced = debounce(updateVideoVolume, 200);
onMount(() => {
if (Hls.isSupported()) {
hls = new Hls();
let src = 'http://localhost:3000/videos/video3';
hls.loadSource(src);
hls.attachMedia(video);
hls.enableWorker = true;
duration = video.duration;
hls.on(Hls.Events.MEDIA_ATTACHED, function () {});
hls.on(Hls.Events.MANIFEST_PARSED, function (event, data) {
console.log(data.levels);
for (let i = 0; i < data.levels.length; i++) {
resolutions = [...resolutions, [data.levels[i].height, data.levels[i].bitrate]];
}
console.log(resolutions);
});
}
});
</script>
<input
type="range"
on:input={handleVolume}
on:change={updateVideoVolumeDebounced}
id="volume"
name="volume"
min="0"
max={maxVolume}
/>
It happens with both on:change and on:input when using the range input element. I also tried to debounce the handleVolume but then the frame drop occurs after the delay. I have also tested it on different browsers. In Firefox, the frame drop is less. Meanwhile in Brave, it is similar. I guess this is because of Chromium.
The code in the question is mostly irrelevant.
You have a binding on
videothat gets and setscurrentTime, the bound variable (playbackTime) is reactive with a dependency onvideo.The volume change has an assignment to a property of
video, thereby invalidatingvideo. This in turn will updateplaybackTimewhich sets the video'scurrentTime, causing a jitter.Would recommend limiting the use of reactive statement, don't see much point in
playbackTimebeing one either, just initialize to0and maybe update once inonMountor on some other events.