diff --git a/package-lock.json b/package-lock.json index 39dda02..359317b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -161,6 +161,22 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "@julusian/freetype2": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@julusian/freetype2/-/freetype2-1.1.0.tgz", + "integrity": "sha512-LR2mNGiLDQfF7HbwIQYhZvzyyu116U0rztB2ASJh7AvC4cncozISRXvPhE3YyCTcJDTwgA3FEBu0FBcQsPjnqw==", + "requires": { + "node-addon-api": "^5.0.0", + "pkg-prebuilds": "^0.1.0" + }, + "dependencies": { + "node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" + } + } + }, "@malept/cross-spawn-promise": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", @@ -554,17 +570,20 @@ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true }, + "alawmulaw": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/alawmulaw/-/alawmulaw-5.0.2.tgz", + "integrity": "sha512-W3bWBB7MwTNGALlAKbOxe+tMNW9DpqGsv1V1idGPzctnBH++eS+Dx3UuucHNe5nk38WvAuy0sgMAbS5idHCArw==" + }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -1240,10 +1259,22 @@ "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", "dev": true }, - "atem": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/atem/-/atem-0.1.8.tgz", - "integrity": "sha512-2epXH22+aJ8uy46A4A184lexklj2A/Uo+kHYOgne1KD38KoVGZwlrRB+N5liPR/Jes9JhtzVISHW2DuDju1bOg==" + "atem-connection": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/atem-connection/-/atem-connection-3.1.3.tgz", + "integrity": "sha512-W3R4CR2kL/juKB409PSOimzGGfX7ZkRfYMIAHmN+bwep6Alwcw1ch7eMLSwRfOJKZsPXc0gEScq+0Dn6ERkeiw==", + "requires": { + "@julusian/freetype2": "^1.1.0", + "debug": "^4.3.4", + "eventemitter3": "^4.0.7", + "exit-hook": "^2.2.1", + "nanotimer": "^0.3.15", + "p-lazy": "^3.1.0", + "p-queue": "^6.6.2", + "threadedclass": "^1.1.1", + "tslib": "^2.3.1", + "wavefile": "^8.4.4" + } }, "available-typed-arrays": { "version": "1.0.5", @@ -1257,12 +1288,22 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "base64-arraybuffer-es6": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/base64-arraybuffer-es6/-/base64-arraybuffer-es6-0.3.1.tgz", + "integrity": "sha512-TrhBheudYaff9adiTAqjSScjvtmClQ4vF9l4cqkPNkVsA11m4/NRdH4LkZ/tAMmpzzwfI20BXnJ/PTtafECCNA==" + }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true }, + "bitdepth": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/bitdepth/-/bitdepth-7.0.2.tgz", + "integrity": "sha512-Ed11TL4IIWyUEoQTfkbRBDCgDNurxYzFgmk30ZU6SgNCsysoEx7UMm+g7SDFHxA2lhLbWyjV8T1ab3z0BtYOAw==" + }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -1427,6 +1468,18 @@ "sax": "^1.2.4" } }, + "byte-data": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/byte-data/-/byte-data-16.0.3.tgz", + "integrity": "sha512-IzV3mzv8OnnzPdb9CoESQr2ikPX/gkHUesRu+vff9XB7KwMxyflPDewtPFWXPvF+Xukl52ceor2IRLbnQZf3PQ==", + "requires": { + "endianness": "^8.0.2", + "ieee754-buffer": "^0.2.1", + "twos-complement-buffer": "0.0.1", + "uint-buffer": "^0.1.0", + "utf8-buffer": "^0.2.0" + } + }, "cacheable-lookup": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", @@ -1460,8 +1513,7 @@ "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" }, "chalk": { "version": "4.1.2", @@ -1511,7 +1563,6 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -1531,7 +1582,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "requires": { "color-name": "~1.1.4" } @@ -1539,8 +1589,7 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "colors": { "version": "1.0.3", @@ -2028,8 +2077,7 @@ "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "end-of-stream": { "version": "1.4.4", @@ -2040,6 +2088,11 @@ "once": "^1.4.0" } }, + "endianness": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/endianness/-/endianness-8.0.2.tgz", + "integrity": "sha512-IU+77+jJ7lpw2qZ3NUuqBZFy3GuioNgXUdsL1L9tooDNTaw0TgOnwNuc+8Ns+haDaTifK97QLzmOANJtI/rGvw==" + }, "env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", @@ -2134,8 +2187,7 @@ "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, "escape-string-regexp": { "version": "4.0.0", @@ -2367,6 +2419,16 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "exit-hook": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-2.2.1.tgz", + "integrity": "sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==" + }, "extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", @@ -2558,8 +2620,7 @@ "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-intrinsic": { "version": "1.1.1", @@ -2860,12 +2921,22 @@ "dev": true, "optional": true }, + "ieee754-buffer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ieee754-buffer/-/ieee754-buffer-0.2.1.tgz", + "integrity": "sha512-dDlJhYk8BAmH1HDncTjCt6xOm2+kT+MxGhRKB+mUoF8nocDzPAgZPEWTRI9QgkGvbDkbJgCqyxweGlIV0yhbUQ==" + }, "ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, + "imaadpcm": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/imaadpcm/-/imaadpcm-4.1.2.tgz", + "integrity": "sha512-7gwxe6lKCGitmkMtGbm1ecnt0Q59KcWwo7AVi2RAd3lQ9VghVN5zX5x3oK6xNhfD9KUMbaYzku43UBn3Ix3RIA==" + }, "import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -3018,8 +3089,7 @@ "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, "is-glob": { "version": "4.0.3", @@ -3060,6 +3130,11 @@ "has-tostringtag": "^1.0.0" } }, + "is-running": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-running/-/is-running-2.1.0.tgz", + "integrity": "sha512-mjJd3PujZMl7j+D395WTIO5tU5RIDBfVSRtRR4VOJou3H66E38UjbjvDGh3slJzPuolsb+yQFqwHNNdyp5jg3w==" + }, "is-shared-array-buffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", @@ -3360,6 +3435,11 @@ "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=" }, + "nanotimer": { + "version": "0.3.15", + "resolved": "https://registry.npmjs.org/nanotimer/-/nanotimer-0.3.15.tgz", + "integrity": "sha512-xj8HcwceqeRbfSuwNIzYhdbyZu3zoiHX3y2cyVB/cLn0RzVCI8ZZVQLZELEUMG2tYEsjqbCLb3b4q1lDC7ENnA==" + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -3649,6 +3729,16 @@ "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", "dev": true }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==" + }, + "p-lazy": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-lazy/-/p-lazy-3.1.0.tgz", + "integrity": "sha512-sCJn0Cdahs6G6SX9+DUihVFUhrzDEduzE5xeViVBGtoqy5dBWko7W8T6Kk6TjR2uevRXJO7CShfWrqdH5s3w3g==" + }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -3667,6 +3757,23 @@ "p-limit": "^3.0.2" } }, + "p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "requires": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + } + }, + "p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "requires": { + "p-finally": "^1.0.0" + } + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -3706,6 +3813,14 @@ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", "dev": true }, + "pkg-prebuilds": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/pkg-prebuilds/-/pkg-prebuilds-0.1.0.tgz", + "integrity": "sha512-ALsGSiwO6EDvjrrFRiv7Q6HZPrqCgTpNxQMFs3P4Ic25cP94DmLy0iGvZDlJmQBbq2IS8xkZrifwkoOHIetY9Q==", + "requires": { + "yargs": "^17.5.1" + } + }, "plist": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.6.tgz", @@ -3801,8 +3916,7 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" }, "resolve": { "version": "1.22.1", @@ -4084,7 +4198,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -4115,7 +4228,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "requires": { "ansi-regex": "^5.0.1" } @@ -4223,6 +4335,24 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "threadedclass": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/threadedclass/-/threadedclass-1.2.1.tgz", + "integrity": "sha512-b8dUXW0K3dUWYrQakKhXvY/Owrnd3p+NKTI0BVEuAU/o7PsLupoNDCadK6V3WwyVLKCy0CS/d1xBmc6uZNPgOw==", + "requires": { + "callsites": "^3.1.0", + "eventemitter3": "^4.0.4", + "is-running": "^2.1.0", + "tslib": "^1.13.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, "thunky": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", @@ -4270,8 +4400,15 @@ "tslib": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", - "optional": true + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "twos-complement-buffer": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/twos-complement-buffer/-/twos-complement-buffer-0.0.1.tgz", + "integrity": "sha512-Ev3p2GfB2GO8pcyb7jIvctS9RAjSZrF/K+u5s3KN00ajY11Dda2oMqI72nXaHVU7doGYNXc0mJG6exWAbmzZiA==", + "requires": { + "uint-buffer": "^0.1.0" + } }, "type-check": { "version": "0.4.0", @@ -4308,6 +4445,11 @@ "rxjs": "*" } }, + "uint-buffer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/uint-buffer/-/uint-buffer-0.1.0.tgz", + "integrity": "sha512-7xjpjCTijFIXAMxN7OMRfykpCMVfbCrlAmAt2RIlihvkHgvkNV5DBFzyc8OpIQeVpRXJkgXBwmKos4hD8DrX1g==" + }, "unbox-primitive": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", @@ -4335,6 +4477,11 @@ "punycode": "^2.1.0" } }, + "utf8-buffer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/utf8-buffer/-/utf8-buffer-0.2.0.tgz", + "integrity": "sha512-DygDeOmOPQRjxnnv8LdfjoSQgG9EgJFH1m/1QcrKkDOxzoOcLLqZ2ONzRYHmiRqJYQYnAvV+zv2Wgk5tXjr4aA==" + }, "utf8-byte-length": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", @@ -4367,6 +4514,18 @@ } } }, + "wavefile": { + "version": "8.4.6", + "resolved": "https://registry.npmjs.org/wavefile/-/wavefile-8.4.6.tgz", + "integrity": "sha512-mKvPtkXTFE3U8Uo8qJr/hCJP3booCI09vsoWY3OHrdKB+8ZefO/5/wSRZSbPSgFDB+WWn3Am3c01h/sguTYuyA==", + "requires": { + "alawmulaw": "^5.0.2", + "base64-arraybuffer-es6": "^0.3.1", + "bitdepth": "^7.0.2", + "byte-data": "^16.0.3", + "imaadpcm": "^4.1.2" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -4418,7 +4577,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -4445,8 +4603,7 @@ "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" }, "yallist": { "version": "4.0.0", @@ -4457,7 +4614,6 @@ "version": "17.6.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", - "dev": true, "requires": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -4471,8 +4627,7 @@ "yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" }, "yauzl": { "version": "2.10.0", diff --git a/package.json b/package.json index 56ba087..828b617 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "prettier": "^2.8.3" }, "dependencies": { - "atem": "^0.1.8", + "atem-connection": "^3.1.3", "bonjour": "^3.5.0", "electron-updater": "^5.3.0", "lodash": "^4.17.21", diff --git a/plugins/atem/main.js b/plugins/atem/main.js index 3efb369..8015426 100644 --- a/plugins/atem/main.js +++ b/plugins/atem/main.js @@ -1,13 +1,12 @@ -const { infoUpdate } = require('../../src/device'); - exports.config = { defaultName: 'ATEM', connectionType: 'atem', defaultPort: 9910, mayChangePort: false, - heartbeatInterval: 5000, - heartbeatTimeout: 6000, + // heartbeatInterval: 5000, + // heartbeatTimeout: 20000, searchOptions: { + // TODO: actually populate search options type: 'UDPsocket', searchBuffer: Buffer.from('', 'ascii'), testPort: 9910, @@ -19,72 +18,100 @@ exports.config = { exports.ready = function ready(_device) { console.log('atem ready'); + const device = _device; + device.data = device.connection.state; + device.draw(); + + // TODO: this is a little hacky but it works? gotta be better way to get initial update going + const interval = setInterval(() => { + device.update('inputs', device.data.video.mixEffects); + device.update('fadeToBlack', device.data.video.mixEffects); + device.update(`transitionPosition`, device.data.video.mixEffects); + device.update('downstreamKeyers', device.data.video.downstreamKeyers); + }, 1000); + setTimeout(() => { + clearInterval(interval); + }, 4000); }; exports.update = function update(device, _document, updateType, data) { const document = _document; + switch (updateType) { + case 'downstreamKeyers': + for (let i = 0; i < data.length; i++) { + const dsk = data[i]; - if (updateType === 'tbar' && document.getElementById('tbar-pos')) { - document.getElementById('tbar-pos').value = data; - } -}; - -exports.data = function data(_device, msg) { - const device = _device; - this.deviceInfoUpdate(device, 'status', 'ok'); - switch (msg.event) { - case 'sourceConfiguration': - if (device.data.source === undefined) { - device.data.source = {}; - } - if (device.data.source[msg.sourceID] === undefined) { - device.data.source[msg.sourceID] = { - tally: { - preview: false, - program: false, - }, - }; - } - - device.data.source[msg.sourceID] = { - ...device.data.source[msg.sourceID], - ...msg.sourceConfiguration, - }; - break; - case 'sourceTally': - if (device.data.source === undefined) { - device.data.source = {}; - } - if (device.data.source[msg.sourceID] === undefined) { - device.data.source[msg.sourceID] = {}; - } - device.data.source[msg.sourceID].tally = msg.state; - device.draw(); - break; - - case 'connectionStateChange': - device.draw(); - break; - - case 'rawCommand': - if (msg.cmd.name === '_pin') { - if (msg.cmd.data !== undefined) { - infoUpdate(device, 'defaultName', msg.cmd.data.toString().trim()); + if (dsk.isAuto) { + document.getElementById(`dsk-${i}-auto`).classList.add('atem-red'); + } else { + document.getElementById(`dsk-${i}-auto`).classList.remove('atem-red'); } - } else if (msg.cmd.name === '_top') { - device.data.topology = { - MEs: msg.cmd.data[0], - sources: msg.cmd.data[1], - colorGens: msg.cmd.data[2], - AUXs: msg.cmd.data[3], - DSKs: msg.cmd.data[4], - stingers: msg.cmd.data[5], - DVEs: msg.cmd.data[6], - superSources: msg.cmd.data[7], - }; - } else if (msg.cmd.name === 'TrPs') { - const tbarPos = msg.cmd.data.readUint16BE(4); - device.update('tbar', tbarPos); + + if (dsk.onAir) { + document.getElementById(`dsk-${i}-onair`).classList.add('atem-red'); + } else { + document.getElementById(`dsk-${i}-onair`).classList.remove('atem-red'); + } + + if (dsk.properties.tie) { + document.getElementById(`dsk-${i}-tie`).classList.add('atem-yellow'); + } else { + document.getElementById(`dsk-${i}-tie`).classList.remove('atem-yellow'); + } + + if (dsk.remainingFrames === dsk.properties.rate) { + document.getElementById(`dsk-${i}-rate`).textContent = '1:00'; + } else { + // TODO: format in 0:00 format + document.getElementById(`dsk-${i}-rate`).textContent = `00${dsk.remainingFrames}`.slice(-2); + } + } + break; + case 'transitionPosition': + for (let i = 0; i < data.length; i++) { + const tbarId = `me-${i}-tbar-pos`; + if (document.getElementById(tbarId)) { + document.getElementById(tbarId).value = data[i].transitionPosition.handlePosition; + } + } + break; + case 'fadeToBlack': + for (let i = 0; i < data.length; i++) { + const fadeToBlack = data[i].fadeToBlack; + const ftbRateId = `me-${i}-ftb-rate`; + const ftbId = `me-${i}-ftb`; + if (fadeToBlack.remainingFrames === fadeToBlack.rate) { + document.getElementById(ftbRateId).textContent = '1:00'; + } else { + // TODO: format in 0:00 format + document.getElementById(ftbRateId).textContent = `00${fadeToBlack.remainingFrames}`.slice(-2); + } + + if (fadeToBlack.inTransition || fadeToBlack.isFullyBlack) { + document.getElementById(ftbId).classList.add('atem-red'); + } else { + document.getElementById(ftbId).classList.remove('atem-red'); + } + } + break; + case 'inputs': + for (let i = 0; i < data.length; i++) { + const programInputs = device.connection.listVisibleInputs('program', i); + const previewInputs = device.connection.listVisibleInputs('preview', i); + + Object.entries(device.data.inputs).forEach(([inputId, input]) => { + if (programInputs.includes(Number(inputId))) { + document.getElementById(`me-${i}-program-input-${inputId}`).classList.add('atem-red'); + } else { + document.getElementById(`me-${i}-program-input-${inputId}`).classList.remove('atem-red'); + } + + if (previewInputs.includes(Number(inputId))) { + document.getElementById(`me-${i}-preview-input-${inputId}`).classList.add('atem-green'); + } else { + document.getElementById(`me-${i}-preview-input-${inputId}`).classList.remove('atem-green'); + } + }); } break; default: @@ -92,4 +119,25 @@ exports.data = function data(_device, msg) { } }; -exports.heartbeat = function heartbeat(device) {}; +exports.data = function data(_device, msg) { + const device = _device; + this.deviceInfoUpdate(device, 'status', 'ok'); + device.data = msg.state; + + msg.pathToChange.forEach((path) => { + if (path.includes('transitionPosition')) { + device.update(`transitionPosition`, device.data.video.mixEffects); + } else if (path.includes('downstreamKeyers')) { + device.update('downstreamKeyers', device.data.video.downstreamKeyers); + } else if (path.includes('fadeToBlack')) { + device.update('fadeToBlack', device.data.video.mixEffects); + } else if (path.includes('programInput')) { + device.update('inputs', device.data.video.mixEffects); + } else if (path.includes('previewInput')) { + device.update('inputs', device.data.video.mixEffects); + } else { + console.log(path); + console.log(device.data); + } + }); +}; diff --git a/plugins/atem/styles.css b/plugins/atem/styles.css index 0292585..a5b7f6b 100644 --- a/plugins/atem/styles.css +++ b/plugins/atem/styles.css @@ -21,16 +21,21 @@ h3 { border-radius: 5px; } -.program-active { +.atem-red { background: rgb(255, 130, 131); background: radial-gradient(circle, rgba(255, 130, 131, 1) 0%, rgba(255, 41, 40, 1) 100%); } -.preview-active { +.atem-green { background: rgb(14, 238, 7); background: radial-gradient(circle, rgba(14, 238, 7, 1) 0%, rgba(29, 204, 14, 1) 100%); } +.atem-yellow { + background: rgb(255, 240, 0); + background: radial-gradient(circle, rgba(255, 240, 0, 1) 0%, rgba(250, 169, 9, 1) 100%); +} + .source-label { display: flex; align-items: center; @@ -43,3 +48,19 @@ h3 { height: 40px; accent-color: limegreen; } + +.dsk .source-wrapper { + display: flex; + flex-direction: column; + width: fit-content; +} + +.dsk-rate, +.ftb-rate { + display: flex; + justify-content: center; +} +.dsk-rate-label, +.ftb-rate-label { + color: rgb(235, 110, 0); +} diff --git a/plugins/atem/template.ejs b/plugins/atem/template.ejs index faa3100..78f9f9f 100644 --- a/plugins/atem/template.ejs +++ b/plugins/atem/template.ejs @@ -2,48 +2,83 @@

