@thunderkiller/video-clipper 1.1.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.
Files changed (140) hide show
  1. package/.env.example +130 -0
  2. package/.github/workflows/ci.yml +42 -0
  3. package/.github/workflows/release.yml +72 -0
  4. package/.husky/pre-commit +3 -0
  5. package/.prettierignore +6 -0
  6. package/.prettierrc +7 -0
  7. package/.releaserc.json +21 -0
  8. package/AGENTS.md +122 -0
  9. package/CHANGELOG.md +45 -0
  10. package/README.md +410 -0
  11. package/dist/cli.js +187 -0
  12. package/dist/config/env.js +14 -0
  13. package/dist/config/index.js +1 -0
  14. package/dist/index.js +35 -0
  15. package/dist/pipeline/runner.js +132 -0
  16. package/dist/pipeline/stages/audioProcessor.js +75 -0
  17. package/dist/pipeline/stages/clipExporter.js +44 -0
  18. package/dist/pipeline/stages/segmentAnalyzer.js +46 -0
  19. package/dist/pipeline/stages/segmentSelector.js +23 -0
  20. package/dist/pipeline/stages/videoResolver.js +34 -0
  21. package/dist/services/audioAnalyzers/base.js +13 -0
  22. package/dist/services/audioAnalyzers/factory.js +56 -0
  23. package/dist/services/audioAnalyzers/gemini.js +109 -0
  24. package/dist/services/audioAnalyzers/index.js +5 -0
  25. package/dist/services/audioAnalyzers/whisper.js +62 -0
  26. package/dist/services/audioAnalyzers/yamnet.js +40 -0
  27. package/dist/services/audioDownloader/index.js +81 -0
  28. package/dist/services/chunkBuilder/index.js +71 -0
  29. package/dist/services/clipGenerator/index.js +156 -0
  30. package/dist/services/clipRefiner/index.js +103 -0
  31. package/dist/services/eventDetector/index.js +54 -0
  32. package/dist/services/llmAnalyzer/LLMAnalyzer.js +63 -0
  33. package/dist/services/llmAnalyzer/index.js +173 -0
  34. package/dist/services/metadataExtractor/index.js +66 -0
  35. package/dist/services/segmentRanker/index.js +40 -0
  36. package/dist/services/signalMerger/index.js +36 -0
  37. package/dist/services/transcriptAnalyzers/base.js +13 -0
  38. package/dist/services/transcriptAnalyzers/factory.js +51 -0
  39. package/dist/services/transcriptAnalyzers/gemini.js +19 -0
  40. package/dist/services/transcriptAnalyzers/index.js +5 -0
  41. package/dist/services/transcriptAnalyzers/whisper.js +55 -0
  42. package/dist/services/transcriptAnalyzers/ytdlp.js +16 -0
  43. package/dist/services/transcriptDetector/index.js +102 -0
  44. package/dist/services/transcriptFetcher/index.js +124 -0
  45. package/dist/services/urlParser/index.js +46 -0
  46. package/dist/services/videoDownloader/index.js +212 -0
  47. package/dist/types/audio.js +15 -0
  48. package/dist/types/cli.js +1 -0
  49. package/dist/types/config.js +150 -0
  50. package/dist/types/index.js +5 -0
  51. package/dist/types/pipeline.js +9 -0
  52. package/dist/types/segment.js +36 -0
  53. package/dist/types/transcript.js +16 -0
  54. package/dist/types/video.js +14 -0
  55. package/dist/utils/cache.js +143 -0
  56. package/dist/utils/chunker.js +51 -0
  57. package/dist/utils/dumper.js +36 -0
  58. package/dist/utils/format.js +10 -0
  59. package/dist/utils/logger.js +16 -0
  60. package/dist/utils/modelFactory.js +60 -0
  61. package/dist/utils/redactConfig.js +20 -0
  62. package/dist/utils/sliceAudio.js +26 -0
  63. package/docs/free-models.md +78 -0
  64. package/docs/plan.md +442 -0
  65. package/docs/refactorPhases.md +105 -0
  66. package/docs/yt-downloader.md +440 -0
  67. package/package.json +65 -0
  68. package/requirements.txt +5 -0
  69. package/scripts/detect_events.py +81 -0
  70. package/scripts/detect_events_whisper.py +101 -0
  71. package/scripts/transcribe_whisper.py +70 -0
  72. package/src/cli.ts +186 -0
  73. package/src/config/env.ts +18 -0
  74. package/src/config/index.ts +2 -0
  75. package/src/index.ts +46 -0
  76. package/src/pipeline/runner.ts +155 -0
  77. package/src/pipeline/stages/audioProcessor.ts +129 -0
  78. package/src/pipeline/stages/clipExporter.ts +80 -0
  79. package/src/pipeline/stages/segmentAnalyzer.ts +72 -0
  80. package/src/pipeline/stages/segmentSelector.ts +39 -0
  81. package/src/pipeline/stages/videoResolver.ts +47 -0
  82. package/src/services/audioAnalyzers/base.ts +32 -0
  83. package/src/services/audioAnalyzers/factory.ts +71 -0
  84. package/src/services/audioAnalyzers/gemini.ts +137 -0
  85. package/src/services/audioAnalyzers/index.ts +6 -0
  86. package/src/services/audioAnalyzers/whisper.ts +80 -0
  87. package/src/services/audioAnalyzers/yamnet.ts +54 -0
  88. package/src/services/audioDownloader/index.ts +102 -0
  89. package/src/services/chunkBuilder/index.ts +86 -0
  90. package/src/services/clipGenerator/index.ts +210 -0
  91. package/src/services/clipRefiner/index.ts +141 -0
  92. package/src/services/eventDetector/index.ts +68 -0
  93. package/src/services/llmAnalyzer/LLMAnalyzer.ts +114 -0
  94. package/src/services/llmAnalyzer/index.ts +231 -0
  95. package/src/services/metadataExtractor/index.ts +83 -0
  96. package/src/services/segmentRanker/index.ts +88 -0
  97. package/src/services/signalMerger/index.ts +53 -0
  98. package/src/services/transcriptAnalyzers/base.ts +26 -0
  99. package/src/services/transcriptAnalyzers/factory.ts +67 -0
  100. package/src/services/transcriptAnalyzers/gemini.ts +24 -0
  101. package/src/services/transcriptAnalyzers/index.ts +6 -0
  102. package/src/services/transcriptAnalyzers/whisper.ts +68 -0
  103. package/src/services/transcriptAnalyzers/ytdlp.ts +19 -0
  104. package/src/services/transcriptDetector/index.ts +128 -0
  105. package/src/services/transcriptFetcher/index.ts +151 -0
  106. package/src/services/urlParser/index.ts +53 -0
  107. package/src/services/videoDownloader/index.ts +282 -0
  108. package/src/types/audio.ts +19 -0
  109. package/src/types/cli.ts +22 -0
  110. package/src/types/config.ts +174 -0
  111. package/src/types/index.ts +26 -0
  112. package/src/types/pipeline.ts +93 -0
  113. package/src/types/segment.ts +43 -0
  114. package/src/types/transcript.ts +22 -0
  115. package/src/types/video.ts +18 -0
  116. package/src/utils/cache.ts +223 -0
  117. package/src/utils/chunker.ts +60 -0
  118. package/src/utils/dumper.ts +41 -0
  119. package/src/utils/format.ts +10 -0
  120. package/src/utils/logger.ts +17 -0
  121. package/src/utils/modelFactory.ts +71 -0
  122. package/src/utils/redactConfig.ts +23 -0
  123. package/src/utils/sliceAudio.ts +35 -0
  124. package/test-trigger.txt +1 -0
  125. package/tests/analyzerFactory.test.ts +146 -0
  126. package/tests/audioEventDetector.test.ts +69 -0
  127. package/tests/cache.test.ts +203 -0
  128. package/tests/chunkBuilder.test.ts +146 -0
  129. package/tests/chunker.test.ts +95 -0
  130. package/tests/eventDetector.test.ts +103 -0
  131. package/tests/llmAnalyzer.test.ts +283 -0
  132. package/tests/segmentRanker.test.ts +133 -0
  133. package/tests/setup.ts +48 -0
  134. package/tests/signalMerger.test.ts +197 -0
  135. package/tests/transcriptDetector.test.ts +150 -0
  136. package/tests/transcriptFetcher.test.ts +179 -0
  137. package/tests/urlParser.test.ts +70 -0
  138. package/tsconfig.json +16 -0
  139. package/tsconfig.test.json +8 -0
  140. package/vitest.config.ts +8 -0
