@brickgale/caption-sync 1.0.0
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 +21 -0
- package/README.md +261 -0
- package/dist/components/Video.d.ts +29 -0
- package/dist/components/Video.d.ts.map +1 -0
- package/dist/components/Video.js +243 -0
- package/dist/components/Video.js.map +1 -0
- package/dist/config.d.ts +148 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +141 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/elevenlabs-provider.d.ts +13 -0
- package/dist/providers/elevenlabs-provider.d.ts.map +1 -0
- package/dist/providers/elevenlabs-provider.js +117 -0
- package/dist/providers/elevenlabs-provider.js.map +1 -0
- package/dist/providers/index.d.ts +30 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +47 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/openai-provider.d.ts +13 -0
- package/dist/providers/openai-provider.d.ts.map +1 -0
- package/dist/providers/openai-provider.js +85 -0
- package/dist/providers/openai-provider.js.map +1 -0
- package/dist/providers/transcription-provider.d.ts +37 -0
- package/dist/providers/transcription-provider.d.ts.map +1 -0
- package/dist/providers/transcription-provider.js +9 -0
- package/dist/providers/transcription-provider.js.map +1 -0
- package/dist/types/index.d.ts +106 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/caption-generator.d.ts +128 -0
- package/dist/utils/caption-generator.d.ts.map +1 -0
- package/dist/utils/caption-generator.js +400 -0
- package/dist/utils/caption-generator.js.map +1 -0
- package/dist/utils/transcription.d.ts +96 -0
- package/dist/utils/transcription.d.ts.map +1 -0
- package/dist/utils/transcription.js +280 -0
- package/dist/utils/transcription.js.map +1 -0
- package/dist/utils/video-renderer.d.ts +58 -0
- package/dist/utils/video-renderer.d.ts.map +1 -0
- package/dist/utils/video-renderer.js +153 -0
- package/dist/utils/video-renderer.js.map +1 -0
- package/package.json +80 -0
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration constants for caption generation and styling
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Caption display configuration
|
|
6
|
+
*/
|
|
7
|
+
export declare const CaptionConfig: {
|
|
8
|
+
/**
|
|
9
|
+
* Maximum characters per caption entry
|
|
10
|
+
* Captions will be split when exceeding this limit
|
|
11
|
+
*/
|
|
12
|
+
readonly MAX_CHARACTERS_PER_CAPTION: 25;
|
|
13
|
+
/**
|
|
14
|
+
* Minimum pause duration (in seconds) to consider as a natural break point
|
|
15
|
+
* Captions will prefer to split at pauses longer than this duration
|
|
16
|
+
*/
|
|
17
|
+
readonly MIN_PAUSE_DURATION: 0.3;
|
|
18
|
+
/**
|
|
19
|
+
* Minimum words per caption (will try to keep at least this many)
|
|
20
|
+
* Helps avoid single-word captions unless necessary
|
|
21
|
+
*/
|
|
22
|
+
readonly MIN_WORDS_PER_CAPTION: 2;
|
|
23
|
+
/**
|
|
24
|
+
* Video resolution presets
|
|
25
|
+
*/
|
|
26
|
+
readonly RESOLUTION: {
|
|
27
|
+
/** Full HD 1080p (1920x1080) */
|
|
28
|
+
readonly FHD: {
|
|
29
|
+
readonly width: 1920;
|
|
30
|
+
readonly height: 1080;
|
|
31
|
+
};
|
|
32
|
+
/** HD 720p (1280x720) */
|
|
33
|
+
readonly HD: {
|
|
34
|
+
readonly width: 1280;
|
|
35
|
+
readonly height: 720;
|
|
36
|
+
};
|
|
37
|
+
/** Square for social media (1080x1080) */
|
|
38
|
+
readonly SQUARE: {
|
|
39
|
+
readonly width: 1080;
|
|
40
|
+
readonly height: 1080;
|
|
41
|
+
};
|
|
42
|
+
/** Vertical for mobile (1080x1920) */
|
|
43
|
+
readonly VERTICAL: {
|
|
44
|
+
readonly width: 1080;
|
|
45
|
+
readonly height: 1920;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Caption placement options
|
|
50
|
+
*/
|
|
51
|
+
readonly PLACEMENT: {
|
|
52
|
+
/** Center top */
|
|
53
|
+
readonly CENTER_TOP: "center-top";
|
|
54
|
+
/** Center bottom */
|
|
55
|
+
readonly CENTER_BOTTOM: "center-bottom";
|
|
56
|
+
/** Center middle */
|
|
57
|
+
readonly CENTER: "center";
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Animation presets for caption entrance/exit
|
|
61
|
+
*/
|
|
62
|
+
readonly ANIMATION: {
|
|
63
|
+
/** Fade in/out animation */
|
|
64
|
+
readonly FADE: "fade";
|
|
65
|
+
/** Slide up from bottom with fade (subtle, 20px movement) */
|
|
66
|
+
readonly SLIDE_UP: "slide-up";
|
|
67
|
+
/** No animation */
|
|
68
|
+
readonly NONE: "none";
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Caption styling configuration
|
|
72
|
+
*/
|
|
73
|
+
readonly STYLE: {
|
|
74
|
+
/** Font size in pixels */
|
|
75
|
+
readonly fontSize: 48;
|
|
76
|
+
/** Font family */
|
|
77
|
+
readonly fontFamily: "Archivo Black, sans-serif";
|
|
78
|
+
/** Google Fonts URL to import (set to null if using system fonts) */
|
|
79
|
+
readonly googleFontsUrl: "https://fonts.googleapis.com/css2?family=Archivo+Black&display=swap";
|
|
80
|
+
/** Letter spacing in pixels */
|
|
81
|
+
readonly letterSpacing: "0px";
|
|
82
|
+
/** Text color */
|
|
83
|
+
readonly textColor: "#FFFFFF";
|
|
84
|
+
/** Background color for caption text box (use null for no background) */
|
|
85
|
+
readonly captionBackgroundColor: null;
|
|
86
|
+
/** Canvas/video background color for chroma keying */
|
|
87
|
+
readonly canvasBackgroundColor: "#00FF00";
|
|
88
|
+
/** Text shadow - using multiple shadows to create outside stroke + drop shadow */
|
|
89
|
+
readonly textShadow: string;
|
|
90
|
+
/** Text stroke/border width - SET TO NULL (using text-shadow for outline instead) */
|
|
91
|
+
readonly textStrokeWidth: null;
|
|
92
|
+
/** Text stroke/border color - SET TO NULL (using text-shadow for outline instead) */
|
|
93
|
+
readonly textStrokeColor: null;
|
|
94
|
+
/** Border radius */
|
|
95
|
+
readonly borderRadius: "10px";
|
|
96
|
+
/** Padding for text box (only applies if captionBackgroundColor is set) */
|
|
97
|
+
readonly padding: "20px 40px";
|
|
98
|
+
/** Bottom padding for caption container positioning (affects vertical position) */
|
|
99
|
+
readonly paddingBottom: "600px";
|
|
100
|
+
/** Left/right padding for caption container (affects horizontal margins) */
|
|
101
|
+
readonly paddingHorizontal: "100px";
|
|
102
|
+
/** Maximum width of caption text (e.g., '90vw', '80%', '800px') */
|
|
103
|
+
readonly maxWidth: "90vw";
|
|
104
|
+
/** Font weight */
|
|
105
|
+
readonly fontWeight: "bold";
|
|
106
|
+
/** Default animation preset */
|
|
107
|
+
readonly animation: "fade" | "slide-up" | "none";
|
|
108
|
+
/** Highlight color for active words (word-by-word highlighting) */
|
|
109
|
+
readonly highlightColor: "#03e6ff";
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Speech-to-text configuration
|
|
114
|
+
*/
|
|
115
|
+
export declare const TranscriptionConfig: {
|
|
116
|
+
/**
|
|
117
|
+
* OpenAI Whisper model to use
|
|
118
|
+
* Options: 'whisper-1'
|
|
119
|
+
*/
|
|
120
|
+
readonly MODEL: "whisper-1";
|
|
121
|
+
/**
|
|
122
|
+
* Language for transcription (optional, auto-detect if not specified)
|
|
123
|
+
*/
|
|
124
|
+
readonly LANGUAGE: "en";
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* Text sanitization configuration
|
|
128
|
+
*/
|
|
129
|
+
export declare const TextSanitizationConfig: {
|
|
130
|
+
/**
|
|
131
|
+
* Characters to remove from text (keep only alphanumeric and basic punctuation)
|
|
132
|
+
*/
|
|
133
|
+
readonly ALLOWED_PATTERN: RegExp;
|
|
134
|
+
/**
|
|
135
|
+
* Normalize whitespace
|
|
136
|
+
*/
|
|
137
|
+
readonly NORMALIZE_WHITESPACE: true;
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* Type definitions for configuration
|
|
141
|
+
*/
|
|
142
|
+
export type CaptionPlacement = (typeof CaptionConfig.PLACEMENT)[keyof typeof CaptionConfig.PLACEMENT];
|
|
143
|
+
export type CaptionAnimation = (typeof CaptionConfig.ANIMATION)[keyof typeof CaptionConfig.ANIMATION];
|
|
144
|
+
export type Resolution = {
|
|
145
|
+
width: number;
|
|
146
|
+
height: number;
|
|
147
|
+
};
|
|
148
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/lib/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,eAAO,MAAM,aAAa;IACxB;;;OAGG;;IAGH;;;OAGG;;IAGH;;;OAGG;;IAGH;;OAEG;;QAED,gCAAgC;;;;;QAEhC,yBAAyB;;;;;QAEzB,0CAA0C;;;;;QAE1C,sCAAsC;;;;;;IAIxC;;OAEG;;QAED,iBAAiB;;QAEjB,oBAAoB;;QAEpB,oBAAoB;;;IAItB;;OAEG;;QAED,4BAA4B;;QAE5B,6DAA6D;;QAE7D,mBAAmB;;;IAIrB;;OAEG;;QAED,0BAA0B;;QAE1B,kBAAkB;;QAElB,qEAAqE;;QAGrE,+BAA+B;;QAE/B,iBAAiB;;QAEjB,yEAAyE;;QAEzE,sDAAsD;;QAEtD,kFAAkF;;QAalF,qFAAqF;;QAErF,qFAAqF;;QAErF,oBAAoB;;QAEpB,2EAA2E;;QAE3E,mFAAmF;;QAEnF,4EAA4E;;QAE5E,mEAAmE;;QAEnE,kBAAkB;;QAElB,+BAA+B;4BACN,MAAM,GAAG,UAAU,GAAG,MAAM;QACrD,mEAAmE;;;CAG7D,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,mBAAmB;IAC9B;;;OAGG;;IAGH;;OAEG;;CAEK,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,sBAAsB;IACjC;;OAEG;;IAGH;;OAEG;;CAEK,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAC1B,CAAC,OAAO,aAAa,CAAC,SAAS,CAAC,CAAC,MAAM,OAAO,aAAa,CAAC,SAAS,CAAC,CAAC;AAEzE,MAAM,MAAM,gBAAgB,GAC1B,CAAC,OAAO,aAAa,CAAC,SAAS,CAAC,CAAC,MAAM,OAAO,aAAa,CAAC,SAAS,CAAC,CAAC;AAEzE,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Configuration constants for caption generation and styling
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.TextSanitizationConfig = exports.TranscriptionConfig = exports.CaptionConfig = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Caption display configuration
|
|
9
|
+
*/
|
|
10
|
+
exports.CaptionConfig = {
|
|
11
|
+
/**
|
|
12
|
+
* Maximum characters per caption entry
|
|
13
|
+
* Captions will be split when exceeding this limit
|
|
14
|
+
*/
|
|
15
|
+
MAX_CHARACTERS_PER_CAPTION: 25,
|
|
16
|
+
/**
|
|
17
|
+
* Minimum pause duration (in seconds) to consider as a natural break point
|
|
18
|
+
* Captions will prefer to split at pauses longer than this duration
|
|
19
|
+
*/
|
|
20
|
+
MIN_PAUSE_DURATION: 0.3,
|
|
21
|
+
/**
|
|
22
|
+
* Minimum words per caption (will try to keep at least this many)
|
|
23
|
+
* Helps avoid single-word captions unless necessary
|
|
24
|
+
*/
|
|
25
|
+
MIN_WORDS_PER_CAPTION: 2,
|
|
26
|
+
/**
|
|
27
|
+
* Video resolution presets
|
|
28
|
+
*/
|
|
29
|
+
RESOLUTION: {
|
|
30
|
+
/** Full HD 1080p (1920x1080) */
|
|
31
|
+
FHD: { width: 1920, height: 1080 },
|
|
32
|
+
/** HD 720p (1280x720) */
|
|
33
|
+
HD: { width: 1280, height: 720 },
|
|
34
|
+
/** Square for social media (1080x1080) */
|
|
35
|
+
SQUARE: { width: 1080, height: 1080 },
|
|
36
|
+
/** Vertical for mobile (1080x1920) */
|
|
37
|
+
VERTICAL: { width: 1080, height: 1920 },
|
|
38
|
+
},
|
|
39
|
+
/**
|
|
40
|
+
* Caption placement options
|
|
41
|
+
*/
|
|
42
|
+
PLACEMENT: {
|
|
43
|
+
/** Center top */
|
|
44
|
+
CENTER_TOP: 'center-top',
|
|
45
|
+
/** Center bottom */
|
|
46
|
+
CENTER_BOTTOM: 'center-bottom',
|
|
47
|
+
/** Center middle */
|
|
48
|
+
CENTER: 'center',
|
|
49
|
+
},
|
|
50
|
+
/**
|
|
51
|
+
* Animation presets for caption entrance/exit
|
|
52
|
+
*/
|
|
53
|
+
ANIMATION: {
|
|
54
|
+
/** Fade in/out animation */
|
|
55
|
+
FADE: 'fade',
|
|
56
|
+
/** Slide up from bottom with fade (subtle, 20px movement) */
|
|
57
|
+
SLIDE_UP: 'slide-up',
|
|
58
|
+
/** No animation */
|
|
59
|
+
NONE: 'none',
|
|
60
|
+
},
|
|
61
|
+
/**
|
|
62
|
+
* Caption styling configuration
|
|
63
|
+
*/
|
|
64
|
+
STYLE: {
|
|
65
|
+
/** Font size in pixels */
|
|
66
|
+
fontSize: 48,
|
|
67
|
+
/** Font family */
|
|
68
|
+
fontFamily: 'Archivo Black, sans-serif',
|
|
69
|
+
/** Google Fonts URL to import (set to null if using system fonts) */
|
|
70
|
+
googleFontsUrl: 'https://fonts.googleapis.com/css2?family=Archivo+Black&display=swap',
|
|
71
|
+
/** Letter spacing in pixels */
|
|
72
|
+
letterSpacing: '0px',
|
|
73
|
+
/** Text color */
|
|
74
|
+
textColor: '#FFFFFF',
|
|
75
|
+
/** Background color for caption text box (use null for no background) */
|
|
76
|
+
captionBackgroundColor: null, // No background on text, using canvas background instead
|
|
77
|
+
/** Canvas/video background color for chroma keying */
|
|
78
|
+
canvasBackgroundColor: '#00FF00', // Pure green for chroma key
|
|
79
|
+
/** Text shadow - using multiple shadows to create outside stroke + drop shadow */
|
|
80
|
+
textShadow:
|
|
81
|
+
// Black outline (outside stroke effect using 8-point shadows)
|
|
82
|
+
'-3px -3px 0 #000, 3px -3px 0 #000, -3px 3px 0 #000, 3px 3px 0 #000, ' +
|
|
83
|
+
'-3px 0 0 #000, 3px 0 0 #000, 0 -3px 0 #000, 0 3px 0 #000, ' +
|
|
84
|
+
// Middle layer (2px) to fill gaps
|
|
85
|
+
'-3px -3px 0 #000, 3px -3px 0 #000, -3px 3px 0 #000, 3px 3px 0 #000, ' +
|
|
86
|
+
'-3px 0 0 #000, 3px 0 0 #000, 0 -3px 0 #000, 0 3px 0 #000, ' +
|
|
87
|
+
// Inner layer (1px) for smoother outline
|
|
88
|
+
'8px 8px 0 #000, 8px 8px 0 #000, 6px 6px 0 #000, 8px 8px 0 #000, ' +
|
|
89
|
+
'0 0 0 #000, 8px 8px 0 #000, 8px 8px 0 #000, 8px 8px 0 #000, ' +
|
|
90
|
+
// Drop shadow for depth
|
|
91
|
+
'3px 6px 0 rgba(0, 0, 0, 1)',
|
|
92
|
+
/** Text stroke/border width - SET TO NULL (using text-shadow for outline instead) */
|
|
93
|
+
textStrokeWidth: null,
|
|
94
|
+
/** Text stroke/border color - SET TO NULL (using text-shadow for outline instead) */
|
|
95
|
+
textStrokeColor: null,
|
|
96
|
+
/** Border radius */
|
|
97
|
+
borderRadius: '10px',
|
|
98
|
+
/** Padding for text box (only applies if captionBackgroundColor is set) */
|
|
99
|
+
padding: '20px 40px',
|
|
100
|
+
/** Bottom padding for caption container positioning (affects vertical position) */
|
|
101
|
+
paddingBottom: '600px',
|
|
102
|
+
/** Left/right padding for caption container (affects horizontal margins) */
|
|
103
|
+
paddingHorizontal: '100px',
|
|
104
|
+
/** Maximum width of caption text (e.g., '90vw', '80%', '800px') */
|
|
105
|
+
maxWidth: '90vw',
|
|
106
|
+
/** Font weight */
|
|
107
|
+
fontWeight: 'bold',
|
|
108
|
+
/** Default animation preset */
|
|
109
|
+
animation: 'slide-up',
|
|
110
|
+
/** Highlight color for active words (word-by-word highlighting) */
|
|
111
|
+
highlightColor: '#03e6ff',
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Speech-to-text configuration
|
|
116
|
+
*/
|
|
117
|
+
exports.TranscriptionConfig = {
|
|
118
|
+
/**
|
|
119
|
+
* OpenAI Whisper model to use
|
|
120
|
+
* Options: 'whisper-1'
|
|
121
|
+
*/
|
|
122
|
+
MODEL: 'whisper-1',
|
|
123
|
+
/**
|
|
124
|
+
* Language for transcription (optional, auto-detect if not specified)
|
|
125
|
+
*/
|
|
126
|
+
LANGUAGE: 'en',
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* Text sanitization configuration
|
|
130
|
+
*/
|
|
131
|
+
exports.TextSanitizationConfig = {
|
|
132
|
+
/**
|
|
133
|
+
* Characters to remove from text (keep only alphanumeric and basic punctuation)
|
|
134
|
+
*/
|
|
135
|
+
ALLOWED_PATTERN: /[^a-zA-Z0-9\s.,!?;:'"()]/g,
|
|
136
|
+
/**
|
|
137
|
+
* Normalize whitespace
|
|
138
|
+
*/
|
|
139
|
+
NORMALIZE_WHITESPACE: true,
|
|
140
|
+
};
|
|
141
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/lib/config.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH;;GAEG;AACU,QAAA,aAAa,GAAG;IAC3B;;;OAGG;IACH,0BAA0B,EAAE,EAAE;IAE9B;;;OAGG;IACH,kBAAkB,EAAE,GAAG;IAEvB;;;OAGG;IACH,qBAAqB,EAAE,CAAC;IAExB;;OAEG;IACH,UAAU,EAAE;QACV,gCAAgC;QAChC,GAAG,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;QAClC,yBAAyB;QACzB,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE;QAChC,0CAA0C;QAC1C,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;QACrC,sCAAsC;QACtC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE;KACxC;IAED;;OAEG;IACH,SAAS,EAAE;QACT,iBAAiB;QACjB,UAAU,EAAE,YAAY;QACxB,oBAAoB;QACpB,aAAa,EAAE,eAAe;QAC9B,oBAAoB;QACpB,MAAM,EAAE,QAAQ;KACR;IAEV;;OAEG;IACH,SAAS,EAAE;QACT,4BAA4B;QAC5B,IAAI,EAAE,MAAM;QACZ,6DAA6D;QAC7D,QAAQ,EAAE,UAAU;QACpB,mBAAmB;QACnB,IAAI,EAAE,MAAM;KACJ;IAEV;;OAEG;IACH,KAAK,EAAE;QACL,0BAA0B;QAC1B,QAAQ,EAAE,EAAE;QACZ,kBAAkB;QAClB,UAAU,EAAE,2BAA2B;QACvC,qEAAqE;QACrE,cAAc,EACZ,qEAAqE;QACvE,+BAA+B;QAC/B,aAAa,EAAE,KAAK;QACpB,iBAAiB;QACjB,SAAS,EAAE,SAAS;QACpB,yEAAyE;QACzE,sBAAsB,EAAE,IAAI,EAAE,yDAAyD;QACvF,sDAAsD;QACtD,qBAAqB,EAAE,SAAS,EAAE,4BAA4B;QAC9D,kFAAkF;QAClF,UAAU;QACR,8DAA8D;QAC9D,sEAAsE;YACtE,4DAA4D;YAC5D,kCAAkC;YAClC,sEAAsE;YACtE,4DAA4D;YAC5D,yCAAyC;YACzC,kEAAkE;YAClE,8DAA8D;YAC9D,wBAAwB;YACxB,4BAA4B;QAC9B,qFAAqF;QACrF,eAAe,EAAE,IAAI;QACrB,qFAAqF;QACrF,eAAe,EAAE,IAAI;QACrB,oBAAoB;QACpB,YAAY,EAAE,MAAM;QACpB,2EAA2E;QAC3E,OAAO,EAAE,WAAW;QACpB,mFAAmF;QACnF,aAAa,EAAE,OAAO;QACtB,4EAA4E;QAC5E,iBAAiB,EAAE,OAAO;QAC1B,mEAAmE;QACnE,QAAQ,EAAE,MAAM;QAChB,kBAAkB;QAClB,UAAU,EAAE,MAAe;QAC3B,+BAA+B;QAC/B,SAAS,EAAE,UAA0C;QACrD,mEAAmE;QACnE,cAAc,EAAE,SAAS;KAC1B;CACO,CAAC;AAEX;;GAEG;AACU,QAAA,mBAAmB,GAAG;IACjC;;;OAGG;IACH,KAAK,EAAE,WAAW;IAElB;;OAEG;IACH,QAAQ,EAAE,IAAI;CACN,CAAC;AAEX;;GAEG;AACU,QAAA,sBAAsB,GAAG;IACpC;;OAEG;IACH,eAAe,EAAE,2BAA2B;IAE5C;;OAEG;IACH,oBAAoB,EAAE,IAAI;CAClB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Caption Sync - Video generation with automatic caption timing
|
|
3
|
+
*
|
|
4
|
+
* This library provides functions for generating captions with weighted
|
|
5
|
+
* timing based on word count, and rendering videos with synchronized
|
|
6
|
+
* captions using Remotion.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { generateVideo } from 'caption-sync';
|
|
13
|
+
*
|
|
14
|
+
* // Generate captions and render video in one step
|
|
15
|
+
* const captions = generateVideo({
|
|
16
|
+
* scriptPath: './script.txt',
|
|
17
|
+
* audioPath: './audio.mp3',
|
|
18
|
+
* outputPath: './out/video.mp4'
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export type { Caption, VideoProps, GenerateCaptionsOptions, RenderVideoOptions, GenerateVideoOptions, TranscribeAudioOptions, TextComparisonResult, } from './types';
|
|
23
|
+
export { CaptionConfig, TranscriptionConfig, TextSanitizationConfig, } from './config';
|
|
24
|
+
export type { CaptionPlacement, CaptionAnimation, Resolution } from './config';
|
|
25
|
+
export { generateCaptions, generateCaptionsFromText, generateCaptionsFromWordTimestamps, getAudioDuration, splitIntoPhrases, countWords, splitByCharacterLimit, } from './utils/caption-generator';
|
|
26
|
+
export { transcribeAudio, transcribeAudioWithTimestamps, sanitizeText, compareTexts, generateCorrections, } from './utils/transcription';
|
|
27
|
+
export { createTranscriptionProvider } from './providers';
|
|
28
|
+
export { OpenAIProvider } from './providers/openai-provider';
|
|
29
|
+
export { ElevenLabsProvider } from './providers/elevenlabs-provider';
|
|
30
|
+
export type { TranscriptionProvider, TranscriptionProviderConfig, WordTimestamp, } from './providers/transcription-provider';
|
|
31
|
+
export { renderVideo, generateVideo } from './utils/video-renderer';
|
|
32
|
+
export { Video } from './components/Video';
|
|
33
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,YAAY,EACV,OAAO,EACP,UAAU,EACV,uBAAuB,EACvB,kBAAkB,EAClB,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAG/E,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,kCAAkC,EAClC,gBAAgB,EAChB,gBAAgB,EAChB,UAAU,EACV,qBAAqB,GACtB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EACL,eAAe,EACf,6BAA6B,EAC7B,YAAY,EACZ,YAAY,EACZ,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,YAAY,EACV,qBAAqB,EACrB,2BAA2B,EAC3B,aAAa,GACd,MAAM,oCAAoC,CAAC;AAG5C,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAGpE,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Caption Sync - Video generation with automatic caption timing
|
|
4
|
+
*
|
|
5
|
+
* This library provides functions for generating captions with weighted
|
|
6
|
+
* timing based on word count, and rendering videos with synchronized
|
|
7
|
+
* captions using Remotion.
|
|
8
|
+
*
|
|
9
|
+
* @packageDocumentation
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { generateVideo } from 'caption-sync';
|
|
14
|
+
*
|
|
15
|
+
* // Generate captions and render video in one step
|
|
16
|
+
* const captions = generateVideo({
|
|
17
|
+
* scriptPath: './script.txt',
|
|
18
|
+
* audioPath: './audio.mp3',
|
|
19
|
+
* outputPath: './out/video.mp4'
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.Video = exports.generateVideo = exports.renderVideo = exports.ElevenLabsProvider = exports.OpenAIProvider = exports.createTranscriptionProvider = exports.generateCorrections = exports.compareTexts = exports.sanitizeText = exports.transcribeAudioWithTimestamps = exports.transcribeAudio = exports.splitByCharacterLimit = exports.countWords = exports.splitIntoPhrases = exports.getAudioDuration = exports.generateCaptionsFromWordTimestamps = exports.generateCaptionsFromText = exports.generateCaptions = exports.TextSanitizationConfig = exports.TranscriptionConfig = exports.CaptionConfig = void 0;
|
|
25
|
+
// Export configuration
|
|
26
|
+
var config_1 = require("./config");
|
|
27
|
+
Object.defineProperty(exports, "CaptionConfig", { enumerable: true, get: function () { return config_1.CaptionConfig; } });
|
|
28
|
+
Object.defineProperty(exports, "TranscriptionConfig", { enumerable: true, get: function () { return config_1.TranscriptionConfig; } });
|
|
29
|
+
Object.defineProperty(exports, "TextSanitizationConfig", { enumerable: true, get: function () { return config_1.TextSanitizationConfig; } });
|
|
30
|
+
// Export caption generation functions
|
|
31
|
+
var caption_generator_1 = require("./utils/caption-generator");
|
|
32
|
+
Object.defineProperty(exports, "generateCaptions", { enumerable: true, get: function () { return caption_generator_1.generateCaptions; } });
|
|
33
|
+
Object.defineProperty(exports, "generateCaptionsFromText", { enumerable: true, get: function () { return caption_generator_1.generateCaptionsFromText; } });
|
|
34
|
+
Object.defineProperty(exports, "generateCaptionsFromWordTimestamps", { enumerable: true, get: function () { return caption_generator_1.generateCaptionsFromWordTimestamps; } });
|
|
35
|
+
Object.defineProperty(exports, "getAudioDuration", { enumerable: true, get: function () { return caption_generator_1.getAudioDuration; } });
|
|
36
|
+
Object.defineProperty(exports, "splitIntoPhrases", { enumerable: true, get: function () { return caption_generator_1.splitIntoPhrases; } });
|
|
37
|
+
Object.defineProperty(exports, "countWords", { enumerable: true, get: function () { return caption_generator_1.countWords; } });
|
|
38
|
+
Object.defineProperty(exports, "splitByCharacterLimit", { enumerable: true, get: function () { return caption_generator_1.splitByCharacterLimit; } });
|
|
39
|
+
// Export transcription and text comparison functions
|
|
40
|
+
var transcription_1 = require("./utils/transcription");
|
|
41
|
+
Object.defineProperty(exports, "transcribeAudio", { enumerable: true, get: function () { return transcription_1.transcribeAudio; } });
|
|
42
|
+
Object.defineProperty(exports, "transcribeAudioWithTimestamps", { enumerable: true, get: function () { return transcription_1.transcribeAudioWithTimestamps; } });
|
|
43
|
+
Object.defineProperty(exports, "sanitizeText", { enumerable: true, get: function () { return transcription_1.sanitizeText; } });
|
|
44
|
+
Object.defineProperty(exports, "compareTexts", { enumerable: true, get: function () { return transcription_1.compareTexts; } });
|
|
45
|
+
Object.defineProperty(exports, "generateCorrections", { enumerable: true, get: function () { return transcription_1.generateCorrections; } });
|
|
46
|
+
// Export transcription providers (Strategy Pattern)
|
|
47
|
+
var providers_1 = require("./providers");
|
|
48
|
+
Object.defineProperty(exports, "createTranscriptionProvider", { enumerable: true, get: function () { return providers_1.createTranscriptionProvider; } });
|
|
49
|
+
var openai_provider_1 = require("./providers/openai-provider");
|
|
50
|
+
Object.defineProperty(exports, "OpenAIProvider", { enumerable: true, get: function () { return openai_provider_1.OpenAIProvider; } });
|
|
51
|
+
var elevenlabs_provider_1 = require("./providers/elevenlabs-provider");
|
|
52
|
+
Object.defineProperty(exports, "ElevenLabsProvider", { enumerable: true, get: function () { return elevenlabs_provider_1.ElevenLabsProvider; } });
|
|
53
|
+
// Export video rendering functions
|
|
54
|
+
var video_renderer_1 = require("./utils/video-renderer");
|
|
55
|
+
Object.defineProperty(exports, "renderVideo", { enumerable: true, get: function () { return video_renderer_1.renderVideo; } });
|
|
56
|
+
Object.defineProperty(exports, "generateVideo", { enumerable: true, get: function () { return video_renderer_1.generateVideo; } });
|
|
57
|
+
// Export Video component
|
|
58
|
+
var Video_1 = require("./components/Video");
|
|
59
|
+
Object.defineProperty(exports, "Video", { enumerable: true, get: function () { return Video_1.Video; } });
|
|
60
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;AAaH,uBAAuB;AACvB,mCAIkB;AAHhB,uGAAA,aAAa,OAAA;AACb,6GAAA,mBAAmB,OAAA;AACnB,gHAAA,sBAAsB,OAAA;AAIxB,sCAAsC;AACtC,+DAQmC;AAPjC,qHAAA,gBAAgB,OAAA;AAChB,6HAAA,wBAAwB,OAAA;AACxB,uIAAA,kCAAkC,OAAA;AAClC,qHAAA,gBAAgB,OAAA;AAChB,qHAAA,gBAAgB,OAAA;AAChB,+GAAA,UAAU,OAAA;AACV,0HAAA,qBAAqB,OAAA;AAGvB,qDAAqD;AACrD,uDAM+B;AAL7B,gHAAA,eAAe,OAAA;AACf,8HAAA,6BAA6B,OAAA;AAC7B,6GAAA,YAAY,OAAA;AACZ,6GAAA,YAAY,OAAA;AACZ,oHAAA,mBAAmB,OAAA;AAGrB,oDAAoD;AACpD,yCAA0D;AAAjD,wHAAA,2BAA2B,OAAA;AACpC,+DAA6D;AAApD,iHAAA,cAAc,OAAA;AACvB,uEAAqE;AAA5D,yHAAA,kBAAkB,OAAA;AAO3B,mCAAmC;AACnC,yDAAoE;AAA3D,6GAAA,WAAW,OAAA;AAAE,+GAAA,aAAa,OAAA;AAEnC,yBAAyB;AACzB,4CAA2C;AAAlC,8FAAA,KAAK,OAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ElevenLabs Speech-to-Text Provider
|
|
3
|
+
*/
|
|
4
|
+
import type { TranscriptionProvider, WordTimestamp } from './transcription-provider';
|
|
5
|
+
export declare class ElevenLabsProvider implements TranscriptionProvider {
|
|
6
|
+
readonly name = "ElevenLabs";
|
|
7
|
+
private apiKey;
|
|
8
|
+
private language;
|
|
9
|
+
private model;
|
|
10
|
+
constructor(apiKey: string, language?: string, model?: string);
|
|
11
|
+
transcribeWithTimestamps(audioPath: string, options?: Record<string, any>): Promise<WordTimestamp[]>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=elevenlabs-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elevenlabs-provider.d.ts","sourceRoot":"","sources":["../../src/lib/providers/elevenlabs-provider.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EACV,qBAAqB,EACrB,aAAa,EACd,MAAM,0BAA0B,CAAC;AAElC,qBAAa,kBAAmB,YAAW,qBAAqB;IAC9D,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,KAAK,CAAS;gBAGpB,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,MAAa,EACvB,KAAK,GAAE,MAAoB;IAOvB,wBAAwB,CAC5B,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC5B,OAAO,CAAC,aAAa,EAAE,CAAC;CAkF5B"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ElevenLabs Speech-to-Text Provider
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.ElevenLabsProvider = void 0;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const https = __importStar(require("https"));
|
|
42
|
+
class ElevenLabsProvider {
|
|
43
|
+
constructor(apiKey, language = 'en', model = 'scribe_v2') {
|
|
44
|
+
this.name = 'ElevenLabs';
|
|
45
|
+
this.apiKey = apiKey;
|
|
46
|
+
this.language = language;
|
|
47
|
+
this.model = model;
|
|
48
|
+
}
|
|
49
|
+
async transcribeWithTimestamps(audioPath, options) {
|
|
50
|
+
if (!fs.existsSync(audioPath)) {
|
|
51
|
+
throw new Error(`Audio file not found: ${audioPath}`);
|
|
52
|
+
}
|
|
53
|
+
const language = options?.language || this.language;
|
|
54
|
+
const model = options?.model || this.model;
|
|
55
|
+
try {
|
|
56
|
+
console.log(`🎤 Transcribing with ${this.name}...`);
|
|
57
|
+
// Create form data for multipart upload
|
|
58
|
+
const FormData = (await Promise.resolve().then(() => __importStar(require('form-data')))).default;
|
|
59
|
+
const formData = new FormData();
|
|
60
|
+
formData.append('file', fs.createReadStream(audioPath));
|
|
61
|
+
formData.append('model_id', model);
|
|
62
|
+
formData.append('language_code', language);
|
|
63
|
+
// Send request to ElevenLabs API using https module
|
|
64
|
+
const result = await new Promise((resolve, reject) => {
|
|
65
|
+
const req = https.request({
|
|
66
|
+
hostname: 'api.elevenlabs.io',
|
|
67
|
+
path: '/v1/speech-to-text',
|
|
68
|
+
method: 'POST',
|
|
69
|
+
headers: {
|
|
70
|
+
'xi-api-key': this.apiKey,
|
|
71
|
+
...formData.getHeaders(),
|
|
72
|
+
},
|
|
73
|
+
}, res => {
|
|
74
|
+
let data = '';
|
|
75
|
+
res.on('data', chunk => (data += chunk));
|
|
76
|
+
res.on('end', () => {
|
|
77
|
+
if (res.statusCode &&
|
|
78
|
+
res.statusCode >= 200 &&
|
|
79
|
+
res.statusCode < 300) {
|
|
80
|
+
try {
|
|
81
|
+
resolve(JSON.parse(data));
|
|
82
|
+
}
|
|
83
|
+
catch (e) {
|
|
84
|
+
reject(new Error(`Failed to parse response: ${data}`));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
reject(new Error(`ElevenLabs API returned ${res.statusCode}: ${data}`));
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
req.on('error', reject);
|
|
93
|
+
formData.pipe(req);
|
|
94
|
+
});
|
|
95
|
+
console.log(`✅ ${this.name} transcription complete`);
|
|
96
|
+
// Parse ElevenLabs response format
|
|
97
|
+
// ElevenLabs returns: { text: string, words: Array<{text, start_time, end_time}> }
|
|
98
|
+
if (result.words && Array.isArray(result.words)) {
|
|
99
|
+
return result.words.map((w) => ({
|
|
100
|
+
word: w.text || w.word,
|
|
101
|
+
start: w.start_time || w.start,
|
|
102
|
+
end: w.end_time || w.end,
|
|
103
|
+
}));
|
|
104
|
+
}
|
|
105
|
+
// If no word timestamps, throw error
|
|
106
|
+
throw new Error('No word-level timestamps in ElevenLabs response');
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
if (error.code === 'ECONNREFUSED') {
|
|
110
|
+
throw new Error(`Could not connect to ElevenLabs API. Check your internet connection.`);
|
|
111
|
+
}
|
|
112
|
+
throw new Error(`${this.name} transcription failed: ${error.message}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
exports.ElevenLabsProvider = ElevenLabsProvider;
|
|
117
|
+
//# sourceMappingURL=elevenlabs-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elevenlabs-provider.js","sourceRoot":"","sources":["../../src/lib/providers/elevenlabs-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Factory for creating transcription providers
|
|
3
|
+
*/
|
|
4
|
+
import type { TranscriptionProvider, TranscriptionProviderConfig } from './transcription-provider';
|
|
5
|
+
/**
|
|
6
|
+
* Create a transcription provider based on configuration
|
|
7
|
+
*
|
|
8
|
+
* @param config - Provider configuration
|
|
9
|
+
* @returns Transcription provider instance
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* // Use OpenAI
|
|
14
|
+
* const provider = createTranscriptionProvider({
|
|
15
|
+
* provider: 'openai',
|
|
16
|
+
* apiKey: process.env.OPENAI_API_KEY!,
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* // Use ElevenLabs
|
|
20
|
+
* const provider = createTranscriptionProvider({
|
|
21
|
+
* provider: 'elevenlabs',
|
|
22
|
+
* apiKey: process.env.ELEVENLABS_API_KEY!,
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* // Get word timestamps
|
|
26
|
+
* const words = await provider.transcribeWithTimestamps('./audio.mp3');
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare function createTranscriptionProvider(config: TranscriptionProviderConfig): TranscriptionProvider;
|
|
30
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/providers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,qBAAqB,EACrB,2BAA2B,EAC5B,MAAM,0BAA0B,CAAC;AAIlC;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,2BAA2B,GAClC,qBAAqB,CAmBvB"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Factory for creating transcription providers
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createTranscriptionProvider = createTranscriptionProvider;
|
|
7
|
+
const openai_provider_1 = require("./openai-provider");
|
|
8
|
+
const elevenlabs_provider_1 = require("./elevenlabs-provider");
|
|
9
|
+
/**
|
|
10
|
+
* Create a transcription provider based on configuration
|
|
11
|
+
*
|
|
12
|
+
* @param config - Provider configuration
|
|
13
|
+
* @returns Transcription provider instance
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* // Use OpenAI
|
|
18
|
+
* const provider = createTranscriptionProvider({
|
|
19
|
+
* provider: 'openai',
|
|
20
|
+
* apiKey: process.env.OPENAI_API_KEY!,
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* // Use ElevenLabs
|
|
24
|
+
* const provider = createTranscriptionProvider({
|
|
25
|
+
* provider: 'elevenlabs',
|
|
26
|
+
* apiKey: process.env.ELEVENLABS_API_KEY!,
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* // Get word timestamps
|
|
30
|
+
* const words = await provider.transcribeWithTimestamps('./audio.mp3');
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
function createTranscriptionProvider(config) {
|
|
34
|
+
const { provider, apiKey, language = 'en', model } = config;
|
|
35
|
+
if (!apiKey) {
|
|
36
|
+
throw new Error(`API key is required for ${provider} provider`);
|
|
37
|
+
}
|
|
38
|
+
switch (provider) {
|
|
39
|
+
case 'openai':
|
|
40
|
+
return new openai_provider_1.OpenAIProvider(apiKey, language, model || 'whisper-1');
|
|
41
|
+
case 'elevenlabs':
|
|
42
|
+
return new elevenlabs_provider_1.ElevenLabsProvider(apiKey, language, model || 'scribe_v2');
|
|
43
|
+
default:
|
|
44
|
+
throw new Error(`Unknown transcription provider: ${provider}. Supported: openai, elevenlabs`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lib/providers/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAiCH,kEAqBC;AAhDD,uDAAmD;AACnD,+DAA2D;AAE3D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,SAAgB,2BAA2B,CACzC,MAAmC;IAEnC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;IAE5D,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,2BAA2B,QAAQ,WAAW,CAAC,CAAC;IAClE,CAAC;IAED,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,QAAQ;YACX,OAAO,IAAI,gCAAc,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,IAAI,WAAW,CAAC,CAAC;QAEpE,KAAK,YAAY;YACf,OAAO,IAAI,wCAAkB,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,IAAI,WAAW,CAAC,CAAC;QAExE;YACE,MAAM,IAAI,KAAK,CACb,mCAAmC,QAAQ,iCAAiC,CAC7E,CAAC;IACN,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI Whisper Transcription Provider
|
|
3
|
+
*/
|
|
4
|
+
import type { TranscriptionProvider, WordTimestamp } from './transcription-provider';
|
|
5
|
+
export declare class OpenAIProvider implements TranscriptionProvider {
|
|
6
|
+
readonly name = "OpenAI Whisper";
|
|
7
|
+
private client;
|
|
8
|
+
private language;
|
|
9
|
+
private model;
|
|
10
|
+
constructor(apiKey: string, language?: string, model?: string);
|
|
11
|
+
transcribeWithTimestamps(audioPath: string, options?: Record<string, any>): Promise<WordTimestamp[]>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=openai-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-provider.d.ts","sourceRoot":"","sources":["../../src/lib/providers/openai-provider.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EACV,qBAAqB,EACrB,aAAa,EACd,MAAM,0BAA0B,CAAC;AAElC,qBAAa,cAAe,YAAW,qBAAqB;IAC1D,QAAQ,CAAC,IAAI,oBAAoB;IACjC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,KAAK,CAAS;gBAGpB,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,MAAa,EACvB,KAAK,GAAE,MAAoB;IAOvB,wBAAwB,CAC5B,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC5B,OAAO,CAAC,aAAa,EAAE,CAAC;CAoC5B"}
|