From efd3bf820eb6fb1de9f2314b37517651a6605142 Mon Sep 17 00:00:00 2001 From: hensm Date: Sun, 23 Aug 2020 15:08:23 +0100 Subject: [PATCH] Get local address for media server from bridge --- app/src/bridge/components/mediaServer.ts | 35 ++++++++++++++++++++---- app/src/bridge/types.ts | 6 +++- ext/src/messaging.ts | 6 +++- ext/src/senders/media/index.ts | 27 ++++-------------- 4 files changed, 44 insertions(+), 30 deletions(-) diff --git a/app/src/bridge/components/mediaServer.ts b/app/src/bridge/components/mediaServer.ts index 9be53c0..04ba12c 100644 --- a/app/src/bridge/components/mediaServer.ts +++ b/app/src/bridge/components/mediaServer.ts @@ -2,6 +2,7 @@ import fs from "fs"; import http from "http"; +import os from "os"; import path from "path"; import stream from "stream"; @@ -131,13 +132,35 @@ export async function startMediaServer (filePath: string, port: number) { } }); - mediaServer.on("listening", () => sendMessage({ - subject: "mediaCast:/mediaServer/started" - , data: { - mediaPath: fileName - , subtitlePaths: Array.from(subtitles.keys()) + mediaServer.on("listening", () => { + let localAddress = ""; + const ifaces = Object.values(os.networkInterfaces()); + for (const iface of ifaces) { + const matchingIface = iface?.find( + details => details.family === "IPv4" && !details.internal); + if (matchingIface) { + localAddress = matchingIface.address; + } } - })); + + if (!localAddress) { + console.error("Failed to get local address."); + sendMessage({ + subject: "mediaCast:/mediaServer/error" + }); + stopMediaServer(); + return; + } + + sendMessage({ + subject: "mediaCast:/mediaServer/started" + , data: { + mediaPath: fileName + , subtitlePaths: Array.from(subtitles.keys()) + , localAddress + } + }); + }); mediaServer.on("close", () => sendMessage({ subject: "mediaCast:/mediaServer/stopped" diff --git a/app/src/bridge/types.ts b/app/src/bridge/types.ts index b03e21a..b57a3c1 100644 --- a/app/src/bridge/types.ts +++ b/app/src/bridge/types.ts @@ -264,7 +264,11 @@ export type Messages = [ , { subject: "mediaCast:/mediaServer/started" - , data: { mediaPath: string, subtitlePaths: string[] } + , data: { + mediaPath: string + , subtitlePaths: string[] + , localAddress: string + } } , { subject: "mediaCast:/mediaServer/stopped" diff --git a/ext/src/messaging.ts b/ext/src/messaging.ts index ebdc392..98c3830 100644 --- a/ext/src/messaging.ts +++ b/ext/src/messaging.ts @@ -234,7 +234,11 @@ export type Messages = [ , { subject: "mediaCast:/mediaServer/started" - , data: { mediaPath: string, subtitlePaths: string[] } + , data: { + mediaPath: string + , subtitlePaths: string[] + , localAddress: string + } } , { subject: "mediaCast:/mediaServer/stopped" diff --git a/ext/src/senders/media/index.ts b/ext/src/senders/media/index.ts index 18ec9f1..0ab094f 100644 --- a/ext/src/senders/media/index.ts +++ b/ext/src/senders/media/index.ts @@ -8,26 +8,10 @@ import { Message } from "../../messaging"; import { Receiver } from "../../types"; -function getLocalAddress () { - const pc = new RTCPeerConnection(); - pc.createDataChannel(""); - pc.createOffer().then(pc.setLocalDescription.bind(pc)); - - return new Promise((resolve, reject) => { - pc.addEventListener("icecandidate", ev => { - if (ev.candidate) { - resolve(ev.candidate.candidate.split(" ")[4]); - } - }); - pc.addEventListener("error", () => { - reject(); - }); - }); -} - function startMediaServer (filePath: string, port: number) : Promise<{ mediaPath: string - , subtitlePaths: string[] }> { + , subtitlePaths: string[] + , localAddress: string }> { return new Promise((resolve, reject) => { backgroundPort.postMessage({ @@ -122,22 +106,21 @@ function getMedia (opts: InitOptions): Promise { let mediaUrl = new URL(opts.mediaUrl); let subtitleUrls: URL[] = []; - const mediaTitle = mediaUrl.pathname; + const mediaTitle = mediaUrl.pathname.slice(1); /** * If the media is a local file, start an HTTP media server * and change the media URL to point to it. */ if (opts.mediaUrl.startsWith("file://")) { - const host = await getLocalAddress(); const port = await options.get("localMediaServerPort"); try { // Wait until media server is listening - const { mediaPath, subtitlePaths } + const { localAddress, mediaPath, subtitlePaths } = await startMediaServer(mediaTitle, port); - const baseUrl = new URL(`http://${host}:${port}/`); + const baseUrl = new URL(`http://${localAddress}:${port}/`); mediaUrl = new URL(mediaPath, baseUrl); subtitleUrls = subtitlePaths.map( path => new URL(path, baseUrl));