@@ -0,0 +1,70 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { parseUrl } from '../src/services/urlParser/index.js';
3
+
4
+ describe('parseUrl', () => {
5
+ describe('valid URLs', () => {
6
+ it('parses a standard youtube.com/watch URL', () => {
7
+ expect(parseUrl('https://www.youtube.com/watch?v=dQw4w9WgXcQ')).toBe('dQw4w9WgXcQ');
8
+ });
9
+
10
+ it('parses a youtube.com/watch URL without www', () => {
11
+ expect(parseUrl('https://youtube.com/watch?v=dQw4w9WgXcQ')).toBe('dQw4w9WgXcQ');
12
+ });
13
+
14
+ it('parses a youtu.be short URL', () => {
15
+ expect(parseUrl('https://youtu.be/dQw4w9WgXcQ')).toBe('dQw4w9WgXcQ');
16
+ });
17
+
18
+ it('parses a youtu.be URL with extra query params', () => {
19
+ expect(parseUrl('https://youtu.be/dQw4w9WgXcQ?t=42')).toBe('dQw4w9WgXcQ');
20
+ });
21
+
22
+ it('parses a youtube.com/embed URL', () => {
23
+ expect(parseUrl('https://www.youtube.com/embed/dQw4w9WgXcQ')).toBe('dQw4w9WgXcQ');
24
+ });
25
+
26
+ it('parses a youtube.com/shorts URL', () => {
27
+ expect(parseUrl('https://www.youtube.com/shorts/dQw4w9WgXcQ')).toBe('dQw4w9WgXcQ');
28
+ });
29
+
30
+ it('parses a watch URL with additional query params', () => {
31
+ expect(parseUrl('https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=120&list=PLxxx')).toBe(
32
+ 'dQw4w9WgXcQ',
33
+ );
34
+ });
35
+ });
36
+
37
+ describe('invalid URLs', () => {
38
+ it('throws on a completely invalid string', () => {
39
+ expect(() => parseUrl('not-a-url')).toThrow('Invalid URL');
40
+ });
41
+
42
+ it('throws on a non-YouTube URL', () => {
43
+ expect(() => parseUrl('https://vimeo.com/123456789')).toThrow('Could not extract video ID');
44
+ });
45
+
46
+ it('throws on a YouTube URL with no video ID', () => {
47
+ expect(() => parseUrl('https://www.youtube.com/watch')).toThrow('Could not extract video ID');
48
+ });
49
+
50
+ it('throws on a YouTube URL with an empty video ID', () => {
51
+ expect(() => parseUrl('https://www.youtube.com/watch?v=')).toThrow();
52
+ });
53
+
54
+ it('throws if the video ID is shorter than 11 characters', () => {
55
+ expect(() => parseUrl('https://www.youtube.com/watch?v=short')).toThrow(
56
+ 'expected 11 characters',
57
+ );
58
+ });
59
+
60
+ it('throws if the video ID is longer than 11 characters', () => {
61
+ expect(() => parseUrl('https://www.youtube.com/watch?v=toolongvideoid')).toThrow(
62
+ 'expected 11 characters',
63
+ );
64
+ });
65
+
66
+ it('throws on an empty string', () => {
67
+ expect(() => parseUrl('')).toThrow('Invalid URL');
68
+ });
69
+ });
70
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "outDir": "dist",
7
+ "rootDir": "src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "resolveJsonModule": true,
11
+ "skipLibCheck": true,
12
+ "types": ["node"]
13
+ },
14
+ "include": ["src/**/*"],
15
+ "exclude": ["node_modules", "dist"]
16
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "rootDir": ".",
5
+ "noEmit": true
6
+ },
7
+ "include": ["src/**/*", "tests/**/*"]
8
+ }
@@ -0,0 +1,8 @@
1
+ import { defineConfig } from 'vitest/config';
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ include: ['tests/**/*.test.ts'],
6
+ setupFiles: ['tests/setup.ts'],
7
+ },
8
+ });