feat: 实现简易字幕

- 添加静态视频
- 添加简易字幕,可修改部分字幕属性
This commit is contained in:
himeditator
2025-05-11 23:50:31 +08:00
parent ccf401a6ab
commit b77ce711a3
12 changed files with 273 additions and 32 deletions

View File

@@ -1,7 +1,9 @@
<template>
<h1>Auto Caption</h1>
<ViedoPlayer />
<Caption />
</template>
<script setup lang="ts">
import ViedoPlayer from './components/VideoPlayer.vue'
import Caption from './components/Caption.vue'
</script>

View File

@@ -0,0 +1,11 @@
<template>
</template>
<script setup lang="ts">
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,5 @@
body {
margin: 0;
padding: 0;
background-color: black;
}

Binary file not shown.

View File

@@ -0,0 +1,44 @@
<template>
<div
class="video-caption"
v-if="captionContent"
ref="captionTarget"
:style="{
color: captionFontColor,
fontSize: captionFontSize + 'px',
fontFamily: captionFontFamily
}"
>
{{ captionContent }}
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { storeToRefs } from 'pinia'
import { useCaptionStore } from '../stores/caption'
const captionContent = ref<String>("これは確か、ずっと前に人からもらって。")
const {captionFontColor, captionFontFamily, captionFontSize} = storeToRefs(useCaptionStore())
const captionTarget = ref()
window.electron.ipcRenderer.on('new-caption', (_, data) => {
captionContent.value = data
})
</script>
<style scoped>
.video-caption {
color: white;
background-color: rgba(99, 99, 99, 0.4);
display: inline-block;
max-width: 80%;
padding: 10px;
font-size: 32px;
font-weight: bold;
border-radius: 10px;
position: fixed;
bottom: 50px;
left: 50%;
transform: translateX(-50%);
}
</style>

View File

@@ -0,0 +1,28 @@
<template>
<div class="settings">
<input type="color" v-model="captionFontColor">
<input type="text" v-model="captionFontFamily">
<input type="number" v-model="captionFontSize">
</div>
</template>
<script setup lang="ts">
import { storeToRefs } from 'pinia'
import { useCaptionStore } from '../stores/caption'
const {captionFontColor, captionFontFamily, captionFontSize} = storeToRefs(useCaptionStore())
</script>
<style scoped>
.settings {
display: flex;
align-items: center;
width: 100%;
height: 50px;
background-color: black;
box-sizing: border-box;
}
input {
height: 30px;
margin: auto 20px;
}
</style>

View File

@@ -0,0 +1,24 @@
<template>
<div class="video-player">
<video src="../assets/video/example-ja.mp4" controls></video>
<Settings />
</div>
</template>
<script setup lang="ts">
import Settings from './Settings.vue'
</script>
<style scoped>
.video-player {
display: flex;
height: 100vh;
align-items: center;
flex-wrap: wrap;
}
video {
width: 100%;
height: calc(100vh - 50px);
}
</style>

View File

@@ -1,4 +1,8 @@
import './assets/styles/reset.css'
import { createPinia } from 'pinia'
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
const app = createApp(App)
app.use(createPinia())
app.mount('#app')

View File

@@ -0,0 +1,9 @@
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 }
})