feat(main): 实现字幕引擎控制功能

- 新增字幕引擎启动和停止功能
- 实现控制窗口的字幕引擎状态显示
- 优化字幕日志的发送逻辑
- 重构子进程相关代码
This commit is contained in:
himeditator
2025-06-19 22:22:17 +08:00
parent 54c618aa3f
commit c446f846bd
12 changed files with 218 additions and 71 deletions

View File

@@ -1,5 +1,8 @@
import { Styles, CaptionItem, Controls } from '../types'
import { BrowserWindow } from 'electron'
import { CaptionEngine } from './engine'
export const captionEngine = new CaptionEngine()
export const styles: Styles = {
fontFamily: 'sans-serif',
@@ -19,12 +22,15 @@ export const controls: Controls = {
sourceLang: 'en',
targetLang: 'zh',
engine: 'gummy',
engineEnabled: false,
translation: true,
customized: false,
customizedApp: '',
customizedCommand: ''
}
export let engineRunning: boolean = false
export function setStyles(args: any) {
styles.fontFamily = args.fontFamily
styles.fontSize = args.fontSize
@@ -40,23 +46,27 @@ export function setStyles(args: any) {
export function sendStyles(window: BrowserWindow) {
window.webContents.send('caption.style.set', styles)
console.log('[INFO] Send Styles:', styles)
console.log(`[INFO] Send Styles to #${window.id}:`, styles)
}
export function sendCaptionLog(window: BrowserWindow) {
window.webContents.send('both.log.set', captionLog)
export function sendCaptionLog(window: BrowserWindow, command: string) {
if(command === 'add'){
window.webContents.send(`both.log.add`, captionLog[captionLog.length - 1])
}
else if(command === 'set'){
window.webContents.send(`both.log.${command}`, captionLog)
}
}
export function addCaptionLog(log: CaptionItem) {
if(captionLog.length && captionLog[captionLog.length - 1].index === log.index) {
captionLog.splice(captionLog.length - 1, 1)
captionLog.push(log)
captionLog.splice(captionLog.length - 1, 1, log)
}
else {
captionLog.push(log)
}
for(const window of BrowserWindow.getAllWindows()){
sendCaptionLog(window)
sendCaptionLog(window, 'add')
}
}
@@ -69,4 +79,9 @@ export function setControls(args: any) {
controls.customizedApp = args.customizedApp
controls.customizedCommand = args.customizedCommand
console.log('[INFO] Set Controls:', controls)
}
export function sendControls(window: BrowserWindow) {
window.webContents.send('control.control.set', controls)
console.log(`[INFO] Send Controls to #${window.id}:`, controls)
}

79
src/main/utils/engine.ts Normal file
View File

@@ -0,0 +1,79 @@
import { spawn } from 'child_process'
import { app } from 'electron'
import path from 'path'
import { addCaptionLog, controls } from './config'
export class CaptionEngine {
appPath: string = ''
command: string[] = []
process: any | undefined
private getApp() {
if(controls.customized && controls.customizedCommand && controls.customizedApp){
this.appPath = controls.customizedApp
this.command = [ controls.customizedCommand ]
}
else if(controls.engine === 'gummy'){
this.appPath = path.join(
app.getAppPath(),
'python-subprocess', 'subenv', 'Scripts', 'python.exe'
)
this.command = []
this.command.push(path.join(
app.getAppPath(),
'python-subprocess', 'main.py'
))
this.command.push('-s', controls.sourceLang)
this.command.push('-t', controls.targetLang)
console.log(this.appPath)
console.log(this.command)
}
}
public start() {
if (this.process) {
this.stop();
}
this.getApp()
this.process = spawn(this.appPath, this.command)
controls.engineEnabled = true
console.log('[INFO] Caption Engine Started: ', {
appPath: this.appPath,
command: this.command
})
this.process.stdout.on('data', (data) => {
const lines = data.toString().split('\n');
lines.forEach( (line: string) => {
if (line.trim()) {
try {
const caption = JSON.parse(line);
addCaptionLog(caption);
} catch (e) {
console.error('Error parsing JSON:', e);
}
}
});
});
this.process.stderr.on('data', (data) => {
console.error(`Python Error: ${data}`);
});
this.process.on('close', (code: any) => {
console.log(`Python process exited with code ${code}`);
this.process = undefined;
});
}
public stop() {
if (this.process) {
this.process.kill();
this.process = undefined;
controls.engineEnabled = false;
console.log('[INFO] Caption engine process stopped');
}
}
}

View File

@@ -1,42 +0,0 @@
import { spawn } from 'child_process'
import { app } from 'electron'
import path from 'path'
import { addCaptionLog } from './config'
export class PythonProcess {
public start() {
const basePath = app.getAppPath()
const pythonPath = path.join(
basePath,
'python-subprocess', 'subenv', 'Scripts', 'python.exe'
)
const targetPath = path.join(basePath, 'python-subprocess', 'main.py')
console.log(pythonPath)
console.log(targetPath)
const pythonProcess = spawn(pythonPath, [targetPath])
pythonProcess.stdout.on('data', (data) => {
const lines = data.toString().split('\n');
lines.forEach( (line: string) => {
if (line.trim()) {
try {
const caption = JSON.parse(line);
addCaptionLog(caption);
} catch (e) {
console.error('Error parsing JSON:', e);
}
}
});
});
pythonProcess.stderr.on('data', (data) => {
console.error(`Python Error: ${data}`);
});
pythonProcess.on('close', (code) => {
console.log(`Python process exited with code ${code}`);
});
}
}