Skip to content

Commit

Permalink
[webcam] Add show image timeout and hide button options
Browse files Browse the repository at this point in the history
  • Loading branch information
knolleary committed Oct 21, 2020
1 parent 241f0a0 commit a4267f5
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 12 deletions.
2 changes: 1 addition & 1 deletion node-red-node-ui-webcam/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"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.",
"author": "Nick O'Leary",
"license": "Apache-2.0",
Expand Down
76 changes: 70 additions & 6 deletions node-red-node-ui-webcam/ui_webcam.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
name: {value: ''},
countdown: { value: false },
autoStart: { value: false },
hideCaptureButton: { value: false },
showImage: { value: 2 },
format: { value:"png" }
},
inputs:1,
Expand All @@ -51,17 +53,60 @@
height: "#node-input-height",
group: "#node-input-group"
});

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;
}

}
});
</script>

<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">
<label for="node-input-group"><i class="fa fa-table"></i> Group</span></label>
<input type="text" id="node-input-group">
Expand All @@ -81,6 +126,21 @@
<input style="width:auto; margin: 0" type="checkbox" id="node-input-autoStart"> Start webcam automatically
</label>
</div>
<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">
<input style="width:auto; margin: 0" type="checkbox" id="node-input-countdown"> Use 5 second countdown when triggered
Expand All @@ -102,10 +162,14 @@
</div>
</script>

<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>
<dd>If set, this will trigger the webcam to capture an image. The webcam must
have been activated on the dashboard first.</dd>
Expand Down
48 changes: 43 additions & 5 deletions node-red-node-ui-webcam/ui_webcam.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,20 @@ module.exports = function(RED) {
return value;
},
beforeEmit: function(msg) {
if (Buffer.isBuffer(msg.payload)) {
msg.payload = msg.payload.toString('base64');
}
return { msg: msg };
},
beforeSend: function (msg, orig) {
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;
}
},
Expand All @@ -174,6 +182,20 @@ module.exports = function(RED) {
$scope.init = function (config) {
// console.log("ui_webcam: initialised config:",config);
$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) {
setTimeout(function() {
$scope.enableCamera();
Expand All @@ -189,6 +211,8 @@ module.exports = function(RED) {
var activeCamera = null;
var oldActiveCamera = null;



$scope.changeCamera = function(deviceId) {
oldActiveCamera = activeCamera;
activeCamera = $scope.data.cameras[deviceId].deviceId;
Expand Down Expand Up @@ -239,6 +263,7 @@ module.exports = function(RED) {
}

navigator.mediaDevices.getUserMedia(constraint).then(function(stream) {
// $scope.send({status:{shape:"dot",fill:"green",text:"active"}})
$("#webcam_"+$scope.$id).addClass("active")
var playbackEl = document.querySelector("video#ui_webcam_playback_"+$scope.$id);
playbackEl.srcObject = stream;
Expand All @@ -263,7 +288,7 @@ module.exports = function(RED) {
stopActiveTracks();
var playbackEl = document.querySelector("video#ui_webcam_playback_"+$scope.$id);
playbackEl.srcObject = null;

// $scope.send({status:{shape:"ring",fill:"red",text:"inactive"}})
active = false;
$("#ui_webcam_btn_enable_"+$scope.$id).show();
$("#ui_webcam_toolbar_"+$scope.$id).hide();
Expand Down Expand Up @@ -303,10 +328,14 @@ module.exports = function(RED) {
canvas.getContext('2d').drawImage(playbackEl, 0, 0);
var img = document.querySelector("img#ui_webcam_image_"+$scope.$id);
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;
}

Expand Down Expand Up @@ -344,9 +373,18 @@ module.exports = function(RED) {
if (!active) {
return;
}
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";
}
}
});
}
Expand Down

0 comments on commit a4267f5

Please sign in to comment.