diff --git a/CHANGELOG.md b/CHANGELOG.md index ddede83..8d0dcf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,5 +25,18 @@ 2025-07- -> 预计为稳定版,之后除非大改,否则版本号第一位不再改变。 +本版本为正式版。 + +### 新增功能 + +- 添加多界面语言支持(中文、英语、日语) + +### 提升体验 + +- 优化界面布局 +- 添加更多可保存和载入的配置项 + +### 新增文档 + +### 修复bug diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..fcca37c --- /dev/null +++ b/TODO.md @@ -0,0 +1,4 @@ +- [x] 添加英语和日语语言支持 +- [ ] 优化长字幕显示效果 +- [ ] 修复字幕引擎空置报错的问题 +- [ ] 添加更多字幕引擎 diff --git a/assets/technical-docs/api-doc.md b/assets/technical-docs/api-doc.md index 3540ff1..b8924c0 100644 --- a/assets/technical-docs/api-doc.md +++ b/assets/technical-docs/api-doc.md @@ -18,6 +18,41 @@ ## 前端 <=> 后端 +### `both.window.mounted` + +**介绍:**前端窗口挂载完毕,请求最新的配置数据 + +**发起方:**前端 + +**接收方:**后端 + +**数据类型:** + +- 发送:无数据 +- 接收:`FullConfig` + +## 前端 ==> 后端 + +### `control.uiLanguage.change` + +**介绍:**前端修改字界面语言,将修改同步给后端 + +**发起方:**前端控制窗口 + +**接收方:**后端控制窗口实例 + +**数据类型:**`UILanguage` + +### `control.leftBarWidth.change` + +**介绍:**前端修改边栏宽度,将修改同步给后端 + +**发起方:**前端控制窗口 + +**接收方:**后端控制窗口实例 + +**数据类型:**`number` + ### `control.captionLog.clear` **介绍:**清空字幕记录 @@ -26,12 +61,7 @@ **接收方:**后端控制窗口实例 -**数据类型:** - -- 发送:无数据 -- 接收:`CaptionItem[]` - -## 前端 ==> 后端 +**数据类型:**无数据 ### `control.styles.change` @@ -135,19 +165,19 @@ ## 后端 ==> 前端 -### `control.engine.already` +### `caption.uiLanguage.set` -**介绍:**引擎已经启动 +**介绍:**后端将最新界面语言发送给前端,前端进行设置 **发起方:**后端 -**接收方:**前端控制窗口 +**接收方:**字幕窗口 -**数据类型:**无数据 +**数据类型:**`UILanguage` ### `control.engine.started` -**介绍:**引擎启动 +**介绍:**引擎启动成功 **发起方:**后端 @@ -185,7 +215,7 @@ **数据类型:**`Controls` -### `caption.styles.set` +### `both.styles.set` **介绍:**后端将最新字幕样式发送给前端,前端进行设置 diff --git a/src/main/CaptionWindow.ts b/src/main/CaptionWindow.ts index a28c13f..ea04d04 100644 --- a/src/main/CaptionWindow.ts +++ b/src/main/CaptionWindow.ts @@ -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) diff --git a/src/main/ControlWindow.ts b/src/main/ControlWindow.ts index 7172a4b..8a3ee69 100644 --- a/src/main/ControlWindow.ts +++ b/src/main/ControlWindow.ts @@ -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 }) } diff --git a/src/main/types/index.ts b/src/main/types/index.ts index 84d1516..4806ed0 100644 --- a/src/main/types/index.ts +++ b/src/main/types/index.ts @@ -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[] } diff --git a/src/main/utils/AllConfig.ts b/src/main/utils/AllConfig.ts index 31753c4..9b8867b 100644 --- a/src/main/utils/AllConfig.ts +++ b/src/main/utils/AllConfig.ts @@ -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' } diff --git a/src/main/utils/CaptionEngine.ts b/src/main/utils/CaptionEngine.ts index 30b262a..a7c977a 100644 --- a/src/main/utils/CaptionEngine.ts +++ b/src/main/utils/CaptionEngine.ts @@ -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') } } diff --git a/src/renderer/src/App.vue b/src/renderer/src/App.vue index 314e3d5..1a4a3f2 100644 --- a/src/renderer/src/App.vue +++ b/src/renderer/src/App.vue @@ -4,10 +4,20 @@ diff --git a/src/renderer/src/components/CaptionStyle.vue b/src/renderer/src/components/CaptionStyle.vue index 636a184..3ee3069 100644 --- a/src/renderer/src/components/CaptionStyle.vue +++ b/src/renderer/src/components/CaptionStyle.vue @@ -54,8 +54,8 @@
{{ $t('general.note') }}
+ +