fear: Add WebRTC (janus-gateway) webcam mode (#1360)

This commit is contained in:
bakatrouble 2023-05-08 21:26:57 +03:00 committed by GitHub
parent ea274c6d4a
commit 34e3e69e5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 415 additions and 34 deletions

279
package-lock.json generated
View File

@ -36,6 +36,7 @@
"regenerator-runtime": "^0.13.9",
"resize-observer-polyfill": "^1.5.1",
"semver": "^7.3.5",
"typed_janus_js": "^1.0.14",
"uuid": "^9.0.0",
"vue": "^2.7.10",
"vue-class-component": "^7.2.6",
@ -3681,8 +3682,7 @@
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"node_modules/base64-js": {
"version": "1.5.1",
@ -5948,8 +5948,7 @@
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"dev": true
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
},
"node_modules/fsevents": {
"version": "2.3.2",
@ -6375,7 +6374,6 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"dev": true,
"dependencies": {
"once": "^1.3.0",
"wrappy": "1"
@ -6384,8 +6382,7 @@
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/ini": {
"version": "2.0.0",
@ -6965,6 +6962,11 @@
"semver": "bin/semver.js"
}
},
"node_modules/jsonc-parser": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
"integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w=="
},
"node_modules/jsonfile": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
@ -7089,8 +7091,7 @@
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"node_modules/lodash.debounce": {
"version": "4.0.8",
@ -7208,6 +7209,11 @@
"node": ">=10"
}
},
"node_modules/lunr": {
"version": "2.3.9",
"resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
"integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow=="
},
"node_modules/magic-string": {
"version": "0.26.5",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.5.tgz",
@ -7226,6 +7232,17 @@
"integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==",
"dev": true
},
"node_modules/marked": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz",
"integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==",
"bin": {
"marked": "bin/marked.js"
},
"engines": {
"node": ">= 12"
}
},
"node_modules/merge-source-map": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz",
@ -7420,7 +7437,6 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dev": true,
"dependencies": {
"wrappy": "1"
}
@ -8092,7 +8108,6 @@
"version": "7.5.7",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz",
"integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==",
"dev": true,
"dependencies": {
"tslib": "^2.1.0"
}
@ -8151,6 +8166,11 @@
"node": ">=8.9.0"
}
},
"node_modules/sdp": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/sdp/-/sdp-3.2.0.tgz",
"integrity": "sha512-d7wDPgDV3DDiqulJjKiV2865wKsJ34YI+NDREbm+FySq6WuKOikwyNQcm+doLAZ1O6ltdO0SeKle2xMpN3Brgw=="
},
"node_modules/semver": {
"version": "7.3.7",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
@ -8195,6 +8215,16 @@
"node": ">=8"
}
},
"node_modules/shiki": {
"version": "0.10.1",
"resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz",
"integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==",
"dependencies": {
"jsonc-parser": "^3.0.0",
"vscode-oniguruma": "^1.6.1",
"vscode-textmate": "5.2.0"
}
},
"node_modules/side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
@ -8770,11 +8800,79 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/typed_janus_js": {
"version": "1.0.14",
"resolved": "https://registry.npmjs.org/typed_janus_js/-/typed_janus_js-1.0.14.tgz",
"integrity": "sha512-WuwxCClbQEYlyyGimyqBb6aaBt/yowHyWL0n0Ui78LRBiffOVdSWvNEdepSIawgwCW3llJajQbpsRkcXFspZ6Q==",
"dependencies": {
"lodash": "^4.17.21",
"rxjs": "^7.5.5",
"typedoc": "^0.22.15",
"webrtc-adapter": "^8.1.1"
}
},
"node_modules/typedoc": {
"version": "0.22.18",
"resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.18.tgz",
"integrity": "sha512-NK9RlLhRUGMvc6Rw5USEYgT4DVAUFk7IF7Q6MYfpJ88KnTZP7EneEa4RcP+tX1auAcz7QT1Iy0bUSZBYYHdoyA==",
"dependencies": {
"glob": "^8.0.3",
"lunr": "^2.3.9",
"marked": "^4.0.16",
"minimatch": "^5.1.0",
"shiki": "^0.10.1"
},
"bin": {
"typedoc": "bin/typedoc"
},
"engines": {
"node": ">= 12.10.0"
},
"peerDependencies": {
"typescript": "4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x || 4.5.x || 4.6.x || 4.7.x"
}
},
"node_modules/typedoc/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/typedoc/node_modules/glob": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
"integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^5.0.1",
"once": "^1.3.0"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/typedoc/node_modules/minimatch": {
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=10"
}
},
"node_modules/typescript": {
"version": "4.8.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
"integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
"dev": true,
"version": "4.7.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
"integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@ -9283,6 +9381,16 @@
"integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==",
"dev": true
},
"node_modules/vscode-oniguruma": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
"integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA=="
},
"node_modules/vscode-textmate": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz",
"integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ=="
},
"node_modules/vscode-uri": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.6.tgz",
@ -9655,6 +9763,18 @@
"integrity": "sha512-8bWq0Iluiv9lVf9YaqWQ9+liNgXSHICm+rg544yRgGYaR8yXZTVBaHZkINZSB2yZSWo4b0F6MIxqJezVfOEAlg==",
"dev": true
},
"node_modules/webrtc-adapter": {
"version": "8.2.2",
"resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-8.2.2.tgz",
"integrity": "sha512-jQWwqiAEAFZamWliJo0Q+dIC6ZMJ8BgCFvW/oXWVFby1Nw14dOUfPwZ3lVe4nafDXdTyCUT7xfLt5xXiioXUCQ==",
"dependencies": {
"sdp": "^3.2.0"
},
"engines": {
"node": ">=6.0.0",
"npm": ">=3.10.0"
}
},
"node_modules/whatwg-url": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
@ -9968,8 +10088,7 @@
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
"node_modules/xml-name-validator": {
"version": "4.0.0",
@ -12687,8 +12806,7 @@
"balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"base64-js": {
"version": "1.5.1",
@ -14277,8 +14395,7 @@
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"dev": true
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
},
"fsevents": {
"version": "2.3.2",
@ -14575,7 +14692,6 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"dev": true,
"requires": {
"once": "^1.3.0",
"wrappy": "1"
@ -14584,8 +14700,7 @@
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"ini": {
"version": "2.0.0",
@ -15001,6 +15116,11 @@
}
}
},
"jsonc-parser": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
"integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w=="
},
"jsonfile": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
@ -15085,8 +15205,7 @@
"lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"lodash.debounce": {
"version": "4.0.8",
@ -15182,6 +15301,11 @@
"yallist": "^4.0.0"
}
},
"lunr": {
"version": "2.3.9",
"resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
"integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow=="
},
"magic-string": {
"version": "0.26.5",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.5.tgz",
@ -15197,6 +15321,11 @@
"integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==",
"dev": true
},
"marked": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz",
"integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A=="
},
"merge-source-map": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz",
@ -15343,7 +15472,6 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dev": true,
"requires": {
"wrappy": "1"
}
@ -15820,7 +15948,6 @@
"version": "7.5.7",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz",
"integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==",
"dev": true,
"requires": {
"tslib": "^2.1.0"
}
@ -15856,6 +15983,11 @@
"chokidar": ">=3.0.0 <4.0.0"
}
},
"sdp": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/sdp/-/sdp-3.2.0.tgz",
"integrity": "sha512-d7wDPgDV3DDiqulJjKiV2865wKsJ34YI+NDREbm+FySq6WuKOikwyNQcm+doLAZ1O6ltdO0SeKle2xMpN3Brgw=="
},
"semver": {
"version": "7.3.7",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
@ -15888,6 +16020,16 @@
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true
},
"shiki": {
"version": "0.10.1",
"resolved": "https://registry.npmjs.org/shiki/-/shiki-0.10.1.tgz",
"integrity": "sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==",
"requires": {
"jsonc-parser": "^3.0.0",
"vscode-oniguruma": "^1.6.1",
"vscode-textmate": "5.2.0"
}
},
"side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
@ -16321,11 +16463,63 @@
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
"dev": true
},
"typed_janus_js": {
"version": "1.0.14",
"resolved": "https://registry.npmjs.org/typed_janus_js/-/typed_janus_js-1.0.14.tgz",
"integrity": "sha512-WuwxCClbQEYlyyGimyqBb6aaBt/yowHyWL0n0Ui78LRBiffOVdSWvNEdepSIawgwCW3llJajQbpsRkcXFspZ6Q==",
"requires": {
"lodash": "^4.17.21",
"rxjs": "^7.5.5",
"typedoc": "^0.22.15",
"webrtc-adapter": "^8.1.1"
}
},
"typedoc": {
"version": "0.22.18",
"resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.22.18.tgz",
"integrity": "sha512-NK9RlLhRUGMvc6Rw5USEYgT4DVAUFk7IF7Q6MYfpJ88KnTZP7EneEa4RcP+tX1auAcz7QT1Iy0bUSZBYYHdoyA==",
"requires": {
"glob": "^8.0.3",
"lunr": "^2.3.9",
"marked": "^4.0.16",
"minimatch": "^5.1.0",
"shiki": "^0.10.1"
},
"dependencies": {
"brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"requires": {
"balanced-match": "^1.0.0"
}
},
"glob": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
"integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^5.0.1",
"once": "^1.3.0"
}
},
"minimatch": {
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
"requires": {
"brace-expansion": "^2.0.1"
}
}
}
},
"typescript": {
"version": "4.8.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
"integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
"dev": true
"version": "4.7.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
"integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ=="
},
"unbox-primitive": {
"version": "1.0.2",
@ -16671,6 +16865,16 @@
"integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==",
"dev": true
},
"vscode-oniguruma": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
"integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA=="
},
"vscode-textmate": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-5.2.0.tgz",
"integrity": "sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ=="
},
"vscode-uri": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.6.tgz",
@ -16958,6 +17162,14 @@
"integrity": "sha512-8bWq0Iluiv9lVf9YaqWQ9+liNgXSHICm+rg544yRgGYaR8yXZTVBaHZkINZSB2yZSWo4b0F6MIxqJezVfOEAlg==",
"dev": true
},
"webrtc-adapter": {
"version": "8.2.2",
"resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-8.2.2.tgz",
"integrity": "sha512-jQWwqiAEAFZamWliJo0Q+dIC6ZMJ8BgCFvW/oXWVFby1Nw14dOUfPwZ3lVe4nafDXdTyCUT7xfLt5xXiioXUCQ==",
"requires": {
"sdp": "^3.2.0"
}
},
"whatwg-url": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
@ -17239,8 +17451,7 @@
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
"xml-name-validator": {
"version": "4.0.0",

View File

@ -51,6 +51,7 @@
"regenerator-runtime": "^0.13.9",
"resize-observer-polyfill": "^1.5.1",
"semver": "^7.3.5",
"typed_janus_js": "^1.0.14",
"uuid": "^9.0.0",
"vue": "^2.7.10",
"vue-class-component": "^7.2.6",

View File

@ -66,6 +66,9 @@
<template v-else-if="currentCam.service === 'webrtc-camerastreamer'">
<webcam-webrtc-camerastreamer :cam-settings="currentCam" />
</template>
<template v-else-if="currentCam.service === 'webrtc-janus'">
<webcam-webrtc-janus :cam-settings="currentCam" />
</template>
<template v-else>
<p class="text-center py-3 font-italic">{{ $t('Panels.WebcamPanel.UnknownWebcamService') }}</p>
</template>
@ -94,6 +97,7 @@ import Panel from '@/components/ui/Panel.vue'
import { GuiWebcamStateWebcam } from '@/store/gui/webcams/types'
import { mdiMenuDown, mdiViewGrid, mdiWebcam } from '@mdi/js'
import WebcamMixin from '@/components/mixins/webcam'
import JanusStreamer from '@/components/webcams/JanusStreamer.vue'
@Component({
components: {
@ -105,6 +109,7 @@ import WebcamMixin from '@/components/mixins/webcam'
'webcam-uv4l-mjpeg': Uv4lMjpeg,
'webcam-jmuxer-stream': JMuxerStream,
'webcam-webrtc-camerastreamer': WebrtcCameraStreamer,
'webcam-webrtc-janus': JanusStreamer,
'webcam-grid': WebcamGrid,
},
})

View File

@ -196,6 +196,9 @@
<template v-else-if="form.service === 'webrtc-camerastreamer'">
<webcam-webrtc-camerastreamer :cam-settings="form" />
</template>
<template v-else-if="form.service === 'webrtc-janus'">
<webcam-webrtc-janus :cam-settings="form" />
</template>
<template v-else>
<p class="text-center py-3 font-italic">
{{ $t('Panels.WebcamPanel.UnknownWebcamService') }}
@ -236,6 +239,7 @@ import { mdiMenuDown, mdiDelete, mdiPencil, mdiWebcam } from '@mdi/js'
import WebcamMixin from '@/components/mixins/webcam'
import { FileStateFile } from '@/store/files/types'
import Hlsstreamer from '../webcams/Hlsstreamer.vue'
import JanusStreamer from '@/components/webcams/JanusStreamer.vue'
interface webcamForm {
bool: boolean
@ -262,6 +266,7 @@ interface webcamForm {
'webcam-webrtc-camerastreamer': WebrtcCameraStreamer,
'webcam-hlsstreamer': Hlsstreamer,
'webcam-jmuxer-stream': JMuxerStream,
'webcam-webrtc-janus': JanusStreamer,
},
})
export default class SettingsWebcamsTab extends Mixins(BaseMixin, WebcamMixin) {
@ -328,6 +333,7 @@ export default class SettingsWebcamsTab extends Mixins(BaseMixin, WebcamMixin) {
{ value: 'webrtc-camerastreamer', text: this.$t('Settings.WebcamsTab.WebrtcCameraStreamer') },
{ value: 'hlsstream', text: this.$t('Settings.WebcamsTab.Hlsstream') },
{ value: 'jmuxer-stream', text: this.$t('Settings.WebcamsTab.JMuxerStream') },
{ value: 'webrtc-janus', text: this.$t('Settings.WebcamsTab.WebrtcJanus') },
]
}

