Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with Loading Multiple Live Streaming Videos Using offline jsmpeg.min.js File #271

Open
fullmooooon opened this issue Jun 4, 2024 · 2 comments

Comments

@fullmooooon
Copy link

fullmooooon commented Jun 4, 2024

Hi, first of all, thank you for your module, which has saved me a lot of time.

I noticed that the rtsp-relay repository behaves differently when using the jsmpeg.min.js file from a CDN compared to using it locally. While using the CDN version, it can successfully play multiple live streaming videos (in my case, it's 3 videos),I suspect that each video is using a different JSMpeg object at this time. However, when using the local jsmpeg.min.js file, no video can be loaded. After investigation, I found that this is due to the issue of JSMpeg object reuse when using offline files.

Steps to Reproduce

Use the local jsmpeg.min.js version.
Attempt to load multiple live streaming videos.
All videos will not play properly, and there will be no error reminders on the console.

Expected Behavior

Expect that when using the local jsmpeg.min.js version, it should be able to successfully load multiple live streaming videos, similar to when using the CDN version.

Actual Behavior

None video is successfully loaded, and all fail to play.

Proposed Solution

I have identified the issue and proposed a solution: this is caused by the reuse of the JSMpeg object. In the proposed solution:

Create a new JSMpeg object when loading each video instead of reusing the existing one.
Ensure that each video has its own independent playback instance to avoid issues caused by object reuse.

Additional Information

Version Used: 1.9.0

I will provide my solution in case someone encounters the same problem and doesn't need to waste 6 hours like me

create file src\assets\rtsp-relay-browser.js copy from node_modules\rtsp-relay\browser\index.js
Make the following modifications

  const importJSMpeg = () =>
    new Promise((resolve, reject) => {
        resolve();
    });
var JSMpeg=【All text from 'https://cdn.jsdelivr.net/gh/phoboslab/jsmpeg@b5799bf/jsmpeg.min.js'】

           const player = new JSMpeg.Player(url, {
       // const player = new window.JSMpeg.Player(url, {
  // if (typeof module !== 'undefined') {
  //   // being imported
  //   module.exports = { loadPlayer };
  // } else {
  //   // loaded via script tag
  //   window.loadPlayer = loadPlayer;
  // }
  window.loadPlayer = loadPlayer;
@k-yle
Copy link
Owner

k-yle commented Jun 4, 2024

[...] when using the local jsmpeg.min.js file

What do you mean the "local jsmpeg.min.js file"? This library does not bundle JSMpeg, we always load it from the CDN.

Create a new JSMpeg object when loading each video instead of reusing the existing one.

We already do this, when you call loadPlayer, it creates a new instance of the JSMpeg class for each stream:

const player = new window.JSMpeg.Player(url, {

We also have end-to-end tests which run in GitHub Actions and confirm that multiple live streams on the same page are already supported. This is the frontend code for that test case:

<canvas></canvas>
<canvas></canvas>
<script src='../index.js'></script>
<script>
const [c1, c2] = document.querySelectorAll('canvas');
async function main() {
await loadPlayer({ url: 'ws://' + location.host + '/api/stream/2', canvas: c2 });
await loadPlayer({ url: 'ws://' + location.host + '/api/stream/1', canvas: c1 });
}
main();
</script>

If this is not working for you, perhaps you could share more information about the browser/platform that your using?

@fullmooooon
Copy link
Author

fullmooooon commented Jun 5, 2024

I have an Electron program that needs to run in an environment where CDN access is not possible. I can confirm that when window.JSMpeg exists, the JSMpeg object reuse occurs. Here are the tests I just conducted.

An Electron program that includes the following configurations

      contextIsolation: false,
      nodeIntegration: true,
      webSecurity: false,

index.vue

<template>
    <div>
        <canvas id="canvas2"></canvas>
        <canvas id="canvas3"></canvas>
    </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { loadPlayer } from 'rtsp-relay/browser'
//import 'assets/rtsp-relay-browser.js'

onMounted(() => {
    ;(async () => {
        const express = require('express')
        const app = express()
        const { proxy, scriptUrl } = require('rtsp-relay')(app)
        const handler1 = proxy({
            url: canvasRTSPurl_1,
            transport: 'tcp',
        })
        app.ws('/api/stream1', handler1)

        const handler2 = proxy({
            url: canvasRTSPurl_2,
            transport: 'tcp',
        })
        app.ws('/api/stream2', handler2)

        const handler3 = proxy({
            url: canvasRTSPurl_3,
            transport: 'tcp',
        })
        app.ws('/api/stream3', handler3)
        app.listen(2001)

        let player_1 = loadPlayer({
            url: `ws://localhost:2001/api/stream1`,
            canvas: document.getElementById('canvas1'),
        })
        let player_2 = loadPlayer({
            url: `ws://localhost:2001/api/stream2`,
            canvas: document.getElementById('canvas2'),
        })
        let player_3 = loadPlayer({
            url: `ws://localhost:2001/api/stream3`,
            canvas: document.getElementById('canvas3'),
        })
        console.log(`player_1 `, player_1 )
        console.log(`player_2 `, player_2 )
        console.log(`player_3 `, player_3 )
    })()
})
</script>

When using the offline jsmpeg.min.js file

index.html

    <script src="/jsmpeg.min.js"></script>

test in electron devtools

player_1_PromiseResult.wasmModule.memory == player_2_PromiseResult.wasmModule.memory
true

When not loading jsmpeg.min.js in index.html (Using CDN)

player_1_PromiseResult.wasmModule.memory == player_2_PromiseResult.wasmModule.memory
false

Use the 'rtsp-relay/browser' that I have modified

player_1_PromiseResult.wasmModule.memory == player_2_PromiseResult.wasmModule.memory
false

@fullmooooon fullmooooon changed the title Issue with Loading Multiple Live Streaming Videos Using Local jsmpeg.min.js File Issue with Loading Multiple Live Streaming Videos Using offline jsmpeg.min.js File Jun 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants