mirror of
https://github.com/hensm/fx_cast.git
synced 2026-06-08 08:39:59 +00:00
90 lines
2.3 KiB
TypeScript
90 lines
2.3 KiB
TypeScript
"use strict";
|
|
|
|
import mdns from "mdns";
|
|
|
|
import type { ReceiverDevice } from "../../messagingTypes";
|
|
|
|
/**
|
|
* Chromecast TXT record
|
|
*/
|
|
interface CastRecord {
|
|
// Device ID
|
|
id: string;
|
|
// Model name (e.g. Chromecast, Google Nest Mini, etc...)
|
|
md: string;
|
|
// Friendly name (user-visible)
|
|
fn: string;
|
|
// Capabilities
|
|
ca: string;
|
|
// Version (?)
|
|
ve: string;
|
|
// Icon path (?)
|
|
ic: string;
|
|
|
|
cd: string;
|
|
rm: string;
|
|
st: string;
|
|
bs: string;
|
|
nf: string;
|
|
rs: string;
|
|
}
|
|
|
|
interface DiscoveryOptions {
|
|
onDeviceFound(device: ReceiverDevice): void;
|
|
onDeviceDown(deviceId: string): void;
|
|
}
|
|
|
|
export default class Discovery {
|
|
browser = mdns.createBrowser(mdns.tcp("googlecast"), {
|
|
resolverSequence: [
|
|
mdns.rst.DNSServiceResolve(),
|
|
"DNSServiceGetAddrInfo" in mdns.dns_sd
|
|
? mdns.rst.DNSServiceGetAddrInfo()
|
|
: // Some issues on Linux with IPv6, so restrict to IPv4
|
|
mdns.rst.getaddrinfo({ families: [4] }),
|
|
mdns.rst.makeAddressesUnique()
|
|
]
|
|
});
|
|
|
|
constructor(opts: DiscoveryOptions) {
|
|
/**
|
|
* When a service is found, gather device info from service
|
|
* object and TXT record, then send a `main:deviceUp` message.
|
|
*/
|
|
this.browser.on("serviceUp", service => {
|
|
// Filter invalid results
|
|
if (!service.txtRecord || !service.name) return;
|
|
|
|
const record = service.txtRecord as CastRecord;
|
|
const device: ReceiverDevice = {
|
|
id: record.id,
|
|
friendlyName: record.fn,
|
|
modelName: record.md,
|
|
capabilities: parseInt(record.ca),
|
|
host: service.addresses[0],
|
|
port: service.port
|
|
};
|
|
|
|
opts.onDeviceFound(device);
|
|
});
|
|
|
|
/**
|
|
* When a service is lost, send a `main:deviceDown` message with
|
|
* the service name as the `deviceId`.
|
|
*/
|
|
this.browser.on("serviceDown", service => {
|
|
// Filter invalid results
|
|
if (!service.name) return;
|
|
|
|
opts.onDeviceDown(service.name);
|
|
});
|
|
}
|
|
|
|
start() {
|
|
this.browser.start();
|
|
}
|
|
stop() {
|
|
this.browser.stop();
|
|
}
|
|
}
|