93 lines
2.9 KiB
TypeScript
93 lines
2.9 KiB
TypeScript
import { TemplateGeneration } from '@/lib/api/template-generations';
|
|
|
|
export const getMediaType = (url: string): 'image' | 'video' | 'unknown' => {
|
|
if (!url) return 'unknown';
|
|
|
|
const extension = url.split('.').pop()?.toLowerCase() || '';
|
|
|
|
const imageExts = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'svg'];
|
|
const videoExts = ['mp4', 'webm', 'avi', 'mov', 'mkv', 'flv', 'm4v'];
|
|
|
|
if (imageExts.includes(extension)) return 'image';
|
|
if (videoExts.includes(extension)) return 'video';
|
|
return 'unknown';
|
|
};
|
|
|
|
export const getCloudflareStreamThumbnail = (
|
|
videoUrl: string,
|
|
options?: {
|
|
time?: string;
|
|
height?: number;
|
|
width?: number;
|
|
fit?: 'crop' | 'clip' | 'scale' | 'fill';
|
|
}
|
|
): string => {
|
|
const cloudflareStreamPattern = /https:\/\/customer-([^.]+)\.cloudflarestream\.com\/([^/]+)/;
|
|
const match = videoUrl.match(cloudflareStreamPattern);
|
|
|
|
if (!match) {
|
|
return videoUrl;
|
|
}
|
|
|
|
const [, customerId, videoId] = match;
|
|
const params = new URLSearchParams();
|
|
|
|
if (options?.time) params.append('time', options.time);
|
|
if (options?.height) params.append('height', options.height.toString());
|
|
if (options?.width) params.append('width', options.width.toString());
|
|
if (options?.fit) params.append('fit', options.fit);
|
|
|
|
const queryString = params.toString();
|
|
const thumbnailUrl = `https://customer-${customerId}.cloudflarestream.com/${videoId}/thumbnails/thumbnail.jpg${queryString ? `?${queryString}` : ''}`;
|
|
|
|
return thumbnailUrl;
|
|
};
|
|
|
|
export const getVideoThumbnail = (
|
|
videoUrl: string,
|
|
options: {
|
|
time?: string;
|
|
width?: number;
|
|
height?: number;
|
|
fit?: 'contain' | 'scale-down' | 'cover';
|
|
format?: 'jpg' | 'png';
|
|
} = {},
|
|
cloudflareZone: string = `popcore.ai`,
|
|
): string => {
|
|
const opts: string[] = ['mode=frame'];
|
|
|
|
if (options?.time) opts.push(`time=${options.time}`);
|
|
if (options?.width) opts.push(`width=${options.width}`);
|
|
if (options?.height) opts.push(`height=${options.height}`);
|
|
if (options?.fit) opts.push(`fit=${options.fit}`);
|
|
if (options?.format) opts.push(`format=${options.format}`);
|
|
|
|
const optionsString = opts.join(',');
|
|
return `https://${cloudflareZone}/cdn-cgi/media/${optionsString}/${videoUrl}`;
|
|
};
|
|
|
|
export const getVideoUrl = (videoUrl: string, cloudflareZone: string = `popcore.ai`)=>{
|
|
return `https://${cloudflareZone}/cdn-cgi/media/mode=video,audio=false/${videoUrl}`;
|
|
}
|
|
|
|
export const distributeToColumns = (items: TemplateGeneration[], videoHeight: number, imageHeight: number, gap: number) => {
|
|
const leftColumn: TemplateGeneration[] = [];
|
|
const rightColumn: TemplateGeneration[] = [];
|
|
let leftHeight = 0;
|
|
let rightHeight = 0;
|
|
|
|
items.forEach(item => {
|
|
const height = item.type === 'VIDEO' ? videoHeight : imageHeight;
|
|
|
|
if (leftHeight <= rightHeight) {
|
|
leftColumn.push(item);
|
|
leftHeight += height + gap;
|
|
} else {
|
|
rightColumn.push(item);
|
|
rightHeight += height + gap;
|
|
}
|
|
});
|
|
|
|
return { leftColumn, rightColumn };
|
|
};
|