Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
live-management-web
Overview
Overview
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
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
haojie
live-management-web
Commits
0d8701a5
Commit
0d8701a5
authored
Aug 02, 2023
by
haojie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
洗稿
parent
8b03221a
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
816 additions
and
406 deletions
+816
-406
src/components/MultipleUpload/index.less
+4
-0
src/components/MultipleUpload/index.tsx
+53
-15
src/components/ScriptTemplate.vue
+8
-3
src/components/loading.vue
+124
-111
src/components/upload/index.tsx
+70
-33
src/hooks/useConfuse.ts
+68
-0
src/layouts/components/Content.vue
+1
-1
src/pages/VocalCustomization/components/MyDigitalPerson.vue
+1
-1
src/pages/VocalCustomization/components/Record.vue
+1
-1
src/pages/createLive/components/scripts.vue
+145
-6
src/pages/createLive/hooks/scripts.ts
+0
-0
src/pages/createLive/index.vue
+14
-68
src/service/Common.ts
+13
-2
src/service/CreateLive.ts
+1
-0
src/store/modules/live.ts
+2
-2
src/utils/api/userApi.ts
+31
-0
src/utils/audio.ts
+159
-108
src/utils/request.ts
+1
-8
src/utils/tool.ts
+89
-47
src/utils/upLoadRequest.ts
+31
-0
No files found.
src/components/MultipleUpload/index.less
View file @
0d8701a5
...
@@ -91,6 +91,10 @@
...
@@ -91,6 +91,10 @@
.upload-success-box {
.upload-success-box {
.file-name {
.file-name {
margin-top: 4px;
margin-top: 4px;
white-space: nowrap;
max-width: 70px;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
}
.uploading-title {
.uploading-title {
...
...
src/components/MultipleUpload/index.tsx
View file @
0d8701a5
import
{
defineComponent
,
reactive
,
ref
,
watch
}
from
'vue'
;
import
{
defineComponent
,
onMounted
,
reactive
,
ref
,
watch
}
from
'vue'
;
import
'./index.less'
;
import
'./index.less'
;
import
{
Button
as
TButton
,
Upload
as
TUpload
,
Progress
as
TProgress
,
UploadFile
}
from
'tdesign-vue-next'
;
import
{
Button
as
TButton
,
Upload
as
TUpload
,
Progress
as
TProgress
,
UploadFile
}
from
'tdesign-vue-next'
;
import
{
getUserCookie
}
from
'@/utils/api/userApi'
;
import
{
getUserCookie
}
from
'@/utils/api/userApi'
;
...
@@ -12,6 +12,10 @@ import { alyOssUpload } from '@/utils/tool';
...
@@ -12,6 +12,10 @@ import { alyOssUpload } from '@/utils/tool';
export
default
defineComponent
({
export
default
defineComponent
({
props
:
{
props
:
{
modelValue
:
Array
,
modelValue
:
Array
,
value
:
{
type
:
Array
,
default
:
[],
},
audioTotolTime
:
{
audioTotolTime
:
{
type
:
[
Number
,
null
],
type
:
[
Number
,
null
],
default
:
null
,
default
:
null
,
...
@@ -53,6 +57,28 @@ export default defineComponent({
...
@@ -53,6 +57,28 @@ export default defineComponent({
},
100
);
},
100
);
};
};
// 更新父组件的list
const
submitList
=
(
list
:
any
[],
change
:
boolean
=
true
)
=>
{
if
(
list
.
length
)
{
Curfile
.
status
=
2
;
}
else
{
Curfile
.
status
=
0
;
}
emit
(
'update:modelValue'
,
list
);
// 再提交一份原始list
if
(
change
)
{
emit
(
'change'
,
list
,
fileList
.
value
);
}
};
onMounted
(()
=>
{
//
if
(
props
.
modelValue
.
length
)
{
Curfile
.
status
=
2
;
fileList
.
value
=
props
.
modelValue
;
}
});
// 是否需要计算文件总时长,音频或视频
// 是否需要计算文件总时长,音频或视频
const
computedTotalTime
=
()
=>
{
const
computedTotalTime
=
()
=>
{
return
typeof
props
.
audioTotolTime
===
'number'
;
return
typeof
props
.
audioTotolTime
===
'number'
;
...
@@ -145,8 +171,11 @@ export default defineComponent({
...
@@ -145,8 +171,11 @@ export default defineComponent({
totalSize
+=
item
.
file
.
size
;
totalSize
+=
item
.
file
.
size
;
}
}
}
}
// 更新绑定的值
submitList
(
list
,
false
);
emit
(
'update:modelValue'
,
list
);
if
(
list
.
length
===
fileList
.
value
.
length
)
{
// 全部上传成功才提交change事件
emit
(
'change'
,
list
,
fileList
.
value
);
}
// 文件总大小
// 文件总大小
emit
(
'update:totalSize'
,
totalSize
);
emit
(
'update:totalSize'
,
totalSize
);
};
};
...
@@ -185,7 +214,26 @@ export default defineComponent({
...
@@ -185,7 +214,26 @@ export default defineComponent({
// 状态成功
// 状态成功
if
(
!
v
.
length
)
{
if
(
!
v
.
length
)
{
Curfile
.
status
=
0
;
Curfile
.
status
=
0
;
fileList
.
value
=
[];
}
else
{
// // 要删除的下标
// let deleteIndex = [];
// // 数组对比,没有的就删除
// for (let i = 0; i < fileList.value.length; i++) {
// let item = fileList.value[i];
// let index = v.findIndex((url: string) => item == url);
// if (index === -1) {
// // 没找到,删除
// deleteIndex.push(i);
// }
// }
// console.log(deleteIndex);
// deleteIndex.forEach((index: any) => {
// fileList.value.splice(index, 1);
// });
}
}
}
else
{
Curfile
.
status
=
0
;
}
}
},
},
);
);
...
@@ -199,8 +247,7 @@ export default defineComponent({
...
@@ -199,8 +247,7 @@ export default defineComponent({
const
reStart
=
()
=>
{
const
reStart
=
()
=>
{
// 重置
// 重置
Curfile
.
status
=
0
;
Curfile
.
status
=
0
;
emit
(
'update:modelValue'
,
[]);
submitList
([]);
emit
(
'change'
,
[]);
};
};
const
requestSuccessMethod
=
async
(
file
:
UploadFile
|
UploadFile
[])
=>
{
const
requestSuccessMethod
=
async
(
file
:
UploadFile
|
UploadFile
[])
=>
{
return
ExtranetUpload
(
file
);
return
ExtranetUpload
(
file
);
...
@@ -227,19 +274,10 @@ export default defineComponent({
...
@@ -227,19 +274,10 @@ export default defineComponent({
totalTime
+=
item
.
time
;
totalTime
+=
item
.
time
;
}
}
});
});
emit
(
'update:modelValue'
,
list
);
submitList
(
list
);
emit
(
'update:audioTotolTime'
,
totalTime
);
emit
(
'update:audioTotolTime'
,
totalTime
);
};
};
watch
(
()
=>
props
.
modelValue
,
(
v
)
=>
{
if
(
!
v
)
{
Curfile
.
status
=
0
;
}
},
);
// 未上传
// 未上传
const
notUploadHtml
=
()
=>
{
const
notUploadHtml
=
()
=>
{
return
(
return
(
...
...
src/components/ScriptTemplate.vue
View file @
0d8701a5
...
@@ -6,9 +6,11 @@
...
@@ -6,9 +6,11 @@
}"
}"
>
>
<div
class=
"script-template-tool"
v-if=
"showTool"
>
<div
class=
"script-template-tool"
v-if=
"showTool"
>
<div
class=
"edit-box"
@
click=
"onEdit"
>
<template
v-if=
"showEdit"
>
<img
:src=
"imgs.edit"
alt=
""
/>
<div
class=
"edit-box"
@
click=
"onEdit"
>
</div>
<img
:src=
"imgs.edit"
alt=
""
/>
</div>
</
template
>
<div
class=
"delete-box"
@
click=
"onDelete"
>
<div
class=
"delete-box"
@
click=
"onDelete"
>
<img
:src=
"imgs.delete"
alt=
""
/>
<img
:src=
"imgs.delete"
alt=
""
/>
</div>
</div>
...
@@ -24,10 +26,12 @@ const props = withDefaults(
...
@@ -24,10 +26,12 @@ const props = withDefaults(
defineProps
<
{
defineProps
<
{
height
?:
string
;
height
?:
string
;
showTool
?:
boolean
;
showTool
?:
boolean
;
showEdit
?:
boolean
;
}
>
(),
}
>
(),
{
{
height
:
'175px'
,
height
:
'175px'
,
showTool
:
true
,
showTool
:
true
,
showEdit
:
true
,
},
},
);
);
const
emit
=
defineEmits
([
'edit'
,
'delete'
]);
const
emit
=
defineEmits
([
'edit'
,
'delete'
]);
...
@@ -59,6 +63,7 @@ const onDelete = () => {
...
@@ -59,6 +63,7 @@ const onDelete = () => {
right
:
12px
;
right
:
12px
;
top
:
12px
;
top
:
12px
;
.da();
.da();
z-index
:
100
;
.edit-box,
.edit-box,
.delete-box
{
.delete-box
{
cursor
:
pointer
;
cursor
:
pointer
;
...
...
src/components/loading.vue
View file @
0d8701a5
<
template
>
<
template
>
<div
<div
class=
"custom-loading-two"
class=
"custom-loading-two"
:class=
"
{
'custom-loading-two-mask': mask,
}"
:style="{
:style="{
position: position,
position: position,
}"
}"
...
@@ -22,9 +25,11 @@
...
@@ -22,9 +25,11 @@
const
props
=
withDefaults
(
const
props
=
withDefaults
(
defineProps
<
{
defineProps
<
{
position
?:
string
;
position
?:
string
;
mask
?:
boolean
;
}
>
(),
}
>
(),
{
{
position
:
'absolute'
,
position
:
'absolute'
,
mask
:
false
,
},
},
);
);
</
script
>
</
script
>
...
@@ -35,136 +40,144 @@ const props = withDefaults(
...
@@ -35,136 +40,144 @@ const props = withDefaults(
left
:
50%
;
left
:
50%
;
transform
:
translate
(
-50%
,
-50%
);
transform
:
translate
(
-50%
,
-50%
);
z-index
:
100
;
z-index
:
100
;
}
.loading,
.loading
,
.loading
>
div
{
.loading
>
div
{
position
:
relative
;
position
:
relative
;
box-sizing
:
border-box
;
box-sizing
:
border-box
;
}
}
.loading
{
.loading
{
display
:
block
;
display
:
block
;
font-size
:
0
;
font-size
:
0
;
color
:
#888fa1
;
color
:
#888fa1
;
}
}
.loading.la-dark
{
.loading.la-dark
{
color
:
#333
;
color
:
#333
;
}
}
.loading
>
div
{
.loading
>
div
{
display
:
inline-block
;
display
:
inline-block
;
float
:
none
;
float
:
none
;
background-color
:
currentColor
;
background-color
:
currentColor
;
border
:
0
solid
currentColor
;
border
:
0
solid
currentColor
;
}
}
.loading
{
.loading
{
width
:
58px
;
width
:
58px
;
height
:
58px
;
height
:
58px
;
}
}
.loading
>
div
{
.loading
>
div
{
position
:
absolute
;
position
:
absolute
;
width
:
4px
;
width
:
4px
;
height
:
14px
;
height
:
14px
;
margin
:
2px
;
margin
:
2px
;
margin-top
:
-5px
;
margin-top
:
-5px
;
margin-left
:
-1px
;
margin-left
:
-1px
;
border-radius
:
4px
;
border-radius
:
4px
;
animation
:
line-spin-clockwise-fade
1s
infinite
ease-in-out
;
animation
:
line-spin-clockwise-fade
1s
infinite
ease-in-out
;
}
}
.loading
>
div
:nth-child
(
1
)
{
.loading
>
div
:nth-child
(
1
)
{
top
:
15%
;
top
:
15%
;
left
:
50%
;
left
:
50%
;
transform
:
rotate
(
0deg
);
transform
:
rotate
(
0deg
);
animation-delay
:
-0.875s
;
animation-delay
:
-0.875s
;
}
}
.loading
>
div
:nth-child
(
2
)
{
.loading
>
div
:nth-child
(
2
)
{
top
:
25.2512626585%
;
top
:
25.2512626585%
;
left
:
74.7487373415%
;
left
:
74.7487373415%
;
transform
:
rotate
(
45deg
);
transform
:
rotate
(
45deg
);
animation-delay
:
-0.75s
;
animation-delay
:
-0.75s
;
}
}
.loading
>
div
:nth-child
(
3
)
{
.loading
>
div
:nth-child
(
3
)
{
top
:
50%
;
top
:
50%
;
left
:
85%
;
left
:
85%
;
transform
:
rotate
(
90deg
);
transform
:
rotate
(
90deg
);
animation-delay
:
-0.625s
;
animation-delay
:
-0.625s
;
}
}
.loading
>
div
:nth-child
(
4
)
{
.loading
>
div
:nth-child
(
4
)
{
top
:
74.7487373415%
;
top
:
74.7487373415%
;
left
:
74.7487373415%
;
left
:
74.7487373415%
;
transform
:
rotate
(
135deg
);
transform
:
rotate
(
135deg
);
animation-delay
:
-0.5s
;
animation-delay
:
-0.5s
;
}
}
.loading
>
div
:nth-child
(
5
)
{
.loading
>
div
:nth-child
(
5
)
{
top
:
84.9999999974%
;
top
:
84.9999999974%
;
left
:
50.0000000004%
;
left
:
50.0000000004%
;
transform
:
rotate
(
180deg
);
transform
:
rotate
(
180deg
);
animation-delay
:
-0.375s
;
animation-delay
:
-0.375s
;
}
}
.loading
>
div
:nth-child
(
6
)
{
.loading
>
div
:nth-child
(
6
)
{
top
:
74.7487369862%
;
top
:
74.7487369862%
;
left
:
25.2512627193%
;
left
:
25.2512627193%
;
transform
:
rotate
(
225deg
);
transform
:
rotate
(
225deg
);
animation-delay
:
-0.25s
;
animation-delay
:
-0.25s
;
}
}
.loading
>
div
:nth-child
(
7
)
{
.loading
>
div
:nth-child
(
7
)
{
top
:
49.9999806189%
;
top
:
49.9999806189%
;
left
:
15.0000039834%
;
left
:
15.0000039834%
;
transform
:
rotate
(
270deg
);
transform
:
rotate
(
270deg
);
animation-delay
:
-0.125s
;
animation-delay
:
-0.125s
;
}
}
.loading
>
div
:nth-child
(
8
)
{
.loading
>
div
:nth-child
(
8
)
{
top
:
25.2506949798%
;
top
:
25.2506949798%
;
left
:
25.2513989292%
;
left
:
25.2513989292%
;
transform
:
rotate
(
315deg
);
transform
:
rotate
(
315deg
);
animation-delay
:
0s
;
animation-delay
:
0s
;
}
}
.loading.la-sm
{
.loading.la-sm
{
width
:
16px
;
width
:
16px
;
height
:
16px
;
height
:
16px
;
}
}
.loading.la-sm
>
div
{
.loading.la-sm
>
div
{
width
:
1px
;
width
:
1px
;
height
:
4px
;
height
:
4px
;
margin-top
:
-2px
;
margin-top
:
-2px
;
margin-left
:
0
;
margin-left
:
0
;
}
}
.loading.la-2x
{
.loading.la-2x
{
width
:
64px
;
width
:
64px
;
height
:
64px
;
height
:
64px
;
}
}
.loading.la-2x
>
div
{
.loading.la-2x
>
div
{
width
:
4px
;
width
:
4px
;
height
:
20px
;
height
:
20px
;
margin-top
:
-10px
;
margin-top
:
-10px
;
margin-left
:
-2px
;
margin-left
:
-2px
;
}
}
.loading.la-3x
{
.loading.la-3x
{
width
:
96px
;
width
:
96px
;
height
:
96px
;
height
:
96px
;
}
}
.loading.la-3x
>
div
{
.loading.la-3x
>
div
{
width
:
6px
;
width
:
6px
;
height
:
30px
;
height
:
30px
;
margin-top
:
-15px
;
margin-top
:
-15px
;
margin-left
:
-3px
;
margin-left
:
-3px
;
}
}
.custom-loading-two-mask
{
width
:
100%
;
height
:
100%
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
background-color
:
rgba
(
255
,
255
,
255
,
0.1
);
}
}
@keyframes
line-spin-clockwise-fade
{
@keyframes
line-spin-clockwise-fade
{
...
...
src/components/upload/index.tsx
View file @
0d8701a5
import
{
defineComponent
,
reactive
,
ref
,
watch
}
from
'vue'
;
import
{
defineComponent
,
onMounted
,
reactive
,
ref
,
watch
}
from
'vue'
;
import
'./index.less'
;
import
'./index.less'
;
import
UploadTip
from
'@/assets/svg/upload/uploadTip2.svg'
;
import
UploadTip
from
'@/assets/svg/upload/uploadTip2.svg'
;
import
{
import
{
...
@@ -36,22 +36,34 @@ export default defineComponent({
...
@@ -36,22 +36,34 @@ export default defineComponent({
type
:
String
,
type
:
String
,
default
:
''
,
default
:
''
,
},
},
id
:
{
type
:
[
Number
,
null
],
default
:
0
,
},
showOldName
:
{
type
:
Boolean
,
default
:
false
,
},
oldName
:
{
type
:
String
,
default
:
''
,
},
},
},
emits
:
[
'update:modelValue'
,
'change'
,
'file'
],
emits
:
[
'update:modelValue'
,
'change'
,
'file'
],
setup
(
props
,
{
emit
})
{
setup
(
props
,
{
emit
})
{
const
files
=
ref
([]);
const
files
=
ref
([]);
// 文件地址
// 文件地址
const
Curfile
=
reactive
({
const
Curfile
=
reactive
({
url
:
''
,
url
:
props
.
modelValue
,
status
:
0
,
status
:
0
,
// 当前上传模块提交的状态
oldName
:
''
,
uploadStatus
:
false
,
});
});
const
actionUrl
=
ref
(
''
);
const
actionUrl
=
ref
(
''
);
// 上传进度条
// 上传进度条
const
percentage
=
ref
(
0
);
const
percentage
=
ref
(
0
);
// 定时器
// 定时器
let
percentageInterval
:
any
=
null
;
let
percentageInterval
:
any
=
null
;
// 上传进度定时器
// 上传进度定时器
const
openpercentage
=
()
=>
{
const
openpercentage
=
()
=>
{
// 开启一个定时器,模拟上传进度
// 开启一个定时器,模拟上传进度
...
@@ -63,6 +75,27 @@ export default defineComponent({
...
@@ -63,6 +75,27 @@ export default defineComponent({
percentage
.
value
+=
1
;
percentage
.
value
+=
1
;
},
100
);
},
100
);
};
};
// 修改上传状态
const
changeUploadStatus
=
(
type
:
'success'
|
'wait'
|
'progress'
=
'success'
)
=>
{
if
(
type
==
'success'
)
{
Curfile
.
url
=
props
.
modelValue
;
Curfile
.
status
=
2
;
}
else
if
(
type
==
'progress'
)
{
Curfile
.
status
=
1
;
}
else
{
Curfile
.
url
=
''
;
Curfile
.
status
=
0
;
files
.
value
=
[];
}
};
// 提交url
const
submitUrl
=
(
url
:
string
)
=>
{
emit
(
'update:modelValue'
,
url
);
emit
(
'change'
,
url
,
props
.
id
,
Curfile
.
oldName
);
};
// 获取文件尺寸
// 获取文件尺寸
const
getFileSize
=
async
(
file
:
any
)
=>
{
const
getFileSize
=
async
(
file
:
any
)
=>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
...
@@ -119,21 +152,16 @@ export default defineComponent({
...
@@ -119,21 +152,16 @@ export default defineComponent({
MessagePlugin
.
success
(
'上传成功'
);
MessagePlugin
.
success
(
'上传成功'
);
// 将将完整url传给父组件
// 将将完整url传给父组件
Curfile
.
url
=
url
;
Curfile
.
url
=
url
;
// 成功2
submitUrl
(
Curfile
.
url
);
Curfile
.
status
=
2
;
changeUploadStatus
(
'success'
);
emit
(
'update:modelValue'
,
Curfile
.
url
);
emit
(
'change'
,
Curfile
.
url
);
};
};
// 上传失败回调
// 上传失败回调
const
UploadErrorCallback
=
()
=>
{
const
UploadErrorCallback
=
()
=>
{
// 关闭定时器
// 关闭定时器
window
.
clearInterval
(
percentageInterval
);
window
.
clearInterval
(
percentageInterval
);
Curfile
.
url
=
''
;
submitUrl
(
Curfile
.
url
);
// 失败0
Curfile
.
status
=
0
;
emit
(
'update:modelValue'
,
Curfile
.
url
);
emit
(
'change'
,
Curfile
.
url
);
MessagePlugin
.
warning
(
'上传失败'
);
MessagePlugin
.
warning
(
'上传失败'
);
changeUploadStatus
(
'wait'
);
};
};
// 外网上传-func
// 外网上传-func
const
ExtranetUpload
=
(
file
:
any
)
=>
{
const
ExtranetUpload
=
(
file
:
any
)
=>
{
...
@@ -141,6 +169,9 @@ export default defineComponent({
...
@@ -141,6 +169,9 @@ export default defineComponent({
// 上传中状态
// 上传中状态
Curfile
.
status
=
1
;
Curfile
.
status
=
1
;
return
new
Promise
<
RequestMethodResponse
>
((
resolve
)
=>
{
return
new
Promise
<
RequestMethodResponse
>
((
resolve
)
=>
{
if
(
props
.
showOldName
)
{
Curfile
.
oldName
=
file
.
name
;
}
const
uuid
=
v4
();
const
uuid
=
v4
();
let
url
=
''
;
let
url
=
''
;
const
{
config
}
=
props
;
const
{
config
}
=
props
;
...
@@ -172,15 +203,12 @@ export default defineComponent({
...
@@ -172,15 +203,12 @@ export default defineComponent({
// 外网url
// 外网url
const
url
=
config
.
domain
+
config
.
dir
+
uuid
+
`.
${
fileName
}
`
;
const
url
=
config
.
domain
+
config
.
dir
+
uuid
+
`.
${
fileName
}
`
;
UploadSuccessCallback
(
uuid
,
url
);
UploadSuccessCallback
(
uuid
,
url
);
//
Curfile
.
uploadStatus
=
true
;
resolve
({
resolve
({
status
:
'success'
,
status
:
'success'
,
response
:
{
url
:
Curfile
.
url
},
response
:
{
url
:
Curfile
.
url
},
});
});
}
else
{
}
else
{
UploadErrorCallback
();
UploadErrorCallback
();
Curfile
.
uploadStatus
=
false
;
}
}
})
})
.
catch
((
e
)
=>
{
.
catch
((
e
)
=>
{
...
@@ -190,14 +218,24 @@ export default defineComponent({
...
@@ -190,14 +218,24 @@ export default defineComponent({
});
});
};
};
onMounted
(()
=>
{
// 根据props的value判断上传状态
if
(
props
.
modelValue
)
{
changeUploadStatus
(
'success'
);
}
else
{
changeUploadStatus
(
'wait'
);
}
});
watch
(
watch
(
()
=>
props
.
modelValue
,
()
=>
props
.
modelValue
,
(
v
)
=>
{
(
v
)
=>
{
if
(
v
)
{
if
(
v
)
{
// 状态成功
// 状态成功
Curfile
.
url
=
v
;
Curfile
.
url
=
v
;
// 成功2
changeUploadStatus
(
'success'
);
Curfile
.
status
=
2
;
}
else
{
changeUploadStatus
(
'wait'
);
}
}
},
},
);
);
...
@@ -205,11 +243,8 @@ export default defineComponent({
...
@@ -205,11 +243,8 @@ export default defineComponent({
const
reStart
=
()
=>
{
const
reStart
=
()
=>
{
// 重置
// 重置
files
.
value
=
[];
files
.
value
=
[];
Curfile
.
url
=
''
;
submitUrl
(
''
);
Curfile
.
status
=
0
;
changeUploadStatus
(
'wait'
);
Curfile
.
uploadStatus
=
false
;
emit
(
'update:modelValue'
,
''
);
emit
(
'change'
,
''
);
};
};
const
requestSuccessMethod
=
async
(
file
:
UploadFile
|
UploadFile
[])
=>
{
const
requestSuccessMethod
=
async
(
file
:
UploadFile
|
UploadFile
[])
=>
{
return
ExtranetUpload
(
file
);
return
ExtranetUpload
(
file
);
...
@@ -263,7 +298,7 @@ export default defineComponent({
...
@@ -263,7 +298,7 @@ export default defineComponent({
<
div
class=
"icon"
>
<
div
class=
"icon"
>
{
props
.
uploadInfo
.
successIcon
?
<
img
src=
{
props
.
uploadInfo
.
successIcon
}
alt=
""
/>
:
''
}
{
props
.
uploadInfo
.
successIcon
?
<
img
src=
{
props
.
uploadInfo
.
successIcon
}
alt=
""
/>
:
''
}
</
div
>
</
div
>
<
div
class=
"file-name"
></
div
>
<
div
class=
"file-name"
>
{
Curfile
.
oldName
?
Curfile
.
oldName
:
props
.
oldName
}
</
div
>
<
Button
class=
"reset-submit"
theme=
"green"
onClick=
{
reStart
}
>
<
Button
class=
"reset-submit"
theme=
"green"
onClick=
{
reStart
}
>
{
props
.
uploadInfo
.
successButtonLabel
??
'重新上传'
}
{
props
.
uploadInfo
.
successButtonLabel
??
'重新上传'
}
</
Button
>
</
Button
>
...
@@ -282,18 +317,20 @@ export default defineComponent({
...
@@ -282,18 +317,20 @@ export default defineComponent({
return
UploadSuccess
();
return
UploadSuccess
();
}
}
};
};
watch
(
()
=>
props
.
modelValue
,
(
v
)
=>
{
if
(
!
v
)
{
Curfile
.
status
=
0
;
}
},
);
return
()
=>
(
return
()
=>
(
<
div
class=
"custom-real-upload"
>
<
div
class=
"custom-real-upload"
>
<
div
class=
"real-upload-content"
>
<
div
class=
"real-upload-content"
>
<
div
class=
"custom-real-upload-component"
>
{
currentUploadStatus
()
}
</
div
>
{
/* <div class="custom-real-upload-component">{currentUploadStatus()}</div> */
}
<
div
class=
"custom-real-upload-component"
v
-
show=
{
Curfile
.
status
==
0
}
>
{
notUploadHtml
()
}
</
div
>
<
div
class=
"custom-real-upload-component"
v
-
show=
{
Curfile
.
status
==
1
}
>
{
UploadingHtml
()
}
</
div
>
<
div
class=
"custom-real-upload-component"
v
-
show=
{
Curfile
.
status
==
2
}
>
{
UploadSuccess
()
}
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
);
);
...
...
src/hooks/useConfuse.ts
0 → 100644
View file @
0d8701a5
import
{
show_message
}
from
'@/utils/tool'
;
import
{
liveContentRegenerate
,
liveContentRegenerateCallback
}
from
'@/utils/api/userApi'
;
import
{
onBeforeUnmount
,
ref
}
from
'vue'
;
export
default
function
()
{
// 洗稿次数
const
confuseNum
=
1
;
// 当前洗稿次数
const
currentConfuseNum
=
ref
(
0
);
// 定时器
const
confuseInterval
=
ref
(
null
);
// 洗稿回调列表
const
confuseList
=
ref
([]);
// 洗稿id
const
currentConfuseId
=
ref
(
''
);
const
openConfuseInterval
=
()
=>
{
confuseInterval
.
value
=
window
.
setTimeout
(()
=>
{
currentStartConfuseBack
(
currentConfuseId
.
value
);
},
3000
);
};
// 关闭定时器
const
closeConfuseInterval
=
()
=>
{
window
.
clearInterval
(
confuseInterval
.
value
);
clearInterval
(
confuseInterval
.
value
);
confuseInterval
.
value
=
null
;
};
// 洗稿提交
const
currentStartConfuse
=
async
(
data
:
any
)
=>
{
try
{
//
let
res
:
any
=
await
liveContentRegenerate
(
data
);
if
(
res
.
code
==
0
)
{
// 打开定时器
openConfuseInterval
();
}
}
catch
(
e
)
{
console
.
log
(
e
);
}
};
// 获取洗稿回调
const
currentStartConfuseBack
=
async
(
id
:
any
)
=>
{
try
{
let
res
:
any
=
await
liveContentRegenerateCallback
({
task_id
:
id
,
});
if
(
res
.
code
==
0
&&
res
.
data
.
length
)
{
closeConfuseInterval
();
confuseList
.
value
=
res
.
data
;
}
}
catch
(
e
)
{
console
.
log
(
e
);
}
};
onBeforeUnmount
(()
=>
{
closeConfuseInterval
();
});
return
{
confuseList
,
currentConfuseId
,
currentStartConfuse
,
};
}
src/layouts/components/Content.vue
View file @
0d8701a5
...
@@ -20,7 +20,7 @@ import { useRoute } from 'vue-router';
...
@@ -20,7 +20,7 @@ import { useRoute } from 'vue-router';
const
route
=
useRoute
();
const
route
=
useRoute
();
const
getKey
=
()
=>
{
const
getKey
=
()
=>
{
return
route
.
fullPath
;
return
route
.
name
;
};
};
</
script
>
</
script
>
...
...
src/pages/VocalCustomization/components/MyDigitalPerson.vue
View file @
0d8701a5
...
@@ -81,7 +81,7 @@ const confirm = () => {
...
@@ -81,7 +81,7 @@ const confirm = () => {
const
getList
=
async
()
=>
{
const
getList
=
async
()
=>
{
try
{
try
{
loading
.
value
=
true
;
loading
.
value
=
true
;
let
res
:
any
=
await
getTonesList
();
let
res
:
any
=
await
getTonesList
(
false
);
res
.
soundColor
.
forEach
((
item
:
any
)
=>
{
res
.
soundColor
.
forEach
((
item
:
any
)
=>
{
item
.
play_status
=
false
;
item
.
play_status
=
false
;
});
});
...
...
src/pages/VocalCustomization/components/Record.vue
View file @
0d8701a5
...
@@ -42,7 +42,7 @@ const loading = ref(false);
...
@@ -42,7 +42,7 @@ const loading = ref(false);
const
getList
=
async
()
=>
{
const
getList
=
async
()
=>
{
try
{
try
{
loading
.
value
=
true
;
loading
.
value
=
true
;
let
res
:
any
=
await
getTonesList
();
let
res
:
any
=
await
getTonesList
(
false
);
res
.
soundColor
.
forEach
((
item
:
any
)
=>
{
res
.
soundColor
.
forEach
((
item
:
any
)
=>
{
item
.
play_status
=
false
;
item
.
play_status
=
false
;
});
});
...
...
src/pages/createLive/components/scripts.vue
View file @
0d8701a5
...
@@ -3,6 +3,30 @@
...
@@ -3,6 +3,30 @@
<div
class=
"all-select"
>
<div
class=
"all-select"
>
<Select
:options=
"scriptTypeList"
v-model=
"currentOption"
@
change=
"scriptTypeChange"
></Select>
<Select
:options=
"scriptTypeList"
v-model=
"currentOption"
@
change=
"scriptTypeChange"
></Select>
<CheckBox
v-model=
"isDisorganize"
@
change=
"checkboxChange"
>
GPT洗稿
</CheckBox>
<CheckBox
v-model=
"isDisorganize"
@
change=
"checkboxChange"
>
GPT洗稿
</CheckBox>
<template
v-if=
"isDev()"
>
<Button
@
click=
"
doCopy(`
大家好!欢迎来到今天的直播!我是你们的主持人,今天我将为大家带来一场精彩的直播节目。在这里,我们将分享一些有趣的内容,并回答你们的问题。
首先,让我们来聊一聊今天的主题。今天我们将重点聚焦在XX领域(根据直播主题填写),这是一个非常热门、有趣且前沿的领域。我们将了解最新的发展动态、分享一些实用的技巧,并回答你们提出的问题。
对于新加入直播的朋友,特别欢迎你们!如果你们有任何问题或者想要了解更多关于XX的信息,请随时在评论区留言,我将尽力回答你们的问题。
在这里,我们鼓励大家积极互动。请大家在评论区留下你们的想法、观点和问题。我会选择一些与主题相关的问题进行回答,在回答问题时我会尽量深入浅出,以确保每个人都能够理解。
也请大家相互尊重,遵守礼貌。如果有令人不舒服的言论或者不适当的内容,请及时举报,我们会及时处理。
接下来,让我们一起进入今天的正题吧!不管你是刚开始接触XX,还是已经有一定了解,请相信你们在这里能够获得更多知识、更多的收获。
再次感谢大家的到来和支持,让我们一起度过这个精彩的时刻!祝愿大家在本次直播中有所收获,也希望大家能够在评论区互相交流,共同进步。
谢谢大家!现在,让我们开始今天的直播吧!
`)
"
>
测试文案
</Button
>
</
template
>
<div
<div
class=
"right-chose-tones"
class=
"right-chose-tones"
:style=
"{
:style=
"{
...
@@ -119,8 +143,38 @@
...
@@ -119,8 +143,38 @@
<Textarea
v-model=
"textareaValue"
@
change=
"textareaChange"
></Textarea>
<Textarea
v-model=
"textareaValue"
@
change=
"textareaChange"
></Textarea>
</
template
>
</
template
>
</div>
</div>
<div
class=
"script-setting-upload flex1"
v-show=
"currentOption === scriptTypePhonetics"
>
<div
class=
"script-setting-upload flex1 narrow-scrollbar"
v-show=
"currentOption === scriptTypePhonetics"
>
<CustomUpload
v-model=
"mp3Url"
:uploadInfo=
"uploadInfo"
:config=
"ossConfig"
@
change=
"uploadChange"
></CustomUpload>
<!-- edit -->
<
template
v-for=
"(item, index) in audioScriptList"
:key=
"index"
>
<ScriptTemplate
height=
"250px"
:showEdit=
"false"
@
edit=
"uploadAudioEdit(index)"
@
delete=
"onDeleteAudio(index)"
>
<div
class=
"script-template-body__audio-add"
>
<MultipleUpload
v-model=
"item.data"
:config=
"ossConfig"
label=
"选择音频"
@
change=
"uploadEdit"
></MultipleUpload>
</div>
</ScriptTemplate>
</
template
>
<!-- create -->
<ScriptTemplate
:showTool=
"false"
height=
"250px"
>
<div
class=
"script-template-body__audio-add"
>
<MultipleUpload
v-model=
"mp3UrlList"
:config=
"ossConfig"
label=
"选择音频"
@
change=
"createUploadFile"
></MultipleUpload>
<!-- <CustomUpload
v-model="mp3Url"
:showOldName="true"
:uploadInfo="uploadInfo"
:config="ossConfig"
@change="createUploadFile"
></CustomUpload> -->
</div>
</ScriptTemplate>
</div>
</div>
<TextScriptDialog
v-model=
"textScriptVisible"
@
submit=
"textScriptSubmit"
:info=
"editTextInfo"
></TextScriptDialog>
<TextScriptDialog
v-model=
"textScriptVisible"
@
submit=
"textScriptSubmit"
:info=
"editTextInfo"
></TextScriptDialog>
<ConfirmDialog
<ConfirmDialog
...
@@ -128,11 +182,18 @@
...
@@ -128,11 +182,18 @@
title=
"确定要删除该声音吗?"
title=
"确定要删除该声音吗?"
@
confirm=
"confirmDeleteText"
@
confirm=
"confirmDeleteText"
></ConfirmDialog>
></ConfirmDialog>
<ConfirmDialog
v-model=
"confirmDeleteAudioVisible"
title=
"确定要删除该声音吗?"
@
confirm=
"confirmDeleteAudio"
></ConfirmDialog>
</div>
</div>
</template>
</template>
<
script
lang=
"tsx"
setup
>
<
script
lang=
"tsx"
setup
>
import
{
computed
,
onMounted
,
reactive
,
ref
,
watch
}
from
'vue'
;
import
{
computed
,
onMounted
,
reactive
,
ref
,
watch
}
from
'vue'
;
import
Button
from
'@/components/Button.vue'
;
import
MultipleUpload
from
'@/components/MultipleUpload'
;
import
CheckBox
from
'@/components/CheckBox.vue'
;
import
CheckBox
from
'@/components/CheckBox.vue'
;
import
ConfirmDialog
from
'@/components/ConfirmDialog.vue'
;
import
ConfirmDialog
from
'@/components/ConfirmDialog.vue'
;
import
TextScriptDialog
from
'./TextScriptDialog.vue'
;
import
TextScriptDialog
from
'./TextScriptDialog.vue'
;
...
@@ -148,6 +209,8 @@ import { getUploadConfig, getTonesList } from '@/service/Common';
...
@@ -148,6 +209,8 @@ import { getUploadConfig, getTonesList } from '@/service/Common';
import
{
v4
}
from
'uuid'
;
import
{
v4
}
from
'uuid'
;
import
{
useStore
}
from
'vuex'
;
import
{
useStore
}
from
'vuex'
;
import
{
useRoute
}
from
'vue-router'
;
import
{
useRoute
}
from
'vue-router'
;
import
useCopy
from
'@/hooks/useCopy'
;
const
{
doCopy
}
=
useCopy
();
const
[
commitInfo
]
=
useLiveInfoSubmit
();
const
[
commitInfo
]
=
useLiveInfoSubmit
();
const
props
=
withDefaults
(
const
props
=
withDefaults
(
...
@@ -171,6 +234,8 @@ const createLiveInfo = computed(() => store.getters['live/getLiveInfo']);
...
@@ -171,6 +234,8 @@ const createLiveInfo = computed(() => store.getters['live/getLiveInfo']);
// 文本脚本列表
// 文本脚本列表
const
textScriptList
=
ref
([]);
const
textScriptList
=
ref
([]);
// 音频脚本列表
const
audioScriptList
=
ref
([]);
// 文本脚本el
// 文本脚本el
const
scriptSettingText
=
ref
<
HTMLDivElement
>
();
const
scriptSettingText
=
ref
<
HTMLDivElement
>
();
// 文本编辑时的行信息
// 文本编辑时的行信息
...
@@ -179,9 +244,16 @@ const editTextInfo = ref({});
...
@@ -179,9 +244,16 @@ const editTextInfo = ref({});
const
deleteTextId
=
ref
();
const
deleteTextId
=
ref
();
// 确认删除弹窗
// 确认删除弹窗
const
confirmDeleteVisible
=
ref
(
false
);
const
confirmDeleteVisible
=
ref
(
false
);
// 确认删除音频弹窗
const
confirmDeleteAudioVisible
=
ref
(
false
);
// 要删除的音频下标
const
deleteAudioIndex
=
ref
();
// 是否gpt洗稿
// 是否gpt洗稿
const
isDisorganize
=
ref
(
false
);
const
isDisorganize
=
ref
(
false
);
// upload组件的ref
const
uploadRef
=
ref
();
const
lists
=
reactive
({
const
lists
=
reactive
({
tones
:
[],
tones
:
[],
soundColor
:
[],
soundColor
:
[],
...
@@ -207,6 +279,8 @@ const textScriptVisible = ref(false);
...
@@ -207,6 +279,8 @@ const textScriptVisible = ref(false);
const
ossConfig
=
ref
({});
const
ossConfig
=
ref
({});
// 上传的音频文件链接
// 上传的音频文件链接
const
mp3Url
=
ref
(
''
);
const
mp3Url
=
ref
(
''
);
// 多选文件列表
const
mp3UrlList
=
ref
([]);
const
uploadInfo
=
{
const
uploadInfo
=
{
label1
:
'选择音频'
,
label1
:
'选择音频'
,
label2
:
'或拖音频到此处上传'
,
label2
:
'或拖音频到此处上传'
,
...
@@ -225,6 +299,51 @@ const textareaValue = ref('');
...
@@ -225,6 +299,51 @@ const textareaValue = ref('');
const
currentOption
=
ref
(
scriptTypeText
);
const
currentOption
=
ref
(
scriptTypeText
);
// 音频脚本上传后
const
createUploadFile
=
(
list
:
any
[],
oldList
:
any
[])
=>
{
// 添加到数组中
audioScriptList
.
value
.
push
({
data
:
JSON
.
parse
(
JSON
.
stringify
(
oldList
)),
});
// 提交到store
uploadChange
();
setTimeout
(()
=>
{
// 清空当前url
mp3UrlList
.
value
=
[];
},
0
);
};
// 音频脚本编辑后
const
uploadEdit
=
(
url
:
string
,
id
:
number
)
=>
{
uploadChange
();
};
const
confirmDeleteAudio
=
()
=>
{
audioScriptList
.
value
.
splice
(
deleteAudioIndex
.
value
,
1
);
uploadChange
();
};
// 删除音频
const
onDeleteAudio
=
(
index
:
number
)
=>
{
confirmDeleteAudioVisible
.
value
=
true
;
deleteAudioIndex
.
value
=
index
;
};
// 编辑按钮 音频脚本
const
uploadAudioEdit
=
(
index
:
number
)
=>
{
// 调用对应的上传事件
if
(
uploadRef
.
value
&&
uploadRef
.
value
.
length
)
{
let
element
:
HTMLDivElement
=
uploadRef
.
value
[
index
].
$el
;
if
(
element
)
{
// 找到上传元素
let
clickElement
=
element
.
getElementsByClassName
(
'custom-upload-click-box'
);
if
(
clickElement
&&
clickElement
.
length
)
{
clickElement
[
0
].
click
();
}
}
}
};
// 洗稿checkbox变化
// 洗稿checkbox变化
const
checkboxChange
=
(
value
:
boolean
)
=>
{
const
checkboxChange
=
(
value
:
boolean
)
=>
{
commitInfo
({
commitInfo
({
...
@@ -304,7 +423,6 @@ const updateTonesInfo = (tone_id: any, phonetic_timbres_id: any) => {
...
@@ -304,7 +423,6 @@ const updateTonesInfo = (tone_id: any, phonetic_timbres_id: any) => {
};
};
const
updateInfo
=
(
info
:
any
)
=>
{
const
updateInfo
=
(
info
:
any
)
=>
{
console
.
log
(
info
);
let
type
=
''
;
let
type
=
''
;
let
type_content
=
''
;
let
type_content
=
''
;
let
phonetic_timbres_id
=
''
;
let
phonetic_timbres_id
=
''
;
...
@@ -379,9 +497,9 @@ const openSoundColor = () => {
...
@@ -379,9 +497,9 @@ const openSoundColor = () => {
};
};
// 音频文件提交
// 音频文件提交
const
uploadChange
=
(
value
:
string
)
=>
{
const
uploadChange
=
()
=>
{
commitInfo
({
commitInfo
({
[
createLiveKeys
.
phoneticsFile
]:
value
,
[
createLiveKeys
.
audioScriptList
]:
audioScriptList
.
value
,
});
});
};
};
...
@@ -648,8 +766,29 @@ onMounted(async () => {
...
@@ -648,8 +766,29 @@ onMounted(async () => {
}
}
}
}
.script-setting-upload
{
.script-setting-upload
{
.custom-real-upload
{
overflow-y
:
auto
;
overflow-x
:
hidden
;
.script-template-body__audio-add
{
height
:
100%
;
height
:
100%
;
.custom-real-upload
{
height
:
100%
;
background
:
transparent
;
.custom-UploadSuccess-stauts
{
.icon
{
img
{
width
:
40px
;
height
:
40px
;
}
}
.file-name
{
margin-bottom
:
12px
;
}
}
}
.custom-multiple-upload
{
height
:
100%
;
background
:
transparent
;
}
}
}
}
}
}
}
...
...
src/pages/createLive/hooks/scripts.ts
View file @
0d8701a5
This diff is collapsed.
Click to expand it.
src/pages/createLive/index.vue
View file @
0d8701a5
...
@@ -50,7 +50,7 @@
...
@@ -50,7 +50,7 @@
</div>
</div>
</div>
</div>
<ConfirmDialog
v-model=
"confirmVisible"
:title=
"'确定要生成该直播吗?'"
@
confirm=
"confirm"
></ConfirmDialog>
<ConfirmDialog
v-model=
"confirmVisible"
:title=
"'确定要生成该直播吗?'"
@
confirm=
"confirm"
></ConfirmDialog>
<Loading
v-show=
"loading"
></Loading>
<Loading
v-show=
"loading"
:mask=
"true"
></Loading>
</div>
</div>
</template>
</template>
...
@@ -66,7 +66,7 @@ import ChoseDigitalPerson from './components/ChoseDigitalPerson.vue';
...
@@ -66,7 +66,7 @@ import ChoseDigitalPerson from './components/ChoseDigitalPerson.vue';
import
HomeSvg
from
'@/assets/svg/createLive/home.svg'
;
import
HomeSvg
from
'@/assets/svg/createLive/home.svg'
;
import
InteractSvg
from
'@/assets/svg/createLive/interact.svg'
;
import
InteractSvg
from
'@/assets/svg/createLive/interact.svg'
;
import
ScriptsSvg
from
'@/assets/svg/createLive/scripts.svg'
;
import
ScriptsSvg
from
'@/assets/svg/createLive/scripts.svg'
;
import
{
computed
,
onMounted
,
ref
,
onBeforeUnmount
}
from
'vue'
;
import
{
computed
,
onMounted
,
ref
,
onBeforeUnmount
,
onActivated
}
from
'vue'
;
import
{
getElBounding
,
show_message
,
DataType
}
from
'@/utils/tool'
;
import
{
getElBounding
,
show_message
,
DataType
}
from
'@/utils/tool'
;
import
{
useStore
}
from
'vuex'
;
import
{
useStore
}
from
'vuex'
;
import
{
createLiveKeys
,
scriptTypeText
,
scriptTypePhonetics
}
from
'@/service/CreateLive'
;
import
{
createLiveKeys
,
scriptTypeText
,
scriptTypePhonetics
}
from
'@/service/CreateLive'
;
...
@@ -78,7 +78,8 @@ import { createLiveRouteKey } from '@/constants/token';
...
@@ -78,7 +78,8 @@ import { createLiveRouteKey } from '@/constants/token';
import
{
callPyjsInWindow
}
from
'@/utils/pyqt'
;
import
{
callPyjsInWindow
}
from
'@/utils/pyqt'
;
import
{
useLiveInfoSubmit
}
from
'@/hooks/useStoreCommit'
;
import
{
useLiveInfoSubmit
}
from
'@/hooks/useStoreCommit'
;
import
{
processTextCallback
}
from
'./hooks/scripts'
;
import
{
processTextCallback
}
from
'./hooks/scripts'
;
const
{
openInterval
}
=
processTextCallback
();
const
{
loading
,
initNum
,
currentSetp
,
openInterval
,
filterFiled
,
backHome
,
submitSuccessed
,
submit
,
initCreateStore
}
=
processTextCallback
();
const
[
commitInfo
]
=
useLiveInfoSubmit
();
const
[
commitInfo
]
=
useLiveInfoSubmit
();
const
store
=
useStore
();
const
store
=
useStore
();
...
@@ -90,18 +91,11 @@ const liveImage = computed(() => store.getters['live/getLiveimage']);
...
@@ -90,18 +91,11 @@ const liveImage = computed(() => store.getters['live/getLiveimage']);
const
createLiveInfo
=
computed
(()
=>
store
.
getters
[
'live/getLiveInfo'
]);
const
createLiveInfo
=
computed
(()
=>
store
.
getters
[
'live/getLiveInfo'
]);
const
liveName
=
computed
(()
=>
store
.
getters
[
'live/getName'
]);
const
liveName
=
computed
(()
=>
store
.
getters
[
'live/getName'
]);
const
loading
=
ref
(
false
);
const
confirmVisible
=
ref
(
false
);
const
confirmVisible
=
ref
(
false
);
const
publicTool
=
ref
<
HTMLElement
>
();
const
publicTool
=
ref
<
HTMLElement
>
();
const
toolHeight
=
ref
(
0
);
const
toolHeight
=
ref
(
0
);
const
currentSetp
=
ref
(
1
);
// 通知子组件初始化
const
initNum
=
ref
(
1
);
const
videoPlay
=
ref
<
HTMLVideoElement
>
();
const
videoPlay
=
ref
<
HTMLVideoElement
>
();
const
videoCanplay
=
()
=>
{
const
videoCanplay
=
()
=>
{
...
@@ -147,8 +141,8 @@ const setpsList = [
...
@@ -147,8 +141,8 @@ const setpsList = [
{
{
key
:
createLiveKeys
.
scriptType
,
key
:
createLiveKeys
.
scriptType
,
value
:
scriptTypePhonetics
,
value
:
scriptTypePhonetics
,
require
:
[
createLiveKeys
.
phoneticsFile
],
require
:
[
createLiveKeys
.
audioScriptList
],
message
:
'音频文件
必填
'
,
message
:
'音频文件
至少上传一个
'
,
},
},
],
],
},
},
...
@@ -225,13 +219,6 @@ const getEditInfo = async (id: any, type: string) => {
...
@@ -225,13 +219,6 @@ const getEditInfo = async (id: any, type: string) => {
}
}
};
};
const
backHome
=
()
=>
{
router
.
push
({
path
:
routerConfig
.
home
.
path
,
name
:
routerConfig
.
home
.
name
,
});
};
//
//
const
currentModuleField
=
()
=>
{
const
currentModuleField
=
()
=>
{
let
index
=
setpsList
.
findIndex
((
item
:
any
)
=>
item
.
value
===
currentSetp
.
value
);
let
index
=
setpsList
.
findIndex
((
item
:
any
)
=>
item
.
value
===
currentSetp
.
value
);
...
@@ -248,7 +235,6 @@ const currentModuleField = () => {
...
@@ -248,7 +235,6 @@ const currentModuleField = () => {
Object
.
keys
(
createLiveInfo
.
value
).
forEach
((
key
:
string
)
=>
{
Object
.
keys
(
createLiveInfo
.
value
).
forEach
((
key
:
string
)
=>
{
if
(
it
===
key
)
{
if
(
it
===
key
)
{
let
value
=
createLiveInfo
.
value
[
key
];
let
value
=
createLiveInfo
.
value
[
key
];
console
.
log
(
value
);
if
(
DataType
(
value
)
&&
!
value
.
length
)
{
if
(
DataType
(
value
)
&&
!
value
.
length
)
{
// 是数组
// 是数组
status
=
false
;
status
=
false
;
...
@@ -308,35 +294,6 @@ const onSave = () => {
...
@@ -308,35 +294,6 @@ const onSave = () => {
}
}
};
};
// 过滤必要的字段
const
filterFiled
=
()
=>
{
let
item
=
createLiveInfo
.
value
;
// 过滤必须字段
let
params
:
any
=
{};
params
.
name
=
liveName
.
value
;
// 数字人id
params
.
digital_man_id
=
item
[
createLiveKeys
.
id
];
// 脚本类型
params
.
type
=
item
[
createLiveKeys
.
scriptType
];
// 脚本内容
if
(
item
[
createLiveKeys
.
scriptType
]
==
scriptTypeText
)
{
// 文本
params
.
type_content
=
item
[
createLiveKeys
.
textScriptValue
];
// 音色id
params
.
phonetic_timbres_id
=
item
[
createLiveKeys
.
textSoundColor
];
}
else
{
// 音频
params
.
type_content
=
item
[
createLiveKeys
.
phoneticsFile
];
// 音色id
params
.
phonetic_timbres_id
=
item
[
createLiveKeys
.
phoneticsSoundColor
];
}
// 音调id
params
.
tone_id
=
item
[
createLiveKeys
.
textTones
];
// 互动库
params
.
interaction_ids
=
item
[
createLiveKeys
.
interactiveLibrary
];
return
params
;
};
// 保存为草稿
// 保存为草稿
const
onSaveDrafts
=
async
()
=>
{
const
onSaveDrafts
=
async
()
=>
{
let
params
=
filterFiled
();
let
params
=
filterFiled
();
...
@@ -396,7 +353,6 @@ const confirm = async () => {
...
@@ -396,7 +353,6 @@ const confirm = async () => {
if
(
item
[
createLiveKeys
.
scriptType
]
==
scriptTypeText
)
{
if
(
item
[
createLiveKeys
.
scriptType
]
==
scriptTypeText
)
{
// 文本脚本
// 文本脚本
loading
.
value
=
true
;
loading
.
value
=
true
;
for
(
let
i
=
0
;
i
<
item
[
createLiveKeys
.
textScriptList
].
length
;
i
++
)
{
for
(
let
i
=
0
;
i
<
item
[
createLiveKeys
.
textScriptList
].
length
;
i
++
)
{
let
params
=
{
let
params
=
{
// 音色
// 音色
...
@@ -421,27 +377,14 @@ const confirm = async () => {
...
@@ -421,27 +377,14 @@ const confirm = async () => {
}
}
}
}
// 开启轮询
// 开启轮询
openInterval
();
openInterval
(
false
);
}
else
{
}
else
{
// 音频脚本
try
{
try
{
loading
.
value
=
true
;
loading
.
value
=
true
;
let
res
:
any
=
await
createLiveTask
(
filterFiled
());
let
res
=
await
submit
();
if
(
res
.
code
==
0
)
{
if
(
res
)
{
show_message
(
'创建成功'
,
'success'
);
submitSuccessed
();
// 回首页
backHome
();
// 清空name
store
.
commit
(
'live/setName'
,
''
);
// 清空edit
store
.
commit
(
'live/clearEditLive'
);
// 清空createLive
store
.
commit
(
'live/clearCreateLive'
);
store
.
commit
(
'live/initLiveInfo'
);
// 清空信息
// 通知三个模块清空自己的内容
initNum
.
value
+=
1
;
// 回到模块1
currentSetp
.
value
=
1
;
}
}
loading
.
value
=
false
;
loading
.
value
=
false
;
}
catch
(
e
)
{
}
catch
(
e
)
{
...
@@ -467,6 +410,9 @@ onMounted(() => {
...
@@ -467,6 +410,9 @@ onMounted(() => {
query
:
route
.
query
,
query
:
route
.
query
,
});
});
});
});
onActivated
(()
=>
{
store
.
commit
(
'live/setName'
,
route
.
query
.
title
?
route
.
query
.
title
:
''
);
});
onBeforeUnmount
(()
=>
{
onBeforeUnmount
(()
=>
{
// 清空选择的数字人
// 清空选择的数字人
...
...
src/service/Common.ts
View file @
0d8701a5
...
@@ -5,10 +5,14 @@ import {
...
@@ -5,10 +5,14 @@ import {
updateLiveTask
,
updateLiveTask
,
getGroupsInteraction
,
getGroupsInteraction
,
updateDrafts
,
updateDrafts
,
liveContentRegenerate
,
liveContentRegenerateCallback
,
}
from
'@/utils/api/userApi'
;
}
from
'@/utils/api/userApi'
;
import
{
typeTones
,
typeSoundColor
}
from
'@/service/CreateLive'
;
import
{
typeTones
,
typeSoundColor
}
from
'@/service/CreateLive'
;
import
{
show_message
}
from
'@/utils/tool'
;
import
{
show_message
}
from
'@/utils/tool'
;
import
{
LIVE_AUDIT_STATUS
}
from
'./Live'
;
// 阿里云上传配置
export
const
getUploadConfig
=
async
()
=>
{
export
const
getUploadConfig
=
async
()
=>
{
try
{
try
{
let
res
:
any
=
await
getAlyOssConfig
();
let
res
:
any
=
await
getAlyOssConfig
();
...
@@ -43,7 +47,7 @@ export const getDigitalPeopleList = async () => {
...
@@ -43,7 +47,7 @@ export const getDigitalPeopleList = async () => {
};
};
// 获取我的音调
// 获取我的音调
export
const
getTonesList
=
async
()
=>
{
export
const
getTonesList
=
async
(
mustSuccess
:
boolean
=
true
)
=>
{
let
obj
=
{
let
obj
=
{
tones
:
[],
tones
:
[],
soundColor
:
[],
soundColor
:
[],
...
@@ -57,7 +61,14 @@ export const getTonesList = async () => {
...
@@ -57,7 +61,14 @@ export const getTonesList = async () => {
item
.
c_categorie
=
item
.
extend
?.
voice
;
item
.
c_categorie
=
item
.
extend
?.
voice
;
});
});
obj
.
tones
=
res
.
data
.
filter
((
item
:
any
)
=>
item
.
type
==
typeTones
);
obj
.
tones
=
res
.
data
.
filter
((
item
:
any
)
=>
item
.
type
==
typeTones
);
obj
.
soundColor
=
res
.
data
.
filter
((
item
:
any
)
=>
item
.
type
==
typeSoundColor
);
obj
.
soundColor
=
res
.
data
.
filter
((
item
:
any
)
=>
{
if
(
item
.
type
==
typeSoundColor
)
{
if
(
item
.
status
!=
LIVE_AUDIT_STATUS
.
LIVE_AUDIT_STATUS_FINISH
&&
mustSuccess
)
{
return
;
}
return
item
;
}
});
}
}
return
obj
;
return
obj
;
}
catch
(
e
)
{
}
catch
(
e
)
{
...
...
src/service/CreateLive.ts
View file @
0d8701a5
...
@@ -8,6 +8,7 @@ export const createLiveKeys = {
...
@@ -8,6 +8,7 @@ export const createLiveKeys = {
textSoundColor
:
'phonetic_timbres_id'
,
// 文本音色
textSoundColor
:
'phonetic_timbres_id'
,
// 文本音色
textScriptValue
:
'type_content'
,
// 文字脚本的文本
textScriptValue
:
'type_content'
,
// 文字脚本的文本
textScriptList
:
'type_content_list'
,
// 文字脚本列表
textScriptList
:
'type_content_list'
,
// 文字脚本列表
audioScriptList
:
'type_content_audio_list'
,
// 音频脚本文件列表
phoneticsSoundColor
:
'phoneticsSoundColor'
,
// 音频 音色
phoneticsSoundColor
:
'phoneticsSoundColor'
,
// 音频 音色
phoneticsFile
:
'phoneticsFile'
,
// 音频文件
phoneticsFile
:
'phoneticsFile'
,
// 音频文件
commentMethod
:
'commentMethod'
,
// 评论方式
commentMethod
:
'commentMethod'
,
// 评论方式
...
...
src/store/modules/live.ts
View file @
0d8701a5
...
@@ -7,13 +7,14 @@ const initParams = () => {
...
@@ -7,13 +7,14 @@ const initParams = () => {
[
createLiveKeys
.
scriptType
]:
''
,
[
createLiveKeys
.
scriptType
]:
''
,
[
createLiveKeys
.
textTones
]:
''
,
[
createLiveKeys
.
textTones
]:
''
,
[
createLiveKeys
.
textSoundColor
]:
''
,
[
createLiveKeys
.
textSoundColor
]:
''
,
[
createLiveKeys
.
textScriptValue
]:
''
,
[
createLiveKeys
.
textScriptValue
]:
[]
,
[
createLiveKeys
.
phoneticsSoundColor
]:
''
,
[
createLiveKeys
.
phoneticsSoundColor
]:
''
,
[
createLiveKeys
.
phoneticsFile
]:
''
,
[
createLiveKeys
.
phoneticsFile
]:
''
,
[
createLiveKeys
.
commentMethod
]:
''
,
[
createLiveKeys
.
commentMethod
]:
''
,
[
createLiveKeys
.
isDisorganize
]:
false
,
[
createLiveKeys
.
isDisorganize
]:
false
,
[
createLiveKeys
.
interactiveLibrary
]:
[],
[
createLiveKeys
.
interactiveLibrary
]:
[],
[
createLiveKeys
.
textScriptList
]:
[],
[
createLiveKeys
.
textScriptList
]:
[],
[
createLiveKeys
.
audioScriptList
]:
[],
[
createLiveKeys
.
scriptUuid
]:
''
,
[
createLiveKeys
.
scriptUuid
]:
''
,
};
};
};
};
...
@@ -39,7 +40,6 @@ const mutations = {
...
@@ -39,7 +40,6 @@ const mutations = {
Object
.
keys
(
info
).
forEach
((
item
:
any
)
=>
{
Object
.
keys
(
info
).
forEach
((
item
:
any
)
=>
{
state
.
createLive
[
item
]
=
info
[
item
];
state
.
createLive
[
item
]
=
info
[
item
];
});
});
console
.
log
(
state
.
createLive
);
},
},
initLiveInfo
(
state
:
StateType
)
{
initLiveInfo
(
state
:
StateType
)
{
state
.
createLive
=
initParams
();
state
.
createLive
=
initParams
();
...
...
src/utils/api/userApi.ts
View file @
0d8701a5
...
@@ -338,3 +338,34 @@ export const getLiveTtsCallback = (data: any) => {
...
@@ -338,3 +338,34 @@ export const getLiveTtsCallback = (data: any) => {
},
},
});
});
};
};
// 洗稿提交
export
const
liveContentRegenerate
=
async
(
data
:
any
)
=>
{
const
header
=
getHeader
();
return
request
.
post
(
`/api/live/content/regenerate`
,
data
,
{
headers
:
{
...
header
,
},
});
};
// 获取洗稿回调
export
const
liveContentRegenerateCallback
=
(
data
:
any
)
=>
{
const
header
=
getHeader
();
return
request
.
get
(
`/api/live/content/regenerate`
,
{
params
:
data
,
headers
:
{
...
header
,
},
});
};
// 重新生成直播
export
const
liveTaskRegenerate
=
()
=>
{
const
header
=
getHeader
();
return
request
.
post
(
`/api/live/task/{id}/regenerate`
,
''
,
{
headers
:
{
...
header
,
},
});
};
src/utils/audio.ts
View file @
0d8701a5
// 将浮点数音频数据转换为16位PCM数据
import
{
downloadBlobFile
,
show_message
}
from
'./tool'
;
const
floatTo16BitPCM
=
(
output
,
offset
,
input
)
=>
{
import
{
v4
}
from
'uuid'
;
for
(
let
i
=
0
;
i
<
input
.
length
;
i
++
,
offset
+=
2
)
{
export
const
createAudioContext
=
()
=>
{
const
s
=
Math
.
max
(
-
1
,
Math
.
min
(
1
,
input
[
i
]));
return
new
(
window
.
AudioContext
||
window
.
webkitAudioContext
)();
output
.
setInt16
(
offset
,
s
<
0
?
s
*
0x8000
:
s
*
0x7fff
,
true
);
}
};
// 在DataView中写入字符串
const
writeString
=
(
view
,
offset
,
string
)
=>
{
for
(
let
i
=
0
;
i
<
string
.
length
;
i
++
)
{
view
.
setUint8
(
offset
+
i
,
string
.
charCodeAt
(
i
));
}
};
};
// 将AudioBuffer转换为WAVE格式的Blob
export
async
function
decodeAudio
(
blob
:
Blob
)
{
const
bufferToWave
=
(
buffer
)
=>
{
const
audioContext
=
createAudioContext
();
const
arrayBuffer
=
new
ArrayBuffer
(
44
+
buffer
.
length
*
2
);
return
new
Promise
((
resolve
,
reject
)
=>
{
const
view
=
new
DataView
(
arrayBuffer
);
const
fileReader
=
new
FileReader
();
fileReader
.
onloadend
=
function
()
{
// 添加WAVE文件头
const
arrayBuffer
=
fileReader
.
result
;
writeString
(
view
,
0
,
'RIFF'
);
audioContext
.
decodeAudioData
(
view
.
setUint32
(
4
,
32
+
buffer
.
length
*
2
,
true
);
arrayBuffer
,
writeString
(
view
,
8
,
'WAVE'
);
(
audioBuffer
:
any
)
=>
{
writeString
(
view
,
12
,
'fmt '
);
resolve
(
audioBuffer
);
view
.
setUint32
(
16
,
16
,
true
);
},
view
.
setUint16
(
20
,
1
,
true
);
reject
,
view
.
setUint16
(
22
,
buffer
.
numberOfChannels
,
true
);
);
view
.
setUint32
(
24
,
buffer
.
sampleRate
,
true
);
};
view
.
setUint32
(
28
,
buffer
.
sampleRate
*
buffer
.
numberOfChannels
*
2
,
true
);
fileReader
.
onerror
=
reject
;
view
.
setUint16
(
32
,
buffer
.
numberOfChannels
*
2
,
true
);
fileReader
.
readAsArrayBuffer
(
blob
);
view
.
setUint16
(
34
,
16
,
true
);
});
writeString
(
view
,
36
,
'data'
);
}
view
.
setUint32
(
40
,
buffer
.
length
*
2
,
true
);
// 合并音频文件
export
async
function
audioMerge
(
filePaths
)
{
// 将音频数据写入buffer
try
{
floatTo16BitPCM
(
view
,
44
,
buffer
);
// 创建一个新的音频上下文
const
audioContext
=
createAudioContext
();
// 将ArrayBuffer转换为Blob
return
new
Blob
([
view
],
{
type
:
'audio/wav'
});
// 存储每个音频文件的解码后的音频数据
};
const
buffers
=
[];
// 音频合并
// 使用 Promise 依次解码和添加音频数据到 buffers 数组
export
const
audioMerge
=
async
(
audioUrls
:
string
[])
=>
{
await
Promise
.
all
(
// 创建一个新的AudioContext对象
filePaths
.
map
(
async
(
filePath
)
=>
{
const
audioContext
=
new
(
window
.
AudioContext
||
window
.
webkitAudioContext
)();
const
response
=
await
fetch
(
filePath
);
const
arrayBuffer
=
await
response
.
arrayBuffer
();
const
audioBuffers
=
[];
const
loadAudioFile
=
async
(
url
)
=>
{
const
audioBuffer
=
await
audioContext
.
decodeAudioData
(
arrayBuffer
);
const
response
=
await
fetch
(
url
);
return
audioBuffer
;
const
arrayBuffer
=
await
response
.
arrayBuffer
();
}),
return
audioContext
.
decodeAudioData
(
arrayBuffer
);
).
then
((
decodedBuffers
)
=>
{
};
buffers
.
push
(...
decodedBuffers
);
// 将解码后的音频缓冲区按顺序添加到数组中
});
const
loadAllAudioFiles
=
async
()
=>
{
for
(
const
audioUrl
of
audioUrls
)
{
// 计算合并后的音频数据的长度
const
audioBuffer
=
await
loadAudioFile
(
audioUrl
);
const
totalDuration
=
buffers
.
reduce
((
accumulator
,
current
)
=>
accumulator
+
current
.
duration
,
0
);
audioBuffers
.
push
(
audioBuffer
);
const
sampleRate
=
audioContext
.
sampleRate
;
}
const
numberOfChannels
=
buffers
[
0
].
numberOfChannels
;
};
const
channels
=
buffers
[
0
].
numberOfChannels
;
// 创建一个新的音频缓冲区
// 合并音频文件
const
mergeAudioFiles
=
async
()
=>
{
// 创建一个新的AudioBuffer对象来保存合并后的音频
const
mergedBuffer
=
audioContext
.
createBuffer
(
const
mergedBuffer
=
audioContext
.
createBuffer
(
audioBuffers
[
0
].
numberOfChannels
,
numberOfChannels
,
audioBuffers
[
0
].
length
,
Math
.
round
(
sampleRate
*
totalDuration
)
,
audioBuffers
[
0
].
sampleRate
,
sampleRate
,
);
);
// 将每个音频文件的数据复制到合并后的AudioBuffer中
let
offset
=
0
;
for
(
let
i
=
0
;
i
<
audioBuffers
.
length
;
i
++
)
{
const
sourceBuffer
=
audioBuffers
[
i
];
// 合并音频数据
for
(
let
channel
=
0
;
channel
<
sourceBuffer
.
numberOfChannels
;
channel
++
)
{
buffers
.
forEach
((
buffer
,
index
)
=>
{
const
sourceData
=
sourceBuffer
.
getChannelData
(
channel
);
for
(
let
channel
=
0
;
channel
<
channels
;
channel
++
)
{
const
mergedData
=
mergedBuffer
.
getChannelData
(
channel
);
const
sourceData
=
buffer
.
getChannelData
(
channel
);
mergedData
.
set
(
sourceData
,
i
*
sourceBuffer
.
length
);
const
targetData
=
mergedBuffer
.
getChannelData
(
channel
);
targetData
.
set
(
sourceData
,
offset
);
}
}
}
offset
+=
Math
.
round
(
buffer
.
duration
*
sampleRate
);
});
// 导出合并后的音频数据为 WAV 文件
const
mergedData
=
exportBufferAsWav
(
mergedBuffer
);
const
blob
=
new
Blob
([
mergedData
],
{
type
:
'audio/wav'
});
return
blob
;
}
catch
(
error
)
{
console
.
error
(
'音频文件合并失败:'
,
error
);
}
}
// 将合并后的音频写入文件
// 切割音频文件
let
renderedBuffer
=
await
audioContext
.
startRendering
();
export
async
function
splitAudio
(
fileBlob
:
Blob
,
splitSize
:
number
)
{
const
offlineAudioContext
=
new
OfflineAudioContext
(
if
(
fileBlob
.
size
<
splitSize
)
{
mergedBuffer
.
numberOfChannels
,
return
[
fileBlob
];
renderedBuffer
.
length
,
}
renderedBuffer
.
sampleRate
,
);
const
source
=
offlineAudioContext
.
createBufferSource
();
source
.
buffer
=
mergedBuffer
;
source
.
connect
(
offlineAudioContext
.
destination
);
source
.
start
();
let
renderedBufferChild
=
await
offlineAudioContext
.
startRendering
();
return
renderedBufferChild
;
// 将合并后的音频保存为文件
const
audioBlob
=
bufferToWave
(
renderedBufferChild
);
// const audioUrl = URL.createObjectURL(audioBlob);
};
// 加载
await
loadAllAudioFiles
();
// 并合并音频文件
return
mergeAudioFiles
();
};
// 切割音频并保存为Blob对象
try
{
export
const
splitAudio
=
async
(
audioBuffer
,
blockSize
)
=>
{
const
MAX_CHUNK_SIZE
=
splitSize
;
const
numBlocks
=
Math
.
ceil
(
audioBuffer
.
length
/
blockSize
);
const
newChunks
=
[];
const
audioChunks
=
[];
for
(
let
i
=
0
;
i
<
numBlocks
;
i
++
)
{
const
asyncReadFile
=
(
file
,
offset
)
=>
{
const
startOffset
=
i
*
blockSize
;
return
new
Promise
((
resolve
,
reject
)
=>
{
const
endOffset
=
Math
.
min
(
startOffset
+
blockSize
,
audioBuffer
.
length
);
const
reader
=
new
FileReader
(
);
const
bufferChunk
=
audioBuffer
.
slice
(
startOffset
,
endOffset
);
reader
.
onload
=
(
event
)
=>
{
audioChunks
.
push
(
bufferChunk
);
const
binaryData
=
event
.
target
.
result
;
const
chunkName
=
v4
();
const
binaryFile
=
new
File
([
binaryData
],
chunkName
,
{
type
:
file
.
type
});
resolve
(
binaryFile
);
};
reader
.
onerror
=
()
=>
{
reject
(
new
Error
(
'File read error.'
));
};
const
chunk
=
file
.
slice
(
offset
,
offset
+
MAX_CHUNK_SIZE
);
reader
.
readAsArrayBuffer
(
chunk
);
});
};
for
(
const
file
of
[
fileBlob
])
{
const
fileSize
=
file
.
size
;
let
offset
=
0
;
while
(
offset
<
fileSize
)
{
const
chunkSize
=
Math
.
min
(
MAX_CHUNK_SIZE
,
fileSize
-
offset
);
const
binaryFile
=
await
asyncReadFile
(
file
,
offset
);
newChunks
.
push
(
binaryFile
);
offset
+=
chunkSize
;
}
}
return
newChunks
;
}
catch
(
e
)
{
show_message
(
'音频切割失败'
);
}
}
// 导出音频缓冲区为 WAV 文件
function
exportBufferAsWav
(
audioBuffer
)
{
const
numberOfChannels
=
audioBuffer
.
numberOfChannels
;
const
sampleRate
=
audioBuffer
.
sampleRate
;
const
length
=
audioBuffer
.
length
;
const
channels
=
[];
// 将音频缓冲区的数据转化为通道数组
for
(
let
channel
=
0
;
channel
<
numberOfChannels
;
channel
++
)
{
channels
.
push
(
audioBuffer
.
getChannelData
(
channel
));
}
}
// 将切割后的音频块进行合并,并转换为Blob对象
// 创建 WAV 文件头
const
mergedChunks
=
new
Blob
(
audioChunks
,
{
type
:
'audio/wav'
});
const
buffer
=
new
ArrayBuffer
(
44
+
length
*
2
);
const
view
=
new
DataView
(
buffer
);
view
.
setUint32
(
0
,
0x52494646
,
false
);
// RIFF 头部
view
.
setUint32
(
4
,
36
+
length
*
2
,
true
);
// 文件大小
view
.
setUint32
(
8
,
0x57415645
,
false
);
// WAVE 标记
view
.
setUint32
(
12
,
0x666d7420
,
false
);
// fmt 头部
view
.
setUint32
(
16
,
16
,
true
);
// fmt 大小
view
.
setUint16
(
20
,
1
,
true
);
// 格式(1表示 PCM)
view
.
setUint16
(
22
,
numberOfChannels
,
true
);
// 通道数
view
.
setUint32
(
24
,
sampleRate
,
true
);
// 采样率
view
.
setUint32
(
28
,
sampleRate
*
2
*
numberOfChannels
,
true
);
// 数据速率
view
.
setUint16
(
32
,
numberOfChannels
*
2
,
true
);
// 数据块大小
view
.
setUint16
(
34
,
16
,
true
);
// 量化位数
view
.
setUint32
(
36
,
0x64617461
,
false
);
// data 头部
view
.
setUint32
(
40
,
length
*
2
,
true
);
// 数据大小
// 将音频数据写入 WAV 文件
for
(
let
i
=
0
;
i
<
length
;
i
++
)
{
for
(
let
channel
=
0
;
channel
<
numberOfChannels
;
channel
++
)
{
const
sample
=
Math
.
max
(
-
1
,
Math
.
min
(
1
,
channels
[
channel
][
i
]));
const
value
=
sample
<
0
?
sample
*
0x8000
:
sample
*
0x7fff
;
view
.
setInt16
(
44
+
i
*
numberOfChannels
*
2
+
channel
*
2
,
value
,
true
);
}
}
return
mergedChunks
;
return
new
Uint8Array
(
buffer
)
;
}
;
}
src/utils/request.ts
View file @
0d8701a5
...
@@ -33,14 +33,6 @@ instance.interceptors.response.use(
...
@@ -33,14 +33,6 @@ instance.interceptors.response.use(
const
{
data
}
=
response
;
const
{
data
}
=
response
;
if
(
data
.
code
===
0
)
{
if
(
data
.
code
===
0
)
{
return
data
;
return
data
;
}
else
{
//@ts-ignore
if
(
response
.
config
.
needCode
)
{
return
data
;
}
else
{
show_message
(
data
.
msg
||
error_messaage
,
'error'
);
return
Promise
.
reject
(
data
.
msg
);
}
}
}
},
},
(
err
)
=>
{
(
err
)
=>
{
...
@@ -61,6 +53,7 @@ instance.interceptors.response.use(
...
@@ -61,6 +53,7 @@ instance.interceptors.response.use(
// 格式不一致的
// 格式不一致的
let
res
=
err
.
toJSON
();
let
res
=
err
.
toJSON
();
show_message
(
res
.
message
,
'error'
);
show_message
(
res
.
message
,
'error'
);
return
;
}
}
},
},
);
);
...
...
src/utils/tool.ts
View file @
0d8701a5
import
{
MessagePlugin
,
RequestMethodResponse
}
from
'tdesign-vue-next'
;
import
{
MessagePlugin
,
RequestMethodResponse
}
from
'tdesign-vue-next'
;
import
request
from
'@/utils/
other
Request'
;
import
request
from
'@/utils/
upLoad
Request'
;
/**
/**
* 函数节流处理
* 函数节流处理
...
@@ -168,56 +168,98 @@ export const alyOssUpload = (
...
@@ -168,56 +168,98 @@ export const alyOssUpload = (
UploadErrorCallback
:
Function
,
UploadErrorCallback
:
Function
,
fileName
:
string
,
fileName
:
string
,
)
=>
{
)
=>
{
return
new
Promise
<
RequestMethodResponse
>
((
resolve
)
=>
{
return
new
Promise
<
RequestMethodResponse
>
((
resolve
,
reject
)
=>
{
let
url
=
''
;
try
{
url
=
'https://'
+
config
.
host
;
let
url
=
''
;
let
files
:
any
[]
=
[];
url
=
'https://'
+
config
.
host
;
if
(
!
DataType
(
file
))
{
let
files
:
any
[]
=
[];
// 不是数组
if
(
!
DataType
(
file
))
{
files
=
[
file
];
// 不是数组
}
else
{
files
=
[
file
];
files
=
file
;
}
else
{
}
files
=
file
;
for
(
let
i
=
0
;
i
<
files
.
length
;
i
++
)
{
}
let
item
=
files
[
i
];
for
(
let
i
=
0
;
i
<
files
.
length
;
i
++
)
{
const
formData
=
new
FormData
();
let
item
=
files
[
i
];
formData
.
append
(
'key'
,
config
.
dir
+
fileName
+
`.
${
getFileSuffix
(
item
)}
`
);
const
formData
=
new
FormData
();
formData
.
append
(
'policy'
,
config
.
policy
);
formData
.
append
(
'key'
,
config
.
dir
+
fileName
+
`.
${
getFileSuffix
(
item
)}
`
);
formData
.
append
(
'OSSAccessKeyId'
,
config
.
accessid
);
formData
.
append
(
'policy'
,
config
.
policy
);
formData
.
append
(
'success_action_status'
,
'200'
);
formData
.
append
(
'OSSAccessKeyId'
,
config
.
accessid
);
formData
.
append
(
'callback'
,
config
.
callback
);
formData
.
append
(
'success_action_status'
,
'200'
);
formData
.
append
(
'signature'
,
config
.
signature
);
formData
.
append
(
'callback'
,
config
.
callback
);
formData
.
append
(
'file'
,
item
.
raw
);
formData
.
append
(
'signature'
,
config
.
signature
);
request
if
(
item
.
raw
)
{
.
post
(
url
,
formData
,
{
// 存在row
headers
:
{
formData
.
append
(
'file'
,
item
.
raw
);
'Content-Type'
:
'multipart/form-data;charset=utf-8'
,
}
else
{
// Accept: '*/*',
// 另一个格式
},
formData
.
append
(
'file'
,
item
);
})
}
.
then
((
res
:
any
)
=>
{
request
// resolve 参数为关键代码
.
post
(
url
,
formData
,
{
if
(
res
===
''
||
res
==
200
)
{
headers
:
{
// 外网url
'Content-Type'
:
'multipart/form-data;charset=utf-8'
,
const
url
=
config
.
domain
+
config
.
dir
+
fileName
+
`.
${
getFileSuffix
(
item
)}
`
;
// Accept: '*/*',
console
.
log
(
url
);
},
UploadSuccessCallback
(
fileName
,
url
);
})
resolve
({
.
then
((
res
:
any
)
=>
{
status
:
'success'
,
// resolve 参数为关键代码
response
:
{
url
:
url
},
if
(
res
===
''
||
res
==
200
)
{
// 外网url
const
url
=
config
.
domain
+
config
.
dir
+
fileName
+
`.
${
getFileSuffix
(
item
)}
`
;
UploadSuccessCallback
(
fileName
,
url
);
resolve
({
status
:
'success'
,
response
:
{
url
:
url
},
});
}
else
{
UploadErrorCallback
(
fileName
);
reject
({
status
:
'error'
,
response
:
''
,
});
}
})
.
catch
((
e
)
=>
{
console
.
log
(
e
);
reject
({
status
:
'error'
,
response
:
''
,
});
});
}
else
{
});
UploadErrorCallback
(
fileName
);
}
}
}
catch
(
e
)
{
})
console
.
log
(
e
);
.
catch
((
e
)
=>
{
reject
({
console
.
log
(
e
);
status
:
'error'
,
});
response
:
''
,
});
}
}
});
});
};
};
// 获取文件后缀
// 获取文件后缀
export
const
getFileSuffix
=
(
file
:
File
)
=>
{
export
const
getFileSuffix
=
(
file
:
any
)
=>
{
return
file
.
name
.
split
(
'.'
)[
1
];
if
(
file
.
name
&&
file
.
name
.
indexOf
(
'.'
)
!==
-
1
)
{
return
file
.
name
.
split
(
'.'
)[
1
];
}
else
{
return
file
.
type
.
split
(
'/'
)[
1
];
}
};
// 二进制文件下载
export
const
downloadBlobFile
=
(
blob
:
Blob
,
name
:
string
=
'test'
)
=>
{
// 创建下载链接
var
url
=
URL
.
createObjectURL
(
blob
);
// 创建下载链接元素
var
link
=
document
.
createElement
(
'a'
);
link
.
href
=
url
;
link
.
download
=
name
;
// 模拟点击事件下载文件
link
.
click
();
// 清理 Blob URL
URL
.
revokeObjectURL
(
url
);
};
};
src/utils/upLoadRequest.ts
0 → 100644
View file @
0d8701a5
import
axios
from
'axios'
;
import
{
MessagePlugin
}
from
'tdesign-vue-next'
;
const
instance
:
any
=
axios
.
create
({
timeout
:
60
*
60
*
1000
,
withCredentials
:
false
,
});
instance
.
all
=
axios
.
all
;
// 请求头
instance
.
interceptors
.
request
.
use
((
config
:
any
)
=>
{
return
config
;
});
instance
.
interceptors
.
response
.
use
(
(
response
)
=>
{
const
{
data
,
status
}
=
response
;
if
(
status
==
201
||
status
==
200
)
{
return
data
;
}
if
(
data
.
code
===
0
)
{
return
data
;
}
},
(
err
)
=>
{
console
.
log
(
err
);
if
(
'response'
in
err
)
{
return
err
.
response
;
}
},
);
export
default
instance
;
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