// Function to process each individual Airtable record function buildVideoScenes(item) { const record = item.json.fields; const images = Array.isArray(record.Images) ? record.Images : []; // Detect aspect ratio: horizontal, vertical, square const getAspectRatio = (image) => { const ratio = image.width / image.height; if (Math.abs(ratio - 1) < 0.1) return 'square'; // square return ratio > 1 ? 'horizontal' : 'vertical'; // horizontal or vertical }; // Sort images into categories const horizontalImages = []; const verticalImages = []; const squareImages = []; images.forEach(image => { const aspect = getAspectRatio(image); if (aspect === 'horizontal') horizontalImages.push(image.url); else if (aspect === 'vertical') verticalImages.push(image.url); else squareImages.push(image.url); }); let remaining = [...horizontalImages, ...verticalImages, ...squareImages]; const shuffle = arr => arr.sort(() => Math.random() - 0.5); remaining = shuffle(remaining); const scenes = []; // --- INTRO --- scenes.push({ copy: "Title-Scene" }); scenes.push({ copy: "Intro-Text" }); scenes.push({ copy: "Intro-Dedication", "ID-Date": record.Date || "", "ID-Name": record["Full Name"] || "" }); // --- MIDDLE --- const shuffleScenes = arr => arr.sort(() => Math.random() - 0.5); let lastSceneType = null; const middleScenes = []; // Caption Scene as first middle scene (if exists) if (record["Caption Text"] && (horizontalImages.length > 0 || squareImages.length > 0)) { const img = horizontalImages.shift() || squareImages.shift(); remaining = remaining.filter(i => i !== img); middleScenes.push({ copy: "Single-Photo-With-Caption", "1PC-Photo": img, "1PC-Caption": record["Caption Text"] }); } while (remaining.length > 0) { const options = []; if (horizontalImages.length + squareImages.length >= 10) options.push("Multiple-Photos-Parallax"); if (verticalImages.length + squareImages.length >= 3) options.push("Three-Photos"); if (verticalImages.length + squareImages.length >= 2) options.push("Two-Photos"); if (verticalImages.length + squareImages.length >= 1) options.push("Single-Photo-With-Backdrop"); if (horizontalImages.length + squareImages.length >= 1) options.push("Single-Photo-With-Angle"); if (horizontalImages.length + squareImages.length >= 1) options.push("Single-Photo-Fullscreen"); if (options.length === 0) break; const filteredOptions = options.filter(opt => opt !== lastSceneType); // Avoid same scene consecutively const finalOptions = filteredOptions.length > 0 ? filteredOptions : options; const sceneType = shuffleScenes(finalOptions)[0]; lastSceneType = sceneType; switch (sceneType) { case "Multiple-Photos-Parallax": { const imgs = []; for (let i = 0; i < 10; i++) { const img = horizontalImages.shift() || squareImages.shift(); if (img) imgs.push(img); } remaining = remaining.filter(i => !imgs.includes(i)); middleScenes.push({ copy: "Multiple-Photos-Parallax", "MPP-Photo-1": imgs[0], "MPP-Photo-2": imgs[1], "MPP-Photo-3": imgs[2], "MPP-Photo-4": imgs[3], "MPP-Photo-5": imgs[4], "MPP-Photo-6": imgs[5], "MPP-Photo-7": imgs[6], "MPP-Photo-8": imgs[7], "MPP-Photo-9": imgs[8], "MPP-Photo-10": imgs[9], "MPP-Photo-Background": imgs[0] }); break; } case "Three-Photos": { const imgs = []; for (let i = 0; i < 3; i++) { const img = verticalImages.shift() || squareImages.shift(); if (img) imgs.push(img); } remaining = remaining.filter(i => !imgs.includes(i)); middleScenes.push({ copy: "Three-Photos", "3P-Photo-1": imgs[0], "3P-Photo-2": imgs[1], "3P-Photo-3": imgs[2] }); break; } case "Two-Photos": { const imgs = []; for (let i = 0; i < 2; i++) { const img = verticalImages.shift() || squareImages.shift(); if (img) imgs.push(img); } remaining = remaining.filter(i => !imgs.includes(i)); middleScenes.push({ copy: "Two-Photos", "2P-Photo-1": imgs[0], "2P-Photo-2": imgs[1], "2P-Photo-Background": imgs[0] }); break; } case "Single-Photo-With-Backdrop": { const img = verticalImages.shift() || squareImages.shift(); remaining = remaining.filter(i => i !== img); middleScenes.push({ copy: "Single-Photo-With-Backdrop", "SPB-Photo": img }); break; } case "Single-Photo-With-Angle": { const img = horizontalImages.shift() || squareImages.shift(); remaining = remaining.filter(i => i !== img); middleScenes.push({ copy: "Single-Photo-With-Angle", "1PA-Photo": img }); break; } case "Single-Photo-Fullscreen": { const img = horizontalImages.shift() || squareImages.shift(); remaining = remaining.filter(i => i !== img); middleScenes.push({ copy: "Single-Photo-Fullscreen", "1PF-Photo": img }); break; } } } scenes.push(...middleScenes); // --- END --- scenes.push({ copy: "Farewell-Message", "FM-Text": record["Farewell Message"] || "" }); scenes.push({ copy: "Final-Tribute", "FT-Name": record["Name"] || "" }); return { json: { "Scenes.elements": scenes } }; } // Apply to all records return items.map(item => buildVideoScenes(item));