Fix media server issues

This commit is contained in:
hensm
2022-04-18 09:18:23 +01:00
parent 3686340f25
commit 224216b692
5 changed files with 62 additions and 47 deletions

View File

@@ -15,7 +15,7 @@ export let mediaServer: http.Server | undefined;
export async function startMediaServer(filePath: string, port: number) { export async function startMediaServer(filePath: string, port: number) {
if (mediaServer?.listening) { if (mediaServer?.listening) {
stopMediaServer(); await stopMediaServer();
} }
let fileDir: string; let fileDir: string;
@@ -30,17 +30,17 @@ export async function startMediaServer(filePath: string, port: number) {
fileName = path.basename(filePath); fileName = path.basename(filePath);
fileSize = stat.size; fileSize = stat.size;
} else { } else {
console.error("Error: Media path is not a file.");
sendMessage({ sendMessage({
subject: "mediaCast:mediaServerError" subject: "mediaCast:mediaServerError",
data: "Media path is not a file."
}); });
return; return;
} }
} catch (err) { } catch (err) {
console.error("Error: Failed to find media path.");
sendMessage({ sendMessage({
subject: "mediaCast:mediaServerError" subject: "mediaCast:mediaServerError",
data: "Failed to find media path."
}); });
return; return;
@@ -48,9 +48,9 @@ export async function startMediaServer(filePath: string, port: number) {
const contentType = mime.lookup(filePath); const contentType = mime.lookup(filePath);
if (!contentType) { if (!contentType) {
console.error("Error: Failed to find media type.");
sendMessage({ sendMessage({
subject: "mediaCast:mediaServerError" subject: "mediaCast:mediaServerError",
data: "Failed to find media type."
}); });
return; return;
@@ -78,7 +78,7 @@ export async function startMediaServer(filePath: string, port: number) {
} }
} }
} catch (err) { } catch (err) {
// TODO: Handle? console.error(`Error: Failed to find/convert subtitles (${filePath}).`);
} }
mediaServer = http.createServer(async (req, res) => { mediaServer = http.createServer(async (req, res) => {
@@ -86,12 +86,13 @@ export async function startMediaServer(filePath: string, port: number) {
return; return;
} }
let decodedUrl = decodeURIComponent(req.url);
// Drop leading slash // Drop leading slash
if (req.url.startsWith("/")) { if (decodedUrl.startsWith("/")) {
req.url = req.url.slice(1); decodedUrl = decodedUrl.slice(1);
} }
switch (req.url) { switch (decodedUrl) {
case fileName: { case fileName: {
const { range } = req.headers; const { range } = req.headers;
@@ -135,22 +136,33 @@ export async function startMediaServer(filePath: string, port: number) {
} }
}); });
mediaServer.on("listening", () => { mediaServer.on("close", () => {
let localAddress = ""; sendMessage({
const ifaces = Object.values(os.networkInterfaces()); subject: "mediaCast:mediaServerStopped"
for (const iface of ifaces) { });
});
mediaServer.on("error", err => {
sendMessage({
subject: "mediaCast:mediaServerError",
data: err.message
});
});
mediaServer.listen(port, () => {
const localAddresses: string[] = [];
for (const iface of Object.values(os.networkInterfaces())) {
const matchingIface = iface?.find( const matchingIface = iface?.find(
details => details.family === "IPv4" && !details.internal details => details.family === "IPv4" && !details.internal
); );
if (matchingIface) { if (matchingIface) {
localAddress = matchingIface.address; localAddresses.push(matchingIface.address);
} }
} }
if (!localAddress) { if (!localAddresses.length) {
console.error("Failed to get local address.");
sendMessage({ sendMessage({
subject: "mediaCast:mediaServerError" subject: "mediaCast:mediaServerError",
data: "Failed to get local address."
}); });
stopMediaServer(); stopMediaServer();
return; return;
@@ -161,28 +173,24 @@ export async function startMediaServer(filePath: string, port: number) {
data: { data: {
mediaPath: fileName, mediaPath: fileName,
subtitlePaths: Array.from(subtitles.keys()), subtitlePaths: Array.from(subtitles.keys()),
localAddress localAddress: localAddresses[0]
} }
}); });
}); });
mediaServer.on("close", () =>
sendMessage({
subject: "mediaCast:mediaServerStopped"
})
);
mediaServer.on("error", () =>
sendMessage({
subject: "mediaCast:mediaServerError"
})
);
mediaServer.listen(port);
} }
export function stopMediaServer() { export function stopMediaServer() {
if (mediaServer?.listening) { return new Promise<void>((resolve, reject) => {
mediaServer.close(); if (mediaServer?.listening) {
mediaServer = undefined; mediaServer.close(err => {
} if (err) {
reject();
}
resolve();
});
mediaServer = undefined;
}
});
} }

