@BartButenaers Your video player works great. Thanks. It really helps for me to test my back end much easier.
Here is an example flow using your player with my mp4frag wrapper using external routes with mp4frag being added to global context. I started with the context approach to be more flexible in case somebody wanted to build something around the lib (and at the time i didnt know i could make my own routes )
[{"id":"26b5a4eb.db1d34","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"95acc154.09f0c","type":"inject","z":"26b5a4eb.db1d34","name":"Start stream","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"str","x":110,"y":40,"wires":[["7dbc80c7.4e764"]]},{"id":"8b7657be.b17558","type":"inject","z":"26b5a4eb.db1d34","name":"Stop stream","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"false","payloadType":"str","x":110,"y":86,"wires":[["7dbc80c7.4e764"]]},{"id":"7dbc80c7.4e764","type":"switch","z":"26b5a4eb.db1d34","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"true","vt":"str"},{"t":"eq","v":"false","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":261,"y":40,"wires":[["70626fe2.0e9c5"],["fd61d017.59965"]]},{"id":"fd61d017.59965","type":"function","z":"26b5a4eb.db1d34","name":"stop","func":"msg= [\n {\n kill:'SIGHUP',\n payload : 'SIGHUP'\n }\n \n \n ]; // set a new payload & the counter\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":281,"y":89,"wires":[["70626fe2.0e9c5"]]},{"id":"70626fe2.0e9c5","type":"exec","z":"26b5a4eb.db1d34","command":"ffmpeg -loglevel quiet -hwaccel rpi -c:v h264_mmal -rtsp_transport tcp -i rtsp://192.168.1.4:554/user=admin_password=pass_channel=0_stream=0.sdp?real_stream -q 2 -vf fps=fps=2,scale=-1:-1 -c:v mjpeg -f image2pipe pipe:2 -an -c:v copy -f mp4 -movflags +frag_keyframe+empty_moov+default_base_moof pipe:1","addpay":false,"append":"","useSpawn":"true","timer":"","oldrc":false,"name":"front porch ip cam main","x":474,"y":49,"wires":[["9bfbb50a.54833"],["752eb.8f4e1d158"],["9bfbb50a.54833"]]},{"id":"522ad11.3d8643","type":"image","z":"26b5a4eb.db1d34","name":"","width":"320","data":"payload","dataType":"msg","thumbnail":false,"active":true,"pass":false,"outputs":0,"x":140,"y":180,"wires":[]},{"id":"752eb.8f4e1d158","type":"pipe2jpeg","z":"26b5a4eb.db1d34","name":"some name","x":680,"y":80,"wires":[["522ad11.3d8643"]]},{"id":"f94373f8.d3d9b","type":"http in","z":"26b5a4eb.db1d34","name":"","url":":base([a-z_]+).m3u8","method":"get","upload":false,"swaggerDoc":"","x":521,"y":196,"wires":[["575c6379.bf74dc"]]},{"id":"d360f454.75f2b8","type":"http in","z":"26b5a4eb.db1d34","name":"","url":"init-:base([a-z_]+).mp4","method":"get","upload":false,"swaggerDoc":"","x":531,"y":236,"wires":[["ccdad96e.857a08"]]},{"id":"bc4e092d.1ee938","type":"http in","z":"26b5a4eb.db1d34","name":"","url":":base([a-z_]+):seq(\\d+).m4s","method":"get","upload":false,"swaggerDoc":"","x":541,"y":276,"wires":[["39c27647.a5d5ca"]]},{"id":"be9c49a3.a66a78","type":"http in","z":"26b5a4eb.db1d34","name":"","url":":base([a-z_]+).m3u8.txt","method":"get","upload":false,"swaggerDoc":"","x":531,"y":316,"wires":[["3827e276.b31f8e"]]},{"id":"3827e276.b31f8e","type":"function","z":"26b5a4eb.db1d34","name":"mp4frag context","func":"const { base } = msg.req.params;\n\nconst mp4frag = global.get(base);\n\nconst m3u8 = mp4frag && mp4frag.m3u8;\n\nif (m3u8) {\n msg.payload = m3u8;\n msg.headers = {'content-type': 'text/plain'};\n} else {\n msg.payload = 'm3u8 playlist not found';\n msg.headers = {'content-type': 'text/plain'};\n msg.statusCode = 404;\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":791,"y":316,"wires":[["228a5549.40f13a"]]},{"id":"228a5549.40f13a","type":"http response","z":"26b5a4eb.db1d34","name":"","statusCode":"","headers":{},"x":961,"y":316,"wires":[]},{"id":"39c27647.a5d5ca","type":"function","z":"26b5a4eb.db1d34","name":"mp4frag context","func":"const { base, seq } = msg.req.params;\n\nconst mp4frag = global.get(base);\n\nconst segment = mp4frag && mp4frag.getHlsSegment(seq);\n\nif (segment) {\n msg.payload = segment;\n msg.headers = {'content-type': 'video/mp4'};\n} else {\n msg.payload = `segment ${seq} not found`;\n msg.headers = {'content-type': 'text/plain'};\n msg.statusCode = 404;\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":790,"y":276,"wires":[["4231b8b3.b0fa68"]]},{"id":"4231b8b3.b0fa68","type":"http response","z":"26b5a4eb.db1d34","name":"","statusCode":"","headers":{},"x":961,"y":276,"wires":[]},{"id":"ccdad96e.857a08","type":"function","z":"26b5a4eb.db1d34","name":"mp4frag context","func":"const { base } = msg.req.params;\n\nconst mp4frag = global.get(base);\n\nconst initialization = mp4frag && mp4frag.initialization;\n\nif (initialization) {\n msg.payload = initialization;\n msg.headers = {'content-type': 'video/mp4'};\n} else {\n msg.payload = 'initialization fragment not found';\n msg.headers = {'content-type': 'text/plain'};\n msg.statusCode = 404;\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":788,"y":236,"wires":[["270da754.a5f5e8"]]},{"id":"270da754.a5f5e8","type":"http response","z":"26b5a4eb.db1d34","name":"","statusCode":"","headers":{},"x":961,"y":236,"wires":[]},{"id":"575c6379.bf74dc","type":"function","z":"26b5a4eb.db1d34","name":"mp4frag context","func":"const { base } = msg.req.params;\n\nconst mp4frag = global.get(base);\n\nconst m3u8 = mp4frag && mp4frag.m3u8;\n\nif (m3u8) {\n msg.payload = m3u8;\n msg.headers = {'content-type': 'application/vnd.apple.mpegURL'};\n //msg.headers = {'content-type': 'application/x-mpegURL'};\n //msg.headers = {'content-type': 'application/x-mpegurl'};\n} else {\n msg.payload = 'm3u8 playlist not found';\n msg.headers = {'content-type': 'text/plain'};\n msg.statusCode = 404;\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":787,"y":196,"wires":[["5e29cec.60df53"]]},{"id":"5e29cec.60df53","type":"http response","z":"26b5a4eb.db1d34","name":"","statusCode":"","headers":{},"x":961,"y":196,"wires":[]},{"id":"9bfbb50a.54833","type":"mp4frag","z":"26b5a4eb.db1d34","uniqueName":"front_porch_main","hlsListSize":"4","contextAccess":"global","httpRoutes":false,"x":710,"y":20,"wires":[[]]},{"id":"387294df.f4c8f4","type":"ui_mp4_player","z":"26b5a4eb.db1d34","group":"ea204528.5e15d8","order":4,"width":"6","height":"3","name":"","sourceType":"url","sourceValue":"http://192.168.1.85:1880/front_porch_main.m3u8","aspectratio":"stretch","x":910,"y":60,"wires":[[]]},{"id":"ea204528.5e15d8","type":"ui_group","name":"Group 1","tab":"ef1a3eec.2694d","order":1,"disp":true,"width":6},{"id":"ef1a3eec.2694d","type":"ui_tab","z":"26b5a4eb.db1d34","name":"Dashboard","icon":"dashboard","order":1,"disabled":false,"hidden":false}]
npm install kevinGodell/node-red-contrib-mp4frag
I am going to push some code in a little while to add the built in http routes and then will add another flow showing the alternative approach.