View File

@ -0,0 +1,152 @@
<template>
<div>
<video
v-show="status === 'started'"
ref="stream"
class="webcamStream"
:style="webcamStyle"
autoplay
muted
playsinline
@playing="updateAspectRatio" />
<v-row v-if="status !== 'started'">
<v-col class="_webcam_webrtc_output text-center d-flex flex-column justify-center align-center">
<v-progress-circular v-if="status === 'connecting'" indeterminate color="primary" class="mb-3" />
<span class="mt-3">{{ status }}</span>
</v-col>
</v-row>
</div>
</template>
<script lang="ts">
import { Component, Mixins, Prop, Ref, Watch } from 'vue-property-decorator'
import { JanusJs, JanusSession, JanusStreamingPlugin } from 'typed_janus_js'
import BaseMixin from '@/components/mixins/base'
import { ConstructorOptions } from 'typed_janus_js/src/interfaces/janus'
@Component
export default class JanusStreamer extends Mixins(BaseMixin) {
private janusClient: JanusJs | null = null
private session: JanusSession | null = null
private handle: JanusStreamingPlugin | null = null
private useStun = false
private aspectRatio: null | number = null
private status: string = 'connecting'
@Prop({ required: true })
camSettings: any
@Prop({ default: null }) declare readonly printerUrl: string | null
@Ref() declare stream: HTMLVideoElement
get url() {
const baseUrl = this.camSettings.urlStream
let url = new URL(baseUrl, this.printerUrl === null ? this.hostUrl.toString() : this.printerUrl)
url.port = '8188'
url.protocol = this.printerUrl?.startsWith('https') ? 'wss' : 'ws'
if (baseUrl.startsWith('ws') || baseUrl.startsWith('http')) {
url = new URL(baseUrl)
const pathnameParts = url.pathname.split('/')
url.pathname = pathnameParts.slice(0, pathnameParts.length - 1).join('/')
}
return url
}
get streamId() {
const pathnameParts = new URL(this.camSettings.urlStream).pathname.split('/')
return pathnameParts[pathnameParts.length - 1]
}
get webcamStyle() {
const output = {
transform: 'none',
aspectRatio: 16 / 9,
}
let transforms = ''
if ('flipX' in this.camSettings && this.camSettings.flipX) transforms += ' scaleX(-1)'
if ('flipX' in this.camSettings && this.camSettings.flipY) transforms += ' scaleY(-1)'
if (transforms.trimStart().length) output.transform = transforms.trimStart()
if (this.aspectRatio) output.aspectRatio = this.aspectRatio
return output
}
get streamConfig() {
let config: ConstructorOptions = {
server: this.url.toString(),
}
if (this.useStun) {
config.iceServers = [{ urls: ['stun:stun.l.google.com:19302'] }]
}
return config
}
async startStream() {
this.janusClient = new JanusJs(this.streamConfig)
await this.janusClient.init({ debug: false })
this.session = await this.janusClient.createSession()
this.handle = await this.session.attach<JanusStreamingPlugin>(JanusStreamingPlugin, {})
this.handle?.onMessage.subscribe(async ({ message, jsep }) => {
if (message?.result?.status) {
this.status = message.result.status
}
if (jsep) {
const answer = await this.handle?.createAnswer({ jsep })
this.handle?.send({ message: { request: 'start' }, jsep: answer })
}
})
const remoteStream = new MediaStream()
JanusJs.attachMediaStream(this.stream as HTMLMediaElement, remoteStream)
this.handle?.onRemoteTrack.subscribe(({ on, track }) => {
if (on) remoteStream.addTrack(track)
else remoteStream.removeTrack(track)
})
this.handle.onIceState.subscribe((value) => {
console.log(`ICE state changed to ${value}`)
})
this.handle.onError.subscribe((value) => {
this.status = `errored: ${JSON.stringify(value)}`
})
await this.handle.send({ message: { request: 'watch', id: parseInt(this.streamId!) } })
}
mounted() {
this.startStream()
}
updateAspectRatio() {
this.aspectRatio = this.stream.videoWidth / this.stream.videoHeight
}
beforeDestroy() {
this.session?.destroy({})
}
@Watch('url')
async changedUrl() {
await this.session?.destroy({})
this.startStream()
}
}
</script>
<style scoped>
.webcamStream {
width: 100%;
}
._webcam_webrtc_output {
aspect-ratio: calc(3 / 2);
}
video {
width: 100%;
}
</style>

