node-av-lgpl 0.0.0 → 7.1.0-beta.1

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 (311) hide show
  1. package/LICENSE.md +22 -0
  2. package/README.md +711 -0
  3. package/dist/api/audio-frame-buffer.d.ts +636 -0
  4. package/dist/api/audio-frame-buffer.js +1027 -0
  5. package/dist/api/audio-frame-buffer.js.map +1 -0
  6. package/dist/api/bitstream-filter.d.ts +938 -0
  7. package/dist/api/bitstream-filter.js +1427 -0
  8. package/dist/api/bitstream-filter.js.map +1 -0
  9. package/dist/api/constants.d.ts +44 -0
  10. package/dist/api/constants.js +45 -0
  11. package/dist/api/constants.js.map +1 -0
  12. package/dist/api/data/test_av1.ivf +0 -0
  13. package/dist/api/data/test_h264.h264 +0 -0
  14. package/dist/api/data/test_hevc.h265 +0 -0
  15. package/dist/api/data/test_mjpeg.mjpeg +0 -0
  16. package/dist/api/data/test_vp8.ivf +0 -0
  17. package/dist/api/data/test_vp9.ivf +0 -0
  18. package/dist/api/decoder.d.ts +1413 -0
  19. package/dist/api/decoder.js +2367 -0
  20. package/dist/api/decoder.js.map +1 -0
  21. package/dist/api/demuxer.d.ts +1295 -0
  22. package/dist/api/demuxer.js +2344 -0
  23. package/dist/api/demuxer.js.map +1 -0
  24. package/dist/api/device.d.ts +589 -0
  25. package/dist/api/device.js +964 -0
  26. package/dist/api/device.js.map +1 -0
  27. package/dist/api/encoder-pool.d.ts +262 -0
  28. package/dist/api/encoder-pool.js +397 -0
  29. package/dist/api/encoder-pool.js.map +1 -0
  30. package/dist/api/encoder.d.ts +1509 -0
  31. package/dist/api/encoder.js +2619 -0
  32. package/dist/api/encoder.js.map +1 -0
  33. package/dist/api/filter-complex.d.ts +828 -0
  34. package/dist/api/filter-complex.js +1661 -0
  35. package/dist/api/filter-complex.js.map +1 -0
  36. package/dist/api/filter-presets.d.ts +800 -0
  37. package/dist/api/filter-presets.js +1554 -0
  38. package/dist/api/filter-presets.js.map +1 -0
  39. package/dist/api/filter.d.ts +1339 -0
  40. package/dist/api/filter.js +2075 -0
  41. package/dist/api/filter.js.map +1 -0
  42. package/dist/api/fmp4-stream.d.ts +797 -0
  43. package/dist/api/fmp4-stream.js +1428 -0
  44. package/dist/api/fmp4-stream.js.map +1 -0
  45. package/dist/api/hardware.d.ts +677 -0
  46. package/dist/api/hardware.js +1300 -0
  47. package/dist/api/hardware.js.map +1 -0
  48. package/dist/api/index.d.ts +21 -0
  49. package/dist/api/index.js +38 -0
  50. package/dist/api/index.js.map +1 -0
  51. package/dist/api/io-stream.d.ts +308 -0
  52. package/dist/api/io-stream.js +358 -0
  53. package/dist/api/io-stream.js.map +1 -0
  54. package/dist/api/muxer.d.ts +1311 -0
  55. package/dist/api/muxer.js +2672 -0
  56. package/dist/api/muxer.js.map +1 -0
  57. package/dist/api/pipeline.d.ts +801 -0
  58. package/dist/api/pipeline.js +1344 -0
  59. package/dist/api/pipeline.js.map +1 -0
  60. package/dist/api/probe.d.ts +128 -0
  61. package/dist/api/probe.js +227 -0
  62. package/dist/api/probe.js.map +1 -0
  63. package/dist/api/rtp-stream.d.ts +497 -0
  64. package/dist/api/rtp-stream.js +1131 -0
  65. package/dist/api/rtp-stream.js.map +1 -0
  66. package/dist/api/scaler.d.ts +561 -0
  67. package/dist/api/scaler.js +918 -0
  68. package/dist/api/scaler.js.map +1 -0
  69. package/dist/api/types.d.ts +17 -0
  70. package/dist/api/types.js +2 -0
  71. package/dist/api/types.js.map +1 -0
  72. package/dist/api/utilities/async-queue.d.ts +149 -0
  73. package/dist/api/utilities/async-queue.js +254 -0
  74. package/dist/api/utilities/async-queue.js.map +1 -0
  75. package/dist/api/utilities/audio-sample.d.ts +117 -0
  76. package/dist/api/utilities/audio-sample.js +112 -0
  77. package/dist/api/utilities/audio-sample.js.map +1 -0
  78. package/dist/api/utilities/audio-transcode.d.ts +20 -0
  79. package/dist/api/utilities/audio-transcode.js +27 -0
  80. package/dist/api/utilities/audio-transcode.js.map +1 -0
  81. package/dist/api/utilities/channel-layout.d.ts +76 -0
  82. package/dist/api/utilities/channel-layout.js +80 -0
  83. package/dist/api/utilities/channel-layout.js.map +1 -0
  84. package/dist/api/utilities/codec-format.d.ts +87 -0
  85. package/dist/api/utilities/codec-format.js +117 -0
  86. package/dist/api/utilities/codec-format.js.map +1 -0
  87. package/dist/api/utilities/context-options.d.ts +25 -0
  88. package/dist/api/utilities/context-options.js +23 -0
  89. package/dist/api/utilities/context-options.js.map +1 -0
  90. package/dist/api/utilities/electron-shared-texture.d.ts +368 -0
  91. package/dist/api/utilities/electron-shared-texture.js +540 -0
  92. package/dist/api/utilities/electron-shared-texture.js.map +1 -0
  93. package/dist/api/utilities/image.d.ts +207 -0
  94. package/dist/api/utilities/image.js +213 -0
  95. package/dist/api/utilities/image.js.map +1 -0
  96. package/dist/api/utilities/index.d.ts +14 -0
  97. package/dist/api/utilities/index.js +27 -0
  98. package/dist/api/utilities/index.js.map +1 -0
  99. package/dist/api/utilities/live-decoding.d.ts +15 -0
  100. package/dist/api/utilities/live-decoding.js +32 -0
  101. package/dist/api/utilities/live-decoding.js.map +1 -0
  102. package/dist/api/utilities/media-type.d.ts +49 -0
  103. package/dist/api/utilities/media-type.js +53 -0
  104. package/dist/api/utilities/media-type.js.map +1 -0
  105. package/dist/api/utilities/packet-age-watchdog.d.ts +198 -0
  106. package/dist/api/utilities/packet-age-watchdog.js +594 -0
  107. package/dist/api/utilities/packet-age-watchdog.js.map +1 -0
  108. package/dist/api/utilities/pixel-format.d.ts +89 -0
  109. package/dist/api/utilities/pixel-format.js +97 -0
  110. package/dist/api/utilities/pixel-format.js.map +1 -0
  111. package/dist/api/utilities/sample-format.d.ts +129 -0
  112. package/dist/api/utilities/sample-format.js +141 -0
  113. package/dist/api/utilities/sample-format.js.map +1 -0
  114. package/dist/api/utilities/scale-size.d.ts +51 -0
  115. package/dist/api/utilities/scale-size.js +55 -0
  116. package/dist/api/utilities/scale-size.js.map +1 -0
  117. package/dist/api/utilities/scheduler.d.ts +138 -0
  118. package/dist/api/utilities/scheduler.js +98 -0
  119. package/dist/api/utilities/scheduler.js.map +1 -0
  120. package/dist/api/utilities/streaming.d.ts +186 -0
  121. package/dist/api/utilities/streaming.js +309 -0
  122. package/dist/api/utilities/streaming.js.map +1 -0
  123. package/dist/api/utilities/timestamp.d.ts +193 -0
  124. package/dist/api/utilities/timestamp.js +206 -0
  125. package/dist/api/utilities/timestamp.js.map +1 -0
  126. package/dist/api/utilities/video-transcode.d.ts +218 -0
  127. package/dist/api/utilities/video-transcode.js +624 -0
  128. package/dist/api/utilities/video-transcode.js.map +1 -0
  129. package/dist/api/utilities/whisper-model.d.ts +330 -0
  130. package/dist/api/utilities/whisper-model.js +587 -0
  131. package/dist/api/utilities/whisper-model.js.map +1 -0
  132. package/dist/api/utils.d.ts +19 -0
  133. package/dist/api/utils.js +39 -0
  134. package/dist/api/utils.js.map +1 -0
  135. package/dist/api/webrtc-stream.d.ts +294 -0
  136. package/dist/api/webrtc-stream.js +546 -0
  137. package/dist/api/webrtc-stream.js.map +1 -0
  138. package/dist/api/whisper.d.ts +326 -0
  139. package/dist/api/whisper.js +402 -0
  140. package/dist/api/whisper.js.map +1 -0
  141. package/dist/constants/bsf-options.d.ts +364 -0
  142. package/dist/constants/bsf-options.js +7 -0
  143. package/dist/constants/bsf-options.js.map +1 -0
  144. package/dist/constants/channel-layouts.d.ts +53 -0
  145. package/dist/constants/channel-layouts.js +57 -0
  146. package/dist/constants/channel-layouts.js.map +1 -0
  147. package/dist/constants/constants.d.ts +2435 -0
  148. package/dist/constants/constants.js +1989 -0
  149. package/dist/constants/constants.js.map +1 -0
  150. package/dist/constants/decoders.d.ts +651 -0
  151. package/dist/constants/decoders.js +641 -0
  152. package/dist/constants/decoders.js.map +1 -0
  153. package/dist/constants/encoders.d.ts +314 -0
  154. package/dist/constants/encoders.js +309 -0
  155. package/dist/constants/encoders.js.map +1 -0
  156. package/dist/constants/filter-options.d.ts +12099 -0
  157. package/dist/constants/filter-options.js +7 -0
  158. package/dist/constants/filter-options.js.map +1 -0
  159. package/dist/constants/format-options.d.ts +4319 -0
  160. package/dist/constants/format-options.js +7 -0
  161. package/dist/constants/format-options.js.map +1 -0
  162. package/dist/constants/formats.d.ts +18 -0
  163. package/dist/constants/formats.js +7 -0
  164. package/dist/constants/formats.js.map +1 -0
  165. package/dist/constants/hardware.d.ts +26 -0
  166. package/dist/constants/hardware.js +27 -0
  167. package/dist/constants/hardware.js.map +1 -0
  168. package/dist/constants/index.d.ts +10 -0
  169. package/dist/constants/index.js +6 -0
  170. package/dist/constants/index.js.map +1 -0
  171. package/dist/constants/options.d.ts +6217 -0
  172. package/dist/constants/options.js +7 -0
  173. package/dist/constants/options.js.map +1 -0
  174. package/dist/ffmpeg/index.d.ts +101 -0
  175. package/dist/ffmpeg/index.js +161 -0
  176. package/dist/ffmpeg/index.js.map +1 -0
  177. package/dist/ffmpeg/version.d.ts +6 -0
  178. package/dist/ffmpeg/version.js +7 -0
  179. package/dist/ffmpeg/version.js.map +1 -0
  180. package/dist/index.d.ts +4 -0
  181. package/dist/index.js +9 -0
  182. package/dist/index.js.map +1 -0
  183. package/dist/lib/audio-fifo.d.ts +399 -0
  184. package/dist/lib/audio-fifo.js +431 -0
  185. package/dist/lib/audio-fifo.js.map +1 -0
  186. package/dist/lib/binding.d.ts +242 -0
  187. package/dist/lib/binding.js +102 -0
  188. package/dist/lib/binding.js.map +1 -0
  189. package/dist/lib/bitstream-filter-context.d.ts +381 -0
  190. package/dist/lib/bitstream-filter-context.js +443 -0
  191. package/dist/lib/bitstream-filter-context.js.map +1 -0
  192. package/dist/lib/bitstream-filter.d.ts +140 -0
  193. package/dist/lib/bitstream-filter.js +154 -0
  194. package/dist/lib/bitstream-filter.js.map +1 -0
  195. package/dist/lib/codec-context.d.ts +1069 -0
  196. package/dist/lib/codec-context.js +1336 -0
  197. package/dist/lib/codec-context.js.map +1 -0
  198. package/dist/lib/codec-parameters.d.ts +664 -0
  199. package/dist/lib/codec-parameters.js +813 -0
  200. package/dist/lib/codec-parameters.js.map +1 -0
  201. package/dist/lib/codec-parser.d.ts +201 -0
  202. package/dist/lib/codec-parser.js +213 -0
  203. package/dist/lib/codec-parser.js.map +1 -0
  204. package/dist/lib/codec.d.ts +617 -0
  205. package/dist/lib/codec.js +746 -0
  206. package/dist/lib/codec.js.map +1 -0
  207. package/dist/lib/device.d.ts +294 -0
  208. package/dist/lib/device.js +326 -0
  209. package/dist/lib/device.js.map +1 -0
  210. package/dist/lib/dictionary.d.ts +333 -0
  211. package/dist/lib/dictionary.js +372 -0
  212. package/dist/lib/dictionary.js.map +1 -0
  213. package/dist/lib/error.d.ts +311 -0
  214. package/dist/lib/error.js +395 -0
  215. package/dist/lib/error.js.map +1 -0
  216. package/dist/lib/fifo.d.ts +416 -0
  217. package/dist/lib/fifo.js +453 -0
  218. package/dist/lib/fifo.js.map +1 -0
  219. package/dist/lib/filter-context.d.ts +714 -0
  220. package/dist/lib/filter-context.js +783 -0
  221. package/dist/lib/filter-context.js.map +1 -0
  222. package/dist/lib/filter-graph-segment.d.ts +161 -0
  223. package/dist/lib/filter-graph-segment.js +172 -0
  224. package/dist/lib/filter-graph-segment.js.map +1 -0
  225. package/dist/lib/filter-graph.d.ts +641 -0
  226. package/dist/lib/filter-graph.js +704 -0
  227. package/dist/lib/filter-graph.js.map +1 -0
  228. package/dist/lib/filter-inout.d.ts +202 -0
  229. package/dist/lib/filter-inout.js +261 -0
  230. package/dist/lib/filter-inout.js.map +1 -0
  231. package/dist/lib/filter.d.ts +243 -0
  232. package/dist/lib/filter.js +272 -0
  233. package/dist/lib/filter.js.map +1 -0
  234. package/dist/lib/format-context.d.ts +1335 -0
  235. package/dist/lib/format-context.js +1455 -0
  236. package/dist/lib/format-context.js.map +1 -0
  237. package/dist/lib/frame-utils.d.ts +116 -0
  238. package/dist/lib/frame-utils.js +98 -0
  239. package/dist/lib/frame-utils.js.map +1 -0
  240. package/dist/lib/frame.d.ts +1315 -0
  241. package/dist/lib/frame.js +1535 -0
  242. package/dist/lib/frame.js.map +1 -0
  243. package/dist/lib/hardware-device-context.d.ts +362 -0
  244. package/dist/lib/hardware-device-context.js +383 -0
  245. package/dist/lib/hardware-device-context.js.map +1 -0
  246. package/dist/lib/hardware-frames-context.d.ts +418 -0
  247. package/dist/lib/hardware-frames-context.js +471 -0
  248. package/dist/lib/hardware-frames-context.js.map +1 -0
  249. package/dist/lib/index.d.ts +35 -0
  250. package/dist/lib/index.js +60 -0
  251. package/dist/lib/index.js.map +1 -0
  252. package/dist/lib/input-format.d.ts +249 -0
  253. package/dist/lib/input-format.js +306 -0
  254. package/dist/lib/input-format.js.map +1 -0
  255. package/dist/lib/io-context.d.ts +698 -0
  256. package/dist/lib/io-context.js +771 -0
  257. package/dist/lib/io-context.js.map +1 -0
  258. package/dist/lib/log.d.ts +174 -0
  259. package/dist/lib/log.js +184 -0
  260. package/dist/lib/log.js.map +1 -0
  261. package/dist/lib/native-types.d.ts +1024 -0
  262. package/dist/lib/native-types.js +2 -0
  263. package/dist/lib/native-types.js.map +1 -0
  264. package/dist/lib/option.d.ts +953 -0
  265. package/dist/lib/option.js +1607 -0
  266. package/dist/lib/option.js.map +1 -0
  267. package/dist/lib/output-format.d.ts +222 -0
  268. package/dist/lib/output-format.js +259 -0
  269. package/dist/lib/output-format.js.map +1 -0
  270. package/dist/lib/packet.d.ts +521 -0
  271. package/dist/lib/packet.js +613 -0
  272. package/dist/lib/packet.js.map +1 -0
  273. package/dist/lib/rational.d.ts +251 -0
  274. package/dist/lib/rational.js +278 -0
  275. package/dist/lib/rational.js.map +1 -0
  276. package/dist/lib/software-resample-context.d.ts +552 -0
  277. package/dist/lib/software-resample-context.js +592 -0
  278. package/dist/lib/software-resample-context.js.map +1 -0
  279. package/dist/lib/software-scale-context.d.ts +344 -0
  280. package/dist/lib/software-scale-context.js +366 -0
  281. package/dist/lib/software-scale-context.js.map +1 -0
  282. package/dist/lib/stream.d.ts +383 -0
  283. package/dist/lib/stream.js +524 -0
  284. package/dist/lib/stream.js.map +1 -0
  285. package/dist/lib/sync-queue.d.ts +179 -0
  286. package/dist/lib/sync-queue.js +197 -0
  287. package/dist/lib/sync-queue.js.map +1 -0
  288. package/dist/lib/types.d.ts +34 -0
  289. package/dist/lib/types.js +2 -0
  290. package/dist/lib/types.js.map +1 -0
  291. package/dist/lib/utilities.d.ts +1198 -0
  292. package/dist/lib/utilities.js +1302 -0
  293. package/dist/lib/utilities.js.map +1 -0
  294. package/dist/utils/electron.d.ts +49 -0
  295. package/dist/utils/electron.js +63 -0
  296. package/dist/utils/electron.js.map +1 -0
  297. package/dist/utils/index.d.ts +6 -0
  298. package/dist/utils/index.js +7 -0
  299. package/dist/utils/index.js.map +1 -0
  300. package/dist/utils/libc.d.ts +11 -0
  301. package/dist/utils/libc.js +35 -0
  302. package/dist/utils/libc.js.map +1 -0
  303. package/dist/utils/variant.d.ts +26 -0
  304. package/dist/utils/variant.js +31 -0
  305. package/dist/utils/variant.js.map +1 -0
  306. package/dist/webrtc/index.d.ts +4 -0
  307. package/dist/webrtc/index.js +7 -0
  308. package/dist/webrtc/index.js.map +1 -0
  309. package/install/check.js +124 -0
  310. package/install/ffmpeg.js +66 -0
  311. package/package.json +165 -3
