vidpipe 1.2.2 → 1.2.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.
Files changed (161) hide show
  1. package/dist/index.d.ts +2 -2
  2. package/dist/index.js +4766 -123
  3. package/dist/index.js.map +1 -1
  4. package/package.json +4 -2
  5. package/dist/agents/BaseAgent.d.ts +0 -52
  6. package/dist/agents/BaseAgent.d.ts.map +0 -1
  7. package/dist/agents/BaseAgent.js +0 -102
  8. package/dist/agents/BaseAgent.js.map +0 -1
  9. package/dist/agents/BlogAgent.d.ts +0 -3
  10. package/dist/agents/BlogAgent.d.ts.map +0 -1
  11. package/dist/agents/BlogAgent.js +0 -163
  12. package/dist/agents/BlogAgent.js.map +0 -1
  13. package/dist/agents/ChapterAgent.d.ts +0 -11
  14. package/dist/agents/ChapterAgent.d.ts.map +0 -1
  15. package/dist/agents/ChapterAgent.js +0 -191
  16. package/dist/agents/ChapterAgent.js.map +0 -1
  17. package/dist/agents/MediumVideoAgent.d.ts +0 -3
  18. package/dist/agents/MediumVideoAgent.d.ts.map +0 -1
  19. package/dist/agents/MediumVideoAgent.js +0 -219
  20. package/dist/agents/MediumVideoAgent.js.map +0 -1
  21. package/dist/agents/ShortsAgent.d.ts +0 -3
  22. package/dist/agents/ShortsAgent.d.ts.map +0 -1
  23. package/dist/agents/ShortsAgent.js +0 -243
  24. package/dist/agents/ShortsAgent.js.map +0 -1
  25. package/dist/agents/SilenceRemovalAgent.d.ts +0 -9
  26. package/dist/agents/SilenceRemovalAgent.d.ts.map +0 -1
  27. package/dist/agents/SilenceRemovalAgent.js +0 -209
  28. package/dist/agents/SilenceRemovalAgent.js.map +0 -1
  29. package/dist/agents/SocialMediaAgent.d.ts +0 -4
  30. package/dist/agents/SocialMediaAgent.d.ts.map +0 -1
  31. package/dist/agents/SocialMediaAgent.js +0 -248
  32. package/dist/agents/SocialMediaAgent.js.map +0 -1
  33. package/dist/agents/SummaryAgent.d.ts +0 -11
  34. package/dist/agents/SummaryAgent.d.ts.map +0 -1
  35. package/dist/agents/SummaryAgent.js +0 -333
  36. package/dist/agents/SummaryAgent.js.map +0 -1
  37. package/dist/commands/doctor.d.ts +0 -4
  38. package/dist/commands/doctor.d.ts.map +0 -1
  39. package/dist/commands/doctor.js +0 -230
  40. package/dist/commands/doctor.js.map +0 -1
  41. package/dist/config/brand.d.ts +0 -29
  42. package/dist/config/brand.d.ts.map +0 -1
  43. package/dist/config/brand.js +0 -83
  44. package/dist/config/brand.js.map +0 -1
  45. package/dist/config/environment.d.ts +0 -39
  46. package/dist/config/environment.d.ts.map +0 -1
  47. package/dist/config/environment.js +0 -47
  48. package/dist/config/environment.js.map +0 -1
  49. package/dist/config/ffmpegResolver.d.ts +0 -3
  50. package/dist/config/ffmpegResolver.d.ts.map +0 -1
  51. package/dist/config/ffmpegResolver.js +0 -37
  52. package/dist/config/ffmpegResolver.js.map +0 -1
  53. package/dist/config/logger.d.ts +0 -5
  54. package/dist/config/logger.d.ts.map +0 -1
  55. package/dist/config/logger.js +0 -13
  56. package/dist/config/logger.js.map +0 -1
  57. package/dist/config/pricing.d.ts +0 -34
  58. package/dist/config/pricing.d.ts.map +0 -1
  59. package/dist/config/pricing.js +0 -71
  60. package/dist/config/pricing.js.map +0 -1
  61. package/dist/index.d.ts.map +0 -1
  62. package/dist/pipeline.d.ts +0 -57
  63. package/dist/pipeline.d.ts.map +0 -1
  64. package/dist/pipeline.js +0 -324
  65. package/dist/pipeline.js.map +0 -1
  66. package/dist/providers/ClaudeProvider.d.ts +0 -14
  67. package/dist/providers/ClaudeProvider.d.ts.map +0 -1
  68. package/dist/providers/ClaudeProvider.js +0 -182
  69. package/dist/providers/ClaudeProvider.js.map +0 -1
  70. package/dist/providers/CopilotProvider.d.ts +0 -17
  71. package/dist/providers/CopilotProvider.d.ts.map +0 -1
  72. package/dist/providers/CopilotProvider.js +0 -149
  73. package/dist/providers/CopilotProvider.js.map +0 -1
  74. package/dist/providers/OpenAIProvider.d.ts +0 -14
  75. package/dist/providers/OpenAIProvider.d.ts.map +0 -1
  76. package/dist/providers/OpenAIProvider.js +0 -175
  77. package/dist/providers/OpenAIProvider.js.map +0 -1
  78. package/dist/providers/index.d.ts +0 -18
  79. package/dist/providers/index.d.ts.map +0 -1
  80. package/dist/providers/index.js +0 -61
  81. package/dist/providers/index.js.map +0 -1
  82. package/dist/providers/types.d.ts +0 -112
  83. package/dist/providers/types.d.ts.map +0 -1
  84. package/dist/providers/types.js +0 -8
  85. package/dist/providers/types.js.map +0 -1
  86. package/dist/services/captionGeneration.d.ts +0 -7
  87. package/dist/services/captionGeneration.d.ts.map +0 -1
  88. package/dist/services/captionGeneration.js +0 -29
  89. package/dist/services/captionGeneration.js.map +0 -1
  90. package/dist/services/costTracker.d.ts +0 -63
  91. package/dist/services/costTracker.d.ts.map +0 -1
  92. package/dist/services/costTracker.js +0 -137
  93. package/dist/services/costTracker.js.map +0 -1
  94. package/dist/services/fileWatcher.d.ts +0 -19
  95. package/dist/services/fileWatcher.d.ts.map +0 -1
  96. package/dist/services/fileWatcher.js +0 -120
  97. package/dist/services/fileWatcher.js.map +0 -1
  98. package/dist/services/gitOperations.d.ts +0 -3
  99. package/dist/services/gitOperations.d.ts.map +0 -1
  100. package/dist/services/gitOperations.js +0 -43
  101. package/dist/services/gitOperations.js.map +0 -1
  102. package/dist/services/socialPosting.d.ts +0 -38
  103. package/dist/services/socialPosting.d.ts.map +0 -1
  104. package/dist/services/socialPosting.js +0 -102
  105. package/dist/services/socialPosting.js.map +0 -1
  106. package/dist/services/transcription.d.ts +0 -3
  107. package/dist/services/transcription.d.ts.map +0 -1
  108. package/dist/services/transcription.js +0 -100
  109. package/dist/services/transcription.js.map +0 -1
  110. package/dist/services/videoIngestion.d.ts +0 -3
  111. package/dist/services/videoIngestion.d.ts.map +0 -1
  112. package/dist/services/videoIngestion.js +0 -104
  113. package/dist/services/videoIngestion.js.map +0 -1
  114. package/dist/tools/captions/captionGenerator.d.ts +0 -84
  115. package/dist/tools/captions/captionGenerator.d.ts.map +0 -1
  116. package/dist/tools/captions/captionGenerator.js +0 -390
  117. package/dist/tools/captions/captionGenerator.js.map +0 -1
  118. package/dist/tools/ffmpeg/aspectRatio.d.ts +0 -101
  119. package/dist/tools/ffmpeg/aspectRatio.d.ts.map +0 -1
  120. package/dist/tools/ffmpeg/aspectRatio.js +0 -339
  121. package/dist/tools/ffmpeg/aspectRatio.js.map +0 -1
  122. package/dist/tools/ffmpeg/audioExtraction.d.ts +0 -16
  123. package/dist/tools/ffmpeg/audioExtraction.d.ts.map +0 -1
  124. package/dist/tools/ffmpeg/audioExtraction.js +0 -87
  125. package/dist/tools/ffmpeg/audioExtraction.js.map +0 -1
  126. package/dist/tools/ffmpeg/captionBurning.d.ts +0 -8
  127. package/dist/tools/ffmpeg/captionBurning.d.ts.map +0 -1
  128. package/dist/tools/ffmpeg/captionBurning.js +0 -72
  129. package/dist/tools/ffmpeg/captionBurning.js.map +0 -1
  130. package/dist/tools/ffmpeg/clipExtraction.d.ts +0 -38
  131. package/dist/tools/ffmpeg/clipExtraction.d.ts.map +0 -1
  132. package/dist/tools/ffmpeg/clipExtraction.js +0 -215
  133. package/dist/tools/ffmpeg/clipExtraction.js.map +0 -1
  134. package/dist/tools/ffmpeg/faceDetection.d.ts +0 -127
  135. package/dist/tools/ffmpeg/faceDetection.d.ts.map +0 -1
  136. package/dist/tools/ffmpeg/faceDetection.js +0 -501
  137. package/dist/tools/ffmpeg/faceDetection.js.map +0 -1
  138. package/dist/tools/ffmpeg/frameCapture.d.ts +0 -10
  139. package/dist/tools/ffmpeg/frameCapture.d.ts.map +0 -1
  140. package/dist/tools/ffmpeg/frameCapture.js +0 -49
  141. package/dist/tools/ffmpeg/frameCapture.js.map +0 -1
  142. package/dist/tools/ffmpeg/silenceDetection.d.ts +0 -10
  143. package/dist/tools/ffmpeg/silenceDetection.d.ts.map +0 -1
  144. package/dist/tools/ffmpeg/silenceDetection.js +0 -56
  145. package/dist/tools/ffmpeg/silenceDetection.js.map +0 -1
  146. package/dist/tools/ffmpeg/singlePassEdit.d.ts +0 -25
  147. package/dist/tools/ffmpeg/singlePassEdit.d.ts.map +0 -1
  148. package/dist/tools/ffmpeg/singlePassEdit.js +0 -124
  149. package/dist/tools/ffmpeg/singlePassEdit.js.map +0 -1
  150. package/dist/tools/search/exaClient.d.ts +0 -8
  151. package/dist/tools/search/exaClient.d.ts.map +0 -1
  152. package/dist/tools/search/exaClient.js +0 -38
  153. package/dist/tools/search/exaClient.js.map +0 -1
  154. package/dist/tools/whisper/whisperClient.d.ts +0 -3
  155. package/dist/tools/whisper/whisperClient.d.ts.map +0 -1
  156. package/dist/tools/whisper/whisperClient.js +0 -77
  157. package/dist/tools/whisper/whisperClient.js.map +0 -1
  158. package/dist/types/index.d.ts +0 -305
  159. package/dist/types/index.d.ts.map +0 -1
  160. package/dist/types/index.js +0 -44
  161. package/dist/types/index.js.map +0 -1
@@ -1,100 +0,0 @@
1
- import path from 'path';
2
- import fsp from 'fs/promises';
3
- import { extractAudio, splitAudioIntoChunks } from '../tools/ffmpeg/audioExtraction';
4
- import { transcribeAudio } from '../tools/whisper/whisperClient';
5
- import { getConfig } from '../config/environment';
6
- import logger from '../config/logger';
7
- const MAX_WHISPER_SIZE_MB = 25;
8
- export async function transcribeVideo(video) {
9
- const config = getConfig();
10
- // 1. Create cache directory for temp audio files
11
- const cacheDir = path.join(config.REPO_ROOT, 'cache');
12
- await fsp.mkdir(cacheDir, { recursive: true });
13
- logger.info(`Cache directory ready: ${cacheDir}`);
14
- // 2. Extract audio as compressed MP3 (much smaller than WAV)
15
- const mp3Path = path.join(cacheDir, `${video.slug}.mp3`);
16
- logger.info(`Extracting audio for "${video.slug}"`);
17
- await extractAudio(video.repoPath, mp3Path);
18
- // 3. Check file size and chunk if necessary
19
- const stats = await fsp.stat(mp3Path);
20
- const fileSizeMB = stats.size / (1024 * 1024);
21
- logger.info(`Extracted audio: ${fileSizeMB.toFixed(1)}MB`);
22
- let transcript;
23
- if (fileSizeMB <= MAX_WHISPER_SIZE_MB) {
24
- // Single-file transcription
25
- logger.info(`Transcribing audio for "${video.slug}"`);
26
- transcript = await transcribeAudio(mp3Path);
27
- }
28
- else {
29
- // Chunk and transcribe (very long videos, 50+ min)
30
- logger.info(`Audio exceeds ${MAX_WHISPER_SIZE_MB}MB, splitting into chunks`);
31
- const chunkPaths = await splitAudioIntoChunks(mp3Path);
32
- transcript = await transcribeChunks(chunkPaths);
33
- // Clean up chunk files
34
- for (const chunkPath of chunkPaths) {
35
- if (chunkPath !== mp3Path) {
36
- await fsp.unlink(chunkPath).catch(() => { });
37
- }
38
- }
39
- }
40
- // 4. Save transcript JSON
41
- const transcriptDir = path.join(config.OUTPUT_DIR, video.slug);
42
- await fsp.mkdir(transcriptDir, { recursive: true });
43
- const transcriptPath = path.join(transcriptDir, 'transcript.json');
44
- await fsp.writeFile(transcriptPath, JSON.stringify(transcript, null, 2), 'utf-8');
45
- logger.info(`Transcript saved: ${transcriptPath}`);
46
- // 5. Clean up temp audio file
47
- await fsp.unlink(mp3Path).catch(() => { });
48
- logger.info(`Cleaned up temp file: ${mp3Path}`);
49
- // 6. Return the transcript
50
- logger.info(`Transcription complete for "${video.slug}" — ` +
51
- `${transcript.segments.length} segments, ${transcript.words.length} words`);
52
- return transcript;
53
- }
54
- /**
55
- * Transcribe multiple audio chunks and merge results with adjusted timestamps.
56
- */
57
- async function transcribeChunks(chunkPaths) {
58
- let allText = '';
59
- const allSegments = [];
60
- const allWords = [];
61
- let cumulativeOffset = 0;
62
- let totalDuration = 0;
63
- let language = 'unknown';
64
- for (let i = 0; i < chunkPaths.length; i++) {
65
- logger.info(`Transcribing chunk ${i + 1}/${chunkPaths.length}: ${chunkPaths[i]}`);
66
- const result = await transcribeAudio(chunkPaths[i]);
67
- if (i === 0)
68
- language = result.language;
69
- // Adjust timestamps by cumulative offset
70
- const offsetSegments = result.segments.map((s) => ({
71
- ...s,
72
- id: allSegments.length + s.id,
73
- start: s.start + cumulativeOffset,
74
- end: s.end + cumulativeOffset,
75
- words: s.words.map((w) => ({
76
- ...w,
77
- start: w.start + cumulativeOffset,
78
- end: w.end + cumulativeOffset,
79
- })),
80
- }));
81
- const offsetWords = result.words.map((w) => ({
82
- ...w,
83
- start: w.start + cumulativeOffset,
84
- end: w.end + cumulativeOffset,
85
- }));
86
- allText += (allText ? ' ' : '') + result.text;
87
- allSegments.push(...offsetSegments);
88
- allWords.push(...offsetWords);
89
- cumulativeOffset += result.duration;
90
- totalDuration += result.duration;
91
- }
92
- return {
93
- text: allText,
94
- segments: allSegments,
95
- words: allWords,
96
- language,
97
- duration: totalDuration,
98
- };
99
- }
100
- //# sourceMappingURL=transcription.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transcription.js","sourceRoot":"","sources":["../../src/services/transcription.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- import { VideoFile } from '../types';
2
- export declare function ingestVideo(sourcePath: string): Promise<VideoFile>;
3
- //# sourceMappingURL=videoIngestion.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"videoIngestion.d.ts","sourceRoot":"","sources":["../../src/services/videoIngestion.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAqBpC,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CA2FxE"}
@@ -1,104 +0,0 @@
1
- import path from 'path';
2
- import fs from 'fs';
3
- import fsp from 'fs/promises';
4
- import slugify from 'slugify';
5
- import ffmpeg from 'fluent-ffmpeg';
6
- import { getConfig } from '../config/environment';
7
- import logger from '../config/logger';
8
- import { getFFmpegPath, getFFprobePath } from '../config/ffmpegResolver.js';
9
- const ffmpegBin = getFFmpegPath();
10
- const ffprobeBin = getFFprobePath();
11
- ffmpeg.setFfmpegPath(ffmpegBin);
12
- ffmpeg.setFfprobePath(ffprobeBin);
13
- function getVideoMetadata(filePath) {
14
- return new Promise((resolve, reject) => {
15
- ffmpeg.ffprobe(filePath, (err, metadata) => {
16
- if (err) {
17
- return reject(err);
18
- }
19
- resolve({ duration: metadata.format.duration ?? 0 });
20
- });
21
- });
22
- }
23
- export async function ingestVideo(sourcePath) {
24
- const config = getConfig();
25
- const baseName = path.basename(sourcePath, path.extname(sourcePath));
26
- const slug = slugify(baseName, { lower: true });
27
- const recordingsDir = path.join(config.OUTPUT_DIR, slug);
28
- const thumbnailsDir = path.join(recordingsDir, 'thumbnails');
29
- const shortsDir = path.join(recordingsDir, 'shorts');
30
- const socialPostsDir = path.join(recordingsDir, 'social-posts');
31
- logger.info(`Ingesting video: ${sourcePath} → ${slug}`);
32
- // Clean stale artifacts if output folder already exists
33
- if (fs.existsSync(recordingsDir)) {
34
- logger.warn(`Output folder already exists, cleaning previous artifacts: ${recordingsDir}`);
35
- const subDirs = ['thumbnails', 'shorts', 'social-posts', 'chapters', 'medium-clips', 'captions'];
36
- for (const sub of subDirs) {
37
- await fsp.rm(path.join(recordingsDir, sub), { recursive: true, force: true });
38
- }
39
- const stalePatterns = [
40
- 'transcript.json', 'transcript-edited.json',
41
- 'captions.srt', 'captions.vtt', 'captions.ass',
42
- 'summary.md', 'blog-post.md', 'README.md',
43
- ];
44
- for (const pattern of stalePatterns) {
45
- await fsp.rm(path.join(recordingsDir, pattern), { force: true });
46
- }
47
- const files = await fsp.readdir(recordingsDir);
48
- for (const file of files) {
49
- if (file.endsWith('-edited.mp4') || file.endsWith('-captioned.mp4')) {
50
- await fsp.rm(path.join(recordingsDir, file), { force: true });
51
- }
52
- }
53
- }
54
- await fsp.mkdir(recordingsDir, { recursive: true });
55
- await fsp.mkdir(thumbnailsDir, { recursive: true });
56
- await fsp.mkdir(shortsDir, { recursive: true });
57
- await fsp.mkdir(socialPostsDir, { recursive: true });
58
- const destFilename = `${slug}.mp4`;
59
- const destPath = path.join(recordingsDir, destFilename);
60
- let needsCopy = true;
61
- try {
62
- const destStats = await fsp.stat(destPath);
63
- const srcStats = await fsp.stat(sourcePath);
64
- if (destStats.size === srcStats.size) {
65
- logger.info(`Video already copied (same size), skipping copy`);
66
- needsCopy = false;
67
- }
68
- }
69
- catch {
70
- // Dest doesn't exist, need to copy
71
- }
72
- if (needsCopy) {
73
- await new Promise((resolve, reject) => {
74
- const readStream = fs.createReadStream(sourcePath);
75
- const writeStream = fs.createWriteStream(destPath);
76
- readStream.on('error', reject);
77
- writeStream.on('error', reject);
78
- writeStream.on('finish', resolve);
79
- readStream.pipe(writeStream);
80
- });
81
- logger.info(`Copied video to ${destPath}`);
82
- }
83
- let duration = 0;
84
- try {
85
- const meta = await getVideoMetadata(destPath);
86
- duration = meta.duration;
87
- }
88
- catch (err) {
89
- logger.warn(`ffprobe failed, continuing without duration metadata: ${err instanceof Error ? err.message : String(err)}`);
90
- }
91
- const stats = await fsp.stat(destPath);
92
- logger.info(`Video metadata: duration=${duration}s, size=${stats.size} bytes`);
93
- return {
94
- originalPath: sourcePath,
95
- repoPath: destPath,
96
- videoDir: recordingsDir,
97
- slug,
98
- filename: destFilename,
99
- duration,
100
- size: stats.size,
101
- createdAt: new Date(),
102
- };
103
- }
104
- //# sourceMappingURL=videoIngestion.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"videoIngestion.js","sourceRoot":"","sources":["../../src/services/videoIngestion.ts"],"names":[],"mappings":"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"}
@@ -1,84 +0,0 @@
1
- /**
2
- * Caption generator for the Advanced SubStation Alpha (ASS) subtitle format.
3
- *
4
- * ### Why ASS instead of SRT/VTT?
5
- * ASS supports inline style overrides — font size, color, and animation per
6
- * character/word — which enables the "active word pop" karaoke effect used
7
- * in modern short-form video (TikTok, Reels). SRT and VTT only support
8
- * plain text or basic HTML tags with no per-word timing control.
9
- *
10
- * ### Karaoke word highlighting approach
11
- * Instead of ASS's native `\k` karaoke tags (which highlight left-to-right
12
- * within a line), we generate **one Dialogue line per word-state**. Each line
13
- * renders the entire caption group but with the currently-spoken word in a
14
- * different color and size. Contiguous end/start timestamps between
15
- * word-states prevent flicker. This gives us full control over the visual
16
- * treatment (color, font-size, scale animations) without the limitations
17
- * of the `\k` tag.
18
- *
19
- * @module captionGenerator
20
- */
21
- import { Transcript, CaptionStyle } from '../../types';
22
- export declare function generateSRT(transcript: Transcript): string;
23
- export declare function generateVTT(transcript: Transcript): string;
24
- /**
25
- * Generate premium ASS captions with active-word-pop highlighting.
26
- *
27
- * ### How it works
28
- * Words are grouped by speech bursts (split on silence gaps > 0.8s or after
29
- * 8 words). Within each group, one Dialogue line is emitted per word — the
30
- * full group is shown each time, but the "active" word gets a different color
31
- * and larger font size. This creates a karaoke-style bounce effect.
32
- *
33
- * @param transcript - Full transcript with word-level timestamps
34
- * @param style - Visual style: 'shorts' (large centered), 'medium' (small bottom),
35
- * or 'portrait' (Opus Clips style with green highlight + scale animation)
36
- * @returns Complete ASS file content (header + dialogue lines)
37
- */
38
- export declare function generateStyledASS(transcript: Transcript, style?: CaptionStyle): string;
39
- /**
40
- * Generate premium ASS captions for a single contiguous segment.
41
- * Filters words within [startTime, endTime] (plus buffer), adjusts timestamps
42
- * relative to the clip's buffered start so they align with the extracted video.
43
- */
44
- export declare function generateStyledASSForSegment(transcript: Transcript, startTime: number, endTime: number, buffer?: number, style?: CaptionStyle): string;
45
- /**
46
- * Generate premium ASS captions for a composite clip made of multiple segments.
47
- * Each segment's words are extracted and remapped to the concatenated timeline,
48
- * accounting for the buffer added during clip extraction.
49
- */
50
- export declare function generateStyledASSForComposite(transcript: Transcript, segments: {
51
- start: number;
52
- end: number;
53
- }[], buffer?: number, style?: CaptionStyle): string;
54
- /**
55
- * Generate ASS dialogue lines for a hook text overlay at the top of the video.
56
- *
57
- * The hook is a short attention-grabbing phrase (e.g. "Here's why you should
58
- * learn TypeScript") displayed as a translucent pill/badge at the top of a
59
- * portrait video for the first few seconds.
60
- *
61
- * Uses the `Hook` style defined in {@link ASS_HEADER_PORTRAIT} which has
62
- * `BorderStyle: 3` (opaque box background) and `Alignment: 8` (top-center).
63
- *
64
- * The `\fad(300,500)` tag creates a 300ms fade-in and 500ms fade-out so the
65
- * hook doesn't appear/disappear abruptly.
66
- *
67
- * @param hookText - The attention-grabbing phrase (truncated to 60 chars)
68
- * @param displayDuration - How long to show the hook in seconds (default: 4s)
69
- * @param _style - Caption style (currently only 'portrait' uses hooks)
70
- * @returns A single ASS Dialogue line to append to the Events section
71
- */
72
- export declare function generateHookOverlay(hookText: string, displayDuration?: number, _style?: CaptionStyle): string;
73
- /**
74
- * Generate a complete portrait ASS file with captions AND hook text overlay.
75
- */
76
- export declare function generatePortraitASSWithHook(transcript: Transcript, hookText: string, startTime: number, endTime: number, buffer?: number): string;
77
- /**
78
- * Generate a complete portrait ASS file for a composite clip with captions AND hook text overlay.
79
- */
80
- export declare function generatePortraitASSWithHookComposite(transcript: Transcript, segments: {
81
- start: number;
82
- end: number;
83
- }[], hookText: string, buffer?: number): string;
84
- //# sourceMappingURL=captionGenerator.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"captionGenerator.d.ts","sourceRoot":"","sources":["../../../src/tools/captions/captionGenerator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,UAAU,EAAiB,YAAY,EAAE,MAAM,aAAa,CAAA;AA+ErE,wBAAgB,WAAW,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAW1D;AAMD,wBAAgB,WAAW,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAW1D;AA6LD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,EAAE,KAAK,GAAE,YAAuB,GAAG,MAAM,CAMhG;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,MAAY,EACpB,KAAK,GAAE,YAAuB,GAC7B,MAAM,CAiBR;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAC3C,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,EAC1C,MAAM,GAAE,MAAY,EACpB,KAAK,GAAE,YAAuB,GAC7B,MAAM,CA4BR;AASD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,eAAe,GAAE,MAAY,EAC7B,MAAM,GAAE,YAAyB,GAChC,MAAM,CAOR;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,GACd,MAAM,CAIR;AAED;;GAEG;AACH,wBAAgB,oCAAoC,CAClD,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,EAC1C,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,GACd,MAAM,CAIR"}