LaiTool/src/main/Service/Book/bookVideo.ts
lq1405 f4d042f699 V 3.1.7
1. 移除软件包自带的本地 whisper(需单独安装)
2. 重构版本底层依赖,移除外部依赖
3. 修复 首页 暗黑模式不兼容的问题
4. 修复 SD 合并提示词报错
2024-10-20 23:19:22 +08:00

243 lines
8.8 KiB
TypeScript

import { OperateBookType } from "../../../define/enum/bookEnum";
import { Book } from "../../../model/book";
import { errorMessage, successMessage } from "../../Public/generalTools";
import { BookService } from "../../../define/db/service/Book/bookService";
import { BookTaskService } from "../../../define/db/service/Book/bookTaskService";
import { GeneralResponse } from "../../../model/generalResponse";
import { Setting } from '../../../main/setting/setting'
import path from 'path'
import { CheckFolderExistsOrCreate } from "../../../define/Tools/file";
import { BookTaskDetailService } from "../../../define/db/service/Book/bookTaskDetailService";
import fs from 'fs'
import { ClipDraft } from '../../Public/clipDraft'
import { BookServiceBasic } from "../ServiceBasic/bookServiceBasic";
export class BookVideo {
bookService: BookService
bookTaskService: BookTaskService
setting: Setting
bookTaskDetailService: BookTaskDetailService
bookServiceBasic: BookServiceBasic
constructor() {
this.setting = new Setting(global)
this.bookServiceBasic = new BookServiceBasic()
}
async InitService() {
if (!this.bookService) {
this.bookService = await BookService.getInstance()
}
if (!this.bookTaskService) {
this.bookTaskService = await BookTaskService.getInstance()
}
if (!this.bookTaskDetailService) {
this.bookTaskDetailService = await BookTaskDetailService.getInstance()
}
}
/**
* 将小说中的生成视频的数据,写道小说批次任务中
* @param id
* @param operateBookType
*/
async UseBookVideoDataToBookTask(id: string, operateBookType: OperateBookType) {
try {
console.log(id, operateBookType)
await this.InitService();
let book = undefined as Book.SelectBook;
let bookTasks = undefined as Book.SelectBookTask[];
if (operateBookType == OperateBookType.BOOK) {
book = this.bookService.GetBookDataById(id);
if (book == null) {
throw new Error('未找到对应的小说')
}
bookTasks = this.bookTaskService.GetBookTaskData({
bookId: id,
}).data;
} else if (operateBookType == OperateBookType.BOOKTASK) {
let bookTask = this.bookTaskService.GetBookTaskDataById(id);
if (bookTask == null) {
throw new Error('未找到对应的小说任务')
}
book = this.bookService.GetBookDataById(bookTask.bookId);
if (book == null) {
throw new Error('未找到对应的小说')
}
bookTasks = [bookTask];
} else {
throw new Error("未知的操作类型");
}
if (bookTasks.length <= 0) {
throw new Error("没有需要操作的小说数据,请检查");
}
// 将修改数据放在一个事务中
for (let i = 0; i < bookTasks.length; i++) {
const element = bookTasks[i];
this.bookServiceBasic.UpdetedBookTaskData(element.id, {
backgroundMusic: book.backgroundMusic,
friendlyReminder: book.friendlyReminder,
draftSrtStyle: book.draftSrtStyle,
srtPath: book.srtPath,
audioPath: book.audioPath,
})
}
return successMessage({
backgroundMusic: book.backgroundMusic,
friendlyReminder: book.friendlyReminder,
draftSrtStyle: book.draftSrtStyle,
srtPath: book.srtPath,
audioPath: book.audioPath,
}, "将小说中的生成视频的数据,写到小说批次任务中成功", "BookTask_UseBookVideoDataToBookTask")
} catch (error) {
return errorMessage('将小说中的生成视频的数据,写到小说批次任务中失败,错误信息如下:' + error.toString(), "BookTask_UseBookVideoDataToBookTask");
}
}
/**
* 生成配置文件,用于生成草稿或者是合成视频
* @param book 小说数据
* @param bookTask 对应的小说任务数据
*/
private async GenerateConfigFile(book: Book.SelectBook, bookTask: Book.SelectBookTask): Promise<void> {
try {
// 先修改通用设置
let saveProjectRes = await this.setting.ModifySampleSetting(JSON.stringify({
project_path: book.bookFolderPath,
project_name: book.name,
}))
if (saveProjectRes.code == 0) {
throw new Error("修改通用设置失败")
}
// 开始生成配置文件
let configPath = path.join(book.bookFolderPath, "scripts/config.json");
await CheckFolderExistsOrCreate(path.dirname(configPath));
// 开始配置
let bookTaskDetail = this.bookTaskDetailService.GetBookTaskData({
bookTaskId: bookTask.id
}).data;
let configData = {
srt_time_information: [],
video_config: {
srt_path: bookTask.srtPath,
audio_path: bookTask.audioPath,
draft_srt_style: bookTask.draftSrtStyle ? bookTask.draftSrtStyle : "0",
background_music: bookTask.backgroundMusic,
friendly_reminder: bookTask.friendlyReminder ? bookTask.friendlyReminder : "0",
}
}
for (let i = 0; i < bookTaskDetail.length; i++) {
const element = bookTaskDetail[i];
let frameData = {
no: element.no,
id: element.id,
lastId: i == 0 ? '' : bookTaskDetail[i - 1].id,
word: element.word,
old_image: element.oldImage,
after_gpt: element.afterGpt,
start_time: element.startTime,
end_time: element.endTime,
timeLimit: `${element.startTime} -- ${element.endTime}`,
subValue: element.subValue?.map(item => {
return {
start_time: item.startTime,
end_time: item.endTime,
srt_value: item.srtValue,
id: item.id
}
}),
character_tags: [],
gpt_prompt: element.gptPrompt,
mjMessage: element.mjMessage,
prompt_json: '',
name: element.name + '.png',
outImagePath: element.outImagePath,
subImagePath: element.subImagePath,
scene_tags: [],
imageLock: element.imageLock,
prompt: element.prompt
}
configData.srt_time_information.push(frameData)
}
// 完毕,将数据写出
await fs.promises.writeFile(configPath, JSON.stringify(configData));
} catch (error) {
throw error
}
}
/**
* 添加剪映草稿
* @param id
* @param operateBookType
* @returns
*/
async AddJianyingDraft(id: string, operateBookType: OperateBookType): Promise<GeneralResponse.ErrorItem | GeneralResponse.SuccessItem> {
try {
await this.InitService();
console.log(id, operateBookType)
let book = undefined as Book.SelectBook
let bookTasks = undefined as Book.SelectBookTask[]
if (operateBookType == OperateBookType.BOOK) {
book = this.bookService.GetBookDataById(id);
if (book == null) {
throw new Error("没有找到对应的小说数据,请检查");
}
bookTasks = this.bookTaskService.GetBookTaskData({
bookId: id
}).data.bookTasks
} else if (operateBookType == OperateBookType.BOOKTASK) {
// 直接获取对应的数据
let tempBookTask = this.bookTaskService.GetBookTaskDataById(id);
if (tempBookTask == null) {
throw new Error("没有找到小说批次任务,请检查");
}
bookTasks = [tempBookTask]
book = this.bookService.GetBookDataById(tempBookTask.bookId);
if (book == null) {
throw new Error
}
} else {
throw new Error("未知的操作类型");
}
if (bookTasks.length <= 0) {
throw new Error("没有找到小说批次任务,请检查")
}
// 判断是不是生成单个,每次生成都要修改一下配置文件
// TODO 后面这个地方要修改
// 调用生成草稿的方法
let result = []
for (let i = 0; i < bookTasks.length; i++) {
const element = bookTasks[i];
await this.GenerateConfigFile(book, element);
// 数据处理完毕,开始输出
let clipDraft = new ClipDraft(global, [element.name, {
srt_path: element.srtPath,
audio_path: element.audioPath,
draft_srt_style: element.draftSrtStyle ? element.draftSrtStyle : "0",
background_music: element.backgroundMusic,
friendly_reminder: element.friendlyReminder ? element.friendlyReminder : "0",
}])
let res = await clipDraft.addDraft();
if (res.code == 0) {
throw new Error(res.message)
}
result.push(res.draft_name);
}
return successMessage(result, `${result.join('\n')} ${'\n'} 剪映草稿添加成功`, "BookTask_AddJianyingDraft")
} catch (error) {
return errorMessage('添加剪映草稿失败,错误信息如下:' + error.toString(), "BookTask_AddJianyingDraft");
}
}
}