Having trouble getting NextJS to work with jsmpeg/node-rtsp-stream for displaying an RTSP stream

Exploring: https://github.com/kyriesent/node-rtsp-stream and How to display IP camera feed from an RTSP url onto reactjs app page? I attempted to showcase the RTSP stream from a CCTV but encountered an error.

ReferenceError: document is not defined
at
scripts\jsmpeg.min.js (1:701) @ eval

I couldn't find any examples of this module in NextJS, so there might be a mistake on my end, but I can't pinpoint it. And I haven't come across a better solution for NextJS yet.

I didn't find any helpful information in: https://github.com/phoboslab/jsmpeg, maybe I'm using it incorrectly here.

This all started from: How can I display an RTSP video stream in a web page?, but everything seems outdated, irrelevant, or too complex for me to understand.

The main question:

How can I resolve the error I'm encountering? Is there an alternative approach in NextJS? All I need is to smoothly stream the RTSP feed from a CCTV.

Folder Structure:

components
   -layout
      -Stream.js
pages
   -api
   -stream
       -[streamId].js
       -app.js
   -index.js
scripts
    -jsmpeg.min.js

Stream.js is a component in stream/app.js, and stream/app.js is used in stream/[streamId].js

Client-side : Stream.js

import JSMpeg from "../../scripts/jsmpeg.min.js";

const Stream = (props) => {
  const player = new JSMpeg.Player("ws://localhost:9999", {
    canvas: document.getElementById("video-canvas"), // Canvas should be a canvas DOM element
  });

 return (
    <Fragment>
        <canvas
          id="video-canvas"
          className={classes.canvas}
          onMouseDown={onMouseDownHandler}
        ></canvas>
    </Fragment>
  );
};

Server-side : [streamId.js]

