0

I have developed 3 years ago an AngularJS/Node.js application that shows a loop of short videos. The screen output is used as input for other video software for displaying these videos on ledboarding. My app is in essence the manageùent tool for setting up playlists etc.

The AngularJS app has a videoOutput directive that is placed 5 times on the screen. Each instance gets a list of X videos as input. Each video is 15 seconds long.

Each 15 seconds an event is broadcasted on which each videoPlayer will start playing the next video. This is done by simply changing the source in the element. <video autoplay muted="muted" src="{{videoSource}}" type="video/mp4"></video>

The videos are hosted locally in a folder in the app and served via Node.js (everything runs on localhost). Below is the function that is used to stream the videos

Everything worked well, but recently at one customer the videos started to lag after 2 hours They still start playing at the correct moment (so no sync issues), but e.g. video A in player 1 and 2 would stop playong after 5 seconds, while that same video plays correctly in player 3... Bit by bit it's degrading to the moment where you need to refresh the browser after which it plays again correctly.

I ran some profiling in Chrome and don't see directly issues. There are also no console errors. It also doesn't seem to happen when the amount of videos in a playlist remain limited (e.g. 6 videos). The issue happens after a few hours of running. We have changed computer etc. I also experience the issue now on my own laptop.

When the issue occurs I stop the server and start it again, but the issue stays. It sometimes goes a bit better for a few minutes but than again it lags when it streams the videos. The lagging is again random.

Could this be an issue of too many open connections towards the server? Or is it something in Chrome? How can I better debug this?

app.route('/videos/:id')
    .get(function (req, res) {
        var path = '../videos/' + req.params.id;

        if (req.query.special) {
            path = '../videos/special/' + req.params.id;
        }

        const stat = fs.statSync(path);
        const fileSize = stat.size;
        const range = req.headers.range;
        if (range) {
            const parts = range.replace(/bytes=/, "").split("-");
            const start = parseInt(parts[0], 10);
            const end = parts[1] ? parseInt(parts[1], 10) : fileSize - 1;
            const chunksize = (end - start) + 1;
            const file = fs.createReadStream(path, { start, end });
            const head = {
                'Content-Range': `bytes ${start}-${end}/${fileSize}`,
                'Accept-Ranges': 'bytes',
                'Content-Length': chunksize,
                'Content-Type': 'video/mp4',
            }
            res.writeHead(206, head);
            file.pipe(res);
        } else {
            const head = {
                'Content-Length': fileSize,
                'Content-Type': 'video/mp4',
            }
            res.writeHead(200, head);
            fs.createReadStream(path).pipe(res);
        }
    })

0