phoboslab / jsmpeg

MPEG1 Video Decoder in JavaScript
MIT License
6.38k stars 1.43k forks source link

Disconnect/Destroy player window using javascript? #130

Open RabenFlug opened 7 years ago

RabenFlug commented 7 years ago

Hey there, I'm using ffmpeg now for two weeks to show my chickens on a website. i love your project, great work! There are some questions that i have:

  1. is there a way to destroy the player object using javascript. I want to add two buttons "cam1" and "cam2" that switches between two streams in the same DIV. I tried it by destroying the player and creating a new one with a different ws url (port). But i was not able to destroy the object

  2. Is there a way to disconnect a running player? I use my own server (connected to a 10mbps upstream dsl). Now i want to add a timer that disconnects the player after some hours to prevent wasting my upstream bandwith. For example when users keep the player open in my company 24/7?

  3. I found a strange behaviour that occurs when the socket turns offline (maybe for restarting the server) and some users are still on the website with the player. In this case, after restarting the node relay, it shows hundreds of "connections". After some random time, the "400 users" decreases to a realistiv value (f.e. 4 users). What can i do to prevent this?

  4. Is there a way to use udp or multicast to save upstream traffic?

I hope my questions are not to stupid?

Very many regards Christian

phoboslab commented 7 years ago

1) For now, use player.source.abort(). When I find the time, I will implement a player.destroy() method, that properly disconnects the source and cleans up WebGL/WebAudio state.

2) You can certainly do that in the websocket-relay.js. Record the time a client connected and check periodically if they're due to disconnect. Maybe the WebSocket implementation ws even offers a direct way to do that!? However, I think such a feature would be outside the scope of JSMpeg.

3) Not sure what's going on. The WebSocket source periodically tries to reconnect to the server, whenever the connection is lost. So maybe these connection attempts get buffered up somehow!? Are you using a proxy (e.g. Nginx) in front of the websocket-relay?

4) WebSockets always run over TCP, not UDP. I don't think it supports multicast either, but I'd love to be proven wrong :)

Edit: after thinking about 2) a bit more: if you just close the connection from the server, the JSMpeg WebSocket source will attempt to reconnect! You can circumvent this by passing reconnectInterval: 1000000 in the player options. But it would probably be better to just attempt to reconnect anyway, when there's an error, not a regular connection close. I'll change this!

RabenFlug commented 7 years ago

Dear phoboslab, thanks for your quick reply and your help. I think i will solve 2) by starting a JS-timer on the client side that stopps or destroys the Player after x Hours. That seems to be the easiest way to get rid of traffic consuming passive clients. What makes me wonder a little bit is that player.stop(); still keeps the traffic flowing? Using player.source.abort() the traffic stops.

Regarding 3) There are no proxies, no caches or something else... It's really strange. After starting the websocket relay (the browser with the player is still "open" with frozen picture, trying to reconnect... New WebSocket Connection: ::ffff:89.246.x.x Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 (1 total) New WebSocket Connection: ::ffff:89.246.x.x Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 (2 total) New WebSocket Connection: ::ffff:89.246.x.x Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 (3 total) ... New WebSocket Connection: ::ffff:89.246.x.x Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 (73 total)

netstat -natp | grep 8085 on the server side shows all the connections: tcp6 0 23460 192.168.x.x:8085 89.246.x.x:64482 VERBUNDEN - tcp6 0 27600 192.168.x.x:8085 89.246.x.x:64551 VERBUNDEN - tcp6 0 27600 192.168.x.x:8085 89.246.x.x:64476 VERBUNDEN -

Now, the traffic is on the limit but the picture is still frozen in the player. Every connection to this single player seems to consume real traffic. After closing the player, within one second, all connections are closed: Disconnected WebSocket (73 total) ... Disconnected WebSocket (2 total) Disconnected WebSocket (1 total) Disconnected WebSocket (0 total)

I now use the workaround by increasing the reconnect interval to 1000sec: reconnectInterval: 1000000 also thank you for that :)

phoboslab commented 7 years ago

