This commit is contained in:
lq1405 2025-02-10 11:44:51 +08:00
parent 597adaa75a
commit d595e932e3
20 changed files with 4491 additions and 0 deletions

BIN
resources/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

53
resources/icon.svg Normal file
View File

@ -0,0 +1,53 @@
<svg class="svg-canvas" viewBox="0 0 800 600" width="1600" height="1200" preserveAspectRatio="none" version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<!--滤镜-->
<defs>
<filter id="filter_shadow_shape_HBt9Poo2sR" width="300%" height="300%" x="-100%" y="-100%">
<feDropShadow dx="7.431448254773942" dy="6.691306063588582" stdDeviation="1.2000000000000002" flood-color="#000000" flood-opacity="0.26"></feDropShadow>
</filter>
</defs>
<!--元素-->
<g id="shape_BG1gIWpILa" ref="shape_BG1gIWpILa" key="shape_BG1gIWpILa" mask="">
<g transform="translate(-82.01635169835797,-38.231795889017974) rotate(0,482.36560107022797,353.36560107022797) scale(1,1)" style="opacity: 1;mix-blend-mode: multiply;" filter="">
<!--普通元素-->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink" width="964.7312021404559" height="706.7312021404559" viewBox="0 0 964.7312021404559 706.7312021404559" data-ligature="true" data-parent="shape_BG1gIWpILa">
<g data-role="text" data-width="354.00141380959474" data-height="117" transform="translate(305.3648941654306, 294.86560107022797)">
<path d="M17.66-71.89L17.66-71.89Q19.68-69.97 28.03-67.96L28.03-67.96Q30.43-66.61 30.43-63.83L30.43-63.83L30.43-63.54Q30.43-60.18 25.05-59.42L25.05-59.42L24.48-58.46L24.48-56.44Q21.79-45.79 21.79-40.89L21.79-40.89L22.08-38.20L20.35-28.70L20.64-27.26Q19.10-16.70 19.10-15.65L19.10-15.65L19.39-15.65Q24.57-15.65 44.44-15.93L44.44-15.93Q46.55-15.65 46.84-15.65L46.84-15.65Q51.64-18.91 53.37-18.91L53.37-18.91L53.94-18.91Q54.52-17.76 54.81-17.76L54.81-17.76Q54.52-14.78 54.52-13.25L54.52-13.25L54.52-12.38Q54.52-10.75 55.38-7.87L55.38-7.87Q55.38-6.72 53.08-4.90L53.08-4.90Q51.54-4.90 51.54-5.47L51.54-5.47L48.57-5.18L44.73-5.18Q41.37-5.18 36.09-5.47L36.09-5.47L35.51-5.18Q34.46-5.47 34.27-5.47L34.27-5.47Q28.12-4.90 24.19-4.90L24.19-4.90L22.08-4.90Q20.64-4.90 17.09-4.03L17.09-4.03L14.11-4.32Q10.46-3.46 10.46-3.17L10.46-3.17Q10.08-3.17 6.91-7.87L6.91-7.87Q4.22-9.89 4.22-11.42L4.22-11.42Q4.22-12.29 6.05-15.65L6.05-15.65Q6.05-17.47 8.45-21.02L8.45-21.02Q13.15-42.62 13.15-61.72L13.15-61.72Q13.44-61.72 13.44-63.25L13.44-63.25L11.71-64.69Q12.09-66.23 16.41-69.78L16.41-69.78Q16.41-71.89 17.66-71.89Z" transform="translate(0 94) " fill="rgb(50, 113, 174)" stroke="rgb(50, 113, 174)" stroke-width="0.164" data-glyph-w="63.4155967830671" data-glyph-h="95.986328125" data-glyph-ascender="84.46796875000001" data-glyph-descender="-11.518359375000001" data-kerning="0"></path>
<path d="M24.19-39.64L24.19-39.64L25.72-39.64Q27.84-39.64 30.72-35.80L30.72-35.80L31.39-35.80Q33.12-37.63 35.80-37.63L35.80-37.63Q39.64-36.19 39.64-32.54L39.64-32.54L41.47-28.99Q41.47-28.51 40.89-26.30L40.89-26.30Q40.89-26.11 41.18-24.48L41.18-24.48Q39.07-19.39 39.07-18.24L39.07-18.24L39.07-17.37Q39.07-15.07 41.18-13.25L41.18-13.25L41.75-13.25Q43.77-13.25 45.88-16.22L45.88-16.22L48.57-17.09Q49.62-17.09 50.10-13.82L50.10-13.82Q48.86-8.45 48.86-7.58L48.86-7.58Q49.43-7.29 49.82-7.29L49.82-7.29Q48.38-4.61 45.59-4.61L45.59-4.61Q44.73-4.61 43.58-4.90L43.58-4.90Q41.95-4.61 40.31-4.61L40.31-4.61Q34.08-7.29 33.12-9.02L33.12-9.02Q26.49-3.65 25.05-3.65L25.05-3.65Q25.05-3.07 20.64-2.78L20.64-2.78Q12.57-2.78 9.31-8.16L9.31-8.16Q5.76-12.48 5.76-17.95L5.76-17.95L5.76-21.21Q5.76-31.48 16.80-37.91L16.80-37.91Q22.46-39.64 24.19-39.64ZM13.15-19.49L13.15-19.49Q14.40-10.56 16.51-10.56L16.51-10.56L19.10-10.56Q23.32-10.56 27.45-19.49L27.45-19.49Q30.43-24.57 30.43-28.99L30.43-28.99Q29.08-30.24 27.16-34.65L27.16-34.65L26.30-34.65Q21.21-34.65 15.55-27.74L15.55-27.74Q13.15-23.71 13.15-19.49Z" transform="translate(63.4155967830671 94) " fill="rgb(50, 113, 174)" stroke="rgb(50, 113, 174)" stroke-width="0.164" data-glyph-w="54.872813579942104" data-glyph-h="95.986328125" data-glyph-ascender="84.46796875000001" data-glyph-descender="-11.518359375000001" data-kerning="0"></path>
<path d="M14.30-56.34L14.30-56.34Q18.24-56.34 20.25-50.68L20.25-50.68Q20.25-49.05 16.13-46.55L16.13-46.55Q12.96-47.32 12.19-47.99L12.19-47.99Q11.71-47.71 11.04-47.71L11.04-47.71Q9.21-50.20 9.21-50.68L9.21-50.68Q9.89-56.06 14.01-56.06L14.01-56.06Q14.01-56.34 14.30-56.34ZM9.21-39.93L9.50-41.47L10.17-41.47Q11.52-41.47 13.15-41.18L13.15-41.18L14.88-41.47Q16.51-41.47 17.85-39.07L17.85-39.07Q16.99-29.76 16.99-21.79L16.99-21.79Q17.28-20.25 17.28-20.06L17.28-20.06L16.99-18.24Q17.28-15.65 17.28-15.26L17.28-15.26L16.99-13.53Q17.28-10.65 17.28-8.16L17.28-8.16L17.28-5.76Q17.28-5.47 17.57-5.47L17.57-5.47Q16.80-0.96 16.41-0.96L16.41-0.96Q15.84-1.25 15.45-1.25L15.45-1.25L15.17-0.67L15.45-0.10Q15.17 0.77 14.88 0.77L14.88 0.77Q13.92 0.19 13.15 0.19L13.15 0.19Q12.86 0.67 12.86 1.34L12.86 1.34L12.48 1.34Q6.24-4.32 6.24-7.58L6.24-7.58Q8.16-20.06 9.21-38.20L9.21-38.20L9.21-39.93Z" transform="translate(118.2884103630092 94) " fill="rgb(50, 113, 174)" stroke="rgb(50, 113, 174)" stroke-width="0.164" data-glyph-w="27.804669048692098" data-glyph-h="95.986328125" data-glyph-ascender="84.46796875000001" data-glyph-descender="-11.518359375000001" data-kerning="0"></path>
<path d="M56.25-68.05L56.25-68.05Q61.34-67.29 61.34-62.97L61.34-62.97L61.34-62.68Q61.14-60.76 56.54-57.30L56.54-57.30Q55.96-56.15 55.96-55.58L55.96-55.58L53.85-55.86L53.56-55.86Q52.98-55.86 52.98-55.00L52.98-55.00Q47.90-55.58 46.17-55.58L46.17-55.58L44.06-55.58Q37.53-55.58 37.53-53.46L37.53-53.46Q37.53-53.08 36.57-52.31L36.57-52.31L36.95-51.06L36.28-49.62L36.57-47.51Q36.57-46.17 36.28-43.67L36.28-43.67Q36.57-38.20 36.57-34.46L36.57-34.46Q36.57-33.79 36.28-31.20L36.28-31.20Q36.57-30.62 36.57-30.24L36.57-30.24L35.99-24.57Q36.28-23.04 36.28-21.31L36.28-21.31Q36.28-20.45 35.99-19.29L35.99-19.29Q36.28-17.66 36.28-16.32L36.28-16.32L36.28-14.49Q34.56-0.77 31.87-0.77L31.87-0.77Q30.81-0.48 30.62-0.48L30.62-0.48Q30.04-0.48 28.60-1.15L28.60-1.15L20.83-0.48L20.83-1.44L19.68-5.86Q21.79-5.86 25.05-37.72L25.05-37.72Q25.05-40.31 25.34-52.02L25.34-52.02L25.63-53.46L25.05-53.75Q14.30-53.46 14.30-52.89L14.30-52.89L12.77-53.18L9.21-52.02Q5.09-52.02 5.09-58.55L5.09-58.55Q4.80-58.55 3.55-60.95L3.55-60.95L3.55-62.10Q3.65-62.68 4.22-62.68L4.22-62.68L4.80-62.68Q6.82-62.68 8.06-61.53L8.06-61.53L9.50-62.10L11.61-61.82Q40.60-66.23 45.88-66.23L45.88-66.23L50.30-66.23Q56.25-67.57 56.25-68.05Z" transform="translate(146.0930794117013 94) " fill="rgb(50, 113, 174)" stroke="rgb(50, 113, 174)" stroke-width="0.164" data-glyph-w="68.2149131893171" data-glyph-h="95.986328125" data-glyph-ascender="84.46796875000001" data-glyph-descender="-11.518359375000001" data-kerning="0"></path>
<path d="M26.49-40.41L26.49-40.41Q44.63-33.31 44.63-24.67L44.63-24.67L44.63-22.27Q44.63-16.32 39.83-11.81L39.83-11.81Q36.86-6.43 30.62-4.13L30.62-4.13Q23.61-2.02 21.69-2.02L21.69-2.02Q13.73-2.02 6.82-12.09L6.82-12.09Q5.95-14.78 5.95-15.74L5.95-15.74L5.95-17.76Q7.01-31.20 8.64-31.20L8.64-31.20Q15.74-40.12 21.98-40.12L21.98-40.12L24.67-39.83Q25.92-40.41 26.49-40.41ZM27.64-30.33L24.96-30.33Q24.96-28.51 18.72-28.51L18.72-28.51L17.85-28.51Q14.88-28.51 13.05-21.69L13.05-21.69L13.05-19.01Q14.21-13.05 17.28-13.05L17.28-13.05Q17.37-12.48 17.85-12.48L17.85-12.48L21.12-12.48Q28.03-12.48 32.44-22.56L32.44-22.56L32.73-25.24Q31.77-30.33 27.64-30.33L27.64-30.33Z" transform="translate(214.30799260101838 94) " fill="rgb(50, 113, 174)" stroke="rgb(50, 113, 174)" stroke-width="0.164" data-glyph-w="54.200909283067105" data-glyph-h="95.986328125" data-glyph-ascender="84.46796875000001" data-glyph-descender="-11.518359375000001" data-kerning="0"></path>
<path d="M26.49-40.41L26.49-40.41Q44.63-33.31 44.63-24.67L44.63-24.67L44.63-22.27Q44.63-16.32 39.83-11.81L39.83-11.81Q36.86-6.43 30.62-4.13L30.62-4.13Q23.61-2.02 21.69-2.02L21.69-2.02Q13.73-2.02 6.82-12.09L6.82-12.09Q5.95-14.78 5.95-15.74L5.95-15.74L5.95-17.76Q7.01-31.20 8.64-31.20L8.64-31.20Q15.74-40.12 21.98-40.12L21.98-40.12L24.67-39.83Q25.92-40.41 26.49-40.41ZM27.64-30.33L24.96-30.33Q24.96-28.51 18.72-28.51L18.72-28.51L17.85-28.51Q14.88-28.51 13.05-21.69L13.05-21.69L13.05-19.01Q14.21-13.05 17.28-13.05L17.28-13.05Q17.37-12.48 17.85-12.48L17.85-12.48L21.12-12.48Q28.03-12.48 32.44-22.56L32.44-22.56L32.73-25.24Q31.77-30.33 27.64-30.33L27.64-30.33Z" transform="translate(268.5089018840855 94) " fill="rgb(50, 113, 174)" stroke="rgb(50, 113, 174)" stroke-width="0.164" data-glyph-w="54.200909283067105" data-glyph-h="95.986328125" data-glyph-ascender="84.46796875000001" data-glyph-descender="-11.518359375000001" data-kerning="0"></path>
<path d="M18.33-68.73L18.33-68.73Q22.56-67.86 22.56-66.71L22.56-66.71Q21.31-61.34 21.31-59.80L21.31-59.80L21.31-57.50Q20.16-35.04 18.72-21.12L18.72-21.12L18.72-19.10L19.58-19.10Q19.58-19.49 24.28-22.36L24.28-22.36Q27.64-25.34 28.22-25.34L28.22-25.34L28.22-24.76Q25.72-19.20 23.71-11.33L23.71-11.33Q20.16-7.68 20.16-5.38L20.16-5.38Q20.16-2.98 13.34-2.40L13.34-2.40Q13.34-2.11 13.05-2.11L13.05-2.11L5.86-5.95Q5.28-7.77 4.99-7.77L4.99-7.77Q5.57-9.31 5.57-13.15L5.57-13.15L5.57-13.44Q8.64-13.44 10.65-52.41L10.65-52.41Q11.23-62.20 11.23-64.60L11.23-64.60Q10.75-64.89 10.08-64.89L10.08-64.89L10.08-65.46Q10.65-67.77 13.63-68.44L13.63-68.44Q14.11-68.44 18.33-68.73Z" transform="translate(322.7098111671526 94) " fill="rgb(50, 113, 174)" stroke="rgb(50, 113, 174)" stroke-width="0.164" data-glyph-w="35.2916026424421" data-glyph-h="95.986328125" data-glyph-ascender="84.46796875000001" data-glyph-descender="-11.518359375000001" data-kerning="0"></path>
</g>
</svg>
</g>
</g>
<g id="shape_HBt9Poo2sR" ref="shape_HBt9Poo2sR" key="shape_HBt9Poo2sR" mask="">
<g transform="translate(290.23123855735,120) rotate(0,109.76876144264,68.206715750285) scale(1,1)" style="opacity: 1;mix-blend-mode: undefined;" filter="url(#filter_shadow_shape_HBt9Poo2sR)">
<!--普通元素-->
<svg version="1.1" id="圖層_1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 -8.068921089172363 315.3833923339844 195.9689178466797" style="enable-background:new 0 0 304.3 187.9;" xml:space="preserve" width="219.53752288528" height="136.41343150057" class="style-removed" preserveAspectRatio="none" data-parent="shape_HBt9Poo2sR">
<g>
<path d="M214.9,124.7L214.9,124.7c1.3,4.5,2.7,9.1,4.2,13.7c12.6,40.3,27.1,42.9,27.1,42.9l4.4,0.4h0.3
c0,0,15.8-3.6,26.7-45c7.4-28.2,11.5-43.9,16.5-62h-64.6C225,91.1,220.3,107.5,214.9,124.7z" fill="rgb(50, 113, 174)" stroke-width="0"></path>
<path d="M88.6,6.5c-0.5-0.2-0.9-0.4-1.3-0.6h-2.8c0,0-13.2-1.6-22,30.7C52.8,72.3,44.9,105,33,141.8
c-14.7,45.5-33,46.1-33,46.1h72.9c0,0,16.6-3.6,27.5-46.3c9.1-35.9,12.6-52.2,19.5-77.5c-1.5-5.6-3.1-11.7-5-18.5
C105.9,13.5,90.3,7.2,88.6,6.5z" fill="rgb(50, 113, 174)" stroke-width="0"></path>
<path d="M212.7,140.4c-0.5-1.5-1-3.1-1.4-4.6c-11.1-36.2-18.8-68.7-28.1-104.1C175.3,1.4,163.6,0,161.6,0
c-0.2,0-0.3,0-0.3,0H90.8c-0.1,0-0.2,0.2-0.1,0.2c1.5,0.5,4.9,2,9.2,5.6c6.7,5.7,15.4,16.8,21.3,37.9c0.7,2.7,1.5,5.2,2.1,7.7
c8.6,31.4,11.7,47.7,21.8,88.6c10.9,44.1,27.5,47.8,27.5,47.8h72.8c-0.7-0.1-5-0.6-11-6.3C229.4,177.3,220.5,165.4,212.7,140.4z" fill="rgb(50, 113, 174)" stroke-width="0"></path>
<ellipse transform="matrix(0.8694 -0.4941 0.4941 0.8694 17.8966 137.5734)" cx="269.2" cy="34.9" rx="37" ry="28.4" fill="rgb(50, 113, 174)" stroke-width="0"></ellipse>
</g>
</svg>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

