Skip to content

Instantly share code, notes, and snippets.

@btsimonh
Last active December 9, 2017 12:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save btsimonh/c15220c4351c8070fcd53005612e5dae to your computer and use it in GitHub Desktop.
Save btsimonh/c15220c4351c8070fcd53005612e5dae to your computer and use it in GitHub Desktop.
Motion detection from http mjpeg feed with frame queue
[
{
"id": "eba842e3.87cce",
"type": "inject",
"z": "206db361.104f6c",
"name": "Start",
"topic": "",
"payload": "1",
"payloadType": "num",
"repeat": "",
"crontab": "",
"once": false,
"x": 110,
"y": 20,
"wires": [
[
"696d274d.a700c8"
]
]
},
{
"id": "d96af7e9.953f18",
"type": "function",
"z": "206db361.104f6c",
"name": "LoadCV",
"func": "var require = global.get('require');\nvar cv = null;\n//try{\n// cv = require.main.require('opencv');\n//} catch(e){\n cv = require('opencv');\n \n//}\n\nvar cvdesc = Object.keys(cv);\nnode.send([null, {payload:cvdesc}]);\nflow.set('cv', cv);\n\nnode.log(\"Starting to create MOG2\");\nbg = cv.BackgroundSubtractor.createMOG2();\nnode.log(\"MOG2 has been created\");\nflow.set('bg', bg);\n\n\nnode.send({payload:1, url:'http://raspberrypi:1880/cam2'});\n//node.send({payload:1, url:'http://127.0.0.1:1880/cam2'});\n\n//node.send({payload:1, url:'http://185.49.168.74:8001/axis-cgi/mjpg/video.cgi'});\n//node.send({payload:1, url:'http://mbewebcam.rhul.ac.uk/mjpg/video.mjpg'});\n",
"outputs": "2",
"noerr": 0,
"x": 300,
"y": 120,
"wires": [
[
"417022f2.ff626c"
],
[]
]
},
{
"id": "4b991c3c.9f1424",
"type": "inject",
"z": "206db361.104f6c",
"name": "Stop",
"topic": "",
"payload": "0",
"payloadType": "num",
"repeat": "",
"crontab": "",
"once": false,
"x": 110,
"y": 160,
"wires": [
[
"665cd6ef.d92a48"
]
]
},
{
"id": "696d274d.a700c8",
"type": "function",
"z": "206db361.104f6c",
"name": "Variables and 'frames'",
"func": "\nflow.set(\"area\", 200);\nflow.set(\"width\", 640);\nflow.set(\"height\", ((flow.get('width')*3/4/2)>>0)*2);\n\nflow.set('framestore', []);\nflow.set('currentframe', 0);\nflow.set('nextframe', 0);\n\n\nvar timings = {};\nflow.set('timings', timings);\n\n\nvar frames = flow.get('frames') || {num:0, dropped:0, frames:[]};\n\nframes.deleteall = function(){\n var len = frames.frames.length;\n \n for (var i = 0; i < len; i++){\n frames.droplast();\n }\n frames = {num:0, dropped:0, frames:[]};\n flow.set('frames', frames);\n \n};\n\nframes.droplast = function(){\n var oldframe = frames.frames.shift();\n if (oldframe.images){\n var keys = Object.keys(oldframe.images);\n for (var i = 0; i < keys.length; i++){\n if (oldframe.images[keys[i]]){\n if (oldframe.images[keys[i]].release){\n oldframe.images[keys[i]].release();\n }\n }\n }\n var keys = Object.keys(oldframe.imagesasync);\n for (var i = 0; i < keys.length; i++){\n if (oldframe.imagesasync[keys[i]]){\n if (oldframe.imagesasync[keys[i]].release){\n oldframe.imagesasync[keys[i]].release();\n }\n }\n }\n }\n //node.warn(\"frame lost \"+oldframe.num );\n};\n\nframes.frameinlist = function(f){\n var framecount = frames.frames.length;\n var found = false;\n for (var i = framecount-1; i >= 0; i-- ){\n if (f.num == frames.frames[i].num){\n found = true;\n break;\n }\n }\n return found;\n};\n\n\nflow.set('frames', frames);\n\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 300,
"y": 20,
"wires": [
[
"97e6dcea.b52cc"
]
]
},
{
"id": "c1e3392c.7efcd8",
"type": "change",
"z": "206db361.104f6c",
"name": "",
"rules": [
{
"t": "set",
"p": "stop",
"pt": "msg",
"to": "true",
"tot": "bool"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 470,
"y": 160,
"wires": [
[
"417022f2.ff626c"
]
]
},
{
"id": "417022f2.ff626c",
"type": "multipart-decoder",
"z": "206db361.104f6c",
"name": "",
"ret": "bin",
"url": "",
"tls": "",
"delay": 0,
"maximum": 1000000,
"x": 490,
"y": 120,
"wires": [
[
"5c862dbb.dd6084",
"12bfb225.cd81ae",
"48f00ccf.f884d4"
]
]
},
{
"id": "d1968f1e.e7738",
"type": "http in",
"z": "206db361.104f6c",
"name": "",
"url": "/pubcam4",
"method": "get",
"upload": false,
"swaggerDoc": "",
"x": 640,
"y": 540,
"wires": [
[
"bfc1b46b.e41858"
]
]
},
{
"id": "12bfb225.cd81ae",
"type": "debug",
"z": "206db361.104f6c",
"name": "",
"active": false,
"console": "false",
"complete": "true",
"x": 670,
"y": 140,
"wires": []
},
{
"id": "97e6dcea.b52cc",
"type": "function",
"z": "206db361.104f6c",
"name": "set opencv folder",
"func": "var req=global.get('require');\n\nvar proc = req('process');\n\n//proc.env['LD_LIBRARY_PATH'] = '/usr/lib/node_modules/opencv/build/opencv/v6.0.0/Release/node-v48-linux-arm/opencv';\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 310,
"y": 80,
"wires": [
[
"d96af7e9.953f18"
]
]
},
{
"id": "bfc1b46b.e41858",
"type": "multipart-encoder",
"z": "206db361.104f6c",
"name": "",
"statusCode": "",
"ignoreMessages": true,
"outputOneNew": false,
"outputIfSingle": false,
"outputIfAll": false,
"globalHeaders": {
"Content-Type": "multipart/x-mixed-replace;boundary=--myboundary",
"Connection": "keep-alive",
"Expires": "Fri, 01 Jan 1990 00:00:00 GMT",
"Cache-Control": "no-cache, no-store, max-age=0, must-revalidate",
"Pragma": "no-cache"
},
"partHeaders": {
"Content-Type": "image/jpeg"
},
"destination": "all",
"highWaterMark": "150000",
"x": 900,
"y": 500,
"wires": [
[]
]
},
{
"id": "5c862dbb.dd6084",
"type": "function",
"z": "206db361.104f6c",
"name": "inputfps timing",
"func": "context.lasttime = context.lasttime || (new Date()).valueOf();\n\nvar now = (new Date()).valueOf();\n\nvar diff = now - context.last;\ncontext.last = now;\n\ncontext.diff = diff;\ncontext.avg = context.avg || diff;\n\ncontext.avg *= 0.995;\ncontext.avg += diff*0.005;\n\ncontext.FPS = 1000/context.diff;\ncontext.FPSavg = 1000/context.avg;\n\nflow.set(\"inputfps\", {fps:context.diff, fpsavg:context.avg});\n\nreturn;",
"outputs": 1,
"noerr": 0,
"x": 680,
"y": 60,
"wires": [
[]
]
},
{
"id": "c1b96bc2.50db28",
"type": "inject",
"z": "206db361.104f6c",
"name": "",
"topic": "",
"payload": "",
"payloadType": "date",
"repeat": "1",
"crontab": "",
"once": false,
"x": 190,
"y": 620,
"wires": [
[
"132fad9c.5c7092"
]
]
},
{
"id": "132fad9c.5c7092",
"type": "function",
"z": "206db361.104f6c",
"name": "",
"func": "\nvar inputfps = flow.get('inputfps');\n\nif (inputfps){\n var keys = Object.keys(inputfps);\n for (var i = 0; i < keys.length; i++){\n node.send([{topic:\"input\"+keys[i], payload:inputfps[keys[i]]}, null]);\n }\n}\n\nvar outputfps = flow.get('outputfps');\n\nif (outputfps){\n var keys = Object.keys(outputfps);\n for (var i = 0; i < keys.length; i++){\n node.send([null, {topic:\"output\"+keys[i], payload:outputfps[keys[i]]}]);\n }\n}\n\nvar output2fps = flow.get('output2fps');\n\nif (output2fps){\n var keys = Object.keys(output2fps);\n for (var i = 0; i < keys.length; i++){\n node.send([null, null, {topic:\"output2\"+keys[i], payload:output2fps[keys[i]]}]);\n }\n}\n\n\n\nreturn;",
"outputs": "3",
"noerr": 0,
"x": 350,
"y": 640,
"wires": [
[
"cdac3ef9.0af12"
],
[
"c009d2e.0a6e53"
],
[
"c2a7176a.0bec78"
]
]
},
{
"id": "cdac3ef9.0af12",
"type": "ui_chart",
"z": "206db361.104f6c",
"name": "",
"group": "885e2c54.00ba2",
"order": 0,
"width": 0,
"height": 0,
"label": "input frame interval",
"chartType": "line",
"legend": "false",
"xformat": "HH:mm:ss",
"interpolate": "linear",
"nodata": "",
"dot": false,
"ymin": "0",
"ymax": "200",
"removeOlder": 1,
"removeOlderPoints": "100",
"removeOlderUnit": "3600",
"cutout": 0,
"useOneColor": false,
"colors": [
"#1f77b4",
"#aec7e8",
"#ff7f0e",
"#2ca02c",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"useOldStyle": false,
"x": 550,
"y": 600,
"wires": [
[],
[]
]
},
{
"id": "c009d2e.0a6e53",
"type": "ui_chart",
"z": "206db361.104f6c",
"name": "",
"group": "885e2c54.00ba2",
"order": 0,
"width": 0,
"height": 0,
"label": "output frame interval",
"chartType": "line",
"legend": "false",
"xformat": "HH:mm:ss",
"interpolate": "linear",
"nodata": "",
"dot": false,
"ymin": "0",
"ymax": "200",
"removeOlder": 1,
"removeOlderPoints": "100",
"removeOlderUnit": "3600",
"cutout": 0,
"useOneColor": false,
"colors": [
"#1f77b4",
"#aec7e8",
"#ff7f0e",
"#2ca02c",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"useOldStyle": false,
"x": 560,
"y": 640,
"wires": [
[],
[]
]
},
{
"id": "29e1f9ae.9fd666",
"type": "debug",
"z": "206db361.104f6c",
"name": "Times Debug",
"active": false,
"console": "false",
"complete": "true",
"x": 830,
"y": 580,
"wires": []
},
{
"id": "48f00ccf.f884d4",
"type": "function",
"z": "206db361.104f6c",
"name": "store frame",
"func": "var frames = flow.get('frames') || {num:0, frames:[]};\n\nvar time_in = (new Date()).valueOf();\nvar frame = { \n jpeg: msg.payload, \n times:{time_in:time_in}, \n num:frames.num++, \n images:{},\n imagesasync:{},\n \n};\n\nif (frames.frames.length < 20){\n frames.frames.push(frame);\n} else {\n frames.dropped = (frames.dropped || 0)+1;\n}\n\nvar now = (new Date).valueOf();\ncontext.laststatus = context.laststatus || now;\ncontext.framesavg = (context.framesavg || 0)*0.9 + frames.frames.length*0.1;\n\nif (now > context.laststatus + 1000){\n var colour = (frames.frames.length > 6)?\"red\":\"green\";\n node.status({fill:colour,shape:\"dot\",text:\"frames:\"+frames.frames.length+\":\"+((context.framesavg*100)>>0)/100+\" dropped:\"+frames.dropped});\n context.laststatus = now;\n}\nreturn {};",
"outputs": 1,
"noerr": 0,
"x": 690,
"y": 100,
"wires": [
[]
]
},
{
"id": "665cd6ef.d92a48",
"type": "function",
"z": "206db361.104f6c",
"name": "delete frames",
"func": "var frames = flow.get('frames') || {num:0, frames:[]};\n\nif (frames.deleteall){\n frames.deleteall();\n}\n\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 280,
"y": 160,
"wires": [
[
"c1e3392c.7efcd8"
]
]
},
{
"id": "4df83085.be935",
"type": "inject",
"z": "206db361.104f6c",
"name": "0.03s",
"topic": "",
"payload": "",
"payloadType": "date",
"repeat": "0.03",
"crontab": "",
"once": false,
"x": 90,
"y": 540,
"wires": [
[
"9e8131d2.32452"
]
]
},
{
"id": "5da40cc0.d41804",
"type": "function",
"z": "206db361.104f6c",
"name": "start jpeg decode",
"func": "var frames = flow.get('frames') || {num:0, frames:[]};\n\n\nvar framecount = frames.frames.length;\nfor (var i = 0; i < framecount; i++ ){\n if (frames.frames[i].jpeg){\n var f = frames.frames[i];\n var cv = flow.get('cv');\n f.times.jpegdecodestart = (new Date()).valueOf();\n var jpeg = f.jpeg;\n delete f.jpeg;\n \n //node.warn(\"payload len \"+msg.payload.length);\n cv.readImageAsync( jpeg, function(err, mat){ \n try{\n f.jpeg = null;\n f.times.jpegdecodeend = (new Date()).valueOf();\n \n f.times.jpegdecodedur = (f.times.jpegdecodeend - f.times.jpegdecodestart);\n\n if (err){\n node.warn(err);\n return;\n }\n if (mat.width() === 0){\n node.warn(\"Matrix width = \" + mat.width() + \" and height = \" + mat.height() + \" nextframe \" + nextframe);\n return; \n }\n \n if (frames.frameinlist(f)){\n //console.log(\"jpegdecodedone \"+i);\n f.images.jpegdecoded = mat;\n } else {\n mat.release();\n console.log(\"jpegdecodeignored \"+i);\n }\n } catch (e){\n console.log(e);\n }\n });\n break;\n }\n}\n\nreturn msg;\n",
"outputs": 1,
"noerr": 0,
"x": 390,
"y": 280,
"wires": [
[]
]
},
{
"id": "3caf2bc8.90dcd4",
"type": "function",
"z": "206db361.104f6c",
"name": "start resize",
"func": "var frames = flow.get('frames') || {num:0, frames:[]};\n\n\nvar framecount = frames.frames.length;\nfor (var i = 0; i < framecount; i++ ){\n var f = frames.frames[i];\n\n if (f.images){\n if (f.images.jpegdecoded){\n var img = f.images.jpegdecoded;\n delete f.images.jpegdecoded;\n f.imagesasync.jpegdecoded = img;\n var cv = flow.get('cv');\n f.times.resizestart = (new Date()).valueOf();\n img.resize(\n flow.get('width'), \n flow.get('height'), \n function(err, mat){\n f.times.resizeend = (new Date()).valueOf();\n f.times.resizedur = (f.times.resizeend - f.times.resizestart);\n if (frames.frameinlist(f)){\n f.images.resized = mat;\n //console.log(\"rezise done \"+ i);\n } else {\n //console.log(\"rezise lost \"+ i);\n mat.release();\n }\n }\n );\n break;\n }\n }\n}\n\nreturn msg;\n",
"outputs": 1,
"noerr": 0,
"x": 370,
"y": 320,
"wires": [
[]
]
},
{
"id": "eda5d1d7.740f7",
"type": "function",
"z": "206db361.104f6c",
"name": "start bgsubtract",
"func": "var frames = flow.get('frames') || {num:0, frames:[]};\n\n \n\nvar framecount = frames.frames.length;\nfor (var i = 0; i < framecount; i++ ){\n var f = frames.frames[i];\n\n if (f.images){\n if (f.images.resized){\n var cv = flow.get('cv');\n var bg = flow.get('bg');\n f.times.bgstart = (new Date()).valueOf();\n f.imagesasync.resized = f.images.resized;\n delete f.images.resized;\n \n bg.apply(f.imagesasync.resized, function(err, mat){\n f.times.bgend = (new Date()).valueOf();\n f.times.bgdur = (f.times.bgend - f.times.bgstart);\n if (frames.frameinlist(f)){\n f.images.background = mat;\n } else {\n mat.release();\n }\n });\n break;\n }\n }\n}\n\nreturn msg;\n",
"outputs": 1,
"noerr": 0,
"x": 380,
"y": 360,
"wires": [
[]
]
},
{
"id": "5716bbe7.2c8f54",
"type": "function",
"z": "206db361.104f6c",
"name": "GetContours",
"func": "var frames = flow.get('frames') || {num:0, frames:[]};\n\n \n\nvar framecount = frames.frames.length;\nfor (var i = 0; i < framecount; i++ ){\n var f = frames.frames[i];\n\n if (f.images){\n if (f.images.background){\n var cv = flow.get('cv');\n f.imagesasync.background = f.images.background;\n delete f.images.background;\n\n f.times.countoursstart = (new Date()).valueOf();\n // sync!!!\n f.contours = f.imagesasync.background.findContours(\n cv.RETR_EXTERNAL, \n cv.CHAIN_APPROX_SIMPLE);\n f.times.countoursend = (new Date()).valueOf();\n f.times.countoursdur = (f.times.countoursend - f.times.countoursstart);\n break;\n }\n }\n}\n\nreturn msg;",
"outputs": "1",
"noerr": 0,
"x": 390,
"y": 400,
"wires": [
[]
]
},
{
"id": "52e94483.5bda0c",
"type": "function",
"z": "206db361.104f6c",
"name": "DrawBoxes",
"func": "var frames = flow.get('frames') || {num:0, frames:[]};\n\n \n\nvar framecount = frames.frames.length;\nfor (var i = 0; i < framecount; i++ ){\n var f = frames.frames[i];\n\n if (frames.frames[i].images){\n if (f.imagesasync.jpegdecoded && \n f.imagesasync.background && \n f.contours){\n var cv = flow.get('cv');\n f.contoursdone = f.contours;\n delete f.contours;\n \n var requiredarea = flow.get('area');\n\n f.times.boxesstart = (new Date()).valueOf();\n // sync!!!\n var cnts = f.contoursdone;\n var numcnts = cnts.size();\n var camera = f.imagesasync.jpegdecoded;\n var out = f.imagesasync.background;\n \n if (numcnts){\n var scalex = camera.width()/out.width();\n var scaley = camera.height()/out.height();\n \n var areas = [];\n for (var c = 0; c < numcnts; c++){\n var area = { area:cnts.area(c), index:c };\n areas.push(area);\n }\n var fn = function(a, b){\n return (b.area - a.area);\n }\n areas.sort(fn);\n //node.warn(numcnts + ' ' + util.inspect(areas)); \n \n // draw only the three biggest\n for (var i = 0; ((i < 3) && (i < numcnts)); i++){\n var c = areas[i].index;\n //node.error(areas[i].index + ' '+areas[i].area);\n if (areas[i].area > requiredarea){\n var bounding = cnts.boundingRect(c);\n //node.error(bounding);\n \n // draw onto original camera image\n camera.rectangle([bounding.x*scalex, bounding.y*scaley], [bounding.width*scalex, bounding.height*scaley], [0, 0, 255], 2);\n movementfound = true;\n }\n }\n }\n \n f.times.boxesend = (new Date()).valueOf();\n f.times.boxesdur = (f.times.boxesend - f.times.boxesstart);\n f.images.boxed = f.imagesasync.jpegdecoded;\n delete f.imagesasync.jpegdecoded;\n break;\n }\n }\n}\n\nreturn msg;",
"outputs": "1",
"noerr": 0,
"x": 391,
"y": 439,
"wires": [
[]
]
},
{
"id": "6e4f4959.09b818",
"type": "function",
"z": "206db361.104f6c",
"name": "jpegencode",
"func": "var frames = flow.get('frames') || {num:0, frames:[]};\n\n \n\nvar framecount = frames.frames.length;\nfor (var i = 0; i < framecount; i++ ){\n\n if (frames.frames[i].images){\n var tosend = 'boxed';\n \n var img = frames.frames[i].images[tosend];\n delete frames.frames[i].images[tosend];\n frames.frames[i].imagesasync[tosend] = img;\n \n if (img){\n var f = frames.frames[i];\n var cv = flow.get('cv');\n\n f.times.encstart = (new Date()).valueOf();\n \n img.toBuffer(function(err, data){\n var newmsg = {\n payload: data,\n time_in: msg.time_in,\n framenumber: msg.framenumber\n };\n f.times.encend = (new Date()).valueOf();\n f.times.encdur = (f.times.encend - f.times.encstart);\n\n if (frames.frameinlist(f)){\n f.jpegout = data;\n } else {\n }\n img.release();\n });\n break;\n }\n }\n}\n\nreturn msg;",
"outputs": "1",
"noerr": 0,
"x": 390,
"y": 480,
"wires": [
[]
]
},
{
"id": "a53386bf.3b8428",
"type": "function",
"z": "206db361.104f6c",
"name": "send",
"func": "var frames = flow.get('frames') || {num:0, frames:[]};\n\nvar framecount = frames.frames.length;\n\nif ((framecount > 0) && (frames.frames[0].jpegout)){\n var f = frames.frames[0];\n msg.payload = f.jpegout;\n delete f.jpegout;\n f.times.time_out = (new Date()).valueOf();\n f.times.time_dur = f.times.time_out - f.times.time_in;\n var newmsg = {\n payload:f.times\n };\n frames.droplast();\n node.send([msg, null] )\n node.send([null, newmsg]);\n}\n\nreturn;",
"outputs": "2",
"noerr": 0,
"x": 373,
"y": 531,
"wires": [
[
"93a1fe0d.f9a4c"
],
[
"29e1f9ae.9fd666"
]
],
"outputLabels": [
"",
"times"
]
},
{
"id": "fd773c61.352ad",
"type": "function",
"z": "206db361.104f6c",
"name": "",
"func": "\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 120,
"y": 380,
"wires": [
[
"5da40cc0.d41804",
"5716bbe7.2c8f54",
"52e94483.5bda0c",
"6e4f4959.09b818",
"3caf2bc8.90dcd4",
"eda5d1d7.740f7"
]
]
},
{
"id": "df44ea76.b9e398",
"type": "function",
"z": "206db361.104f6c",
"name": "GetFramesDebug",
"func": "msg.payload = flow.get('frames');\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 670,
"y": 340,
"wires": [
[
"23e92d17.b82962"
]
]
},
{
"id": "696b436d.ffbd2c",
"type": "inject",
"z": "206db361.104f6c",
"name": "",
"topic": "",
"payload": "",
"payloadType": "date",
"repeat": "",
"crontab": "",
"once": false,
"x": 620,
"y": 300,
"wires": [
[
"df44ea76.b9e398"
]
]
},
{
"id": "23e92d17.b82962",
"type": "debug",
"z": "206db361.104f6c",
"name": "",
"active": false,
"console": "false",
"complete": "false",
"x": 630,
"y": 380,
"wires": []
},
{
"id": "1184b364.17f0dd",
"type": "function",
"z": "206db361.104f6c",
"name": "output FPS timing",
"func": "context.lasttime = context.lasttime || (new Date()).valueOf();\n\nvar now = (new Date()).valueOf();\n\nvar diff = now - context.last;\ncontext.last = now;\n\ncontext.diff = diff;\ncontext.avg = context.avg || diff;\n\ncontext.avg *= 0.995;\ncontext.avg += diff*0.005;\n\ncontext.FPS = 1000/context.diff;\ncontext.FPSavg = 1000/context.avg;\n\nflow.set(\"outputfps\", {fps:context.diff, fpsavg:context.avg});\n\nreturn;",
"outputs": 1,
"noerr": 0,
"x": 810,
"y": 460,
"wires": [
[]
]
},
{
"id": "9e8131d2.32452",
"type": "function",
"z": "206db361.104f6c",
"name": "",
"func": "node.send([msg, null]);\nnode.send([null, msg]);\n",
"outputs": "2",
"noerr": 0,
"x": 110,
"y": 460,
"wires": [
[
"a53386bf.3b8428"
],
[
"fd773c61.352ad"
]
]
},
{
"id": "5a214438.de4a3c",
"type": "function",
"z": "206db361.104f6c",
"name": "",
"func": "node.send([msg, null]);\nnode.send([null, msg]);\n",
"outputs": "2",
"noerr": 0,
"x": 610,
"y": 480,
"wires": [
[
"bfc1b46b.e41858"
],
[
"1184b364.17f0dd"
]
]
},
{
"id": "74537121.4081b",
"type": "function",
"z": "206db361.104f6c",
"name": "'input to encoder' timing",
"func": "context.lasttime = context.lasttime || (new Date()).valueOf();\n\nvar now = (new Date()).valueOf();\n\nvar diff = now - context.last;\ncontext.last = now;\n\ncontext.diff = diff;\ncontext.avg = context.avg || diff;\n\ncontext.avg *= 0.995;\ncontext.avg += diff*0.005;\n\ncontext.FPS = 1000/context.diff;\ncontext.FPSavg = 1000/context.avg;\n\nflow.set(\"output2fps\", {fps:context.diff, fpsavg:context.avg});\n\nreturn;",
"outputs": 1,
"noerr": 0,
"x": 790,
"y": 420,
"wires": [
[]
]
},
{
"id": "93a1fe0d.f9a4c",
"type": "function",
"z": "206db361.104f6c",
"name": "",
"func": "node.send([msg, null]);\nnode.send([null, msg]);\n",
"outputs": "2",
"noerr": 0,
"x": 590,
"y": 440,
"wires": [
[
"74537121.4081b"
],
[
"5a214438.de4a3c"
]
]
},
{
"id": "c2a7176a.0bec78",
"type": "ui_chart",
"z": "206db361.104f6c",
"name": "",
"group": "885e2c54.00ba2",
"order": 0,
"width": 0,
"height": 0,
"label": "input to encoder frame interval",
"chartType": "line",
"legend": "false",
"xformat": "HH:mm:ss",
"interpolate": "linear",
"nodata": "",
"dot": false,
"ymin": "0",
"ymax": "200",
"removeOlder": 1,
"removeOlderPoints": "100",
"removeOlderUnit": "3600",
"cutout": 0,
"useOneColor": false,
"colors": [
"#1f77b4",
"#aec7e8",
"#ff7f0e",
"#2ca02c",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"useOldStyle": false,
"x": 590,
"y": 680,
"wires": [
[],
[]
]
},
{
"id": "885e2c54.00ba2",
"type": "ui_group",
"z": "",
"name": "Default",
"tab": "55e1e9cf.f824a8",
"disp": true,
"width": "6"
},
{
"id": "55e1e9cf.f824a8",
"type": "ui_tab",
"z": "",
"name": "new",
"icon": "dashboard"
}
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment