lq1405 f17de033e1 V 3.2.2
1. 文案处理后端服务迁移(此版本之前的后端服务持续到12月1日)
2. 新增默认动图方式
3. (聚合推文)实现原创分类的图生视频(runway,luma,可灵)
4. 修复软件内配音
5. 删除旧的原创生图(原创,SD反推,MJ反推等操作在聚合推文中)
6. 导出剪映适配(视频)
7. 新增四个单句推理模式
2024-11-19 20:28:31 +08:00

201 lines
7.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { TaskModal } from "@/model/task";
import { BookServiceBasic } from "../ServiceBasic/bookServiceBasic";
import { ValidateJson } from "@/define/Tools/validate";
import { BookTaskDetail } from "@/model/book/bookTaskDetail";
import { GetImageBase64 } from "@/define/Tools/image";
import { cloneDeep, isEmpty } from "lodash";
import { GetBaseUrl } from "@/define/Tools/common";
import axios from "axios";
import { Book } from "@/model/book/book";
import { c } from "naive-ui";
import { VideoStatus } from "@/define/enum/video";
import { SendMessageToRenderer } from "../globalService";
import { ResponseMessageType } from "@/define/enum/softwareEnum";
import { BookBackTaskStatus, BookTaskStatus } from "@/define/enum/bookEnum";
export class KlingService {
bookServiceBasic: BookServiceBasic
constructor() {
this.bookServiceBasic = new BookServiceBasic();
}
/**
* 可灵图转视频
* @param task 任务
* @param gptUrl GPT地址
* @param gptApiKey GPTAPIKey
*/
async KlingImageToVideo(task: TaskModal.Task, gptUrl: string, gptApiKey: string): Promise<void> {
try {
let bookTaskDetail = await this.bookServiceBasic.GetBookTaskDetailDataById(task.bookTaskDetailId);
let klingOptionsString = bookTaskDetail.videoMessage.klingOptions;
if (!ValidateJson(klingOptionsString)) {
throw new Error("klingOptions参数错误请检查");
}
let klingOptions: BookTaskDetail.klingOptions = JSON.parse(klingOptionsString);
// console.log("klingOptions", klingOptions, "gptUrl", gptUrl, "gptApiKey", gptApiKey);
let data: BookTaskDetail.klingOptions = {
image: klingOptions.image,
model: "kling-v1"
}
if (!data.image.startsWith("http")) {
data.image = await GetImageBase64(data.image);
}
// 尾帧控制
if (klingOptions.hasOwnProperty("style") && !isEmpty(klingOptions.image_tail)) {
if (klingOptions.image_tail.startsWith("http")) {
data.image_tail = klingOptions.image_tail;
} else {
data.image_tail = await GetImageBase64(klingOptions.image_tail);
}
}
if (klingOptions.hasOwnProperty("prompt") && !isEmpty(klingOptions.prompt)) {
data.prompt = klingOptions.prompt;
}
if (klingOptions.hasOwnProperty("negative_prompt") && !isEmpty(klingOptions.negative_prompt)) {
data.negative_prompt = klingOptions.negative_prompt;
}
if (klingOptions.hasOwnProperty("cfg_scale")) {
data.cfg_scale = klingOptions.cfg_scale;
}
if (klingOptions.hasOwnProperty("mode")) {
data.mode = klingOptions.mode;
}
if (klingOptions.hasOwnProperty("duration")) {
data.duration = klingOptions.duration;
}
if (klingOptions.hasOwnProperty("callback_url")) {
data.callback_url = klingOptions.callback_url;
}
// 开始请求
let baseUrl = GetBaseUrl(gptUrl);
let url = baseUrl + "/kling/v1/videos/image2video";
let res = await axios.post(url, data, {
headers: {
"Authorization": gptApiKey
}
});
// console.log("kling合成视频结果", res);
let resData = res.data;
let id = resData.data.task_id;
// 修改数据
let videoMessage = cloneDeep(bookTaskDetail.videoMessage);
videoMessage.taskId = id;
videoMessage.status = VideoStatus.WAIT;
videoMessage.messageData = JSON.stringify(resData);
delete videoMessage.id;
await this.bookServiceBasic.UpdateBookTaskDetailVideoMessage(task.bookTaskDetailId, videoMessage);
// 返回前端数据
SendMessageToRenderer({
code: 1,
id: task.bookTaskDetailId,
message: "可灵合成任务提交成功",
type: ResponseMessageType.KLING_VIDEO,
data: JSON.stringify(resData)
}, task.messageName);
await this.FetchKlingVideoResult(bookTaskDetail, task, resData.data.task_id, baseUrl, gptApiKey);
} catch (error) {
throw new Error("可灵合成视频失败,失败信息如下:" + error.toString());
}
}
async FetchKlingVideoResult(bookTaskDetail: Book.SelectBookTaskDetail, task: TaskModal.Task, taskId: string, baseUrl: string, gptApiKey: string) {
while (true) {
try {
let url = baseUrl + "/kling/v1/videos/image2video/" + taskId;
let res = await axios.get(url, {
headers: {
Authorization: gptApiKey
}
});
// console.log("kling合成视频结果", res.data);
let data = res.data.data;
if (data.task_status == "submitted") {
SendMessageToRenderer({
code: 1,
id: bookTaskDetail.id,
message: "可灵合成任务提交成功,正在合成中",
type: ResponseMessageType.KLING_VIDEO,
data: JSON.stringify(data)
}, task.messageName);
} else if (data.task_status == "processing") {
let videoMessage = cloneDeep(bookTaskDetail.videoMessage);
delete videoMessage.id;
videoMessage.status = VideoStatus.PROCESSING;
videoMessage.taskId = taskId;
videoMessage.messageData = JSON.stringify(data);
await this.bookServiceBasic.UpdateBookTaskDetailVideoMessage(task.bookTaskDetailId, videoMessage);
SendMessageToRenderer({
code: 1,
id: bookTaskDetail.id,
message: "可灵合成任务正在合成中",
type: ResponseMessageType.KLING_VIDEO,
data: JSON.stringify(data)
}, task.messageName);
} else if (data.task_status == "succeed") {
// 完成
let videoMessage = cloneDeep(bookTaskDetail.videoMessage);
delete videoMessage.id;
videoMessage.status = VideoStatus.SUCCESS;
videoMessage.taskId = taskId;
videoMessage.videoUrl = data.task_result.videos[0].url;
videoMessage.messageData = JSON.stringify(data);
await this.bookServiceBasic.UpdateBookTaskDetailVideoMessage(task.bookTaskDetailId, videoMessage);
await this.bookServiceBasic.UpdetedBookTaskData(task.bookTaskId, {
status: BookTaskStatus.IMAGE_TO_VIDEO_SUCCESS,
})
await this.bookServiceBasic.UpdateTaskStatus({
id: task.id,
status: BookBackTaskStatus.DONE,
})
SendMessageToRenderer({
code: 1,
id: bookTaskDetail.id,
message: "可灵合成视频完成",
type: ResponseMessageType.KLING_VIDEO,
data: JSON.stringify(data.data)
}, task.messageName);
break;
} else {
// 失败
let videoMessage = cloneDeep(bookTaskDetail.videoMessage);
delete videoMessage.id;
videoMessage.status = VideoStatus.FAIL;
videoMessage.msg = res.data.message;
videoMessage.taskId = taskId;
videoMessage.messageData = JSON.stringify(data);
await this.bookServiceBasic.UpdateBookTaskDetailVideoMessage(bookTaskDetail.id, videoMessage);
SendMessageToRenderer({
code: 0,
id: bookTaskDetail.id,
message: "runway合成视频失败错误信息如下" + res.data.message,
type: ResponseMessageType.KLING_VIDEO,
data: JSON.stringify(data)
}, task.messageName);
throw new Error("可灵合成视频失败,失败信息如下:" + res.data.message);
}
// 等待20秒后再次请求
await new Promise(resolve => setTimeout(resolve, 20000));
} catch (error) {
throw error;
}
}
}
}