Commit 9c638a90 by haojie

python处理音频

parent 163f7c92
<template>
<div>
<Dialog v-model="modelValue" @confirm="confirm">
<Dialog v-model="dialogVisible" @confirm="confirm">
<div class="custom-mizable-dialog-body">
<div class="title">
{{ dialogInfo.title }}
......@@ -35,13 +35,8 @@ const props = withDefaults(
);
const emit = defineEmits(['update:modelValue', 'update:value', 'confirm']);
const confirmVisible = ref(false);
const dialogVisible = ref(props.modelValue);
const inputValue = ref(props.value);
watch(
() => props.modelValue,
(v) => {
emit('update:modelValue', v);
},
);
const confirm = () => {
if (!inputValue.value) {
......@@ -70,6 +65,20 @@ watch(
emit('update:value', v);
},
);
watch(
() => props.modelValue,
(v) => {
dialogVisible.value = v;
},
);
watch(
() => dialogVisible.value,
(v) => {
emit('update:modelValue', v);
},
);
</script>
<style lang="less">
......
......@@ -131,7 +131,7 @@ export const emailReg = /^\w{3,}(\.\w+)*@[A-z0-9]+(\.[A-z]{2,8}){1,2}$/;
export const createLiveRouteKey = 'create_live_route_key';
// 音频上传格式限制
export const audioAccept = 'wav';
export const audioAccept = 'wav,mpeg,mp3';
// 音频切割间隔时长
export const audioSplitDuration = 300;
......@@ -76,17 +76,26 @@ import { computed, onBeforeMount, ref, onBeforeUnmount, onActivated } from 'vue'
import { getElBounding, show_message, DataType, dimensionalConvert, ecursionDeepCopy, getFile } from '@/utils/tool';
import { getDurationOfAudioFile } from '@/utils/audio';
import { useStore } from 'vuex';
import { createLiveKeys, scriptTypeText, scriptTypePhonetics, mergeSameAudio, filterFiled } from '@/service/CreateLive';
import {
createLiveKeys,
scriptTypeText,
scriptTypePhonetics,
mergeSameAudio,
filterFiled,
getAudioUrl,
} from '@/service/CreateLive';
import { getLiveTaskInfo, createDrafts, getDraftsDetail, liveTts, createLiveTask } from '@/utils/api/userApi';
import { useRoute, onBeforeRouteLeave } from 'vue-router';
import routerConfig from '@/router/tool';
import { onUpdateLiveTask } from '@/service/Common';
import { callPyjsInWindow, writeLog } from '@/utils/pyqt';
import { callPyjsInWindow, writeLog, injectWindow } from '@/utils/pyqt';
import { useLiveInfoSubmit } from '@/hooks/useStoreCommit';
import { processTextCallback } from '@/hooks/useScript';
import CustomException from '@/utils/error';
import { v4 } from 'uuid';
import { splitAudio } from '@/utils/audio';
import { audioScriptVersion } from '@/service/CreateLive';
import { audioSplitDuration } from '@/constants/token';
const {
loading,
initNum,
......@@ -120,6 +129,9 @@ const toolHeight = ref(0);
const videoPlay = ref<HTMLVideoElement>();
// 统计本次音频切割任务总数
const audioSplitTaskTotal = ref(0);
const videoCanplay = () => {
videoPlay.value.play();
};
......@@ -371,23 +383,34 @@ const onSaveDrafts = async () => {
}
};
// 编辑页面音频脚本更新
const audioScriptEditSubmit = async () => {
let params = filterFiled(getCreateLiveInfo());
let res: any = await onUpdateLiveTask(route.query.id, params);
console.log('编辑提交的参数', params);
if (res) {
if (route.query.type === 'edit') {
// 通知python删除对应的output.mp4
callPyjsInWindow('deleteOutputVideo', {
id: route.query.id,
});
}
submitSuccessed('');
loading.value = false;
}
};
// 编辑时音频提交
const editAudioSave = async () => {
try {
loading.value = true;
await audioSplit();
let params = filterFiled(getCreateLiveInfo());
let res: any = await onUpdateLiveTask(route.query.id, params);
if (res) {
if (route.query.type === 'edit') {
// 通知python删除对应的output.mp4
callPyjsInWindow('deleteOutputVideo', {
id: route.query.id,
});
}
submitSuccessed('');
if (audioScriptVersion == 'v1') {
await audioSplit();
await audioScriptEditSubmit();
} else {
// v2
audioSplitV2('update');
}
loading.value = false;
} catch (e) {
writeLog({
name: 'createLive editAudioSave error',
......@@ -449,7 +472,7 @@ const onEditSave = async () => {
}
};
// 音频切割
// 音频切割v1
const audioSplit = async () => {
for (let i = 0; i < createLiveInfo.value[createLiveKeys.audioScriptList].length; i++) {
let item = createLiveInfo.value[createLiveKeys.audioScriptList][i];
......@@ -500,24 +523,126 @@ const audioSplit = async () => {
}
};
// python切割回调
const splitCallback = (splitInfo: any) => {
console.log(splitInfo);
let num = 0;
if ('url' in splitInfo && 'list' in splitInfo) {
let audioScriptList = createLiveInfo.value[createLiveKeys.audioScriptList];
// 根据切割前的链接匹配更新
for (let i = 0; i < audioScriptList.length; i++) {
let item = audioScriptList[i];
for (let j = 0; j < item.data.length; j++) {
let row = item.data[j];
if (getAudioUrl(row) == splitInfo.url) {
row.new_content = splitInfo.list.join('|');
row.py_split_status = true;
}
// 统计完成数量
if (row.py_remove && row.py_split_status && row.new_content) {
num += 1;
}
}
}
if (audioSplitTaskTotal.value === num) {
// 执行完毕,可以提交
if (splitInfo.type == 'create') {
// 创建
audioScriptLiveTaskSubmit();
} else {
// 更新
audioScriptEditSubmit();
}
}
} else {
//
console.log('切割回调错误');
writeLog({
name: 'python split callback error',
value: splitInfo,
});
}
};
// 音频切割v2
const audioSplitV2 = async (type: string) => {
// 清空总次数
audioSplitTaskTotal.value = 0;
for (let i = 0; i < createLiveInfo.value[createLiveKeys.audioScriptList].length; i++) {
let item = createLiveInfo.value[createLiveKeys.audioScriptList][i];
for (let j = 0; j < item.data.length; j++) {
let row = item.data[j];
if (row.children && row.children.length > 1) {
// 编辑时没有修改参数
continue;
}
if (
row.duration &&
row.duration > audioSplitNum &&
row.content &&
row.content.indexOf('|') == -1 &&
row.old_content &&
!row.file?.raw
) {
console.log('大于5分钟,开始下载文件');
// 没有文件时,下载
let file = await getFile(row.old_content);
row.file = {};
row.file.raw = file;
console.log(row.file);
}
if (row.file && row.file.raw) {
// 文件时长
let fileDuration = await getDurationOfAudioFile(row.file.raw);
console.log(fileDuration, '文件时长');
if (fileDuration > audioSplitNum) {
// 通知python切割
callPyjsInWindow('splitAudio', {
url: getAudioUrl(row),
duration: audioSplitDuration,
id: route.query.id,
type: type,
});
// 更新状态
row.py_remove = true;
row.py_split_status = false;
// 统计总次数
audioSplitTaskTotal.value += 1;
}
}
}
}
};
// 音频脚本直播创建
const audioScriptLiveTaskSubmit = async () => {
let type = '';
if (route.query.type == 'edit_drafts') {
type = 'edit_drafts';
}
let params = filterFiled(getCreateLiveInfo(), type);
console.log('创建提交的参数', params);
let res: any = await createLiveTask(params);
if (res.code == 0) {
console.log('创建成功-', res.data.id);
live_task_id.value = res.data.id;
submitSuccessed();
}
// v2提交后关闭loading
loading.value = false;
};
// 音频提交
const audioSubmit = async () => {
// 切割
try {
loading.value = true;
await audioSplit();
let type = '';
if (route.query.type == 'edit_drafts') {
type = 'edit_drafts';
}
let params = filterFiled(getCreateLiveInfo(), type);
let res: any = await createLiveTask(params);
if (res.code == 0) {
console.log('创建成功-', res.data.id);
live_task_id.value = res.data.id;
submitSuccessed();
if (audioScriptVersion == 'v1') {
await audioSplit();
await audioScriptLiveTaskSubmit();
} else {
// v2版本,提交到python处理
audioSplitV2('create');
}
loading.value = false;
} catch (e) {
writeLog({
name: 'createLive audioSubmit error',
......@@ -595,20 +720,8 @@ onBeforeMount(() => {
// 缓存进入
onActivated(() => {
enterPageEvent();
// 测试
// let list = [
// // 小文件
// 'http://nls-cloud-cn-shanghai.oss-cn-shanghai.aliyuncs.com/jupiter-flow/tmp/e56d8750eb3a44f9930f73703489acb1.wav?Expires=1692087730&OSSAccessKeyId=LTAIUpwNp2H7pBG5&Signature=FtKSld5Dn55po9GyTm%2BefRKmPqw%3D',
// 'http://nls-cloud-cn-shanghai.oss-cn-shanghai.aliyuncs.com/jupiter-flow/tmp/e56d8750eb3a44f9930f73703489acb1.wav?Expires=1692087730&OSSAccessKeyId=LTAIUpwNp2H7pBG5&Signature=FtKSld5Dn55po9GyTm%2BefRKmPqw%3D',
// 'http://nls-cloud-cn-shanghai.oss-cn-shanghai.aliyuncs.com/jupiter-flow/tmp/e56d8750eb3a44f9930f73703489acb1.wav?Expires=1692087730&OSSAccessKeyId=LTAIUpwNp2H7pBG5&Signature=FtKSld5Dn55po9GyTm%2BefRKmPqw%3D',
// 'http://nls-cloud-cn-shanghai.oss-cn-shanghai.aliyuncs.com/jupiter-flow/tmp/e56d8750eb3a44f9930f73703489acb1.wav?Expires=1692087730&OSSAccessKeyId=LTAIUpwNp2H7pBG5&Signature=FtKSld5Dn55po9GyTm%2BefRKmPqw%3D',
// // 大文件
// // 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/15/2023-08-072cfde637-5487-47fc-9cea-3e984b92ee6f.wav',
// ];
// audioStart([
// 'http://nls-cloud-cn-shanghai.oss-cn-shanghai.aliyuncs.com/jupiter-flow/tmp/ad08fa0a70ae4ea88d11ad5e394ce045.wav?Expires=1692149777&OSSAccessKeyId=LTAIUpwNp2H7pBG5&Signature=D93qMT1DovslSOVa9oufV2cGZxE%3D',
// ]);
// 注入切割回调
injectWindow('splitAudioCallback', splitCallback);
});
// 路由离开前保存query
......
......@@ -197,6 +197,7 @@ const getList = async () => {
digitalPeopleList.loading = false;
}
};
const startTest = async () => {
// let list = [
// // 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/1/2023-08-114e482462-6047-47be-a30c-b85a17c95665.mp3',
......@@ -205,29 +206,24 @@ const startTest = async () => {
// 'http://nls-cloud-cn-shanghai.oss-cn-shanghai.aliyuncs.com/jupiter-flow/tmp/ad08fa0a70ae4ea88d11ad5e394ce045.wav?Expires=1692149777&OSSAccessKeyId=LTAIUpwNp2H7pBG5&Signature=D93qMT1DovslSOVa9oufV2cGZxE%3D',
// 'http://nls-cloud-cn-shanghai.oss-cn-shanghai.aliyuncs.com/jupiter-flow/tmp/ad08fa0a70ae4ea88d11ad5e394ce045.wav?Expires=1692149777&OSSAccessKeyId=LTAIUpwNp2H7pBG5&Signature=D93qMT1DovslSOVa9oufV2cGZxE%3D',
// ];
let list = [
'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/1/2023-08-11dd2372d8-73ff-4526-bf59-b1618a3f218f.mp3',
];
// 注入一个接收方法
const splitCallback = (url: string[]) => {
console.log(url, '切割后的音频列表');
};
injectWindow('splitAudioCallback', splitCallback);
// 传给python
console.log('通知切割');
callPyjsInWindow('splitAudio', {
url: list[0],
duration: audioSplitDuration,
id: 1,
});
// let list = [
// 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/1/2023-08-11dd2372d8-73ff-4526-bf59-b1618a3f218f.mp3',
// ];
// injectWindow('splitAudioCallback', splitCallback);
// // 传给python
// callPyjsInWindow('splitAudio', {
// url: list[0],
// duration: audioSplitDuration,
// id: 1,
// });
};
onMounted(() => {
// 发送token,即使重新登录也会回到首页再次发送
callPyjsInWindow('setToken', userToken.value);
// 获取我的数字人
getList();
startTest();
// 发送token,即使重新登录也会回到首页再次发送
callPyjsInWindow('setToken', userToken.value);
});
</script>
......
......@@ -14,6 +14,9 @@ import { v4 } from 'uuid';
import { writeLog } from '@/utils/pyqt';
import { audioSplitDuration } from '@/constants/token';
// 音频类型校验
export const audioTypeCheck = () => {};
// 阿里云上传配置
export const getUploadConfig = async () => {
try {
......
......@@ -13,6 +13,9 @@ import { getDurationOfAudioFile } from '@/utils/audio';
*/
export const createLiveVersion = 'v2';
// 音频脚本提交的版本
export const audioScriptVersion = 'v2';
// 创建直播时提交的变量名
export const createLiveKeys = {
id_type: 'id_type', // 数字人库类型(数字人库和我的数字人)
......@@ -163,6 +166,17 @@ export const submitAudioTask = async (list: any[], item: any, uuid: string) => {
// openInterval(true, '', true, currentConfuseId.value, false, list.length);
};
// 提交时获取音频链接
export const getAudioUrl = (item: any) => {
if (DataType(item, 'string')) {
return item;
} else if (item.url) {
return item.url;
} else if (item.audio_url) {
return item.url;
}
};
// 过滤必要的字段
export const filterFiled = (item: any, type: string = '') => {
// 过滤必须字段
......
......@@ -317,6 +317,7 @@ export const getFile = (url: string) => {
resolve(res);
})
.catch((error) => {
console.log(error, '下载文件失败');
reject(error);
});
});
......
......@@ -22,20 +22,21 @@ instance.interceptors.response.use(
// 状态不对的
writeLog({
name: 'upLoad request status error',
name: 'upLoad request status error-1',
value: response,
});
},
(err) => {
console.log(err);
if ('response' in err) {
writeLog({
name: 'upLoad request status error',
name: 'upLoad request status error-2',
value: err.response,
});
return err.response;
} else {
writeLog({
name: 'upLoad request status error',
name: 'upLoad request status error-3',
value: err,
});
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment