Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
D
digitalPerson-fe
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
digitalPerson
digitalPerson-fe
Commits
a5fc900c
Commit
a5fc900c
authored
Sep 27, 2024
by
Dazzle Wu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: 视频生成参数调整
parent
27a61770
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
109 additions
and
111 deletions
+109
-111
digital-creation.ts
src/apis/digital-creation.ts
+5
-0
creation.ts
src/store/modules/creation.ts
+10
-6
creation.ts
src/store/types/creation.ts
+8
-17
digital-human.vue
src/views/creation/components/digital/digital-human.vue
+3
-3
digital-position.vue
src/views/creation/components/digital/digital-position.vue
+6
-6
digital-setting.vue
src/views/creation/components/digital/digital-setting.vue
+3
-3
preview-content.vue
src/views/creation/components/preview-content.vue
+14
-8
header-bar.vue
src/views/creation/layout/header-bar.vue
+37
-58
index.vue
src/views/creation/layout/index.vue
+23
-10
No files found.
src/apis/digital-creation.ts
View file @
a5fc900c
...
...
@@ -55,6 +55,11 @@ export function fetchTimbreByExample<T>(condition: string) {
return
request
.
post
<
T
>
(
`/bizDigitalHumanTimbreRest/getByExample.json?condition=
${
condition
}
`
)
}
// 保存当前用户的草稿配置
export
function
fetchDraftConfigById
<
T
>
(
id
:
number
)
{
return
request
.
post
<
T
>
(
`/bizDigitalHumanMemberDraftConfigRest/getById.json?id=
${
id
}
`
)
}
// 保存当前用户的草稿配置
export
function
saveDraftConfig
<
T
>
(
payload
:
object
)
{
return
request
.
post
<
T
>
(
'/bizDigitalHumanMemberDraftConfigRest/saveOrUpdate.json'
,
payload
)
...
...
src/store/modules/creation.ts
View file @
a5fc900c
...
...
@@ -56,8 +56,12 @@ export const useDigitalCreationStore = defineStore('digital-creation-store', {
this
.
text
=
text
},
setDigitalImageUrl
(
digitalImageUrl
:
string
)
{
this
.
inputImageUrl
=
digitalImageUrl
setInputImageUrl
(
inputImageUrl
:
string
)
{
this
.
inputImageUrl
=
inputImageUrl
},
setInputAudioUrl
(
inputAudioUrl
:
string
)
{
this
.
inputAudioUrl
=
inputAudioUrl
},
setPerson
(
person
:
string
)
{
...
...
@@ -72,19 +76,19 @@ export const useDigitalCreationStore = defineStore('digital-creation-store', {
this
.
pitch
=
pitch
},
set
DigitalImagePosition
X
(
x
:
number
)
{
setX
(
x
:
number
)
{
this
.
x
=
x
},
set
DigitalImagePosition
Y
(
y
:
number
)
{
setY
(
y
:
number
)
{
this
.
y
=
y
},
set
DigitalImagePosition
W
(
w
:
number
)
{
setW
(
w
:
number
)
{
this
.
w
=
w
},
set
DigitalImagePosition
H
(
h
:
number
)
{
setH
(
h
:
number
)
{
this
.
h
=
h
},
...
...
src/store/types/creation.ts
View file @
a5fc900c
...
...
@@ -28,7 +28,7 @@ export interface DigitalTemplate {
driveType
:
DriveType
text
:
string
ttsParams
:
{
person
:
string
person
:
string
|
null
speed
:
string
volume
:
string
pitch
:
string
...
...
@@ -141,20 +141,11 @@ export interface DraftConfig {
}
export
interface
BaseVideoTask
{
figureId
:
string
|
null
driveType
:
string
|
null
text
:
string
|
null
ttsParams
:
{
preson
:
string
|
null
speed
?:
string
|
null
pitch
?:
string
|
null
volume
?:
string
|
null
}
videoParams
:
{
width
:
number
height
:
number
transparent
?:
string
|
null
}
backgroundImageUrl
:
string
|
null
autoAnimoji
:
string
|
null
draftId
:
number
videoName
:
string
width
:
number
height
:
number
transparent
:
string
videoType
:
string
audioUrl
:
string
}
src/views/creation/components/digital/digital-human.vue
View file @
a5fc900c
...
...
@@ -23,7 +23,7 @@ watch(
([
figureId
,
len
])
=>
{
if
(
!
digitalCreationStore
.
inputImageUrl
&&
figureId
&&
len
)
{
const
imageUrl
=
allImageList
.
value
.
find
((
i
)
=>
i
.
figureId
===
figureId
)?.
imageUrl
imageUrl
&&
digitalCreationStore
.
set
Digital
ImageUrl
(
imageUrl
)
imageUrl
&&
digitalCreationStore
.
set
Input
ImageUrl
(
imageUrl
)
}
},
)
...
...
@@ -52,8 +52,8 @@ async function handleSearch(value: string) {
}
function
handleClickDigitalImage
(
digitalItem
:
DigitalImageItem
)
{
digitalCreationStore
.
setFigureId
(
digitalItem
.
figureId
!
)
digitalCreationStore
.
set
Digital
ImageUrl
(
digitalItem
.
imageUrl
)
digitalCreationStore
.
setFigureId
(
digitalItem
.
figureId
)
digitalCreationStore
.
set
Input
ImageUrl
(
digitalItem
.
imageUrl
)
}
function
handleClickAll
(
imageType
:
ImageType
)
{
...
...
src/views/creation/components/digital/digital-position.vue
View file @
a5fc900c
...
...
@@ -9,7 +9,7 @@ const digitalImagePositionX = computed({
return
digitalCreationStore
.
x
},
set
(
value
)
{
digitalCreationStore
.
set
DigitalImagePosition
X
(
value
)
digitalCreationStore
.
setX
(
value
)
},
})
...
...
@@ -18,7 +18,7 @@ const digitalImagePositionY = computed({
return
digitalCreationStore
.
y
},
set
(
value
)
{
digitalCreationStore
.
set
DigitalImagePosition
Y
(
value
)
digitalCreationStore
.
setY
(
value
)
},
})
...
...
@@ -28,8 +28,8 @@ const digitalImagePositionW = computed({
},
set
(
width
)
{
const
height
=
(
width
*
16
)
/
9
digitalCreationStore
.
set
DigitalImagePosition
W
(
width
)
digitalCreationStore
.
set
DigitalImagePosition
H
(
parseInt
(
height
+
''
))
digitalCreationStore
.
setW
(
width
)
digitalCreationStore
.
setH
(
parseInt
(
height
+
''
))
},
})
...
...
@@ -39,8 +39,8 @@ const digitalImagePositionH = computed({
},
set
(
height
)
{
const
width
=
(
height
*
9
)
/
16
digitalCreationStore
.
set
DigitalImagePosition
H
(
height
)
digitalCreationStore
.
set
DigitalImagePosition
W
(
parseInt
(
width
+
''
))
digitalCreationStore
.
setH
(
height
)
digitalCreationStore
.
setW
(
parseInt
(
width
+
''
))
},
})
</
script
>
...
...
src/views/creation/components/digital/digital-setting.vue
View file @
a5fc900c
...
...
@@ -7,13 +7,13 @@ import DigitalPosition from './digital-position.vue'
<
template
>
<n-tabs
type=
"line"
animated
class=
"h-full"
>
<n-tab-pane
name=
"human"
tab=
"選擇"
class=
"h-full"
>
<DigitalHuman
/>
<DigitalHuman
style=
"min-height: calc(100vh - 158px)"
/>
</n-tab-pane>
<n-tab-pane
name=
"position"
tab=
"位置"
class=
"h-full"
>
<DigitalPosition
/>
<DigitalPosition
style=
"min-height: calc(100vh - 158px)"
/>
</n-tab-pane>
<n-tab-pane
name=
"audio"
tab=
"聲音"
class=
"h-full"
>
<DigitalAudio
/>
<DigitalAudio
style=
"min-height: calc(100vh - 158px)"
/>
</n-tab-pane>
</n-tabs>
</
template
>
...
...
src/views/creation/components/preview-content.vue
View file @
a5fc900c
...
...
@@ -13,11 +13,18 @@ const digitalHumanWidth = computed(() => (digitalCreationStore.w * previewConten
const
digitalHumanHeight
=
computed
(()
=>
(
digitalCreationStore
.
h
*
previewContentHeight
.
value
!
)
/
1920
)
const
digitalHumanLeft
=
computed
(()
=>
(
digitalCreationStore
.
x
*
previewContentWidth
.
value
!
)
/
1080
)
const
digitalHumanTop
=
computed
(()
=>
(
digitalCreationStore
.
y
*
previewContentHeight
.
value
!
)
/
1920
)
const
audioUrl
=
computed
({
get
()
{
return
digitalCreationStore
.
inputAudioUrl
||
''
},
set
(
value
)
{
digitalCreationStore
.
setInputAudioUrl
(
value
)
},
})
const
url
=
'wss://ai-api-sit.gsstcloud.com/websocket/textToSpeechTC.ws'
const
isConnected
=
ref
(
false
)
const
audioData
=
ref
(
''
)
const
voiceUrl
=
ref
(
''
)
let
websocket
:
WebSocket
function
connectWebSocket
()
{
...
...
@@ -35,7 +42,7 @@ function connectWebSocket() {
if
(
event
.
data
)
{
const
data
=
JSON
.
parse
(
event
.
data
)
data
.
audio
&&
(
audioData
.
value
+=
data
.
audio
)
data
.
replyVoiceUrl
&&
(
voice
Url
.
value
=
data
.
replyVoiceUrl
)
data
.
replyVoiceUrl
&&
(
audio
Url
.
value
=
data
.
replyVoiceUrl
)
data
.
final
&&
disconnectWebSocket
()
}
}
...
...
@@ -46,7 +53,6 @@ function connectWebSocket() {
}
function
disconnectWebSocket
()
{
console
.
log
(
'audio'
,
audioData
.
value
)
if
(
websocket
)
{
websocket
.
close
()
}
...
...
@@ -58,7 +64,7 @@ function sendDataToWebSocket() {
sampleRate
:
16000
,
speed
:
Number
(
digitalCreationStore
.
speed
),
volume
:
Number
(
digitalCreationStore
.
volume
),
voiceType
:
101
8
,
voiceType
:
101
019
,
content
:
digitalCreationStore
.
text
,
}
websocket
.
send
(
JSON
.
stringify
(
payload
))
...
...
@@ -96,17 +102,17 @@ function playAudio() {
</div>
</div>
<div
class=
"flex bg-white p-4"
>
<
div
class=
"flex-1 text-lg"
>
00:11:22
</div
>
<
!--
<div
class=
"flex flex-1 items-center text-lg"
>
00:11:22
</div>
--
>
<div
class=
"flex flex-1 justify-center"
>
<n-button
v-if=
"!audioData"
type=
"info"
:loading=
"isConnected"
@
click=
"generatePreview"
>
生成预览
</n-button>
<CustomIcon
v-else
class=
"cursor-pointer text-2xl"
icon=
"ph:play"
@
click=
"playAudio"
/>
</div>
<div
class=
"flex flex-1 items-center justify-end gap-4"
>
<
!--
<
div
class=
"flex flex-1 items-center justify-end gap-4"
>
<CustomIcon
class=
"cursor-pointer text-lg"
icon=
"mingcute:volume-line"
/>
<CustomIcon
class=
"cursor-pointer text-lg"
icon=
"mingcute:fullscreen-line"
/>
</div>
</div>
-->
</div>
</div>
<audio
ref=
"digitalAudio"
:src=
"
voice
Url"
></audio>
<audio
ref=
"digitalAudio"
:src=
"
audio
Url"
></audio>
</
template
>
src/views/creation/layout/header-bar.vue
View file @
a5fc900c
...
...
@@ -2,38 +2,34 @@
import
{
createBaseVideoDigitalHumanTask
,
saveDraftConfig
}
from
'@/apis/digital-creation'
import
{
useDigitalCreationStore
}
from
'@/store/modules/creation'
import
{
BaseVideoTask
,
DraftConfig
}
from
'@/store/types/creation'
import
{
ref
,
watch
}
from
'vue'
import
{
ref
}
from
'vue'
const
digitalCreationStore
=
useDigitalCreationStore
()
const
showExportModal
=
ref
(
false
)
const
exportForm
=
ref
({
name
:
''
,
ratio
:
720
,
transparent
:
false
,
format
:
'mp4'
,
})
const
ratioValue
=
ref
(
720
)
const
ratioList
=
[
{
value
:
720
,
label
:
'720p'
},
{
value
:
1080
,
label
:
'1080p'
},
]
const
transparent
=
[
{
value
:
false
,
label
:
'全部'
},
{
value
:
true
,
label
:
'僅數字人(透明背景)'
},
]
const
formatList
=
[
{
value
:
'mp4'
,
label
:
'MP4'
},
{
value
:
'webm'
,
label
:
'WEBM'
},
{
value
:
'N'
,
label
:
'全部'
},
{
value
:
'Y'
,
label
:
'僅數字人(透明背景)'
},
]
watch
(
()
=>
exportForm
.
value
.
transparent
,
(
val
)
=>
{
exportForm
.
value
.
format
=
val
?
'webm'
:
'mp4'
},
)
// 保存为草稿
async
function
saveDraft
()
{
const
payload
:
{
draftConfigDto
:
DraftConfig
}
=
{
draftConfigDto
:
digitalCreationStore
.
$state
,
}
const
res
=
await
saveDraftConfig
(
payload
)
if
(
res
.
code
===
0
)
{
window
.
$message
.
success
(
'保存成功'
)
}
}
// 导出视频
function
confirmExport
()
{
if
(
!
exportForm
.
value
.
n
ame
)
{
if
(
!
digitalCreationStore
.
videoN
ame
)
{
window
.
$message
.
error
(
'請輸入視頻名稱'
)
return
false
}
...
...
@@ -41,40 +37,29 @@ function confirmExport() {
}
async
function
createBaseVideoTask
()
{
if
(
!
digitalCreationStore
.
id
)
{
window
.
$message
.
error
(
'請先保存視頻為草稿'
)
return
}
if
(
!
digitalCreationStore
.
inputAudioUrl
)
{
window
.
$message
.
error
(
'請先生成預覽音頻'
)
return
}
const
payload
:
BaseVideoTask
=
{
figureId
:
digitalCreationStore
.
figureId
,
driveType
:
digitalCreationStore
.
driveType
,
text
:
digitalCreationStore
.
text
,
ttsParams
:
{
preson
:
digitalCreationStore
.
person
,
speed
:
digitalCreationStore
.
speed
,
pitch
:
digitalCreationStore
.
pitch
,
volume
:
digitalCreationStore
.
volume
,
},
videoParams
:
{
width
:
digitalCreationStore
.
width
,
height
:
digitalCreationStore
.
height
,
transparent
:
digitalCreationStore
.
transparent
,
},
backgroundImageUrl
:
digitalCreationStore
.
backgroundImageUrl
,
autoAnimoji
:
digitalCreationStore
.
autoAnimoji
,
draftId
:
digitalCreationStore
.
id
,
videoName
:
digitalCreationStore
.
videoName
,
width
:
ratioValue
.
value
===
720
?
720
:
1080
,
height
:
ratioValue
.
value
===
720
?
1280
:
1920
,
transparent
:
digitalCreationStore
.
transparent
,
videoType
:
'mp4'
,
audioUrl
:
digitalCreationStore
.
inputAudioUrl
,
}
const
res
=
await
createBaseVideoDigitalHumanTask
(
''
,
payload
)
const
res
=
await
createBaseVideoDigitalHumanTask
(
'
null
'
,
payload
)
if
(
res
.
code
===
0
)
{
window
.
$message
.
success
(
'導出成功'
)
showExportModal
.
value
=
false
}
}
async
function
saveDraft
()
{
const
payload
:
{
draftConfigDto
:
DraftConfig
}
=
{
draftConfigDto
:
digitalCreationStore
.
$state
,
}
const
res
=
await
saveDraftConfig
(
payload
)
if
(
res
.
code
===
0
)
{
window
.
$message
.
success
(
'保存成功'
)
}
}
</
script
>
<
template
>
...
...
@@ -105,12 +90,12 @@ async function saveDraft() {
@
positive-click=
"confirmExport"
@
negative-click=
"showExportModal = false"
>
<n-form
ref=
"formRef"
:label-width=
"120"
:model=
"exportForm"
label-placement=
"left"
>
<n-form
ref=
"formRef"
:label-width=
"120"
label-placement=
"left"
>
<n-form-item
label=
"視頻名稱"
required
>
<n-input
v-model:value=
"
exportForm.n
ame"
placeholder=
"請輸入視頻名稱"
/>
<n-input
v-model:value=
"
digitalCreationStore.videoN
ame"
placeholder=
"請輸入視頻名稱"
/>
</n-form-item>
<n-form-item
label=
"視頻分辨率"
required
>
<n-radio-group
v-model:value=
"
exportForm.ratio
"
name=
"ratio"
>
<n-radio-group
v-model:value=
"
ratioValue
"
name=
"ratio"
>
<n-space>
<n-radio
v-for=
"ratio in ratioList"
:key=
"ratio.value"
:value=
"ratio.value"
>
{{
ratio
.
label
}}
...
...
@@ -119,7 +104,7 @@ async function saveDraft() {
</n-radio-group>
</n-form-item>
<n-form-item
label=
"導出範圍"
required
>
<n-radio-group
v-model:value=
"
exportForm
.transparent"
name=
"transparent"
>
<n-radio-group
v-model:value=
"
digitalCreationStore
.transparent"
name=
"transparent"
>
<n-space>
<n-radio
v-for=
"item in transparent"
:key=
"item.value"
:value=
"item.value"
>
{{
item
.
label
}}
...
...
@@ -128,13 +113,7 @@ async function saveDraft() {
</n-radio-group>
</n-form-item>
<n-form-item
label=
"視頻格式"
required
>
<n-radio-group
v-model:value=
"exportForm.format"
name=
"format"
disabled
>
<n-space>
<n-radio
v-for=
"format in formatList"
:key=
"format.value"
:value=
"format.value"
>
{{
format
.
label
}}
</n-radio>
</n-space>
</n-radio-group>
<n-radio
value=
"mp4"
checked
>
MP4
</n-radio>
</n-form-item>
</n-form>
</n-modal>
...
...
src/views/creation/layout/index.vue
View file @
a5fc900c
<
script
setup
lang=
"ts"
>
import
{
fetchDigitalHumanTemplateStatus
}
from
'@/apis/digital-creation'
import
{
fetchDigitalHumanTemplateStatus
,
fetchDraftConfigById
}
from
'@/apis/digital-creation'
import
{
useDigitalCreationStore
}
from
'@/store/modules/creation'
import
{
DigitalTemplate
,
DraftConfig
}
from
'@/store/types/creation'
import
{
onMounted
}
from
'vue'
import
{
useRoute
}
from
'vue-router'
import
HeaderBar
from
'./header-bar.vue'
import
MainContent
from
'./main-content.vue'
import
SideBar
from
'./side-bar.vue'
const
route
=
useRoute
()
const
digitalCreationStore
=
useDigitalCreationStore
()
onMounted
(()
=>
{
getDigitalTemplate
(
1
)
if
(
route
.
params
.
draftId
)
{
getDraft
(
Number
(
route
.
params
.
draftId
))
}
else
{
getDigitalTemplate
(
1
)
}
})
async
function
getDigitalTemplate
(
id
:
number
)
{
...
...
@@ -34,14 +40,14 @@ async function getDigitalTemplate(id: number) {
inputAudioUrl
:
digitalTemplate
.
inputAudioUrl
,
callbackUrl
:
digitalTemplate
.
callbackUrl
,
figureId
:
digitalTemplate
.
figureId
,
width
:
digitalTemplate
.
videoParams
.
width
,
height
:
digitalTemplate
.
videoParams
.
height
,
width
:
digitalTemplate
.
videoParams
.
width
||
0
,
height
:
digitalTemplate
.
videoParams
.
height
||
0
,
transparent
:
digitalTemplate
.
videoParams
.
transparent
?
'Y'
:
'N'
,
cameraId
:
digitalTemplate
.
dhParams
.
cameraId
,
x
:
digitalTemplate
.
dhParams
.
position
.
x
,
y
:
digitalTemplate
.
dhParams
.
position
.
y
,
w
:
digitalTemplate
.
dhParams
.
position
.
w
,
h
:
digitalTemplate
.
dhParams
.
position
.
h
,
x
:
digitalTemplate
.
dhParams
.
position
.
x
||
0
,
y
:
digitalTemplate
.
dhParams
.
position
.
y
||
0
,
w
:
digitalTemplate
.
dhParams
.
position
.
w
||
0
,
h
:
digitalTemplate
.
dhParams
.
position
.
h
||
0
,
subtitlePolicy
:
digitalTemplate
.
subtitleParams
.
subtitlePolicy
,
enabled
:
digitalTemplate
.
subtitleParams
.
enabled
?
'Y'
:
'N'
,
backgroundImageUrl
:
digitalTemplate
.
backgroundImageUrl
,
...
...
@@ -49,13 +55,20 @@ async function getDigitalTemplate(id: number) {
enablePalindrome
:
digitalTemplate
.
enablePalindrome
?
'Y'
:
'N'
,
templateId
:
String
(
digitalTemplate
.
id
),
title
:
digitalTemplate
.
title
,
logoUrl
:
digitalTemplate
.
logoParams
.
logoUr
l
,
bgmUrl
:
digitalTemplate
.
bgmParams
.
bgmUr
l
,
logoUrl
:
digitalTemplate
.
logoParams
?.
logoUrl
||
nul
l
,
bgmUrl
:
digitalTemplate
.
bgmParams
?.
bgmUrl
||
nul
l
,
materialUrl
:
digitalTemplate
.
materialUrl
,
}
digitalCreationStore
.
updateDigitalCreation
(
draftConfig
)
}
}
async
function
getDraft
(
id
:
number
)
{
const
res
=
await
fetchDraftConfigById
<
DraftConfig
>
(
id
)
if
(
res
.
code
===
0
)
{
digitalCreationStore
.
updateDigitalCreation
(
res
.
data
)
}
}
</
script
>
<
template
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment