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

View File

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

View File

@@ -37,7 +37,7 @@ function startMediaServer(
break;
}
case "mediaCast:mediaServerError": {
reject();
reject(message.data);
break;
}
}
@@ -100,9 +100,8 @@ function getSession(opts: InitOptions): Promise<cast.Session> {
function getMedia(opts: InitOptions): Promise<cast.media.Media> {
return new Promise(async (resolve, reject) => {
let mediaUrl = new URL(opts.mediaUrl);
let subtitleUrls: URL[] = [];
const mediaTitle = mediaUrl.pathname.slice(1);
const subtitleUrls: URL[] = [];
/**
* 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}/`);
mediaUrl = new URL(mediaPath, baseUrl);
subtitleUrls = subtitlePaths.map(
path => new URL(path, baseUrl)
subtitleUrls.push(
...subtitlePaths.map(path => new URL(path, baseUrl))
);
console.info(mediaUrl);
} 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) {
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 isLocalMediaEnabled = await options.get("localMediaEnabled");

View File

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