save changes
This commit is contained in:
@ -23,8 +23,8 @@
|
||||
},
|
||||
"3": {
|
||||
"inputs": {
|
||||
"width": 320,
|
||||
"height": 640,
|
||||
"width": 720,
|
||||
"height": 1280,
|
||||
"batch_size": 1
|
||||
},
|
||||
"class_type": "EmptySD3LatentImage",
|
||||
@ -34,7 +34,7 @@
|
||||
},
|
||||
"4": {
|
||||
"inputs": {
|
||||
"seed": 803508963683741,
|
||||
"seed": 844515265883614,
|
||||
"steps": 20,
|
||||
"cfg": 1,
|
||||
"sampler_name": "euler",
|
||||
@ -45,7 +45,7 @@
|
||||
0
|
||||
],
|
||||
"positive": [
|
||||
"18",
|
||||
"11",
|
||||
0
|
||||
],
|
||||
"negative": [
|
||||
@ -127,7 +127,7 @@
|
||||
},
|
||||
"11": {
|
||||
"inputs": {
|
||||
"strength": 0.20000000000000004,
|
||||
"strength": 0.6000000000000001,
|
||||
"conditioning": [
|
||||
"14",
|
||||
0
|
||||
@ -157,7 +157,7 @@
|
||||
},
|
||||
"13": {
|
||||
"inputs": {
|
||||
"image": "fd2dc3bbc879703b03abf892d4189667.jpg"
|
||||
"image": "7a103725df2576b79c7306f0d3050991.jpg"
|
||||
},
|
||||
"class_type": "LoadImage",
|
||||
"_meta": {
|
||||
@ -166,7 +166,7 @@
|
||||
},
|
||||
"14": {
|
||||
"inputs": {
|
||||
"text": "Ethereal realistic girl with flowing blue hair, glowing sparkles and stardust, elegant backless dress shimmering with cosmic light, dreamy profile pose, soft glowing skin, fantasy night atmosphere, luminous and magical aesthetic",
|
||||
"text": "scify movie scene",
|
||||
"clip": [
|
||||
"1",
|
||||
0
|
||||
@ -189,52 +189,5 @@
|
||||
"_meta": {
|
||||
"title": "Save Image"
|
||||
}
|
||||
},
|
||||
"16": {
|
||||
"inputs": {
|
||||
"image": "a09ee3d44fff05f20c88976555f8fa10.jpg"
|
||||
},
|
||||
"class_type": "LoadImage",
|
||||
"_meta": {
|
||||
"title": "Load Image 2"
|
||||
}
|
||||
},
|
||||
"17": {
|
||||
"inputs": {
|
||||
"crop": "center",
|
||||
"clip_vision": [
|
||||
"10",
|
||||
0
|
||||
],
|
||||
"image": [
|
||||
"16",
|
||||
0
|
||||
]
|
||||
},
|
||||
"class_type": "CLIPVisionEncode",
|
||||
"_meta": {
|
||||
"title": "CLIP Vision Encode"
|
||||
}
|
||||
},
|
||||
"18": {
|
||||
"inputs": {
|
||||
"strength": 0.20000000000000004,
|
||||
"conditioning": [
|
||||
"11",
|
||||
0
|
||||
],
|
||||
"style_model": [
|
||||
"8",
|
||||
0
|
||||
],
|
||||
"clip_vision_output": [
|
||||
"17",
|
||||
0
|
||||
]
|
||||
},
|
||||
"class_type": "ApplyStyleModelAdjust",
|
||||
"_meta": {
|
||||
"title": "Apply Style Model (Adjusted)"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -14,10 +14,10 @@ interface VideoRecord {
|
||||
}
|
||||
|
||||
const servers = [
|
||||
/*{
|
||||
{
|
||||
baseUrl: process.env.SERVER1_COMFY_BASE_URL,
|
||||
outputDir: process.env.SERVER1_COMFY_OUTPUT_DIR,
|
||||
},*/
|
||||
},
|
||||
{
|
||||
baseUrl: process.env.SERVER2_COMFY_BASE_URL,
|
||||
outputDir: process.env.SERVER2_COMFY_OUTPUT_DIR,
|
||||
@ -61,7 +61,7 @@ async function worker(server: any) {
|
||||
while (true) {
|
||||
await sleep(Math.random() * 3000); // Random delay
|
||||
const videosToProcess = (await query(
|
||||
"SELECT * FROM video WHERE (video_path IS NULL OR video_path = '') AND modified_at < '2025-08-22' LIMIT 1"
|
||||
"SELECT * FROM video WHERE (image_path IS NULL OR image_path = '') LIMIT 1"
|
||||
)) as any[];
|
||||
|
||||
if (videosToProcess.length === 0) {
|
||||
|
||||
@ -30,7 +30,7 @@ async function generateImage(
|
||||
workflow['13']['inputs']['image'] = imageName1;
|
||||
|
||||
// Set image name
|
||||
workflow['16']['inputs']['image'] = imageName2;
|
||||
//workflow['16']['inputs']['image'] = imageName2;
|
||||
|
||||
workflow['3']['inputs']['width'] = size.width;
|
||||
workflow['3']['inputs']['height'] = size.height;
|
||||
|
||||
@ -3043,7 +3043,7 @@
|
||||
},
|
||||
{
|
||||
"genre": "fantasy",
|
||||
"subGenre": "ddreamy room",
|
||||
"subGenre": "dreamy room",
|
||||
"pinIds": [
|
||||
"2533343538161690",
|
||||
"22236591907669199",
|
||||
@ -3645,6 +3645,34 @@
|
||||
"64387469667053244"
|
||||
]
|
||||
},
|
||||
{
|
||||
"genre": "fantasy",
|
||||
"subGenre": "Magics",
|
||||
"pinIds": [
|
||||
"44332377578826021",
|
||||
"914862421098890",
|
||||
"105201341292428725",
|
||||
"396035361002191644",
|
||||
"41517627812390162",
|
||||
"1618549864404055",
|
||||
"31877109857926612",
|
||||
"3518505954100471",
|
||||
"35114072091147253",
|
||||
"716846465726941759",
|
||||
"17170042324986575",
|
||||
"492649953385330",
|
||||
"2111131072434296",
|
||||
"11329436558460911",
|
||||
"281543723928763",
|
||||
"6122149487574205",
|
||||
"1337074889544820",
|
||||
"8655424281626310",
|
||||
"4292562140536462",
|
||||
"1970393583505897",
|
||||
"37436240649695593",
|
||||
"44332377578826021"
|
||||
]
|
||||
},
|
||||
{
|
||||
"genre": "fashion",
|
||||
"subGenre": "Accessories",
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { downloadImagesFromPinterestPin } from './lib/downloader';
|
||||
import { callOpenAIWithFile } from './lib/openai';
|
||||
import { generateVideo } from './lib/video-generator';
|
||||
import { generateImage } from './lib/image-generator-mix-style';
|
||||
import { generateImage as generateImageMixStyle } from './lib/image-generator-mix-style';
|
||||
import { generateImage as generateImage } from './lib/image-generator';
|
||||
import { logger } from './lib/logger';
|
||||
import * as fs from 'fs/promises';
|
||||
import dotenv from 'dotenv';
|
||||
@ -11,6 +12,8 @@ import { VideoModel } from './lib/db/video';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const USE_REFERENCE_IMAGE = (process.env.USE_REFERENCE_IMAGE || 'true').toLowerCase() === 'true';
|
||||
|
||||
|
||||
// Utility: extract JSON substring from a text.
|
||||
// Tries fenced ```json``` blocks first, otherwise extracts first {...} span.
|
||||
@ -248,32 +251,47 @@ async function generateImageForTask(task: GenerationTask, server: { baseUrl: str
|
||||
|
||||
const sourceFileNames: string[] = [];
|
||||
try {
|
||||
for (const sourcePath of renamedImagePaths) {
|
||||
const fileName = path.basename(sourcePath);
|
||||
const destPath = path.join(inputDir, fileName);
|
||||
await fs.copyFile(sourcePath, destPath);
|
||||
sourceFileNames.push(fileName);
|
||||
logger.info(`Copied ${sourcePath} to ${destPath}`);
|
||||
if (USE_REFERENCE_IMAGE) {
|
||||
// Copy renamed source images to the server input directory
|
||||
for (const sourcePath of renamedImagePaths) {
|
||||
const fileName = path.basename(sourcePath);
|
||||
const destPath = path.join(inputDir, fileName);
|
||||
await fs.copyFile(sourcePath, destPath);
|
||||
sourceFileNames.push(fileName);
|
||||
logger.info(`Copied ${sourcePath} to ${destPath}`);
|
||||
}
|
||||
|
||||
// generateImageMixStyle expects two source files; if we only have one, pass the same one twice
|
||||
const srcA = sourceFileNames[0];
|
||||
const srcB = sourceFileNames[1] || sourceFileNames[0];
|
||||
|
||||
const generatedImagePath = await generateImageMixStyle(
|
||||
imagePrompt,
|
||||
srcA,
|
||||
srcB,
|
||||
imageFileName,
|
||||
baseUrl,
|
||||
outputDir,
|
||||
{ width: 720, height: 1280 }
|
||||
);
|
||||
return generatedImagePath;
|
||||
} else {
|
||||
// Use Pinterest images only to create the prompt; generate final image using the single-image generator
|
||||
const generatedImagePath = await generateImage(
|
||||
imagePrompt,
|
||||
imageFileName,
|
||||
baseUrl,
|
||||
outputDir,
|
||||
'qwen',
|
||||
{ width: 720, height: 1280 }
|
||||
);
|
||||
return generatedImagePath;
|
||||
}
|
||||
|
||||
// generateImage expects two source files; if we only have one, pass the same one twice
|
||||
const srcA = sourceFileNames[0];
|
||||
const srcB = sourceFileNames[1] || sourceFileNames[0];
|
||||
|
||||
const generatedImagePath = await generateImage(
|
||||
imagePrompt,
|
||||
srcA,
|
||||
srcB,
|
||||
imageFileName,
|
||||
baseUrl,
|
||||
outputDir,
|
||||
{ width: 720, height: 1280 }
|
||||
);
|
||||
return generatedImagePath;
|
||||
} catch (error) {
|
||||
logger.error(`Failed to generate image for ${imageFileName} on server ${baseUrl}:`, error);
|
||||
return null;
|
||||
} finally {
|
||||
// cleanup local renamed images and any files copied to the server input dir
|
||||
for (const sourcePath of renamedImagePaths) {
|
||||
try {
|
||||
await fs.unlink(sourcePath);
|
||||
@ -338,8 +356,30 @@ async function getPinUrlFromPinterest(keyword: string): Promise<string | null> {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
allKeywords = allKeywords.filter(a => {
|
||||
return (a.genre == "sports" && a.subGenre == "Motocross")
|
||||
return (a.genre == "city" && a.subGenre == "Bridges") ||
|
||||
(a.genre == "city" && a.subGenre == "Castles") ||
|
||||
(a.genre == "city" && a.subGenre == "Cathedrals") ||
|
||||
(a.genre == "city" && a.subGenre == "Factories") ||
|
||||
(a.genre == "city" && a.subGenre == "Futuristic Cities") ||
|
||||
(a.genre == "city" && a.subGenre == "Historic Towns") ||
|
||||
(a.genre == "city" && a.subGenre == "Libraries") ||
|
||||
(a.genre == "city" && a.subGenre == "Markets") ||
|
||||
(a.genre == "city" && a.subGenre == "Modern Plazas") ||
|
||||
(a.genre == "city" && a.subGenre == "Museums") ||
|
||||
(a.genre == "city" && a.subGenre == "Palaces") ||
|
||||
(a.genre == "city" && a.subGenre == "Residential Blocks") ||
|
||||
(a.genre == "city" && a.subGenre == "Skylines") ||
|
||||
(a.genre == "city" && a.subGenre == "Stadiums") ||
|
||||
(a.genre == "city" && a.subGenre == "Street Cafes") ||
|
||||
(a.genre == "city" && a.subGenre == "Urban Parks") ||
|
||||
(a.genre == "city" && a.subGenre == "Skyscrapers") ||
|
||||
(a.genre == "city" && a.subGenre == "Slums")
|
||||
});
|
||||
*/
|
||||
allKeywords = allKeywords.filter(a => {
|
||||
return (a.genre == "city")
|
||||
});
|
||||
|
||||
function shuffle<T>(arr: T[]): T[] {
|
||||
@ -350,9 +390,10 @@ async function getPinUrlFromPinterest(keyword: string): Promise<string | null> {
|
||||
return arr;
|
||||
}
|
||||
|
||||
const selectedEntries = shuffle(allKeywords.slice()).slice(0, Math.min(20, allKeywords.length));
|
||||
//const selectedEntries = shuffle(allKeywords.slice()).slice(0, Math.min(20, allKeywords.length));
|
||||
const selectedEntries = allKeywords;
|
||||
|
||||
// Download up to `count` images from a pin URL by opening the pin page and scrolling up to 5 times to trigger lazy loading
|
||||
// Download up to `count` images from a pin URL by opening the pin page and scro lling up to 5 times to trigger lazy loading
|
||||
// Returns an array of saved image paths (may be empty)
|
||||
async function downloadOneImageFromPin(pinUrl: string, count: number = 1): Promise<string[]> {
|
||||
const browser = await puppeteer.launch({ headless: false });
|
||||
@ -459,7 +500,9 @@ async function getPinUrlFromPinterest(keyword: string): Promise<string | null> {
|
||||
|
||||
const { genre, subGenre } = genreSubGenre;
|
||||
|
||||
for (const pinId of genreSubGenre.pinIds) {
|
||||
const pickedUpPinIds = shuffle<string>(genreSubGenre.pinIds).slice(0, 2);
|
||||
|
||||
for (const pinId of pickedUpPinIds) {
|
||||
|
||||
const pin = `https://www.pinterest.com/pin/${pinId}/`;
|
||||
logger.info(`--- Starting processing for pin: ${pin} ---`);
|
||||
|
||||
Reference in New Issue
Block a user