mirror of
https://github.com/hensm/fx_cast.git
synced 2026-06-08 08:39:59 +00:00
Fix media server issues
This commit is contained in:
@@ -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;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -150,8 +150,6 @@ export default class Session {
|
||||
media.mediaSessionId === mediaStatus.mediaSessionId
|
||||
);
|
||||
|
||||
console.info(media);
|
||||
|
||||
// Handle Media creation
|
||||
if (!media) {
|
||||
media = new Media(
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user