mirror of
https://github.com/HiMeditator/auto-caption.git
synced 2026-02-19 23:44:41 +08:00
feat: 完全实现多语言支持、优化软件体验
- 完成多语言的剩余内容的翻译 - 重构配置管理,前端页面实现更快速的配置载入 - 为字幕引擎添加更严格的状态限制,防止出现僵尸进程
This commit is contained in:
@@ -3,7 +3,6 @@ import path from 'path'
|
||||
import { is } from '@electron-toolkit/utils'
|
||||
import icon from '../../resources/icon.png?asset'
|
||||
import { controlWindow } from './ControlWindow'
|
||||
import { allConfig } from './utils/AllConfig'
|
||||
|
||||
class CaptionWindow {
|
||||
window: BrowserWindow | undefined;
|
||||
@@ -27,13 +26,6 @@ class CaptionWindow {
|
||||
}
|
||||
})
|
||||
|
||||
setTimeout(() => {
|
||||
if (this.window) {
|
||||
allConfig.sendStyles(this.window);
|
||||
allConfig.sendCaptionLog(this.window, 'set');
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
this.window.on('ready-to-show', () => {
|
||||
this.window?.show()
|
||||
})
|
||||
@@ -57,7 +49,6 @@ class CaptionWindow {
|
||||
}
|
||||
|
||||
public handleMessage() {
|
||||
// 激活控制窗口
|
||||
ipcMain.on('caption.controlWindow.activate', () => {
|
||||
if(!controlWindow.window){
|
||||
controlWindow.createWindow()
|
||||
@@ -67,21 +58,18 @@ class CaptionWindow {
|
||||
}
|
||||
})
|
||||
|
||||
// 字幕窗口高度发生变化
|
||||
ipcMain.on('caption.windowHeight.change', (_, height) => {
|
||||
if(this.window){
|
||||
this.window.setSize(this.window.getSize()[0], height)
|
||||
}
|
||||
})
|
||||
|
||||
// 关闭字幕窗口
|
||||
ipcMain.on('caption.window.close', () => {
|
||||
if(this.window){
|
||||
this.window.close()
|
||||
}
|
||||
})
|
||||
|
||||
// 是否固定在最前面
|
||||
ipcMain.on('caption.pin.set', (_, pinned) => {
|
||||
if(this.window){
|
||||
this.window.setAlwaysOnTop(pinned)
|
||||
|
||||
@@ -28,14 +28,6 @@ class ControlWindow {
|
||||
|
||||
allConfig.readConfig()
|
||||
|
||||
setTimeout(() => {
|
||||
if (this.window) {
|
||||
allConfig.sendStyles(this.window)
|
||||
allConfig.sendControls(this.window)
|
||||
allConfig.sendCaptionLog(this.window, 'set')
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
this.window.on('ready-to-show', () => {
|
||||
this.window?.show()
|
||||
})
|
||||
@@ -58,12 +50,21 @@ class ControlWindow {
|
||||
}
|
||||
|
||||
public handleMessage() {
|
||||
// 控制窗口初始化完毕
|
||||
ipcMain.handle('control.window.mounted', async () => {
|
||||
return allConfig.getControlWindowConfig()
|
||||
ipcMain.handle('both.window.mounted', () => {
|
||||
return allConfig.getFullConfig()
|
||||
})
|
||||
|
||||
ipcMain.on('control.uiLanguage.change', (_, args) => {
|
||||
allConfig.uiLanguage = args
|
||||
if(captionWindow.window){
|
||||
captionWindow.window.webContents.send('caption.uiLanguage.set', args)
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('control.leftBarWidth.change', (_, args) => {
|
||||
allConfig.leftBarWidth = args
|
||||
})
|
||||
|
||||
// 样式变更
|
||||
ipcMain.on('control.styles.change', (_, args) => {
|
||||
allConfig.setStyles(args)
|
||||
if(captionWindow.window){
|
||||
@@ -71,7 +72,6 @@ class ControlWindow {
|
||||
}
|
||||
})
|
||||
|
||||
// 样式重置
|
||||
ipcMain.on('control.styles.reset', () => {
|
||||
allConfig.resetStyles()
|
||||
if(this.window){
|
||||
@@ -82,7 +82,6 @@ class ControlWindow {
|
||||
}
|
||||
})
|
||||
|
||||
// 激活字幕窗口
|
||||
ipcMain.on('control.captionWindow.activate', () => {
|
||||
if(!captionWindow.window){
|
||||
captionWindow.createWindow()
|
||||
@@ -92,31 +91,20 @@ class ControlWindow {
|
||||
}
|
||||
})
|
||||
|
||||
// 字幕引擎配置更新
|
||||
ipcMain.on('control.controls.change', (_, args) => {
|
||||
allConfig.setControls(args)
|
||||
})
|
||||
|
||||
// 启动字幕引擎
|
||||
ipcMain.on('control.engine.start', () => {
|
||||
if(allConfig.controls.engineEnabled){
|
||||
this.window?.webContents.send('control.engine.already')
|
||||
}
|
||||
else {
|
||||
captionEngine.start()
|
||||
}
|
||||
captionEngine.start()
|
||||
})
|
||||
|
||||
// 停止字幕引擎
|
||||
ipcMain.on('control.engine.stop', () => {
|
||||
captionEngine.stop()
|
||||
this.window?.webContents.send('control.engine.stopped')
|
||||
})
|
||||
|
||||
// 清空字幕记录
|
||||
ipcMain.handle('control.captionLog.clear', () => {
|
||||
ipcMain.on('control.captionLog.clear', () => {
|
||||
allConfig.captionLog.splice(0)
|
||||
return allConfig.captionLog
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ export interface Styles {
|
||||
fontColor: string,
|
||||
background: string,
|
||||
opacity: number,
|
||||
showPreview: boolean,
|
||||
transDisplay: boolean,
|
||||
transFontFamily: string,
|
||||
transFontSize: number,
|
||||
@@ -32,9 +33,10 @@ export interface CaptionItem {
|
||||
translation: string
|
||||
}
|
||||
|
||||
export interface ControlWindowConfig {
|
||||
export interface FullConfig {
|
||||
uiLanguage: UILanguage,
|
||||
leftBarWidth: number,
|
||||
styles: Styles,
|
||||
controls: Controls
|
||||
controls: Controls,
|
||||
captionLog: CaptionItem[]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {
|
||||
UILanguage, Styles, CaptionItem, Controls,
|
||||
ControlWindowConfig
|
||||
FullConfig
|
||||
} from '../types'
|
||||
import { app, BrowserWindow } from 'electron'
|
||||
import * as path from 'path'
|
||||
@@ -12,6 +12,7 @@ const defaultStyles: Styles = {
|
||||
fontColor: '#000000',
|
||||
background: '#dbe2ef',
|
||||
opacity: 80,
|
||||
showPreview: true,
|
||||
transDisplay: true,
|
||||
transFontFamily: 'sans-serif',
|
||||
transFontSize: 24,
|
||||
@@ -55,6 +56,7 @@ class AllConfig {
|
||||
public writeConfig() {
|
||||
const config = {
|
||||
uiLanguage: this.uiLanguage,
|
||||
leftBarWidth: this.leftBarWidth,
|
||||
controls: this.controls,
|
||||
styles: this.styles
|
||||
}
|
||||
@@ -63,12 +65,13 @@ class AllConfig {
|
||||
console.log('[INFO] Write Config to:', configPath)
|
||||
}
|
||||
|
||||
public getControlWindowConfig(): ControlWindowConfig {
|
||||
public getFullConfig(): FullConfig {
|
||||
return {
|
||||
uiLanguage: this.uiLanguage,
|
||||
leftBarWidth: this.leftBarWidth,
|
||||
styles: this.styles,
|
||||
controls: this.controls
|
||||
controls: this.controls,
|
||||
captionLog: this.captionLog
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,12 +89,12 @@ class AllConfig {
|
||||
}
|
||||
|
||||
public sendStyles(window: BrowserWindow) {
|
||||
window.webContents.send('caption.styles.set', this.styles)
|
||||
window.webContents.send('both.styles.set', this.styles)
|
||||
console.log(`[INFO] Send Styles to #${window.id}:`, this.styles)
|
||||
}
|
||||
|
||||
public setControls(args: Controls) {
|
||||
const engineEnabled = args.engineEnabled
|
||||
const engineEnabled = this.controls.engineEnabled
|
||||
for(let key in this.controls){
|
||||
if(key in args) {
|
||||
this.controls[key] = args[key]
|
||||
@@ -108,7 +111,11 @@ class AllConfig {
|
||||
|
||||
public updateCaptionLog(log: CaptionItem) {
|
||||
let command: 'add' | 'upd' = 'add'
|
||||
if(this.captionLog.length && this.captionLog[this.captionLog.length - 1].index === log.index) {
|
||||
if(
|
||||
this.captionLog.length &&
|
||||
this.captionLog[this.captionLog.length - 1].index === log.index &&
|
||||
this.captionLog[this.captionLog.length - 1].time_s === log.time_s
|
||||
) {
|
||||
this.captionLog.splice(this.captionLog.length - 1, 1, log)
|
||||
command = 'upd'
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ export class CaptionEngine {
|
||||
appPath: string = ''
|
||||
command: string[] = []
|
||||
process: any | undefined
|
||||
processStatus: 'running' | 'stopping' | 'stopped' = 'stopped'
|
||||
|
||||
private getApp(): boolean {
|
||||
if (allConfig.controls.customized && allConfig.controls.customizedApp) {
|
||||
@@ -60,7 +61,9 @@ export class CaptionEngine {
|
||||
}
|
||||
|
||||
public start() {
|
||||
if (this.process) { this.stop() }
|
||||
if (this.processStatus!== 'stopped') {
|
||||
return
|
||||
}
|
||||
if(!this.getApp()){ return }
|
||||
|
||||
try {
|
||||
@@ -72,13 +75,16 @@ export class CaptionEngine {
|
||||
return
|
||||
}
|
||||
|
||||
console.log('[INFO] Caption Engine Started')
|
||||
this.processStatus = 'running'
|
||||
console.log('[INFO] Caption Engine Started, PID:', this.process.pid)
|
||||
|
||||
allConfig.controls.engineEnabled = true
|
||||
|
||||
if(controlWindow.window){
|
||||
allConfig.sendControls(controlWindow.window)
|
||||
controlWindow.window.webContents.send('control.engine.started')
|
||||
controlWindow.window.webContents.send(
|
||||
'control.engine.started',
|
||||
this.process.pid
|
||||
)
|
||||
}
|
||||
|
||||
this.process.stdout.on('data', (data: any) => {
|
||||
@@ -107,12 +113,17 @@ export class CaptionEngine {
|
||||
allConfig.controls.engineEnabled = false
|
||||
if(controlWindow.window){
|
||||
allConfig.sendControls(controlWindow.window)
|
||||
controlWindow.window.webContents.send('control.engine.stopped')
|
||||
}
|
||||
this.processStatus = 'stopped'
|
||||
console.log('[INFO] Caption engine process stopped')
|
||||
});
|
||||
}
|
||||
|
||||
public stop() {
|
||||
if(this.processStatus !== 'running') return
|
||||
if (this.process) {
|
||||
console.log('[INFO] Trying to stop process, PID:', this.process.pid)
|
||||
if (process.platform === "win32" && this.process.pid) {
|
||||
exec(`taskkill /pid ${this.process.pid} /t /f`, (error) => {
|
||||
if (error) {
|
||||
@@ -124,12 +135,8 @@ export class CaptionEngine {
|
||||
this.process.kill('SIGKILL');
|
||||
}
|
||||
}
|
||||
this.process = undefined;
|
||||
allConfig.controls.engineEnabled = false;
|
||||
console.log('[INFO] Caption engine process stopped')
|
||||
if(controlWindow.window) {
|
||||
allConfig.sendControls(controlWindow.window)
|
||||
}
|
||||
this.processStatus = 'stopping'
|
||||
console.log('[INFO] Caption engine process stopping')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user