Files
live-stream-app/src/main/ipc/live.ts
2025-10-27 17:54:11 +08:00

195 lines
6.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { ipcMain, BrowserWindow } from "electron";
import { preload, indexHtml, ELECTRON_RENDERER_URL } from "../config";
import { showPrompt } from "../utils/tools";
import { OllamaClient } from "../utils/ollama-client";
let liveWindow: BrowserWindow | null = null;
const client = new OllamaClient({
baseUrl: "http://127.0.0.1:11434", // 可选,默认值
timeout: 30000, // 可选默认30秒
});
// 直播相关的主进程处理
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,
},
});
// liveWindow.webContents.openDevTools();
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 };
}
});
ipcMain.handle("ollama-test", async (_, jobInfo) => {
try {
const result = await client.generateText({
model: "qwen:7b",
prompt: `请根据提供的 json 数据:${jobInfo},直接生成一段用于吸引求职者投递的岗位介绍文案。文案需:
1、简洁、有力突出岗位核心价值和吸引力。
2、不包含任何多余的开头、结尾、解释或废话。
3、目标是立即抓住用户眼球并促使他们投递简历。
4、不含任何废话或与岗位无关的内容
**要求:**只输出生成的岗位介绍文案本身。`,
});
return { success: true, data: result };
} catch (error: any) {
console.error("Ollama error:", error);
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),
});
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 };
}
}