mirror of
https://github.com/HiMeditator/auto-caption.git
synced 2026-02-21 08:34:43 +08:00
feat(renderer): 初步添加字幕显示窗口
This commit is contained in:
22
package-lock.json
generated
22
package-lock.json
generated
@@ -13,6 +13,7 @@
|
|||||||
"@electron-toolkit/utils": "^4.0.0",
|
"@electron-toolkit/utils": "^4.0.0",
|
||||||
"ant-design-vue": "^4.2.6",
|
"ant-design-vue": "^4.2.6",
|
||||||
"pinia": "^3.0.2",
|
"pinia": "^3.0.2",
|
||||||
|
"vue-router": "^4.5.1",
|
||||||
"ws": "^8.18.2"
|
"ws": "^8.18.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -9429,6 +9430,27 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vue-router": {
|
||||||
|
"version": "4.5.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.5.1.tgz",
|
||||||
|
"integrity": "sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@vue/devtools-api": "^6.6.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/posva"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"vue": "^3.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/vue-router/node_modules/@vue/devtools-api": {
|
||||||
|
"version": "6.6.4",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
|
||||||
|
"integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/vue-tsc": {
|
"node_modules/vue-tsc": {
|
||||||
"version": "2.2.10",
|
"version": "2.2.10",
|
||||||
"resolved": "https://registry.npmmirror.com/vue-tsc/-/vue-tsc-2.2.10.tgz",
|
"resolved": "https://registry.npmmirror.com/vue-tsc/-/vue-tsc-2.2.10.tgz",
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
"@electron-toolkit/utils": "^4.0.0",
|
"@electron-toolkit/utils": "^4.0.0",
|
||||||
"ant-design-vue": "^4.2.6",
|
"ant-design-vue": "^4.2.6",
|
||||||
"pinia": "^3.0.2",
|
"pinia": "^3.0.2",
|
||||||
|
"vue-router": "^4.5.1",
|
||||||
"ws": "^8.18.2"
|
"ws": "^8.18.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { electronApp, optimizer, is } from '@electron-toolkit/utils'
|
|||||||
import icon from '../../resources/icon.png?asset'
|
import icon from '../../resources/icon.png?asset'
|
||||||
|
|
||||||
let mainWindow: BrowserWindow | undefined
|
let mainWindow: BrowserWindow | undefined
|
||||||
|
let captionWindow: BrowserWindow | undefined
|
||||||
function createMainWindow(): void {
|
function createMainWindow(): void {
|
||||||
mainWindow = new BrowserWindow({
|
mainWindow = new BrowserWindow({
|
||||||
icon: icon,
|
icon: icon,
|
||||||
@@ -36,6 +36,39 @@ function createMainWindow(): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createCaptionWindow(): void {
|
||||||
|
captionWindow = new BrowserWindow({
|
||||||
|
icon: icon,
|
||||||
|
width: 900,
|
||||||
|
height: 670,
|
||||||
|
show: false,
|
||||||
|
center: true,
|
||||||
|
autoHideMenuBar: true,
|
||||||
|
...(process.platform === 'linux' ? { icon } : {}),
|
||||||
|
webPreferences: {
|
||||||
|
preload: path.join(__dirname, '../preload/index.js'),
|
||||||
|
sandbox: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
captionWindow.on('ready-to-show', () => {
|
||||||
|
captionWindow?.show()
|
||||||
|
})
|
||||||
|
|
||||||
|
captionWindow.webContents.setWindowOpenHandler((details) => {
|
||||||
|
shell.openExternal(details.url)
|
||||||
|
return { action: 'deny' }
|
||||||
|
})
|
||||||
|
|
||||||
|
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
|
||||||
|
captionWindow.loadURL(`${process.env['ELECTRON_RENDERER_URL']}/#/caption`)
|
||||||
|
} else {
|
||||||
|
captionWindow.loadFile(path.join(__dirname, '../renderer/index.html'), {
|
||||||
|
hash: 'caption'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
app.whenReady().then(() => {
|
app.whenReady().then(() => {
|
||||||
electronApp.setAppUserModelId('com.himeditator.autocaption')
|
electronApp.setAppUserModelId('com.himeditator.autocaption')
|
||||||
|
|
||||||
@@ -44,6 +77,7 @@ app.whenReady().then(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
createMainWindow()
|
createMainWindow()
|
||||||
|
createCaptionWindow()
|
||||||
|
|
||||||
app.on('activate', function () {
|
app.on('activate', function () {
|
||||||
if (BrowserWindow.getAllWindows().length === 0) createMainWindow()
|
if (BrowserWindow.getAllWindows().length === 0) createMainWindow()
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<title>Auto Caption Player</title>
|
|
||||||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
|
||||||
<meta
|
|
||||||
http-equiv="Content-Security-Policy"
|
|
||||||
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"
|
|
||||||
/>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div id="app"></div>
|
|
||||||
<script type="module" src="/src/main.ts"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<template>
|
|
||||||
<h1>Caption</h1>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
</script>
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
background-color: black;
|
|
||||||
}
|
|
||||||
1
src/renderer/caption/src/env.d.ts
vendored
1
src/renderer/caption/src/env.d.ts
vendored
@@ -1 +0,0 @@
|
|||||||
/// <reference types="vite/client" />
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
import './assets/styles/reset.css'
|
|
||||||
import { createPinia } from 'pinia'
|
|
||||||
import { createApp } from 'vue'
|
|
||||||
import App from './App.vue'
|
|
||||||
|
|
||||||
const app = createApp(App)
|
|
||||||
app.use(createPinia())
|
|
||||||
app.mount('#app')
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
import { ref } from 'vue'
|
|
||||||
import { defineStore } from 'pinia'
|
|
||||||
|
|
||||||
export const useCaptionStore = defineStore('caption', () => {
|
|
||||||
const captionFontFamily = ref<string>('sans-serif')
|
|
||||||
const captionFontSize = ref<number>(24)
|
|
||||||
const captionFontColor = ref<string>('#ffffff')
|
|
||||||
return { captionFontFamily, captionFontSize, captionFontColor }
|
|
||||||
})
|
|
||||||
@@ -1,56 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<router-view></router-view>
|
||||||
<a-row>
|
|
||||||
<a-col :span="controlSpan">
|
|
||||||
<div class="caption-control">
|
|
||||||
<a-card size="small" title="页面宽度">
|
|
||||||
<div>
|
|
||||||
<a-input
|
|
||||||
type="range" class="span-input"
|
|
||||||
min="6" max="18"
|
|
||||||
v-model:value="controlSpan"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</a-card>
|
|
||||||
<CaptionControl />
|
|
||||||
<CaptionStyle />
|
|
||||||
</div>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="24 - controlSpan">
|
|
||||||
<div class="caption-data">
|
|
||||||
<CaptionData />
|
|
||||||
</div>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import CaptionStyle from './components/CaptionStyle.vue'
|
|
||||||
import CaptionControl from './components/CaptionControl.vue';
|
|
||||||
import CaptionData from './components/CaptionData.vue'
|
|
||||||
import { ref } from 'vue'
|
|
||||||
const controlSpan = ref(8)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.caption-control {
|
|
||||||
height: 100vh;
|
|
||||||
border-right: 1px solid #7774;
|
|
||||||
padding: 20px;
|
|
||||||
overflow-y: auto;
|
|
||||||
scrollbar-width: thin;
|
|
||||||
}
|
|
||||||
|
|
||||||
.caption-data {
|
|
||||||
height: 100vh;
|
|
||||||
padding: 20px;
|
|
||||||
overflow-y: auto;
|
|
||||||
scrollbar-width: thin;
|
|
||||||
}
|
|
||||||
|
|
||||||
.span-input {
|
|
||||||
width: 100px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -2,7 +2,8 @@
|
|||||||
<div style="height: 20px;"></div>
|
<div style="height: 20px;"></div>
|
||||||
<a-card size="small" title="字幕控制">
|
<a-card size="small" title="字幕控制">
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<a @click="applyControl">应用</a>
|
<a @click="applyChange">更改设置</a> |
|
||||||
|
<a @click="cancelChange">取消更改</a>
|
||||||
</template>
|
</template>
|
||||||
<div class="control-item">
|
<div class="control-item">
|
||||||
<span class="control-label">源语言</span>
|
<span class="control-label">源语言</span>
|
||||||
@@ -71,13 +72,21 @@ const langList = computed(() => {
|
|||||||
return []
|
return []
|
||||||
})
|
})
|
||||||
|
|
||||||
function applyControl(){
|
function applyChange(){
|
||||||
captionControl.sourceLang = currentSourceLang.value
|
captionControl.sourceLang = currentSourceLang.value
|
||||||
captionControl.targetLang = currentTargetLang.value
|
captionControl.targetLang = currentTargetLang.value
|
||||||
captionControl.engine = currentEngine.value
|
captionControl.engine = currentEngine.value
|
||||||
captionControl.port = currentPort.value
|
captionControl.port = currentPort.value
|
||||||
captionControl.translation = currentTranslation.value
|
captionControl.translation = currentTranslation.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cancelChange(){
|
||||||
|
currentSourceLang.value = captionControl.sourceLang
|
||||||
|
currentTargetLang.value = captionControl.targetLang
|
||||||
|
currentEngine.value = captionControl.engine
|
||||||
|
currentPort.value = captionControl.port
|
||||||
|
currentTranslation.value = captionControl.translation
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
import './assets/styles/reset.css'
|
import './assets/styles/reset.css'
|
||||||
import { createPinia } from 'pinia'
|
import { createPinia } from 'pinia'
|
||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
|
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
|
import router from './router'
|
||||||
import Antd from 'ant-design-vue';
|
import Antd from 'ant-design-vue';
|
||||||
import 'ant-design-vue/dist/reset.css';
|
import 'ant-design-vue/dist/reset.css';
|
||||||
|
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
app.use(createPinia())
|
app.use(createPinia())
|
||||||
|
app.use(router)
|
||||||
app.use(Antd)
|
app.use(Antd)
|
||||||
app.mount('#app')
|
app.mount('#app')
|
||||||
21
src/renderer/src/router/index.ts
Normal file
21
src/renderer/src/router/index.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { createRouter, createWebHashHistory } from 'vue-router'
|
||||||
|
import HomePage from '../views/HomePage.vue'
|
||||||
|
import CaptionPage from '@renderer/views/CaptionPage.vue'
|
||||||
|
|
||||||
|
const router = createRouter({
|
||||||
|
history: createWebHashHistory(),
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
name: 'home',
|
||||||
|
component: HomePage
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/caption',
|
||||||
|
name: 'caption',
|
||||||
|
component: CaptionPage
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
export default router
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<h1>字幕测试 字幕测试 字幕测试</h1>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
52
src/renderer/src/views/HomePage.vue
Normal file
52
src/renderer/src/views/HomePage.vue
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<a-row>
|
||||||
|
<a-col :span="controlSpan">
|
||||||
|
<div class="caption-control">
|
||||||
|
<a-card size="small" title="页面宽度">
|
||||||
|
<div>
|
||||||
|
<a-input type="range" class="span-input" min="6" max="18" v-model:value="controlSpan" />
|
||||||
|
</div>
|
||||||
|
</a-card>
|
||||||
|
<CaptionControl />
|
||||||
|
<CaptionStyle />
|
||||||
|
</div>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="24 - controlSpan">
|
||||||
|
<div class="caption-data">
|
||||||
|
<CaptionData />
|
||||||
|
</div>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import CaptionStyle from '../components/CaptionStyle.vue'
|
||||||
|
import CaptionControl from '../components/CaptionControl.vue';
|
||||||
|
import CaptionData from '../components/CaptionData.vue'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
const controlSpan = ref(8)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.caption-control {
|
||||||
|
height: 100vh;
|
||||||
|
border-right: 1px solid #7774;
|
||||||
|
padding: 20px;
|
||||||
|
overflow-y: auto;
|
||||||
|
scrollbar-width: thin;
|
||||||
|
}
|
||||||
|
|
||||||
|
.caption-data {
|
||||||
|
height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
overflow-y: auto;
|
||||||
|
scrollbar-width: thin;
|
||||||
|
}
|
||||||
|
|
||||||
|
.span-input {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user