# Media source extension video player for live streaming mp4

**URL:** <https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958>\
**Category:** Developing Nodes\
**Created:** [24 August 2020 15:35 UTC](https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958 "2020-08-24T15:35:50Z")\
**Posts on this page:** 20\
**Page:** 3

<div class="post-metadata">

**Author:** ![kevinGodell](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/kevingodell/32/27040_2.png) [@kevinGodell](https://discourse.nodered.org/u/kevinGodell)\
**Post date:** [4 September 2020 11:45 UTC](https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958/41 "2020-09-04T11:45:45Z")

</div>

> [@BartButenaers](#):
>
> But for the linter: I use all my other nodes with the same format, so would like to keep that like it is...

I don't want to change your style, necessarily. It's just that having a linter setup makes it easier for others to contribute code to your repo. They can make their experiments work. Then they can lint their code to match `bart's preferred style` . And then make the pull request so that their contributions don't affect the overall style and make it seem like they changed every line of code. For example, in my mp4frag node, you can run `npm run lint` to cleanup the mp4frag.js file. (still haven't found a good linter setup for the mp4frag.html file). But, this is not important right now. Although it may have sped up development a little.

---

<div class="post-metadata">

**Author:** ![SuperNinja](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/superninja/32/5761_2.png) [@SuperNinja](https://discourse.nodered.org/u/SuperNinja)\
**Post date:** [4 September 2020 13:38 UTC](https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958/42 "2020-09-04T13:38:21Z")

</div>

> [@kevinGodell](#):
>
> If it is mainly a cctv solution, then typically audio is not used.

Indeed it may not be a priority but if we want to go to the end of the monitoring I think we should not remove the sound.  
Having a "loudspeaker" to turn on or off somewhere would be nice: hearing a broken window or the sound of strangers talking in your garden. An extreme case: a spray paint on the camera: there is still the sound! That would reassure the Anguished who leave their house.  
Off topic: for example: we could have a node which measures decibels, and above a threshold, output a payload to an alarm in Node Red, or make detection more efficient (avoid false positives?).

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [4 September 2020 18:27 UTC](https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958/43 "2020-09-04T18:27:09Z")

</div>

All of those use cases don’t really require synchronised audio. So it could be handled via a separate parallel flow.

---

<div class="post-metadata">

**Author:** ![kevinGodell](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/kevingodell/32/27040_2.png) [@kevinGodell](https://discourse.nodered.org/u/kevinGodell)\
**Post date:** [4 September 2020 18:56 UTC](https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958/44 "2020-09-04T18:56:37Z")

</div>

No worries about removing sounds. The debate was about having it muted in the ui because of browsers restricting autoplay with sound. The audio track will not be removed, unless you pass the **-an** flag to ffmpeg.

I like the idea of audio as another means of detecting the baddies. I had the thought myself years ago but never acted on it because my cams have no audio. I think moe at shinobi implemented a decibel library to do this.

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [4 September 2020 23:24 UTC](https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958/45 "2020-09-04T23:24:44Z")

</div>

> [@BartButenaers](#):
>
> Sorry didn't have a chance yet to look at your code. Will review it this weekend!

Some feedback about your node. Hopefully you don't interpret this as criticism, because I'm _ **VERY** _ impressed that you learned developing such a heavy node in such a short time!!!!!!!!

- Most Node-RED nodes have a similar looking readme page (which sections like 'install', 'usage', 'node properties'...). It might be useful to do it that way.

- About:  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/7/3/7358c8487792e3635b263da172825aded672c5e1.png)  
All nodes that I know have a _ **"Name"** _ field. This an optional field where you can type whatever you like, use even duplicate names or leave it empty.

- About the context dropdown:

- It is not clear to my why you store your mp4frag instance on global/flow memory. I don't think this is necessary, and be aware that users can setup a persistent context store e.g. file based (as you can read [here](https://nodered.org/docs/user-guide/context)). You don't want your instance to survive a Node-RED restart, so you don't need this setup ...

- _ **But I'm still not sure whether your "non-UI" node should setup the UI routes. Seems something that my UI node should do... WOULD BE NICE IF ANYBODY COULD GIVE US SOME ADVICE HERE!!** _

- When an error occurs you show the error description in the node status label:

- About the 'dynamic' routes. I think this can be greatly simplified, but perhaps I'm not understanding the whole picture correctly! I would do it like this:

Keep up the good/hard work!!!

---

<div class="post-metadata">

**Author:** ![kevinGodell](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/kevingodell/32/27040_2.png) [@kevinGodell](https://discourse.nodered.org/u/kevinGodell)\
**Post date:** [5 September 2020 02:09 UTC](https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958/46 "2020-09-05T02:09:33Z")

</div>

Thanks for the many tidbits of code and the in-depth critique.

> [@BartButenaers](#):
>
> Most Node-RED nodes have a similar looking readme page (which sections like 'install', 'usage', 'node properties'...). It might be useful to do it that way

Definitely will make a better readme. Was focusing more on making it viable, admittedly quick and dirty.

> [@BartButenaers](#):
>
> You need a unique name (since it used as xxx.m3u8 file name) in your http endpoint. If I were you, I would use the node id for that purpose (I have explained below how you can use it). It is generated automatically and it is unique. You can read and use it simply as `node.id` ...

Originally I played with using the id, but i was unsure if it would use unsafe url characters. Plus, I keep the hlsBase name limited to letters and underscores. Trying to keep the paths as simple as possible to extract the segment number from the http request and then to grab it from mp4frag's buffer. Although, I may be able to use the id in the path and then keep the **resource** to use a simple generic name as `playlist.m3u8, init-playlist.mp4, playlist123.m4s`, etc. I was trying not to strain the backend express too much with complicated route patterns. This may be the solution.

> [@BartButenaers](#):
>
> It is not clear to my why you store your mp4frag instance on global/flow memory. I don't think this is necessary, and be aware that users can setup a persistent context store e.g. file based (as you can read [here](https://nodered.org/docs/user-guide/context)). You don't want your instance to survive a Node-RED restart, so you don't need this setup ...

Originally, this was my way to make the internal mp4frag instance accessible from the outside. I then used the built-in http in node and a function node to deliver the m3u8 content. Since learning how to add routes, that was a leftover feature that will actually be used in a future feature not related to video streaming. It will contain buffered past video of however many seconds as a source to record from when motion detection happens. Sometimes it is good to record a few seconds of video prior to the triggering event. Also, you will see in the "close" event that the context is removed and never persists.

> [@BartButenaers](#):
>
> But I'm still not sure whether your "non-UI" node should setup the UI routes. Seems something that my UI node should do... WOULD BE NICE IF ANYBODY COULD GIVE US SOME ADVICE HERE!!

It seems that the core "http in" node adds routes and it is not listed as a "ui" node. Also, it removes the route when closed. I tried to imitate its behavior. My code is more of a backend server that makes content for your ui video player. I would consider the video player and its contents to be ui. The video source and its routes is strictly backend and should be separate and not be tightly coupled to the front end. This will allow for other video players to consume the content.

Ok, I looked a little closer at how you add routes. You add it **before** an instance of your node is created. I add my routes **after** an instance of my node is created so that I have access to the unique values set by the user. Because my mp4frag thing will be a source for video beyond a node-red client ui, I have to keep my routes user configurable and not based on a randomly generated ids, but of course, I may wrong.

Thanks again.

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [5 September 2020 05:57 UTC](https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958/47 "2020-09-05T05:57:37Z")

</div>

> [@kevinGodell](#):
>
> i was unsure if it would use unsafe url characters

Morning Kevin,  
Damn had forgotten about that. When you have a look at the node id, you will see that there is always a dot in the middle:

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/c/e/cea467da0f0e13ed3cd223c7b42fb922eb9e88f8.png)

When I use the node id in the url, that works fine (cross-browser) except for the dot. Because the dot is the only symbol that is not a number or a character. But I always solve that by replacing it by an underscore, both in the endpoint and in the location where I call the endpoint ...

> [@kevinGodell](#):
>
> in the "close" event that the context is removed and never persists

Ah ok, that is indeed true. But keep in mind that the `node.mp4frag` can also be used everywhere. And it keeps your config screen simple and less confusing for users.

> [@kevinGodell](#):
>
> how you add routes. You add it **before** an instance of your node is created

I have been reading the code of many nodes in the past, and allmost all of them do it like that. Indeed I would simply define the endpoint, and try to get the node id:

```auto
RED.httpNode.get(uiPath, function(req, res) {
     // As explained above, get the node id from the request
    var nodeId = ...

   // The dot in the node id has been replaced by an underscore, so change it back...
   nodeId = nodeId.replace("_", ".");

   var mp4fragNode = RED.nodes.getNode(nodeId);

   if (!mp4fragNode) {
      res.status(404).json('Unexisting node (with id " + nodeId + "). Possible not deployed yet..."');
      return;
   }
   ...

```

You won't find the node, until it has been deployed. Suppose I user changes the info on the config screen of your node, your endpoint will keep using the old info (from the last deploy). As soon as he deploys his new info, this endpoint will start using the new info. Seems like a very Node-RED compliant mechanism to me.

> [@kevinGodell](#):
>
> Because my mp4frag thing will be a source for video beyond a node-red client ui, I have to keep my routes user configurable and not based on a randomly generated ids, but of course, I may wrong.

Yes I fully understand that my UI node won't be the only consumer of your streams. I'm pretty sure that the e.g. the uibuilder users will start consuming your streams in the near future...

_ **But that is one of the main reasons why I find it so awkward that your node uses `RED.httpNode.get``in contradiction to the other non-ui nodes that use `RED.httpAdmin.get`. Now it really feels that your node has been developed only to support my UI node. But here ends my knowledge, so hopefully somebody else can join the discussion.** _

_ **But indeed when you don't want the generated node id in the path, you need a unique name on the config screen. But I would use an extra field - beside the optional "Name" field. But again it would be nice to get other opinions about this.** _

> [@kevinGodell](#):
>
> It seems that the core "http in" node adds routes and it is not listed as a "ui" node. Also, it removes the route when closed. I tried to imitate its behavior.

_ **I have no idea what the advantage of that is. Again hopefully somebody else can explain here.** _

Would be nice if these questions were solved before you continue, just to make sure you don't have to redesign your node later on. Because your node is going to become a popular node, that I can tell you 🤫

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [5 September 2020 06:24 UTC](https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958/48 "2020-09-05T06:24:29Z")

</div>

> [@BartButenaers](#):
>
> Because your node is going to become a popular node

About popular nodes. We have to keep in mind that also novice users will like to use your nodes to show their camera streams on their dashboard. But they most probably will quit frustrated during the ffmpeg installation. Some time ago I had lots of troubles getting ffmpeg installed on my Raspberry (i.e. compilation errors...), and it was not clear to me how to install it with h264 or not, and other decisions I had to make.

So minimal there should be a clear description on your readme, of the steps they have to execute. Or a link to a tutorial ..

Due to the installation issues, I had registered this [issue](https://github.com/kribblo/node-ffmpeg-installer/issues/22) to have ARM support for the pre-build binaries. At the time being I had the idea to add that npm library as a dependency for my ffmpeg node, or create a separate _ **node-red-contrib-ffmpeg-installer** _ node. What is your opinion about that? P.S. I haven't followed that node-ffmpeg-installer project meanwhile, so don't know if the binaries keep up with the recent ffmpeg versions, or whether the Raspberry 4 architecture is supported, or ... But I hope you will get the idea.

Because we have to be aware that not all Node-RED users are highly technical skilled, and we should try to create nodes for all types of users. Which might not be easy due to the ffmpeg dependency...

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [5 September 2020 06:57 UTC](https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958/49 "2020-09-05T06:57:06Z")

</div>

Bart, Kevin, the endpoints should be quite simple. The httpadmin ones are protected by the admin auth mechanism, and are for people who should have access to the editor. The others are protected by the http auth and are for users of the flow. So a node that needs to get something from the back end during config would use the admin route, but once deployed and in use it would expose an http one for users to hit.

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [5 September 2020 10:03 UTC](https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958/50 "2020-09-05T10:03:55Z")

</div>

Thanks for following this discussion Dave! So then I have been confusing Kevin, and it is fine that he defines the endpoint. That case is closed then...

Do you know what the advantage is of removing the routes, like the http-in node? Seems quite some overhead to me, since the `:resource` parameter in the url allows Kevin to use 1 endpoint for all his nodes and routes. But most probably I have missed something...

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [5 September 2020 11:33 UTC](https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958/51 "2020-09-05T11:33:43Z")

</div>

Because you shouldn’t leave them exposed when you close down. Potential security hole. Ties up resources etc. Memory leak etc

---

<div class="post-metadata">

**Author:** ![kevinGodell](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/kevingodell/32/27040_2.png) [@kevinGodell](https://discourse.nodered.org/u/kevinGodell)\
**Post date:** [5 September 2020 12:17 UTC](https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958/52 "2020-09-05T12:17:57Z")

</div>

> [@BartButenaers](#):
>
> Ah ok, that is indeed true. But keep in mind that the `node.mp4frag` can also be used everywhere. And it keeps your config screen simple and less confusing for users.

Does this mean that other nodes can easily access the internal mp4frag instance if I attach it to `this` node? If that is the case, then they would probably need the randomly generated id as opposed to a simply named identifier to access it from flow or global context?

I definitely like the idea of using just 1 endpoint. That would make things simpler for me. Right now, I add **4 per node instance** , really only needs 3 but I added the .m3u8.txt for debugging to make it easier to view the playlist in your browser by delivering it as plain text. I could probably reduce it to **1 per node instance** if I use the unique name in the path instead of the file, such as `/unique_name/:resource` with all of the resource files simple being named _playlist.m3u8_, _init-playlist.mp4_, etc. So the public routes matched would be `/front_porch_main/playlist.m3u8` or `/back_door_sub/playlist.m3u8`. But then I wonder if the additional `if/else` blocks and additional getter code overhead vs the overhead of having specific routes already matched to the content and having the mp4frag value encapsulated in the route handler. This would be very hard to test the performance gains or losses based on the routing structure.

> [@BartButenaers](#):
>
> So minimal there should be a clear description on your readme, of the steps they have to execute. Or a link to a tutorial ..

I still am still planning on doing that once I have the node a little more built out. As a node-red novice, I found its layout and interface to not be very intuitive. I am also surprised that there seems to be no helpful information on the settings screen of a node. Hunting for help text while being a newbie was a bit tricky. I wanted to put more details on my settings screen but didn't want to break with the norm of being unhelpful. Trust me, the `show help` button is not very obvious to a new user. Is there a way to trigger the help screen to open by clicking on a little `i` symbol next to a settings option? Now that would really be helpful for new users. Also, I will add back the `Name` option to comply with the norm.

> [@BartButenaers](#):
>
> Because we have to be aware that not all Node-RED users are highly technical skilled, and we should try to create nodes for all types of users. Which might not be easy due to the ffmpeg dependency...

The ffmpeg thing will be tricky. Luckily for me on a pi 4, I ended up with newer version after updating on the command line. In the past, and in some of my travis/appveyor tests, I think I use an npm module that brings ffmpeg with it. Problem is that it also brings with many other ffmpegs for other systems too. On a small system, that may be a waste of precious space. Will have to look into it further. I was planning on building a wrapper around my ffmpeg lib that monitors its progress and can automagically respawn it. Sometimes a video feed source may freeze, but ffmpeg will stay open as it patiently waits for more video content to arrive. I monitor the progress with a timer and respawn the process x number of times until finally emitting a 'fail' event which can ultimately alert you that your video feed is down hard.

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [5 September 2020 14:04 UTC](https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958/53 "2020-09-05T14:04:41Z")

</div>

> [@kevinGodell](#):
>
> Does this mean that other nodes can easily access the internal mp4frag instance if I attach it to `this` node?

Yes indeed.

> [@kevinGodell](#):
>
> need the randomly generated id as opposed to a simply named identifier

Well by using the id it is rather simple to get the corresponding node instance. But I understand thzt you would like to allow the user to enter a unique name. Since I don't want to be your party-stopper I think you can achieve that, since you can loop the nodes (as I have done [here](https://github.com/bartbutenaers/node-red-contrib-node-list/blob/master/node_list.js#L14) in the past. Something like this:

```auto
RED.nodes.eachNode(function(node) {
   If (node.uniqueName && node.uniqueName === someName) {
  // node with unique id found, so access node.mp4frag
}
})

```

Although it might (again) result in a lot of cpu usage, since you do such a large amoung of http requests ...

Perhaps you can create simply a global Javascript object mp4fragments, where you store - as soon is created - a reference to your node. So instead of only keeping the uniqueNames [here](http://uniqueNames), store the link uniqueName vs node reference. Then you only need to search in that object...

> [@kevinGodell](#):
>
> This would be very hard to test

Yes. Perhaps @afelix has some experience with that...

> [@kevinGodell](#):
>
> Is there a way to trigger the help screen to open by clicking on a little `i` symbol next

Don't know that...

---

<div class="post-metadata">

**Author:** ![SuperNinja](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/superninja/32/5761_2.png) [@SuperNinja](https://discourse.nodered.org/u/SuperNinja)\
**Post date:** [5 September 2020 16:40 UTC](https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958/54 "2020-09-05T16:40:17Z")

</div>

> [@BartButenaers](#):
>
> At the time being I had the idea to add that npm library as a dependency for my ffmpeg node, or create a separate _ **node-red-contrib-ffmpeg-installer** _ node.

> [@BartButenaers](#):
>
> Because we have to be aware that not all Node-RED users are highly technical skilled, and we should try to create nodes for all types of users. Which might not be easy due to the ffmpeg dependency...

👍

Why not draw from this tutorial :

> [@Display camera ip in dashboard and store video in raspberry](https://discourse.nodered.org/t/display-camera-ip-in-dashboard-and-store-video-in-raspberry/6349/62):
>
> I'm currently following this instruction for one of my RPi3B, not finished yet but I believe you have to build from source like it's described in this guide

the creation of this contrib-ffmpeg-installer node?

---

<div class="post-metadata">

**Author:** ![ristomatti](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ristomatti/32/5857_2.png) [@ristomatti](https://discourse.nodered.org/u/ristomatti)\
**Post date:** [5 September 2020 18:59 UTC](https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958/55 "2020-09-05T18:59:07Z")

</div>

As a silent follower of this topic, I would suggest to ignore the potential ffmpeg installation difficulties for now and focus on the core functionalities. 🙂

I also remember giving up on some NVR software installation attempt due to how confusing it seemed but then later on found out that the current Raspbian/Raspberry OS versions come with a suitable ffmpeg version built in.

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [5 September 2020 19:48 UTC](https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958/56 "2020-09-05T19:48:16Z")

</div>

> [@ristomatti](#):
>
> suggest to ignore the potential ffmpeg installation difficulties

Yes that seems to make sense. But the problem was that I still need to install ffmpeg on my system (to test Kevin's node), and I don't have the time or energy to go through the same mess as last time ... So I thought: if I have to install it anyway, why not trying to automate the process (for most know platforms) via pre-build stuff. Of course if possible with minimal efforts ...

When I simply do this:

```auto
npm install --save @ffmpeg-installer/ffmpeg

```

Then less than a minute later, ffmpeg is up-and-running.  
No headache... How cool is that...

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/a/f/afc98cad2f1a5cf22c224bc8867261a12fed2bb5.png)

However I think it is a rather old version (?), and I don't know whether it is compiled using the correct settings (?)

---

<div class="post-metadata">

**Author:** ![ristomatti](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ristomatti/32/5857_2.png) [@ristomatti](https://discourse.nodered.org/u/ristomatti)\
**Post date:** [5 September 2020 19:51 UTC](https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958/57 "2020-09-05T19:51:56Z")

</div>

I forgot we're not taking about Raspberry Pi's here. I can imagine it could be painful especially to compile a custom version on Windows... 🙄

But if the prebuilt one installed from npm works, that is truly handy!

---

<div class="post-metadata">

**Author:** ![kevinGodell](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/kevingodell/32/27040_2.png) [@kevinGodell](https://discourse.nodered.org/u/kevinGodell)\
**Post date:** [5 September 2020 20:40 UTC](https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958/58 "2020-09-05T20:40:57Z")

</div>

Right now I am trying to beat up node-red to see what it can handle on a pi 4. The current experiment is to test my suspicious routing configuration and tweak it. I have to put it under load to see if there can be a more efficient way to handle the constant http requests for the hls fragments. Ultimately, sockets should win the fight vs http, but that is a future implementation.

So far, the limitation that I see is on the client side hls.js library. Trying to stream 14 mostly 1080p videos seems too much for the browser to handle, while the node-red server side seems to run just fine at a fluctuating node-red cpu load of 10% to 30% based on htop. This was strictly stream copying the main channel from the ip cams and delivering via http requests. No jpegs stuff in this experiment.

Realistically, we should not try to stream multiple 1080p cams at the same time to a browser, but of course, we will. Personally, I would use the sub stream for regular viewing when there is a montage of cams, and only use the main stream when viewing a single cam or using as a source for recording. FYI, you can view some debug info on chrome @ chrome://media-internals/.

Also, I was able to get good audio on 2 of my 3 cams that support it. In the past versions of ffmpeg, the audio seemed to not work very good. I read that the aac encoder is no longer experimental, but am not 100% sure on that. 1 of my cams has audio already encoded as aac, so I am able to stream copy it. The other 2 cams audio is pcm\_alaw, which I encode to aac. One of those encoded audio is a little low quality and I am seeing how ffmpeg can filter its crackly sound if possible.

 ![Screen Shot 2020-09-05 at 3.07.17 PM](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/9/4/943cc8042613e4cf9fea9654a487be90e6770377.png)

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [5 September 2020 21:02 UTC](https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958/59 "2020-09-05T21:02:05Z")

</div>

Wow ... 👍

> [@kevinGodell](#):
>
> cpu load of 10% to 30%

That is pretty low, not?

> [@kevinGodell](#):
>
> Personally, I would use the sub stream for regular viewing when there is a montage of cams, and only use the main stream when viewing a single cam or using as a source for recording.

Main stream: does this main high frame rate and high resolution?

---

<div class="post-metadata">

**Author:** ![kevinGodell](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/kevingodell/32/27040_2.png) [@kevinGodell](https://discourse.nodered.org/u/kevinGodell)\
**Post date:** [5 September 2020 21:13 UTC](https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958/60 "2020-09-05T21:13:03Z")

</div>

> [@BartButenaers](#):
>
> That is pretty low, not?

That was just for the node-red process, excluding all the other processes. It's not that bad. We have to make some benchmarks.

> [@BartButenaers](#):
>
> Main stream: does this main high frame rate and high resolution?

Main stream is usually higher resolution and sub stream is lower res. They can each have their own independent frame rate. The higher resolution definitely puts a strain on the browser for decoding and playback.

> [@BartButenaers](#):
>
> However I think it is a rather old version (?), and I don't know whether it is compiled using the correct settings (?)

I was playing with my old repo ffmpeg-streamer to see if it would work on the pi. If it used the default system ffmpeg, then it worked good. If I triggered it to use the ffmpeg using the npm lib `ffbinaries`, it does not work good. It is an older version of ffmpeg that had some tls issue and could no longer read https files after some websites (including github that was hosting my hls files) did some tls 1.2 update a couple years back. I can't remember the exact details, but not all of the pre-combiled binaries may be fully compliant. Lots of testing needed.

[Previous page](https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958.md?page=2)

[Next page](https://discourse.nodered.org/t/media-source-extension-video-player-for-live-streaming-mp4/31958.md?page=4)
