@mux/ai 0.1.1 → 0.1.3
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.
- package/LICENSE +10 -18
- package/README.md +493 -171
- package/dist/index-BNnz9P_5.d.mts +144 -0
- package/dist/index-Bnv7tv90.d.ts +477 -0
- package/dist/index-DyTSka2R.d.ts +144 -0
- package/dist/index-vJ5r2FNm.d.mts +477 -0
- package/dist/index.d.mts +13 -0
- package/dist/index.d.ts +13 -9
- package/dist/index.js +2237 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2205 -0
- package/dist/index.mjs.map +1 -0
- package/dist/primitives/index.d.mts +3 -0
- package/dist/primitives/index.d.ts +3 -0
- package/dist/primitives/index.js +409 -0
- package/dist/primitives/index.js.map +1 -0
- package/dist/primitives/index.mjs +358 -0
- package/dist/primitives/index.mjs.map +1 -0
- package/dist/types-ktXDZ93V.d.mts +137 -0
- package/dist/types-ktXDZ93V.d.ts +137 -0
- package/dist/workflows/index.d.mts +8 -0
- package/dist/workflows/index.d.ts +8 -0
- package/dist/workflows/index.js +2217 -0
- package/dist/workflows/index.js.map +1 -0
- package/dist/workflows/index.mjs +2168 -0
- package/dist/workflows/index.mjs.map +1 -0
- package/package.json +104 -29
- package/dist/audio-translation.d.ts +0 -21
- package/dist/audio-translation.d.ts.map +0 -1
- package/dist/audio-translation.js +0 -229
- package/dist/audio-translation.js.map +0 -1
- package/dist/burned-in-captions.d.ts +0 -19
- package/dist/burned-in-captions.d.ts.map +0 -1
- package/dist/burned-in-captions.js +0 -243
- package/dist/burned-in-captions.js.map +0 -1
- package/dist/chapters.d.ts +0 -18
- package/dist/chapters.d.ts.map +0 -1
- package/dist/chapters.js +0 -255
- package/dist/chapters.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/moderation.d.ts +0 -39
- package/dist/moderation.d.ts.map +0 -1
- package/dist/moderation.js +0 -341
- package/dist/moderation.js.map +0 -1
- package/dist/summarization.d.ts +0 -26
- package/dist/summarization.d.ts.map +0 -1
- package/dist/summarization.js +0 -337
- package/dist/summarization.js.map +0 -1
- package/dist/translation.d.ts +0 -22
- package/dist/translation.d.ts.map +0 -1
- package/dist/translation.js +0 -196
- package/dist/translation.js.map +0 -1
- package/dist/types.d.ts +0 -12
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/dist/utils/image-download.d.ts +0 -65
- package/dist/utils/image-download.d.ts.map +0 -1
- package/dist/utils/image-download.js +0 -150
- package/dist/utils/image-download.js.map +0 -1
- package/dist/utils/storyboard-processor.d.ts +0 -40
- package/dist/utils/storyboard-processor.d.ts.map +0 -1
- package/dist/utils/storyboard-processor.js +0 -202
- package/dist/utils/storyboard-processor.js.map +0 -1
- package/dist/utils/vtt-parser.d.ts +0 -8
- package/dist/utils/vtt-parser.d.ts.map +0 -1
- package/dist/utils/vtt-parser.js +0 -43
- package/dist/utils/vtt-parser.js.map +0 -1
|
@@ -1,243 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import { zodTextFormat } from 'openai/helpers/zod';
|
|
3
|
-
import { getAssetInfo, processStoryboardWithAnthropic } from './utils/storyboard-processor';
|
|
4
|
-
const burnedInCaptionsSchema = z.object({
|
|
5
|
-
hasBurnedInCaptions: z.boolean(),
|
|
6
|
-
confidence: z.number().min(0).max(1),
|
|
7
|
-
detectedLanguage: z.string().nullable()
|
|
8
|
-
});
|
|
9
|
-
const 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.
|
|
10
|
-
|
|
11
|
-
CRITICAL: 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.
|
|
12
|
-
|
|
13
|
-
Analyze the provided video storyboard by:
|
|
14
|
-
1. COUNT how many frames contain text overlays vs. how many don't
|
|
15
|
-
2. Check if text appears in consistent positions across multiple frames
|
|
16
|
-
3. Verify text changes content between frames (indicating dialogue/narration)
|
|
17
|
-
4. Ensure text has caption-style formatting (contrasting colors, readable fonts)
|
|
18
|
-
|
|
19
|
-
ONLY classify as burned-in captions if:
|
|
20
|
-
- Text appears in multiple frames (not just 1-2 end frames)
|
|
21
|
-
- Text positioning is consistent across those frames
|
|
22
|
-
- Content suggests dialogue, narration, or subtitles (not marketing)
|
|
23
|
-
- Formatting looks like captions (not graphics/logos)
|
|
24
|
-
|
|
25
|
-
DO NOT classify as burned-in captions:
|
|
26
|
-
- Marketing taglines appearing only in final 1-2 frames
|
|
27
|
-
- Single words or phrases that don't change between frames
|
|
28
|
-
- Graphics, logos, watermarks, or UI elements
|
|
29
|
-
- Text that's part of the original scene content
|
|
30
|
-
- End-cards with calls-to-action or brand messaging
|
|
31
|
-
|
|
32
|
-
If you detect burned-in captions, try to identify the language of the text.`;
|
|
33
|
-
const 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.
|
|
34
|
-
|
|
35
|
-
Key principles:
|
|
36
|
-
1. Burned-in captions appear across multiple frames throughout the video timeline
|
|
37
|
-
2. End-cards and marketing text appear only in final frames
|
|
38
|
-
3. Captions have consistent positioning and caption-style formatting
|
|
39
|
-
4. Caption text typically changes between frames (dialogue/narration)
|
|
40
|
-
|
|
41
|
-
Analysis approach:
|
|
42
|
-
- Look for text overlays distributed across different parts of the timeline
|
|
43
|
-
- Distinguish between dialogue captions vs. marketing end-cards
|
|
44
|
-
- Consider text positioning, formatting, and content patterns`;
|
|
45
|
-
const DEFAULT_USER_PROMPT = `Analyze this video storyboard for burned-in captions. Follow this systematic approach:
|
|
46
|
-
|
|
47
|
-
STEP 1: Count the frames
|
|
48
|
-
- How many total frames are shown in this storyboard?
|
|
49
|
-
- How many frames contain any text overlays?
|
|
50
|
-
- What percentage of frames contain text?
|
|
51
|
-
|
|
52
|
-
STEP 2: Analyze text consistency
|
|
53
|
-
- If text is present, does it appear in the same position across multiple frames?
|
|
54
|
-
- Does the text content change between frames (suggesting dialogue)?
|
|
55
|
-
- Or is it the same text in just 1-2 frames (suggesting marketing/end-card)?
|
|
56
|
-
|
|
57
|
-
STEP 3: Classification
|
|
58
|
-
- Are there burned-in captions (text overlaid that appears to be subtitles/captions)?
|
|
59
|
-
- How confident are you (0.0 to 1.0)? Be decisive and accurate:
|
|
60
|
-
* If clear dialogue/caption text across multiple frames → 0.8+ confidence, TRUE
|
|
61
|
-
* If ONLY marketing text in final frames → 0.0 confidence, FALSE
|
|
62
|
-
* If truly uncertain → 0.3-0.5 confidence
|
|
63
|
-
- If captions are present, what language?
|
|
64
|
-
|
|
65
|
-
REMEMBER: Marketing taglines in final frames = NOT captions (0.0 confidence, FALSE). Dialogue text across timeline = captions (0.8+ confidence, TRUE).
|
|
66
|
-
|
|
67
|
-
Respond with your analysis.`;
|
|
68
|
-
const ANTHROPIC_USER_PROMPT = `Analyze this storyboard for burned-in captions:
|
|
69
|
-
|
|
70
|
-
1. Examine each frame from left to right (timeline order)
|
|
71
|
-
2. Note which frames have text overlays and their positions
|
|
72
|
-
3. Determine the pattern:
|
|
73
|
-
- Text scattered across timeline = likely captions
|
|
74
|
-
- Text only in final 1-2 frames = likely end-card/marketing
|
|
75
|
-
|
|
76
|
-
Classification rules:
|
|
77
|
-
- If text appears in 3+ frames distributed throughout timeline → burned-in captions
|
|
78
|
-
- If text appears only in final frames → NOT burned-in captions
|
|
79
|
-
- Look for dialogue-style content vs. marketing taglines
|
|
80
|
-
|
|
81
|
-
Analyze and classify with confidence level.`;
|
|
82
|
-
const ANTHROPIC_JSON_PROMPT = `Apply the frame analysis above.
|
|
83
|
-
|
|
84
|
-
Key rule: Text appearing only in final 2-3 frames = NOT captions. Text distributed throughout timeline = captions.
|
|
85
|
-
|
|
86
|
-
Respond ONLY with valid JSON:
|
|
87
|
-
{
|
|
88
|
-
"hasBurnedInCaptions": true/false,
|
|
89
|
-
"confidence": 0.85,
|
|
90
|
-
"detectedLanguage": "English" (or null if no captions or language unclear)
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
Do not include any text before or after the JSON. The JSON must be valid and parseable.`;
|
|
94
|
-
export async function hasBurnedInCaptions(assetId, options = {}) {
|
|
95
|
-
const { provider = 'openai', model, imageSubmissionMode = 'url', imageDownloadOptions, muxTokenId, muxTokenSecret, openaiApiKey, anthropicApiKey, ...config } = options;
|
|
96
|
-
// Set default models based on provider
|
|
97
|
-
const defaultModel = provider === 'anthropic' ? 'claude-3-5-haiku-20241022' : 'gpt-4o-mini';
|
|
98
|
-
const finalModel = model || defaultModel;
|
|
99
|
-
// Validate required credentials
|
|
100
|
-
const openaiKey = openaiApiKey || process.env.OPENAI_API_KEY;
|
|
101
|
-
const anthropicKey = anthropicApiKey || process.env.ANTHROPIC_API_KEY;
|
|
102
|
-
if (provider === 'openai' && !openaiKey) {
|
|
103
|
-
throw new Error('OpenAI API key is required for OpenAI provider. Provide openaiApiKey in options or set OPENAI_API_KEY environment variable.');
|
|
104
|
-
}
|
|
105
|
-
if (provider === 'anthropic' && !anthropicKey) {
|
|
106
|
-
throw new Error('Anthropic API key is required for Anthropic provider. Provide anthropicApiKey in options or set ANTHROPIC_API_KEY environment variable.');
|
|
107
|
-
}
|
|
108
|
-
// Get asset information
|
|
109
|
-
const storyboardOptions = {
|
|
110
|
-
muxTokenId,
|
|
111
|
-
muxTokenSecret,
|
|
112
|
-
openaiApiKey,
|
|
113
|
-
anthropicApiKey,
|
|
114
|
-
imageSubmissionMode,
|
|
115
|
-
imageDownloadOptions
|
|
116
|
-
};
|
|
117
|
-
const assetInfo = await getAssetInfo(assetId, storyboardOptions);
|
|
118
|
-
const imageUrl = `https://image.mux.com/${assetInfo.playbackId}/storyboard.png?width=640`;
|
|
119
|
-
let analysisResult = null;
|
|
120
|
-
if (provider === 'openai') {
|
|
121
|
-
// Handle OpenAI with structured outputs directly
|
|
122
|
-
const OpenAI = require('openai').default;
|
|
123
|
-
const openaiClient = new OpenAI({ apiKey: openaiKey });
|
|
124
|
-
if (imageSubmissionMode === 'base64') {
|
|
125
|
-
const { downloadImageAsBase64 } = require('./utils/image-download');
|
|
126
|
-
const downloadResult = await downloadImageAsBase64(imageUrl, imageDownloadOptions);
|
|
127
|
-
const response = await openaiClient.responses.parse({
|
|
128
|
-
model: finalModel,
|
|
129
|
-
input: [
|
|
130
|
-
{
|
|
131
|
-
role: "system",
|
|
132
|
-
content: ANTHROPIC_SYSTEM_PROMPT,
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
role: "user",
|
|
136
|
-
content: [
|
|
137
|
-
{
|
|
138
|
-
type: "input_text",
|
|
139
|
-
text: ANTHROPIC_USER_PROMPT,
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
type: "input_image",
|
|
143
|
-
image_url: downloadResult.base64Data,
|
|
144
|
-
detail: "high",
|
|
145
|
-
},
|
|
146
|
-
],
|
|
147
|
-
},
|
|
148
|
-
],
|
|
149
|
-
text: {
|
|
150
|
-
format: zodTextFormat(burnedInCaptionsSchema, "analysis"),
|
|
151
|
-
},
|
|
152
|
-
});
|
|
153
|
-
analysisResult = response.output_parsed;
|
|
154
|
-
}
|
|
155
|
-
else {
|
|
156
|
-
// URL-based submission with retry logic for structured outputs
|
|
157
|
-
let retryAttempt = 0;
|
|
158
|
-
const maxRetries = 3;
|
|
159
|
-
while (retryAttempt <= maxRetries) {
|
|
160
|
-
try {
|
|
161
|
-
const response = await openaiClient.responses.parse({
|
|
162
|
-
model: finalModel,
|
|
163
|
-
input: [
|
|
164
|
-
{
|
|
165
|
-
role: "system",
|
|
166
|
-
content: ANTHROPIC_SYSTEM_PROMPT,
|
|
167
|
-
},
|
|
168
|
-
{
|
|
169
|
-
role: "user",
|
|
170
|
-
content: [
|
|
171
|
-
{
|
|
172
|
-
type: "input_text",
|
|
173
|
-
text: ANTHROPIC_USER_PROMPT,
|
|
174
|
-
},
|
|
175
|
-
{
|
|
176
|
-
type: "input_image",
|
|
177
|
-
image_url: imageUrl,
|
|
178
|
-
detail: "high",
|
|
179
|
-
},
|
|
180
|
-
],
|
|
181
|
-
},
|
|
182
|
-
],
|
|
183
|
-
text: {
|
|
184
|
-
format: zodTextFormat(burnedInCaptionsSchema, "analysis"),
|
|
185
|
-
},
|
|
186
|
-
});
|
|
187
|
-
analysisResult = response.output_parsed;
|
|
188
|
-
break;
|
|
189
|
-
}
|
|
190
|
-
catch (error) {
|
|
191
|
-
const isTimeoutError = error instanceof Error && error.message && error.message.includes('Timeout while downloading');
|
|
192
|
-
if (isTimeoutError && retryAttempt < maxRetries) {
|
|
193
|
-
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
194
|
-
retryAttempt++;
|
|
195
|
-
continue;
|
|
196
|
-
}
|
|
197
|
-
throw new Error(`Failed to analyze storyboard with OpenAI: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
else if (provider === 'anthropic') {
|
|
203
|
-
const anthropicPrompt = `${ANTHROPIC_USER_PROMPT}
|
|
204
|
-
|
|
205
|
-
${ANTHROPIC_JSON_PROMPT}`;
|
|
206
|
-
const responseParser = (response) => {
|
|
207
|
-
const content = response.content[0];
|
|
208
|
-
if (content.type === 'text') {
|
|
209
|
-
const jsonText = content.text.trim();
|
|
210
|
-
try {
|
|
211
|
-
return JSON.parse(jsonText);
|
|
212
|
-
}
|
|
213
|
-
catch (parseError) {
|
|
214
|
-
throw new Error(`Failed to parse JSON response from Anthropic: ${parseError instanceof Error ? parseError.message : 'Unknown error'}`);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
throw new Error('Unexpected response type from Anthropic');
|
|
219
|
-
}
|
|
220
|
-
};
|
|
221
|
-
analysisResult = await processStoryboardWithAnthropic(imageUrl, anthropicPrompt, {
|
|
222
|
-
apiKey: anthropicKey,
|
|
223
|
-
model: finalModel,
|
|
224
|
-
responseParser,
|
|
225
|
-
imageSubmissionMode,
|
|
226
|
-
imageDownloadOptions
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
else {
|
|
230
|
-
throw new Error(`Unsupported provider: ${provider}`);
|
|
231
|
-
}
|
|
232
|
-
if (!analysisResult) {
|
|
233
|
-
throw new Error('No analysis result received from AI provider');
|
|
234
|
-
}
|
|
235
|
-
return {
|
|
236
|
-
assetId,
|
|
237
|
-
hasBurnedInCaptions: analysisResult.hasBurnedInCaptions ?? false,
|
|
238
|
-
confidence: analysisResult.confidence ?? 0,
|
|
239
|
-
detectedLanguage: analysisResult.detectedLanguage ?? null,
|
|
240
|
-
storyboardUrl: imageUrl,
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
//# sourceMappingURL=burned-in-captions.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"burned-in-captions.js","sourceRoot":"","sources":["../src/burned-in-captions.ts"],"names":[],"mappings":"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"}
|
package/dist/chapters.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { MuxAIOptions } from './types';
|
|
2
|
-
export interface Chapter {
|
|
3
|
-
/** Start time in seconds */
|
|
4
|
-
startTime: number;
|
|
5
|
-
/** Chapter title */
|
|
6
|
-
title: string;
|
|
7
|
-
}
|
|
8
|
-
export interface ChaptersResult {
|
|
9
|
-
assetId: string;
|
|
10
|
-
languageCode: string;
|
|
11
|
-
chapters: Chapter[];
|
|
12
|
-
}
|
|
13
|
-
export interface ChaptersOptions extends MuxAIOptions {
|
|
14
|
-
provider?: 'openai' | 'anthropic';
|
|
15
|
-
model?: string;
|
|
16
|
-
}
|
|
17
|
-
export declare function generateChapters(assetId: string, languageCode: string, options?: ChaptersOptions): Promise<ChaptersResult>;
|
|
18
|
-
//# sourceMappingURL=chapters.d.ts.map
|
package/dist/chapters.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"chapters.d.ts","sourceRoot":"","sources":["../src/chapters.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,MAAM,WAAW,OAAO;IACtB,4BAA4B;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACnD,QAAQ,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA8FD,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,cAAc,CAAC,CAoMzB"}
|
package/dist/chapters.js
DELETED
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
import Mux from '@mux/mux-node';
|
|
2
|
-
import OpenAI from 'openai';
|
|
3
|
-
import Anthropic from '@anthropic-ai/sdk';
|
|
4
|
-
import { z } from 'zod';
|
|
5
|
-
import { zodTextFormat } from 'openai/helpers/zod';
|
|
6
|
-
const chaptersSchema = z.object({
|
|
7
|
-
chapters: z.array(z.object({
|
|
8
|
-
startTime: z.number(),
|
|
9
|
-
title: z.string()
|
|
10
|
-
}))
|
|
11
|
-
});
|
|
12
|
-
const DEFAULT_SYSTEM_PROMPT = `Your role is to segment the following captions into chunked chapters, summarising each chapter with a title.
|
|
13
|
-
|
|
14
|
-
Analyze 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.
|
|
15
|
-
|
|
16
|
-
You must respond with valid JSON in exactly this format:
|
|
17
|
-
{
|
|
18
|
-
"chapters": [
|
|
19
|
-
{"startTime": 0, "title": "Introduction"},
|
|
20
|
-
{"startTime": 45.5, "title": "Main Topic Discussion"},
|
|
21
|
-
{"startTime": 120.0, "title": "Conclusion"}
|
|
22
|
-
]
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
Important rules:
|
|
26
|
-
- startTime must be in seconds (not HH:MM:SS format)
|
|
27
|
-
- Always start with startTime: 0 for the first chapter
|
|
28
|
-
- Create 3-8 chapters depending on content length and natural breaks
|
|
29
|
-
- Chapter titles should be concise and descriptive
|
|
30
|
-
- Do not include any text before or after the JSON
|
|
31
|
-
- The JSON must be valid and parseable`;
|
|
32
|
-
const ANTHROPIC_JSON_PROMPT = `You must respond with valid JSON in exactly this format:
|
|
33
|
-
{
|
|
34
|
-
"chapters": [
|
|
35
|
-
{"startTime": 0, "title": "Chapter title here"},
|
|
36
|
-
{"startTime": 45.5, "title": "Another chapter title"}
|
|
37
|
-
]
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
Do not include any text before or after the JSON. The JSON must be valid and parseable.`;
|
|
41
|
-
/**
|
|
42
|
-
* Converts VTT timestamp (HH:MM:SS.mmm) to seconds
|
|
43
|
-
*/
|
|
44
|
-
function vttTimestampToSeconds(timestamp) {
|
|
45
|
-
const parts = timestamp.split(':');
|
|
46
|
-
if (parts.length !== 3)
|
|
47
|
-
return 0;
|
|
48
|
-
const hours = parseInt(parts[0], 10) || 0;
|
|
49
|
-
const minutes = parseInt(parts[1], 10) || 0;
|
|
50
|
-
const seconds = parseFloat(parts[2]) || 0;
|
|
51
|
-
return hours * 3600 + minutes * 60 + seconds;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Extracts timestamps and text from VTT content for chapter generation
|
|
55
|
-
*/
|
|
56
|
-
function extractTimestampsFromVTT(vttContent) {
|
|
57
|
-
if (!vttContent.trim()) {
|
|
58
|
-
return '';
|
|
59
|
-
}
|
|
60
|
-
const lines = vttContent.split('\n');
|
|
61
|
-
const segments = [];
|
|
62
|
-
for (let i = 0; i < lines.length; i++) {
|
|
63
|
-
const line = lines[i].trim();
|
|
64
|
-
// Find timestamp lines (contain -->)
|
|
65
|
-
if (line.includes('-->')) {
|
|
66
|
-
const startTime = line.split(' --> ')[0].trim();
|
|
67
|
-
const timeInSeconds = vttTimestampToSeconds(startTime);
|
|
68
|
-
// Get the subtitle text (next non-empty line)
|
|
69
|
-
let j = i + 1;
|
|
70
|
-
while (j < lines.length && !lines[j].trim()) {
|
|
71
|
-
j++;
|
|
72
|
-
}
|
|
73
|
-
if (j < lines.length) {
|
|
74
|
-
const text = lines[j].trim().replace(/<[^>]*>/g, ''); // Remove formatting tags
|
|
75
|
-
if (text) {
|
|
76
|
-
segments.push({ time: timeInSeconds, text });
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
// Create a readable transcript with timestamps for the AI
|
|
82
|
-
return segments
|
|
83
|
-
.map(segment => `[${Math.floor(segment.time)}s] ${segment.text}`)
|
|
84
|
-
.join('\n');
|
|
85
|
-
}
|
|
86
|
-
export async function generateChapters(assetId, languageCode, options = {}) {
|
|
87
|
-
const { provider = 'openai', model, muxTokenId, muxTokenSecret, openaiApiKey, anthropicApiKey, ...config } = options;
|
|
88
|
-
// Set default models based on provider
|
|
89
|
-
const defaultModel = provider === 'anthropic' ? 'claude-3-5-haiku-20241022' : 'gpt-4o-mini';
|
|
90
|
-
const finalModel = model || defaultModel;
|
|
91
|
-
// Validate required credentials
|
|
92
|
-
const muxId = muxTokenId || process.env.MUX_TOKEN_ID;
|
|
93
|
-
const muxSecret = muxTokenSecret || process.env.MUX_TOKEN_SECRET;
|
|
94
|
-
const openaiKey = openaiApiKey || process.env.OPENAI_API_KEY;
|
|
95
|
-
const anthropicKey = anthropicApiKey || process.env.ANTHROPIC_API_KEY;
|
|
96
|
-
if (!muxId || !muxSecret) {
|
|
97
|
-
throw new Error('Mux credentials are required. Provide muxTokenId and muxTokenSecret in options or set MUX_TOKEN_ID and MUX_TOKEN_SECRET environment variables.');
|
|
98
|
-
}
|
|
99
|
-
if (provider === 'openai' && !openaiKey) {
|
|
100
|
-
throw new Error('OpenAI API key is required for OpenAI provider. Provide openaiApiKey in options or set OPENAI_API_KEY environment variable.');
|
|
101
|
-
}
|
|
102
|
-
if (provider === 'anthropic' && !anthropicKey) {
|
|
103
|
-
throw new Error('Anthropic API key is required for Anthropic provider. Provide anthropicApiKey in options or set ANTHROPIC_API_KEY environment variable.');
|
|
104
|
-
}
|
|
105
|
-
// Initialize clients
|
|
106
|
-
const mux = new Mux({
|
|
107
|
-
tokenId: muxId,
|
|
108
|
-
tokenSecret: muxSecret,
|
|
109
|
-
});
|
|
110
|
-
let openaiClient;
|
|
111
|
-
let anthropicClient;
|
|
112
|
-
if (provider === 'openai') {
|
|
113
|
-
openaiClient = new OpenAI({
|
|
114
|
-
apiKey: openaiKey,
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
else if (provider === 'anthropic') {
|
|
118
|
-
anthropicClient = new Anthropic({
|
|
119
|
-
apiKey: anthropicKey,
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
// Fetch asset data from Mux
|
|
123
|
-
let assetData;
|
|
124
|
-
try {
|
|
125
|
-
const asset = await mux.video.assets.retrieve(assetId);
|
|
126
|
-
assetData = asset;
|
|
127
|
-
}
|
|
128
|
-
catch (error) {
|
|
129
|
-
throw new Error(`Failed to fetch asset from Mux: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
130
|
-
}
|
|
131
|
-
// Get playback ID
|
|
132
|
-
const playbackId = assetData.playback_ids?.[0]?.id;
|
|
133
|
-
if (!playbackId) {
|
|
134
|
-
throw new Error('No playback ID found for this asset');
|
|
135
|
-
}
|
|
136
|
-
// Find caption track in the specified language
|
|
137
|
-
if (!assetData.tracks) {
|
|
138
|
-
throw new Error('No tracks found for this asset');
|
|
139
|
-
}
|
|
140
|
-
const captionTrack = assetData.tracks.find((track) => track.type === 'text' &&
|
|
141
|
-
track.status === 'ready' &&
|
|
142
|
-
track.text_type === 'subtitles' &&
|
|
143
|
-
track.language_code === languageCode);
|
|
144
|
-
if (!captionTrack) {
|
|
145
|
-
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(', ')}`);
|
|
146
|
-
}
|
|
147
|
-
// Fetch the VTT content
|
|
148
|
-
const transcriptUrl = `https://stream.mux.com/${playbackId}/text/${captionTrack.id}.vtt`;
|
|
149
|
-
let vttContent;
|
|
150
|
-
try {
|
|
151
|
-
const transcriptResponse = await fetch(transcriptUrl);
|
|
152
|
-
if (!transcriptResponse.ok) {
|
|
153
|
-
throw new Error(`Failed to fetch VTT: ${transcriptResponse.statusText}`);
|
|
154
|
-
}
|
|
155
|
-
vttContent = await transcriptResponse.text();
|
|
156
|
-
}
|
|
157
|
-
catch (error) {
|
|
158
|
-
throw new Error(`Failed to fetch caption track: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
159
|
-
}
|
|
160
|
-
// Extract timestamped transcript for AI processing
|
|
161
|
-
const timestampedTranscript = extractTimestampsFromVTT(vttContent);
|
|
162
|
-
if (!timestampedTranscript) {
|
|
163
|
-
throw new Error('No usable content found in caption track');
|
|
164
|
-
}
|
|
165
|
-
// Generate chapters using AI
|
|
166
|
-
let chaptersData = null;
|
|
167
|
-
if (provider === 'openai') {
|
|
168
|
-
try {
|
|
169
|
-
const response = await openaiClient.responses.parse({
|
|
170
|
-
model: finalModel,
|
|
171
|
-
input: [
|
|
172
|
-
{
|
|
173
|
-
role: "system",
|
|
174
|
-
content: DEFAULT_SYSTEM_PROMPT,
|
|
175
|
-
},
|
|
176
|
-
{
|
|
177
|
-
role: "user",
|
|
178
|
-
content: [
|
|
179
|
-
{
|
|
180
|
-
type: "input_text",
|
|
181
|
-
text: timestampedTranscript,
|
|
182
|
-
},
|
|
183
|
-
],
|
|
184
|
-
},
|
|
185
|
-
],
|
|
186
|
-
text: {
|
|
187
|
-
format: zodTextFormat(chaptersSchema, "chapters"),
|
|
188
|
-
},
|
|
189
|
-
});
|
|
190
|
-
chaptersData = response.output_parsed;
|
|
191
|
-
}
|
|
192
|
-
catch (error) {
|
|
193
|
-
throw new Error(`Failed to generate chapters with OpenAI: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
else if (provider === 'anthropic') {
|
|
197
|
-
const anthropicPrompt = `${DEFAULT_SYSTEM_PROMPT}
|
|
198
|
-
|
|
199
|
-
${ANTHROPIC_JSON_PROMPT}
|
|
200
|
-
|
|
201
|
-
Transcript:
|
|
202
|
-
${timestampedTranscript}`;
|
|
203
|
-
try {
|
|
204
|
-
const response = await anthropicClient.messages.create({
|
|
205
|
-
model: finalModel,
|
|
206
|
-
max_tokens: 2000,
|
|
207
|
-
messages: [
|
|
208
|
-
{
|
|
209
|
-
role: "user",
|
|
210
|
-
content: anthropicPrompt,
|
|
211
|
-
},
|
|
212
|
-
],
|
|
213
|
-
});
|
|
214
|
-
const content = response.content[0];
|
|
215
|
-
if (content.type === 'text') {
|
|
216
|
-
const jsonText = content.text.trim();
|
|
217
|
-
try {
|
|
218
|
-
chaptersData = JSON.parse(jsonText);
|
|
219
|
-
}
|
|
220
|
-
catch (parseError) {
|
|
221
|
-
throw new Error(`Failed to parse JSON response from Anthropic: ${parseError instanceof Error ? parseError.message : 'Unknown error'}`);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
else {
|
|
225
|
-
throw new Error('Unexpected response type from Anthropic');
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
catch (error) {
|
|
229
|
-
throw new Error(`Failed to generate chapters with Anthropic: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
else {
|
|
233
|
-
throw new Error(`Unsupported provider: ${provider}`);
|
|
234
|
-
}
|
|
235
|
-
if (!chaptersData || !chaptersData.chapters) {
|
|
236
|
-
throw new Error('No chapters generated from AI response');
|
|
237
|
-
}
|
|
238
|
-
// Validate and sort chapters
|
|
239
|
-
const validChapters = chaptersData.chapters
|
|
240
|
-
.filter(chapter => typeof chapter.startTime === 'number' && typeof chapter.title === 'string')
|
|
241
|
-
.sort((a, b) => a.startTime - b.startTime);
|
|
242
|
-
if (validChapters.length === 0) {
|
|
243
|
-
throw new Error('No valid chapters found in AI response');
|
|
244
|
-
}
|
|
245
|
-
// Ensure first chapter starts at 0
|
|
246
|
-
if (validChapters[0].startTime !== 0) {
|
|
247
|
-
validChapters[0].startTime = 0;
|
|
248
|
-
}
|
|
249
|
-
return {
|
|
250
|
-
assetId,
|
|
251
|
-
languageCode,
|
|
252
|
-
chapters: validChapters,
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
//# sourceMappingURL=chapters.js.map
|
package/dist/chapters.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"chapters.js","sourceRoot":"","sources":["../src/chapters.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AAErC,eAAO,MAAM,OAAO,UAAU,CAAC"}
|
package/dist/moderation.d.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { MuxAIOptions } from './types';
|
|
2
|
-
import { ImageDownloadOptions } from './utils/image-download';
|
|
3
|
-
export interface ThumbnailModerationScore {
|
|
4
|
-
url: string;
|
|
5
|
-
sexual: number;
|
|
6
|
-
violence: number;
|
|
7
|
-
error: boolean;
|
|
8
|
-
}
|
|
9
|
-
export interface ModerationResult {
|
|
10
|
-
assetId: string;
|
|
11
|
-
thumbnailScores: ThumbnailModerationScore[];
|
|
12
|
-
maxScores: {
|
|
13
|
-
sexual: number;
|
|
14
|
-
violence: number;
|
|
15
|
-
};
|
|
16
|
-
exceedsThreshold: boolean;
|
|
17
|
-
thresholds: {
|
|
18
|
-
sexual: number;
|
|
19
|
-
violence: number;
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
export interface ModerationOptions extends MuxAIOptions {
|
|
23
|
-
provider?: 'openai' | 'hive';
|
|
24
|
-
model?: string;
|
|
25
|
-
thresholds?: {
|
|
26
|
-
sexual?: number;
|
|
27
|
-
violence?: number;
|
|
28
|
-
};
|
|
29
|
-
thumbnailInterval?: number;
|
|
30
|
-
thumbnailWidth?: number;
|
|
31
|
-
maxConcurrent?: number;
|
|
32
|
-
/** Method for submitting images to AI providers (default: 'url') */
|
|
33
|
-
imageSubmissionMode?: 'url' | 'base64';
|
|
34
|
-
/** Options for image download when using base64 submission mode */
|
|
35
|
-
imageDownloadOptions?: ImageDownloadOptions;
|
|
36
|
-
hiveApiKey?: string;
|
|
37
|
-
}
|
|
38
|
-
export declare function getModerationScores(assetId: string, options?: ModerationOptions): Promise<ModerationResult>;
|
|
39
|
-
//# sourceMappingURL=moderation.d.ts.map
|
package/dist/moderation.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"moderation.d.ts","sourceRoot":"","sources":["../src/moderation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,oBAAoB,EAA0B,MAAM,wBAAwB,CAAC;AAEtF,MAAM,WAAW,wBAAwB;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,wBAAwB,EAAE,CAAC;IAC5C,SAAS,EAAE;QACT,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,gBAAgB,EAAE,OAAO,CAAC;IAC1B,UAAU,EAAE;QACV,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACrD,QAAQ,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE;QACX,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oEAAoE;IACpE,mBAAmB,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IACvC,mEAAmE;IACnE,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAwUD,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAoH3B"}
|