Issue with video.js text track memory leakage (WebVTT/VTT)

I am utilizing Video Text Tracks to showcase advanced live information on top of the video.
A new video is loaded every few minutes, each with its own .webvtt file (consisting of 2-3k lines).

Although everything is functioning properly, there is a persistent issue with memory usage increasing continuously.

This problem stems from a memory leak where additional VTTCue and TextTrack records are added for each new video, leading to an accumulation of unnecessary data. https://i.stack.imgur.com/HN3Ln.png

After trying several approaches without success, I find myself stuck with the current method:

The text tracks are implemented according to the guidelines in the Video.js documentation (remote text tracks):

player.ready(() => {
  if (videoOptions.subtitles) {
    player.addRemoteTextTrack(
      {
        src: videoOptions.subtitles,
        kind: 'subtitles',
      },
      false,
    );
  }
});

And they are removed before disposing of the player:

const remoteTextTracks = this.player.remoteTextTracks();
for (let i = remoteTextTracks.length - 1; i >= 0; i -= 1) {
  this.player.removeRemoteTextTrack(remoteTextTracks[i]);
}

Even though they are successfully removed from the player, they linger in memory. Is there a way to prompt/urge/force the GC to completely eliminate old text tracks?

Answer №1

To prevent Video.js' memory leak when working with text tracks, consider implementing the following steps:

if (player && player.remoteTextTracks().length) {
  while (player.remoteTextTracks().length > 0) {
    player.removeRemoteTextTrack(player.remoteTextTracks()[0]);
  }
  player.remoteTextTracks().forEach(function(track) {
    track.src = '';
    player.removeRemoteTextTrack(track);
  });
}

Answer №2

If someone is facing a similar problem and needs a solution, here's what worked for me:

const remoteTextTracks = this.player.remoteTextTracks();
for (let i = remoteTextTracks.length - 1; i >= 0; i -= 1) {
    
    remoteTextTracks[i].activeCues_.forEach((val, key) => {
        delete remoteTextTracks[i].activeCues_[key];
    });

    remoteTextTracks[i].cues_.forEach((val, key) => {
        delete remoteTextTracks[i].cues_[key];
    });

    if (!isNil(remoteTextTracks[i].lastCue)) {
        delete remoteTextTracks[i].lastCue;
    }

    this.player.removeRemoteTextTrack(remoteTextTracks[i]);
}

To free up memory, all items had to be deleted individually — other solutions didn't cut it.

After digging deeper due to additional memory leaks, I found out this was the culprit - the issue stemmed from Vue Dev Tools, but disabling it resolved everything.

The memory leak was actually present in production, and though I fixed it using the mentioned method, Vue Dev Tools masked my realization of the fix. :|

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Dealing with checked input type='checkbox' in React - A guide

Having a set of checkboxes, some already checked and some to be updated by the user. The issue here is that while the checkboxes render correctly initially, they do not change upon clicking. The 'checked' value does get updated when onChange is t ...

Simple way to retrieve the first and last date of the current month using Node.js