BIN
resources/icon11.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

BIN
resources/icon_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
resources/icon_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

172
src/define/define_string.js Normal file
View File

@ -0,0 +1,172 @@
export const DEFINE_STRING = {
SAVE_DEFINE_CONFIG_JSON_BY_PROPERTY: "SAVE_DEFINE_CONFIG_JSON_BY_PROPERTY",
GET_DEFINE_CONFIG_JSON_BY_PROPERTY: "GET_DEFINE_CONFIG_JSON_BY_PROPERTY",
GET_IMAGE_GENERATE_CATEGORY: "GET_IMAGE_GENERATE_CATEGORY",
SHOW_MAIN_NOTIFICATION: "SHOW_MAIN_NOTIFICATION",
CHECK_MACHINE_ID: "CHECK_MACHINE_ID",
GET_CUSTOMIZE_GPT_PROMPT: "GET_CUSTOMIZE_GPT_PROMPT",
GENERATE_GPT_EXAMPLE_OUT: "GENERATE_GPT_EXAMPLE_OUT",
GET_PERMISSION: "GET_PERMISSION",
SAVE_IMAGE_TO_OTHER_FOLDER: "SAVE_IMAGE_TO_OTHER_FOLDER",
GET_IMAGE_AUTO_SAVE_SETTING: "GET_IMAGE_AUTO_SAVE_SETTING",
SAVE_IMAGE_AUTO_SAVE_SETTING: "SAVE_IMAGE_AUTO_SAVE_SETTING",
GET_AUTO_SAVE_IMAGE_CLASSIFY_OPTIONS: "GET_AUTO_SAVE_IMAGE_CLASSIFY_OPTIONS",
MODIFY_GENERATE_TASK_STATUS: "MODIFY_GENERATE_TASK_STATUS",
DELETE_BACK_TASK: "DELETE_BACK_TASK",
SAVE_VIDEO_SRT_AND_AUDIO_MESSAGE: "SAVE_VIDEO_SRT_AND_AUDIO_MESSAGE",
SAVE_KEY_FRAME_SETTING: "SAVE_KEY_FRAME_SETTING",
MODIFY_SAMPLE_SETTING: "MODIFY_SAMPLE_SETTING",
GET_SETTING_Dafault_DATA: "GET_SETTING_Dafault_DATA",
GET_DRAFT_FILE_LIST: "GET_DRAFT_FILE_LIST",
GET_FRAME: "GET_FRAME",
PYTHON_ERROR: "PYTHON_ERROR",
PYTHON_CLOSE: "PYTHON_CLOSE",
PYTHON_OUTPUT: "PYTHON_OUTPUT",
RESTART_GENERATE: "RESTART_GENERATE",
ALIGN_DRAFT_IMG: "ALIGN_DRAFT_IMG",
ALIGN_DRAFT_IMG_TO_TEXT: "ALIGN_DRAFT_IMG_TO_TEXT",
REGENERATE_IMAGE_RETUN: "REGENERATE_IMAGE_RETUN",
GET_SUBFOLDER_LIST: "GET_SUBFOLDER_LIST",
REFRASH_IMAGWE_DATA: "REFRASH_IMAGWE_DATA",
GET_IMAGE_PROMPTLIST: "GET_IMAGE_PROMPTLIST",
SELECT_FILE: "SELECT_FILE",
IMPROVE_IMAGE_RESOULTION: "IMPROVE_IMAGE_RESOULTION",
GET_BACKGROUND_MUSIC_CONFIG_LIST: "GET_BACKGROUND_MUSIC_CONFIG_LIST",
ADD_BACKGROUND_MUSIC_FOLDER: "ADD_BACKGROUND_MUSIC_FOLDER",
DELETE_CLIP_SETTING: "DELETE_CLIP_SETTING",
DELETE_FRIENDLY_REMINDER: "DELETE_FRIENDLY_REMINDER",
MODIFY_INPUT_CROP_JSON: "MODIFY_INPUT_CROP_JSON",
PUSH_BACK_PROMPT: "PUSH_BACK_PROMPT",
GET_FRIENDLY_REMINDER_DRAFT: "GET_FRIENDLY_REMINDER_DRAFT",
GET_FRIENDLY_REMINDER_LIST: "GET_FRIENDLY_REMINDER_LIST",
AUTO_GENERATION_VIDEO: "AUTO_GENERATION_VIDEO",
GET_PROJECT_WORD: "GET_PROJECT_WORD",
AIMODIFY_ONE_WORD: "AIMODIFY_ONE_WORD",
IMPORT_SRT_AND_GET_TIME: "IMPORT_SRT_AND_GET_TIME",
SAVE_NEW_WORD: "SAVE_NEW_WORD",
SAVE_COPYWRITING_INFOMATION: "SAVE_COPYWRITING_INFOMATION",
SAVE_SD_CONFIG: "SAVE_SD_CONFIG",
SAVE_GENERAL_SETTING: "SAVE_GENERAL_SETTING",
GET_VIDEO_CONFIG_MESSAGE: "GET_VIDEO_CONFIG_MESSAGE",
GET_SYSTEM_INSTALL_FONTNAME: "GET_SYSTEM_INSTALL_FONTNAME",
SAVE_ASS_CONFIG: "SAVE_ASS_CONFIG",
DELETE_VIDEO_CONFIG: "DELETE_VIDEO_CONFIG",
SHOW_NEW_WINDOW: "SHOW_NEW_WINDOW",
GET_DRAFT_FILE_LIST: "GET_DRAFT_FILE_LIST",
SELECT_FOLDER: "SELECT_FOLDER",
GET_DRAFT_TEXT_STYLE: "GET_DRAFT_TEXT_STYLE",
GET_TEXT_STYLE_LIST: "GET_TEXT_STYLE_LIST",
DELETE_DRAFT_TEXT_STYLE: "DELETE_DRAFT_TEXT_STYLE",
ADD_DRAFT: "ADD_DRAFT",
RETURN_IMAGE_PROMPT: "RETURN_IMAGE_PROMPT",
RE_GENERATE_IAMGE_ONE: "RE_GENERATE_IAMGE_ONE",
INIT_SD_CONFIG: "INIT_SD_CONFIG",
ADD_IMAGE_TASK_LIST: "ADD_IMAGE_TASK_LIST",
GET_GENERATE_TASK_LIST: "GET_GENERATE_TASK_LIST",
DELETE_IMAGE_TASK_LIST: "DELETE_IMAGE_TASK_LIST",
GENERATE_IMAGWE_IN_SELECT_TASK: "GENERATE_IMAGWE_IN_SELECT_TASK",
GET_MACHINE_ID: "GET_MACHINE_ID",
QUIT_APP: "QUIT_APP",
GET_BAD_PROMPT: "GET_BAD_PROMPT",
SAVE_BAD_PROMPT: "SAVE_BAD_PROMPT",
DELETE_BAD_PROMPT: "DELETE_BAD_PROMPT",
ADD_WEBUI_JSON: "ADD_WEBUI_JSON",
OPEN_GPT_BUY_URL: "OPEN_GPT_BUY_URL",
GET_IAMGE_PROMPT_LIST: "GET_IAMGE_PROMPT_LIST",
GET_ADETAILER_LIST: "GET_ADETAILER_LIST",
SAVE_DETAILER_CONFIG: "SAVE_DETAILER_CONFIG",
OPEN_URL: "OPEN_URL",
GET_VERSION: "GET_VERSION",
GET_FRAME_RETUN: "GET_FRAME_RETUN",
DOWNLOAD_MODEL: "DOWNLOAD_MODEL",
START_STORY_BOARDING: "START_STORY_BOARDING",
SHOW_MESSAGE_DIALOG: "SHOW_MESSAGE_DIALOG",
SHOW_GLOABAL_MESSAGE_DIALOG: "SHOW_GLOABAL_MESSAGE_DIALOG",
IMAGE_TASK_STATUS_REFRESH: "IMAGE_TASK_STATUS_REFRESH",
SAVE_TRIAL_END_TIME: "SAVE_TRIAL_END_TIME",
DOWNLOAD_IMAGE_FILE: "DOWNLOAD_IMAGE_FILE",
OPEN_FOLDER: "OPEN_FOLDER",
VIDEO_GENERATE_STATUS_REFRESH: "VIDEO_GENERATE_STATUS_REFRESH",
AUTO_CONDITION_CHECK: "AUTO_CONDITION_CHECK",
MODIFY_IMAGE_TASK_LIST: "MODIFY_IMAGE_TASK_LIST",
ACTION_AUTO_VIDEO_TASK: "ACTION_AUTO_VIDEO_TASK",
GET_VIDEO_GENERATE_CONFIG: "GET_VIDEO_GENERATE_CONFIG",
TRANSLATE_PROMPT: "TRANSLATE_PROMPT",
TRANSLATE_RETURN_NOW: "TRANSLATE_RETURN_NOW",
TRANSLATE_RETURN_REFRESH: "TRANSLATE_RETURN_REFRESH",
GET_SHOW_MESSAGE: "GET_SHOW_MESSAGE",
AUTO_ANALYZE_CHARACTER: "AUTO_ANALYZE_CHARACTER",
GET_CONFIG_JSON: "GET_CONFIG_JSON",
ORIGINAL_ADD_WEBUI_JSON: "ORIGINAL_ADD_WEBUI_JSON",
GET_PROMPT_JSON: "GET_PROMPT_JSON",
GPT_PROMPT: "GPT_PROMPT",
GPT_GENERATE_PROMPT_RETURN: "GPT_GENERATE_PROMPT_RETURN",
AUTO_SAVE_DATA_JSON: "AUTO_SAVE_DATA_JSON",
ORIGINAL_SD_SINGLE_IMAGE_GENERATE: "ORIGINAL_SD_SINGLE_IMAGE_GENERATE",
SD_ORIGINAL_GENERATE_IMAGE_RETURN: "SD_ORIGINAL_GENERATE_IMAGE_RETURN",
GET_STYLE_IMAGE_SUB_LIST: "GET_STYLE_IMAGE_SUB_LIST",
GET_IMAGE_STYLE_INFOMATION: "GET_IMAGE_STYLE_INFOMATION",
GET_IMAGE_STYLE_MENU: "GET_IMAGE_STYLE_MENU",
GET_GPT_BUSINESS_OPTION: "GET_GPT_BUSINESS_OPTION",
GET_GPT_MODEL_OPTION: "GET_GPT_MODEL_OPTION",
GET_GPT_AUTO_INFERENCE_OPTIONS: "GET_GPT_AUTO_INFERENCE_OPTIONS",
SAVE_DYNAMIC_GPT_OPTION: "SAVE_DYNAMIC_GPT_OPTION",
DELETE_DYNAMIC_GPT_OPTION: "DELETE_DYNAMIC_GPT_OPTION",
TEST_GPT_CONNECTION: "TEST_GPT_CONNECTION",
SAVE_WORD_TXT: "SAVE_WORD_TXT",
GET_KEY_FRAME_CONFIG_DATA: "GET_KEY_FRAME_CONFIG_DATA",
GET_KEYFRAME_OPTIONS: "GET_KEYFRAME_OPTIONS",
QUEUE_BATCH: {
SD_ORIGINAL_GENERATE_IMAGE: "SD_ORIGINAL_GENERATE_IMAGE",
SD_ORIGINAL_GPT_PROMPT: "SD_ORIGINAL_GPT_PROMPT",
SD_BACKSTEP_GENERATE_IMAGE: "SD_BACKSTEP_GENERATE_IMAGE",
MJ_ORIGINAL_GENERATE_IMAGE: "MJ_ORIGINAL_GENERATE_IMAGE",
LOCAL_IMAGE_IMPROVE: "LOCAL_IMAGE_IMPROVE",
AUTO_VIDEO_GENERATE: "AUTO_VIDEO_GENERATE",
AUTO_VIDEO_GENERATE_SINGLE: "AUTO_VIDEO_GENERATE_SINGLE",
TRANSLATE_PROMPT: "TRANSLATE_PROMPT",
TRANSLATE_RETURN_NOW_TASK: "TRANSLATE_RETURN_NOW_TASK",
IMAGE_SAVE_TO_OTHER_FOLDER: "IMAGE_SAVE_TO_OTHER_FOLDER",
SAVE_FILE_QUEUE: "SAVE_FILE_QUEUE",
},
PERMISSIONS: {
NORMAL_PERMISSION: "NORMAL_PERMISSION",
AUTO_SAVE_IMAGE_PERMISSION: "AUTO_SAVE_IMAGE_PERMISSION",
},
MJ: {
SAVE_WORD_SRT: "SAVE_WORD_SRT",
GET_MJ_CONFIG_SRT_INFORMATION: "GET_MJ_CONFIG_SRT_INFORMATION",
GET_TAG_DATA_BY_TYPE_AND_PROPERTY: "GET_TAG_DATA_BY_TYPE_AND_PROPERTY",
SAVE_TAG_PROPERTY_DATA: "SAVE_TAG_PROPERTY_DATA",
DELETE_TAG_PROPERTY_DATA: "DELETE_TAG_PROPERTY_DATA",
GET_TAG_SELECT_MODEL: "GET_TAG_SELECT_MODEL",
TRANSLATE_RETURN_NOW_TASK: "TRANSLATE_RETURN_NOW_TASK",
ORIGINAL_MJ_IMAGE_GENERATE: "ORIGINAL_MJ_IMAGE_GENERATE",
GET_CHANNEL_ROBOTS: "GET_CHANNEL_ROBOTS",
GET_MJ_GENERATE_CATEGORY: "GET_MJ_GENERATE_CATEGORY",
IMAGE_SPLIT: "IMAGE_SPLIT",
ADD_MJ_BAD_PROMPT: "ADD_MJ_BAD_PROMPT",
MJ_BAD_PROMPT_CHECK: "MJ_BAD_PROMPT_CHECK",
GET_GENERATED_MJ_IMAGE_AND_SPLIT: "GET_GENERATED_MJ_IMAGE_AND_SPLIT",
DOWNLOAD_IMAGE_URL_AND_SPLIT: "DOWNLOAD_IMAGE_URL_AND_SPLIT"
},
DISCORD: {
OPERATE_REFRASH_DISCORD_URL: "OPERATE_REFRASH_DISCORD_URL",
GET_DISCORD_WINDOW_URL: "GET_DISCORD_WINDOW_URL",
CREATE_MESSAGE: "CREATE_MESSAGE",
UPDATE_MESSAGE: "UPDATE_MESSAGE",
DELETE_MESSAGE: "DELETE_MESSAGE",
MAIN_DISCORD_MESSAGE_CHANGE: "MAIN_DISCORD_MESSAGE_CHANGE",
},
DISCORD_REQUEST_LISTENER_TYPE: {
INPUT_MODEL_IMAGINE_REQUEST: "INPUT_MODEL_IMAGINE_REQUEST",
},
DISCORD_SIMPLE_DATA_TYPE: {
URL: "URL",
TOKEN: "TOKEN",
},
MAIN: {
OPEN_DISCORD_WINDOW: "OPEN_DISCORD_WINDOW"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,72 @@
const {
ipcMain
} = require("electron")
import { DEFINE_STRING } from '../../define/define_string'
import {
Setting
} from '../setting/setting'
let setting = new Setting(global);
function SettingIpc() {
// 获取背景音乐配置列表
ipcMain.handle(DEFINE_STRING.GET_BACKGROUND_MUSIC_CONFIG_LIST, async (event) => await setting.GetBackGroundMusicConfigList());
// 获取剪映关键帧配置列表
ipcMain.handle(DEFINE_STRING.GET_KEYFRAME_OPTIONS, async (event) => await setting.GetKeyFrameOptions());
// 保存剪映关键帧配置
ipcMain.handle(DEFINE_STRING.SAVE_KEY_FRAME_SETTING, async (event, value) => await setting.SaveKeyFrameSetting(value));
// 监听添加背景音乐文件
ipcMain.handle(DEFINE_STRING.ADD_BACKGROUND_MUSIC_FOLDER, async (event, value) => await setting.AddBackgroundMusicFolder(value))
// 删除剪映的样式设置
ipcMain.handle(DEFINE_STRING.DELETE_DRAFT_TEXT_STYLE, async (event, value) => await setting.deleteClipSetting("text_style", value));
// 删除剪映的背景音乐设置
ipcMain.handle(DEFINE_STRING.DELETE_CLIP_SETTING, async (event, value) => await setting.deleteClipSetting("background_music_setting", value));
// 删除剪映的友情提示设置
ipcMain.handle(DEFINE_STRING.DELETE_FRIENDLY_REMINDER, async (event, value) => await setting.deleteClipSetting("friendly_reminder_setting", value));
// 监听获取SD配置任务
ipcMain.handle(DEFINE_STRING.INIT_SD_CONFIG, async (event, value) => await setting.InitSDConfig());
// 获取主页显示信息
ipcMain.handle(DEFINE_STRING.GET_SHOW_MESSAGE, async (event) => await setting.GetShowMessage())
// 获取关键帧的配置数据
ipcMain.handle(DEFINE_STRING.GET_KEY_FRAME_CONFIG_DATA, async (event) => await setting.GetKeyFrameConfigData());
// 删除后台队列任务
ipcMain.handle(DEFINE_STRING.DELETE_BACK_TASK, async (event, value) => await setting.RemoveTask(value));
// 获取自动保存图片的分类方式
ipcMain.handle(DEFINE_STRING.GET_AUTO_SAVE_IMAGE_CLASSIFY_OPTIONS, async (event) => await setting.GetAutoSaveImageClassifyOptions());
// 保存图片自动保存的配置
ipcMain.handle(DEFINE_STRING.SAVE_IMAGE_AUTO_SAVE_SETTING, async (event, value) => await setting.SaveImageAutoSaveSetting(value));
// 获取当前的自动保存图片的设置
ipcMain.handle(DEFINE_STRING.GET_IMAGE_AUTO_SAVE_SETTING, async (event) => await setting.GetImageAutoSaveSetting());
// 开始手动保存图片
ipcMain.handle(DEFINE_STRING.SAVE_IMAGE_TO_OTHER_FOLDER, async (event, value) => await setting.SaveImageToOtherFolder(value));
// 检查机器码是否存在
ipcMain.handle(DEFINE_STRING.CHECK_MACHINE_ID, async (event, value) => await setting.CheckMachineId(value));
//修改剪映草稿配置
ipcMain.handle(DEFINE_STRING.MODIFY_SAMPLE_SETTING, async (event, value) => await setting.ModifySampleSetting(value));
// 获取选择角色场景模式的options
ipcMain.handle(DEFINE_STRING.MJ.GET_TAG_SELECT_MODEL, async (event) => await setting.GetRoleSceneModeOptions());
// 获取当前生成图片的生图方式sd,mj,d3
ipcMain.handle(DEFINE_STRING.GET_IMAGE_GENERATE_CATEGORY, async (event) => await setting.GetImageGenerateCategory());
// // 获取指定的配置文件里面指定的属性的数据
ipcMain.handle(DEFINE_STRING.GET_DEFINE_CONFIG_JSON_BY_PROPERTY, async (event, value) => await setting.GetDefineConfigJsonByProperty(value))
// // 保存指定的配置文件里面指定的属性的数据
ipcMain.handle(DEFINE_STRING.SAVE_DEFINE_CONFIG_JSON_BY_PROPERTY, async (event, value) => await setting.SaveDefineConfigJsonByProperty(value))
}
export {
SettingIpc
}

View File

@ -0,0 +1,28 @@
import {
ipcMain
} from "electron";
import { DEFINE_STRING } from '../../define/define_string'
import {
Writing
} from '../backPrompt/writing'
let writing = new Writing(global);
function WritingIpc() {
// 监听分镜时间的保存
ipcMain.handle(DEFINE_STRING.SAVE_COPYWRITING_INFOMATION, async (event, value) => await writing.SaveCopywritingInformation(value));
// 监听获取当前项目下面的分镜文案
ipcMain.handle(DEFINE_STRING.GET_PROJECT_WORD, async (event, value) => await writing.GetProjectWord());
// 获取config配置文件数据
ipcMain.handle(DEFINE_STRING.GET_CONFIG_JSON, async (event, value) => await writing.GetConfigJson(value));
// 将指定的文案txt数组写入到指定的文件中
ipcMain.handle(DEFINE_STRING.SAVE_WORD_TXT, async (event, value) => await writing.SaveWordTxt(value));
// 监听获取字幕时间
ipcMain.handle(DEFINE_STRING.IMPORT_SRT_AND_GET_TIME, async (event, value) => await writing.ImportSrtAndGetTime(value))
}
export {
WritingIpc
}

View File

@ -0,0 +1,33 @@
import { TagDefine } from "../../define/tagDefine";
export class TagCustomize {
constructor(global) {
this.global = global;
this.tagDefine = new TagDefine(global);
}
/**
* 获取默认的tag
* @param {*} value
*/
async GetTagDataByTypeAndProperty(value) {
return await this.tagDefine.getTagDataByTypeAndProperty(value[0], value[1]);
}
/**
* 保存数据到指定的tag中
* @param {*} value
* @returns
*/
async SaveTagPropertyData(value) {
return await this.tagDefine.saveTagPropertyData(value);
}
/**
* 删除指定的tag数据
* @param {*} value
* @returns
*/
async DeleteTagPropertyData(value) {
return await this.tagDefine.deleteTagPropertyData(value);
}
}

View File

@ -0,0 +1,493 @@
import { Tools } from "../tools";
import path from "path";
import { DEFINE_STRING } from "../../define/define_string";
import { define } from "../../define/define";
import { PublicMethod } from "../Public/publicMethod";
import { SD } from "../Public/SD"
const util = require('util');
const { spawn, exec } = require('child_process');
import axios from "axios";
const sharp = require('sharp');
const execAsync = util.promisify(exec);
const { v4: uuidv4 } = require('uuid'); // 引入UUID库来生成唯一标识符
let fspromises = require("fs").promises;
import { MD5 } from "crypto-js";
import { ImageSetting } from "../../define/setting/imageSetting";
export class ImageGenerate {
constructor(global) {
this.global = global;
this.tools = new Tools();
this.pm = new PublicMethod(global);
this.sd = new SD(global);
}
/**
* 获取指定名称的提示词json文件数据
* @param {*} value
*/
async GetPromptJson(value) {
try {
let json_path = path.join(this.global.config.project_path, "tmp/input_crop/" + value + ".json");
let isExist = await this.tools.checkExists(json_path);
if (!isExist) {
throw new Error("提示词文件不存在");
}
let res = JSON.parse(await fspromises.readFile(json_path, 'utf-8'));
return {
value: 1,
data: res
}
} catch (error) {
return {
code: 0,
message: error.toString()
}
}
}
/**
* 修改指定任务队列的状态
* @param {*} value 0 使用什么查找idout_folder, 1查找的值 2 状态值
* @returns
*/
async ModifyGenerateTaskStatus(value) {
try {
await this.pm.ModifyTaskStatus(value[0], value[1], value[2]);
return {
code: 1
}
} catch (error) {
return {
code: 0,
message: error.toString()
}
}
}
/**
* 修改本地的参数
* @param {修改json的参数} value
*/
async ModifyInpurCropJson(value) {
try {
value = JSON.parse(value);
let prompt = value.prompt;
// 重绘幅度
let denoising_strength = value.denoising_strength;
let json_path = path.join(path.join(global.config.project_path, 'tmp/input_crop'), value.name + ".json");
let old_json = JSON.parse(await fspromises.readFile(json_path, 'utf-8'));
old_json.webui_config.prompt = prompt;
old_json.webui_config.denoising_strength = denoising_strength;
old_json.model = value.model;
old_json.adetailer = value.adetailer;
old_json.chinese_prompt = value.chinese_prompt;
if (value.modify_old) {
old_json.webui_config.init_images = value.modify_old;
}
await fspromises.writeFile(json_path, JSON.stringify(old_json));
return {
code: 1
}
} catch (error) {
throw new Error(error);
}
}
/**
* 返回文件夹里的所有的图片以及其他信息
* @param {图片文件夹} value
* @returns
*/
async getFolderImageList(mainWindow, value, isReturn) {
try {
let img_dir = path.normalize(value);
let base_name = path.basename(img_dir);
let tmp = path.dirname(img_dir);
let input_path = path.join(tmp, "input_crop")
// console.log(tmp, input_path)
let files = await fspromises.readdir(img_dir)
let imageFiles = files.filter(file => /\.(png)$/i.test(file));
imageFiles.sort();
let res = [];
let task_list_json = JSON.parse(await fspromises.readFile(path.join(this.global.config.project_path, 'scripts/task_list.json'), 'utf-8'));
// 处理数据
for (let i = 0; i < imageFiles.length; i++) {
const img = imageFiles[i];
let imput_path = path.join(input_path, img);
let img_json = path.join(input_path, img + '.json');
// 判断文件是不是存在
let prompt_json = JSON.parse(await fspromises.readFile(img_json));
let output_list = await this.pm.getSubFolderList(path.join(this.global.config.project_path, "tmp"), 'start', 'output_crop');
let output_image_list = [];
for (let i = 0; i < output_list.length; i++) {
const item = output_list[i];
// 找到找到文件对应的任务列表的样式和lora
let task_list = task_list_json.task_list.filter(a => a.out_folder == item);
let output_1 = path.join(tmp, item);
let obj = {
id: uuidv4(),
img_path: path.join(output_1, img),
image_style: task_list[0].image_style,
lora: task_list[0].lora
}
output_image_list.push(obj);
}
let main_task_list = task_list_json.task_list.filter(a => a.out_folder == base_name);
let obj = {
name: img,
id: uuidv4(),
sampler_name: prompt_json.webui_config.sampler_name,
prompt: prompt_json.webui_config.prompt,
chinese_prompt: prompt_json.chinese_prompt,
negative_prompt: prompt_json.webui_config.negative_prompt,
denoising_strength: prompt_json.webui_config.denoising_strength,
seed: prompt_json.webui_config.seed,
image: path.join(img_dir, img),
oldImage: prompt_json.webui_config.init_images,
output_list: output_image_list,
model: prompt_json.model,
image_style: main_task_list[0].image_style,
lora: main_task_list[0].lora,
image_style_list: main_task_list[0].image_style_list,
adetailer: prompt_json.adetailer,
width: prompt_json.webui_config.width,
height: prompt_json.webui_config.height
}
res.push(obj)
// 获取提示词
}
if (isReturn) {
return {
code: 1,
windowID: mainWindow.id,
value: res
}
} else {
mainWindow.webContents.send(DEFINE_STRING.RETURN_IMAGE_PROMPT, {
code: 1,
windowID: mainWindow.id,
value: res
})
}
} catch (error) {
return {
code: 0,
message: `Error message ${error.toString()}`
}
}
}
/**
* 将反推的图片的信息添加到一个json文件中
*/
async AddWebuiJson() {
try {
return await this.pm.AddWebuiJson();
} catch (error) {
return {
code: 0,
message: error.toString()
}
}
}
/**
* 修改任务队列数据
* @param {替换后的值} value
*/
async ModifyImageTaskList(value) {
try {
let res = await this.pm.ModifyImageTaskList(value);
if (res) {
return {
code: 1,
message: "替换成功"
}
}
} catch (error) {
return {
code: 0,
message: error.toString()
}
}
}
/**
* 获取生成图片的任务队列可以添加部分判断
*/
async GetGenerateTaskList() {
try {
return await this.pm.GetImageTask()
} catch (error) {
return {
code: 0,
message: error.message
}
}
}
/**
* 生成任务中的队列
* @param {传入所有执行生图队列的任务} value
*/
async GenerateImageInSelectTask(value) {
try {
let batch = DEFINE_STRING.QUEUE_BATCH.SD_BACKSTEP_GENERATE_IMAGE
let taskPath = path.join(this.global.config.project_path, 'scripts/task_list.json');
let task_list_json = JSON.parse(await fspromises.readFile(taskPath, 'utf-8'));
let auto_save_image = await this.tools.getJsonFilePropertyValue(define.img_base, "auto_save_image", {}, false);
let png_files = [];
// 读取队列中的任务,然后添加队列
for (let i = 0; i < value.length; i++) {
const element = value[i];
let task_list = task_list_json.task_list.filter(item => item.id == element)[0];
let seed = -1;
let images = await this.tools.getFilesWithExtensions(path.join(this.global.config.project_path, 'tmp/input_crop'), '.png');
await fspromises.mkdir(path.join(this.global.config.project_path, 'tmp/' + task_list.out_folder), { recursive: true });
if (images.length <= 0) {
throw new Error("未检测到抽帧图片。请检查");
}
if (images.length > auto_save_image.save_match_count) {
png_files = await this.tools.getFilesWithExtensions(auto_save_image.main_save_folder, '.png');
}
this.global.requestQuene.enqueue(async () => {
let res = await this.sd.OneImageGeneration(images[0], task_list, seed);
let tmp_seed = -1;
if (seed == -1) {
tmp_seed = res;
}
for (let j = 1; j < images.length; j++) {
const item = images[j];
let has_permission = false;
// 判断权限
let permission = this.global.permission;
if (permission && permission.length >= 0) {
if (permission.indexOf(DEFINE_STRING.PERMISSIONS.AUTO_SAVE_IMAGE_PERMISSION) >= 0) {
has_permission = true;
}
} else {
has_permission = true;
}
if (auto_save_image.save_match_count && j >= auto_save_image.save_match_count && has_permission && auto_save_image.auto_match) {
// 现在随机匹配视频
// 获取指定的文件夹中的图片
let randomData = png_files[Math.floor(Math.random() * png_files.length)];
let base_name = path.basename(item);
let copy_path = path.join(this.global.config.project_path, 'tmp/' + task_list.out_folder, base_name);
await this.tools.copyFileOrDirectory(randomData, copy_path);
} else {
this.global.requestQuene.enqueue(async () => {
await this.sd.OneImageGeneration(item, task_list, tmp_seed);
}, `${task_list.out_folder}_${images[j]}`, batch, task_list.out_folder)
}
}
}, `${task_list.out_folder}_${images[0]}`, batch, task_list.out_folder)
// }
task_list.status = 'queue';
// 开始批次执行(全部刷新)
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.IMAGE_TASK_STATUS_REFRESH, task_list);
// 判断是不是还有批次执行的任务
// 监听子批次完成(修改当前批次的状态)
this.global.requestQuene.setSubBatchCompletionCallback(batch, task_list.out_folder, async (failedTasks) => {
console.log(failedTasks)
if (failedTasks.length > 0) {
} else {
// 判断是不是有错误。没有错误的话。直接修改状态。有错误直接记录错误(写入一个就行)
task_list_json = JSON.parse(await fspromises.readFile(taskPath, 'utf-8'));
// 全部执行完毕之后,修改
task_list_json.task_list.map(a => {
if (a.out_folder == task_list.out_folder) {
a.status = "ok";
}
})
// 写入
await fspromises.writeFile(taskPath, JSON.stringify(task_list_json));
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.IMAGE_TASK_STATUS_REFRESH, {
out_folder: task_list.out_folder,
status: "ok"
});
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.VIDEO_GENERATE_STATUS_REFRESH, {
out_folder: task_list.out_folder,
status: "ok"
})
}
})
}
// 监听总批次完成
this.global.requestQuene.setBatchCompletionCallback(batch, (failedTasks) => {
if (failedTasks.length > 0) {
let message = `
批次生成任务都已完成
但是以下任务执行失败
`
failedTasks.forEach(({ taskId, error }) => {
message += `${taskId}-, \n 错误信息: ${error}` + '\n';
});
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, {
code: 0,
message: message
})
} else {
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, {
code: 1,
message: "所有生成任务完成"
})
}
})
// 写回
await fspromises.writeFile(taskPath, JSON.stringify(task_list_json));
return {
code: 1,
}
} catch (error) {
return {
code: 0,
message: error.toString()
}
}
}
/**
* 批量高清文件夹
* @param {项目下面的文件夹的值} value
*/
async ImproveResolution(value) {
try {
let batch = DEFINE_STRING.QUEUE_BATCH.LOCAL_IMAGE_IMPROVE;
// 加入队列
for (let i = 0; i < value.length; i++) {
const folder = value[i];
this.global.requestQuene.enqueue(async () => {
await this.pm.ImproveFolder(folder);
}, folder, batch)
// 添加队列后修改状态
await this.pm.ModifyTaskStatus('out_folder', folder, "video_improving");
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.VIDEO_GENERATE_STATUS_REFRESH, {
out_folder: folder,
status: "video_improving"
})
}
global.requestQuene.setBatchCompletionCallback(batch, async (failedTasks) => {
let permission = this.global.permission;
// 判断权限
if (permission && permission.length >= 0) {
if (permission.indexOf(DEFINE_STRING.PERMISSIONS.AUTO_SAVE_IMAGE_PERMISSION) >= 0) {
// 在高清前,先将要高清的图片保存
let res = await ImageSetting.SaveImageToOtherFolder(value, null);
if (res.code == 0) {
return res;
}
}
} else {
// 在高清前,先将要高清的图片保存
let res = await ImageSetting.SaveImageToOtherFolder(value, null);
if (res.code == 0) {
return res;
}
}
if (failedTasks.length > 0) {
let message = `
高清任务都已完成
但是以下任务执行失败
`
failedTasks.forEach(({ taskId, error }) => {
message += `${taskId}-, \n 错误信息: ${error}` + '\n';
});
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, {
code: 0,
message: message
})
} else {
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, {
code: 1,
message: "所有任务高清完成"
})
}
})
return {
code: 1
}
} catch (error) {
return {
code: 0,
message: error.toString()
}
}
}
/**
* 下载文件到指定位置
* @param {*} value 0: 源图片地址 1: 类型 2: 目标文件地址
*/
async DownloadImageFile(value) {
try {
let type = value[1];
let img_file = value[0];
let target_file = value[2];
if (type == "cover") {
// 下载封面
// 判断封面是不是存在
let cover_path = path.join(this.global.config.project_path, 'data/封面');
let isExist = await this.tools.checkExists(cover_path);
if (!isExist) {
await fspromises.mkdir(cover_path, { recursive: true });
}
// 复制
await fspromises.copyFile(img_file, path.join(cover_path, Date.now() + '.png'));
return {
code: 1,
message: "保存成功!"
}
} else if (type == "replace") {
if (!target_file) {
throw new Error("目标文件地址不存在");
}
await fspromises.copyFile(path.normalize(decodeURIComponent(img_file)), path.normalize(decodeURIComponent(target_file)));
await this.tools.copyFileOrDirectory(decodeURIComponent(img_file), decodeURIComponent(target_file).replace("output_crop_1", "input_crop"));
return {
code: 1,
}
}
else {
return {
code: 0,
message: "参数错误"
}
}
} catch (error) {
return {
code: 0,
message: error.toString()
}
}
}
}

