mirror of
https://github.com/HiMeditator/auto-caption.git
synced 2026-02-22 01:14:41 +08:00
feat(main): 实现字幕引擎控制功能
- 新增字幕引擎启动和停止功能 - 实现控制窗口的字幕引擎状态显示 - 优化字幕日志的发送逻辑 - 重构子进程相关代码
This commit is contained in:
@@ -30,7 +30,7 @@ class CaptionWindow {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (this.window) {
|
if (this.window) {
|
||||||
sendStyles(this.window);
|
sendStyles(this.window);
|
||||||
sendCaptionLog(this.window);
|
sendCaptionLog(this.window, 'set');
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
|
|||||||
@@ -4,15 +4,18 @@ import { is } from '@electron-toolkit/utils'
|
|||||||
import icon from '../../resources/icon.png?asset'
|
import icon from '../../resources/icon.png?asset'
|
||||||
import { captionWindow } from './caption'
|
import { captionWindow } from './caption'
|
||||||
import {
|
import {
|
||||||
|
captionEngine,
|
||||||
|
controls,
|
||||||
setStyles,
|
setStyles,
|
||||||
sendStyles,
|
sendStyles,
|
||||||
sendCaptionLog,
|
sendCaptionLog,
|
||||||
setControls
|
setControls,
|
||||||
|
sendControls
|
||||||
} from './utils/config'
|
} from './utils/config'
|
||||||
|
|
||||||
class ControlWindow {
|
class ControlWindow {
|
||||||
window: BrowserWindow | undefined;
|
window: BrowserWindow | undefined;
|
||||||
|
|
||||||
public createWindow(): void {
|
public createWindow(): void {
|
||||||
this.window = new BrowserWindow({
|
this.window = new BrowserWindow({
|
||||||
icon: icon,
|
icon: icon,
|
||||||
@@ -32,8 +35,9 @@ class ControlWindow {
|
|||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (this.window) {
|
if (this.window) {
|
||||||
sendStyles(this.window);
|
sendStyles(this.window) // 配置初始样式
|
||||||
sendCaptionLog(this.window);
|
sendCaptionLog(this.window, 'set') // 配置当前字幕记录
|
||||||
|
sendControls(this.window) // 配置字幕引擎配置
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
@@ -75,10 +79,25 @@ class ControlWindow {
|
|||||||
captionWindow.window.show()
|
captionWindow.window.show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// 字幕引擎控制配置更新
|
// 字幕引擎控制配置更新并启动引擎
|
||||||
ipcMain.on('control.control.change', (_, args) => {
|
ipcMain.on('control.control.change', (_, args) => {
|
||||||
setControls(args)
|
setControls(args)
|
||||||
})
|
})
|
||||||
|
// 启动字幕引擎
|
||||||
|
ipcMain.on('control.engine.start', () => {
|
||||||
|
if(controls.engineEnabled){
|
||||||
|
this.window?.webContents.send('control.engine.already')
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
captionEngine.start()
|
||||||
|
this.window?.webContents.send('control.engine.started')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 停止字幕引擎
|
||||||
|
ipcMain.on('control.engine.stop', () => {
|
||||||
|
captionEngine.stop()
|
||||||
|
this.window?.webContents.send('control.engine.stopped')
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,6 @@ import { electronApp, optimizer } from '@electron-toolkit/utils'
|
|||||||
import { controlWindow } from './control'
|
import { controlWindow } from './control'
|
||||||
import { captionWindow } from './caption'
|
import { captionWindow } from './caption'
|
||||||
|
|
||||||
import { PythonProcess } from './utils/pythonProcess'
|
|
||||||
const pySubProcess = new PythonProcess()
|
|
||||||
|
|
||||||
app.whenReady().then(() => {
|
app.whenReady().then(() => {
|
||||||
electronApp.setAppUserModelId('com.himeditator.autocaption')
|
electronApp.setAppUserModelId('com.himeditator.autocaption')
|
||||||
|
|
||||||
@@ -18,8 +15,6 @@ app.whenReady().then(() => {
|
|||||||
|
|
||||||
controlWindow.createWindow()
|
controlWindow.createWindow()
|
||||||
|
|
||||||
// pySubProcess.start()
|
|
||||||
|
|
||||||
app.on('activate', function () {
|
app.on('activate', function () {
|
||||||
if (BrowserWindow.getAllWindows().length === 0){
|
if (BrowserWindow.getAllWindows().length === 0){
|
||||||
controlWindow.createWindow()
|
controlWindow.createWindow()
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ export interface CaptionItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface Controls {
|
export interface Controls {
|
||||||
|
engineEnabled: boolean,
|
||||||
sourceLang: string,
|
sourceLang: string,
|
||||||
targetLang: string,
|
targetLang: string,
|
||||||
engine: string,
|
engine: string,
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
import { Styles, CaptionItem, Controls } from '../types'
|
import { Styles, CaptionItem, Controls } from '../types'
|
||||||
import { BrowserWindow } from 'electron'
|
import { BrowserWindow } from 'electron'
|
||||||
|
import { CaptionEngine } from './engine'
|
||||||
|
|
||||||
|
export const captionEngine = new CaptionEngine()
|
||||||
|
|
||||||
export const styles: Styles = {
|
export const styles: Styles = {
|
||||||
fontFamily: 'sans-serif',
|
fontFamily: 'sans-serif',
|
||||||
@@ -19,12 +22,15 @@ export const controls: Controls = {
|
|||||||
sourceLang: 'en',
|
sourceLang: 'en',
|
||||||
targetLang: 'zh',
|
targetLang: 'zh',
|
||||||
engine: 'gummy',
|
engine: 'gummy',
|
||||||
|
engineEnabled: false,
|
||||||
translation: true,
|
translation: true,
|
||||||
customized: false,
|
customized: false,
|
||||||
customizedApp: '',
|
customizedApp: '',
|
||||||
customizedCommand: ''
|
customizedCommand: ''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export let engineRunning: boolean = false
|
||||||
|
|
||||||
export function setStyles(args: any) {
|
export function setStyles(args: any) {
|
||||||
styles.fontFamily = args.fontFamily
|
styles.fontFamily = args.fontFamily
|
||||||
styles.fontSize = args.fontSize
|
styles.fontSize = args.fontSize
|
||||||
@@ -40,23 +46,27 @@ export function setStyles(args: any) {
|
|||||||
|
|
||||||
export function sendStyles(window: BrowserWindow) {
|
export function sendStyles(window: BrowserWindow) {
|
||||||
window.webContents.send('caption.style.set', styles)
|
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) {
|
export function sendCaptionLog(window: BrowserWindow, command: string) {
|
||||||
window.webContents.send('both.log.set', captionLog)
|
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) {
|
export function addCaptionLog(log: CaptionItem) {
|
||||||
if(captionLog.length && captionLog[captionLog.length - 1].index === log.index) {
|
if(captionLog.length && captionLog[captionLog.length - 1].index === log.index) {
|
||||||
captionLog.splice(captionLog.length - 1, 1)
|
captionLog.splice(captionLog.length - 1, 1, log)
|
||||||
captionLog.push(log)
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
captionLog.push(log)
|
captionLog.push(log)
|
||||||
}
|
}
|
||||||
for(const window of BrowserWindow.getAllWindows()){
|
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.customizedApp = args.customizedApp
|
||||||
controls.customizedCommand = args.customizedCommand
|
controls.customizedCommand = args.customizedCommand
|
||||||
console.log('[INFO] Set Controls:', controls)
|
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
79
src/main/utils/engine.ts
Normal 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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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}`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -59,12 +59,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed } from 'vue'
|
import { ref, computed, watch } from 'vue'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { useCaptionControlStore } from '@renderer/stores/captionControl'
|
import { useCaptionControlStore } from '@renderer/stores/captionControl'
|
||||||
|
|
||||||
const captionControl = useCaptionControlStore()
|
const captionControl = useCaptionControlStore()
|
||||||
const { captionEngine } = storeToRefs(captionControl)
|
const { captionEngine, changeSignal } = storeToRefs(captionControl)
|
||||||
|
|
||||||
const currentSourceLang = ref('auto')
|
const currentSourceLang = ref('auto')
|
||||||
const currentTargetLang = ref('zh')
|
const currentTargetLang = ref('zh')
|
||||||
@@ -107,6 +107,13 @@ function cancelChange(){
|
|||||||
currentCustomizedApp.value = captionControl.customizedApp
|
currentCustomizedApp.value = captionControl.customizedApp
|
||||||
currentCustomizedCommand.value = captionControl.customizedCommand
|
currentCustomizedCommand.value = captionControl.customizedCommand
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watch(changeSignal, (val) => {
|
||||||
|
if(val == true) {
|
||||||
|
cancelChange();
|
||||||
|
captionControl.changeSignal = false;
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
<div class="caption-stat">
|
<div class="caption-stat">
|
||||||
<a-row>
|
<a-row>
|
||||||
<a-col :span="6">
|
<a-col :span="6">
|
||||||
<a-statistic title="字幕引擎" :value="'gummy'" />
|
<a-statistic title="字幕引擎" :value="engine" />
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="6">
|
<a-col :span="6">
|
||||||
<a-statistic title="字幕引擎状态" :value="'未连接'" />
|
<a-statistic title="字幕引擎状态" :value="engineEnabled?'已启动':'未启动'" />
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="6">
|
<a-col :span="6">
|
||||||
<a-statistic title="已记录字幕" :value="captionData.length" />
|
<a-statistic title="已记录字幕" :value="captionData.length" />
|
||||||
@@ -14,9 +14,19 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="caption-control">
|
<div class="caption-control">
|
||||||
<a-button type="primary" class="control-button" @click="openCaptionWindow">打开字幕窗口</a-button>
|
<a-button
|
||||||
<a-button class="control-button">启动字幕引擎</a-button>
|
type="primary"
|
||||||
<a-button danger class="control-button">关闭字幕引擎</a-button>
|
class="control-button"
|
||||||
|
@click="openCaptionWindow"
|
||||||
|
>打开字幕窗口</a-button>
|
||||||
|
<a-button
|
||||||
|
class="control-button"
|
||||||
|
@click="captionControl.startEngine"
|
||||||
|
>启动字幕引擎</a-button>
|
||||||
|
<a-button
|
||||||
|
danger class="control-button"
|
||||||
|
@click="captionControl.stopEngine"
|
||||||
|
>关闭字幕引擎</a-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="caption-list">
|
<div class="caption-list">
|
||||||
@@ -51,9 +61,11 @@
|
|||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { useCaptionLogStore } from '@renderer/stores/captionLog'
|
import { useCaptionLogStore } from '@renderer/stores/captionLog'
|
||||||
|
import { useCaptionControlStore } from '@renderer/stores/captionControl'
|
||||||
const captionLog = useCaptionLogStore()
|
const captionLog = useCaptionLogStore()
|
||||||
const { captionData } = storeToRefs(captionLog)
|
const { captionData } = storeToRefs(captionLog)
|
||||||
|
const captionControl = useCaptionControlStore()
|
||||||
|
const { engineEnabled, engine } = storeToRefs(captionControl)
|
||||||
const pagination = ref({
|
const pagination = ref({
|
||||||
current: 1,
|
current: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
@@ -93,7 +105,6 @@ const columns = [
|
|||||||
function openCaptionWindow() {
|
function openCaptionWindow() {
|
||||||
window.electron.ipcRenderer.send('control.captionWindow.activate')
|
window.electron.ipcRenderer.send('control.captionWindow.activate')
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
|
import { notification } from 'ant-design-vue'
|
||||||
|
|
||||||
export const useCaptionControlStore = defineStore('captionControl', () => {
|
export const useCaptionControlStore = defineStore('captionControl', () => {
|
||||||
const captionEngine = ref([
|
const captionEngine = ref([
|
||||||
@@ -24,18 +25,21 @@ export const useCaptionControlStore = defineStore('captionControl', () => {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
const engineEnabled = ref(false)
|
||||||
|
|
||||||
const sourceLang = ref<string>('auto')
|
const sourceLang = ref<string>('en')
|
||||||
const targetLang = ref<string>('zh')
|
const targetLang = ref<string>('zh')
|
||||||
const engine = ref<string>('gummy')
|
const engine = ref<string>('gummy')
|
||||||
const translation = ref<boolean>(false)
|
const translation = ref<boolean>(true)
|
||||||
const customized = ref<boolean>(false)
|
const customized = ref<boolean>(false)
|
||||||
const customizedApp = ref<string>('')
|
const customizedApp = ref<string>('')
|
||||||
const customizedCommand = ref<string>('')
|
const customizedCommand = ref<string>('')
|
||||||
|
|
||||||
|
const changeSignal = ref<boolean>(false)
|
||||||
|
|
||||||
function sendControlChange() {
|
function sendControlChange() {
|
||||||
const controls = {
|
const controls = {
|
||||||
|
engineEnabled: engineEnabled.value,
|
||||||
sourceLang: sourceLang.value,
|
sourceLang: sourceLang.value,
|
||||||
targetLang: targetLang.value,
|
targetLang: targetLang.value,
|
||||||
engine: engine.value,
|
engine: engine.value,
|
||||||
@@ -47,8 +51,52 @@ export const useCaptionControlStore = defineStore('captionControl', () => {
|
|||||||
window.electron.ipcRenderer.send('control.control.change', controls)
|
window.electron.ipcRenderer.send('control.control.change', controls)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function startEngine() {
|
||||||
|
window.electron.ipcRenderer.send('control.engine.start')
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopEngine() {
|
||||||
|
window.electron.ipcRenderer.send('control.engine.stop')
|
||||||
|
}
|
||||||
|
|
||||||
|
window.electron.ipcRenderer.on('control.control.set', (_, controls) => {
|
||||||
|
sourceLang.value = controls.sourceLang
|
||||||
|
targetLang.value = controls.targetLang
|
||||||
|
engine.value = controls.engine
|
||||||
|
translation.value = controls.translation
|
||||||
|
customized.value = controls.customized
|
||||||
|
customizedApp.value = controls.customizedApp
|
||||||
|
customizedCommand.value = controls.customizedCommand
|
||||||
|
changeSignal.value = true
|
||||||
|
})
|
||||||
|
|
||||||
|
window.electron.ipcRenderer.on('control.engine.already', () => {
|
||||||
|
engineEnabled.value = true
|
||||||
|
notification.open({
|
||||||
|
message: '字幕引擎已经启动',
|
||||||
|
description: '字幕引擎已经启动,请勿重复启动'
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
window.electron.ipcRenderer.on('control.engine.started', () => {
|
||||||
|
engineEnabled.value = true
|
||||||
|
notification.open({
|
||||||
|
message: '字幕引擎启动',
|
||||||
|
description: `原语言:${sourceLang.value},是否翻译:${translation.value?'是':'否'},翻译语言:${targetLang.value}`
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
window.electron.ipcRenderer.on('control.engine.stopped', () => {
|
||||||
|
engineEnabled.value = false
|
||||||
|
notification.open({
|
||||||
|
message: '字幕引擎停止',
|
||||||
|
description: '可点击“启动字幕引擎”按钮重新启动'
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
captionEngine, // 字幕引擎
|
captionEngine, // 字幕引擎
|
||||||
|
engineEnabled, // 字幕引擎是否启用
|
||||||
sourceLang, // 源语言
|
sourceLang, // 源语言
|
||||||
targetLang, // 目标语言
|
targetLang, // 目标语言
|
||||||
engine, // 字幕引擎
|
engine, // 字幕引擎
|
||||||
@@ -56,6 +104,9 @@ export const useCaptionControlStore = defineStore('captionControl', () => {
|
|||||||
customized, // 是否使用自定义字幕引擎
|
customized, // 是否使用自定义字幕引擎
|
||||||
customizedApp, // 自定义字幕引擎的应用程序
|
customizedApp, // 自定义字幕引擎的应用程序
|
||||||
customizedCommand, // 自定义字幕引擎的命令
|
customizedCommand, // 自定义字幕引擎的命令
|
||||||
sendControlChange // 发送最新控制消息到后端
|
sendControlChange, // 发送最新控制消息到后端
|
||||||
|
startEngine, // 启动字幕引擎
|
||||||
|
stopEngine, // 停止字幕引擎
|
||||||
|
changeSignal, // 配置改变信号
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -12,6 +12,15 @@ interface CaptionItem {
|
|||||||
export const useCaptionLogStore = defineStore('captionLog', () => {
|
export const useCaptionLogStore = defineStore('captionLog', () => {
|
||||||
const captionData = ref<CaptionItem[]>([])
|
const captionData = ref<CaptionItem[]>([])
|
||||||
|
|
||||||
|
window.electron.ipcRenderer.on('both.log.add', (_, log) => {
|
||||||
|
if(captionData.value.length && log.index === captionData.value[captionData.value.length - 1].index) {
|
||||||
|
captionData.value.splice(captionData.value.length - 1, 1, log)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
captionData.value.push(log)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
window.electron.ipcRenderer.on('both.log.set', (_, logs) => {
|
window.electron.ipcRenderer.on('both.log.set', (_, logs) => {
|
||||||
captionData.value = logs
|
captionData.value = logs
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -7,10 +7,12 @@ export const useCaptionStyleStore = defineStore('captionStyle', () => {
|
|||||||
const fontColor = ref<string>('#000000')
|
const fontColor = ref<string>('#000000')
|
||||||
const background = ref<string>('#dbe2ef')
|
const background = ref<string>('#dbe2ef')
|
||||||
const opacity = ref<number>(80)
|
const opacity = ref<number>(80)
|
||||||
|
|
||||||
const transDisplay = ref<boolean>(true)
|
const transDisplay = ref<boolean>(true)
|
||||||
const transFontFamily = ref<string>('sans-serif')
|
const transFontFamily = ref<string>('sans-serif')
|
||||||
const transFontSize = ref<number>(24)
|
const transFontSize = ref<number>(24)
|
||||||
const transFontColor = ref<string>('#000000')
|
const transFontColor = ref<string>('#000000')
|
||||||
|
|
||||||
const changeSignal = ref<boolean>(false)
|
const changeSignal = ref<boolean>(false)
|
||||||
|
|
||||||
function addOpicityToColor(color: string, opicity: number) {
|
function addOpicityToColor(color: string, opicity: number) {
|
||||||
|
|||||||
Reference in New Issue
Block a user