Get local address for media server from bridge

This commit is contained in:
hensm
2020-08-23 15:08:23 +01:00
parent a6ab018171
commit efd3bf820e
4 changed files with 44 additions and 30 deletions

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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<cast.media.Media> {
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));