@mux/ai 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/image-download.ts","../src/moderation.ts","../src/summarization.ts","../src/utils/vtt-parser.ts","../src/translation.ts","../src/audio-translation.ts","../src/chapters.ts","../src/utils/storyboard-processor.ts","../src/burned-in-captions.ts","../src/index.ts"],"names":["pRetry","AbortError","processor","Mux","OpenAI","z","Anthropic","zodTextFormat","S3Client","Upload","GetObjectCommand","getSignedUrl","audioUrl","ANTHROPIC_JSON_PROMPT","downloadImageAsBase64"],"mappings":"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","file":"index.cjs","sourcesContent":["import pRetry, { AbortError } from 'p-retry';\n\nexport interface ImageDownloadOptions {\n /** Request timeout in milliseconds (default: 10000) */\n timeout?: number;\n /** Maximum number of retry attempts (default: 3) */\n retries?: number;\n /** Base delay between retries in milliseconds (default: 1000) */\n retryDelay?: number;\n /** Maximum delay between retries in milliseconds (default: 10000) */\n maxRetryDelay?: number;\n /** Whether to use exponential backoff (default: true) */\n exponentialBackoff?: boolean;\n}\n\nexport interface ImageDownloadResult {\n /** Base64 encoded image data with data URI prefix (e.g., \"data:image/png;base64,iVBORw0K...\") */\n base64Data: string;\n /** Raw image buffer for multipart/form-data uploads */\n buffer: Buffer;\n /** Original image URL */\n url: string;\n /** Content type of the downloaded image */\n contentType: string;\n /** Size of the downloaded image in bytes */\n sizeBytes: number;\n /** Number of retry attempts made (0 if successful on first try) */\n attempts: number;\n}\n\nexport interface AnthropicFileUploadResult {\n /** Anthropic Files API file ID */\n fileId: string;\n /** Original image URL */\n url: string;\n /** Content type of the uploaded image */\n contentType: string;\n /** Size of the uploaded image in bytes */\n sizeBytes: number;\n}\n\nconst DEFAULT_OPTIONS: Required<ImageDownloadOptions> = {\n timeout: 10000,\n retries: 3,\n retryDelay: 1000,\n maxRetryDelay: 10000,\n exponentialBackoff: true,\n};\n\n/**\n * Downloads an image from a URL and converts it to base64 with robust retry logic\n * \n * @param url - The image URL to download\n * @param options - Download configuration options\n * @returns Promise resolving to ImageDownloadResult with base64 data and metadata\n * @throws Error if download fails after all retries\n */\nexport async function downloadImageAsBase64(\n url: string,\n options: ImageDownloadOptions = {}\n): Promise<ImageDownloadResult> {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n let attemptCount = 0;\n\n return pRetry(\n async () => {\n attemptCount++;\n \n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), opts.timeout);\n\n try {\n const response = await fetch(url, {\n signal: controller.signal,\n headers: {\n 'User-Agent': '@mux/ai image downloader',\n },\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n // Don't retry 4xx errors (except 429 rate limiting)\n if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n throw new AbortError(`HTTP ${response.status}: ${response.statusText}`);\n }\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const contentType = response.headers.get('content-type');\n if (!contentType?.startsWith('image/')) {\n throw new AbortError(`Invalid content type: ${contentType}. Expected image/*`);\n }\n\n const arrayBuffer = await response.arrayBuffer();\n const buffer = Buffer.from(arrayBuffer);\n \n if (buffer.length === 0) {\n throw new AbortError('Downloaded image is empty');\n }\n\n // Convert to base64 with data URI prefix\n const base64Data = `data:${contentType};base64,${buffer.toString('base64')}`;\n\n return {\n base64Data,\n buffer,\n url,\n contentType,\n sizeBytes: buffer.length,\n attempts: attemptCount,\n };\n\n } catch (error) {\n clearTimeout(timeoutId);\n \n // If it's an AbortError (non-retryable), re-throw it\n if (error instanceof AbortError) {\n throw error;\n }\n\n // For network errors, timeout errors, etc., wrap in retryable error\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n throw new Error(`Request timeout after ${opts.timeout}ms`);\n }\n throw new Error(`Download failed: ${error.message}`);\n }\n \n throw new Error('Unknown download error');\n }\n },\n {\n retries: opts.retries,\n minTimeout: opts.retryDelay,\n maxTimeout: opts.maxRetryDelay,\n factor: opts.exponentialBackoff ? 2 : 1,\n randomize: true, // Add jitter to prevent thundering herd\n onFailedAttempt: (error) => {\n console.warn(`Image download attempt ${error.attemptNumber} failed for ${url}`);\n if (error.retriesLeft > 0) {\n console.warn(`Retrying... (${error.retriesLeft} attempts left)`);\n }\n },\n }\n );\n}\n\n/**\n * Downloads multiple images concurrently with controlled concurrency\n * \n * @param urls - Array of image URLs to download\n * @param options - Download configuration options \n * @param maxConcurrent - Maximum concurrent downloads (default: 5)\n * @returns Promise resolving to array of ImageDownloadResult (in same order as input URLs)\n */\nexport async function downloadImagesAsBase64(\n urls: string[],\n options: ImageDownloadOptions = {},\n maxConcurrent: number = 5\n): Promise<ImageDownloadResult[]> {\n const results: ImageDownloadResult[] = [];\n \n for (let i = 0; i < urls.length; i += maxConcurrent) {\n const batch = urls.slice(i, i + maxConcurrent);\n const batchPromises = batch.map(url => downloadImageAsBase64(url, options));\n const batchResults = await Promise.all(batchPromises);\n results.push(...batchResults);\n }\n \n return results;\n}\n\n/**\n * Uploads an image to Anthropic Files API for use in messages\n * \n * @param url - The image URL to download and upload\n * @param anthropicApiKey - Anthropic API key\n * @param options - Download configuration options\n * @returns Promise resolving to AnthropicFileUploadResult with file ID and metadata\n * @throws Error if download or upload fails\n */\nexport async function uploadImageToAnthropicFiles(\n url: string,\n anthropicApiKey: string,\n options: ImageDownloadOptions = {}\n): Promise<AnthropicFileUploadResult> {\n // First download the image\n const downloadResult = await downloadImageAsBase64(url, options);\n \n // Create form data for Files API upload\n const formData = new FormData();\n \n // Create a Blob from the buffer for form data\n const imageBlob = new Blob([downloadResult.buffer], { \n type: downloadResult.contentType \n });\n \n // Get file extension from content type\n const extension = downloadResult.contentType.split('/')[1] || 'png';\n formData.append('file', imageBlob, `image.${extension}`);\n\n // Upload to Anthropic Files API\n const response = await fetch('https://api.anthropic.com/v1/files', {\n method: 'POST',\n headers: {\n 'x-api-key': anthropicApiKey,\n 'anthropic-version': '2023-06-01',\n 'anthropic-beta': 'files-api-2025-04-14',\n // Don't set Content-Type header - let fetch set it with boundary for multipart\n },\n body: formData\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Anthropic Files API error: ${response.status} ${response.statusText} - ${errorText}`);\n }\n\n const fileResult = await response.json() as { id: string };\n \n return {\n fileId: fileResult.id,\n url: downloadResult.url,\n contentType: downloadResult.contentType,\n sizeBytes: downloadResult.sizeBytes,\n };\n}","import Mux from '@mux/mux-node';\nimport OpenAI from 'openai';\nimport { MuxAIOptions } from './types';\nimport { ImageDownloadOptions, downloadImagesAsBase64 } from './utils/image-download';\n\nexport interface ThumbnailModerationScore {\n url: string;\n sexual: number;\n violence: number;\n error: boolean;\n}\n\nexport interface ModerationResult {\n assetId: string;\n thumbnailScores: ThumbnailModerationScore[];\n maxScores: {\n sexual: number;\n violence: number;\n };\n exceedsThreshold: boolean;\n thresholds: {\n sexual: number;\n violence: number;\n };\n}\n\nexport interface ModerationOptions extends MuxAIOptions {\n provider?: 'openai' | 'hive';\n model?: string;\n thresholds?: {\n sexual?: number;\n violence?: number;\n };\n thumbnailInterval?: number;\n thumbnailWidth?: number;\n maxConcurrent?: number;\n /** Method for submitting images to AI providers (default: 'url') */\n imageSubmissionMode?: 'url' | 'base64';\n /** Options for image download when using base64 submission mode */\n imageDownloadOptions?: ImageDownloadOptions;\n hiveApiKey?: string;\n}\n\nconst DEFAULT_THRESHOLDS = {\n sexual: 0.7,\n violence: 0.8\n};\n\n// Process promises in batches with maximum concurrency limit\nasync function processConcurrently<T>(\n items: any[],\n processor: (item: any) => Promise<T>,\n maxConcurrent: number = 5\n): Promise<T[]> {\n const results: T[] = [];\n \n for (let i = 0; i < items.length; i += maxConcurrent) {\n const batch = items.slice(i, i + maxConcurrent);\n const batchPromises = batch.map(processor);\n const batchResults = await Promise.all(batchPromises);\n results.push(...batchResults);\n }\n \n return results;\n}\n\n// Mapping Hive categories to OpenAI-compatible scores\nconst HIVE_SEXUAL_CATEGORIES = [\n 'general_nsfw',\n 'general_suggestive', \n 'yes_sexual_activity',\n 'female_underwear',\n 'male_underwear',\n 'bra',\n 'panties',\n 'sex_toys',\n 'nudity_female',\n 'nudity_male',\n 'cleavage',\n 'swimwear'\n];\n\nconst HIVE_VIOLENCE_CATEGORIES = [\n 'gun_in_hand',\n 'gun_not_in_hand',\n 'animated_gun',\n 'knife_in_hand',\n 'knife_not_in_hand',\n 'culinary_knife_not_in_hand',\n 'culinary_knife_in_hand',\n 'very_bloody',\n 'a_little_bloody',\n 'other_blood',\n 'hanging',\n 'noose',\n 'human_corpse',\n 'animated_corpse',\n 'emaciated_body',\n 'self_harm',\n 'animal_abuse',\n 'fights',\n 'garm_death_injury_or_military_conflict'\n];\n\n// Generates thumbnail URLs at regular intervals based on video duration\nfunction getThumbnailUrls(playbackId: string, duration: number, options: { interval?: number; width?: number } = {}): string[] {\n const { interval = 10, width = 640 } = options;\n const timestamps: number[] = [];\n\n if (duration <= 50) {\n // Short videos: 5 evenly spaced thumbnails\n const spacing = duration / 6;\n for (let i = 1; i <= 5; i++) {\n timestamps.push(Math.round(i * spacing));\n }\n } else {\n // Longer videos: one thumbnail every interval seconds\n for (let time = 0; time < duration; time += interval) {\n timestamps.push(time);\n }\n }\n\n return timestamps.map(\n (time) => `https://image.mux.com/${playbackId}/thumbnail.png?time=${time}&width=${width}`\n );\n}\n\n// Sends thumbnail URLs to OpenAI moderation API with concurrency limiting\nasync function requestOpenAIModeration(\n imageUrls: string[], \n openaiClient: OpenAI, \n model: string, \n maxConcurrent: number = 5,\n submissionMode: 'url' | 'base64' = 'url',\n downloadOptions?: ImageDownloadOptions\n): Promise<ThumbnailModerationScore[]> {\n \n // If using base64 mode, download all images first\n if (submissionMode === 'base64') {\n \n try {\n const downloadResults = await downloadImagesAsBase64(imageUrls, downloadOptions, maxConcurrent);\n \n // Process each downloaded image through OpenAI moderation\n const processor = async (downloadResult: typeof downloadResults[0]): Promise<ThumbnailModerationScore> => {\n try {\n const moderation = await openaiClient.moderations.create({\n model,\n input: [\n {\n type: \"image_url\",\n image_url: {\n url: downloadResult.base64Data, // Use base64 data URI\n },\n },\n ],\n });\n\n const categoryScores = moderation.results[0].category_scores;\n\n return {\n url: downloadResult.url, // Return original URL for tracking\n sexual: categoryScores.sexual || 0,\n violence: categoryScores.violence || 0,\n error: false\n };\n\n } catch (error) {\n console.error(`Failed to moderate downloaded image ${downloadResult.url}:`, error);\n return {\n url: downloadResult.url,\n sexual: 0,\n violence: 0,\n error: true,\n };\n }\n };\n\n return processConcurrently(downloadResults, processor, maxConcurrent);\n \n } catch (error) {\n console.error('Failed to download images for base64 submission:', error);\n // Return error results for all URLs\n return imageUrls.map(url => ({\n url,\n sexual: 0,\n violence: 0,\n error: true,\n }));\n }\n }\n \n // Original URL-based submission mode\n const processor = async (url: string): Promise<ThumbnailModerationScore> => {\n try {\n const moderation = await openaiClient.moderations.create({\n model,\n input: [\n {\n type: \"image_url\",\n image_url: {\n url: url,\n },\n },\n ],\n });\n\n const categoryScores = moderation.results[0].category_scores;\n\n return {\n url,\n sexual: categoryScores.sexual || 0,\n violence: categoryScores.violence || 0,\n error: false\n };\n\n } catch (error) {\n console.error(\"Failed to moderate image:\", error);\n return {\n url,\n sexual: 0,\n violence: 0,\n error: true,\n };\n }\n };\n\n return processConcurrently(imageUrls, processor, maxConcurrent);\n}\n\n// Sends thumbnail URLs to Hive moderation API with concurrency limiting\nasync function requestHiveModeration(\n imageUrls: string[], \n hiveApiKey: string, \n maxConcurrent: number = 5,\n submissionMode: 'url' | 'base64' = 'url',\n downloadOptions?: ImageDownloadOptions\n): Promise<ThumbnailModerationScore[]> {\n \n // If using base64 mode, download all images first and upload via multipart/form-data\n if (submissionMode === 'base64') {\n \n try {\n const downloadResults = await downloadImagesAsBase64(imageUrls, downloadOptions, maxConcurrent);\n \n // Process each downloaded image through Hive moderation via file upload\n const processor = async (downloadResult: typeof downloadResults[0]): Promise<ThumbnailModerationScore> => {\n try {\n // Create form data with image buffer\n const formData = new FormData();\n \n // Create a Blob from the buffer for form data\n const imageBlob = new Blob([downloadResult.buffer], { \n type: downloadResult.contentType \n });\n \n // Get file extension from content type\n const extension = downloadResult.contentType.split('/')[1] || 'png';\n formData.append('media', imageBlob, `image.${extension}`);\n\n const response = await fetch('https://api.thehive.ai/api/v2/task/sync', {\n method: 'POST',\n headers: {\n 'Authorization': `Token ${hiveApiKey}`,\n // Don't set Content-Type header - let fetch set it with boundary for multipart\n },\n body: formData\n });\n\n if (!response.ok) {\n throw new Error(`Hive API error: ${response.statusText}`);\n }\n\n const hiveResult = await response.json() as any;\n \n // Extract scores from Hive response and map to OpenAI format\n const classes = hiveResult.status?.[0]?.response?.output?.[0]?.classes || [];\n const scoreMap = Object.fromEntries(classes.map((c: any) => [c.class, c.score]));\n \n const sexualScores = HIVE_SEXUAL_CATEGORIES.map(category => \n scoreMap[category] || 0\n );\n const violenceScores = HIVE_VIOLENCE_CATEGORIES.map(category => \n scoreMap[category] || 0\n );\n\n return {\n url: downloadResult.url, // Return original URL for tracking\n sexual: Math.max(...sexualScores, 0),\n violence: Math.max(...violenceScores, 0),\n error: false\n };\n\n } catch (error) {\n console.error(`Failed to moderate uploaded image ${downloadResult.url}:`, error);\n return {\n url: downloadResult.url,\n sexual: 0,\n violence: 0,\n error: true,\n };\n }\n };\n\n return processConcurrently(downloadResults, processor, maxConcurrent);\n \n } catch (error) {\n console.error('Failed to download images for Hive multipart upload:', error);\n // Return error results for all URLs\n return imageUrls.map(url => ({\n url,\n sexual: 0,\n violence: 0,\n error: true,\n }));\n }\n }\n \n // Original URL-based submission mode\n const processor = async (url: string): Promise<ThumbnailModerationScore> => {\n try {\n const response = await fetch('https://api.thehive.ai/api/v2/task/sync', {\n method: 'POST',\n headers: {\n 'Authorization': `Token ${hiveApiKey}`,\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({ url })\n });\n\n if (!response.ok) {\n throw new Error(`Hive API error: ${response.statusText}`);\n }\n\n const hiveResult = await response.json() as any;\n \n // Extract scores from Hive response and map to OpenAI format\n // Hive returns scores in status[0].response.output[0].classes as array of {class, score}\n const classes = hiveResult.status?.[0]?.response?.output?.[0]?.classes || [];\n const scoreMap = Object.fromEntries(classes.map((c: any) => [c.class, c.score]));\n \n const sexualScores = HIVE_SEXUAL_CATEGORIES.map(category => \n scoreMap[category] || 0\n );\n const violenceScores = HIVE_VIOLENCE_CATEGORIES.map(category => \n scoreMap[category] || 0\n );\n\n return {\n url,\n sexual: Math.max(...sexualScores, 0),\n violence: Math.max(...violenceScores, 0),\n error: false\n };\n\n } catch (error) {\n console.error(\"Failed to moderate image with Hive:\", error);\n return {\n url,\n sexual: 0,\n violence: 0,\n error: true,\n };\n }\n };\n\n return processConcurrently(imageUrls, processor, maxConcurrent);\n}\n\nexport async function getModerationScores(\n assetId: string,\n options: ModerationOptions = {}\n): Promise<ModerationResult> {\n const {\n provider = 'openai',\n model = 'omni-moderation-latest',\n thresholds = DEFAULT_THRESHOLDS,\n thumbnailInterval = 10,\n thumbnailWidth = 640,\n maxConcurrent = 5,\n imageSubmissionMode = 'url',\n imageDownloadOptions,\n muxTokenId,\n muxTokenSecret,\n openaiApiKey,\n ...config\n } = options;\n\n if (provider !== 'openai' && provider !== 'hive') {\n throw new Error('Only OpenAI and Hive providers are currently supported');\n }\n\n // Validate required credentials\n const muxId = muxTokenId || process.env.MUX_TOKEN_ID;\n const muxSecret = muxTokenSecret || process.env.MUX_TOKEN_SECRET;\n const openaiKey = openaiApiKey || process.env.OPENAI_API_KEY;\n const hiveKey = options.hiveApiKey || process.env.HIVE_API_KEY;\n\n if (!muxId || !muxSecret) {\n throw new Error('Mux credentials are required. Provide muxTokenId and muxTokenSecret in options or set MUX_TOKEN_ID and MUX_TOKEN_SECRET environment variables.');\n }\n\n if (provider === 'openai' && !openaiKey) {\n throw new Error('OpenAI API key is required for OpenAI provider. Provide openaiApiKey in options or set OPENAI_API_KEY environment variable.');\n }\n\n if (provider === 'hive' && !hiveKey) {\n throw new Error('Hive API key is required for Hive provider. Provide hiveApiKey in options or set HIVE_API_KEY environment variable.');\n }\n\n // Initialize clients\n const mux = new Mux({\n tokenId: muxId,\n tokenSecret: muxSecret,\n });\n\n let openaiClient: OpenAI | undefined;\n if (provider === 'openai') {\n openaiClient = new OpenAI({\n apiKey: openaiKey!,\n });\n }\n\n // Fetch asset data from Mux\n let assetData;\n try {\n const asset = await mux.video.assets.retrieve(assetId);\n assetData = asset;\n } catch (error) {\n throw new Error(`Failed to fetch asset from Mux: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n\n // Get playback ID - prefer public playback IDs\n const publicPlaybackIds = assetData.playback_ids?.filter(pid => pid.policy === 'public') || [];\n \n if (publicPlaybackIds.length === 0) {\n throw new Error('No public playback IDs found for this asset. Moderation requires public playback access.');\n }\n\n const playbackId = publicPlaybackIds[0].id;\n const duration = assetData.duration || 0;\n\n // Generate thumbnail URLs\n const thumbnailUrls = getThumbnailUrls(playbackId, duration, {\n interval: thumbnailInterval,\n width: thumbnailWidth\n });\n\n // Request moderation for all thumbnails\n let thumbnailScores: ThumbnailModerationScore[];\n \n if (provider === 'openai') {\n thumbnailScores = await requestOpenAIModeration(\n thumbnailUrls, \n openaiClient!, \n model, \n maxConcurrent, \n imageSubmissionMode, \n imageDownloadOptions\n );\n } else if (provider === 'hive') {\n thumbnailScores = await requestHiveModeration(\n thumbnailUrls, \n hiveKey!, \n maxConcurrent, \n imageSubmissionMode, \n imageDownloadOptions\n );\n } else {\n throw new Error('Unsupported provider');\n }\n \n // Find highest scores across all thumbnails\n const maxSexual = Math.max(...thumbnailScores.map(s => s.sexual));\n const maxViolence = Math.max(...thumbnailScores.map(s => s.violence));\n \n const finalThresholds = { ...DEFAULT_THRESHOLDS, ...thresholds };\n \n return {\n assetId,\n thumbnailScores,\n maxScores: {\n sexual: maxSexual,\n violence: maxViolence\n },\n exceedsThreshold: maxSexual > finalThresholds.sexual || maxViolence > finalThresholds.violence,\n thresholds: finalThresholds\n };\n}","import Mux from '@mux/mux-node';\nimport OpenAI from 'openai';\nimport Anthropic from '@anthropic-ai/sdk';\nimport { z } from 'zod';\nimport { zodTextFormat } from 'openai/helpers/zod';\nimport { MuxAIOptions, ToneType } from './types';\nimport { ImageDownloadOptions, downloadImageAsBase64, uploadImageToAnthropicFiles } from './utils/image-download';\nimport { extractTextFromVTT } from './utils/vtt-parser';\n\nexport interface SummaryAndTagsResult {\n assetId: string;\n title: string;\n description: string;\n tags: string[];\n storyboardUrl?: string;\n}\n\nexport interface SummarizationOptions extends MuxAIOptions {\n provider?: 'openai' | 'anthropic';\n model?: string;\n maxSummaryLength?: number;\n maxTags?: number;\n customPrompt?: string;\n tone?: ToneType;\n includeTranscript?: boolean;\n /** Whether to clean VTT timestamps and formatting from transcript (default: true) */\n cleanTranscript?: boolean;\n /** Method for submitting storyboard to AI providers (default: 'url') */\n imageSubmissionMode?: 'url' | 'base64';\n /** Options for image download when using base64 submission mode */\n imageDownloadOptions?: ImageDownloadOptions;\n}\n\nconst summarySchema = z.object({\n keywords: z.array(z.string()).max(10),\n title: z.string().max(100),\n description: z.string().max(1000)\n});\n\nconst DEFAULT_PROMPT = \"Generate a short title (max 100 characters) and description (max 500 characters) for what happens. Start immediately with the action or subject - never reference that this is a video, content, or storyboard. Example: Title: 'Cooking Pasta Tutorial' Description: 'Someone cooks pasta by boiling water and adding noodles.'\";\n\nconst ANTHROPIC_JSON_PROMPT = `You must respond with valid JSON in exactly this format:\n{\n \"title\": \"Your title here (max 100 characters)\",\n \"description\": \"Your description here (max 500 characters)\",\n \"keywords\": [\"keyword1\", \"keyword2\", \"keyword3\"]\n}\n\nDo not include any text before or after the JSON. The JSON must be valid and parseable.`;\n\nexport async function getSummaryAndTags(\n assetId: string,\n promptOrOptions?: string | SummarizationOptions,\n options?: SummarizationOptions\n): Promise<SummaryAndTagsResult> {\n // Handle overloaded parameters\n let prompt: string;\n let actualOptions: SummarizationOptions;\n \n if (typeof promptOrOptions === 'string') {\n prompt = promptOrOptions;\n actualOptions = options || {};\n } else {\n prompt = DEFAULT_PROMPT;\n actualOptions = promptOrOptions || {};\n }\n const {\n provider = 'openai',\n model,\n tone = 'normal',\n includeTranscript = true,\n cleanTranscript = true,\n imageSubmissionMode = 'url',\n imageDownloadOptions,\n muxTokenId,\n muxTokenSecret,\n openaiApiKey,\n anthropicApiKey,\n ...config\n } = actualOptions;\n\n // Set default models based on provider\n const defaultModel = provider === 'anthropic' ? 'claude-3-5-haiku-20241022' : 'gpt-4o-mini';\n const finalModel = model || defaultModel;\n\n // Validate required credentials\n const muxId = muxTokenId || process.env.MUX_TOKEN_ID;\n const muxSecret = muxTokenSecret || process.env.MUX_TOKEN_SECRET;\n const openaiKey = openaiApiKey || process.env.OPENAI_API_KEY;\n const anthropicKey = anthropicApiKey || process.env.ANTHROPIC_API_KEY;\n\n if (!muxId || !muxSecret) {\n throw new Error('Mux credentials are required. Provide muxTokenId and muxTokenSecret in options or set MUX_TOKEN_ID and MUX_TOKEN_SECRET environment variables.');\n }\n\n if (provider === 'openai' && !openaiKey) {\n throw new Error('OpenAI API key is required. Provide openaiApiKey in options or set OPENAI_API_KEY environment variable.');\n }\n\n if (provider === 'anthropic' && !anthropicKey) {\n throw new Error('Anthropic API key is required. Provide anthropicApiKey in options or set ANTHROPIC_API_KEY environment variable.');\n }\n\n // Initialize clients\n const mux = new Mux({\n tokenId: muxId,\n tokenSecret: muxSecret,\n });\n\n let openaiClient: OpenAI | undefined;\n let anthropicClient: Anthropic | undefined;\n\n if (provider === 'openai') {\n openaiClient = new OpenAI({\n apiKey: openaiKey!,\n });\n } else if (provider === 'anthropic') {\n anthropicClient = new Anthropic({\n apiKey: anthropicKey!,\n });\n }\n\n // Fetch asset data from Mux\n let assetData;\n try {\n const asset = await mux.video.assets.retrieve(assetId);\n assetData = asset;\n } catch (error) {\n throw new Error(`Failed to fetch asset from Mux: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n\n // Get playback ID for storyboard URL\n const playbackId = assetData.playback_ids?.[0]?.id;\n if (!playbackId) {\n throw new Error('No playback ID found for this asset');\n }\n\n // Check for text tracks and fetch transcript if available\n let transcriptText = '';\n if (includeTranscript && assetData.tracks) {\n const textTrack = assetData.tracks.find((track) => \n track.type === 'text' && track.status === 'ready'\n );\n \n if (textTrack) {\n const transcriptUrl = `https://stream.mux.com/${playbackId}/text/${textTrack.id}.vtt`;\n \n try {\n const transcriptResponse = await fetch(transcriptUrl);\n if (transcriptResponse.ok) {\n const rawVttContent = await transcriptResponse.text();\n // Use clean text or raw VTT based on user preference\n transcriptText = cleanTranscript \n ? extractTextFromVTT(rawVttContent)\n : rawVttContent;\n }\n } catch (error) {\n console.warn('Failed to fetch transcript:', error);\n }\n }\n }\n\n // Create tone-informed prompt\n let toneInstruction = '';\n switch (tone) {\n case 'sassy':\n toneInstruction = ' Answer with a sassy, playful attitude and personality.';\n break;\n case 'professional':\n toneInstruction = ' Provide a professional, executive-level analysis suitable for business reporting.';\n break;\n default: // normal\n toneInstruction = ' Provide a clear, straightforward analysis.';\n }\n\n // Add transcript context to prompt if available\n let contextualPrompt = prompt + toneInstruction;\n if (transcriptText) {\n const transcriptType = cleanTranscript ? 'transcript' : 'WebVTT transcript';\n contextualPrompt += ` Use the following ${transcriptType} for additional context: \"${transcriptText}\"`;\n }\n\n // Analyze storyboard with AI provider\n const imageUrl = `https://image.mux.com/${playbackId}/storyboard.png?width=640`;\n \n let aiAnalysis: { title?: string; description?: string; keywords?: string[] } | null = null;\n let retryAttempt = 0;\n const maxRetries = 3;\n \n if (provider === 'openai') {\n // Handle base64 vs URL submission modes\n if (imageSubmissionMode === 'base64') {\n \n try {\n const downloadResult = await downloadImageAsBase64(imageUrl, imageDownloadOptions);\n \n const response = await openaiClient!.responses.parse({\n model: finalModel,\n input: [\n {\n role: \"system\",\n content: \"You are an image analysis tool. You will be given a storyboard image from a video showing multiple frames/scenes, and be expected to return structured data about the contents across all the frames.\",\n },\n {\n role: \"user\",\n content: [\n {\n type: \"input_text\",\n text: contextualPrompt,\n },\n {\n type: \"input_image\",\n image_url: downloadResult.base64Data, // Use base64 data URI\n detail: \"high\",\n },\n ],\n },\n ],\n text: {\n format: zodTextFormat(summarySchema, \"analysis\"),\n },\n });\n\n aiAnalysis = response.output_parsed;\n \n } catch (error: unknown) {\n throw new Error(`Failed to analyze video content with OpenAI in base64 mode: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n } else {\n // Original URL-based submission with retry logic\n while (retryAttempt <= maxRetries) {\n try {\n const response = await openaiClient!.responses.parse({\n model: finalModel,\n input: [\n {\n role: \"system\",\n content: \"You are an image analysis tool. You will be given a storyboard image from a video showing multiple frames/scenes, and be expected to return structured data about the contents across all the frames.\",\n },\n {\n role: \"user\",\n content: [\n {\n type: \"input_text\",\n text: contextualPrompt,\n },\n {\n type: \"input_image\",\n image_url: imageUrl,\n detail: \"high\",\n },\n ],\n },\n ],\n text: {\n format: zodTextFormat(summarySchema, \"analysis\"),\n },\n });\n\n aiAnalysis = response.output_parsed;\n break; // Success, exit retry loop\n \n } catch (error: unknown) {\n const isTimeoutError = error instanceof Error && error.message && error.message.includes('Timeout while downloading');\n \n if (isTimeoutError && retryAttempt < maxRetries) {\n await new Promise(resolve => setTimeout(resolve, 5000));\n retryAttempt++;\n continue;\n }\n \n throw new Error(`Failed to analyze video content with OpenAI: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n }\n } else if (provider === 'anthropic') {\n // Anthropic doesn't have structured outputs, so we use prompt engineering\n const anthropicPrompt = `${contextualPrompt}\n\n${ANTHROPIC_JSON_PROMPT}`;\n \n // Handle base64 vs URL submission modes\n if (imageSubmissionMode === 'base64') {\n \n try {\n // Upload to Files API instead of using base64 inline (no 5MB limit)\n const fileUploadResult = await uploadImageToAnthropicFiles(imageUrl, anthropicKey!, imageDownloadOptions);\n \n \n const response = await anthropicClient!.messages.create({\n model: finalModel,\n max_tokens: 1000,\n messages: [\n {\n role: \"user\",\n content: [\n {\n type: \"image\",\n source: {\n type: \"file\",\n file_id: fileUploadResult.fileId,\n } as any, // Type assertion for Files API support\n },\n {\n type: \"text\",\n text: anthropicPrompt,\n },\n ],\n },\n ],\n }, {\n headers: {\n 'anthropic-beta': 'files-api-2025-04-14'\n }\n });\n\n const content = response.content[0];\n if (content.type === 'text') {\n const jsonText = content.text.trim();\n try {\n aiAnalysis = JSON.parse(jsonText);\n } catch (parseError) {\n throw new Error(`Failed to parse JSON response from Anthropic: ${parseError instanceof Error ? parseError.message : 'Unknown error'}`);\n }\n } else {\n throw new Error('Unexpected response type from Anthropic');\n }\n \n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n throw new Error(`Failed to analyze video content with Anthropic Files API: ${errorMessage}`);\n }\n } else {\n // URL-based submission with retry logic\n while (retryAttempt <= maxRetries) {\n try {\n const response = await anthropicClient!.messages.create({\n model: finalModel,\n max_tokens: 1000,\n messages: [\n {\n role: \"user\",\n content: [\n {\n type: \"image\",\n source: {\n type: \"url\",\n url: imageUrl,\n } as any, // Type assertion to work around SDK type definitions\n },\n {\n type: \"text\",\n text: anthropicPrompt,\n },\n ],\n },\n ],\n });\n\n const content = response.content[0];\n if (content.type === 'text') {\n // Parse JSON from Anthropic response\n const jsonText = content.text.trim();\n try {\n aiAnalysis = JSON.parse(jsonText);\n break; // Success, exit retry loop\n } catch (parseError) {\n if (retryAttempt < maxRetries) {\n console.warn(`Failed to parse JSON from Anthropic (attempt ${retryAttempt + 1}):`, jsonText);\n retryAttempt++;\n await new Promise(resolve => setTimeout(resolve, 2000));\n continue;\n }\n throw new Error(`Failed to parse JSON response from Anthropic: ${parseError instanceof Error ? parseError.message : 'Unknown error'}`);\n }\n } else {\n throw new Error('Unexpected response type from Anthropic');\n }\n \n } catch (error: unknown) {\n if (retryAttempt < maxRetries) {\n await new Promise(resolve => setTimeout(resolve, 5000));\n retryAttempt++;\n continue;\n }\n \n throw new Error(`Failed to analyze video content with Anthropic: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n }\n } else {\n throw new Error(`Unsupported provider: ${provider}`);\n }\n\n if (!aiAnalysis) {\n throw new Error('No analysis result received from AI provider');\n }\n\n return {\n assetId,\n title: aiAnalysis.title || 'No title available',\n description: aiAnalysis.description || 'No description available',\n tags: aiAnalysis.keywords || [],\n storyboardUrl: imageUrl,\n };\n}","/**\n * Parses WebVTT content and extracts clean text for AI processing\n * \n * @param vttContent - Raw WebVTT content\n * @returns Clean transcript text without timestamps and markers\n */\nexport function extractTextFromVTT(vttContent: string): string {\n if (!vttContent.trim()) {\n return '';\n }\n\n const lines = vttContent.split('\\n');\n const textLines: string[] = [];\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n \n // Skip empty lines\n if (!line) continue;\n \n // Skip WEBVTT header\n if (line === 'WEBVTT') continue;\n \n // Skip NOTE lines\n if (line.startsWith('NOTE ')) continue;\n \n // Skip timestamp lines (contain -->)\n if (line.includes('-->')) continue;\n \n // Skip cue identifiers (numeric or UUID-like patterns)\n if (/^[\\d\\w-]+$/.test(line) && !line.includes(' ')) continue;\n \n // Skip style/formatting tags\n if (line.startsWith('STYLE') || line.startsWith('REGION')) continue;\n \n // This should be subtitle text\n // Remove any inline formatting tags like <c.color> or <b>\n const cleanLine = line.replace(/<[^>]*>/g, '').trim();\n \n if (cleanLine) {\n textLines.push(cleanLine);\n }\n }\n \n // Join all text lines with spaces and clean up multiple spaces\n return textLines.join(' ').replace(/\\s+/g, ' ').trim();\n}","import Mux from '@mux/mux-node';\nimport Anthropic from '@anthropic-ai/sdk';\nimport { S3Client } from '@aws-sdk/client-s3';\nimport { Upload } from '@aws-sdk/lib-storage';\nimport { GetObjectCommand } from '@aws-sdk/client-s3';\nimport { getSignedUrl } from '@aws-sdk/s3-request-presigner';\nimport { MuxAIOptions } from './types';\n\nexport interface TranslationResult {\n assetId: string;\n sourceLanguageCode: string;\n targetLanguageCode: string;\n originalVtt: string;\n translatedVtt: string;\n uploadedTrackId?: string;\n presignedUrl?: string;\n}\n\nexport interface TranslationOptions extends MuxAIOptions {\n provider?: 'anthropic';\n model?: string;\n s3Endpoint?: string;\n s3Region?: string;\n s3Bucket?: string;\n s3AccessKeyId?: string;\n s3SecretAccessKey?: string;\n uploadToMux?: boolean;\n}\n\nexport async function translateCaptions(\n assetId: string,\n fromLanguageCode: string,\n toLanguageCode: string,\n options: TranslationOptions = {}\n): Promise<TranslationResult> {\n const {\n provider = 'anthropic',\n model = 'claude-sonnet-4-20250514',\n muxTokenId,\n muxTokenSecret,\n anthropicApiKey,\n ...config\n } = options;\n\n if (provider !== 'anthropic') {\n throw new Error('Only Anthropic provider is currently supported for translation');\n }\n\n // Validate required credentials\n const muxId = muxTokenId || process.env.MUX_TOKEN_ID;\n const muxSecret = muxTokenSecret || process.env.MUX_TOKEN_SECRET;\n const anthropicKey = anthropicApiKey || process.env.ANTHROPIC_API_KEY;\n \n // S3 configuration\n const s3Endpoint = options.s3Endpoint || process.env.S3_ENDPOINT;\n const s3Region = options.s3Region || process.env.S3_REGION || 'auto';\n const s3Bucket = options.s3Bucket || process.env.S3_BUCKET;\n const s3AccessKeyId = options.s3AccessKeyId || process.env.S3_ACCESS_KEY_ID;\n const s3SecretAccessKey = options.s3SecretAccessKey || process.env.S3_SECRET_ACCESS_KEY;\n const uploadToMux = options.uploadToMux !== false; // Default to true\n\n if (!muxId || !muxSecret) {\n throw new Error('Mux credentials are required. Provide muxTokenId and muxTokenSecret in options or set MUX_TOKEN_ID and MUX_TOKEN_SECRET environment variables.');\n }\n\n if (!anthropicKey) {\n throw new Error('Anthropic API key is required. Provide anthropicApiKey in options or set ANTHROPIC_API_KEY environment variable.');\n }\n \n if (uploadToMux && (!s3Endpoint || !s3Bucket || !s3AccessKeyId || !s3SecretAccessKey)) {\n throw new Error('S3 configuration is required for uploading to Mux. Provide s3Endpoint, s3Bucket, s3AccessKeyId, and s3SecretAccessKey in options or set S3_ENDPOINT, S3_BUCKET, S3_ACCESS_KEY_ID, and S3_SECRET_ACCESS_KEY environment variables.');\n }\n\n // Initialize clients\n const mux = new Mux({\n tokenId: muxId,\n tokenSecret: muxSecret,\n });\n\n const anthropicClient = new Anthropic({\n apiKey: anthropicKey,\n });\n\n // Fetch asset data from Mux\n let assetData;\n try {\n const asset = await mux.video.assets.retrieve(assetId);\n assetData = asset;\n } catch (error) {\n throw new Error(`Failed to fetch asset from Mux: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n\n // Get playback ID for caption URL\n const playbackId = assetData.playback_ids?.[0]?.id;\n if (!playbackId) {\n throw new Error('No playback ID found for this asset');\n }\n\n // Find text track with the source language\n if (!assetData.tracks) {\n throw new Error('No tracks found for this asset');\n }\n\n const sourceTextTrack = assetData.tracks.find((track) => \n track.type === 'text' && \n track.status === 'ready' && \n track.language_code === fromLanguageCode\n );\n\n if (!sourceTextTrack) {\n throw new Error(`No ready text track found with language code '${fromLanguageCode}' for this asset`);\n }\n\n // Fetch the VTT file content\n const vttUrl = `https://stream.mux.com/${playbackId}/text/${sourceTextTrack.id}.vtt`;\n let vttContent: string;\n \n try {\n const vttResponse = await fetch(vttUrl);\n if (!vttResponse.ok) {\n throw new Error(`Failed to fetch VTT file: ${vttResponse.statusText}`);\n }\n vttContent = await vttResponse.text();\n } catch (error) {\n throw new Error(`Failed to fetch VTT content: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n\n console.log(`✅ Found VTT content for language '${fromLanguageCode}'`);\n\n // Translate VTT content using Anthropic\n let translatedVtt: string;\n \n try {\n const response = await anthropicClient.messages.create({\n model,\n max_tokens: 4000,\n messages: [\n {\n role: 'user',\n content: `Translate the following VTT subtitle file from ${fromLanguageCode} to ${toLanguageCode}. Return the translated VTT in JSON format with the key 'translation'. Preserve all timestamps and VTT formatting exactly as they appear.\\n\\n${vttContent}`\n }\n ]\n });\n\n const content = response.content[0];\n if (content.type === 'text') {\n // Parse JSON from Anthropic response\n const responseText = content.text.trim();\n try {\n // Remove code block markers if present\n const cleanedResponse = responseText.replace(/```json/g, '').replace(/```/g, '').trim();\n const parsed = JSON.parse(cleanedResponse);\n translatedVtt = parsed.translation;\n } catch (parseError) {\n throw new Error(`Failed to parse JSON response from Anthropic: ${parseError instanceof Error ? parseError.message : 'Unknown error'}`);\n }\n } else {\n throw new Error('Unexpected response type from Anthropic');\n }\n } catch (error) {\n throw new Error(`Failed to translate VTT with Anthropic: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n\n console.log(`\\n✅ Translation completed successfully!`);\n \n // If uploadToMux is false, just return the translation\n if (!uploadToMux) {\n console.log(`✅ VTT translated to ${toLanguageCode} successfully!`);\n \n return {\n assetId,\n sourceLanguageCode: fromLanguageCode,\n targetLanguageCode: toLanguageCode,\n originalVtt: vttContent,\n translatedVtt: translatedVtt\n };\n }\n \n // Upload translated VTT to S3-compatible storage\n console.log('📤 Uploading translated VTT to S3-compatible storage...');\n \n const s3Client = new S3Client({\n region: s3Region,\n endpoint: s3Endpoint,\n credentials: {\n accessKeyId: s3AccessKeyId!,\n secretAccessKey: s3SecretAccessKey!\n },\n forcePathStyle: true // Often needed for non-AWS S3 services\n });\n \n // Create unique key for the VTT file\n const vttKey = `translations/${assetId}/${fromLanguageCode}-to-${toLanguageCode}-${Date.now()}.vtt`;\n \n let presignedUrl: string;\n \n try {\n // Upload VTT to S3\n const upload = new Upload({\n client: s3Client,\n params: {\n Bucket: s3Bucket!,\n Key: vttKey,\n Body: translatedVtt,\n ContentType: 'text/vtt'\n }\n });\n \n await upload.done();\n console.log(`✅ VTT uploaded successfully to: ${vttKey}`);\n \n // Generate presigned URL (valid for 1 hour)\n const getObjectCommand = new GetObjectCommand({\n Bucket: s3Bucket!,\n Key: vttKey\n });\n \n presignedUrl = await getSignedUrl(s3Client, getObjectCommand, { \n expiresIn: 3600 // 1 hour\n });\n \n console.log(`🔗 Generated presigned URL (expires in 1 hour)`);\n \n } catch (error) {\n throw new Error(`Failed to upload VTT to S3: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n \n // Add translated track to Mux asset\n console.log('📹 Adding translated track to Mux asset...');\n \n let uploadedTrackId: string | undefined;\n \n try {\n const languageName = new Intl.DisplayNames(['en'], { type: 'language' }).of(toLanguageCode) || toLanguageCode.toUpperCase();\n const trackName = `${languageName} (auto-translated)`;\n \n const trackResponse = await mux.video.assets.createTrack(assetId, {\n type: 'text',\n text_type: 'subtitles',\n language_code: toLanguageCode,\n name: trackName,\n url: presignedUrl\n });\n \n uploadedTrackId = trackResponse.id;\n console.log(`✅ Track added to Mux asset with ID: ${uploadedTrackId}`);\n console.log(`📋 Track name: \"${trackName}\"`);\n \n } catch (error) {\n console.warn(`⚠️ Failed to add track to Mux asset: ${error instanceof Error ? error.message : 'Unknown error'}`);\n console.log('🔗 You can manually add the track using this presigned URL:');\n console.log(presignedUrl);\n }\n \n return {\n assetId,\n sourceLanguageCode: fromLanguageCode,\n targetLanguageCode: toLanguageCode,\n originalVtt: vttContent,\n translatedVtt: translatedVtt,\n uploadedTrackId,\n presignedUrl\n };\n}","import Mux from '@mux/mux-node';\n// Using direct HTTP requests instead of SDK for better compatibility\nimport { S3Client } from '@aws-sdk/client-s3';\nimport { Upload } from '@aws-sdk/lib-storage';\nimport { GetObjectCommand } from '@aws-sdk/client-s3';\nimport { getSignedUrl } from '@aws-sdk/s3-request-presigner';\nimport { MuxAIOptions } from './types';\n\nexport interface AudioTranslationResult {\n assetId: string;\n targetLanguageCode: string;\n dubbingId: string;\n uploadedTrackId?: string;\n presignedUrl?: string;\n}\n\nexport interface AudioTranslationOptions extends MuxAIOptions {\n provider?: 'elevenlabs';\n numSpeakers?: number;\n s3Endpoint?: string;\n s3Region?: string;\n s3Bucket?: string;\n s3AccessKeyId?: string;\n s3SecretAccessKey?: string;\n uploadToMux?: boolean;\n elevenLabsApiKey?: string;\n}\n\nexport async function translateAudio(\n assetId: string,\n toLanguageCode: string,\n options: AudioTranslationOptions = {}\n): Promise<AudioTranslationResult> {\n // Uses the default audio track on your asset, language is auto-detected by ElevenLabs\n const {\n provider = 'elevenlabs',\n numSpeakers = 0, // 0 = auto-detect\n muxTokenId,\n muxTokenSecret,\n elevenLabsApiKey,\n uploadToMux = true,\n ...config\n } = options;\n\n if (provider !== 'elevenlabs') {\n throw new Error('Only ElevenLabs provider is currently supported for audio translation');\n }\n\n // Validate required credentials\n const muxId = muxTokenId || process.env.MUX_TOKEN_ID;\n const muxSecret = muxTokenSecret || process.env.MUX_TOKEN_SECRET;\n const elevenLabsKey = elevenLabsApiKey || process.env.ELEVENLABS_API_KEY;\n \n // S3 configuration\n const s3Endpoint = options.s3Endpoint || process.env.S3_ENDPOINT;\n const s3Region = options.s3Region || process.env.S3_REGION || 'auto';\n const s3Bucket = options.s3Bucket || process.env.S3_BUCKET;\n const s3AccessKeyId = options.s3AccessKeyId || process.env.S3_ACCESS_KEY_ID;\n const s3SecretAccessKey = options.s3SecretAccessKey || process.env.S3_SECRET_ACCESS_KEY;\n\n if (!muxId || !muxSecret) {\n throw new Error('Mux credentials are required. Provide muxTokenId and muxTokenSecret in options or set MUX_TOKEN_ID and MUX_TOKEN_SECRET environment variables.');\n }\n\n if (!elevenLabsKey) {\n throw new Error('ElevenLabs API key is required. Provide elevenLabsApiKey in options or set ELEVENLABS_API_KEY environment variable.');\n }\n \n if (uploadToMux && (!s3Endpoint || !s3Bucket || !s3AccessKeyId || !s3SecretAccessKey)) {\n throw new Error('S3 configuration is required for uploading to Mux. Provide s3Endpoint, s3Bucket, s3AccessKeyId, and s3SecretAccessKey in options or set S3_ENDPOINT, S3_BUCKET, S3_ACCESS_KEY_ID, and S3_SECRET_ACCESS_KEY environment variables.');\n }\n\n // Initialize clients\n const mux = new Mux({\n tokenId: muxId,\n tokenSecret: muxSecret,\n });\n\n // Fetch asset data from Mux\n console.log(`🎬 Fetching Mux asset: ${assetId}`);\n let assetData;\n try {\n const asset = await mux.video.assets.retrieve(assetId);\n assetData = asset;\n } catch (error) {\n throw new Error(`Failed to fetch asset from Mux: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n\n // Check for audio-only static rendition\n console.log('🔍 Checking for audio-only static rendition...');\n \n if (!assetData.static_renditions || !assetData.static_renditions.files) {\n throw new Error('No static renditions found for this asset');\n }\n\n const staticRenditionFiles = assetData.static_renditions.files as any[];\n\n if (staticRenditionFiles.length === 0) {\n throw new Error('No static rendition files found for this asset');\n }\n\n const audioRendition = staticRenditionFiles.find((rendition: any) => \n rendition.name === 'audio.m4a' && rendition.status === 'ready'\n );\n\n if (!audioRendition) {\n throw new Error('No ready audio-only static rendition found for this asset. Please ensure the asset has an audio.m4a static rendition.');\n }\n\n const audioUrl = `https://stream.mux.com/${assetData.playback_ids?.[0]?.id}/audio.m4a`;\n console.log(`✅ Found audio rendition: ${audioUrl}`);\n\n // Create dubbing job in ElevenLabs\n console.log(`🎙️ Creating ElevenLabs dubbing job (auto-detect → ${toLanguageCode})`);\n \n let dubbingId: string;\n \n try {\n // Fetch audio file and create dubbing job\n const audioResponse = await fetch(audioUrl);\n if (!audioResponse.ok) {\n throw new Error(`Failed to fetch audio file: ${audioResponse.statusText}`);\n }\n \n const audioBuffer = await audioResponse.arrayBuffer();\n const audioBlob = new Blob([audioBuffer], { type: 'audio/mp4' });\n const audioFile = audioBlob as any; // ElevenLabs accepts Blob\n \n // Create dubbing job using direct HTTP request\n const formData = new FormData();\n formData.append('file', audioFile);\n formData.append('target_lang', toLanguageCode);\n // Note: source_lang is omitted to enable automatic language detection\n formData.append('num_speakers', numSpeakers.toString());\n formData.append('name', `Mux Asset ${assetId} - auto to ${toLanguageCode}`);\n \n const dubbingResponse = await fetch('https://api.elevenlabs.io/v1/dubbing', {\n method: 'POST',\n headers: {\n 'xi-api-key': elevenLabsKey!\n },\n body: formData\n });\n \n if (!dubbingResponse.ok) {\n throw new Error(`ElevenLabs API error: ${dubbingResponse.statusText}`);\n }\n \n const dubbingData = await dubbingResponse.json() as any;\n \n dubbingId = dubbingData.dubbing_id;\n console.log(`✅ Dubbing job created: ${dubbingId}`);\n console.log(`⏱️ Expected duration: ${dubbingData.expected_duration_sec}s`);\n \n } catch (error) {\n throw new Error(`Failed to create ElevenLabs dubbing job: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n\n // Poll for completion\n console.log('⏳ Waiting for dubbing to complete...');\n \n let dubbingStatus: string = 'dubbing';\n let pollAttempts = 0;\n const maxPollAttempts = 180; // 30 minutes at 10s intervals\n \n while (dubbingStatus === 'dubbing' && pollAttempts < maxPollAttempts) {\n await new Promise(resolve => setTimeout(resolve, 10000)); // Wait 10 seconds\n pollAttempts++;\n \n try {\n const statusResponse = await fetch(`https://api.elevenlabs.io/v1/dubbing/${dubbingId}`, {\n headers: {\n 'xi-api-key': elevenLabsKey!\n }\n });\n \n if (!statusResponse.ok) {\n throw new Error(`Status check failed: ${statusResponse.statusText}`);\n }\n \n const statusData = await statusResponse.json() as any;\n dubbingStatus = statusData.status;\n \n console.log(`📊 Status check ${pollAttempts}: ${dubbingStatus}`);\n \n if (dubbingStatus === 'failed') {\n throw new Error('ElevenLabs dubbing job failed');\n }\n \n } catch (error) {\n throw new Error(`Failed to check dubbing status: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n \n if (dubbingStatus !== 'dubbed') {\n throw new Error(`Dubbing job timed out or failed. Final status: ${dubbingStatus}`);\n }\n \n console.log('✅ Dubbing completed successfully!');\n\n // If uploadToMux is false, just return the dubbing info\n if (!uploadToMux) {\n return {\n assetId,\n targetLanguageCode: toLanguageCode,\n dubbingId\n };\n }\n\n // Download dubbed audio from ElevenLabs\n console.log('📥 Downloading dubbed audio from ElevenLabs...');\n \n let dubbedAudioBuffer: ArrayBuffer;\n \n try {\n // Get dubbed audio using fetch (since the SDK method might not be available)\n const audioUrl = `https://api.elevenlabs.io/v1/dubbing/${dubbingId}/audio/${toLanguageCode}`;\n const audioResponse = await fetch(audioUrl, {\n headers: {\n 'xi-api-key': elevenLabsKey!\n }\n });\n \n if (!audioResponse.ok) {\n throw new Error(`Failed to fetch dubbed audio: ${audioResponse.statusText}`);\n }\n \n dubbedAudioBuffer = await audioResponse.arrayBuffer();\n console.log(`✅ Downloaded dubbed audio (${dubbedAudioBuffer.byteLength} bytes)`);\n \n } catch (error) {\n throw new Error(`Failed to download dubbed audio: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n\n // Upload to S3-compatible storage\n console.log('📤 Uploading dubbed audio to S3-compatible storage...');\n \n const s3Client = new S3Client({\n region: s3Region,\n endpoint: s3Endpoint,\n credentials: {\n accessKeyId: s3AccessKeyId!,\n secretAccessKey: s3SecretAccessKey!\n },\n forcePathStyle: true\n });\n \n // Create unique key for the audio file\n const audioKey = `audio-translations/${assetId}/auto-to-${toLanguageCode}-${Date.now()}.m4a`;\n \n let presignedUrl: string;\n \n try {\n // Upload audio to S3\n const upload = new Upload({\n client: s3Client,\n params: {\n Bucket: s3Bucket!,\n Key: audioKey,\n Body: new Uint8Array(dubbedAudioBuffer),\n ContentType: 'audio/mp4'\n }\n });\n \n await upload.done();\n console.log(`✅ Audio uploaded successfully to: ${audioKey}`);\n \n // Generate presigned URL (valid for 1 hour)\n const getObjectCommand = new GetObjectCommand({\n Bucket: s3Bucket!,\n Key: audioKey\n });\n \n presignedUrl = await getSignedUrl(s3Client, getObjectCommand, { \n expiresIn: 3600 // 1 hour\n });\n \n console.log(`🔗 Generated presigned URL (expires in 1 hour)`);\n \n } catch (error) {\n throw new Error(`Failed to upload audio to S3: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n\n // Add translated audio track to Mux asset\n console.log('🎬 Adding translated audio track to Mux asset...');\n \n let uploadedTrackId: string | undefined;\n \n try {\n const languageName = new Intl.DisplayNames(['en'], { type: 'language' }).of(toLanguageCode) || toLanguageCode.toUpperCase();\n const trackName = `${languageName} (auto-dubbed)`;\n \n const trackResponse = await mux.video.assets.createTrack(assetId, {\n type: 'audio',\n language_code: toLanguageCode,\n name: trackName,\n url: presignedUrl\n });\n \n uploadedTrackId = trackResponse.id;\n console.log(`✅ Audio track added to Mux asset with ID: ${uploadedTrackId}`);\n console.log(`🎵 Track name: \"${trackName}\"`);\n \n } catch (error) {\n console.warn(`⚠️ Failed to add audio track to Mux asset: ${error instanceof Error ? error.message : 'Unknown error'}`);\n console.log('🔗 You can manually add the track using this presigned URL:');\n console.log(presignedUrl);\n }\n\n return {\n assetId,\n targetLanguageCode: toLanguageCode,\n dubbingId,\n uploadedTrackId,\n presignedUrl\n };\n}","import Mux from '@mux/mux-node';\nimport OpenAI from 'openai';\nimport Anthropic from '@anthropic-ai/sdk';\nimport { z } from 'zod';\nimport { zodTextFormat } from 'openai/helpers/zod';\nimport { MuxAIOptions } from './types';\n\nexport interface Chapter {\n /** Start time in seconds */\n startTime: number;\n /** Chapter title */\n title: string;\n}\n\nexport interface ChaptersResult {\n assetId: string;\n languageCode: string;\n chapters: Chapter[];\n}\n\nexport interface ChaptersOptions extends MuxAIOptions {\n provider?: 'openai' | 'anthropic';\n model?: string;\n}\n\nconst chaptersSchema = z.object({\n chapters: z.array(z.object({\n startTime: z.number(),\n title: z.string()\n }))\n});\n\nconst DEFAULT_SYSTEM_PROMPT = `Your role is to segment the following captions into chunked chapters, summarising each chapter with a title. \n\nAnalyze the transcript and create logical chapter breaks based on topic changes, major transitions, or distinct sections of content. Each chapter should represent a meaningful segment of the video.\n\nYou must respond with valid JSON in exactly this format:\n{\n \"chapters\": [\n {\"startTime\": 0, \"title\": \"Introduction\"},\n {\"startTime\": 45.5, \"title\": \"Main Topic Discussion\"},\n {\"startTime\": 120.0, \"title\": \"Conclusion\"}\n ]\n}\n\nImportant rules:\n- startTime must be in seconds (not HH:MM:SS format)\n- Always start with startTime: 0 for the first chapter\n- Create 3-8 chapters depending on content length and natural breaks\n- Chapter titles should be concise and descriptive\n- Do not include any text before or after the JSON\n- The JSON must be valid and parseable`;\n\nconst ANTHROPIC_JSON_PROMPT = `You must respond with valid JSON in exactly this format:\n{\n \"chapters\": [\n {\"startTime\": 0, \"title\": \"Chapter title here\"},\n {\"startTime\": 45.5, \"title\": \"Another chapter title\"}\n ]\n}\n\nDo not include any text before or after the JSON. The JSON must be valid and parseable.`;\n\n/**\n * Converts VTT timestamp (HH:MM:SS.mmm) to seconds\n */\nfunction vttTimestampToSeconds(timestamp: string): number {\n const parts = timestamp.split(':');\n if (parts.length !== 3) return 0;\n \n const hours = parseInt(parts[0], 10) || 0;\n const minutes = parseInt(parts[1], 10) || 0;\n const seconds = parseFloat(parts[2]) || 0;\n \n return hours * 3600 + minutes * 60 + seconds;\n}\n\n/**\n * Extracts timestamps and text from VTT content for chapter generation\n */\nfunction extractTimestampsFromVTT(vttContent: string): string {\n if (!vttContent.trim()) {\n return '';\n }\n\n const lines = vttContent.split('\\n');\n const segments: Array<{time: number, text: string}> = [];\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n \n // Find timestamp lines (contain -->)\n if (line.includes('-->')) {\n const startTime = line.split(' --> ')[0].trim();\n const timeInSeconds = vttTimestampToSeconds(startTime);\n \n // Get the subtitle text (next non-empty line)\n let j = i + 1;\n while (j < lines.length && !lines[j].trim()) {\n j++;\n }\n \n if (j < lines.length) {\n const text = lines[j].trim().replace(/<[^>]*>/g, ''); // Remove formatting tags\n if (text) {\n segments.push({ time: timeInSeconds, text });\n }\n }\n }\n }\n \n // Create a readable transcript with timestamps for the AI\n return segments\n .map(segment => `[${Math.floor(segment.time)}s] ${segment.text}`)\n .join('\\n');\n}\n\nexport async function generateChapters(\n assetId: string,\n languageCode: string,\n options: ChaptersOptions = {}\n): Promise<ChaptersResult> {\n const {\n provider = 'openai',\n model,\n muxTokenId,\n muxTokenSecret,\n openaiApiKey,\n anthropicApiKey,\n ...config\n } = options;\n\n // Set default models based on provider\n const defaultModel = provider === 'anthropic' ? 'claude-3-5-haiku-20241022' : 'gpt-4o-mini';\n const finalModel = model || defaultModel;\n\n // Validate required credentials\n const muxId = muxTokenId || process.env.MUX_TOKEN_ID;\n const muxSecret = muxTokenSecret || process.env.MUX_TOKEN_SECRET;\n const openaiKey = openaiApiKey || process.env.OPENAI_API_KEY;\n const anthropicKey = anthropicApiKey || process.env.ANTHROPIC_API_KEY;\n\n if (!muxId || !muxSecret) {\n throw new Error('Mux credentials are required. Provide muxTokenId and muxTokenSecret in options or set MUX_TOKEN_ID and MUX_TOKEN_SECRET environment variables.');\n }\n\n if (provider === 'openai' && !openaiKey) {\n throw new Error('OpenAI API key is required for OpenAI provider. Provide openaiApiKey in options or set OPENAI_API_KEY environment variable.');\n }\n\n if (provider === 'anthropic' && !anthropicKey) {\n throw new Error('Anthropic API key is required for Anthropic provider. Provide anthropicApiKey in options or set ANTHROPIC_API_KEY environment variable.');\n }\n\n // Initialize clients\n const mux = new Mux({\n tokenId: muxId,\n tokenSecret: muxSecret,\n });\n\n let openaiClient: OpenAI | undefined;\n let anthropicClient: Anthropic | undefined;\n\n if (provider === 'openai') {\n openaiClient = new OpenAI({\n apiKey: openaiKey!,\n });\n } else if (provider === 'anthropic') {\n anthropicClient = new Anthropic({\n apiKey: anthropicKey!,\n });\n }\n\n // Fetch asset data from Mux\n let assetData;\n try {\n const asset = await mux.video.assets.retrieve(assetId);\n assetData = asset;\n } catch (error) {\n throw new Error(`Failed to fetch asset from Mux: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n\n // Get playback ID\n const playbackId = assetData.playback_ids?.[0]?.id;\n if (!playbackId) {\n throw new Error('No playback ID found for this asset');\n }\n\n // Find caption track in the specified language\n if (!assetData.tracks) {\n throw new Error('No tracks found for this asset');\n }\n\n const captionTrack = assetData.tracks.find((track) => \n track.type === 'text' && \n track.status === 'ready' &&\n track.text_type === 'subtitles' &&\n track.language_code === languageCode\n );\n\n if (!captionTrack) {\n throw new Error(`No caption track found for language '${languageCode}'. Available languages: ${assetData.tracks.filter(t => t.type === 'text').map(t => t.language_code).join(', ')}`);\n }\n\n // Fetch the VTT content\n const transcriptUrl = `https://stream.mux.com/${playbackId}/text/${captionTrack.id}.vtt`;\n \n let vttContent: string;\n try {\n const transcriptResponse = await fetch(transcriptUrl);\n if (!transcriptResponse.ok) {\n throw new Error(`Failed to fetch VTT: ${transcriptResponse.statusText}`);\n }\n vttContent = await transcriptResponse.text();\n } catch (error) {\n throw new Error(`Failed to fetch caption track: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n\n // Extract timestamped transcript for AI processing\n const timestampedTranscript = extractTimestampsFromVTT(vttContent);\n \n if (!timestampedTranscript) {\n throw new Error('No usable content found in caption track');\n }\n\n // Generate chapters using AI\n let chaptersData: { chapters: Chapter[] } | null = null;\n\n if (provider === 'openai') {\n try {\n const response = await openaiClient!.responses.parse({\n model: finalModel,\n input: [\n {\n role: \"system\",\n content: DEFAULT_SYSTEM_PROMPT,\n },\n {\n role: \"user\",\n content: [\n {\n type: \"input_text\",\n text: timestampedTranscript,\n },\n ],\n },\n ],\n text: {\n format: zodTextFormat(chaptersSchema, \"chapters\"),\n },\n });\n\n chaptersData = response.output_parsed;\n } catch (error) {\n throw new Error(`Failed to generate chapters with OpenAI: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n } else if (provider === 'anthropic') {\n const anthropicPrompt = `${DEFAULT_SYSTEM_PROMPT}\n\n${ANTHROPIC_JSON_PROMPT}\n\nTranscript:\n${timestampedTranscript}`;\n\n try {\n const response = await anthropicClient!.messages.create({\n model: finalModel,\n max_tokens: 2000,\n messages: [\n {\n role: \"user\",\n content: anthropicPrompt,\n },\n ],\n });\n\n const content = response.content[0];\n if (content.type === 'text') {\n const jsonText = content.text.trim();\n try {\n chaptersData = JSON.parse(jsonText);\n } catch (parseError) {\n throw new Error(`Failed to parse JSON response from Anthropic: ${parseError instanceof Error ? parseError.message : 'Unknown error'}`);\n }\n } else {\n throw new Error('Unexpected response type from Anthropic');\n }\n } catch (error) {\n throw new Error(`Failed to generate chapters with Anthropic: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n } else {\n throw new Error(`Unsupported provider: ${provider}`);\n }\n\n if (!chaptersData || !chaptersData.chapters) {\n throw new Error('No chapters generated from AI response');\n }\n\n // Validate and sort chapters\n const validChapters = chaptersData.chapters\n .filter(chapter => typeof chapter.startTime === 'number' && typeof chapter.title === 'string')\n .sort((a, b) => a.startTime - b.startTime);\n\n if (validChapters.length === 0) {\n throw new Error('No valid chapters found in AI response');\n }\n\n // Ensure first chapter starts at 0\n if (validChapters[0].startTime !== 0) {\n validChapters[0].startTime = 0;\n }\n\n return {\n assetId,\n languageCode,\n chapters: validChapters,\n };\n}","import Mux from '@mux/mux-node';\nimport OpenAI from 'openai';\nimport Anthropic from '@anthropic-ai/sdk';\nimport { ImageDownloadOptions, downloadImageAsBase64, uploadImageToAnthropicFiles } from './image-download';\n\nexport interface StoryboardProcessorOptions {\n muxTokenId?: string;\n muxTokenSecret?: string;\n openaiApiKey?: string;\n anthropicApiKey?: string;\n imageSubmissionMode?: 'url' | 'base64';\n imageDownloadOptions?: ImageDownloadOptions;\n}\n\nexport interface AssetInfo {\n playbackId: string;\n duration?: number;\n}\n\n/**\n * Retrieves asset information from Mux including playback ID and duration\n */\nexport async function getAssetInfo(assetId: string, options: StoryboardProcessorOptions): Promise<AssetInfo> {\n const muxId = options.muxTokenId || process.env.MUX_TOKEN_ID;\n const muxSecret = options.muxTokenSecret || process.env.MUX_TOKEN_SECRET;\n\n if (!muxId || !muxSecret) {\n throw new Error('Mux credentials are required. Provide muxTokenId and muxTokenSecret in options or set MUX_TOKEN_ID and MUX_TOKEN_SECRET environment variables.');\n }\n\n const mux = new Mux({\n tokenId: muxId,\n tokenSecret: muxSecret,\n });\n\n try {\n const asset = await mux.video.assets.retrieve(assetId);\n \n const playbackId = asset.playback_ids?.[0]?.id;\n if (!playbackId) {\n throw new Error('No playback ID found for this asset');\n }\n\n return {\n playbackId,\n duration: asset.duration || undefined\n };\n } catch (error) {\n throw new Error(`Failed to fetch asset from Mux: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Processes a storyboard image with OpenAI\n */\nexport async function processStoryboardWithOpenAI<T>(\n imageUrl: string,\n prompt: string,\n systemPrompt: string,\n options: {\n apiKey: string;\n model: string;\n responseParser: (response: any) => T;\n imageSubmissionMode?: 'url' | 'base64';\n imageDownloadOptions?: ImageDownloadOptions;\n maxRetries?: number;\n }\n): Promise<T> {\n const { apiKey, model, responseParser, imageSubmissionMode = 'url', imageDownloadOptions, maxRetries = 3 } = options;\n \n const openaiClient = new OpenAI({ apiKey });\n let retryAttempt = 0;\n\n if (imageSubmissionMode === 'base64') {\n try {\n const downloadResult = await downloadImageAsBase64(imageUrl, imageDownloadOptions);\n \n const response = await openaiClient.chat.completions.create({\n model,\n messages: [\n {\n role: \"system\",\n content: systemPrompt,\n },\n {\n role: \"user\",\n content: [\n {\n type: \"text\",\n text: prompt,\n },\n {\n type: \"image_url\",\n image_url: {\n url: downloadResult.base64Data,\n detail: \"high\",\n },\n },\n ],\n },\n ],\n });\n\n return responseParser(response);\n \n } catch (error: unknown) {\n throw new Error(`Failed to process storyboard with OpenAI in base64 mode: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n } else {\n // URL-based submission with retry logic\n while (retryAttempt <= maxRetries) {\n try {\n const response = await openaiClient.chat.completions.create({\n model,\n messages: [\n {\n role: \"system\",\n content: systemPrompt,\n },\n {\n role: \"user\",\n content: [\n {\n type: \"text\",\n text: prompt,\n },\n {\n type: \"image_url\",\n image_url: {\n url: imageUrl,\n detail: \"high\",\n },\n },\n ],\n },\n ],\n });\n\n return responseParser(response);\n \n } catch (error: unknown) {\n const isTimeoutError = error instanceof Error && error.message && error.message.includes('Timeout while downloading');\n \n if (isTimeoutError && retryAttempt < maxRetries) {\n await new Promise(resolve => setTimeout(resolve, 5000));\n retryAttempt++;\n continue;\n }\n \n throw new Error(`Failed to process storyboard with OpenAI: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n }\n\n throw new Error('All retry attempts failed');\n}\n\n/**\n * Processes a storyboard image with Anthropic\n */\nexport async function processStoryboardWithAnthropic<T>(\n imageUrl: string,\n prompt: string,\n options: {\n apiKey: string;\n model: string;\n responseParser: (response: any) => T;\n imageSubmissionMode?: 'url' | 'base64';\n imageDownloadOptions?: ImageDownloadOptions;\n maxRetries?: number;\n }\n): Promise<T> {\n const { apiKey, model, responseParser, imageSubmissionMode = 'url', imageDownloadOptions, maxRetries = 3 } = options;\n \n const anthropicClient = new Anthropic({ apiKey });\n let retryAttempt = 0;\n\n if (imageSubmissionMode === 'base64') {\n try {\n // Upload to Files API instead of using base64 inline (no 5MB limit)\n const fileUploadResult = await uploadImageToAnthropicFiles(imageUrl, apiKey, imageDownloadOptions);\n \n const response = await anthropicClient.messages.create({\n model,\n max_tokens: 1000,\n messages: [\n {\n role: \"user\",\n content: [\n {\n type: \"image\",\n source: {\n type: \"file\",\n file_id: fileUploadResult.fileId,\n } as any, // Type assertion for Files API support\n },\n {\n type: \"text\",\n text: prompt,\n },\n ],\n },\n ],\n }, {\n headers: {\n 'anthropic-beta': 'files-api-2025-04-14'\n }\n });\n\n return responseParser(response);\n \n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n throw new Error(`Failed to process storyboard with Anthropic Files API: ${errorMessage}`);\n }\n } else {\n // URL-based submission with retry logic\n while (retryAttempt <= maxRetries) {\n try {\n const response = await anthropicClient.messages.create({\n model,\n max_tokens: 1000,\n messages: [\n {\n role: \"user\",\n content: [\n {\n type: \"image\",\n source: {\n type: \"url\",\n url: imageUrl,\n } as any, // Type assertion to work around SDK type definitions\n },\n {\n type: \"text\",\n text: prompt,\n },\n ],\n },\n ],\n });\n\n return responseParser(response);\n \n } catch (error: unknown) {\n if (retryAttempt < maxRetries) {\n await new Promise(resolve => setTimeout(resolve, 5000));\n retryAttempt++;\n continue;\n }\n \n throw new Error(`Failed to process storyboard with Anthropic: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n }\n\n throw new Error('All retry attempts failed');\n}","import { z } from 'zod';\nimport { zodTextFormat } from 'openai/helpers/zod';\nimport { MuxAIOptions } from './types';\nimport { ImageDownloadOptions } from './utils/image-download';\nimport { \n getAssetInfo, \n processStoryboardWithOpenAI, \n processStoryboardWithAnthropic,\n StoryboardProcessorOptions \n} from './utils/storyboard-processor';\n\nexport interface BurnedInCaptionsResult {\n assetId: string;\n hasBurnedInCaptions: boolean;\n confidence: number;\n detectedLanguage: string | null;\n storyboardUrl?: string;\n}\n\nexport interface BurnedInCaptionsOptions extends MuxAIOptions {\n provider?: 'openai' | 'anthropic';\n model?: string;\n /** Method for submitting storyboard to AI providers (default: 'url') */\n imageSubmissionMode?: 'url' | 'base64';\n /** Options for image download when using base64 submission mode */\n imageDownloadOptions?: ImageDownloadOptions;\n}\n\nconst burnedInCaptionsSchema = z.object({\n hasBurnedInCaptions: z.boolean(),\n confidence: z.number().min(0).max(1),\n detectedLanguage: z.string().nullable()\n});\n\nconst DEFAULT_SYSTEM_PROMPT = `You are an expert at analyzing video frames to detect burned-in captions (also called open captions or hardcoded subtitles). These are text overlays that are permanently embedded in the video image, common on TikTok, Instagram Reels, and other social media platforms.\n\nCRITICAL: Burned-in captions must appear consistently across MOST frames in the storyboard. Text appearing in only 1-2 frames at the end is typically marketing copy, taglines, or end-cards - NOT burned-in captions.\n\nAnalyze the provided video storyboard by:\n1. COUNT how many frames contain text overlays vs. how many don't\n2. Check if text appears in consistent positions across multiple frames\n3. Verify text changes content between frames (indicating dialogue/narration)\n4. Ensure text has caption-style formatting (contrasting colors, readable fonts)\n\nONLY classify as burned-in captions if:\n- Text appears in multiple frames (not just 1-2 end frames)\n- Text positioning is consistent across those frames\n- Content suggests dialogue, narration, or subtitles (not marketing)\n- Formatting looks like captions (not graphics/logos)\n\nDO NOT classify as burned-in captions:\n- Marketing taglines appearing only in final 1-2 frames\n- Single words or phrases that don't change between frames\n- Graphics, logos, watermarks, or UI elements\n- Text that's part of the original scene content\n- End-cards with calls-to-action or brand messaging\n\nIf you detect burned-in captions, try to identify the language of the text.`;\n\nconst ANTHROPIC_SYSTEM_PROMPT = `You are an expert at analyzing video frames to detect burned-in captions (also called open captions or hardcoded subtitles). These are text overlays permanently embedded in video images, common on social media platforms.\n\nKey principles:\n1. Burned-in captions appear across multiple frames throughout the video timeline\n2. End-cards and marketing text appear only in final frames\n3. Captions have consistent positioning and caption-style formatting\n4. Caption text typically changes between frames (dialogue/narration)\n\nAnalysis approach:\n- Look for text overlays distributed across different parts of the timeline\n- Distinguish between dialogue captions vs. marketing end-cards\n- Consider text positioning, formatting, and content patterns`;\n\nconst DEFAULT_USER_PROMPT = `Analyze this video storyboard for burned-in captions. Follow this systematic approach:\n\nSTEP 1: Count the frames\n- How many total frames are shown in this storyboard?\n- How many frames contain any text overlays?\n- What percentage of frames contain text?\n\nSTEP 2: Analyze text consistency\n- If text is present, does it appear in the same position across multiple frames?\n- Does the text content change between frames (suggesting dialogue)?\n- Or is it the same text in just 1-2 frames (suggesting marketing/end-card)?\n\nSTEP 3: Classification\n- Are there burned-in captions (text overlaid that appears to be subtitles/captions)?\n- How confident are you (0.0 to 1.0)? Be decisive and accurate:\n * If clear dialogue/caption text across multiple frames → 0.8+ confidence, TRUE\n * If ONLY marketing text in final frames → 0.0 confidence, FALSE\n * If truly uncertain → 0.3-0.5 confidence\n- If captions are present, what language?\n\nREMEMBER: Marketing taglines in final frames = NOT captions (0.0 confidence, FALSE). Dialogue text across timeline = captions (0.8+ confidence, TRUE).\n\nRespond with your analysis.`;\n\nconst ANTHROPIC_USER_PROMPT = `Analyze this storyboard for burned-in captions:\n\n1. Examine each frame from left to right (timeline order)\n2. Note which frames have text overlays and their positions\n3. Determine the pattern:\n - Text scattered across timeline = likely captions\n - Text only in final 1-2 frames = likely end-card/marketing\n\nClassification rules:\n- If text appears in 3+ frames distributed throughout timeline → burned-in captions\n- If text appears only in final frames → NOT burned-in captions\n- Look for dialogue-style content vs. marketing taglines\n\nAnalyze and classify with confidence level.`;\n\nconst ANTHROPIC_JSON_PROMPT = `Apply the frame analysis above.\n\nKey rule: Text appearing only in final 2-3 frames = NOT captions. Text distributed throughout timeline = captions.\n\nRespond ONLY with valid JSON:\n{\n \"hasBurnedInCaptions\": true/false,\n \"confidence\": 0.85,\n \"detectedLanguage\": \"English\" (or null if no captions or language unclear)\n}\n\nDo not include any text before or after the JSON. The JSON must be valid and parseable.`;\n\nexport async function hasBurnedInCaptions(\n assetId: string,\n options: BurnedInCaptionsOptions = {}\n): Promise<BurnedInCaptionsResult> {\n const {\n provider = 'openai',\n model,\n imageSubmissionMode = 'url',\n imageDownloadOptions,\n muxTokenId,\n muxTokenSecret,\n openaiApiKey,\n anthropicApiKey,\n ...config\n } = options;\n\n // Set default models based on provider\n const defaultModel = provider === 'anthropic' ? 'claude-3-5-haiku-20241022' : 'gpt-4o-mini';\n const finalModel = model || defaultModel;\n\n // Validate required credentials\n const openaiKey = openaiApiKey || process.env.OPENAI_API_KEY;\n const anthropicKey = anthropicApiKey || process.env.ANTHROPIC_API_KEY;\n\n if (provider === 'openai' && !openaiKey) {\n throw new Error('OpenAI API key is required for OpenAI provider. Provide openaiApiKey in options or set OPENAI_API_KEY environment variable.');\n }\n\n if (provider === 'anthropic' && !anthropicKey) {\n throw new Error('Anthropic API key is required for Anthropic provider. Provide anthropicApiKey in options or set ANTHROPIC_API_KEY environment variable.');\n }\n\n // Get asset information\n const storyboardOptions: StoryboardProcessorOptions = {\n muxTokenId,\n muxTokenSecret,\n openaiApiKey,\n anthropicApiKey,\n imageSubmissionMode,\n imageDownloadOptions\n };\n\n const assetInfo = await getAssetInfo(assetId, storyboardOptions);\n const imageUrl = `https://image.mux.com/${assetInfo.playbackId}/storyboard.png?width=640`;\n\n let analysisResult: { hasBurnedInCaptions?: boolean; confidence?: number; detectedLanguage?: string | null } | null = null;\n\n if (provider === 'openai') {\n // Handle OpenAI with structured outputs directly\n const OpenAI = require('openai').default;\n const openaiClient = new OpenAI({ apiKey: openaiKey });\n\n if (imageSubmissionMode === 'base64') {\n const { downloadImageAsBase64 } = require('./utils/image-download');\n const downloadResult = await downloadImageAsBase64(imageUrl, imageDownloadOptions);\n \n const response = await openaiClient.responses.parse({\n model: finalModel,\n input: [\n {\n role: \"system\",\n content: ANTHROPIC_SYSTEM_PROMPT,\n },\n {\n role: \"user\",\n content: [\n {\n type: \"input_text\",\n text: ANTHROPIC_USER_PROMPT,\n },\n {\n type: \"input_image\",\n image_url: downloadResult.base64Data,\n detail: \"high\",\n },\n ],\n },\n ],\n text: {\n format: zodTextFormat(burnedInCaptionsSchema, \"analysis\"),\n },\n });\n\n analysisResult = response.output_parsed;\n } else {\n // URL-based submission with retry logic for structured outputs\n let retryAttempt = 0;\n const maxRetries = 3;\n\n while (retryAttempt <= maxRetries) {\n try {\n const response = await openaiClient.responses.parse({\n model: finalModel,\n input: [\n {\n role: \"system\",\n content: ANTHROPIC_SYSTEM_PROMPT,\n },\n {\n role: \"user\",\n content: [\n {\n type: \"input_text\",\n text: ANTHROPIC_USER_PROMPT,\n },\n {\n type: \"input_image\",\n image_url: imageUrl,\n detail: \"high\",\n },\n ],\n },\n ],\n text: {\n format: zodTextFormat(burnedInCaptionsSchema, \"analysis\"),\n },\n });\n\n analysisResult = response.output_parsed;\n break;\n \n } catch (error: unknown) {\n const isTimeoutError = error instanceof Error && error.message && error.message.includes('Timeout while downloading');\n \n if (isTimeoutError && retryAttempt < maxRetries) {\n await new Promise(resolve => setTimeout(resolve, 5000));\n retryAttempt++;\n continue;\n }\n \n throw new Error(`Failed to analyze storyboard with OpenAI: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n }\n } else if (provider === 'anthropic') {\n const anthropicPrompt = `${ANTHROPIC_USER_PROMPT}\n\n${ANTHROPIC_JSON_PROMPT}`;\n\n const responseParser = (response: any) => {\n const content = response.content[0];\n if (content.type === 'text') {\n const jsonText = content.text.trim();\n try {\n return JSON.parse(jsonText);\n } catch (parseError) {\n throw new Error(`Failed to parse JSON response from Anthropic: ${parseError instanceof Error ? parseError.message : 'Unknown error'}`);\n }\n } else {\n throw new Error('Unexpected response type from Anthropic');\n }\n };\n\n analysisResult = await processStoryboardWithAnthropic(\n imageUrl,\n anthropicPrompt,\n {\n apiKey: anthropicKey!,\n model: finalModel,\n responseParser,\n imageSubmissionMode,\n imageDownloadOptions\n }\n );\n } else {\n throw new Error(`Unsupported provider: ${provider}`);\n }\n\n if (!analysisResult) {\n throw new Error('No analysis result received from AI provider');\n }\n\n return {\n assetId,\n hasBurnedInCaptions: analysisResult.hasBurnedInCaptions ?? false,\n confidence: analysisResult.confidence ?? 0,\n detectedLanguage: analysisResult.detectedLanguage ?? null,\n storyboardUrl: imageUrl,\n };\n}","export * from './types';\nexport * from './moderation';\nexport * from './summarization';\nexport * from './translation';\nexport * from './audio-translation';\nexport * from './chapters';\nexport * from './burned-in-captions';\n\nexport const version = '0.1.0';"]}
@@ -0,0 +1,164 @@
1
+ interface MuxAIConfig {
2
+ muxTokenId?: string;
3
+ muxTokenSecret?: string;
4
+ openaiApiKey?: string;
5
+ anthropicApiKey?: string;
6
+ baseUrl?: string;
7
+ }
8
+ interface MuxAIOptions extends MuxAIConfig {
9
+ timeout?: number;
10
+ }
11
+ type ToneType = 'normal' | 'sassy' | 'professional';
12
+
13
+ interface ImageDownloadOptions {
14
+ /** Request timeout in milliseconds (default: 10000) */
15
+ timeout?: number;
16
+ /** Maximum number of retry attempts (default: 3) */
17
+ retries?: number;
18
+ /** Base delay between retries in milliseconds (default: 1000) */
19
+ retryDelay?: number;
20
+ /** Maximum delay between retries in milliseconds (default: 10000) */
21
+ maxRetryDelay?: number;
22
+ /** Whether to use exponential backoff (default: true) */
23
+ exponentialBackoff?: boolean;
24
+ }
25
+
26
+ interface ThumbnailModerationScore {
27
+ url: string;
28
+ sexual: number;
29
+ violence: number;
30
+ error: boolean;
31
+ }
32
+ interface ModerationResult {
33
+ assetId: string;
34
+ thumbnailScores: ThumbnailModerationScore[];
35
+ maxScores: {
36
+ sexual: number;
37
+ violence: number;
38
+ };
39
+ exceedsThreshold: boolean;
40
+ thresholds: {
41
+ sexual: number;
42
+ violence: number;
43
+ };
44
+ }
45
+ interface ModerationOptions extends MuxAIOptions {
46
+ provider?: 'openai' | 'hive';
47
+ model?: string;
48
+ thresholds?: {
49
+ sexual?: number;
50
+ violence?: number;
51
+ };
52
+ thumbnailInterval?: number;
53
+ thumbnailWidth?: number;
54
+ maxConcurrent?: number;
55
+ /** Method for submitting images to AI providers (default: 'url') */
56
+ imageSubmissionMode?: 'url' | 'base64';
57
+ /** Options for image download when using base64 submission mode */
58
+ imageDownloadOptions?: ImageDownloadOptions;
59
+ hiveApiKey?: string;
60
+ }
61
+ declare function getModerationScores(assetId: string, options?: ModerationOptions): Promise<ModerationResult>;
62
+
63
+ interface SummaryAndTagsResult {
64
+ assetId: string;
65
+ title: string;
66
+ description: string;
67
+ tags: string[];
68
+ storyboardUrl?: string;
69
+ }
70
+ interface SummarizationOptions extends MuxAIOptions {
71
+ provider?: 'openai' | 'anthropic';
72
+ model?: string;
73
+ maxSummaryLength?: number;
74
+ maxTags?: number;
75
+ customPrompt?: string;
76
+ tone?: ToneType;
77
+ includeTranscript?: boolean;
78
+ /** Whether to clean VTT timestamps and formatting from transcript (default: true) */
79
+ cleanTranscript?: boolean;
80
+ /** Method for submitting storyboard to AI providers (default: 'url') */
81
+ imageSubmissionMode?: 'url' | 'base64';
82
+ /** Options for image download when using base64 submission mode */
83
+ imageDownloadOptions?: ImageDownloadOptions;
84
+ }
85
+ declare function getSummaryAndTags(assetId: string, promptOrOptions?: string | SummarizationOptions, options?: SummarizationOptions): Promise<SummaryAndTagsResult>;
86
+
87
+ interface TranslationResult {
88
+ assetId: string;
89
+ sourceLanguageCode: string;
90
+ targetLanguageCode: string;
91
+ originalVtt: string;
92
+ translatedVtt: string;
93
+ uploadedTrackId?: string;
94
+ presignedUrl?: string;
95
+ }
96
+ interface TranslationOptions extends MuxAIOptions {
97
+ provider?: 'anthropic';
98
+ model?: string;
99
+ s3Endpoint?: string;
100
+ s3Region?: string;
101
+ s3Bucket?: string;
102
+ s3AccessKeyId?: string;
103
+ s3SecretAccessKey?: string;
104
+ uploadToMux?: boolean;
105
+ }
106
+ declare function translateCaptions(assetId: string, fromLanguageCode: string, toLanguageCode: string, options?: TranslationOptions): Promise<TranslationResult>;
107
+
108
+ interface AudioTranslationResult {
109
+ assetId: string;
110
+ targetLanguageCode: string;
111
+ dubbingId: string;
112
+ uploadedTrackId?: string;
113
+ presignedUrl?: string;
114
+ }
115
+ interface AudioTranslationOptions extends MuxAIOptions {
116
+ provider?: 'elevenlabs';
117
+ numSpeakers?: number;
118
+ s3Endpoint?: string;
119
+ s3Region?: string;
120
+ s3Bucket?: string;
121
+ s3AccessKeyId?: string;
122
+ s3SecretAccessKey?: string;
123
+ uploadToMux?: boolean;
124
+ elevenLabsApiKey?: string;
125
+ }
126
+ declare function translateAudio(assetId: string, toLanguageCode: string, options?: AudioTranslationOptions): Promise<AudioTranslationResult>;
127
+
128
+ interface Chapter {
129
+ /** Start time in seconds */
130
+ startTime: number;
131
+ /** Chapter title */
132
+ title: string;
133
+ }
134
+ interface ChaptersResult {
135
+ assetId: string;
136
+ languageCode: string;
137
+ chapters: Chapter[];
138
+ }
139
+ interface ChaptersOptions extends MuxAIOptions {
140
+ provider?: 'openai' | 'anthropic';
141
+ model?: string;
142
+ }
143
+ declare function generateChapters(assetId: string, languageCode: string, options?: ChaptersOptions): Promise<ChaptersResult>;
144
+
145
+ interface BurnedInCaptionsResult {
146
+ assetId: string;
147
+ hasBurnedInCaptions: boolean;
148
+ confidence: number;
149
+ detectedLanguage: string | null;
150
+ storyboardUrl?: string;
151
+ }
152
+ interface BurnedInCaptionsOptions extends MuxAIOptions {
153
+ provider?: 'openai' | 'anthropic';
154
+ model?: string;
155
+ /** Method for submitting storyboard to AI providers (default: 'url') */
156
+ imageSubmissionMode?: 'url' | 'base64';
157
+ /** Options for image download when using base64 submission mode */
158
+ imageDownloadOptions?: ImageDownloadOptions;
159
+ }
160
+ declare function hasBurnedInCaptions(assetId: string, options?: BurnedInCaptionsOptions): Promise<BurnedInCaptionsResult>;
161
+
162
+ declare const version = "0.1.0";
163
+
164
+ export { type AudioTranslationOptions, type AudioTranslationResult, type BurnedInCaptionsOptions, type BurnedInCaptionsResult, type Chapter, type ChaptersOptions, type ChaptersResult, type ModerationOptions, type ModerationResult, type MuxAIConfig, type MuxAIOptions, type SummarizationOptions, type SummaryAndTagsResult, type ThumbnailModerationScore, type ToneType, type TranslationOptions, type TranslationResult, generateChapters, getModerationScores, getSummaryAndTags, hasBurnedInCaptions, translateAudio, translateCaptions, version };