I need help with retrieving the first and last date of the current month using the code below:- let currentDate = new Date(); let month = currentDate.getMonth() + 1; console.log(month); let firstDate = new Date(currentDate.getFullYear(), currentDate.getMon ...

Issue with datepicker initialization causing format not to work in Bootstrap

I am currently incorporating the angular-bootstrap datepicker module into my app and have run into a minor issue. I am using an input text field and a button to display the date in the following manner: <div class="row" id="datePicker"> <p cl ...

Tips for modifying CSS when a user scrolls beyond a specific div

Currently, I am working on implementing a scroll function that dynamically moves elements based on the user's scrolling behavior. The code I have written works to some extent and successfully moves the elements. However, my goal is to create a list o ...

The error encountered is due to an invalid assignment on the left-hand side

I'm encountering the error below: Uncaught ReferenceError: Invalid left-hand side in assignment This is the problematic code: if (!oPrismaticMaterial = "") { for (var i = 0; i < oPrismaticMaterial.length; i++) { if (oPrismaticMater ...

Fixing Memory Leaks from Objects Created with NEW Keyword

Is there a method to monitor memory blocks allocated using the new statement that have not been released? This information should be displayed upon application exit, including the filename and fileline where the memory was allocated. This would allow for e ...

Implementing long-lasting login functionality in React using JSON Web Tokens

Currently, I have developed an application using React client/Express API with functioning Authentication. Users are able to register and login successfully. My next step is to implement persistent login using JWT tokens so that when a user accesses the U ...

Tips for concealing labels until the submit button is activated

I am currently handling a project involving a Spring Controller and JSP. Within a JSP page, I have included a button labeled Process. Upon clicking this button, two radio buttons are displayed below it along with a Submit button. After tapping the Submit ...

With a tree arrangement flanking the Transfer module on either side

I have successfully implemented the antd's Transfer component using the examples provided in the documentation. I was able to create a tree transfer box that looks like this: However, I am wondering if there is a way to have a tree structure on both ...

Retrieve the selected value from a specific div element

Having some issues with retrieving the selected value from a Bootstrap chosen select field within a div. Any ideas on what might be causing this problem? $('#content_' + id).find('#GroupID > option:selected').text() // returns blank ...

Should I return X in async functions, or should I return "Promise.Resolve(X)"?

I've always found this to be a tricky concept to fully grasp. Let's delve into async functions in Typescript. Which implementation is accurate? async function asyncFunctionOne(string1: string, string2: string, string3: string) { var returnOb ...

Creating a custom homepage route in Nuxt and Netlify for a dynamic experience

I am working on a single page site with some content management featured on the homepage. The main file for the homepage content is located at /content/index.md This file references the template called home found in /pages/_home.vue During development, ...

How can a false validation be conducted on knockout js?

Using knockout js, I have an input type checkbox and I want to trigger the "not true" action when this checkbox is selected. Here's what I have attempted: <input type="checkbox" data-bind="checked: !IsVisible"/> Unfortunately, this code isn&ap ...

Generating various arrays of data

I am currently facing an issue with creating separate datasets based on the month value. Despite my efforts, all month values are being combined into a single dataset in my code. Any assistance in dynamically generating different datasets would be greatly ...

When running the PHP script, the output is shown in the console rather than in the

Here is a PHP script snippet that I am working with: <?php add_action('wp_ajax_nopriv_getuser', 'getuser'); add_action('wp_ajax_getuser', 'getuser'); function getuser($str) { global $wpdb; if(!wp_verif ...

Achieve a Smooth Transition: Utilizing Bootstrap 3 to Create an Alert Box that Fades In upon Click and Fades Out

Incorporating AngularJS and Bootstrap 3 into my web app, there is an "Update" button that saves user changes. Upon clicking the "Update" button, I aim to trigger and display bootstrap's alert box with the message "Information has been saved," followed ...

The frequency of database updates exceeds expectations - involving vue.js this.$router.push and express operations

Having some trouble updating a MongoDB with this code. It seems to be updating three times instead of just once due to having three dates in the posts.date field. Utilizing Vue, Mongo, and Express for this project, I have the following data structure: { ...

Update the div element without needing to reload the entire page

Is there a way to reload a div tag without refreshing the entire page? I understand this question has been asked before, but I want to make sure I have a clear understanding. <p>click HERE</p> <div class="sample"> <?php functi ...

Carrying over additions in arrays using only Javascript

I'd like to implement a basic array addition with carryover. Additionally, I need to display the carryover and result values. For instance: e.g var input = [[0,0,9],[0,9,9]]; var carryover = []; var result = []; Thank you! ...

The table is not visible when using Bootstrap Vue

Can anyone help me with displaying a table of flowers? I am having trouble making it show up on my page. Not quite sure how to use my data to get the flowers to display properly. Any guidance or advice would be greatly appreciated. <b-table> ...