<%= listName %>

-
-

Program

-
- <% Object.entries(data.source).forEach(([sourceID, state])=>{ %> - <% if (state.tally && state.tally.program) { %> -
-
- <%= state.abbreviation %> +<% if (data.video.mixEffects) { %> + +<% Object.entries(data.video.mixEffects).forEach(([meIndex, state])=>{ %> +
+

ME<%= Number(meIndex) + 1 %>

+
+

Program

+
+ <% Object.entries(data.inputs).forEach(([inputId, state])=>{ %> +
+
<%= state.shortName %>
-
- <% } else { %> -
-
- <%= state.abbreviation %> + <% }) %> +
+
+ +
+

Preview

+
+ <% Object.entries(data.inputs).forEach(([inputId, state])=>{ %> +
+
<%= state.shortName %>
-
- <% } %> - <% }) %> + <% }) %> +
+
+ +
+

Next Transition

+
+
+ +
+

Transition Style

+
+
+ +
+

Fade to Black

+
+
+
1:00
+
+
+
FTB
+
+
+
+ +
+ +
-
+<% }) %> +<% } %> -
-

Preview

-
- <% Object.entries(data.source).forEach(([sourceID, state])=>{ %> - <% if (state.tally && state.tally.preview) { %> -
-
-
<%= state.abbreviation %>
-
-
- <% } else { %> -
-
-
<%= state.abbreviation %>
-
-
- <% } %> - <% }) %> -
-
-
- -
+<% if (data.video.downstreamKeyers) { %> + <% Object.entries(data.video.downstreamKeyers).forEach(([dskIndex, state])=>{ %> +
+

DSK<%= Number(dskIndex) + 1 %>

+
+
+
TIE
+
+
+
1:00
+
+
+
ON AIR
+
+ +
+
AUTO
+
+
+
+ <% }) %> +<% } %> + diff --git a/src/device.js b/src/device.js index 924878a..f098a97 100644 --- a/src/device.js +++ b/src/device.js @@ -2,7 +2,7 @@ const { v4: uuid } = require('uuid'); const osc = require('osc'); const net = require('net'); const udp = require('dgram'); -const Atem = require('atem'); +const { Atem } = require('atem-connection'); const PLUGINS = require('./plugins.js'); const VIEW = require('./view.js'); const SAVESLOTS = require('./saveSlots.js'); @@ -194,45 +194,24 @@ function initDeviceConnection(id) { device.send = (data) => {}; } else if (plugins[type].config.connectionType === 'atem') { - device.connection = new Atem(device.addresses[0]); - device.connection.on('connectionStateChange', (state) => { - plugins[type].ready(device); + device.connection = new Atem({ + // this gets around the no workers nodejs error + disableMultithreaded: true, + }); + device.connection.connect(device.addresses[0]); + + device.connection.on('connected', () => { infoUpdate(device, 'status', 'ok'); - const msg = { - event: 'connectionStateChange', + plugins[type].ready(device); + }); + + device.connection.on('stateChanged', (state, pathToChange) => { + device.lastMessage = Date.now(); + plugins[type].data(device, { + pathToChange, state, - }; - plugins[type].data(device, msg); - }); - - device.connection.on('sourceTally', (sourceID, state) => { - const msg = { - event: 'sourceTally', - sourceID, - state, - }; - plugins[type].data(device, msg); - }); - - device.connection.on('sourceConfiguration', (sourceID, sourceConfiguration) => { - const msg = { - event: 'sourceConfiguration', - sourceID, - sourceConfiguration, - }; - plugins[type].data(device, msg); - }); - - device.connection.on('rawCommand', (cmd) => { - const msg = { - event: 'rawCommand', - cmd, - }; - plugins[type].data(device, msg); - }); - - device.connection.on('connectionLost', () => { - console.log('connection lost'); + }); + infoUpdate(device, 'status', 'ok'); }); }