@@ -0,0 +1,402 @@
1
+ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
2
+ if (value !== null && value !== void 0) {
3
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
4
+ var dispose, inner;
5
+ if (async) {
6
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
7
+ dispose = value[Symbol.asyncDispose];
8
+ }
9
+ if (dispose === void 0) {
10
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
11
+ dispose = value[Symbol.dispose];
12
+ if (async) inner = dispose;
13
+ }
14
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
15
+ if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
16
+ env.stack.push({ value: value, dispose: dispose, async: async });
17
+ }
18
+ else if (async) {
19
+ env.stack.push({ async: true });
20
+ }
21
+ return value;
22
+ };
23
+ var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
24
+ return function (env) {
25
+ function fail(e) {
26
+ env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
27
+ env.hasError = true;
28
+ }
29
+ var r, s = 0;
30
+ function next() {
31
+ while (r = env.stack.pop()) {
32
+ try {
33
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
34
+ if (r.dispose) {
35
+ var result = r.dispose.call(r.value);
36
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
37
+ }
38
+ else s |= 1;
39
+ }
40
+ catch (e) {
41
+ fail(e);
42
+ }
43
+ }
44
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
45
+ if (env.hasError) throw env.error;
46
+ }
47
+ return next();
48
+ };
49
+ })(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
50
+ var e = new Error(message);
51
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
52
+ });
53
+ import { AV_NOPTS_VALUE } from '../constants/constants.js';
54
+ import { FilterPreset } from './filter-presets.js';
55
+ import { FilterAPI } from './filter.js';
56
+ import { WhisperDownloader } from './utilities/whisper-model.js';
57
+ /**
58
+ * High-level Whisper transcriber for automatic speech recognition.
59
+ *
60
+ * Provides streaming audio transcription using OpenAI's Whisper model via whisper.cpp.
61
+ * Supports GPU acceleration, VAD (Voice Activity Detection), and real-time processing.
62
+ * Built on FFmpeg's whisper filter with automatic frame metadata extraction.
63
+ *
64
+ * Features:
65
+ * - Real-time streaming transcription
66
+ * - GPU acceleration (CUDA/Vulkan/Metal)
67
+ * - Voice Activity Detection for better segmentation
68
+ * - Automatic language detection
69
+ * - Type-safe transcription segments
70
+ * - Frame-based API for flexible integration
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * import { Demuxer, Decoder, WhisperTranscriber } from 'node-av/api';
75
+ * import { WhisperDownloader } from 'node-av/api/utilities/whisper-model';
76
+ *
77
+ * // Download model
78
+ * const modelPath = await WhisperDownloader.downloadModel({
79
+ * model: 'base.en',
80
+ * outputPath: './models'
81
+ * });
82
+ *
83
+ * // Open audio and create decoder
84
+ * await using input = await Demuxer.open('podcast.mp3');
85
+ * using decoder = await Decoder.create(input.audio());
86
+ *
87
+ * // Create transcriber
88
+ * await using transcriber = await WhisperTranscriber.create({
89
+ * model: modelPath,
90
+ * language: 'en'
91
+ * });
92
+ *
93
+ * // Transcribe using decoded frames
94
+ * for await (const segment of transcriber.transcribe(decoder.frames(input.packets()))) {
95
+ * const timestamp = `[${(segment.start / 1000).toFixed(1)}s - ${(segment.end / 1000).toFixed(1)}s]`;
96
+ * console.log(`${timestamp}: ${segment.text}`);
97
+ * }
98
+ * ```
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * // Real-time microphone transcription with VAD
103
+ * import { Demuxer, Decoder, WhisperTranscriber } from 'node-av/api';
104
+ * import { WhisperDownloader } from 'node-av/api/utilities/whisper-model';
105
+ *
106
+ * // Download VAD model
107
+ * const vadPath = await WhisperDownloader.downloadVADModel('silero-v5.1.2', './models');
108
+ *
109
+ * // Setup transcriber with VAD
110
+ * await using transcriber = await WhisperTranscriber.create({
111
+ * model: './models/ggml-medium.bin',
112
+ * language: 'en',
113
+ * queue: 10,
114
+ * vadModel: vadPath,
115
+ * vadThreshold: 0.5
116
+ * });
117
+ *
118
+ * // Live transcription from decoded audio frames
119
+ * using decoder = await Decoder.create(microphoneStream);
120
+ * for await (const segment of transcriber.transcribe(decoder.frames(microphonePackets))) {
121
+ * if (segment.turn) {
122
+ * console.log('\n--- New speaker turn ---');
123
+ * }
124
+ * console.log(segment.text);
125
+ * }
126
+ * ```
127
+ *
128
+ * @see {@link WhisperDownloader} For downloading Whisper and VAD models
129
+ * @see {@link Decoder} For audio decoding
130
+ * @see {@link Demuxer} For reading media files
131
+ */
132
+ export class WhisperTranscriber {
133
+ options;
134
+ isClosed = false;
135
+ /**
136
+ * @param options - Transcriber configuration
137
+ *
138
+ * Use {@link create} factory method instead
139
+ *
140
+ * @internal
141
+ */
142
+ constructor(options) {
143
+ this.options = options;
144
+ }
145
+ /**
146
+ * Create a Whisper transcriber instance.
147
+ *
148
+ * Initializes the transcriber with the specified model and configuration.
149
+ * The transcriber can then process audio frames from any source.
150
+ *
151
+ * @param options - Transcriber configuration
152
+ *
153
+ * @returns Configured transcriber instance
154
+ *
155
+ * @throws {Error} If model file does not exist
156
+ *
157
+ * @throws {Error} If VAD model file does not exist (when vadModel specified)
158
+ *
159
+ * @example
160
+ * ```typescript
161
+ * import { WhisperTranscriber } from 'node-av/api';
162
+ *
163
+ * // Create transcriber with basic options
164
+ * await using transcriber = await WhisperTranscriber.create({
165
+ * model: './models/ggml-base.en.bin',
166
+ * language: 'en'
167
+ * });
168
+ * ```
169
+ *
170
+ * @example
171
+ * ```typescript
172
+ * // Create transcriber with GPU and VAD support
173
+ * await using transcriber = await WhisperTranscriber.create({
174
+ * model: './models/ggml-base.bin',
175
+ * language: 'auto',
176
+ * useGpu: true,
177
+ * gpuDevice: 0,
178
+ * vadModel: './models/ggml-silero-v5.1.2.bin',
179
+ * vadThreshold: 0.5,
180
+ * queue: 10
181
+ * });
182
+ * ```
183
+ */
184
+ static async create(options) {
185
+ const modelsToDownload = [options.model, options.vadModel].filter(Boolean);
186
+ const [modelPath, vadModelPath] = await WhisperDownloader.downloadModels(modelsToDownload, options.modelDir);
187
+ const fullOptions = {
188
+ model: modelPath,
189
+ vadModel: vadModelPath,
190
+ modelDir: options.modelDir ?? WhisperDownloader.DEFAULT_MODEL_PATH,
191
+ language: options.language ?? 'auto',
192
+ queue: options.queue ?? 3,
193
+ useGpu: options.useGpu ?? true,
194
+ gpuDevice: options.gpuDevice ?? 0,
195
+ vadThreshold: options.vadThreshold ?? 0.5,
196
+ vadMinSpeechDuration: options.vadMinSpeechDuration ?? 0.1,
197
+ vadMinSilenceDuration: options.vadMinSilenceDuration ?? 0.5,
198
+ };
199
+ return new WhisperTranscriber(fullOptions);
200
+ }
201
+ /**
202
+ * Transcribe audio frames to text segments.
203
+ *
204
+ * Processes audio frames through the Whisper filter and yields transcribed segments.
205
+ * Each segment contains start/end timestamps and the transcribed text.
206
+ * Reads metadata directly from frame metadata tags (lavfi.whisper.text, lavfi.whisper.duration).
207
+ *
208
+ * The generator continues until the input stream ends or close() is called.
209
+ * When the input ends, the filter is flushed so audio still buffered in the
210
+ * whisper queue is transcribed before the generator finishes.
211
+ * Always use with `for await...of` to properly handle async iteration.
212
+ *
213
+ * @param frames - Audio frames (from Decoder.frames()) or single frame to transcribe
214
+ *
215
+ * @yields {WhisperSegment} Transcribed audio segments with timing and text
216
+ *
217
+ * @throws {FFmpegError} If filter initialization fails
218
+ *
219
+ * @example
220
+ * ```typescript
221
+ * import { Demuxer, Decoder, WhisperTranscriber } from 'node-av/api';
222
+ *
223
+ * await using input = await Demuxer.open('podcast.mp3');
224
+ * using decoder = await Decoder.create(input.audio());
225
+ * await using transcriber = await WhisperTranscriber.create({
226
+ * model: './models/ggml-base.en.bin',
227
+ * language: 'en'
228
+ * });
229
+ *
230
+ * // Transcribe decoded frames
231
+ * for await (const segment of transcriber.transcribe(decoder.frames(input.packets()))) {
232
+ * console.log(`[${segment.start}ms]: ${segment.text}`);
233
+ * }
234
+ * ```
235
+ *
236
+ * @example
237
+ * ```typescript
238
+ * // With custom timing format
239
+ * const audioFrames = decoder.frames(input.packets());
240
+ * for await (const segment of transcriber.transcribe(audioFrames)) {
241
+ * const startSec = (segment.start / 1000).toFixed(2);
242
+ * const endSec = (segment.end / 1000).toFixed(2);
243
+ * console.log(`[${startSec}s - ${endSec}s]: ${segment.text}`);
244
+ * }
245
+ * ```
246
+ *
247
+ * @example
248
+ * ```typescript
249
+ * // Process single frame
250
+ * using frame = decoder.decodeSync(packet);
251
+ * for await (const segment of transcriber.transcribe(frame)) {
252
+ * console.log(`Transcribed: ${segment.text}`);
253
+ * }
254
+ * ```
255
+ */
256
+ async *transcribe(frames) {
257
+ const env_1 = { stack: [], error: void 0, hasError: false };
258
+ try {
259
+ const chain = FilterPreset.chain()
260
+ .whisper({
261
+ model: this.options.model,
262
+ language: this.options.language,
263
+ queue: this.options.queue,
264
+ useGpu: this.options.useGpu,
265
+ gpuDevice: this.options.gpuDevice,
266
+ vadModel: this.options.vadModel,
267
+ vadThreshold: this.options.vadThreshold,
268
+ vadMinSpeechDuration: this.options.vadMinSpeechDuration,
269
+ vadMinSilenceDuration: this.options.vadMinSilenceDuration,
270
+ })
271
+ .build();
272
+ // Create filter API
273
+ const filter = __addDisposableResource(env_1, FilterAPI.create(chain, {
274
+ allowReinit: true,
275
+ dropOnChange: false,
276
+ }), false);
277
+ // Fallback clock for frames without usable timestamps (in milliseconds)
278
+ let fallbackEnd = 0;
279
+ const toSegment = (frame) => {
280
+ const metadata = frame.getMetadata();
281
+ const text = metadata.get('lavfi.whisper.text');
282
+ const durationStr = metadata.get('lavfi.whisper.duration');
283
+ if (!text?.trim()) {
284
+ return null;
285
+ }
286
+ // Parse duration (in seconds)
287
+ const duration = durationStr ? parseFloat(durationStr) * 1000 : 0;
288
+ // The whisper filter attaches its result to the frame that triggered the
289
+ // transcription, so that frame's timestamp marks (approximately) the end
290
+ // of the transcribed chunk. Deriving start/end from the frame PTS keeps
291
+ // segments aligned with the actual audio position; a counter that only
292
+ // advances on chunks that produced text would silently swallow every
293
+ // silent span and drift (e.g. a 60s intro would put the first segment
294
+ // at start 0).
295
+ const tb = frame.timeBase;
296
+ const frameTime = frame.pts !== AV_NOPTS_VALUE && tb.den !== 0 ? (Number(frame.pts) * 1000 * tb.num) / tb.den : null;
297
+ const end = frameTime ?? fallbackEnd + duration;
298
+ fallbackEnd = end;
299
+ return {
300
+ start: Math.max(0, end - duration),
301
+ end,
302
+ text: text.trim(),
303
+ };
304
+ };
305
+ // Decode and process frames through filter
306
+ for await (const frame_1 of filter.frames(frames)) {
307
+ const env_2 = { stack: [], error: void 0, hasError: false };
308
+ try {
309
+ const frame = __addDisposableResource(env_2, frame_1, false);
310
+ if (this.isClosed) {
311
+ break;
312
+ }
313
+ if (!frame?.isAudio()) {
314
+ continue;
315
+ }
316
+ const segment = toSegment(frame);
317
+ if (segment) {
318
+ yield segment;
319
+ }
320
+ }
321
+ catch (e_1) {
322
+ env_2.error = e_1;
323
+ env_2.hasError = true;
324
+ }
325
+ finally {
326
+ __disposeResources(env_2);
327
+ }
328
+ }
329
+ // Inputs that end without a trailing null never flush the filter, and the
330
+ // whisper queue (up to `queue` seconds of buffered audio) would be
331
+ // destroyed with it. Drain explicitly; after an upstream EOF this second
332
+ // flush is a no-op.
333
+ if (!this.isClosed) {
334
+ for await (const frame_2 of filter.flushFrames()) {
335
+ const env_3 = { stack: [], error: void 0, hasError: false };
336
+ try {
337
+ const frame = __addDisposableResource(env_3, frame_2, false);
338
+ if (!frame.isAudio()) {
339
+ continue;
340
+ }
341
+ const segment = toSegment(frame);
342
+ if (segment) {
343
+ yield segment;
344
+ }
345
+ }
346
+ catch (e_2) {
347
+ env_3.error = e_2;
348
+ env_3.hasError = true;
349
+ }
350
+ finally {
351
+ __disposeResources(env_3);
352
+ }
353
+ }
354
+ }
355
+ }
356
+ catch (e_3) {
357
+ env_1.error = e_3;
358
+ env_1.hasError = true;
359
+ }
360
+ finally {
361
+ __disposeResources(env_1);
362
+ }
363
+ }
364
+ /**
365
+ * Close transcriber and clean up resources.
366
+ *
367
+ * Releases filter graph and stops frame processing.
368
+ * Called automatically when using `await using` syntax.
369
+ *
370
+ * @example
371
+ * ```typescript
372
+ * // Automatic cleanup
373
+ * {
374
+ * await using transcriber = await WhisperTranscriber.create(options);
375
+ * // Use transcriber
376
+ * } // Automatically calls close()
377
+ *
378
+ * // Manual cleanup
379
+ * const transcriber = await WhisperTranscriber.create(options);
380
+ * try {
381
+ * // Use transcriber
382
+ * } finally {
383
+ * await transcriber.close();
384
+ * }
385
+ * ```
386
+ */
387
+ close() {
388
+ if (this.isClosed) {
389
+ return;
390
+ }
391
+ this.isClosed = true;
392
+ }
393
+ /**
394
+ * Symbol.asyncDispose implementation for `await using` syntax.
395
+ *
396
+ * @internal
397
+ */
398
+ [Symbol.dispose]() {
399
+ this.close();
400
+ }
401
+ }
402
+ //# sourceMappingURL=whisper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whisper.js","sourceRoot":"","sources":["../../src/api/whisper.ts"],"names":[],"mappings":"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"}