mirror of
https://github.com/koush/scrypted.git
synced 2026-02-10 01:02:18 +00:00
remove avahi dependency
This commit is contained in:
226
plugins/chromecast/package-lock.json
generated
226
plugins/chromecast/package-lock.json
generated
@@ -1,24 +1,23 @@
|
||||
{
|
||||
"name": "@scrypted/chromecast",
|
||||
"version": "0.1.32",
|
||||
"version": "0.1.34",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/chromecast",
|
||||
"version": "0.1.32",
|
||||
"version": "0.1.34",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"castv2-promise": "^1.0.0",
|
||||
"mdns": "^2.7.2",
|
||||
"memoize-one": "^5.1.1",
|
||||
"mime": "^2.5.2",
|
||||
"query-string": "^7.0.0"
|
||||
"multicast-dns": "^7.2.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mdns": "^0.0.34",
|
||||
"@types/mime": "^2.0.3",
|
||||
"@types/multicast-dns": "^7.2.1",
|
||||
"@types/node": "^16.9.0"
|
||||
}
|
||||
},
|
||||
@@ -74,6 +73,11 @@
|
||||
"../sdk": {
|
||||
"extraneous": true
|
||||
},
|
||||
"node_modules/@leichtgewicht/ip-codec": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz",
|
||||
"integrity": "sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg=="
|
||||
},
|
||||
"node_modules/@protobufjs/aspromise": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
||||
@@ -132,26 +136,36 @@
|
||||
"resolved": "../../sdk",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@types/long": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz",
|
||||
"integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w=="
|
||||
},
|
||||
"node_modules/@types/mdns": {
|
||||
"version": "0.0.34",
|
||||
"resolved": "https://registry.npmjs.org/@types/mdns/-/mdns-0.0.34.tgz",
|
||||
"integrity": "sha512-4Rrt/0wRAudtOnmhfDdoFhy5r20yHe0KiDK+/+I9RBBMW67F4S6y8tJH06AzrUDZzS/SH/U2pw1W0lrgQ+OlPg==",
|
||||
"node_modules/@types/dns-packet": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/dns-packet/-/dns-packet-5.2.2.tgz",
|
||||
"integrity": "sha512-Rqq7rGKIdn7OTWG7gq+mZi+F5D6CnbeLKsPByH6TU8TCJKhdKDLJrIyjVHv+vQv1MfMFqvCNo1IG7yifDK+fIw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/long": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz",
|
||||
"integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w=="
|
||||
},
|
||||
"node_modules/@types/mime": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.3.tgz",
|
||||
"integrity": "sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/multicast-dns": {
|
||||
"version": "7.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/multicast-dns/-/multicast-dns-7.2.1.tgz",
|
||||
"integrity": "sha512-A2PmB8MRcNVEkw6wzGT5rtBHqyHOVjiRMkJH+zpJKXipSi+GGkHg6JjNFApDiYK9WefJqkVG0taln1VMl4TGfw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/dns-packet": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "16.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.0.tgz",
|
||||
@@ -206,20 +220,15 @@
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"node_modules/decode-uri-component": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
|
||||
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
|
||||
"node_modules/dns-packet": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.3.0.tgz",
|
||||
"integrity": "sha512-Nce7YLu6YCgWRvOmDBsJMo9M5/jV3lEZ5vUWnWXYmwURvPylHvq7nkDWhNmk1ZQoZZOP7oQh/S0lSxbisKOfHg==",
|
||||
"dependencies": {
|
||||
"@leichtgewicht/ip-codec": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/filter-obj": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
|
||||
"integrity": "sha1-mzERErxsYSehbgFsbF1/GeCAXFs=",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/long": {
|
||||
@@ -227,21 +236,6 @@
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
|
||||
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
|
||||
},
|
||||
"node_modules/mdns": {
|
||||
"version": "2.7.2",
|
||||
"resolved": "https://registry.npmjs.org/mdns/-/mdns-2.7.2.tgz",
|
||||
"integrity": "sha512-NBOQT22DKvuNWVY7nKNbs6w9eGRyPwnc4ZjKOsCG2G/4wNt1+IyiHvc+5yhcAUZLG46cOY321YW7Ufz3lMtrhw==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"bindings": "~1.2.1",
|
||||
"nan": "^2.14.0"
|
||||
}
|
||||
},
|
||||
"node_modules/mdns/node_modules/bindings": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz",
|
||||
"integrity": "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE="
|
||||
},
|
||||
"node_modules/memoize-one": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.1.1.tgz",
|
||||
@@ -263,10 +257,17 @@
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"node_modules/nan": {
|
||||
"version": "2.14.2",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
|
||||
"integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ=="
|
||||
"node_modules/multicast-dns": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.3.tgz",
|
||||
"integrity": "sha512-TzxgGSLRLB7tqAlzjgd2x2ZE0cDsGFq4rs9W4yE5xp+7hlRXeUQGtXZsTGfGw2FwWB45rfe8DtXMYBpZGMLUng==",
|
||||
"dependencies": {
|
||||
"dns-packet": "^5.2.2",
|
||||
"thunky": "^1.0.2"
|
||||
},
|
||||
"bin": {
|
||||
"multicast-dns": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/node-dns-sd": {
|
||||
"version": "0.4.2",
|
||||
@@ -302,41 +303,18 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.46.tgz",
|
||||
"integrity": "sha512-dqpbzK/KDsOlEt+oyB3rv+u1IxlLFziZu/Z0adfRKoelkr+sTd6QcgiQC+HWq/vkYkHwG5ot2LxgV05aAjnhcg=="
|
||||
},
|
||||
"node_modules/query-string": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/query-string/-/query-string-7.0.0.tgz",
|
||||
"integrity": "sha512-Iy7moLybliR5ZgrK/1R3vjrXq03S13Vz4Rbm5Jg3EFq1LUmQppto0qtXz4vqZ386MSRjZgnTSZ9QC+NZOSd/XA==",
|
||||
"dependencies": {
|
||||
"decode-uri-component": "^0.2.0",
|
||||
"filter-obj": "^1.1.0",
|
||||
"split-on-first": "^1.0.0",
|
||||
"strict-uri-encode": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/split-on-first": {
|
||||
"node_modules/thunky": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
|
||||
"integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/strict-uri-encode": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
|
||||
"integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
"resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
|
||||
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA=="
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@leichtgewicht/ip-codec": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz",
|
||||
"integrity": "sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg=="
|
||||
},
|
||||
"@protobufjs/aspromise": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
||||
@@ -430,26 +408,36 @@
|
||||
"webpack-inject-plugin": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"@types/long": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz",
|
||||
"integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w=="
|
||||
},
|
||||
"@types/mdns": {
|
||||
"version": "0.0.34",
|
||||
"resolved": "https://registry.npmjs.org/@types/mdns/-/mdns-0.0.34.tgz",
|
||||
"integrity": "sha512-4Rrt/0wRAudtOnmhfDdoFhy5r20yHe0KiDK+/+I9RBBMW67F4S6y8tJH06AzrUDZzS/SH/U2pw1W0lrgQ+OlPg==",
|
||||
"@types/dns-packet": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/dns-packet/-/dns-packet-5.2.2.tgz",
|
||||
"integrity": "sha512-Rqq7rGKIdn7OTWG7gq+mZi+F5D6CnbeLKsPByH6TU8TCJKhdKDLJrIyjVHv+vQv1MfMFqvCNo1IG7yifDK+fIw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/long": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz",
|
||||
"integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w=="
|
||||
},
|
||||
"@types/mime": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.3.tgz",
|
||||
"integrity": "sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/multicast-dns": {
|
||||
"version": "7.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/multicast-dns/-/multicast-dns-7.2.1.tgz",
|
||||
"integrity": "sha512-A2PmB8MRcNVEkw6wzGT5rtBHqyHOVjiRMkJH+zpJKXipSi+GGkHg6JjNFApDiYK9WefJqkVG0taln1VMl4TGfw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/dns-packet": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "16.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.0.tgz",
|
||||
@@ -508,37 +496,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"decode-uri-component": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
|
||||
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU="
|
||||
},
|
||||
"filter-obj": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
|
||||
"integrity": "sha1-mzERErxsYSehbgFsbF1/GeCAXFs="
|
||||
"dns-packet": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.3.0.tgz",
|
||||
"integrity": "sha512-Nce7YLu6YCgWRvOmDBsJMo9M5/jV3lEZ5vUWnWXYmwURvPylHvq7nkDWhNmk1ZQoZZOP7oQh/S0lSxbisKOfHg==",
|
||||
"requires": {
|
||||
"@leichtgewicht/ip-codec": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"long": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
|
||||
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
|
||||
},
|
||||
"mdns": {
|
||||
"version": "2.7.2",
|
||||
"resolved": "https://registry.npmjs.org/mdns/-/mdns-2.7.2.tgz",
|
||||
"integrity": "sha512-NBOQT22DKvuNWVY7nKNbs6w9eGRyPwnc4ZjKOsCG2G/4wNt1+IyiHvc+5yhcAUZLG46cOY321YW7Ufz3lMtrhw==",
|
||||
"requires": {
|
||||
"bindings": "~1.2.1",
|
||||
"nan": "^2.14.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"bindings": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz",
|
||||
"integrity": "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE="
|
||||
}
|
||||
}
|
||||
},
|
||||
"memoize-one": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.1.1.tgz",
|
||||
@@ -554,10 +524,14 @@
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"nan": {
|
||||
"version": "2.14.2",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
|
||||
"integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ=="
|
||||
"multicast-dns": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.3.tgz",
|
||||
"integrity": "sha512-TzxgGSLRLB7tqAlzjgd2x2ZE0cDsGFq4rs9W4yE5xp+7hlRXeUQGtXZsTGfGw2FwWB45rfe8DtXMYBpZGMLUng==",
|
||||
"requires": {
|
||||
"dns-packet": "^5.2.2",
|
||||
"thunky": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node-dns-sd": {
|
||||
"version": "0.4.2",
|
||||
@@ -591,26 +565,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"query-string": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/query-string/-/query-string-7.0.0.tgz",
|
||||
"integrity": "sha512-Iy7moLybliR5ZgrK/1R3vjrXq03S13Vz4Rbm5Jg3EFq1LUmQppto0qtXz4vqZ386MSRjZgnTSZ9QC+NZOSd/XA==",
|
||||
"requires": {
|
||||
"decode-uri-component": "^0.2.0",
|
||||
"filter-obj": "^1.1.0",
|
||||
"split-on-first": "^1.0.0",
|
||||
"strict-uri-encode": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"split-on-first": {
|
||||
"thunky": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
|
||||
"integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw=="
|
||||
},
|
||||
"strict-uri-encode": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
|
||||
"integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY="
|
||||
"resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
|
||||
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/chromecast",
|
||||
"version": "0.1.32",
|
||||
"version": "0.1.34",
|
||||
"description": "Send video, audio, and text to speech notifications to Chromecast and Google Home devices",
|
||||
"author": "Scrypted",
|
||||
"license": "Apache-2.0",
|
||||
@@ -32,14 +32,13 @@
|
||||
"dependencies": {
|
||||
"@scrypted/sdk": "file:../../sdk",
|
||||
"castv2-promise": "^1.0.0",
|
||||
"mdns": "^2.7.2",
|
||||
"memoize-one": "^5.1.1",
|
||||
"mime": "^2.5.2",
|
||||
"query-string": "^7.0.0"
|
||||
"multicast-dns": "^7.2.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mdns": "^0.0.34",
|
||||
"@types/mime": "^2.0.3",
|
||||
"@types/multicast-dns": "^7.2.1",
|
||||
"@types/node": "^16.9.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import util from 'util';
|
||||
import sdk, { Device, DeviceProvider, EngineIOHandler, HttpRequest, MediaObject, MediaPlayer, MediaPlayerOptions, MediaPlayerState, MediaStatus, Refresh, RTCAVMessage, ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes } from '@scrypted/sdk';
|
||||
import { EventEmitter } from 'events';
|
||||
import mdns from 'mdns';
|
||||
import mdns from 'multicast-dns';
|
||||
import mime from 'mime';
|
||||
|
||||
const { mediaManager, systemManager, endpointManager, deviceManager, log } = sdk;
|
||||
@@ -18,15 +18,15 @@ util.inherits(ScryptedMediaReceiver, DefaultMediaReceiver);
|
||||
// in the quickjs environment.
|
||||
function toBuffer(buffer) {
|
||||
if (buffer && (buffer.constructor.name === ArrayBuffer.name || buffer.constructor.name === Uint8Array.name)) {
|
||||
var ret = Buffer.from(buffer);
|
||||
const ret = Buffer.from(buffer);
|
||||
return ret;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
const BufferConcat = Buffer.concat;
|
||||
Buffer.concat = function (bufs) {
|
||||
var copy = [];
|
||||
for (var buf of bufs) {
|
||||
const copy = [];
|
||||
for (const buf of bufs) {
|
||||
copy.push(toBuffer(buf));
|
||||
}
|
||||
return BufferConcat(copy);
|
||||
@@ -66,7 +66,7 @@ class CastDevice extends ScryptedDeviceBase implements MediaPlayer, Refresh, Eng
|
||||
return this.playerPromise = this.connectClient()
|
||||
.then(client => {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.log.i('launching');
|
||||
this.console.log('launching');
|
||||
client.launch(app, (err, player) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
@@ -74,12 +74,12 @@ class CastDevice extends ScryptedDeviceBase implements MediaPlayer, Refresh, Eng
|
||||
}
|
||||
|
||||
player.on('close', () => {
|
||||
this.log.i('player closed');
|
||||
this.console.log('player closed');
|
||||
player.removeAllListeners();
|
||||
this.playerPromise = undefined;
|
||||
});
|
||||
|
||||
this.log.i('player launched.');
|
||||
this.console.log('player launched.');
|
||||
resolve(player);
|
||||
});
|
||||
});
|
||||
@@ -96,9 +96,9 @@ class CastDevice extends ScryptedDeviceBase implements MediaPlayer, Refresh, Eng
|
||||
return this.clientPromise;
|
||||
}
|
||||
|
||||
var promise;
|
||||
let promise;
|
||||
return this.clientPromise = promise = new Promise((resolve, reject) => {
|
||||
var client = new Client();
|
||||
const client = new Client();
|
||||
|
||||
const cleanup = () => {
|
||||
client.removeAllListeners();
|
||||
@@ -109,12 +109,12 @@ class CastDevice extends ScryptedDeviceBase implements MediaPlayer, Refresh, Eng
|
||||
}
|
||||
client.on('close', cleanup);
|
||||
client.on('error', err => {
|
||||
this.log.i(`Client error: ${err.message}`);
|
||||
this.console.log(`Client error: ${err.message}`);
|
||||
cleanup();
|
||||
reject(err);
|
||||
});
|
||||
client.on('status', async status => {
|
||||
this.log.i(JSON.stringify(status));
|
||||
this.console.log(JSON.stringify(status));
|
||||
try {
|
||||
await this.joinPlayer();
|
||||
}
|
||||
@@ -122,7 +122,7 @@ class CastDevice extends ScryptedDeviceBase implements MediaPlayer, Refresh, Eng
|
||||
}
|
||||
})
|
||||
client.connect(this.host, () => {
|
||||
this.log.i(`client connected.`);
|
||||
this.console.log(`client connected.`);
|
||||
resolve(client);
|
||||
});
|
||||
})
|
||||
@@ -131,7 +131,7 @@ class CastDevice extends ScryptedDeviceBase implements MediaPlayer, Refresh, Eng
|
||||
tokens = new Map<string, MediaObject>();
|
||||
|
||||
async sendMediaToClient(title: string, mediaUrl: string, mimeType: string, opts?: any) {
|
||||
var media: any = {
|
||||
const media: any = {
|
||||
// Here you can plug an URL to any mp4, webm, mp3 or jpg file with the proper contentType.
|
||||
contentId: mediaUrl,
|
||||
contentType: mimeType,
|
||||
@@ -156,14 +156,14 @@ class CastDevice extends ScryptedDeviceBase implements MediaPlayer, Refresh, Eng
|
||||
const player = await this.connectPlayer(DefaultMediaReceiver)
|
||||
player.load(media, opts, (err, status) => {
|
||||
if (err) {
|
||||
this.log.e(`load error: ${err}`);
|
||||
this.console.error(`load error: ${err}`);
|
||||
return;
|
||||
}
|
||||
this.log.i(`media loaded playerState=${status.playerState}`);
|
||||
this.console.log(`media loaded playerState=${status.playerState}`);
|
||||
});
|
||||
}
|
||||
|
||||
async load(media: string|MediaObject, options: MediaPlayerOptions) {
|
||||
async load(media: string | MediaObject, options: MediaPlayerOptions) {
|
||||
// check to see if this is url friendly media.
|
||||
if (typeof media === 'string')
|
||||
media = mediaManager.createMediaObject(media, ScryptedMimeTypes.Url);
|
||||
@@ -194,7 +194,7 @@ class CastDevice extends ScryptedDeviceBase implements MediaPlayer, Refresh, Eng
|
||||
const token = Math.random().toString();
|
||||
this.tokens.set(token, media);
|
||||
|
||||
var castMedia: any = {
|
||||
const castMedia: any = {
|
||||
contentId: cameraStreamAuthToken,
|
||||
contentType: ScryptedMimeTypes.LocalUrl,
|
||||
streamType: 'LIVE',
|
||||
@@ -218,10 +218,10 @@ class CastDevice extends ScryptedDeviceBase implements MediaPlayer, Refresh, Eng
|
||||
const player = await this.connectPlayer(ScryptedMediaReceiver as any)
|
||||
player.load(castMedia, opts, (err, status) => {
|
||||
if (err) {
|
||||
this.log.e(`load error: ${err}`);
|
||||
this.console.error(`load error: ${err}`);
|
||||
return;
|
||||
}
|
||||
this.log.i(`media loaded playerState=${status.playerState}`);
|
||||
this.console.log(`media loaded playerState=${status.playerState}`);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -230,45 +230,45 @@ class CastDevice extends ScryptedDeviceBase implements MediaPlayer, Refresh, Eng
|
||||
const ws = new WebSocket(webSocketUrl);
|
||||
|
||||
ws.onmessage = async (message) => {
|
||||
const token = message.data as string;
|
||||
const token = message.data as string;
|
||||
|
||||
const videoStream = this.tokens.get(token);
|
||||
if (!videoStream) {
|
||||
ws.close();
|
||||
return;
|
||||
}
|
||||
const videoStream = this.tokens.get(token);
|
||||
if (!videoStream) {
|
||||
ws.close();
|
||||
return;
|
||||
}
|
||||
|
||||
const offer: RTCAVMessage = JSON.parse((await mediaManager.convertMediaObjectToBuffer(
|
||||
videoStream,
|
||||
ScryptedMimeTypes.RTCAVOffer
|
||||
)).toString());
|
||||
const offer: RTCAVMessage = JSON.parse((await mediaManager.convertMediaObjectToBuffer(
|
||||
videoStream,
|
||||
ScryptedMimeTypes.RTCAVOffer
|
||||
)).toString());
|
||||
|
||||
ws.send(JSON.stringify(offer));
|
||||
ws.send(JSON.stringify(offer));
|
||||
|
||||
const answer = await new Promise(resolve => ws.onmessage = (message) => resolve(message.data)) as string;
|
||||
const mo = mediaManager.createMediaObject(Buffer.from(answer), ScryptedMimeTypes.RTCAVAnswer);
|
||||
const answer = await new Promise(resolve => ws.onmessage = (message) => resolve(message.data)) as string;
|
||||
const mo = mediaManager.createMediaObject(Buffer.from(answer), ScryptedMimeTypes.RTCAVAnswer);
|
||||
const result = await mediaManager.convertMediaObjectToBuffer(mo, ScryptedMimeTypes.RTCAVOffer);
|
||||
ws.send(result.toString());
|
||||
|
||||
ws.onmessage = async (message) => {
|
||||
const mo = mediaManager.createMediaObject(Buffer.from(message.data), ScryptedMimeTypes.RTCAVAnswer);
|
||||
const result = await mediaManager.convertMediaObjectToBuffer(mo, ScryptedMimeTypes.RTCAVOffer);
|
||||
ws.send(result.toString());
|
||||
}
|
||||
|
||||
ws.onmessage = async (message) => {
|
||||
const mo = mediaManager.createMediaObject(Buffer.from(message.data), ScryptedMimeTypes.RTCAVAnswer);
|
||||
const result = await mediaManager.convertMediaObjectToBuffer(mo, ScryptedMimeTypes.RTCAVOffer);
|
||||
ws.send(result.toString());
|
||||
}
|
||||
|
||||
const emptyObject = JSON.stringify({
|
||||
description: null,
|
||||
id: offer.id,
|
||||
candidates: [],
|
||||
configuration: null,
|
||||
});
|
||||
while (true ){
|
||||
const mo = mediaManager.createMediaObject(Buffer.from(emptyObject), ScryptedMimeTypes.RTCAVAnswer);
|
||||
const result = await mediaManager.convertMediaObjectToBuffer(mo, ScryptedMimeTypes.RTCAVOffer);
|
||||
ws.send(result.toString());
|
||||
}
|
||||
const emptyObject = JSON.stringify({
|
||||
description: null,
|
||||
id: offer.id,
|
||||
candidates: [],
|
||||
configuration: null,
|
||||
});
|
||||
while (true) {
|
||||
const mo = mediaManager.createMediaObject(Buffer.from(emptyObject), ScryptedMimeTypes.RTCAVAnswer);
|
||||
const result = await mediaManager.convertMediaObjectToBuffer(mo, ScryptedMimeTypes.RTCAVOffer);
|
||||
ws.send(result.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mediaPlayerPromise: Promise<any>;
|
||||
@@ -278,10 +278,10 @@ class CastDevice extends ScryptedDeviceBase implements MediaPlayer, Refresh, Eng
|
||||
return this.mediaPlayerPromise;
|
||||
}
|
||||
|
||||
this.log.i('attempting to join session2');
|
||||
this.console.log('attempting to join session2');
|
||||
return this.mediaPlayerPromise = this.connectClient()
|
||||
.then(client => {
|
||||
this.log.i('attempting to join session');
|
||||
this.console.log('attempting to join session');
|
||||
return new Promise((resolve, reject) => {
|
||||
client.getSessions((err, applications) => {
|
||||
if (err) {
|
||||
@@ -302,7 +302,7 @@ class CastDevice extends ScryptedDeviceBase implements MediaPlayer, Refresh, Eng
|
||||
}
|
||||
|
||||
player.on('close', () => {
|
||||
this.log.i('player closed');
|
||||
this.console.log('player closed');
|
||||
player.removeAllListeners();
|
||||
this.mediaPlayerPromise = undefined;
|
||||
this.mediaPlayerStatus = undefined;
|
||||
@@ -333,7 +333,7 @@ class CastDevice extends ScryptedDeviceBase implements MediaPlayer, Refresh, Eng
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
this.log.e(`Error connecting to current session ${e}`);
|
||||
this.console.error(`Error connecting to current session ${e}`);
|
||||
this.mediaPlayerPromise = undefined;
|
||||
throw e;
|
||||
})
|
||||
@@ -385,7 +385,7 @@ class CastDevice extends ScryptedDeviceBase implements MediaPlayer, Refresh, Eng
|
||||
return this.getMediaStatusInternal();
|
||||
}
|
||||
getMediaStatusInternal(): MediaStatus {
|
||||
var mediaPlayerState: MediaPlayerState = this.parseState();
|
||||
const mediaPlayerState: MediaPlayerState = this.parseState();
|
||||
const media = this.mediaPlayerStatus && this.mediaPlayerStatus.media;
|
||||
const metadata = media && media.metadata;
|
||||
let position = this.mediaPlayerStatus && this.mediaPlayerStatus.currentTime;
|
||||
@@ -438,59 +438,87 @@ class CastDevice extends ScryptedDeviceBase implements MediaPlayer, Refresh, Eng
|
||||
class CastDeviceProvider extends ScryptedDeviceBase implements DeviceProvider {
|
||||
devices: any = {};
|
||||
search = new EventEmitter();
|
||||
browser = mdns.createBrowser(mdns.tcp('googlecast'));
|
||||
browser = mdns()
|
||||
searching: boolean;
|
||||
|
||||
constructor() {
|
||||
super(null);
|
||||
|
||||
this.browser.on('serviceUp', (service) => {
|
||||
this.log.i(JSON.stringify(service));
|
||||
var id = service.txtRecord.id;
|
||||
if (!id) {
|
||||
// wtf?
|
||||
return;
|
||||
|
||||
this.browser.on('response', response => {
|
||||
for (const additional of response.additionals) {
|
||||
if (additional.name.endsWith('_googlecast._tcp.local') && additional.type === 'TXT') {
|
||||
const txt = new Map<string, string>();
|
||||
for (const d of additional.data as any) {
|
||||
const parts = d.toString().split('=');
|
||||
txt.set(parts[0], parts[1]);
|
||||
}
|
||||
|
||||
const id = txt.get('id');
|
||||
if (!id) {
|
||||
// wtf?
|
||||
return;
|
||||
}
|
||||
const model = txt.get('md');
|
||||
const name = txt.get('fn');;
|
||||
|
||||
const service = response.additionals.find(check => check.type === 'SRV' && check.name === additional.name);
|
||||
if (!service) {
|
||||
console.warn('no SRV found for', additional.name);
|
||||
continue;
|
||||
}
|
||||
const host = (service.data as any).target;
|
||||
let arec = response.additionals.find(check => check.name === host && check.type === 'A');
|
||||
if (!arec)
|
||||
arec = response.additionals.find(check => check.name === host && check.type === 'AAAA');
|
||||
if (!arec) {
|
||||
console.warn('no A/AAAA record found for', additional.name);
|
||||
continue;
|
||||
}
|
||||
const ip = arec.data as string;
|
||||
const port = (service.data as any).port;
|
||||
|
||||
this.onDiscover(id, name, model, ip, port);
|
||||
}
|
||||
}
|
||||
var model = service.txtRecord.md;
|
||||
var name = service.txtRecord.fn;
|
||||
var type = (model && model.indexOf('Google Home') != -1 && model.indexOf('Hub') == -1) ? ScryptedDeviceType.Speaker : ScryptedDeviceType.Display;
|
||||
|
||||
var interfaces = [
|
||||
ScryptedInterface.MediaPlayer,
|
||||
ScryptedInterface.Refresh,
|
||||
ScryptedInterface.StartStop,
|
||||
ScryptedInterface.Pause,
|
||||
ScryptedInterface.EngineIOHandler,
|
||||
];
|
||||
|
||||
var device: Device = {
|
||||
nativeId: id,
|
||||
name,
|
||||
info: {
|
||||
model,
|
||||
},
|
||||
type,
|
||||
interfaces,
|
||||
};
|
||||
|
||||
const host = service.addresses[0];
|
||||
const port = service.port;
|
||||
|
||||
|
||||
this.log.i(`found cast device: ${name}`);
|
||||
|
||||
var castDevice = this.devices[id] || (this.devices[id] = new CastDevice(this, device.nativeId));
|
||||
castDevice.device = device;
|
||||
castDevice.host = host;
|
||||
castDevice.port = port;
|
||||
|
||||
this.search.emit(id);
|
||||
deviceManager.onDeviceDiscovered(device);
|
||||
});
|
||||
})
|
||||
|
||||
this.discoverDevices(30000);
|
||||
}
|
||||
|
||||
onDiscover(id: string, name: string, model: string, ip: string, port: number) {
|
||||
|
||||
const interfaces = [
|
||||
ScryptedInterface.MediaPlayer,
|
||||
ScryptedInterface.Refresh,
|
||||
ScryptedInterface.StartStop,
|
||||
ScryptedInterface.Pause,
|
||||
ScryptedInterface.EngineIOHandler,
|
||||
];
|
||||
|
||||
const type = (model && model.indexOf('Google Home') != -1 && model.indexOf('Hub') == -1) ? ScryptedDeviceType.Speaker : ScryptedDeviceType.Display;
|
||||
|
||||
const device: Device = {
|
||||
nativeId: id,
|
||||
name,
|
||||
info: {
|
||||
model,
|
||||
},
|
||||
type,
|
||||
interfaces,
|
||||
};
|
||||
|
||||
console.log(`found cast device: ${name}`);
|
||||
|
||||
const castDevice = this.devices[id] || (this.devices[id] = new CastDevice(this, device.nativeId));
|
||||
castDevice.device = device;
|
||||
castDevice.host = ip;
|
||||
castDevice.port = port;
|
||||
|
||||
this.search.emit(id);
|
||||
deviceManager.onDeviceDiscovered(device);
|
||||
}
|
||||
|
||||
getDevice(nativeId: string) {
|
||||
return this.devices[nativeId] || (this.devices[nativeId] = new CastDevice(this, nativeId));
|
||||
}
|
||||
@@ -501,12 +529,24 @@ class CastDeviceProvider extends ScryptedDeviceBase implements DeviceProvider {
|
||||
}
|
||||
this.searching = true;
|
||||
duration = duration || 10000;
|
||||
setTimeout(() => {
|
||||
this.searching = false;
|
||||
this.browser.stop();
|
||||
}, duration)
|
||||
// setTimeout(() => {
|
||||
// this.searching = false;
|
||||
// this.browser.stop();
|
||||
// }, duration)
|
||||
|
||||
this.browser.start();
|
||||
// this.browser.start();
|
||||
for (let i = 0; i < 6; i++) {
|
||||
setTimeout(() => {
|
||||
this.browser.query([
|
||||
{
|
||||
type: 'PTR',
|
||||
name: '_googlecast._tcp.local'
|
||||
}
|
||||
]);
|
||||
}, i * 10000)
|
||||
}
|
||||
|
||||
// this.querySSDP();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user