node-red-node-ui-webcam
Advanced tools
+1
-1
| { | ||
| "name": "node-red-node-ui-webcam", | ||
| "version": "0.1.1", | ||
| "version": "0.2.0", | ||
| "description": "A Node-RED ui node to capture images from a webcam.", | ||
@@ -5,0 +5,0 @@ "author": "Nick O'Leary", |
+70
-6
@@ -36,2 +36,4 @@ <!-- | ||
| autoStart: { value: false }, | ||
| hideCaptureButton: { value: false }, | ||
| showImage: { value: 2 }, | ||
| format: { value:"png" } | ||
@@ -55,8 +57,51 @@ }, | ||
| }); | ||
| var showImage = this.showImage === undefined ? 2 : this.showImage; | ||
| if (showImage === 0) { | ||
| // Show image without clearing | ||
| $("#node-input-showImage-enable").attr("checked",true) | ||
| $("#node-input-showImage-timeout").attr("checked",false) | ||
| $("#node-input-showImage-time").val("2") | ||
| } else if (showImage === -1) { | ||
| // Don't show image | ||
| $("#node-input-showImage-enable").attr("checked",false) | ||
| $("#node-input-showImage-timeout").attr("checked",false) | ||
| $("#node-input-showImage-time").val("2") | ||
| } else { | ||
| // Show image with clear | ||
| $("#node-input-showImage-enable").attr("checked",true) | ||
| $("#node-input-showImage-timeout").attr("checked",true) | ||
| $("#node-input-showImage-time").val(showImage) | ||
| } | ||
| $("#node-input-showImage-enable").on("change", function() { | ||
| $("#node-input-showImage-timeout").attr("disabled",!this.checked) | ||
| if (!this.checked) { | ||
| $(".node-row-ui-webcam-showImage-timeout").css("opacity",0.6); | ||
| $("#node-input-showImage-time").attr("disabled",true) | ||
| } else { | ||
| $("#node-input-showImage-time").attr("disabled",!$("#node-input-showImage-timeout")[0].checked) | ||
| $(".node-row-ui-webcam-showImage-timeout").css("opacity",1); | ||
| } | ||
| }) | ||
| $("#node-input-showImage-timeout").on("change", function() { | ||
| $("#node-input-showImage-time").attr("disabled",!this.checked) | ||
| }) | ||
| $("#node-input-showImage-enable").trigger("change"); | ||
| }, | ||
| oneditsave: function() { | ||
| // var ts = $("#node-input-select-timeslice").val(); | ||
| // if (ts === 'once') { | ||
| // $("#node-input-timeslice").val("") | ||
| // } | ||
| var showImageEnable = $("#node-input-showImage-enable")[0].checked; | ||
| var showImageTimeout = $("#node-input-showImage-timeout")[0].checked; | ||
| var showImageTime = $("#node-input-showImage-time").val(); | ||
| if (!showImageEnable) { | ||
| this.showImage = -1; | ||
| } else if (!showImageTimeout) { | ||
| this.showImage = 0; | ||
| } else { | ||
| this.showImage = showImageTime; | ||
| } | ||
| } | ||
@@ -66,3 +111,3 @@ }); | ||
| <script type="text/x-red" data-template-name="ui_webcam"> | ||
| <script type="text/html" data-template-name="ui_webcam"> | ||
| <div class="form-row" id="template-row-group"> | ||
@@ -88,2 +133,17 @@ <label for="node-input-group"><i class="fa fa-table"></i> Group</span></label> | ||
| <div class="form-row"> | ||
| <label style="width: auto" for="node-input-showImage-enable"> | ||
| <input style="width:auto; margin: 0" type="checkbox" id="node-input-showImage-enable"> Show image after capture | ||
| </label> | ||
| <div class="node-row-ui-webcam-showImage-timeout"> | ||
| <label style="margin-bottom: 0; margin-left: 20px; width: auto" for="node-input-showImage-timeout"> | ||
| <input style="width:auto; margin: 0" type="checkbox" id="node-input-showImage-timeout"> Clear image after <input style="width:60px; margin: 0" type="text" id="node-input-showImage-time"> seconds | ||
| </label> | ||
| </div> | ||
| </div> | ||
| <div class="form-row"> | ||
| <label style="width: auto" for="node-input-hideCaptureButton"> | ||
| <input style="width:auto; margin: 0" type="checkbox" id="node-input-hideCaptureButton"> Hide capture button | ||
| </label> | ||
| </div> | ||
| <div class="form-row"> | ||
| <label style="width: auto" for="node-input-countdown"> | ||
@@ -109,6 +169,10 @@ <input style="width:auto; margin: 0" type="checkbox" id="node-input-countdown"> Use 5 second countdown when triggered | ||
| <script type="text/x-red" data-help-name="ui_webcam"> | ||
| <script type="text/html" data-help-name="ui_webcam"> | ||
| <p>A Node Red dashboard ui node to capture images from the browser's webcam.</p> | ||
| <h3>Inputs</h3> | ||
| <dl class="message-properties"> | ||
| <dt>payload<span class="property-type">Buffer | Boolean</span></dt> | ||
| <dd>If set to a Buffer containing an image, it will be displayed in | ||
| the place of the webcam view on the dashboard. If set to <code>null</code> | ||
| or <code>false</code>, the displayed image will be cleared.</dd> | ||
| <dt>capture</dt> | ||
@@ -115,0 +179,0 @@ <dd>If set, this will trigger the webcam to capture an image. The webcam must |
+43
-5
@@ -154,2 +154,5 @@ /** | ||
| beforeEmit: function(msg) { | ||
| if (Buffer.isBuffer(msg.payload)) { | ||
| msg.payload = msg.payload.toString('base64'); | ||
| } | ||
| return { msg: msg }; | ||
@@ -159,4 +162,9 @@ }, | ||
| if (orig) { | ||
| // if (orig.msg.status) { | ||
| // node.status(orig.msg.status); | ||
| // return null; | ||
| // } | ||
| var urlPreamble = "data:image/"+(config.format||"png")+";base64,"; | ||
| orig.msg.payload = Buffer.from(orig.msg.payload.substring(urlPreamble.length),'base64') | ||
| delete orig.msg.capture; | ||
| return orig.msg; | ||
@@ -179,2 +187,16 @@ } | ||
| $scope.config = config; | ||
| if ($scope.config.showImage === undefined) { | ||
| $scope.config.showImageTimeout = 2000; | ||
| $scope.config.showImage = true; | ||
| } else if ($scope.config.showImage === -1) { | ||
| $scope.config.showImage = false; | ||
| } else { | ||
| $scope.config.showImageTimeout = parseFloat($scope.config.showImage)*1000; | ||
| $scope.config.showImage = true; | ||
| } | ||
| if ($scope.config.hideCaptureButton) { | ||
| setTimeout(function() { | ||
| $("#ui_webcam_btn_trigger_"+$scope.$id).hide(); | ||
| },100); | ||
| } | ||
| if ($scope.config.autoStart) { | ||
@@ -195,2 +217,4 @@ setTimeout(function() { | ||
| $scope.changeCamera = function(deviceId) { | ||
@@ -246,2 +270,3 @@ oldActiveCamera = activeCamera; | ||
| navigator.mediaDevices.getUserMedia(constraint).then(function(stream) { | ||
| // $scope.send({status:{shape:"dot",fill:"green",text:"active"}}) | ||
| $("#webcam_"+$scope.$id).addClass("active") | ||
@@ -271,3 +296,3 @@ var playbackEl = document.querySelector("video#ui_webcam_playback_"+$scope.$id); | ||
| playbackEl.srcObject = null; | ||
| // $scope.send({status:{shape:"ring",fill:"red",text:"inactive"}}) | ||
| active = false; | ||
@@ -312,6 +337,10 @@ $("#ui_webcam_btn_enable_"+$scope.$id).show(); | ||
| img.src = canvas.toDataURL('image/'+($scope.config.format||'png')); | ||
| img.style.display = "block"; | ||
| setTimeout(function() { | ||
| img.style.display = "none"; | ||
| },2000); | ||
| if ($scope.config.showImage) { | ||
| img.style.display = "block"; | ||
| if ($scope.config.showImageTimeout) { | ||
| activeTimeout = setTimeout(function() { | ||
| img.style.display = "none"; | ||
| },$scope.config.showImageTimeout); | ||
| } | ||
| } | ||
| return img.src; | ||
@@ -354,5 +383,14 @@ } | ||
| } | ||
| var img = document.querySelector("img#ui_webcam_image_"+$scope.$id); | ||
| if (msg.capture) { | ||
| msg.payload = takePhoto(); | ||
| $scope.send(msg); | ||
| } else if (typeof msg.payload === 'string') { | ||
| clearTimeout(activeTimeout); | ||
| if (msg.payload === "") { | ||
| img.style.display = "none"; | ||
| } else { | ||
| img.src = "data:image/"+($scope.config.format||"png")+";base64,"+msg.payload; | ||
| img.style.display = "block"; | ||
| } | ||
| } | ||
@@ -359,0 +397,0 @@ }); |
40340
16.92%382
10.72%