import { Transcript } from "common-utils"; import _ from "lodash"; import { random, staticFile, useCurrentFrame } from "remotion"; import { DisplayMedia } from "./ig-reel/IGSimpleScene"; function levenshteinDistance(str1: string, str2: string) { const dp = Array.from({ length: str1.length + 1 }, (_, i) => [i]); for (let j = 1; j <= str2.length; j++) { dp[0][j] = j; } for (let i = 1; i <= str1.length; i++) { for (let j = 1; j <= str2.length; j++) { const cost = str1[i - 1] === str2[j - 1] ? 0 : 1; dp[i][j] = Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + cost); } } return dp[str1.length][str2.length]; } export class RenderUtils { public static calculateDisplayMedia( item: Transcript, durationInSeconds: number, frame: number, fps: number) { let currentDisplayMedia: DisplayMedia = (item?.mediaAbsPaths as any || [])[0] if (!_.isEmpty(item?.mediaAbsPaths)) { let frameOffest = 0 for (let i = 0; i < item?.mediaAbsPaths.length; i++) { const media: DisplayMedia = item.mediaAbsPaths[i] as any; if (!media) { return undefined } media.idx = i media.startFrame = frameOffest if (media.durationSec == undefined) { media.durationSec = durationInSeconds / (item?.mediaAbsPaths.length) if (i == item.mediaAbsPaths.length - 1) { media.durationSec = durationInSeconds } } media.durationFrames = media.durationSec * fps media.endFrame = frameOffest + media.durationFrames frameOffest = frameOffest + media.durationFrames if (frame > media.startFrame && frame < media.endFrame) { currentDisplayMedia = media } } } return currentDisplayMedia } public static tryStaticFile(file: string) { try { return staticFile(file); } catch (e) { let fileName = RenderUtils.getFileName(file) return staticFile(fileName!!); } } public static convertVHToPixels(vh: string) { return Math.round(window.innerHeight * (parseInt(vh.replace("vh", "")) / 100)); } public static convertVWToPixels(vw: string) { return Math.round(window.innerWidth * (parseInt(vw.replace("vw", "")) / 100)); } public static splitWordsIntoGroups(words: any) { const groups = []; let currentGroup = []; for (const word of words) { if (currentGroup.length === 0) { currentGroup.push(word); } else if (word.sentence_end) { currentGroup.push(word); groups.push(currentGroup); currentGroup = []; } else if (currentGroup.length < 5) { currentGroup.push(word); } else { groups.push(currentGroup); currentGroup = [word]; } } if (currentGroup.length > 0) { groups.push(currentGroup); } // Ensure each group has a maximum of 5 words const finalGroups = []; for (const group of groups) { while (group.length > 5) { finalGroups.push(group.slice(0, 5)); group.splice(0, 5); } finalGroups.push(group); } return finalGroups?.map(group => { return { words: group, start: undefined, end: undefined } }); } public static findCurrentGroupByTime(timeSec: Number, groups: any[]) { var t = timeSec; let wds = groups for (let i = 0; i < wds.length; i++) { const x: any = wds[i]; if (x.start != undefined && x.end != undefined && (t >= x.start && t < x.end)) { return x } } } public static findCurrentWord(timeSec: Number, frames: any[]) { var t = timeSec; let wds = frames for (let i = 0; i < wds.length; i++) { const x = wds[i]; if (x.start && x.end && (t >= x.start && t < x.end)) { return x } } } public static randomElement(arr: T[], seed: string): T { return arr[Math.floor(random(seed || 1) * arr.length)]; } public static hashCode(s: string) { return s.split("").reduce(function (a: number, b: string) { a = ((a << 5) - a) + b.charCodeAt(0); return a & a; }, 0); } public static splitArrayIntoChunks(arr: string | any[], chunkSize: number) { const chunkedArr = []; for (let i = 0; i < arr.length; i += chunkSize) { chunkedArr.push(arr.slice(i, i + chunkSize)); } return chunkedArr; } public static splitArray(arr: string | any[], pieces: number) { let result = []; let chunkSize = Math.ceil(arr.length / pieces); for (let i = 0, j = arr.length; i < j; i += chunkSize) { result.push(arr.slice(i, i + chunkSize)); } return result; } public static getFileName(filePath: string, subdirpath?: string): string | undefined { if (!filePath) return undefined; if (filePath.startsWith("http")) return filePath; // Always extract just the filename from any path const match = filePath.match(/([^\/\\]+)$/); let filename = match ? match[1] : ''; if (subdirpath) { return subdirpath + "/" + filename; } else { return filename; } } public static findMostSimilarString(inputString: string, stringArray: string[]) { let minDistance = Number.MAX_SAFE_INTEGER; let mostSimilarString = ''; stringArray.forEach((str) => { const distance = levenshteinDistance(inputString, str); if (distance < minDistance) { minDistance = distance; mostSimilarString = str; } }); return mostSimilarString; } }