You can now specify reconnectInterval: 0 to never reconnect automatically. I also implemented player.destroy() and fixed a bug regarding to reconnects - maybe that fixes 3).

RabenFlug commented 7 years ago

Dear Dominic, the destroy method works perfect! That gives me the possibility to "switch" between two streams by destroying and recreating the player with a different ws URL. Pefekt! Your fix regarding the reconnect 3) seems to work, no useless conenctions anymore. Also the reconnectInterval:0 thing works fine! I solved 2) by starting a 6 hour JS timer on the client side when the page is opened that stops and destroys the player and shows a info dialog after that time. Thank you very much for your support! Last question for today: Is there a paypal account to give a donation to you or the project?

tinyXiongGG commented 5 years ago

Dear Dominic, the destroy method works perfect! That gives me the possibility to "switch" between two streams by destroying and recreating the player with a different ws URL. Pefekt! Your fix regarding the reconnect 3) seems to work, no useless conenctions anymore. Also the reconnectInterval:0 thing works fine! I solved 2) by starting a 6 hour JS timer on the client side when the page is opened that stops and destroys the player and shows a info dialog after that time. Thank you very much for your support! Last question for today: Is there a paypal account to give a donation to you or the project?

Hi RabenFlug, i got same question as ur question 1, but my player.destory() not work well, can u give me some help? this is my js function:

<body>
    <div>
        <button onclick="play('wss://localhost:7072/live1')">live1</button>
        <button onclick="play('wss://localhost:7072/live2')">live2</button>
    </div>
    <canvas id="video-canvas"></canvas>
    <script type="text/javascript" src="jsmpeg.min.js"></script>
    <script type="text/javascript">
    var player;
    function play(url) {
        if (player) {
        player.destroy();
        }
            var canvas = document.getElementById('video-canvas');
            player = new JSMpeg.Player(url, {canvas: canvas});
    }
    </script>
</body>

when i first click,it played well. but when i chose other stream, there is no picture to display.

tinyXiongGG commented 5 years ago

Dear Dominic, the destroy method works perfect! That gives me the possibility to "switch" between two streams by destroying and recreating the player with a different ws URL. Pefekt! Your fix regarding the reconnect 3) seems to work, no useless conenctions anymore. Also the reconnectInterval:0 thing works fine! I solved 2) by starting a 6 hour JS timer on the client side when the page is opened that stops and destroys the player and shows a info dialog after that time. Thank you very much for your support! Last question for today: Is there a paypal account to give a donation to you or the project?

Hi RabenFlug, i got same question as ur question 1, but my player.destory() not work well, can u give me some help? this is my js function:

<body>
    <div>
        <button onclick="play('wss://localhost:7072/live1')">live1</button>
        <button onclick="play('wss://localhost:7072/live2')">live2</button>
    </div>
    <canvas id="video-canvas"></canvas>
    <script type="text/javascript" src="jsmpeg.min.js"></script>
    <script type="text/javascript">
  var player;
  function play(url) {
      if (player) {
      player.destroy();
      }
            var canvas = document.getElementById('video-canvas');
            player = new JSMpeg.Player(url, {canvas: canvas});
  }
    </script>
</body>

when i first click,it played well. but when i chose other stream, there is no picture to display.

I have solved this problem.
when i call destroy method, the canvas element destroyed too. so i create new canvas after called destroy

nitinkothwal commented 4 years ago

We are using JSMPEG player in our angular application. We having issue with switching between two video sources. We are seeing still image from older stream for few seconds say 10 to 15 secs and then it starts showing new stream.

We always create new player instance and canvas element to stream new source. We're also destroying existing player instance as well canvas before switching to new stream.

ghost commented 4 years ago

Hello all, I am using jsmpeg player in my android app.I having some issue regarding closing jmpeg websocket stream while I destroy my activity.player.destroy() method calls properly but it is abnormal termination of websocket connection.What I need is I just want to clear the jsmpeg player object or need to close player.close() or ws.close(); so that my player object get closed or removed from memory and I am able to create fresh player object with new url so any one help me out there?