QQ扫一扫联系
需要掌握 js 开发能力
{
"name": "server-xxx", // 模型名称
"version": "0.1.0", // 模型版本
"title": "语音模型", // 模型标题
"description": "模型描述", // 模型描述
"deviceDescription":"设备描述",
"platformName": "win", // 支持系统,win, osx, linux
"platformArch": "x86", // 支持架构,x86, arm64
"serverRequire": ">=0.5.0", // 对AigcPanel版本的要求,如 >=0.5.0
"entry": "main.exe", // 入口文件
"functions": [
"videoGen", // 支持视频生成
"soundTTS", // 支持语音合成
"soundClone" // 支持语音克隆
],
"settings": [ // 模型配置项,可以显示在模型配置页面
{
"name": "port",
"type": "text",
"title": "服务端口",
"default": "",
"placeholder": "留空会检测使用随机端口"
}
]
}
const serverRuntime = {
port: 0,
}
let shellController = null
let isRunning = false
module.exports = {
ServerApi: null,
ServerInfo: null,
url() {
return `http://localhost:${serverRuntime.port}/`
},
// 模型启动
async start() {
// 发送一个启动中的消息
this.send('starting', this.ServerInfo)
// 获取一个可用端口,如果用户设置了端口,则使用用户设置的端口
if (this.ServerInfo.setting && this.ServerInfo.setting.port) {
serverRuntime.port = this.ServerInfo.setting.port
} else if (!serverRuntime.port || !await this.ServerApi.app.isPortAvailable(serverRuntime.port)) {
serverRuntime.port = await this.ServerApi.app.availablePort(50617)
}
// 模型启动命令,这里假设需要运行的命令是 python main.py
let command = []
command.push(`"${this.ServerInfo.localPath}/_aienv/python.exe"`)
command.push(`main.py`)
// 环境变量,这里需要定义一下环境变量,比如python路径,二进制文件路径等,以下环境变量是绝大多数环境需要添加的
const envMap = {}
const dep = process.platform === 'win32' ? ';' : ':'
envMap['PATH'] = process.env['PATH'] || ''
envMap['PATH'] = `${this.ServerInfo.localPath}{dep}${envMap['PATH']}`
envMap['PYTHONIOENCODING'] = 'utf-8'
// 这里开始启动命令,启动命令会返回一个控制器,可以用来停止命令
shellController = await this.ServerApi.app.spawnShell(command, {
stdout: (data) => {
this.sendLog(data)
},
stderr: (data) => {
this.sendLog(data)
},
success: (data) => {
this.send('success', this.ServerInfo)
},
error: (data, code) => {
this.sendLog(data)
this.send('error', this.ServerInfo)
},
env: envMap,
cwd: this.ServerInfo.localPath,
})
},
// 模型测试是否可用
async ping() {
try {
// 这里假设模型的ping接口是 /ping ,正确返回 ping,错误返回 false
const res = await this.ServerApi.request(`${this.url()}ping`)
return true
} catch (e) {
return false
}
},
// 模型停止
async stop() {
this.send('stopping', this.ServerInfo)
try {
shellController.stop()
shellController = null
} catch (e) {
console.log('stop error', e)
}
this.send('stopped', this.ServerInfo)
},
// 获取模型配置信息
async config() {
return {
code: 0,
msg: "ok",
data: {
// 模型的地址信息
httpUrl: shellController ? this.url() : null,
// 模型说明信息
content: '模型说明',
functions: {
// 声音合成
soundTts: {
param:[]
},
// 声音克隆
soundClone: {
param: []
},
// 视频对口型
videoGen: {
param: []
}
}
}
}
},
// 执行调用:视频对口型
async videoGen(data) {
// data = { id: '任务ID', videoFile: '视频文件路径', soundFile: '声音文件路径' }
const resultData = {
// success, querying, retry
type: 'success',
start: 0,
end: 0,
data: {
filePath: null
}
}
if (isRunning) {
resultData.type = 'retry'
return { code: 0, msg: 'ok', data: resultData }
}
isRunning = true
const param = data.param || {}
resultData.start = Date.now()
try {
this.send('taskRunning', {id: data.id})
// 模型调用请求,完成调用逻辑
// 视频文件路径 data.videoFile
// 声音文件路径 data.soundFile
resultData.data.filePath = '合成之后的本地mp4路径'
resultData.end = result.endTime
return { code: 0, msg: 'ok', data: resultData }
} catch (e) {
throw e
} finally {
isRunning = false
}
},
// 执行调用:声音合成
async soundTts(data) {
// data = { id: '任务ID', text: '合成文本' }
const resultData = {
// success, querying, retry
type: 'success',
start: 0,
end: 0,
data: {
filePath: null
}
}
if (isRunning) {
resultData.type = 'retry'
return { code: 0, msg: 'ok', data: resultData }
}
isRunning = true
const param = data.param || {}
resultData.start = Date.now()
try {
this.send('taskRunning', {id: data.id})
// 模型调用请求,完成调用逻辑
// 合成文本 data.text
resultData.data.filePath = '合成之后的本地wav路径'
resultData.end = result.endTime
return { code: 0, msg: 'ok', data: resultData }
} catch (e) {
throw e
} finally {
isRunning = false
}
},
// 执行调用:声音克隆
async soundClone(data) {
// data = { id: '任务ID', text: '合成文本', promptAudio: '参考音频路径', promptText: '参考音频文字' }
const resultData = {
// success, querying, retry
type: 'success',
start: 0,
end: 0,
data: {
filePath: null
}
}
if (isRunning) {
resultData.type = 'retry'
return { code: 0, msg: 'ok', data: resultData }
}
isRunning = true
const param = data.param || {}
resultData.start = Date.now()
try {
this.send('taskRunning', {id: data.id})
// 模型调用请求,完成调用逻辑
// 合成文本 data.text
resultData.data.filePath = '合成之后的本地wav路径'
resultData.end = result.endTime
return { code: 0, msg: 'ok', data: resultData }
} catch (e) {
throw e
} finally {
isRunning = false
}
},
}
完成两个文件的开发之后,在软件中尝试选择模型文件夹中的config.json导入。