Commit 9c638a90 by haojie

python处理音频

parent 163f7c92
<template> <template>
<div> <div>
<Dialog v-model="modelValue" @confirm="confirm"> <Dialog v-model="dialogVisible" @confirm="confirm">
<div class="custom-mizable-dialog-body"> <div class="custom-mizable-dialog-body">
<div class="title"> <div class="title">
{{ dialogInfo.title }} {{ dialogInfo.title }}
...@@ -35,13 +35,8 @@ const props = withDefaults( ...@@ -35,13 +35,8 @@ const props = withDefaults(
); );
const emit = defineEmits(['update:modelValue', 'update:value', 'confirm']); const emit = defineEmits(['update:modelValue', 'update:value', 'confirm']);
const confirmVisible = ref(false); const confirmVisible = ref(false);
const dialogVisible = ref(props.modelValue);
const inputValue = ref(props.value); const inputValue = ref(props.value);
watch(
() => props.modelValue,
(v) => {
emit('update:modelValue', v);
},
);
const confirm = () => { const confirm = () => {
if (!inputValue.value) { if (!inputValue.value) {
...@@ -70,6 +65,20 @@ watch( ...@@ -70,6 +65,20 @@ watch(
emit('update:value', v); emit('update:value', v);
}, },
); );
watch(
() => props.modelValue,
(v) => {
dialogVisible.value = v;
},
);
watch(
() => dialogVisible.value,
(v) => {
emit('update:modelValue', v);
},
);
</script> </script>
<style lang="less"> <style lang="less">
......
...@@ -131,7 +131,7 @@ export const emailReg = /^\w{3,}(\.\w+)*@[A-z0-9]+(\.[A-z]{2,8}){1,2}$/; ...@@ -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 createLiveRouteKey = 'create_live_route_key';
// 音频上传格式限制 // 音频上传格式限制
export const audioAccept = 'wav'; export const audioAccept = 'wav,mpeg,mp3';
// 音频切割间隔时长 // 音频切割间隔时长
export const audioSplitDuration = 300; export const audioSplitDuration = 300;
...@@ -76,17 +76,26 @@ import { computed, onBeforeMount, ref, onBeforeUnmount, onActivated } from 'vue' ...@@ -76,17 +76,26 @@ import { computed, onBeforeMount, ref, onBeforeUnmount, onActivated } from 'vue'
import { getElBounding, show_message, DataType, dimensionalConvert, ecursionDeepCopy, getFile } from '@/utils/tool'; import { getElBounding, show_message, DataType, dimensionalConvert, ecursionDeepCopy, getFile } from '@/utils/tool';
import { getDurationOfAudioFile } from '@/utils/audio'; import { getDurationOfAudioFile } from '@/utils/audio';
import { useStore } from 'vuex'; 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 { getLiveTaskInfo, createDrafts, getDraftsDetail, liveTts, createLiveTask } from '@/utils/api/userApi';
import { useRoute, onBeforeRouteLeave } from 'vue-router'; import { useRoute, onBeforeRouteLeave } from 'vue-router';
import routerConfig from '@/router/tool'; import routerConfig from '@/router/tool';
import { onUpdateLiveTask } from '@/service/Common'; import { onUpdateLiveTask } from '@/service/Common';
import { callPyjsInWindow, writeLog } from '@/utils/pyqt'; import { callPyjsInWindow, writeLog, injectWindow } from '@/utils/pyqt';
import { useLiveInfoSubmit } from '@/hooks/useStoreCommit'; import { useLiveInfoSubmit } from '@/hooks/useStoreCommit';
import { processTextCallback } from '@/hooks/useScript'; import { processTextCallback } from '@/hooks/useScript';
import CustomException from '@/utils/error'; import CustomException from '@/utils/error';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
import { splitAudio } from '@/utils/audio'; import { splitAudio } from '@/utils/audio';
import { audioScriptVersion } from '@/service/CreateLive';
import { audioSplitDuration } from '@/constants/token';
const { const {
loading, loading,
initNum, initNum,
...@@ -120,6 +129,9 @@ const toolHeight = ref(0); ...@@ -120,6 +129,9 @@ const toolHeight = ref(0);
const videoPlay = ref<HTMLVideoElement>(); const videoPlay = ref<HTMLVideoElement>();
// 统计本次音频切割任务总数
const audioSplitTaskTotal = ref(0);
const videoCanplay = () => { const videoCanplay = () => {
videoPlay.value.play(); videoPlay.value.play();
}; };
...@@ -371,23 +383,34 @@ const onSaveDrafts = async () => { ...@@ -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 () => { const editAudioSave = async () => {
try { try {
loading.value = true; loading.value = true;
await audioSplit(); if (audioScriptVersion == 'v1') {
let params = filterFiled(getCreateLiveInfo()); await audioSplit();
let res: any = await onUpdateLiveTask(route.query.id, params); await audioScriptEditSubmit();
if (res) { } else {
if (route.query.type === 'edit') { // v2
// 通知python删除对应的output.mp4 audioSplitV2('update');
callPyjsInWindow('deleteOutputVideo', {
id: route.query.id,
});
}
submitSuccessed('');
} }
loading.value = false;
} catch (e) { } catch (e) {
writeLog({ writeLog({
name: 'createLive editAudioSave error', name: 'createLive editAudioSave error',
...@@ -449,7 +472,7 @@ const onEditSave = async () => { ...@@ -449,7 +472,7 @@ const onEditSave = async () => {
} }
}; };
// 音频切割 // 音频切割v1
const audioSplit = async () => { const audioSplit = async () => {
for (let i = 0; i < createLiveInfo.value[createLiveKeys.audioScriptList].length; i++) { for (let i = 0; i < createLiveInfo.value[createLiveKeys.audioScriptList].length; i++) {
let item = createLiveInfo.value[createLiveKeys.audioScriptList][i]; let item = createLiveInfo.value[createLiveKeys.audioScriptList][i];
...@@ -500,24 +523,126 @@ const audioSplit = async () => { ...@@ -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 () => { const audioSubmit = async () => {
// 切割
try { try {
loading.value = true; loading.value = true;
await audioSplit(); if (audioScriptVersion == 'v1') {
let type = ''; await audioSplit();
if (route.query.type == 'edit_drafts') { await audioScriptLiveTaskSubmit();
type = 'edit_drafts'; } else {
} // v2版本,提交到python处理
let params = filterFiled(getCreateLiveInfo(), type); audioSplitV2('create');
let res: any = await createLiveTask(params);
if (res.code == 0) {
console.log('创建成功-', res.data.id);
live_task_id.value = res.data.id;
submitSuccessed();
} }
loading.value = false;
} catch (e) { } catch (e) {
writeLog({ writeLog({
name: 'createLive audioSubmit error', name: 'createLive audioSubmit error',
...@@ -595,20 +720,8 @@ onBeforeMount(() => { ...@@ -595,20 +720,8 @@ onBeforeMount(() => {
// 缓存进入 // 缓存进入
onActivated(() => { onActivated(() => {
enterPageEvent(); enterPageEvent();
// 测试 // 注入切割回调
// let list = [ injectWindow('splitAudioCallback', splitCallback);
// // 小文件
// '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',
// ]);
}); });
// 路由离开前保存query // 路由离开前保存query
......
...@@ -197,6 +197,7 @@ const getList = async () => { ...@@ -197,6 +197,7 @@ const getList = async () => {
digitalPeopleList.loading = false; digitalPeopleList.loading = false;
} }
}; };
const startTest = async () => { const startTest = async () => {
// let list = [ // let list = [
// // 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/1/2023-08-114e482462-6047-47be-a30c-b85a17c95665.mp3', // // '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 () => { ...@@ -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',
// '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 = [ // let list = [
'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/1/2023-08-11dd2372d8-73ff-4526-bf59-b1618a3f218f.mp3', // 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/1/2023-08-11dd2372d8-73ff-4526-bf59-b1618a3f218f.mp3',
]; // ];
// 注入一个接收方法 // injectWindow('splitAudioCallback', splitCallback);
const splitCallback = (url: string[]) => { // // 传给python
console.log(url, '切割后的音频列表'); // callPyjsInWindow('splitAudio', {
}; // url: list[0],
injectWindow('splitAudioCallback', splitCallback); // duration: audioSplitDuration,
// 传给python // id: 1,
console.log('通知切割'); // });
callPyjsInWindow('splitAudio', {
url: list[0],
duration: audioSplitDuration,
id: 1,
});
}; };
onMounted(() => { onMounted(() => {
// 发送token,即使重新登录也会回到首页再次发送
callPyjsInWindow('setToken', userToken.value);
// 获取我的数字人 // 获取我的数字人
getList(); getList();
startTest(); startTest();
// 发送token,即使重新登录也会回到首页再次发送
callPyjsInWindow('setToken', userToken.value);
}); });
</script> </script>
......
...@@ -14,6 +14,9 @@ import { v4 } from 'uuid'; ...@@ -14,6 +14,9 @@ import { v4 } from 'uuid';
import { writeLog } from '@/utils/pyqt'; import { writeLog } from '@/utils/pyqt';
import { audioSplitDuration } from '@/constants/token'; import { audioSplitDuration } from '@/constants/token';
// 音频类型校验
export const audioTypeCheck = () => {};
// 阿里云上传配置 // 阿里云上传配置
export const getUploadConfig = async () => { export const getUploadConfig = async () => {
try { try {
......
...@@ -13,6 +13,9 @@ import { getDurationOfAudioFile } from '@/utils/audio'; ...@@ -13,6 +13,9 @@ import { getDurationOfAudioFile } from '@/utils/audio';
*/ */
export const createLiveVersion = 'v2'; export const createLiveVersion = 'v2';
// 音频脚本提交的版本
export const audioScriptVersion = 'v2';
// 创建直播时提交的变量名 // 创建直播时提交的变量名
export const createLiveKeys = { export const createLiveKeys = {
id_type: 'id_type', // 数字人库类型(数字人库和我的数字人) id_type: 'id_type', // 数字人库类型(数字人库和我的数字人)
...@@ -163,6 +166,17 @@ export const submitAudioTask = async (list: any[], item: any, uuid: string) => { ...@@ -163,6 +166,17 @@ export const submitAudioTask = async (list: any[], item: any, uuid: string) => {
// openInterval(true, '', true, currentConfuseId.value, false, list.length); // 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 = '') => { export const filterFiled = (item: any, type: string = '') => {
// 过滤必须字段 // 过滤必须字段
......
...@@ -317,6 +317,7 @@ export const getFile = (url: string) => { ...@@ -317,6 +317,7 @@ export const getFile = (url: string) => {
resolve(res); resolve(res);
}) })
.catch((error) => { .catch((error) => {
console.log(error, '下载文件失败');
reject(error); reject(error);
}); });
}); });
......
...@@ -22,20 +22,21 @@ instance.interceptors.response.use( ...@@ -22,20 +22,21 @@ instance.interceptors.response.use(
// 状态不对的 // 状态不对的
writeLog({ writeLog({
name: 'upLoad request status error', name: 'upLoad request status error-1',
value: response, value: response,
}); });
}, },
(err) => { (err) => {
console.log(err);
if ('response' in err) { if ('response' in err) {
writeLog({ writeLog({
name: 'upLoad request status error', name: 'upLoad request status error-2',
value: err.response, value: err.response,
}); });
return err.response; return err.response;
} else { } else {
writeLog({ writeLog({
name: 'upLoad request status error', name: 'upLoad request status error-3',
value: err, 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