301 lines
12 KiB
JavaScript
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.

let path = require("path");
let fspromises = require("fs").promises;
import { Tools } from "../tools";
import { DEFINE_STRING } from "../../define/define_string";
import { PublicMethod } from "../Public/publicMethod";
import { define } from "../../define/define";
import { get, has } from "lodash";
import { ClipSetting } from "../../define/setting/clipSetting";
const { v4: uuidv4 } = require('uuid'); // 引入UUID库来生成唯一标识符
let tools = new Tools();
export class Writing {
constructor(global) {
this.global = global
this.pm = new PublicMethod(global);
}
/**
* 将文案信息写入到本地的文案文件中
* @param {*} value
*/
async SaveWordTxt(value) {
try {
let word_path = path.join(global.config.project_path, "文案.txt");
await tools.writeArrayToFile(value, word_path);
return {
code: 1,
message: "保存成功"
}
} catch (error) {
throw new Error(error);
}
}
/**
* 将分镜的时间信息添加道配置文件中
* @param {*} value 是一个数组0 :写入的数据 1写入的属性 2是否需要解析
*/
async SaveCopywritingInformation(value) {
try {
return await this.pm.SaveConfigJsonProperty(value);
} catch (error) {
return {
code: 0,
message: error.toString()
}
}
}
/**
* 获取Config.json文件中指定的属性
* @param {Array} value 传入的值 0 需要获取的属性 1 返回的默认值
* @returns
*/
async GetConfigJson(value) {
try {
return await this.pm.GetConfigJson(value, false);
} catch (error) {
return {
code: 0,
message: error.toString()
}
}
}
/**
* 获取当前项目下面的文案
*/
async GetProjectWord() {
try {
// 先判断当前的项目文件下面是不是又配置文件。没有才读取文案
let srt_config_path = path.join(global.config.project_path, "scripts/config.json");
let isExist = await tools.checkExists(srt_config_path);
let data = null;
let isImformation = false;
if (isExist) {
let config_1 = JSON.parse(await fspromises.readFile(srt_config_path));
isImformation = has(config_1, 'srt_time_information');
if (isImformation) {
data = JSON.parse(await fspromises.readFile(srt_config_path)).srt_time_information;
}
}
if (!isExist || !isImformation) {
let word_path = path.join(global.config.project_path, "文案.txt");
let isExistWord = await tools.checkExists(word_path);
if (!isExistWord) {
return {
code: 0,
message: "没有文案文件"
}
}
let data = await fspromises.readFile(word_path, { encoding: 'utf-8' });
let lines = data.split(/\r?\n/);
// 打印或返回这个数组
// console.log(lines);
// 判断是不是有洗稿后的文件
let new_srt_path = path.join(global.config.project_path, "new_word.txt");
let isExistAfterGPTWord = await tools.checkExists(new_srt_path);
let after_data = null;
if (isExistAfterGPTWord) {
after_data = (await fspromises.readFile(new_srt_path, { encoding: 'utf-8' })).split(/\r?\n/);
}
// 判断抽帧文件是不是存在
// 返回图片信息
let old_image_path_list = await tools.getFilesWithExtensions(path.join(global.config.project_path, "tmp/input_crop"), '.png');
let res = [];
let lastId = '';
// 处理数据
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
let id = uuidv4();
let after_gpt = null;
if (after_data != null) {
after_gpt = after_data[i];
}
let img_path = null;
if (old_image_path_list != null) {
img_path = old_image_path_list[i];
}
let obj = {
no: i + 1,
id: id,
lastId: lastId,
word: line,
old_image: img_path,
after_gpt: after_gpt,
start_time: null,
end_time: null,
timeLimit: null,
subValue: []
}
res.push(obj);
lastId = id;
}
return {
code: 1,
type: 0,
data: res
}
} else {
let data = JSON.parse(await fspromises.readFile(srt_config_path)).srt_time_information;
return {
code: 1,
type: 1,
data: data
}
}
} catch (error) {
throw new Error(error);
}
}
/**
* 搭导入srt。然后加载时间轴。完全匹配失败的将会还是会导入然后手动手动切换
* @param {文案洗稿界面信息} textData
*/
async ImportSrtAndGetTime(data) {
let textData = data[0];
let init_num = textData.length;
let srt_path = data[1];
let current_text = "";
try {
if (!srt_path) {
// 获取项目下面的所有的srt
let srtfiles = await tools.getFilesWithExtensions(global.config.project_path, '.srt');
if (srtfiles.length <= 0) {
throw new Error("没有SRT文件");
}
srt_path = srtfiles[0];
}
let srt_data = (await fspromises.readFile(srt_path, 'utf-8')).toString("utf-8");
const entries = srt_data.replace(/\r\n/g, '\n').split('\n\n');
let data = entries.map(entry => {
const lines = entry.split('\n');
if (lines.length >= 3) {
const times = lines[1];
const text = lines.slice(2).join(' ');
const [start, end] = times.split(' --> ').map(time => {
const [hours, minutes, seconds] = time.split(':');
const [sec, millis] = seconds.split(',');
return ((parseInt(hours) * 3600 + parseInt(minutes) * 60 + parseInt(sec)) * 1000 + parseInt(millis));
});
return { start, end, text, id: uuidv4() };
}
}).filter(entry => entry);
// 开始匹配(洗稿后的)
let srt_list = [];
let srt_obj = null
let text_count = 0;
let tmp_str = "";
for (let i = 0; i < data.length;) {
let srt_value = data[i].text;
current_text = `字幕: “${srt_value}” 和文案第${text_count + 1} 行数据 “${textData[text_count].after_gpt}” 数据不匹配(检查一下上下文)`;
let start_time = data[i].start;
let end_time = data[i].end;
let obj = {
start_time,
end_time,
srt_value,
id: data[i].id
};
// 判断当前字幕是不是在当前句
// 不能用简单的包含,而是将数据进行去除特殊符号拼接后判断是不是相同
tmp_str += srt_value;
if (tools.removePunctuationIncludingEllipsis(textData[text_count].after_gpt).startsWith(tools.removePunctuationIncludingEllipsis(tmp_str))) {
if (srt_obj == null) {
srt_obj = {}
srt_obj.id = uuidv4();
srt_obj.start_time = start_time;
srt_obj.value = srt_value;
srt_obj.subValue = [obj];
}
else {
srt_obj.value = srt_obj.value + srt_value;
srt_obj.subValue = [...srt_obj.subValue, obj];
}
textData[text_count].start_time = srt_obj.start_time;
textData[text_count].subValue = srt_obj.subValue
srt_list.push(obj);
i++;
} else {
// 判断下一句文件是不是以当当前巨开头。是的话继续。不是的话。直接返回后面的所有信息
if (tools.removePunctuationIncludingEllipsis(textData[text_count + 1].after_gpt).startsWith(tools.removePunctuationIncludingEllipsis(srt_value))) {
textData[text_count].end_time = srt_list[srt_list.length - 1].end_time;
text_count++;
srt_obj = null;
tmp_str = ""
} else {
// 将下面的数据直接 添加到textData后面。
// 修改当前行数据的结束事件为
if (srt_list.length > 0) {
textData[text_count].end_time = srt_list[srt_list.length - 1].end_time;
text_count++;
}
// 将后面的数据直接添加
let lastId = textData[textData.length - 1].id;
for (let j = i; j < data.length; j++) {
// 直接修改原有数据
if (text_count < init_num) {
textData[text_count].subValue = [{
start_time: data[j].start,
end_time: data[j].end,
id: data[j].id,
srt_value: data[j].text
}]
textData[text_count].start_time = data[j].start;
textData[text_count].end_time = data[j].end;
text_count++;
}
else {
let id = uuidv4();
// 添加
let obj = {
no: j + 1,
id: id,
word: null,
lastId: lastId,
old_image: path.normalize(define.zhanwei_image),
after_gpt: null,
start_time: data[j].start,
end_time: data[j].end,
subValue: [{
start_time: data[j].start,
end_time: data[j].end,
id: data[j].id,
srt_value: data[j].text
}]
}
lastId = id;
textData.push(obj);
}
}
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, {
code: 0,
message: current_text
})
return {
code: 1,
data: textData
}
}
}
}
// 最后对齐
textData[textData.length - 1].end_time = srt_list[srt_list.length - 1].end_time
// 返回数据
return {
code: 1,
data: textData
}
} catch (error) {
return {
code: 0,
message: error.toString()
}
}
}
}