View File

@ -0,0 +1,556 @@
import path from "path";
import { define } from "../../define/define";
import { Tools } from "../tools";
import { PublicMethod } from "../Public/publicMethod";
import { func } from '../func'
import { DEFINE_STRING } from "../../define/define_string";
const util = require('util');
const { spawn, exec } = require('child_process');
const execAsync = util.promisify(exec);
const fspromises = require("fs").promises;
import { SD } from "../Public/SD"
export class VideoGenerate {
constructor(global) {
this.global = global;
this.tools = new Tools();
this.pm = new PublicMethod(global);
this.sd = new SD(global);
}
/**
* 获取之前的基础配置
*/
async GetVideoGenerateConfig() {
try {
let res = await this.tools.getJsonFilePropertyValue(path.join(this.global.config.project_path, "scripts/config.json"), "video_config", {}, false);
return {
code: 1,
data: res
}
} catch (error) {
return {
code: 0,
message: error.toString()
}
}
}
/**
* 保存合成视频的基础信息Srtaudiobackground
* @param {*} value 保存合成视频的基础信息Srtaudiobackground
*/
async SaveVideoSrtAndAudioMessage(value) {
try {
value = JSON.parse(value);
await this.tools.writeJsonFilePropertyValue(path.join(this.global.config.project_path, "scripts/config.json"), "video_config", value);
return {
code: 1
}
} catch (error) {
return {
code: 0,
message: error.toString()
}
}
}
/**
*全自动合成视频的任务出图高清合成视频
* @param {传入的需要执行的task_list的任务} value
*/
async ActionAutoVideoTask(value) {
try {
// 开始添加队列任务
// 生图
// 将当前的所有任务添加到队列中
await this.pm.AddWebuiJson();
let batch = DEFINE_STRING.QUEUE_BATCH.AUTO_VIDEO_GENERATE;
let taskPath = path.join(this.global.config.project_path, "scripts/task_list.json");
// // 修改数据保存srt字幕文件位置。配音文件位置。背景音乐文件
// this.global.fileQueue.enqueue(async () => {
// let config_json = JSON.parse(await fspromises.readFile(path.join(this.global.config.project_path, "scripts/config.json"), 'utf-8'));
// config_json.srt_path = value[1].srt_path;
// config_json.audio_path = value[1].audio_path;
// config_json.background_music = value[1].background_music;
// await fspromises.writeFile(path.join(this.global.config.project_path, "scripts/config.json"), JSON.stringify(config_json));
// })
await this.tools.writeJsonFilePropertyValue(path.join(this.global.config.project_path, "scripts/config.json"), "video_config", value[1]);
// 便利所有的队列任务
for (let i = 0; i < value[0].length; i++) {
// 将所有的数据天添加到队列(总的大队列,有很多的小队列)
// 将所有生图任务添加到队列中
const task_list = value[0][i];
let seed = -1;
let subBatchId = `${task_list.out_folder}_image`
let images = await this.tools.getFilesWithExtensions(path.join(this.global.config.project_path, 'tmp/input_crop'), '.png');
await fspromises.mkdir(path.join(this.global.config.project_path, 'tmp/' + task_list.out_folder), { recursive: true });
if (images.length <= 0) {
throw new Error("未检测到抽帧图片。请检查");
}
this.global.requestQuene.enqueue(async () => {
let res = await this.sd.OneImageGeneration(images[0], task_list, seed);
let tmp_seed = -1;
if (seed == -1) {
tmp_seed = res;
}
for (let j = 1; j < images.length; j++) {
const element = images[j];
this.global.requestQuene.enqueue(async () => {
await this.sd.OneImageGeneration(element, task_list, tmp_seed);
}, `${task_list.out_folder}_${images[j]}`, batch, subBatchId)
}
}, `${task_list.out_folder}_${images[0]}`, batch, subBatchId)
// }
task_list.status = 'queue';
task_list["isAuto"] = "true";
await this.pm.ModifyImageTaskList([task_list]);
// 修改状态
// await this.pm.ModifyTaskStatus("id", task_list.id, "queue");
// this.global.fileQueue.enqueue(async () => {
// let task_json = JSON.parse(await fspromises.readFile(taskPath, 'utf-8'));
// let index = task_json.task_list.findIndex(item => item.id == task_list.id);
// task_json.task_list[index] = task_list;
// await fspromises.writeFile(taskPath, JSON.stringify(task_json));
// })
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.VIDEO_GENERATE_STATUS_REFRESH, task_list)
// 判断是不是还有批次执行的任务
// 监听子批次完成(修改当前批次的状态)
this.global.requestQuene.setSubBatchCompletionCallback(batch, subBatchId, async (failedTasks) => {
console.log(failedTasks)
if (failedTasks.length > 0) {
// 之前的任务出现错误
// 执行错误
} else {
// 判断是不是有错误。没有错误的话。直接修改状态。有错误直接记录错误(写入一个就行)
task_list.status = "ok";
await this.pm.ModifyTaskStatus("id", task_list.id, 'ok');
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.VIDEO_GENERATE_STATUS_REFRESH, task_list)
console.log(subBatchId + "生图执行完毕。可以开始执行高清")
// 添加高清队列
// task_list
this.global.requestQuene.enqueue(async () => {
await this.pm.ImproveFolder(task_list.out_folder);
}, `${task_list.out_folder}_improve`, batch, `${task_list.out_folder}_improve`);
// 添加队列后修改状态
task_list.status = "video_improving"
await this.pm.ModifyTaskStatus('out_folder', task_list.out_folder, "video_improving");
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.VIDEO_GENERATE_STATUS_REFRESH, task_list)
// 监听高清任务完成
this.global.requestQuene.setSubBatchCompletionCallback(batch, `${task_list.out_folder}_improve`, async (failedTasks) => {
console.log(failedTasks)
if (failedTasks.length > 0) {
// 之前的任务出现错误
// 执行错误
} else {
console.log(task_list.out_folder + "高清完成,可以开始合成视频");
// 添加生成视频队列
this.global.requestQuene.enqueue(async () => {
let video_config = JSON.parse(await fspromises.readFile(define.video_config, 'utf-8'));
await this.AutoGeneretionOneVide(task_list.out_folder, video_config, value);
}, `${task_list.out_folder}_video`, batch, `${task_list.out_folder}_video`);
task_list.status = "video_queue";
// 添加后修改状态
await this.pm.ModifyTaskStatus('out_folder', task_list.out_folder, "video_queue");
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.VIDEO_GENERATE_STATUS_REFRESH, task_list)
// 监听生成视频任务完成
this.global.requestQuene.setSubBatchCompletionCallback(batch, `${task_list.out_folder}_video`, async (failedTasks) => {
console.log(failedTasks)
if (failedTasks.length > 0) {
// 之前的任务出现错误
// 执行错误
} else {
console.log(task_list.out_folder + "合成视频完成");
// 添加生成视频队列
task_list.status = "video_ok";
// 添加后修改状态
await this.pm.ModifyTaskStatus('out_folder', task_list.out_folder, "video_ok");
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.VIDEO_GENERATE_STATUS_REFRESH, task_list)
}
})
}
})
}
})
}
// 监听总批次完成
this.global.requestQuene.setBatchCompletionCallback(batch, async (failedTasks) => {
if (failedTasks.length > 0) {
let message = `
批次生成任务都已完成
但是以下任务执行失败
`
failedTasks.forEach(({ taskId, error }) => {
message += `${taskId}-, \n 错误信息: ${error}` + '\n';
});
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, {
code: 0,
message: message
})
} else {
console.log("所有的自动生成任务完成");
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, {
code: 1,
message: "所有自动任务完成"
})
}
this.global.fileQueue.enqueue(async () => {
// 读取最新的数据删除
// 将自动化标识删除
let task_json = JSON.parse(await fspromises.readFile(taskPath, 'utf-8'));
for (let i = 0; i < task_json.task_list.length; i++) {
let task_list = task_json.task_list[i];
task_list["isAuto"] = "false";
await this.pm.ModifyImageTaskList([task_list]);
}
})
})
return {
code: 1,
message: "自动任务添加到队列中"
}
} catch (error) {
console.error(error)
return {
code: 0,
message: error.message
}
}
}
/**
* 获取文件夹下面的子文件夹添加判断条件
* @param {value} value
* @returns
*/
async getSubFolderList(value) {
try {
let folder = await this.pm.getSubFolderList(path.join(this.global.config.project_path, "tmp"), value[0], value[1]);
// 找到所有的数据(查询状态返回)
let task_path = path.join(this.global.config.project_path, "scripts/task_list.json");
let isExist = await this.tools.checkExists(task_path);
let data = [];
if (!isExist) {
for (let i = 0; i < folder.length; i++) {
const element = folder[i];
let obj = {
folder: element,
status: "unkown error"
}
data.push(obj);
}
} else {
let task_list = JSON.parse(await fspromises.readFile(task_path, 'utf-8'))["task_list"];
// 查询状态
for (let i = 0; i < folder.length; i++) {
const element = folder[i];
let index = task_list.findIndex(item => item.out_folder == element);
if (index < 0) {
let obj = {
folder: element,
status: "unkown error"
}
data.push(obj);
} else {
let status = task_list[index].status;
let obj = {
folder: element,
status: status
}
data.push(obj);
}
}
}
return {
code: 1,
data: data
}
} catch (error) {
return {
code: 0,
message: `Error Message ${error}`
}
}
}
/**
* 自动生成一个视频
* @param {视频生成图片的文件夹} element
* @param {视频配置} video_config
* @param {参数第一个值为数组为生成的图片文件第二个参数是配置} value
*/
async AutoGeneretionOneVide(element, video_config, value) {
try {
let background_music = "";
// 读取背景音乐的路径
if (value[1].background_music != "") {
let background_music_config = (await func.getClipSetting("background_music_setting")).value;
let background_music_filter = background_music_config.filter(item => item.id == value[1].background_music);
if (background_music_filter.length <= 0) {
throw new Error("背景音乐对应的配置没有找到");
} else {
background_music = background_music_filter[0].folder_path;
}
}
// 随机获取字幕设置
let ass_config = video_config.assConfig;
let ass_random_index = Math.floor(Math.random() * ass_config.length);
let watermark_config = video_config.watermarkConfig;
let watermark_random_index = Math.floor(Math.random() * watermark_config.length);
// 对每个视频生成配置文件并将其添加到配置文件中
let obj = {
srt_path: value[1].srt_path,
// 字幕样式(需要随机)
srt_style: ass_config[ass_random_index],
audio_path: value[1].audio_path,
background_music_folder: background_music,
// 水印设置(需要随机)
friendly_reminder: watermark_config[watermark_random_index],
video_resolution_x: video_config.video_resolution_x,
video_resolution_y: video_config.video_resolution_y,
outpue_file: path.join(this.global.config.project_path, this.global.config.project_name + element + ".mp4"),
image_folder: path.join(this.global.config.project_path, 'tmp/' + element),
srt_config: path.join(this.global.config.project_path, 'scripts/config.json'),
mp4_file_txt: path.join(this.global.config.project_path, `scripts/${element}.txt`),
status: "no",
audio_sound_size: video_config.audioSoundSize,
background_music_sound_size: video_config.backgroundMusicSoundSize,
keyFrame: video_config.keyframe,
frameRate: video_config.frameRate,
bitRate: video_config.bitRate
}
// 将配置文件写入
let project_config_path = path.join(this.global.config.project_path, `scripts/${element}.json`);
await fspromises.writeFile(project_config_path, JSON.stringify(obj));
// let task_list = JSON.parse(await fspromises.readFile(path.join(this.global.config.project_path,'scripts/task_')));
let scriptPath = path.join(define.scripts_path, 'Lai.exe');
// 执行生成图片的脚本
let script = `cd "${define.scripts_path}" && "${scriptPath}" -c "${project_config_path.replaceAll('\\', '/')}"`;
const output = await execAsync(script, { maxBuffer: 1024 * 1024 * 10, encoding: 'utf-8' });
if (output.stderr != '') {
obj.status = "video_error";
obj.stdout = output.stdout;
obj.stderr = output.stderr;
await this.pm.ModifyTaskStatus('out_folder', element, "video_error");
throw new Error(output.stderr);
} else {
obj.status = "video_ok";
obj.stdout = output.stdout;
obj.stderr = output.stderr;
await this.pm.ModifyTaskStatus('out_folder', element, "video_ok");
// 将写出的视频中的exif数据删除
// await this.tools.deletePngAndDeleteExifData(obj.outpue_file, path.join(this.global.config.project_path, this.global.config.project_name + "_" + element.split('_')[element.split('_').length - 1] + ".mp4"));
}
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.VIDEO_GENERATE_STATUS_REFRESH, {
out_folder: element,
status: obj.status
})
} catch (error) {
//手动修改
let task_list_json = JSON.parse(await fspromises.readFile(path.join(this.global.config.project_path, "scripts/task_list.json"), 'utf-8'));
let index = task_list_json.task_list.findIndex(item => item.out_folder == element);
if (index < 0) {
throw new Error("未找到对应的任务");
}
task_list_json.task_list[index].status = "video_error";
task_list_json.task_list[index].errorMessage = error.toString();
// 写回
await fspromises.writeFile(path.join(this.global.config.project_path, "scripts/task_list.json"), JSON.stringify(task_list_json));
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.VIDEO_GENERATE_STATUS_REFRESH, {
out_folder: element,
status: "video_error"
})
throw error;
}
}
/**
* 添加自动合成任务到队列中去
* @param {} value
*/
async AutoGeneretionVideo(value) {
try {
// 先检查所有的条件
let batch = DEFINE_STRING.QUEUE_BATCH.AUTO_VIDEO_GENERATE_SINGLE;
// console.log(value);
let video_config = JSON.parse(await fspromises.readFile(define.video_config, 'utf-8'));
let res = await this.CheckVideoGenerattionAllCondition(video_config, value[1], value[0]);
if (res.code == 0) {
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, res);
return res;
}
for (let i = 0; i < value[0].length; i++) {
const element = value[0][i];
this.global.requestQuene.enqueue(async () => {
await this.AutoGeneretionOneVide(element, video_config, value)
}, element, batch);
// 添加队列后修改状态
await this.pm.ModifyTaskStatus('out_folder', element, "video_queue");
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.VIDEO_GENERATE_STATUS_REFRESH, {
out_folder: element,
status: "video_queue"
})
}
this.global.requestQuene.setBatchCompletionCallback(batch, (failedTasks) => {
if (failedTasks.length > 0) {
let message = `
生成视频任务都已完成
但是以下任务执行失败
`
failedTasks.forEach(({ taskId, error }) => {
message += `${taskId}-, \n 错误信息: ${error}` + '\n';
});
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, {
code: 0,
message: message
})
} else {
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, {
code: 1,
message: "所有生成视频任务已完成"
})
}
})
return {
code: 1
}
} catch (error) {
return {
code: 0,
message: error.toString()
}
}
}
/**
* 检测生成视频条件的必要条件
* @param {生成视频配置文件} video_config
* @param {生成视频的基础配置} simpleData
* @param {输出文件夹位置为null检查input文件里面的图片文件是不是和配置文件中的图片数量一致} out_folder
* @returns
*/
async CheckVideoGenerattionAllCondition(video_config, simpleData, out_folder) {
let message = "";
if (video_config == null) {
video_config = JSON.parse(await fspromises.readFile(define.video_config, 'utf-8'));
}
// 基础信息检测
if (video_config.audioSoundSize == null) {
message += "配音大小不能为空" + '\n';
}
if (video_config.backgroundMusicSoundSize == null) {
message += "背景音乐音量大学不能为空" + '\n';
}
if (video_config.video_resolution_x == null) {
message += "生成视频的宽度不能为空" + '\n';
}
if (video_config.video_resolution_y == null) {
message += "生成视频的高度不能为空" + '\r\n';
}
if (video_config.offsetValue == null) {
message += "视频的上下偏移量不能为空" + '\n';
}
if (video_config.frameRate == null) {
message += "生成视频的帧率不能为空" + '\n';
}
if (video_config.bitRate == null) {
message += "生成视频码率的不能为空" + '\n';
}
// 判断字幕列表中是不是有数据
if (video_config.assConfig == null || video_config.assConfig.length <= 0) {
message += "字幕设置最少包含一条" + '\n';
}
if (video_config.watermarkConfig == null || video_config.watermarkConfig.length <= 0) {
message += "水印设置最少包含一条" + '\n';
}
// 判断背景音乐文件夹中是不是存在。并且检查其中是不是有音乐文件
if (simpleData.background_music == "") {
message += "背景音乐文件夹路径不能为空" + '\n';
}
// 判断背景音乐文件夹是不是存在
if (await this.tools.checkExists(simpleData.background_music)) {
message += "背景音乐文件夹不存在" + '\n';
}
// 判断里面是不是有MP3或者是wav
let clip_json = JSON.parse(await fspromises.readFile(define.clip_setting, 'utf-8'))["background_music_setting"];
let background_music_obj = clip_json.filter(item => item.id == simpleData.background_music)[0];
let mp3_file = await this.tools.getFilesWithExtensions(background_music_obj.folder_path, '.mp3');
let wav_file = await this.tools.getFilesWithExtensions(background_music_obj.folder_path, '.wav');
if (mp3_file.length <= 0 && wav_file.length <= 0) {
message += "背景文件夹中没有 MP3 或 WAV 文件" + '\n';
}
let config_path = path.join(this.global.config.project_path, 'scripts/config.json');
let isE = await this.tools.checkExists(config_path);
if (!isE) {
message += "配置文件不存在。请先导入字幕文件。并调整时间轴。"
} else {
// 判断文案时间信息和图片信息是不是相同
let config_json = JSON.parse(await fspromises.readFile(config_path, 'utf-8'));
let len = config_json["srt_time_information"].length;
if (out_folder == null) {
// 判断输入文件中的配置文件中的数量是不是对上
let img_l = await this.tools.getFilesWithExtensions(path.join(this.global.config.project_path, "tmp/input_crop"), '.png');
if (img_l.length != len) {
message += `input_crop 文件里面图片和文案信息对不上。检查是不是图片数量不对`
}
// 判断是不是有tag文件
let tag_txt = await this.tools.getFilesWithExtensions(path.join(this.global.config.project_path, "tmp/input_crop"), '.txt');
let c_j = await this.tools.getFilesWithExtensions(path.join(this.global.config.project_path, "tmp/input_crop"), '.json');
if (tag_txt.length > 0) {
if (tag_txt.length != img_l.length) {
message += "反推的tag文件和图片的数量对不上。" + "\n";
}
} else if (c_j.length > 0) {
if (c_j.length != img_l.length) {
message += "已存在的配置文件和图片的数量对不上。" + "\n";
}
} else {
message += "好像没有反推呢" + "\n";
}
} else {
// 判断当前的输入的 out_folder 中图片数量是不是可以和配置文件中能否对上
for (let i = 0; i < out_folder.length; i++) {
const element = out_folder[i];
let image_l = await this.tools.getFilesWithExtensions(path.join(this.global.config.project_path, "tmp/" + element), '.png');
if (image_l.length != len) {
message += `${element} 文件里面图片和文案信息对不上。检查是不是图片数量不对`
}
}
}
}
if (message != '') {
let res = {
code: 0,
message: message
}
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, res)
return res;
}
return {
code: 1,
}
}
}

