этом вопросе, в узле шаблона.
На данный момент мне удается реализовать этот код в Node-Red, и он работает на ПК Chrome. Chrome просит меня включить камеру для панели управления, и если я позволю, я смогу просмотреть вывод камеры. Но когда я пытаюсь использовать ту же панель управления на iPhone Safari, я не вижу дисплея камеры. Он даже не спрашивает моего разрешения на использование камеры. Что я делаю не так?
Ниже показан экспортированный поток Node-Red, который я создал на данный момент.
Спасибо.
[
{
"id": "c911c322aad92eb4",
"type": "tab",
"label": "Flow 1",
"disabled": false,
"info": "",
"env": []
},
{
"id": "cf18f162c725eabc",
"type": "ui-base",
"name": "My Dashboard1",
"path": "/dashboard",
"includeClientData": true,
"acceptsClientConfig": [
"ui-notification",
"ui-control"
],
"showPathInSidebar": false,
"navigationStyle": "default"
},
{
"id": "f33b4cc2097266ae",
"type": "ui-theme",
"name": "Default Theme",
"colors": {
"surface": "#ffffff",
"primary": "#0094CE",
"bgPage": "#eeeeee",
"groupBg": "#ffffff",
"groupOutline": "#cccccc"
},
"sizes": {
"pagePadding": "12px",
"groupGap": "12px",
"groupBorderRadius": "4px",
"widgetGap": "12px"
}
},
{
"id": "e2669f7ebdf6c137",
"type": "ui-page",
"name": "Page N",
"ui": "cf18f162c725eabc",
"path": "/pageN",
"icon": "home",
"layout": "grid",
"theme": "f33b4cc2097266ae",
"order": -1,
"className": "",
"visible": "true",
"disabled": "false"
},
{
"id": "e6e8fb22f71d7392",
"type": "ui-group",
"name": "My Group",
"page": "e2669f7ebdf6c137",
"width": 6,
"height": 1,
"order": -1,
"showTitle": true,
"className": "",
"visible": true,
"disabled": false
},
{
"id": "3afec64dc18d92b8",
"type": "ui-group",
"name": "Group Name",
"page": "e2669f7ebdf6c137",
"width": "6",
"height": "1",
"order": -1,
"showTitle": true,
"className": "",
"visible": "true",
"disabled": "false"
},
{
"id": "167a8a7d56b7f4e7",
"type": "ui-template",
"z": "c911c322aad92eb4",
"group": "e6e8fb22f71d7392",
"page": "",
"ui": "",
"name": "iOS Camera Access",
"order": 0,
"width": 0,
"height": 0,
"head": "",
"format": "\n\n\n\n\n\n \n Get User Media Code Along!\n \n\n\n\n\n \n \n Take Photo\n \n \n\n \n \n \n \n\n \n\n \n\n\n\n\n\n\n\n\n export default {\n data() {\n // define variables available component-wide\n // (in and component functions)\n \n },\n watch: {\n // watch for any changes of \"count\"\n \n },\n computed: {\n // automatically compute this variable\n // whenever VueJS deems appropriate\n \n },\n methods: {\n // expose a method to our and Vue Application\n increase: function () {\n this.count++\n },\n takePhoto: function () {\n // played the sound\n snap.currentTime = 0;\n snap.play();\n \n // take the data out of the canvas\n const data = canvas.toDataURL('image/jpeg');\n const link = document.createElement('a');\n link.href = data;\n link.setAttribute('download', 'handsome');\n link.innerHTML = `
`;\n strip.insertBefore(link, strip.firstChild);\n }\n\n },\n mounted() {\n // code here when the component is first loaded\n\n const video = document.querySelector('.player');\n const canvas = document.querySelector('.photo');\n const ctx = canvas.getContext('2d');\n const strip = document.querySelector('.strip');\n const snap = document.querySelector('.snap');\n\n // Fix for iOS Safari from https://leemartin.dev/hello-webrtc-on-s ... b5335295\n video.setAttribute('autoplay', '');\n video.setAttribute('muted', '');\n video.setAttribute('playsinline', '')\n\n const constraints = {\n audio: false,\n video: {\n facingMode: 'user'\n }\n }\n\n function getVideo() {\n navigator.mediaDevices.getUserMedia(constraints)\n .then(localMediaStream => {\n console.log(localMediaStream);\n \n // DEPRECIATION : \n // The following has been depreceated by major browsers as of Chrome and Firefox.\n // video.src = window.URL.createObjectURL(localMediaStream);\n // Please refer to these:\n // Deprecated - https://developer.mozilla.org/en-US/doc ... bjectURL\n // Newer Syntax - https://developer.mozilla.org/en-US/doc ... rcObject\n console.dir(video);\n if ('srcObject' in video) {\n video.srcObject = localMediaStream;\n } else {\n video.src = URL.createObjectURL(localMediaStream);\n }\n // video.src = window.URL.createObjectURL(localMediaStream);\n video.play();\n })\n .catch(err => {\n console.error(`OH NO!!!!`, err);\n });\n }\n\n function paintToCanvas() {\n const width = video.videoWidth;\n const height = video.videoHeight;\n canvas.width = width;\n canvas.height = height;\n\n return setInterval(() => {\n ctx.drawImage(video, 0, 0, width, height);\n // take the pixels out\n // let pixels = ctx.getImageData(0, 0, width, height);\n // mess with them\n // pixels = redEffect(pixels);\n\n // pixels = rgbSplit(pixels);\n // ctx.globalAlpha = 0.8;\n\n // pixels = greenScreen(pixels);\n // put them back\n // ctx.putImageData(pixels, 0, 0);\n }, 16);\n }\n\n \n\n function redEffect(pixels) {\n for (let i = 0; i < pixels.data.length; i+=4) {\n pixels.data[i + 0] = pixels.data[i + 0] + 200; // RED\n pixels.data[i + 1] = pixels.data[i + 1] - 50; // GREEN\n pixels.data[i + 2] = pixels.data[i + 2] * 0.5; // Blue\n }\n return pixels;\n }\n\n function rgbSplit(pixels) {\n for (let i = 0; i < pixels.data.length; i+=4) {\n pixels.data = pixels.data[i + 0]; // RED\n pixels.data[i + 500] = pixels.data[i + 1]; // GREEN\n pixels.data = pixels.data[i + 2]; // Blue\n }\n return pixels;\n }\n\n function greenScreen(pixels) {\n const levels = {};\n\n document.querySelectorAll('.rgb input').forEach((input) => {\n levels[input.name] = input.value;\n });\n\n for (i = 0; i < pixels.data.length; i = i + 4) {\n red = pixels.data[i + 0];\n green = pixels.data[i + 1];\n blue = pixels.data[i + 2];\n alpha = pixels.data[i + 3];\n\n if (red >= levels.rmin\n && green >= levels.gmin\n && blue >= levels.bmin\n && red
Подробнее здесь: https://stackoverflow.com/questions/783 ... hboard-2-0