LaiTool/src/main/Service/Book/bookVideo.ts
lq1405 0c5988ed41 V3.1.8
1. 添加软件高清倍率设置,实现自定义高清倍率(支持两倍、三倍和四倍,默认是两倍)
2. (聚合推文)新增导出草稿。可以依赖做好的草稿文件,只替换图片文件
3. (聚合推文)新增批量生成草稿
4. (聚合推文)修改小说批次任务进行详细界面操作为双击
2024-10-23 22:59:29 +08:00

234 lines
9.4 KiB
TypeScript

import { OperateBookType } from "../../../define/enum/bookEnum";
import { Book } from "../../../model/book";
import { errorMessage, successMessage } from "../../Public/generalTools";
import { GeneralResponse } from "../../../model/generalResponse";
import { Setting } from '../../../main/setting/setting'
import path from 'path'
import { CheckFolderExistsOrCreate } from "../../../define/Tools/file";
import fs from 'fs'
import { ClipDraft } from '../../Public/clipDraft'
import { BookServiceBasic } from "../ServiceBasic/bookServiceBasic";
import { isEmpty } from "lodash";
import JianyingService from "../jianying/jianyingService";
export class BookVideo {
setting: Setting
bookServiceBasic: BookServiceBasic
jianyingService: JianyingService
constructor() {
this.setting = new Setting(global)
this.bookServiceBasic = new BookServiceBasic()
this.jianyingService = new JianyingService()
}
/**
* 将小说中的生成视频的数据,写道小说批次任务中
* @param id
* @param operateBookType
*/
async UseBookVideoDataToBookTask(id: string, operateBookType: OperateBookType) {
try {
console.log(id, operateBookType)
let book = undefined as Book.SelectBook;
let bookTasks = undefined as Book.SelectBookTask[];
if (operateBookType == OperateBookType.BOOK) {
book = await this.bookServiceBasic.GetBookDataById(id);
if (book == null) {
throw new Error('未找到对应的小说')
}
bookTasks = (await this.bookServiceBasic.GetBookTaskData({
bookId: id,
})).bookTasks;
} else if (operateBookType == OperateBookType.BOOKTASK) {
let bookTask = await this.bookServiceBasic.GetBookTaskDataById(id);
if (bookTask == null) {
throw new Error('未找到对应的小说任务')
}
book = await this.bookServiceBasic.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 = await this.bookServiceBasic.GetBookTaskDetailData({
bookTaskId: bookTask.id
});
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,
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 | string[], operateBookType: OperateBookType): Promise<GeneralResponse.ErrorItem | GeneralResponse.SuccessItem> {
try {
console.log(id, operateBookType)
let book = undefined as Book.SelectBook
let bookTasks = [] as Book.SelectBookTask[]
if (operateBookType == OperateBookType.ASSIGNBOOKTASK) {
if (id.length <= 0) {
throw new Error("没有找到小说批次任务,请检查");
}
for (let i = 0; i < id.length; i++) {
const element = id[i];
let tempBookTask = await this.bookServiceBasic.GetBookTaskDataById(element as string);
bookTasks.push(tempBookTask)
book = await this.bookServiceBasic.GetBookDataById(tempBookTask.bookId);
}
} else if (operateBookType == OperateBookType.BOOKTASK) {
// 直接获取对应的数据
let tempBookTask = await this.bookServiceBasic.GetBookTaskDataById(id as string);
if (tempBookTask == null) {
throw new Error("没有找到小说批次任务,请检查");
}
bookTasks = [tempBookTask]
book = await this.bookServiceBasic.GetBookDataById(tempBookTask.bookId);
if (book == null) {
throw new Error
}
} else {
throw new Error("未知的操作类型");
}
if (bookTasks.length <= 0) {
throw new Error("没有找到小说批次任务,请检查")
}
// 判断是不是生成单个,每次生成都要修改一下配置文件
// 调用生成草稿的方法
let result = []
for (let i = 0; i < bookTasks.length; i++) {
const element = bookTasks[i];
// 判断是不是又依赖的草稿,又依赖的草稿,对于依赖的草稿进行操作
if ((!isEmpty(element.draftDepend) && operateBookType != OperateBookType.ASSIGNBOOKTASK) || (operateBookType == OperateBookType.ASSIGNBOOKTASK && !isEmpty(book.draftDepend))) {
let draft_name = `${book.name}_${element.name}`;
if (draft_name == element.draftDepend) {
throw new Error("生成的草稿名称和依赖的草稿名称一样,请检查");
}
await this.jianyingService.GenerateDraftFromDepend(
operateBookType == OperateBookType.ASSIGNBOOKTASK ? book.draftDepend : element.draftDepend,
element.imageFolder, draft_name);
result.push(draft_name);
} else {
await this.GenerateConfigFile(book, element);
// 数据处理完毕,开始输出
let clipDraft = new ClipDraft(global, [element.name, {
srt_path: operateBookType == OperateBookType.ASSIGNBOOKTASK ? book.srtPath : element.srtPath,
audio_path: operateBookType == OperateBookType.ASSIGNBOOKTASK ? book.audioPath : element.audioPath,
draft_srt_style: operateBookType == OperateBookType.ASSIGNBOOKTASK ? (book.draftSrtStyle ? book.draftSrtStyle : '0') : (element.draftSrtStyle ? element.draftSrtStyle : "0"),
background_music: operateBookType == OperateBookType.ASSIGNBOOKTASK ? book.backgroundMusic : element.backgroundMusic,
friendly_reminder: operateBookType == OperateBookType.ASSIGNBOOKTASK ? (book.friendlyReminder ? book.bookFolderPath : '0') : (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");
}
}
}