View File

@ -0,0 +1,301 @@
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()
}
}
}
}

View File

@ -0,0 +1,490 @@
const axios = require('axios');
// import { Midjourney as mApi} from "midjourney";
// const MJapi2 = require('midjourney');
// const { midjourney } = require('midjourney')
// const Midjourney = require('midjourney');
// ES5 的模块引入方式
const fetch = require("node-fetch");
// ES6 的模块引入方式
// import fetch from "node-fetch";
export class DiscordAPI {
constructor(mj_setting) {
// https://discord.com/api/v9/channels/1208362852482809939/messages?limit=20
this.apiClient = axios.create({
baseURL: 'https://discord.com'
});
this.DiscordBaseUrl = 'https://discord.com';
this.ServerId = mj_setting.serviceID;
this.ChannelId = mj_setting.channelID;
this.userToken = mj_setting.token;
this.botId = mj_setting.select_robot?.botId;
this.commandId = mj_setting.select_robot?.commandId;
this.versionId = mj_setting.select_robot?.versionId;
this.versionName = mj_setting.select_robot?.versionName;
this.botName = mj_setting.select_robot?.botName;
}
// 提交任务
async imagine(data) {
// let req_data = {
// "token": this.userToken,
// "method": "post",
// "api_url": "/mj/submit/imagine",
// "data":data
// }
// const response = await this.apiClient.post('/api/v3/req_mj_api', req_data);
// await this.interactions(data.prompt);
return await this.interactions(data.prompt)
// return {
// code:1,
// result:'taskid_'+new Date().getTime()
// }
// return response.data;
}
async channelList() {
axios.get(`https://discord.com/api/v9/channels/${this.ChannelId}/messages?limit=20`, {
method: 'get',
headers: {
"Authorization": this.userToken
}
})
.then(response => {
// 请求成功处理
console.log(typeof response.data);
let eList = []
let flg = false;
let job_id = '';
let type = '';
if (response && response.data) {
try {
response.data.forEach(element => {
flg = false;
type = '';
if (element.attachments && element.attachments.length) {
const arr = element.attachments[0].filename.split("_");
job_id = arr[arr.length - 1].replace(".png", '');
if (element.components) {
element.components.forEach(e2 => {
e2.components.forEach(e3 => {
if (e3.label == 'U1') {
flg = true;
type = 'U1'
} else if (e3.label && e3.label.indexOf('Upscale') > -1) {
flg = true;
type = 'Upscale'
}
})
});
}
let t = eList.find((e) => {
return e.filename == element.attachments[0].filename;
})
if (!t) {
eList.push(
{
flg: flg, job_id: job_id, filename: element.attachments[0].filename,
url: element.attachments[0].url,
proxy_url: element.attachments[0].proxy_url,
type: type,
timestamp: element.timestamp
})
}
// console.log({flg:flg,job_id:job_id,filename:element.attachments[0].filename})
} else {
console.log({ flg: flg })
}
});
} catch (error) {
console.log('异常2', error)
}
// console.log(eList)
// 8e7406df-bf0c-4e3d-8e49-b2bb8e2c263d
// 5abedc71-ba80-4756-8ddc-489c927d3acd
}
}).catch(error => {
// 请求失败处理
console.error(error);
});
}
// 混合
async blend(data) {
let req_data = {
"token": this.userToken,
"method": "post",
"api_url": "/mj/submit/blend",
"data": data
}
const response = await this.apiClient.post('/api/v3/req_mj_api', req_data);
return response.data;
}
// 反推
async describe(data) {
let req_data = {
"token": this.userToken,
"method": "post",
"api_url": "/mj/submit/describe",
"data": data
}
const response = await this.apiClient.post('/api/v3/req_mj_api', req_data);
return response.data;
}
// 获取任务
async getTaskId(task_id) {
let req_data = {
"token": this.userToken,
"method": "get",
"api_url": `/mj/task/${task_id}/fetch`,
"data": {}
}
const response = await this.apiClient.post('/api/v3/req_mj_api', req_data);
return response.data;
}
//获取seed
async imageSeed(task_id) {
let req_data = {
"token": this.userToken,
"method": "get",
"api_url": `/mj/task/${task_id}/image-seed`,
"data": {}
}
const response = await this.apiClient.post('/api/v3/req_mj_api', req_data);
return response.data;
}
//账号创建
async account_create(data) {
let req_data = {
"token": this.userToken,
"method": "post",
"api_url": '/mj/account/create',
"data": data
}
const response = await this.apiClient.post('/api/v3/req_mj_api', req_data, { timeout: 20000 });
return response.data;
}
//账号创建
async account_fetch(cid) {
let req_data = {
"token": this.userToken,
"method": "get",
"api_url": `/mj/account/${cid}/fetch`,
"data": {}
}
const response = await this.apiClient.post('/api/v3/req_mj_api', req_data);
return response.data;
}
//账号同步信息
async account_asyn_info(cid) {
let req_data = {
"token": this.userToken,
"method": "post",
"api_url": `/mj/account/${cid}/sync-info`,
"data": {}
}
const response = await this.apiClient.post('/api/v3/req_mj_api', req_data, { timeout: 20000 });
return response.data;
}
//账号删除信息
async account_del_info(cid) {
let req_data = {
"token": this.userToken,
"method": "delete",
"api_url": `/mj/account/${cid}/delete`,
"data": {}
}
const response = await this.apiClient.post('/api/v3/req_mj_api', req_data);
return response.data;
}
//执行动作
async action(data) {
let req_data = {
"token": this.userToken,
"method": "post",
"api_url": '/mj/submit/action',
"data": data
}
const response = await this.apiClient.post('/api/v3/req_mj_api', req_data);
return response.data;
}
// 确认弹窗
async modal(data) {
let req_data = {
"token": this.userToken,
"method": "post",
"api_url": '/mj/submit/modal',
"data": data
}
const response = await this.apiClient.post('/api/v3/req_mj_api', req_data);
return response.data;
}
async interactions(prompt) {
// 直接自己调用
prompt = prompt.trim();
// prompt = "4k,8k,best quality, masterpiece, woman, divorced, leaving fast-paced city life, serene expression, walking away from cityscape, bustling streets, entering tranquil countryside, peaceful surroundings, rejuvenating atmosphere, , --niji 5 --ar 4:3"
var payload = {};
if (this.botName == 'niji') {
payload = {
"type": 2,
"application_id": this.botId,
"guild_id": this.ServerId,
"channel_id": this.ChannelId,
"session_id": this.userToken,
"data": {
"version": this.versionId,
"id": this.commandId,
"name": "imagine",
"type": 1,
"options": [
{
"type": 3,
"name": "prompt",
"value": prompt
}
],
"application_command": {
"id": this.commandId,
"type": 1,
"application_id": this.botId,
"version": this.versionId,
"name": "imagine",
"description": "Create images with Midjourney",
"options": [
{
"type": 3,
"name": "prompt",
"description": "The prompt to imagine",
"required": true,
"description_localized": "The prompt to imagine",
"name_localized": "prompt"
}
],
"integration_types": [
0
],
"global_popularity_rank": 1,
"description_localized": "Create images with Midjourney",
"name_localized": "imagine"
},
"attachments": [
]
},
// "nonce": "1210857131343872000",
"analytics_location": "slash_ui"
}
} else {
payload = {
"type": 2,
// "application_id":"1022952195194359889",//niji
"application_id": this.botId,
"guild_id": this.ServerId,
"channel_id": this.ChannelId,
"session_id": this.userToken,
"data": {
"version": this.versionId,
"id": this.commandId,
"name": "imagine", "type": 1,
"options":
[{
"type": 3,
"name": "prompt",
"value": prompt
}],
"application_command": {
"id": this.commandId,
"type": 1,
"application_id": this.botId,
"version": this.versionId,
"name": "imagine",
"description": "Create images with Niji journey",
"options": [{ "type": 3, "name": "prompt", "description": "The prompt to imagine", "required": true, "description_localized": "The prompt to imagine", "name_localized": "prompt" }],
"integration_types": [0], "global_popularity_rank": 1, "description_localized": "Create images with Niji journey", "name_localized": "imagine"
},
"attachments": []
},
"analytics_location": "slash_ui"
}
}
let response = {
status: 200,
data: {}
};
try {
const headers = {
"Content-Type": "application/json",
Authorization: this.userToken,
};
await fetch(`${this.DiscordBaseUrl}/api/v9/interactions`, {
method: "POST",
body: JSON.stringify(payload),
headers: headers,
}).then(res => res.json()).then(res => {
response.data = res;
}).catch(e => {
console.error("请求失败了,详细信息:" + JSON.stringify(e));
response = {
status: 500,
data: JSON.stringify(e)
};
});
console.log('response结果')
console.log(response)
// if (response.status == 204) {
// //成功
// }
if (response.status >= 400) {
console.error("api.error.config", {
payload: JSON.stringify(payload)
});
}
return {
code: response.status,
response: response
};
}
catch (error) {
console.error(error);
return 500;
}
return;
const client = new Midjourney.Midjourney({
ServerId: this.ServerId,
ChannelId: this.ChannelId,
SalaiToken: this.userToken,
Debug: true,
fetch: fetch,
Ws: true, //enable ws is required for remix mode (and custom zoom)
});
await client.init();
console.log('mjmj_begin2', prompt);
// const prompt =
// "Christmas dinner with spaghetti with family in a cozy house, we see interior details , simple blue&white illustration";
//imagine
const Imagine = await client.Imagine(
prompt,
(uri, progress) => {
client.Close();
console.log("loading", uri, "progress", progress);
return
}
);
console.log(Imagine);
if (!Imagine) {
console.log("no message");
console.log('mjmj_end2')
return;
}
console.log('mjmj_end')
client.Close();
return
}
/**
* 获取频道内的机器人
* @returns 返回机器人列表
*/
async getBotList() {
try {
const headers = {
'Host': 'discord.com',
'Connection': 'keep-alive',
'authorization': this.userToken,
}
await fetch('https://discord.com/api/v9/guilds/1182523906855284826/application-command-index', {
method: 'GET',
headers: headers,
})
.then(response => {
response.json()
}
)
.then(data => {
console.log(data)
})
.catch(error => {
console.error('Error:', error)
})
} catch (error) {
throw new Error(error);
}
}
async getMjMsgList() {
// const headers = {
// "Content-Type": "application/json",
// Authorization:this.userToken,
// };
let response = {
status: 200,
data: {}
};
// // `https://discord.com/api/v9/channels/${mj_channelId}/messages?limit=10
// await fetch(`${this.DiscordBaseUrl}/api/v9/channels/${this.ChannelId}/messages?limit=50`, {
// method: "GET",
// headers: headers,
// }).then(res => res.json()).then(res => {
// response.data=res;
// }).catch(e => {
// console.error("请求失败了,详细信息:" + JSON.stringify(e));
// response ={
// status:500,
// data:JSON.stringify(e)
// };
// });
// console.log('getMjMsgList_response结果')
// // console.log(response)
// return response;
axios.get(`https://discord.com/api/v9/channels/${this.ChannelId}/messages?limit=20`, {
method: 'get',
headers: {
"Authorization": this.userToken
}
}).then(res => {
response.data = res;
}).catch(error => {
// 请求失败处理
console.error(error);
});
}
}

View File

@ -0,0 +1,28 @@
import { contextBridge, ipcRenderer } from 'electron'
import { DEFINE_STRING } from '../define/define_string.js';
// Custom APIs for renderer
let events = [];
const api = {
// 创建MJ消息
CreateMessage: (value) => ipcRenderer.send(DEFINE_STRING.DISCORD.CREATE_MESSAGE, value),
// MJ消息更新
UpdateMessage: (value) => ipcRenderer.send(DEFINE_STRING.DISCORD.UPDATE_MESSAGE, value),
// MJ消息删除
DeleteMessage: (value) => ipcRenderer.send(DEFINE_STRING.DISCORD.DELETE_MESSAGE, value),
}
// Use `contextBridge` APIs to expose Electron APIs to
// renderer only if context isolation is enabled, otherwise
// just add to the DOM global.
if (process.contextIsolated) {
try {
contextBridge.exposeInMainWorld('api', api)
} catch (error) {
console.error(error)
}
} else {
window.api = api
}