2025-10-27 17:54:11 +08:00
|
|
|
|
import { ipcMain, BrowserWindow } from "electron";
|
|
|
|
|
|
import { preload, indexHtml, ELECTRON_RENDERER_URL } from "../config";
|
|
|
|
|
|
import { showPrompt } from "../utils/tools";
|
|
|
|
|
|
let liveWindow: BrowserWindow | null = null;
|
|
|
|
|
|
|
|
|
|
|
|
// 直播相关的主进程处理
|
|
|
|
|
|
export function setupLiveHandlers() {
|
|
|
|
|
|
let LiveSessionId = null;
|
|
|
|
|
|
let isVideoInserted = false;
|
|
|
|
|
|
|
|
|
|
|
|
// 切换摄像头插入状态
|
|
|
|
|
|
ipcMain.on("toggle-camera-insert", async () => {
|
|
|
|
|
|
if (liveWindow) {
|
|
|
|
|
|
isVideoInserted = !isVideoInserted;
|
|
|
|
|
|
liveWindow.webContents.send(
|
|
|
|
|
|
"toggle-camera-insert",
|
|
|
|
|
|
isVideoInserted,
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 插入摄像头视频
|
|
|
|
|
|
ipcMain.on("insert-camera-video", async (_) => {
|
|
|
|
|
|
if (liveWindow) {
|
|
|
|
|
|
liveWindow.webContents.send("insert-camera-video");
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 插入音频
|
|
|
|
|
|
ipcMain.on("insert-video-audio", async (_) => {
|
|
|
|
|
|
if (liveWindow) {
|
|
|
|
|
|
liveWindow.webContents.send("insert-video-audio");
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 开始直播
|
|
|
|
|
|
ipcMain.handle("start-live", async (_) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
console.log("Starting live stream...");
|
|
|
|
|
|
// TODO: 实现直播推流逻辑
|
|
|
|
|
|
return { success: true };
|
|
|
|
|
|
} catch (error: any) {
|
|
|
|
|
|
return { success: false, error: error.message };
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 结束直播
|
|
|
|
|
|
ipcMain.handle("stop-live", async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
// TODO: 实现结束直播逻辑
|
|
|
|
|
|
return { success: true };
|
|
|
|
|
|
} catch (error: any) {
|
|
|
|
|
|
return { success: false, error: error.message };
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
ipcMain.handle("explain-position", async (_, content: string) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
let params = {
|
|
|
|
|
|
sessionid: LiveSessionId,
|
|
|
|
|
|
text: content,
|
|
|
|
|
|
type: "echo",
|
|
|
|
|
|
interrupt: true,
|
|
|
|
|
|
};
|
|
|
|
|
|
await sendMessage(params);
|
|
|
|
|
|
// TODO: 实现结束直播逻辑
|
|
|
|
|
|
return { success: true };
|
|
|
|
|
|
} catch (error: any) {
|
|
|
|
|
|
return { success: false, error: error.message };
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 打开直播窗口
|
|
|
|
|
|
ipcMain.handle("open-live-window", async (_, args) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
if (liveWindow) {
|
|
|
|
|
|
liveWindow.focus();
|
|
|
|
|
|
showPrompt("直播窗口已打开", "info");
|
|
|
|
|
|
return { success: true };
|
|
|
|
|
|
}
|
|
|
|
|
|
const { width, height, path, userId } = args;
|
|
|
|
|
|
let liveUrl = `${ELECTRON_RENDERER_URL}/#/${path}`;
|
|
|
|
|
|
if (userId) {
|
|
|
|
|
|
liveUrl += `?userId=${userId}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
// TODO: 实现打开直播窗口逻辑
|
|
|
|
|
|
liveWindow = new BrowserWindow({
|
|
|
|
|
|
title: "直播窗口",
|
|
|
|
|
|
width,
|
|
|
|
|
|
height,
|
|
|
|
|
|
minimizable: false, // 是否可以最小化
|
|
|
|
|
|
maximizable: false, // 是否可以最小化
|
|
|
|
|
|
closable: true, // 窗口是否可关闭
|
|
|
|
|
|
alwaysOnTop: true, // 窗口是否永远在别的窗口的上面
|
|
|
|
|
|
webPreferences: {
|
|
|
|
|
|
preload,
|
|
|
|
|
|
nodeIntegration: true,
|
|
|
|
|
|
contextIsolation: false,
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
2025-11-11 21:31:32 +08:00
|
|
|
|
// liveWindow.webContents.openDevTools();
|
2025-10-27 17:54:11 +08:00
|
|
|
|
liveWindow.on("closed", () => {
|
|
|
|
|
|
liveWindow = null;
|
|
|
|
|
|
});
|
|
|
|
|
|
if (ELECTRON_RENDERER_URL) {
|
|
|
|
|
|
liveWindow.loadURL(liveUrl);
|
|
|
|
|
|
setTimeout(async () => {
|
|
|
|
|
|
const res = await getSessionId({ userId: userId });
|
|
|
|
|
|
if (res.success) {
|
|
|
|
|
|
LiveSessionId = res.sessionId;
|
|
|
|
|
|
console.log(
|
|
|
|
|
|
"Session ID obtained successfully",
|
|
|
|
|
|
LiveSessionId,
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
}, 3000);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
liveWindow.loadFile(indexHtml, { hash: `/${path}` });
|
|
|
|
|
|
}
|
|
|
|
|
|
return { success: true };
|
|
|
|
|
|
} catch (error: any) {
|
|
|
|
|
|
return { success: false, error: error.message };
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function getSessionId(requestBody: object) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const response = await fetch("http://ywpt.hx.cn/dmhx/get_sessionid", {
|
|
|
|
|
|
method: "POST",
|
|
|
|
|
|
headers: {
|
|
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
|
|
},
|
|
|
|
|
|
body: JSON.stringify(requestBody),
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2025-11-11 21:31:32 +08:00
|
|
|
|
// 首先检查响应内容类型
|
|
|
|
|
|
const contentType = response.headers.get("content-type");
|
|
|
|
|
|
if (!contentType || !contentType.includes("application/json")) {
|
|
|
|
|
|
// 如果不是JSON,读取原始文本进行调试
|
|
|
|
|
|
const rawText = await response.text();
|
|
|
|
|
|
console.warn("服务器返回非JSON响应:", rawText);
|
|
|
|
|
|
|
|
|
|
|
|
// 尝试解析可能的JSON响应(即使Content-Type不正确)
|
|
|
|
|
|
try {
|
|
|
|
|
|
const data = JSON.parse(rawText);
|
|
|
|
|
|
if (response.ok && data.sessionid) {
|
|
|
|
|
|
return { success: true, sessionId: data.sessionid };
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return {
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
error: data.message || "服务器返回非JSON格式",
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (parseError) {
|
|
|
|
|
|
return {
|
|
|
|
|
|
success: false,
|
|
|
|
|
|
error: `服务器响应格式错误: ${rawText.substring(0, 100)}...`,
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 如果是JSON,正常解析
|
2025-10-27 17:54:11 +08:00
|
|
|
|
const data = await response.json();
|
|
|
|
|
|
|
|
|
|
|
|
if (response.ok && data.sessionid) {
|
|
|
|
|
|
return { success: true, sessionId: data.sessionid };
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return { success: false, error: data.message || "未知错误" };
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error: any) {
|
|
|
|
|
|
console.error("Error in getSessionId:", error);
|
|
|
|
|
|
return { success: false, error: error.message };
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async function sendMessage(requestBody: object) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const response = await fetch(`http://ywpt.hx.cn/dmhx/human`, {
|
|
|
|
|
|
method: "POST",
|
|
|
|
|
|
headers: {
|
|
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
|
|
},
|
|
|
|
|
|
body: JSON.stringify(requestBody),
|
|
|
|
|
|
});
|
|
|
|
|
|
const data = await response.json();
|
|
|
|
|
|
|
|
|
|
|
|
if (response.ok) {
|
|
|
|
|
|
return { success: true };
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return { success: false, error: data.message || "未知错误" };
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error: any) {
|
|
|
|
|
|
console.error("Error in sendMessage:", error);
|
|
|
|
|
|
return { success: false, error: error.message };
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|