View File

@@ -169,7 +169,7 @@ type MessageDefinitions = {
* Sent to media sender from bridge when the media server has * Sent to media sender from bridge when the media server has
* encountered an error. * encountered an error.
*/ */
"mediaCast:mediaServerError": {}; "mediaCast:mediaServerError": string;
}; };
interface MessageBase<K extends keyof MessageDefinitions> { interface MessageBase<K extends keyof MessageDefinitions> {

View File

@@ -150,8 +150,6 @@ export default class Session {
media.mediaSessionId === mediaStatus.mediaSessionId media.mediaSessionId === mediaStatus.mediaSessionId
); );
console.info(media);
// Handle Media creation // Handle Media creation
if (!media) { if (!media) {
media = new Media( media = new Media(

View File

@@ -37,7 +37,7 @@ function startMediaServer(
break; break;
} }
case "mediaCast:mediaServerError": { case "mediaCast:mediaServerError": {
reject(); reject(message.data);
break; break;
} }
} }
@@ -100,9 +100,8 @@ function getSession(opts: InitOptions): Promise<cast.Session> {
function getMedia(opts: InitOptions): Promise<cast.media.Media> { function getMedia(opts: InitOptions): Promise<cast.media.Media> {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
let mediaUrl = new URL(opts.mediaUrl); let mediaUrl = new URL(opts.mediaUrl);
let subtitleUrls: URL[] = [];
const mediaTitle = mediaUrl.pathname.slice(1); const mediaTitle = mediaUrl.pathname.slice(1);
const subtitleUrls: URL[] = [];
/** /**
* If the media is a local file, start an HTTP media server * If the media is a local file, start an HTTP media server
@@ -118,11 +117,13 @@ function getMedia(opts: InitOptions): Promise<cast.media.Media> {
const baseUrl = new URL(`http://${localAddress}:${port}/`); const baseUrl = new URL(`http://${localAddress}:${port}/`);
mediaUrl = new URL(mediaPath, baseUrl); mediaUrl = new URL(mediaPath, baseUrl);
subtitleUrls = subtitlePaths.map( subtitleUrls.push(
path => new URL(path, baseUrl) ...subtitlePaths.map(path => new URL(path, baseUrl))
); );
console.info(mediaUrl);
} catch (err) { } catch (err) {
throw logger.error("Failed to start media server"); throw logger.error("Failed to start media server", err);
} }
} }
@@ -341,6 +342,14 @@ interface InitOptions {
export async function init(opts: InitOptions) { export async function init(opts: InitOptions) {
backgroundPort = await ensureInit(); backgroundPort = await ensureInit();
backgroundPort.addEventListener("message", ev => {
const message = ev.data as Message;
switch (message.subject) {
case "mediaCast:mediaServerError":
logger.error("Media server error", message.data);
}
});
const isLocalMedia = opts.mediaUrl.startsWith("file://"); const isLocalMedia = opts.mediaUrl.startsWith("file://");
const isLocalMediaEnabled = await options.get("localMediaEnabled"); const isLocalMediaEnabled = await options.get("localMediaEnabled");

View File

@@ -228,7 +228,7 @@ type AppMessageDefinitions = {
* Sent to media sender from bridge when the media server has * Sent to media sender from bridge when the media server has
* encountered an error. * encountered an error.
*/ */
"mediaCast:mediaServerError": {}; "mediaCast:mediaServerError": string;
}; };
type MessageDefinitions = ExtMessageDefinitions & AppMessageDefinitions; type MessageDefinitions = ExtMessageDefinitions & AppMessageDefinitions;