Open vodlogic opened 6 months ago
Should the expression be
return cue.startTime <= currentTime && cue.endTime >= currentTime
to determine if cue is active?
I think the idea is not to discard future cues that are likely to be needed soon.
@vodlogic Can you share a stream to reproduce this? Typically, deleteAllTextTracks
is called once a new source is attached. I checked in v5.0.0, and I don't see the number of cues increasing when calling attachSource
multiple times with https://dash.akamaized.net/akamai/test/caption_test/ElephantsDream/elephants_dream_480p_heaac5_1_https.mpd
isCueActive
also seems to wrong to me. Instead, it should be like this:
function _isCueActive(cue) {
const currentTime = videoModel.getTime();
return currentTime >= cue.startTime && currentTime <= cue.endTime
}
@dsilhavy issue is visible also with https://dash.akamaized.net/akamai/test/caption_test/ElephantsDream/elephants_dream_480p_heaac5_1_https.mpd Prerequisites:
attachSource()
againSo for this stream you need to wait 30s (subtitles are from around 20s after start).
I tested also the development
branch and it looks the same so v5.0.0 is also affected.
There is a minimal test scenario where heap is slowly growing:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="http://cdn.dashjs.org/v4.7.4/dash.all.min.js"></script>
</head>
<body>
<div>
<video id="videoPlayer" controls></video>
<div id='sub'/>
</div>
<script>
const sleep = s => new Promise(r => setTimeout(r, s * 1000));
const videoElement = document.getElementById('videoPlayer');
const subElement = document.getElementById("sub");
// Initialize the Dash.js player
const player = dashjs.MediaPlayer().create();
// Setup the player
player.initialize(videoElement);
player.attachTTMLRenderingDiv(subElement);
// Set defaultEnabled: true to enable subtitles
player.updateSettings({streaming: {text: {defaultEnabled: true}}});
player.setInitialMediaSettingsFor('text', {
lang: 'eng',
});
async function test() {
while (true) {
player.attachSource('https://dash.akamaized.net/akamai/test/caption_test/ElephantsDream/elephants_dream_480p_heaac5_1_https.mpd');
await sleep(30);
}
}
test();
</script>
</body>
</html>
@nielar0 @vodlogic Thanks for providing this example. Which platform/browser combination are you using in your tests? I checked with dash.js v5.0.0 Google Chrome 124 on MacOSX Sonoma 14.2.1 running the example around 20 minutes.
performance.memory.usedJSHeapSize
slightly decreased, comparing the values in the beginning to the ones in the endvideoelement.textTracks[0]
it is not increasing over time. Which means the cues are removed after calling attachSource
@dsilhavy I tested with Google Chrome 113 on Ubuntu an Vewd on embedded OS. For both environment result is the same. Three weeks ago I also checked with dash.js v5.0.0 (from development branch) and heap also was growing.
Using Chrome developer tools and the memory tab, taking heap snapshots showed a slight increase of around 1MB in 20 minutes.
And every 20 minutes this will increase of additional 1MB. I tested with https://rdmedia.bbc.co.uk/testcard/simulcast/manifests/avc-full.mpd (with sleep was set to 5s) and heap was growing much faster.
Checking the number of cues in videoelement.textTracks[0] it is not increasing over time. Which means the cues are removed after calling attachSource
Probably because videoelement
is changed after call attachSource
.
When collected snapshot during test I see a lot of Detached HTMLVideoElement
. This problem isn't visible when subtitles are disabled or body of addTextTrack()
from TextTracks.js
is commented out.
We see this issue on dash.js 4.7.4 in chrome 113 and hisense with chrome 111
We have observed JS Heap increasing at a rate of approximately 1MB every 3 minutes when a new manifest is loaded when
player.attachSource(<new manifest URL>)
is called every 15 seconds when subtitles are enabled. We observe this in dash.js 4.7.4 and are yet to try earlier versions of dash.jsWhen subtitles are disabled, JS heap increases only a couple of MB per hour when
attachSource()
is called every 15 seconds.This leads us to hypothesise that cues are not being properly cleaned up when a new manifest is loaded by the player.
We can see that the number of cues continues to grow across calls to
attachSource()
The fix merged in #4305 resolved a memory leak when soak testing a stream for 24 hours without calling
attachSource()
Not sure if this is related, but we also wanted to check the logic that has been implemented for the previous PR to discard outdated cues.
https://github.com/Dash-Industry-Forum/dash.js/pull/4305/files#diff-033321ac6c729cfa349f6ca06067679dc6919fe8fe1023ec6fd990c83e98ac9aR829
Should the expression be
return cue.startTime <= currentTime && cue.endTime >= currentTime
to determine if cue is active?