export async function getStaticProps(context) {
const StreamCCTV = require("node-rtsp-stream");
  const streamCCTV = new StreamCCTV({
    ffmpegPath: "C:\\Program Files\\ffmpeg\\bin\\ffmpeg.exe", //! remove on Ubuntu
    name: "name",
    streamUrl: "rtsp://someuser:<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7a0915171f0a1b09090d15081e3a4b544b544b544b">[email protected]</a>",
    wsPort: 9999,
    ffmpegOptions: {
      // options ffmpeg flags
      "-stats": "", // an option with no neccessary value uses a blank string
      "-r": 30, // options with required values specify the value after the key
    },
  });

Edit:

I also experimented with https://www.npmjs.com/package/jsmpeg. After altering Stream.js to:

import jsmpeg from 'jsmpeg';

const Stream = (props) => {
  const client = new WebSocket("ws://localhost:9999")
  const player = new jsmpeg(client, {
    canvas: document.getElementById("video-canvas"), // Canvas should be a canvas DOM element
  });

 return (
    <Fragment>
        <canvas
          id="video-canvas"
          className={classes.canvas}
          onMouseDown={onMouseDownHandler}
        ></canvas>
    </Fragment>
  );
};

Now I'm facing the error:

ReferenceError: window is not defined

Answer №1

I successfully got this to work using two different methods:

  1. First, download jsmpeg.min.js from this link and place it in the same directory as your component (or any other desired location).

  2. Edit the beginning of the file from var JSMpeg... to export const JSMpeg...

  3. Create a component with the following code:

import { useRef } from 'react'

const StreamPlayer = () => {
    
    const streamRef = useRef(null)

    useEffect(() => {
        const { JSMpeg } = require('./jsmpeg.min.js')
        const player = new JSMpeg.Player('ws://localhost:9999', {
            canvas: streamRef.current
        })
    }, [])

return <canvas ref={streamRef} id="stream-canvas"></canvas>
}

NOTE

I'm unsure about the use of require within useEffect, but since JSMpeg relies on the document and window objects, they need to be imported after being loaded.

The second approach
involves a less modular method that avoids potential issues:
  1. Start by downloading jsmpeg.min.js from here and adding it to the /public directory of your Next.js project.

  2. Create a component with the following code:

import Script from 'next/script'

const StreamPlayer = () => {

return (
    <>
        <canvas id="stream-canvas"></canvas>
        <Script src="jsmpeg.min.js" id="jsmpeg"></Script>
    </>
)}
  1. Finally, at the end of the jsmpeg.min.js file, I appended:
player = new JSMpeg.Player('ws://localhost:9999', {
    canvas: document.getElementById('stream-canvas')
})

Answer №2

If you're looking to play mpeg1 files with jsmpeg, keep in mind that it only supports that specific format. You may want to consider using ffmpeg with a mpegts format stream for other types of videos.

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

Leveraging a Mongoose Schema Method within a Exported Mongoose Model

Lately, I've been developing an authentication system that is designed to either create a new user if no user with a specific ID exists OR retrieve a user with an existing ID. Through my exploration, I discovered that it's possible to determine w ...

Generate a dynamic file import loop within a React application

Suppose I have a directory containing several .md files: /static/blog/ example_title.md another_example.md three_examples.md and an array that includes all the titles: const blogEntries = ["example_title", "another_example", "three_examples"] In ...

The Chrome extension I created using JQuery to trigger 'keyup' events is not updating the value of the 'input' field on a website that utilizes knockout JS

I am currently working on developing a Google Chrome extension for a website that appears to be utilizing 'knockout JS'. Let's take a look at the HTML element below: <input type="text" class="form-control text-right" id="amount" autoco ...

Guide on replacing buttons with <a> tags in express.js posts

I've incorporated handlebars as my chosen templating engine and I'm utilizing buttons to trigger app.post() in my JavaScript file. <form method="POST" action="/smo_assessment"> <div class="container" id="div1"> <h3 id="header" ...

Using AngularJS client and Flask server for a RESTful call, one can include the

I am currently facing an issue where I need to send a REST request from my AngularJs client to a Flask server. The problem arises when one of the ids (key) in the request contains a forward slash. Interestingly, if the key does not contain a slash, the re ...

Storing duplicate code in multiple cache files using ReactJS ServiceWorker

I am currently working on integrating a serviceworker into an existing React application that has the following filesystem layout: Filesystem The initialization code is stored in the public folder, while the main code resides in the src folder. In my serv ...

Guide to making a button in jQuery that triggers a function with arguments

I've been working on creating a button in jQuery with an onClick event that calls a function and passes some parameters. Here's what I have tried so far: let userArray = []; userArray['recipient_name'] = recipient_name.value; userArray[ ...

Difficulty in detecting state changes without refreshing the component when using Redux and React

I'm encountering difficulties detecting state changes from my Redux reducer in a React application. When I modify the state within one component, the other component in the app does not get the update unless the component is reloaded or refreshed. Let ...

What is the mechanism behind the operation of the inherits feature in Node.js?

The following code snippet illustrates how the inherits function works in node.js: exports.inherits = function(ctor, superCtor) { ctor.super_ = superCtor; ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, ...

Creating dynamic components with constructor parameters in Angular 9

Having trouble passing a value to the constructor in the component generation code. Check out the original code here: https://stackblitz.com/edit/angular-ivy-tcejuo private addComponent(template: string) { class TemplateComponent { @ViewChild( ...

Encountering a Firebase error: createUser failed due to missing "password" key in the first argument in AngularJS

Recently, I started learning Angular and decided to follow an online tutorial on creating a chat application. However, I encountered an issue when trying to register with an email and password - the error message "Firebase.createUser failed: First argument ...

Tips for customizing the appearance of the Alert Dialog in React-admin?

React-admin alert dialog example I'm currently working on a React-admin project and I am looking to customize the alert dialog that displays errors, warnings, and success messages on the page. Specifically, I want to apply CSS styles like z-index and ...

Utilizing pop-up alerts and AJAX requests in jQuery forms

I am looking to enhance my website by creating a form using PHP and jQuery. Currently, the form is placed in the footer of my website. However, I want to display the form results in a popup within the main section of the website without requiring a page ...

What are the steps to start a project on a personal computer?

Utilized on   - Windows 7, 64-bit I am interested in exploring how the project functions with github.com - project. Query: How can I get the project to do this? Steps Taken:   1. Saved the project to the directory. c:\test\visualStudio ...

Unable to eliminate top margin in Bootstrap 3 affix feature

Struggling to locate the source of the margin-top when utilizing the affix plugin on my Navbar. You can view [my website here] for better understanding. Should I be implementing Javascript to solve this issue? My current skills in that area are not very ...

What is the best way to render components with unique keys?

I am currently working on a dashboard and would like to incorporate the functionalities of React-Grid-Layout from this link. However, I am facing an issue where the components are only rendered if they have been favorited. In order to utilize the grid layo ...

Error: req.next is not a recognized function in node.js

I am completely stumped by this sudden issue that just appeared out of nowhere, with no changes in the code! TypeError: req.next is not a function The error is occurring at line 120. Here is the corresponding SQL query and the problematic line 120: // Set ...

The image being displayed is significantly wider than the corresponding HTML element

I'm attempting to display this webpage in PNG format using npm's wkhtmltox: <!doctype html> <html> <head> <meta charset="utf-8"> <style> html, body { padding: 0; width: 340px; } ...

What is the functionality of Google Chrome's "New Tab" iframes?

Have you ever wondered about those 8 small iframes displaying your most visited websites? How do they capture snapshots of the websites? How are the websites chosen for display? And most importantly, how do they actually work? Edit: I want to learn how to ...

Tap on the child to reveal their parent

I am working with a family tree that includes dropdown menus containing the names of parents and children. Each child has a link, and when I click on a child's link, I want their father to be displayed in the dropdown menu as the selected option. Can ...