-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Expand file tree
/
Copy pathmodel.js
More file actions
130 lines (117 loc) · 4.01 KB
/
Copy pathmodel.js
File metadata and controls
130 lines (117 loc) · 4.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import { ipcMain } from 'electron'
import fs from 'fs'
import path from 'path'
import dayjs from 'dayjs'
import { isEmpty } from 'lodash'
import { insert, selectPage, count, selectByID, remove as deleteModel } from '../dao/f2f-model.js'
import { train as trainVoice } from './voice.js'
import { assetPath } from '../config/config.js'
import log from '../logger.js'
import { extractAudio, toH264 } from '../util/ffmpeg.js'
const MODEL_NAME = 'model'
/**
* 新增模特
* @param {string} modelName 模特名称
* @param {string} videoPath 模特视频路径
* @returns
*/
async function addModel(modelName, filePath, isImage = false) {
if (!fs.existsSync(assetPath.model)) {
fs.mkdirSync(assetPath.model, {
recursive: true
})
}
if (isImage) {
const extname = path.extname(filePath)
const modelFileName = dayjs().format('YYYYMMDDHHmmssSSS') + extname
const modelPath = path.join(assetPath.model, modelFileName)
fs.copyFileSync(filePath, modelPath)
const relativeModelPath = path.relative(assetPath.model, modelPath)
const id = insert({ modelName, coverPath: relativeModelPath, isImage: 1 })
return id
} else {
// copy video to model video path
const extname = path.extname(filePath)
const modelFileName = dayjs().format('YYYYMMDDHHmmssSSS') + extname
const modelPath = path.join(assetPath.model, modelFileName)
await toH264(filePath, modelPath)
// 用ffmpeg分离音频
if (!fs.existsSync(assetPath.ttsTrain)) {
fs.mkdirSync(assetPath.ttsTrain, {
recursive: true
})
}
const audioPath = path.join(assetPath.ttsTrain, modelFileName.replace(extname, '.wav'))
return extractAudio(modelPath, audioPath).then(() => {
// 训练语音模型
const relativeAudioPath = path.relative(assetPath.ttsRoot, audioPath)
if (process.env.NODE_ENV === 'development') {
// TODO 写死调试
return trainVoice('origin_audio/test.wav', 'zh')
} else {
return trainVoice(relativeAudioPath, 'zh')
}
}).then((voiceId)=>{
// 插入模特信息
const relativeModelPath = path.relative(assetPath.model, modelPath)
const relativeAudioPath = path.relative(assetPath.ttsRoot, audioPath)
// insert model info to db
const id = insert({ modelName, videoPath: relativeModelPath, audioPath: relativeAudioPath, voiceId, isImage: 0 })
return id
})
}
}
function page({ page, pageSize, name = '' }) {
const total = count(name)
return {
total,
list: selectPage({ page, pageSize, name }).map((model) => ({
...model,
video_path: path.join(assetPath.model, model.video_path),
audio_path: path.join(assetPath.ttsRoot, model.audio_path)
}))
}
}
function findModel(modelId) {
const model = selectByID(modelId)
return {
...model,
video_path: path.join(assetPath.model, model.video_path),
audio_path: path.join(assetPath.ttsRoot, model.audio_path)
}
}
function removeModel(modelId) {
const model = selectByID(modelId)
log.debug('~ removeModel ~ modelId:', modelId)
// 删除视频
const videoPath = path.join(assetPath.model, model.video_path ||'')
if (!isEmpty(model.video_path) && fs.existsSync(videoPath)) {
fs.unlinkSync(videoPath)
}
// 删除音频
const audioPath = path.join(assetPath.ttsRoot, model.audio_path ||'')
if (!isEmpty(model.audio_path) && fs.existsSync(audioPath)) {
fs.unlinkSync(audioPath)
}
deleteModel(modelId)
}
function countModel(name = '') {
return count(name)
}
export function init() {
ipcMain.handle(MODEL_NAME + '/addModel', (event, modelName, filePath, isImage) => {
return addModel(modelName, filePath, isImage)
})
ipcMain.handle(MODEL_NAME + '/page', (event, ...args) => {
return page(...args)
})
ipcMain.handle(MODEL_NAME + '/find', (event, ...args) => {
return findModel(...args)
})
ipcMain.handle(MODEL_NAME + '/count', (event, ...args) => {
return countModel(...args)
})
ipcMain.handle(MODEL_NAME + '/remove', (event, ...args) => {
return removeModel(...args)
})
}