@warren-bank/fx_cast_bridge 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/js/config.json +4 -0
- package/js/src/bridge/components/airplay/auth.js +251 -0
- package/js/src/bridge/components/airplay/bplist.js +13 -0
- package/js/src/bridge/components/cast/Session.js +204 -0
- package/js/src/bridge/components/cast/client.js +107 -0
- package/js/src/bridge/components/cast/discovery.js +49 -0
- package/js/src/bridge/components/cast/index.js +107 -0
- package/js/src/bridge/components/cast/remote.js +120 -0
- package/js/src/bridge/components/cast/types.js +96 -0
- package/js/src/bridge/components/mediaServer.js +231 -0
- package/js/src/bridge/index.js +161 -0
- package/js/src/bridge/lib/mdns.js +154 -0
- package/js/src/bridge/lib/ping.js +20 -0
- package/js/src/bridge/lib/subtitles.js +131 -0
- package/js/src/bridge/messaging.js +56 -0
- package/js/src/bridge/messagingTypes.js +22 -0
- package/js/src/daemon.js +181 -0
- package/js/src/main.js +236 -0
- package/js/src/transforms.js +77 -0
- package/package.json +51 -0
package/js/src/daemon.js
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding =
|
|
3
|
+
(this && this.__createBinding) ||
|
|
4
|
+
(Object.create
|
|
5
|
+
? function (o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (
|
|
9
|
+
!desc ||
|
|
10
|
+
("get" in desc
|
|
11
|
+
? !m.__esModule
|
|
12
|
+
: desc.writable || desc.configurable)
|
|
13
|
+
) {
|
|
14
|
+
desc = {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function () {
|
|
17
|
+
return m[k];
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
Object.defineProperty(o, k2, desc);
|
|
22
|
+
}
|
|
23
|
+
: function (o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
o[k2] = m[k];
|
|
26
|
+
});
|
|
27
|
+
var __setModuleDefault =
|
|
28
|
+
(this && this.__setModuleDefault) ||
|
|
29
|
+
(Object.create
|
|
30
|
+
? function (o, v) {
|
|
31
|
+
Object.defineProperty(o, "default", {
|
|
32
|
+
enumerable: true,
|
|
33
|
+
value: v
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
: function (o, v) {
|
|
37
|
+
o["default"] = v;
|
|
38
|
+
});
|
|
39
|
+
var __importStar =
|
|
40
|
+
(this && this.__importStar) ||
|
|
41
|
+
(function () {
|
|
42
|
+
var ownKeys = function (o) {
|
|
43
|
+
ownKeys =
|
|
44
|
+
Object.getOwnPropertyNames ||
|
|
45
|
+
function (o) {
|
|
46
|
+
var ar = [];
|
|
47
|
+
for (var k in o)
|
|
48
|
+
if (Object.prototype.hasOwnProperty.call(o, k))
|
|
49
|
+
ar[ar.length] = k;
|
|
50
|
+
return ar;
|
|
51
|
+
};
|
|
52
|
+
return ownKeys(o);
|
|
53
|
+
};
|
|
54
|
+
return function (mod) {
|
|
55
|
+
if (mod && mod.__esModule) return mod;
|
|
56
|
+
var result = {};
|
|
57
|
+
if (mod != null)
|
|
58
|
+
for (var k = ownKeys(mod), i = 0; i < k.length; i++)
|
|
59
|
+
if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
60
|
+
__setModuleDefault(result, mod);
|
|
61
|
+
return result;
|
|
62
|
+
};
|
|
63
|
+
})();
|
|
64
|
+
var __awaiter =
|
|
65
|
+
(this && this.__awaiter) ||
|
|
66
|
+
function (thisArg, _arguments, P, generator) {
|
|
67
|
+
function adopt(value) {
|
|
68
|
+
return value instanceof P
|
|
69
|
+
? value
|
|
70
|
+
: new P(function (resolve) {
|
|
71
|
+
resolve(value);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
75
|
+
function fulfilled(value) {
|
|
76
|
+
try {
|
|
77
|
+
step(generator.next(value));
|
|
78
|
+
} catch (e) {
|
|
79
|
+
reject(e);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function rejected(value) {
|
|
83
|
+
try {
|
|
84
|
+
step(generator["throw"](value));
|
|
85
|
+
} catch (e) {
|
|
86
|
+
reject(e);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function step(result) {
|
|
90
|
+
result.done
|
|
91
|
+
? resolve(result.value)
|
|
92
|
+
: adopt(result.value).then(fulfilled, rejected);
|
|
93
|
+
}
|
|
94
|
+
step(
|
|
95
|
+
(generator = generator.apply(thisArg, _arguments || [])).next()
|
|
96
|
+
);
|
|
97
|
+
});
|
|
98
|
+
};
|
|
99
|
+
var __importDefault =
|
|
100
|
+
(this && this.__importDefault) ||
|
|
101
|
+
function (mod) {
|
|
102
|
+
return mod && mod.__esModule ? mod : { default: mod };
|
|
103
|
+
};
|
|
104
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
105
|
+
exports.init = init;
|
|
106
|
+
const http_1 = __importDefault(require("http"));
|
|
107
|
+
const https_1 = __importDefault(require("https"));
|
|
108
|
+
const bridge = __importStar(require("./bridge"));
|
|
109
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
110
|
+
const ws_1 = __importDefault(require("ws"));
|
|
111
|
+
const messaging_1 = require("./bridge/messaging");
|
|
112
|
+
process.on("SIGTERM", () =>
|
|
113
|
+
__awaiter(void 0, void 0, void 0, function* () {
|
|
114
|
+
process.exit(1);
|
|
115
|
+
})
|
|
116
|
+
);
|
|
117
|
+
function init(opts) {
|
|
118
|
+
const server = !opts.secure
|
|
119
|
+
? http_1.default.createServer()
|
|
120
|
+
: https_1.default.createServer({
|
|
121
|
+
key: opts.key,
|
|
122
|
+
cert: opts.cert
|
|
123
|
+
});
|
|
124
|
+
const wss = new ws_1.default.Server({ noServer: true });
|
|
125
|
+
wss.on("connection", socket => {
|
|
126
|
+
bridge.run(new messaging_1.WebsocketMessenger(socket));
|
|
127
|
+
});
|
|
128
|
+
function authenticate(req) {
|
|
129
|
+
if (!opts.password) return true;
|
|
130
|
+
const password = new URL(
|
|
131
|
+
req.url,
|
|
132
|
+
`http://${req.headers.host}`
|
|
133
|
+
).searchParams.get("password");
|
|
134
|
+
return password === opts.password;
|
|
135
|
+
}
|
|
136
|
+
server.on("upgrade", (req, socket, head) => {
|
|
137
|
+
var _a;
|
|
138
|
+
if (
|
|
139
|
+
((_a = req.headers.origin) === null || _a === void 0
|
|
140
|
+
? void 0
|
|
141
|
+
: _a.startsWith("moz-extension://")) &&
|
|
142
|
+
authenticate(req)
|
|
143
|
+
) {
|
|
144
|
+
wss.handleUpgrade(req, socket, head, ws => {
|
|
145
|
+
wss.emit("connection", ws, req);
|
|
146
|
+
});
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
socket.write("HTTP/1.1 401 Unauthorized\r\n\r\n");
|
|
150
|
+
socket.destroy();
|
|
151
|
+
});
|
|
152
|
+
server.on("request", (req, res) => {
|
|
153
|
+
if ("origin" in req.headers) {
|
|
154
|
+
req.destroy();
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
res.writeHead(authenticate(req) ? 200 : 401);
|
|
158
|
+
res.end();
|
|
159
|
+
});
|
|
160
|
+
if (
|
|
161
|
+
opts.host !== "localhost" &&
|
|
162
|
+
opts.host !== "127.0.0.1" &&
|
|
163
|
+
!opts.secure
|
|
164
|
+
) {
|
|
165
|
+
process.stdout.write(
|
|
166
|
+
chalk_1.default.red(
|
|
167
|
+
"WARNING: A non-local host is set, but secure connections are not enabled!\n"
|
|
168
|
+
)
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
process.stdout.write(
|
|
172
|
+
`Starting WebSocket server at ${opts.secure ? "wss" : "ws"}://${opts.host.includes(":") ? `[${opts.host}]` : opts.host}:${opts.port}... `
|
|
173
|
+
);
|
|
174
|
+
server.listen({ port: opts.port, host: opts.host }, () => {
|
|
175
|
+
process.stdout.write("Done!\n");
|
|
176
|
+
});
|
|
177
|
+
server.on("error", err => {
|
|
178
|
+
console.error("Failed!");
|
|
179
|
+
console.error(err.message);
|
|
180
|
+
});
|
|
181
|
+
}
|
package/js/src/main.js
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
#! /usr/bin/env node
|
|
2
|
+
|
|
3
|
+
"use strict";
|
|
4
|
+
var __createBinding =
|
|
5
|
+
(this && this.__createBinding) ||
|
|
6
|
+
(Object.create
|
|
7
|
+
? function (o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (
|
|
11
|
+
!desc ||
|
|
12
|
+
("get" in desc
|
|
13
|
+
? !m.__esModule
|
|
14
|
+
: desc.writable || desc.configurable)
|
|
15
|
+
) {
|
|
16
|
+
desc = {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function () {
|
|
19
|
+
return m[k];
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
Object.defineProperty(o, k2, desc);
|
|
24
|
+
}
|
|
25
|
+
: function (o, m, k, k2) {
|
|
26
|
+
if (k2 === undefined) k2 = k;
|
|
27
|
+
o[k2] = m[k];
|
|
28
|
+
});
|
|
29
|
+
var __setModuleDefault =
|
|
30
|
+
(this && this.__setModuleDefault) ||
|
|
31
|
+
(Object.create
|
|
32
|
+
? function (o, v) {
|
|
33
|
+
Object.defineProperty(o, "default", {
|
|
34
|
+
enumerable: true,
|
|
35
|
+
value: v
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
: function (o, v) {
|
|
39
|
+
o["default"] = v;
|
|
40
|
+
});
|
|
41
|
+
var __importStar =
|
|
42
|
+
(this && this.__importStar) ||
|
|
43
|
+
(function () {
|
|
44
|
+
var ownKeys = function (o) {
|
|
45
|
+
ownKeys =
|
|
46
|
+
Object.getOwnPropertyNames ||
|
|
47
|
+
function (o) {
|
|
48
|
+
var ar = [];
|
|
49
|
+
for (var k in o)
|
|
50
|
+
if (Object.prototype.hasOwnProperty.call(o, k))
|
|
51
|
+
ar[ar.length] = k;
|
|
52
|
+
return ar;
|
|
53
|
+
};
|
|
54
|
+
return ownKeys(o);
|
|
55
|
+
};
|
|
56
|
+
return function (mod) {
|
|
57
|
+
if (mod && mod.__esModule) return mod;
|
|
58
|
+
var result = {};
|
|
59
|
+
if (mod != null)
|
|
60
|
+
for (var k = ownKeys(mod), i = 0; i < k.length; i++)
|
|
61
|
+
if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
62
|
+
__setModuleDefault(result, mod);
|
|
63
|
+
return result;
|
|
64
|
+
};
|
|
65
|
+
})();
|
|
66
|
+
var __awaiter =
|
|
67
|
+
(this && this.__awaiter) ||
|
|
68
|
+
function (thisArg, _arguments, P, generator) {
|
|
69
|
+
function adopt(value) {
|
|
70
|
+
return value instanceof P
|
|
71
|
+
? value
|
|
72
|
+
: new P(function (resolve) {
|
|
73
|
+
resolve(value);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
77
|
+
function fulfilled(value) {
|
|
78
|
+
try {
|
|
79
|
+
step(generator.next(value));
|
|
80
|
+
} catch (e) {
|
|
81
|
+
reject(e);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function rejected(value) {
|
|
85
|
+
try {
|
|
86
|
+
step(generator["throw"](value));
|
|
87
|
+
} catch (e) {
|
|
88
|
+
reject(e);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function step(result) {
|
|
92
|
+
result.done
|
|
93
|
+
? resolve(result.value)
|
|
94
|
+
: adopt(result.value).then(fulfilled, rejected);
|
|
95
|
+
}
|
|
96
|
+
step(
|
|
97
|
+
(generator = generator.apply(thisArg, _arguments || [])).next()
|
|
98
|
+
);
|
|
99
|
+
});
|
|
100
|
+
};
|
|
101
|
+
var __importDefault =
|
|
102
|
+
(this && this.__importDefault) ||
|
|
103
|
+
function (mod) {
|
|
104
|
+
return mod && mod.__esModule ? mod : { default: mod };
|
|
105
|
+
};
|
|
106
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
107
|
+
const fs_1 = __importDefault(require("fs"));
|
|
108
|
+
const path_1 = __importDefault(require("path"));
|
|
109
|
+
const yargs_1 = __importDefault(require("yargs"));
|
|
110
|
+
const config_json_1 = require("../config.json");
|
|
111
|
+
const messaging_1 = require("./bridge/messaging");
|
|
112
|
+
const argv = (0, yargs_1.default)()
|
|
113
|
+
.scriptName(config_json_1.applicationName)
|
|
114
|
+
.usage("$0 [args]")
|
|
115
|
+
.help()
|
|
116
|
+
.alias("help", "h")
|
|
117
|
+
.version(`v${config_json_1.applicationVersion}`)
|
|
118
|
+
.alias("version", "v")
|
|
119
|
+
.config("config", parseConfig)
|
|
120
|
+
.option("daemon", {
|
|
121
|
+
alias: "d",
|
|
122
|
+
describe: `Launch in daemon mode. This starts a WebSocket server that \
|
|
123
|
+
the extension can be configured to connect to under bridge options.`,
|
|
124
|
+
type: "boolean",
|
|
125
|
+
default: true
|
|
126
|
+
})
|
|
127
|
+
.option("host", {
|
|
128
|
+
alias: "n",
|
|
129
|
+
describe: `Host for daemon WebSocket server. This must match the host \
|
|
130
|
+
set in the extension options.`,
|
|
131
|
+
default: "localhost"
|
|
132
|
+
})
|
|
133
|
+
.option("port", {
|
|
134
|
+
alias: "p",
|
|
135
|
+
describe: `Port number for daemon WebSocket server. This must match \
|
|
136
|
+
the port set in the extension options.`,
|
|
137
|
+
default: 9556
|
|
138
|
+
})
|
|
139
|
+
.option("password", {
|
|
140
|
+
alias: "P",
|
|
141
|
+
describe: `Set an optional password for the daemon WebSocket server. \
|
|
142
|
+
This must match the password set in the extension options.
|
|
143
|
+
Note: If using this option it is highly recommended that you enable secure \
|
|
144
|
+
connections to avoid leaking plaintext passwords!`,
|
|
145
|
+
type: "string"
|
|
146
|
+
})
|
|
147
|
+
.option("secure", {
|
|
148
|
+
alias: "s",
|
|
149
|
+
describe: `Use a secure HTTPS server for WebSocket connections. \
|
|
150
|
+
Requires key/cert file options to be specified.`,
|
|
151
|
+
type: "boolean",
|
|
152
|
+
default: false
|
|
153
|
+
})
|
|
154
|
+
.option("key-file", {
|
|
155
|
+
alias: "k",
|
|
156
|
+
describe: `Path to the private key PEM file to use for the \
|
|
157
|
+
HTTPS server.`,
|
|
158
|
+
type: "string"
|
|
159
|
+
})
|
|
160
|
+
.option("cert-file", {
|
|
161
|
+
alias: "c",
|
|
162
|
+
describe: `Path to the certificate PEM file to use for the \
|
|
163
|
+
HTTPS server.`,
|
|
164
|
+
type: "string"
|
|
165
|
+
})
|
|
166
|
+
.check(argv => {
|
|
167
|
+
if (!argv.daemon) {
|
|
168
|
+
argv.daemon = true;
|
|
169
|
+
}
|
|
170
|
+
if (argv.port < 1025 || argv.port > 65535) {
|
|
171
|
+
throw new Error("Invalid port specified!");
|
|
172
|
+
}
|
|
173
|
+
if (argv.secure) {
|
|
174
|
+
if (!argv["key-file"] || !argv["cert-file"]) {
|
|
175
|
+
throw new Error("Missing required key/cert files.");
|
|
176
|
+
}
|
|
177
|
+
if (
|
|
178
|
+
!fs_1.default.existsSync(argv["key-file"]) ||
|
|
179
|
+
!fs_1.default.existsSync(argv["cert-file"])
|
|
180
|
+
) {
|
|
181
|
+
throw new Error("Specified key/cert files do not exist.");
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return true;
|
|
185
|
+
})
|
|
186
|
+
.parseSync(process.argv);
|
|
187
|
+
function parseConfig(configPath) {
|
|
188
|
+
let config;
|
|
189
|
+
try {
|
|
190
|
+
config = JSON.parse(
|
|
191
|
+
fs_1.default.readFileSync(configPath, { encoding: "utf-8" })
|
|
192
|
+
);
|
|
193
|
+
} catch (err) {
|
|
194
|
+
throw new Error(`Failed to parse config file!`);
|
|
195
|
+
}
|
|
196
|
+
const configDirName = path_1.default.dirname(configPath);
|
|
197
|
+
if (typeof config["key-file"] === "string") {
|
|
198
|
+
config["key-file"] = path_1.default.resolve(
|
|
199
|
+
configDirName,
|
|
200
|
+
config["key-file"]
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
if (typeof config["cert-file"] === "string") {
|
|
204
|
+
config["cert-file"] = path_1.default.resolve(
|
|
205
|
+
configDirName,
|
|
206
|
+
config["cert-file"]
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
return config;
|
|
210
|
+
}
|
|
211
|
+
function main() {
|
|
212
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
213
|
+
if (argv.daemon) {
|
|
214
|
+
const daemon = yield Promise.resolve().then(() =>
|
|
215
|
+
__importStar(require("./daemon"))
|
|
216
|
+
);
|
|
217
|
+
const daemonOpts = {
|
|
218
|
+
host: argv.host,
|
|
219
|
+
port: argv.port,
|
|
220
|
+
password: argv.password
|
|
221
|
+
};
|
|
222
|
+
if (argv.secure) {
|
|
223
|
+
daemonOpts.secure = true;
|
|
224
|
+
daemonOpts.key = fs_1.default.readFileSync(argv.keyFile);
|
|
225
|
+
daemonOpts.cert = fs_1.default.readFileSync(argv.certFile);
|
|
226
|
+
}
|
|
227
|
+
daemon.init(daemonOpts);
|
|
228
|
+
} else {
|
|
229
|
+
const bridge = yield Promise.resolve().then(() =>
|
|
230
|
+
__importStar(require("./bridge"))
|
|
231
|
+
);
|
|
232
|
+
bridge.run(new messaging_1.StdioMessenger());
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
main();
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EncodeTransform =
|
|
4
|
+
exports.DecodeTransform =
|
|
5
|
+
exports.ResponseTransform =
|
|
6
|
+
void 0;
|
|
7
|
+
const stream_1 = require("stream");
|
|
8
|
+
class ResponseTransform extends stream_1.Transform {
|
|
9
|
+
constructor(_handler) {
|
|
10
|
+
super({
|
|
11
|
+
readableObjectMode: true,
|
|
12
|
+
writableObjectMode: true
|
|
13
|
+
});
|
|
14
|
+
this._handler = _handler;
|
|
15
|
+
}
|
|
16
|
+
_transform(chunk, _encoding, callback) {
|
|
17
|
+
Promise.resolve(this._handler(chunk)).then(res => {
|
|
18
|
+
if (res) {
|
|
19
|
+
callback(null, res);
|
|
20
|
+
} else {
|
|
21
|
+
callback(null);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.ResponseTransform = ResponseTransform;
|
|
27
|
+
class DecodeTransform extends stream_1.Transform {
|
|
28
|
+
constructor() {
|
|
29
|
+
super({
|
|
30
|
+
readableObjectMode: true
|
|
31
|
+
});
|
|
32
|
+
this._messageBuffer = Buffer.alloc(0);
|
|
33
|
+
}
|
|
34
|
+
_transform(chunk, _encoding, callback) {
|
|
35
|
+
this._messageBuffer = Buffer.concat([this._messageBuffer, chunk]);
|
|
36
|
+
for (;;) {
|
|
37
|
+
if (this._messageLength === undefined) {
|
|
38
|
+
if (this._messageBuffer.length >= 4) {
|
|
39
|
+
this._messageLength = this._messageBuffer.readUInt32LE(0);
|
|
40
|
+
this._messageBuffer = this._messageBuffer.slice(4);
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
if (this._messageBuffer.length >= this._messageLength) {
|
|
45
|
+
const message = JSON.parse(
|
|
46
|
+
this._messageBuffer
|
|
47
|
+
.slice(0, this._messageLength)
|
|
48
|
+
.toString()
|
|
49
|
+
);
|
|
50
|
+
this.push(message);
|
|
51
|
+
this._messageBuffer = this._messageBuffer.slice(
|
|
52
|
+
this._messageLength
|
|
53
|
+
);
|
|
54
|
+
this._messageLength = undefined;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
callback();
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.DecodeTransform = DecodeTransform;
|
|
64
|
+
class EncodeTransform extends stream_1.Transform {
|
|
65
|
+
constructor() {
|
|
66
|
+
super({
|
|
67
|
+
writableObjectMode: true
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
_transform(chunk, _encoding, callback) {
|
|
71
|
+
const messageLength = Buffer.alloc(4);
|
|
72
|
+
const message = Buffer.from(JSON.stringify(chunk));
|
|
73
|
+
messageLength.writeUInt32LE(message.length, 0);
|
|
74
|
+
callback(null, Buffer.concat([messageLength, message]));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.EncodeTransform = EncodeTransform;
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@warren-bank/fx_cast_bridge",
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"description": "fx_cast companion application (bridge)",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "commonjs",
|
|
7
|
+
"files": [
|
|
8
|
+
"js/"
|
|
9
|
+
],
|
|
10
|
+
"bin": {
|
|
11
|
+
"fx_cast_bridge": "./js/src/main.js"
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"start": "node ./js/src/main.js"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"bplist-creator": "^0.1.0",
|
|
18
|
+
"bplist-parser": "^0.3.1",
|
|
19
|
+
"castv2": "^0.1.10",
|
|
20
|
+
"chalk": "^4.1.2",
|
|
21
|
+
"fast-srp-hap": "^2.0.4",
|
|
22
|
+
"mime-types": "^2.1.35",
|
|
23
|
+
"node-dns-sd": "^1.0.1",
|
|
24
|
+
"node-fetch": "^3.2.10",
|
|
25
|
+
"tweetnacl": "^1.0.3",
|
|
26
|
+
"ws": "^8.5.0",
|
|
27
|
+
"yargs": "^17.5.1"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/mdns": "^0.0.34",
|
|
31
|
+
"@types/mime-types": "^2.1.1",
|
|
32
|
+
"@types/minimist": "^1.2.2",
|
|
33
|
+
"@types/node": "^17.0.26",
|
|
34
|
+
"@types/node-fetch": "^2.6.1",
|
|
35
|
+
"@types/ws": "^8.5.3",
|
|
36
|
+
"@types/yargs": "^17.0.11",
|
|
37
|
+
"fs-extra": "^10.1.0",
|
|
38
|
+
"mustache": "^4.2.0",
|
|
39
|
+
"tiny-typed-emitter": "^2.1.0"
|
|
40
|
+
},
|
|
41
|
+
"repository": {
|
|
42
|
+
"type": "git",
|
|
43
|
+
"url": "https://github.com/warren-bank/fork-node-fx_cast_bridge"
|
|
44
|
+
},
|
|
45
|
+
"keywords": [
|
|
46
|
+
"fx_cast",
|
|
47
|
+
"bridge",
|
|
48
|
+
"firefox",
|
|
49
|
+
"chromecast"
|
|
50
|
+
]
|
|
51
|
+
}
|