View File

@ -25,6 +25,9 @@
<template v-else-if="webcam.service === 'jmuxer-stream'">
<webcam-jmuxer-stream :cam-settings="webcam" />
</template>
<template v-else-if="webcam.service === 'webrtc-janus'">
<webcam-webrtc-janus :cam-settings="webcam" />
</template>
<template v-else>
<p class="text-center py-3 font-italic">{{ $t('Panels.WebcamPanel.UnknownWebcamService') }}</p>
</template>
@ -44,6 +47,7 @@ import Hlsstreamer from '@/components/webcams/Hlsstreamer.vue'
import JMuxerStream from '@/components/webcams/JMuxerStream.vue'
import WebrtcCameraStreamer from '@/components/webcams/WebrtcCameraStreamer.vue'
import { GuiWebcamStateWebcam } from '@/store/gui/webcams/types'
import JanusStreamer from '@/components/webcams/JanusStreamer.vue'
@Component({
components: {
@ -54,6 +58,7 @@ import { GuiWebcamStateWebcam } from '@/store/gui/webcams/types'
'webcam-hlsstreamer': Hlsstreamer,
'webcam-jmuxer-stream': JMuxerStream,
'webcam-webrtc-camerastreamer': WebrtcCameraStreamer,
'webcam-webrtc-janus': JanusStreamer,
},
})
export default class WebcamGrid extends Mixins(BaseMixin) {

View File

@ -1075,6 +1075,7 @@
"IconPrinter": "Printer",
"Ipstream": "IP Camera",
"Hlsstream": "HLS Stream",
"WebrtcJanus": "WebRTC (janus-gateway)",
"Mjpegstreamer": "MJPEG-Streamer",
"MjpegstreamerAdaptive": "Adaptive MJPEG-Streamer (experimental)",
"JMuxerStream": "Raw h264 stream (jmuxer)",