diff --git a/components/aigc/generation/CGTaskCard.client.vue b/components/aigc/generation/CGTaskCard.client.vue
new file mode 100644
index 0000000..d955e57
--- /dev/null
+++ b/components/aigc/generation/CGTaskCard.client.vue
@@ -0,0 +1,295 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ stateDisplay.text }}
+
+
+
+
+
+
+
+
+ {{ course.title }}
+
+
+ {{ dayjs(course.create_time * 1000).format('YYYY-MM-DD HH:mm:ss') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
微课视频预览
+
+ {{ course.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
嵌入视频字幕
+
+ {{ course.title }}
+
+
+
+
+
+
+
+
+ {{ step }}
+
+
+
+
+
+ {{ step }}
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/aigc/generation/CGTaskCard.vue b/components/aigc/generation/CGTaskCard.vue
deleted file mode 100644
index 82595bd..0000000
--- a/components/aigc/generation/CGTaskCard.vue
+++ /dev/null
@@ -1,296 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ stateDisplay.text }}
-
-
-
-
-
-
-
-
- {{ course.title }}
-
-
- {{ dayjs(course.create_time * 1000).format('YYYY-MM-DD HH:mm:ss') }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
微课视频预览
-
- {{ course.title }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/components/aigc/generation/GBTaskCard.vue b/components/aigc/generation/GBTaskCard.vue
index 2718304..659f680 100644
--- a/components/aigc/generation/GBTaskCard.vue
+++ b/components/aigc/generation/GBTaskCard.vue
@@ -90,7 +90,7 @@ const onClick = () => {
{{ video.progress }}%
-
+
@@ -109,15 +109,19 @@ const onClick = () => {
驱动文本
- {{ video.content }}
+ {{ video.content }}
+
+
+
+
+
-
-
数字人 {{ video.digital_human_id }}
+ class="w-fit hidden sm:flex items-center gap-1 transition-all group-hover:opacity-0 group-hover:pointer-events-none">
+
{{ video.digital_human_id }}
import type { PropType } from 'vue'
import { encode } from '@monosky/base64'
+import { object, string, number, type InferType } from 'yup';
interface Subtitle {
start: string;
@@ -9,6 +10,8 @@ interface Subtitle {
active?: boolean
}
+type SubtitleStyleEdit = Pick
+
const props = defineProps({
course: {
type: Object as PropType,
@@ -29,6 +32,33 @@ const modified = ref(false)
const videoElement = ref(null)
+const subtitleStyleSchema = object({
+ color: string().required(),
+ fontSize: number().required(),
+ bottomOffset: number().required(),
+ strokeStyle: string().required(),
+ textShadow: object({
+ offsetX: number().required(),
+ offsetY: number().required(),
+ blur: number().required(),
+ color: string().required(),
+ }).required(),
+})
+type subtitleStyleSchema = InferType
+
+const subtitleStyleState = reactive({
+ color: '#000',
+ fontSize: 20,
+ bottomOffset: 0,
+ strokeStyle: 'none',
+ textShadow: {
+ offsetX: 0,
+ offsetY: 0,
+ blur: 0,
+ color: '#000',
+ },
+})
+
const loadSrt = async () => {
isLoading.value = true
try {
@@ -40,7 +70,7 @@ const loadSrt = async () => {
} catch (err) {
toast.add({
title: '加载字幕失败',
- description: `${ err }` || '未知错误',
+ description: `${err}` || '未知错误',
color: 'red',
})
} finally {
@@ -78,7 +108,7 @@ const parseSrt = (srt: string) => {
const generateSrt = () => {
return subtitles.value.map((subtitle, index) => {
- return `${ index + 1 }\n${ subtitle.start } --> ${ subtitle.end }\n${ subtitle.text }\n`
+ return `${index + 1}\n${subtitle.start} --> ${subtitle.end}\n${subtitle.text}\n`
}).join('\n')
}
@@ -114,7 +144,7 @@ const syncSubtitles = () => {
subtitle.active = currentTime >= startTime && currentTime <= endTime
// scroll active subtitle into view
if (subtitle.active) {
- const element = document.getElementById(`subtitle-${ subtitles.value.indexOf(subtitle) }`)!
+ const element = document.getElementById(`subtitle-${subtitles.value.indexOf(subtitle)}`)!
const parent = element?.parentElement
// scroll element to the center of parent
parent?.scrollTo({
@@ -178,25 +208,14 @@ defineExpose({
-
+
-
+
字幕编辑器
@@ -211,48 +230,87 @@ defineExpose({
-