webcodecs-node 0.2.2

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 (455) hide show
  1. package/LICENSE +656 -0
  2. package/README.md +607 -0
  3. package/dist/AudioData.d.ts +6 -0
  4. package/dist/AudioData.d.ts.map +1 -0
  5. package/dist/AudioData.js +6 -0
  6. package/dist/AudioData.js.map +1 -0
  7. package/dist/AudioDecoder.d.ts +6 -0
  8. package/dist/AudioDecoder.d.ts.map +1 -0
  9. package/dist/AudioDecoder.js +6 -0
  10. package/dist/AudioDecoder.js.map +1 -0
  11. package/dist/AudioEncoder.d.ts +6 -0
  12. package/dist/AudioEncoder.d.ts.map +1 -0
  13. package/dist/AudioEncoder.js +6 -0
  14. package/dist/AudioEncoder.js.map +1 -0
  15. package/dist/EncodedAudioChunk.d.ts +6 -0
  16. package/dist/EncodedAudioChunk.d.ts.map +1 -0
  17. package/dist/EncodedAudioChunk.js +6 -0
  18. package/dist/EncodedAudioChunk.js.map +1 -0
  19. package/dist/EncodedVideoChunk.d.ts +6 -0
  20. package/dist/EncodedVideoChunk.d.ts.map +1 -0
  21. package/dist/EncodedVideoChunk.js +6 -0
  22. package/dist/EncodedVideoChunk.js.map +1 -0
  23. package/dist/FFmpegProcess.d.ts +6 -0
  24. package/dist/FFmpegProcess.d.ts.map +1 -0
  25. package/dist/FFmpegProcess.js +6 -0
  26. package/dist/FFmpegProcess.js.map +1 -0
  27. package/dist/HardwareAcceleration.d.ts +6 -0
  28. package/dist/HardwareAcceleration.d.ts.map +1 -0
  29. package/dist/HardwareAcceleration.js +6 -0
  30. package/dist/HardwareAcceleration.js.map +1 -0
  31. package/dist/ImageDecoder.d.ts +6 -0
  32. package/dist/ImageDecoder.d.ts.map +1 -0
  33. package/dist/ImageDecoder.js +6 -0
  34. package/dist/ImageDecoder.js.map +1 -0
  35. package/dist/Logger.d.ts +6 -0
  36. package/dist/Logger.d.ts.map +1 -0
  37. package/dist/Logger.js +6 -0
  38. package/dist/Logger.js.map +1 -0
  39. package/dist/MediaCapabilities.d.ts +9 -0
  40. package/dist/MediaCapabilities.d.ts.map +1 -0
  41. package/dist/MediaCapabilities.js +8 -0
  42. package/dist/MediaCapabilities.js.map +1 -0
  43. package/dist/VideoDecoder.d.ts +6 -0
  44. package/dist/VideoDecoder.d.ts.map +1 -0
  45. package/dist/VideoDecoder.js +6 -0
  46. package/dist/VideoDecoder.js.map +1 -0
  47. package/dist/VideoEncoder.d.ts +6 -0
  48. package/dist/VideoEncoder.d.ts.map +1 -0
  49. package/dist/VideoEncoder.js +6 -0
  50. package/dist/VideoEncoder.js.map +1 -0
  51. package/dist/VideoFrame.d.ts +10 -0
  52. package/dist/VideoFrame.d.ts.map +1 -0
  53. package/dist/VideoFrame.js +9 -0
  54. package/dist/VideoFrame.js.map +1 -0
  55. package/dist/__tests__/AudioData.test.d.ts +5 -0
  56. package/dist/__tests__/AudioData.test.d.ts.map +1 -0
  57. package/dist/__tests__/AudioData.test.js +179 -0
  58. package/dist/__tests__/AudioData.test.js.map +1 -0
  59. package/dist/__tests__/AudioDecoder.test.d.ts +5 -0
  60. package/dist/__tests__/AudioDecoder.test.d.ts.map +1 -0
  61. package/dist/__tests__/AudioDecoder.test.js +733 -0
  62. package/dist/__tests__/AudioDecoder.test.js.map +1 -0
  63. package/dist/__tests__/AudioEncoder.test.d.ts +5 -0
  64. package/dist/__tests__/AudioEncoder.test.d.ts.map +1 -0
  65. package/dist/__tests__/AudioEncoder.test.js +247 -0
  66. package/dist/__tests__/AudioEncoder.test.js.map +1 -0
  67. package/dist/__tests__/EncodedChunks.test.d.ts +5 -0
  68. package/dist/__tests__/EncodedChunks.test.d.ts.map +1 -0
  69. package/dist/__tests__/EncodedChunks.test.js +99 -0
  70. package/dist/__tests__/EncodedChunks.test.js.map +1 -0
  71. package/dist/__tests__/HardwareAcceleration.test.d.ts +5 -0
  72. package/dist/__tests__/HardwareAcceleration.test.d.ts.map +1 -0
  73. package/dist/__tests__/HardwareAcceleration.test.js +84 -0
  74. package/dist/__tests__/HardwareAcceleration.test.js.map +1 -0
  75. package/dist/__tests__/ImageDecoder.test.d.ts +5 -0
  76. package/dist/__tests__/ImageDecoder.test.d.ts.map +1 -0
  77. package/dist/__tests__/ImageDecoder.test.js +587 -0
  78. package/dist/__tests__/ImageDecoder.test.js.map +1 -0
  79. package/dist/__tests__/MediaCapabilities.test.d.ts +5 -0
  80. package/dist/__tests__/MediaCapabilities.test.d.ts.map +1 -0
  81. package/dist/__tests__/MediaCapabilities.test.js +346 -0
  82. package/dist/__tests__/MediaCapabilities.test.js.map +1 -0
  83. package/dist/__tests__/VideoDecoder.test.d.ts +5 -0
  84. package/dist/__tests__/VideoDecoder.test.d.ts.map +1 -0
  85. package/dist/__tests__/VideoDecoder.test.js +675 -0
  86. package/dist/__tests__/VideoDecoder.test.js.map +1 -0
  87. package/dist/__tests__/VideoEncoder.test.d.ts +5 -0
  88. package/dist/__tests__/VideoEncoder.test.d.ts.map +1 -0
  89. package/dist/__tests__/VideoEncoder.test.js +468 -0
  90. package/dist/__tests__/VideoEncoder.test.js.map +1 -0
  91. package/dist/__tests__/VideoFrame.test.d.ts +5 -0
  92. package/dist/__tests__/VideoFrame.test.d.ts.map +1 -0
  93. package/dist/__tests__/VideoFrame.test.js +243 -0
  94. package/dist/__tests__/VideoFrame.test.js.map +1 -0
  95. package/dist/__tests__/aac-utils.test.d.ts +2 -0
  96. package/dist/__tests__/aac-utils.test.d.ts.map +1 -0
  97. package/dist/__tests__/aac-utils.test.js +37 -0
  98. package/dist/__tests__/aac-utils.test.js.map +1 -0
  99. package/dist/__tests__/avc-utils.test.d.ts +2 -0
  100. package/dist/__tests__/avc-utils.test.d.ts.map +1 -0
  101. package/dist/__tests__/avc-utils.test.js +63 -0
  102. package/dist/__tests__/avc-utils.test.js.map +1 -0
  103. package/dist/__tests__/hevc-utils.test.d.ts +2 -0
  104. package/dist/__tests__/hevc-utils.test.d.ts.map +1 -0
  105. package/dist/__tests__/hevc-utils.test.js +78 -0
  106. package/dist/__tests__/hevc-utils.test.js.map +1 -0
  107. package/dist/capabilities/MediaCapabilities.d.ts +78 -0
  108. package/dist/capabilities/MediaCapabilities.d.ts.map +1 -0
  109. package/dist/capabilities/MediaCapabilities.js +276 -0
  110. package/dist/capabilities/MediaCapabilities.js.map +1 -0
  111. package/dist/capabilities/codecs.d.ts +72 -0
  112. package/dist/capabilities/codecs.d.ts.map +1 -0
  113. package/dist/capabilities/codecs.js +153 -0
  114. package/dist/capabilities/codecs.js.map +1 -0
  115. package/dist/capabilities/index.d.ts +7 -0
  116. package/dist/capabilities/index.d.ts.map +1 -0
  117. package/dist/capabilities/index.js +8 -0
  118. package/dist/capabilities/index.js.map +1 -0
  119. package/dist/capabilities/types.d.ts +77 -0
  120. package/dist/capabilities/types.d.ts.map +1 -0
  121. package/dist/capabilities/types.js +5 -0
  122. package/dist/capabilities/types.js.map +1 -0
  123. package/dist/core/AudioData.d.ts +36 -0
  124. package/dist/core/AudioData.d.ts.map +1 -0
  125. package/dist/core/AudioData.js +229 -0
  126. package/dist/core/AudioData.js.map +1 -0
  127. package/dist/core/EncodedAudioChunk.d.ts +26 -0
  128. package/dist/core/EncodedAudioChunk.d.ts.map +1 -0
  129. package/dist/core/EncodedAudioChunk.js +58 -0
  130. package/dist/core/EncodedAudioChunk.js.map +1 -0
  131. package/dist/core/EncodedVideoChunk.d.ts +23 -0
  132. package/dist/core/EncodedVideoChunk.d.ts.map +1 -0
  133. package/dist/core/EncodedVideoChunk.js +55 -0
  134. package/dist/core/EncodedVideoChunk.js.map +1 -0
  135. package/dist/core/VideoFrame.d.ts +61 -0
  136. package/dist/core/VideoFrame.d.ts.map +1 -0
  137. package/dist/core/VideoFrame.js +385 -0
  138. package/dist/core/VideoFrame.js.map +1 -0
  139. package/dist/core/index.d.ts +8 -0
  140. package/dist/core/index.d.ts.map +1 -0
  141. package/dist/core/index.js +8 -0
  142. package/dist/core/index.js.map +1 -0
  143. package/dist/debug-h264.d.ts +5 -0
  144. package/dist/debug-h264.d.ts.map +1 -0
  145. package/dist/debug-h264.js +103 -0
  146. package/dist/debug-h264.js.map +1 -0
  147. package/dist/decoders/AudioDecoder.d.ts +57 -0
  148. package/dist/decoders/AudioDecoder.d.ts.map +1 -0
  149. package/dist/decoders/AudioDecoder.js +333 -0
  150. package/dist/decoders/AudioDecoder.js.map +1 -0
  151. package/dist/decoders/ImageDecoder.d.ts +111 -0
  152. package/dist/decoders/ImageDecoder.d.ts.map +1 -0
  153. package/dist/decoders/ImageDecoder.js +686 -0
  154. package/dist/decoders/ImageDecoder.js.map +1 -0
  155. package/dist/decoders/VideoDecoder.d.ts +70 -0
  156. package/dist/decoders/VideoDecoder.d.ts.map +1 -0
  157. package/dist/decoders/VideoDecoder.js +410 -0
  158. package/dist/decoders/VideoDecoder.js.map +1 -0
  159. package/dist/decoders/index.d.ts +8 -0
  160. package/dist/decoders/index.d.ts.map +1 -0
  161. package/dist/decoders/index.js +7 -0
  162. package/dist/decoders/index.js.map +1 -0
  163. package/dist/demos/demo-audio-opus.d.ts +5 -0
  164. package/dist/demos/demo-audio-opus.d.ts.map +1 -0
  165. package/dist/demos/demo-audio-opus.js +107 -0
  166. package/dist/demos/demo-audio-opus.js.map +1 -0
  167. package/dist/demos/demo-audio.d.ts +10 -0
  168. package/dist/demos/demo-audio.d.ts.map +1 -0
  169. package/dist/demos/demo-audio.js +135 -0
  170. package/dist/demos/demo-audio.js.map +1 -0
  171. package/dist/demos/demo-conversion.d.ts +13 -0
  172. package/dist/demos/demo-conversion.d.ts.map +1 -0
  173. package/dist/demos/demo-conversion.js +301 -0
  174. package/dist/demos/demo-conversion.js.map +1 -0
  175. package/dist/demos/demo-h264.d.ts +7 -0
  176. package/dist/demos/demo-h264.d.ts.map +1 -0
  177. package/dist/demos/demo-h264.js +134 -0
  178. package/dist/demos/demo-h264.js.map +1 -0
  179. package/dist/demos/demo-hwaccel-conversion.d.ts +8 -0
  180. package/dist/demos/demo-hwaccel-conversion.d.ts.map +1 -0
  181. package/dist/demos/demo-hwaccel-conversion.js +161 -0
  182. package/dist/demos/demo-hwaccel-conversion.js.map +1 -0
  183. package/dist/demos/demo-hwaccel.d.ts +7 -0
  184. package/dist/demos/demo-hwaccel.d.ts.map +1 -0
  185. package/dist/demos/demo-hwaccel.js +51 -0
  186. package/dist/demos/demo-hwaccel.js.map +1 -0
  187. package/dist/demos/demo-image.d.ts +12 -0
  188. package/dist/demos/demo-image.d.ts.map +1 -0
  189. package/dist/demos/demo-image.js +178 -0
  190. package/dist/demos/demo-image.js.map +1 -0
  191. package/dist/demos/demo-mediabunny.d.ts +7 -0
  192. package/dist/demos/demo-mediabunny.d.ts.map +1 -0
  193. package/dist/demos/demo-mediabunny.js +78 -0
  194. package/dist/demos/demo-mediabunny.js.map +1 -0
  195. package/dist/demos/demo-pipeline.d.ts +8 -0
  196. package/dist/demos/demo-pipeline.d.ts.map +1 -0
  197. package/dist/demos/demo-pipeline.js +83 -0
  198. package/dist/demos/demo-pipeline.js.map +1 -0
  199. package/dist/demos/demo-samples.d.ts +9 -0
  200. package/dist/demos/demo-samples.d.ts.map +1 -0
  201. package/dist/demos/demo-samples.js +413 -0
  202. package/dist/demos/demo-samples.js.map +1 -0
  203. package/dist/demos/demo-streaming.d.ts +8 -0
  204. package/dist/demos/demo-streaming.d.ts.map +1 -0
  205. package/dist/demos/demo-streaming.js +299 -0
  206. package/dist/demos/demo-streaming.js.map +1 -0
  207. package/dist/demos/demo-webcodecs.d.ts +8 -0
  208. package/dist/demos/demo-webcodecs.d.ts.map +1 -0
  209. package/dist/demos/demo-webcodecs.js +316 -0
  210. package/dist/demos/demo-webcodecs.js.map +1 -0
  211. package/dist/demos/demo.d.ts +10 -0
  212. package/dist/demos/demo.d.ts.map +1 -0
  213. package/dist/demos/demo.js +123 -0
  214. package/dist/demos/demo.js.map +1 -0
  215. package/dist/encoders/AudioEncoder.d.ts +69 -0
  216. package/dist/encoders/AudioEncoder.d.ts.map +1 -0
  217. package/dist/encoders/AudioEncoder.js +425 -0
  218. package/dist/encoders/AudioEncoder.js.map +1 -0
  219. package/dist/encoders/VideoEncoder.d.ts +80 -0
  220. package/dist/encoders/VideoEncoder.d.ts.map +1 -0
  221. package/dist/encoders/VideoEncoder.js +386 -0
  222. package/dist/encoders/VideoEncoder.js.map +1 -0
  223. package/dist/encoders/codecs/av1.d.ts +31 -0
  224. package/dist/encoders/codecs/av1.d.ts.map +1 -0
  225. package/dist/encoders/codecs/av1.js +66 -0
  226. package/dist/encoders/codecs/av1.js.map +1 -0
  227. package/dist/encoders/codecs/h264.d.ts +28 -0
  228. package/dist/encoders/codecs/h264.d.ts.map +1 -0
  229. package/dist/encoders/codecs/h264.js +95 -0
  230. package/dist/encoders/codecs/h264.js.map +1 -0
  231. package/dist/encoders/codecs/hevc.d.ts +28 -0
  232. package/dist/encoders/codecs/hevc.d.ts.map +1 -0
  233. package/dist/encoders/codecs/hevc.js +73 -0
  234. package/dist/encoders/codecs/hevc.js.map +1 -0
  235. package/dist/encoders/codecs/index.d.ts +19 -0
  236. package/dist/encoders/codecs/index.d.ts.map +1 -0
  237. package/dist/encoders/codecs/index.js +60 -0
  238. package/dist/encoders/codecs/index.js.map +1 -0
  239. package/dist/encoders/codecs/vp9.d.ts +29 -0
  240. package/dist/encoders/codecs/vp9.d.ts.map +1 -0
  241. package/dist/encoders/codecs/vp9.js +58 -0
  242. package/dist/encoders/codecs/vp9.js.map +1 -0
  243. package/dist/encoders/index.d.ts +8 -0
  244. package/dist/encoders/index.d.ts.map +1 -0
  245. package/dist/encoders/index.js +8 -0
  246. package/dist/encoders/index.js.map +1 -0
  247. package/dist/ffmpeg/FFmpegProcess.d.ts +111 -0
  248. package/dist/ffmpeg/FFmpegProcess.d.ts.map +1 -0
  249. package/dist/ffmpeg/FFmpegProcess.js +543 -0
  250. package/dist/ffmpeg/FFmpegProcess.js.map +1 -0
  251. package/dist/ffmpeg/audio-codecs.d.ts +59 -0
  252. package/dist/ffmpeg/audio-codecs.d.ts.map +1 -0
  253. package/dist/ffmpeg/audio-codecs.js +99 -0
  254. package/dist/ffmpeg/audio-codecs.js.map +1 -0
  255. package/dist/ffmpeg/formats.d.ts +42 -0
  256. package/dist/ffmpeg/formats.d.ts.map +1 -0
  257. package/dist/ffmpeg/formats.js +147 -0
  258. package/dist/ffmpeg/formats.js.map +1 -0
  259. package/dist/ffmpeg/index.d.ts +9 -0
  260. package/dist/ffmpeg/index.d.ts.map +1 -0
  261. package/dist/ffmpeg/index.js +13 -0
  262. package/dist/ffmpeg/index.js.map +1 -0
  263. package/dist/ffmpeg/parsers/annexb.d.ts +88 -0
  264. package/dist/ffmpeg/parsers/annexb.d.ts.map +1 -0
  265. package/dist/ffmpeg/parsers/annexb.js +201 -0
  266. package/dist/ffmpeg/parsers/annexb.js.map +1 -0
  267. package/dist/ffmpeg/parsers/index.d.ts +6 -0
  268. package/dist/ffmpeg/parsers/index.d.ts.map +1 -0
  269. package/dist/ffmpeg/parsers/index.js +8 -0
  270. package/dist/ffmpeg/parsers/index.js.map +1 -0
  271. package/dist/ffmpeg/parsers/ivf.d.ts +54 -0
  272. package/dist/ffmpeg/parsers/ivf.d.ts.map +1 -0
  273. package/dist/ffmpeg/parsers/ivf.js +109 -0
  274. package/dist/ffmpeg/parsers/ivf.js.map +1 -0
  275. package/dist/ffmpeg/types.d.ts +85 -0
  276. package/dist/ffmpeg/types.d.ts.map +1 -0
  277. package/dist/ffmpeg/types.js +8 -0
  278. package/dist/ffmpeg/types.js.map +1 -0
  279. package/dist/formats/audio-formats.d.ts +61 -0
  280. package/dist/formats/audio-formats.d.ts.map +1 -0
  281. package/dist/formats/audio-formats.js +113 -0
  282. package/dist/formats/audio-formats.js.map +1 -0
  283. package/dist/formats/color-space.d.ts +35 -0
  284. package/dist/formats/color-space.d.ts.map +1 -0
  285. package/dist/formats/color-space.js +62 -0
  286. package/dist/formats/color-space.js.map +1 -0
  287. package/dist/formats/conversions/frame-converter.d.ts +42 -0
  288. package/dist/formats/conversions/frame-converter.d.ts.map +1 -0
  289. package/dist/formats/conversions/frame-converter.js +244 -0
  290. package/dist/formats/conversions/frame-converter.js.map +1 -0
  291. package/dist/formats/conversions/index.d.ts +8 -0
  292. package/dist/formats/conversions/index.d.ts.map +1 -0
  293. package/dist/formats/conversions/index.js +10 -0
  294. package/dist/formats/conversions/index.js.map +1 -0
  295. package/dist/formats/index.d.ts +9 -0
  296. package/dist/formats/index.d.ts.map +1 -0
  297. package/dist/formats/index.js +14 -0
  298. package/dist/formats/index.js.map +1 -0
  299. package/dist/formats/parsers/index.d.ts +5 -0
  300. package/dist/formats/parsers/index.d.ts.map +1 -0
  301. package/dist/formats/parsers/index.js +5 -0
  302. package/dist/formats/parsers/index.js.map +1 -0
  303. package/dist/formats/parsers/webp.d.ts +16 -0
  304. package/dist/formats/parsers/webp.d.ts.map +1 -0
  305. package/dist/formats/parsers/webp.js +116 -0
  306. package/dist/formats/parsers/webp.js.map +1 -0
  307. package/dist/formats/pixel-formats.d.ts +41 -0
  308. package/dist/formats/pixel-formats.d.ts.map +1 -0
  309. package/dist/formats/pixel-formats.js +113 -0
  310. package/dist/formats/pixel-formats.js.map +1 -0
  311. package/dist/hardware/HardwareAcceleration.d.ts +6 -0
  312. package/dist/hardware/HardwareAcceleration.d.ts.map +1 -0
  313. package/dist/hardware/HardwareAcceleration.js +6 -0
  314. package/dist/hardware/HardwareAcceleration.js.map +1 -0
  315. package/dist/hardware/decoder-args.d.ts +25 -0
  316. package/dist/hardware/decoder-args.d.ts.map +1 -0
  317. package/dist/hardware/decoder-args.js +84 -0
  318. package/dist/hardware/decoder-args.js.map +1 -0
  319. package/dist/hardware/detection.d.ts +39 -0
  320. package/dist/hardware/detection.d.ts.map +1 -0
  321. package/dist/hardware/detection.js +178 -0
  322. package/dist/hardware/detection.js.map +1 -0
  323. package/dist/hardware/encoder-args.d.ts +38 -0
  324. package/dist/hardware/encoder-args.d.ts.map +1 -0
  325. package/dist/hardware/encoder-args.js +177 -0
  326. package/dist/hardware/encoder-args.js.map +1 -0
  327. package/dist/hardware/index.d.ts +12 -0
  328. package/dist/hardware/index.d.ts.map +1 -0
  329. package/dist/hardware/index.js +14 -0
  330. package/dist/hardware/index.js.map +1 -0
  331. package/dist/hardware/types.d.ts +29 -0
  332. package/dist/hardware/types.d.ts.map +1 -0
  333. package/dist/hardware/types.js +58 -0
  334. package/dist/hardware/types.js.map +1 -0
  335. package/dist/index.d.ts +44 -0
  336. package/dist/index.d.ts.map +1 -0
  337. package/dist/index.js +37 -0
  338. package/dist/index.js.map +1 -0
  339. package/dist/mediabunny/FFmpegAudioDecoder.d.ts +37 -0
  340. package/dist/mediabunny/FFmpegAudioDecoder.d.ts.map +1 -0
  341. package/dist/mediabunny/FFmpegAudioDecoder.js +254 -0
  342. package/dist/mediabunny/FFmpegAudioDecoder.js.map +1 -0
  343. package/dist/mediabunny/FFmpegAudioEncoder.d.ts +77 -0
  344. package/dist/mediabunny/FFmpegAudioEncoder.d.ts.map +1 -0
  345. package/dist/mediabunny/FFmpegAudioEncoder.js +484 -0
  346. package/dist/mediabunny/FFmpegAudioEncoder.js.map +1 -0
  347. package/dist/mediabunny/FFmpegVideoDecoder.d.ts +58 -0
  348. package/dist/mediabunny/FFmpegVideoDecoder.d.ts.map +1 -0
  349. package/dist/mediabunny/FFmpegVideoDecoder.js +366 -0
  350. package/dist/mediabunny/FFmpegVideoDecoder.js.map +1 -0
  351. package/dist/mediabunny/FFmpegVideoEncoder.d.ts +77 -0
  352. package/dist/mediabunny/FFmpegVideoEncoder.d.ts.map +1 -0
  353. package/dist/mediabunny/FFmpegVideoEncoder.js +551 -0
  354. package/dist/mediabunny/FFmpegVideoEncoder.js.map +1 -0
  355. package/dist/mediabunny/index.d.ts +21 -0
  356. package/dist/mediabunny/index.d.ts.map +1 -0
  357. package/dist/mediabunny/index.js +33 -0
  358. package/dist/mediabunny/index.js.map +1 -0
  359. package/dist/polyfill.d.ts +27 -0
  360. package/dist/polyfill.d.ts.map +1 -0
  361. package/dist/polyfill.js +78 -0
  362. package/dist/polyfill.js.map +1 -0
  363. package/dist/polyfills/CanvasRenderingContext2DPolyfill.d.ts +72 -0
  364. package/dist/polyfills/CanvasRenderingContext2DPolyfill.d.ts.map +1 -0
  365. package/dist/polyfills/CanvasRenderingContext2DPolyfill.js +293 -0
  366. package/dist/polyfills/CanvasRenderingContext2DPolyfill.js.map +1 -0
  367. package/dist/polyfills/ImageDataPolyfill.d.ts +12 -0
  368. package/dist/polyfills/ImageDataPolyfill.d.ts.map +1 -0
  369. package/dist/polyfills/ImageDataPolyfill.js +22 -0
  370. package/dist/polyfills/ImageDataPolyfill.js.map +1 -0
  371. package/dist/polyfills/OffscreenCanvas.d.ts +15 -0
  372. package/dist/polyfills/OffscreenCanvas.d.ts.map +1 -0
  373. package/dist/polyfills/OffscreenCanvas.js +35 -0
  374. package/dist/polyfills/OffscreenCanvas.js.map +1 -0
  375. package/dist/polyfills/OffscreenCanvasPolyfill.d.ts +16 -0
  376. package/dist/polyfills/OffscreenCanvasPolyfill.d.ts.map +1 -0
  377. package/dist/polyfills/OffscreenCanvasPolyfill.js +46 -0
  378. package/dist/polyfills/OffscreenCanvasPolyfill.js.map +1 -0
  379. package/dist/polyfills/VideoFramePolyfill.d.ts +44 -0
  380. package/dist/polyfills/VideoFramePolyfill.d.ts.map +1 -0
  381. package/dist/polyfills/VideoFramePolyfill.js +98 -0
  382. package/dist/polyfills/VideoFramePolyfill.js.map +1 -0
  383. package/dist/tools/generate-capabilities-profile.d.ts +2 -0
  384. package/dist/tools/generate-capabilities-profile.d.ts.map +1 -0
  385. package/dist/tools/generate-capabilities-profile.js +63 -0
  386. package/dist/tools/generate-capabilities-profile.js.map +1 -0
  387. package/dist/types/audio.d.ts +26 -0
  388. package/dist/types/audio.d.ts.map +1 -0
  389. package/dist/types/audio.js +5 -0
  390. package/dist/types/audio.js.map +1 -0
  391. package/dist/types/common.d.ts +68 -0
  392. package/dist/types/common.d.ts.map +1 -0
  393. package/dist/types/common.js +70 -0
  394. package/dist/types/common.js.map +1 -0
  395. package/dist/types/geometry.d.ts +35 -0
  396. package/dist/types/geometry.d.ts.map +1 -0
  397. package/dist/types/geometry.js +34 -0
  398. package/dist/types/geometry.js.map +1 -0
  399. package/dist/types/index.d.ts +8 -0
  400. package/dist/types/index.d.ts.map +1 -0
  401. package/dist/types/index.js +8 -0
  402. package/dist/types/index.js.map +1 -0
  403. package/dist/types/video.d.ts +43 -0
  404. package/dist/types/video.d.ts.map +1 -0
  405. package/dist/types/video.js +5 -0
  406. package/dist/types/video.js.map +1 -0
  407. package/dist/types.d.ts +6 -0
  408. package/dist/types.d.ts.map +1 -0
  409. package/dist/types.js +6 -0
  410. package/dist/types.js.map +1 -0
  411. package/dist/utils/aac.d.ts +26 -0
  412. package/dist/utils/aac.d.ts.map +1 -0
  413. package/dist/utils/aac.js +129 -0
  414. package/dist/utils/aac.js.map +1 -0
  415. package/dist/utils/avc.d.ts +39 -0
  416. package/dist/utils/avc.d.ts.map +1 -0
  417. package/dist/utils/avc.js +225 -0
  418. package/dist/utils/avc.js.map +1 -0
  419. package/dist/utils/buffer.d.ts +25 -0
  420. package/dist/utils/buffer.d.ts.map +1 -0
  421. package/dist/utils/buffer.js +73 -0
  422. package/dist/utils/buffer.js.map +1 -0
  423. package/dist/utils/hevc.d.ts +27 -0
  424. package/dist/utils/hevc.d.ts.map +1 -0
  425. package/dist/utils/hevc.js +239 -0
  426. package/dist/utils/hevc.js.map +1 -0
  427. package/dist/utils/index.d.ts +11 -0
  428. package/dist/utils/index.d.ts.map +1 -0
  429. package/dist/utils/index.js +16 -0
  430. package/dist/utils/index.js.map +1 -0
  431. package/dist/utils/logger.d.ts +55 -0
  432. package/dist/utils/logger.d.ts.map +1 -0
  433. package/dist/utils/logger.js +110 -0
  434. package/dist/utils/logger.js.map +1 -0
  435. package/dist/utils/type-guards.d.ts +50 -0
  436. package/dist/utils/type-guards.d.ts.map +1 -0
  437. package/dist/utils/type-guards.js +49 -0
  438. package/dist/utils/type-guards.js.map +1 -0
  439. package/dist/utils/validation.d.ts +32 -0
  440. package/dist/utils/validation.d.ts.map +1 -0
  441. package/dist/utils/validation.js +66 -0
  442. package/dist/utils/validation.js.map +1 -0
  443. package/docs/api.md +506 -0
  444. package/docs/codecs.md +382 -0
  445. package/docs/configuration.md +442 -0
  446. package/examples/README.md +100 -0
  447. package/examples/audio-encoding.ts +85 -0
  448. package/examples/hardware-decoding.ts +245 -0
  449. package/examples/hardware-encoding.ts +231 -0
  450. package/examples/image-decoding.ts +145 -0
  451. package/examples/streaming.ts +151 -0
  452. package/examples/transparent-video.ts +162 -0
  453. package/examples/video-decoding.ts +107 -0
  454. package/examples/video-encoding.ts +93 -0
  455. package/package.json +105 -0
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Demo: WebCodecs API usage in Node.js
3
+ *
4
+ * This demo shows how to:
5
+ * 1. Create VideoFrames from raw pixel data
6
+ * 2. Encode frames to H.264
7
+ * 3. Decode encoded chunks back to frames
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=demo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demo.d.ts","sourceRoot":"","sources":["../../src/demos/demo.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Demo: WebCodecs API usage in Node.js
3
+ *
4
+ * This demo shows how to:
5
+ * 1. Create VideoFrames from raw pixel data
6
+ * 2. Encode frames to H.264
7
+ * 3. Decode encoded chunks back to frames
8
+ */
9
+ import { VideoFrame, VideoEncoder, VideoDecoder, } from '../index.js';
10
+ async function main() {
11
+ console.log('WebCodecs Node.js Demo');
12
+ console.log('======================\n');
13
+ // Configuration
14
+ const width = 320;
15
+ const height = 240;
16
+ const frameCount = 30;
17
+ const framerate = 30;
18
+ const codec = 'vp09'; // VP9 - uses IVF container with per-frame parsing
19
+ // Check encoder support
20
+ const encoderSupport = await VideoEncoder.isConfigSupported({
21
+ codec,
22
+ width,
23
+ height,
24
+ bitrate: 1_000_000,
25
+ framerate,
26
+ });
27
+ console.log(`Encoder support for ${codec}: ${encoderSupport.supported}`);
28
+ // Check decoder support
29
+ const decoderSupport = await VideoDecoder.isConfigSupported({
30
+ codec,
31
+ codedWidth: width,
32
+ codedHeight: height,
33
+ });
34
+ console.log(`Decoder support for ${codec}: ${decoderSupport.supported}\n`);
35
+ // Storage for encoded chunks and decoded frames
36
+ const encodedChunks = [];
37
+ const decodedFrames = [];
38
+ // Create encoder
39
+ const encoder = new VideoEncoder({
40
+ output: (chunk, metadata) => {
41
+ console.log(`Encoded chunk: type=${chunk.type}, timestamp=${chunk.timestamp}, bytes=${chunk.byteLength}`);
42
+ if (metadata?.decoderConfig) {
43
+ console.log(` Decoder config: ${JSON.stringify(metadata.decoderConfig)}`);
44
+ }
45
+ encodedChunks.push(chunk);
46
+ },
47
+ error: (err) => {
48
+ console.error('Encoder error:', err);
49
+ },
50
+ });
51
+ // Configure encoder
52
+ encoder.configure({
53
+ codec,
54
+ width,
55
+ height,
56
+ bitrate: 1_000_000,
57
+ framerate,
58
+ });
59
+ console.log('Encoder state:', encoder.state);
60
+ console.log(`\nEncoding ${frameCount} frames...`);
61
+ // Generate and encode frames
62
+ for (let i = 0; i < frameCount; i++) {
63
+ // Create a simple gradient frame (RGBA)
64
+ const frameData = new Uint8Array(width * height * 4);
65
+ for (let y = 0; y < height; y++) {
66
+ for (let x = 0; x < width; x++) {
67
+ const idx = (y * width + x) * 4;
68
+ // Create a moving gradient pattern
69
+ frameData[idx] = (x + i * 10) % 256; // R
70
+ frameData[idx + 1] = (y + i * 5) % 256; // G
71
+ frameData[idx + 2] = (i * 8) % 256; // B
72
+ frameData[idx + 3] = 255; // A
73
+ }
74
+ }
75
+ const frame = new VideoFrame(frameData, {
76
+ format: 'RGBA',
77
+ codedWidth: width,
78
+ codedHeight: height,
79
+ timestamp: (i * 1_000_000) / framerate, // microseconds
80
+ duration: 1_000_000 / framerate,
81
+ });
82
+ encoder.encode(frame, { keyFrame: i % 30 === 0 });
83
+ frame.close();
84
+ }
85
+ // Flush encoder
86
+ console.log('Flushing encoder...');
87
+ await encoder.flush();
88
+ console.log(`Encoded ${encodedChunks.length} chunks\n`);
89
+ // Now decode the chunks
90
+ console.log('Creating decoder...');
91
+ const decoder = new VideoDecoder({
92
+ output: (frame) => {
93
+ console.log(`Decoded frame: ${frame.codedWidth}x${frame.codedHeight}, timestamp=${frame.timestamp}`);
94
+ decodedFrames.push(frame);
95
+ },
96
+ error: (err) => {
97
+ console.error('Decoder error:', err);
98
+ },
99
+ });
100
+ // Configure decoder
101
+ decoder.configure({
102
+ codec,
103
+ codedWidth: width,
104
+ codedHeight: height,
105
+ });
106
+ console.log('Decoder state:', decoder.state);
107
+ console.log(`\nDecoding ${encodedChunks.length} chunks...`);
108
+ // Decode all chunks
109
+ for (const chunk of encodedChunks) {
110
+ decoder.decode(chunk);
111
+ }
112
+ // Flush decoder
113
+ console.log('Flushing decoder...');
114
+ await decoder.flush();
115
+ console.log(`\nDecoded ${decodedFrames.length} frames`);
116
+ // Cleanup
117
+ encoder.close();
118
+ decoder.close();
119
+ decodedFrames.forEach((f) => f.close());
120
+ console.log('\nDemo complete!');
121
+ }
122
+ main().catch(console.error);
123
+ //# sourceMappingURL=demo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demo.js","sourceRoot":"","sources":["../../src/demos/demo.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * AudioEncoder - Encodes AudioData into EncodedAudioChunks
3
+ * https://developer.mozilla.org/en-US/docs/Web/API/AudioEncoder
4
+ */
5
+ import { EventEmitter } from 'events';
6
+ import { AudioData } from '../core/AudioData.js';
7
+ import { EncodedAudioChunk } from '../core/EncodedAudioChunk.js';
8
+ export type CodecState = 'unconfigured' | 'configured' | 'closed';
9
+ export interface AudioEncoderConfig {
10
+ codec: string;
11
+ sampleRate: number;
12
+ numberOfChannels: number;
13
+ bitrate?: number;
14
+ bitrateMode?: 'constant' | 'variable';
15
+ latencyMode?: 'quality' | 'realtime';
16
+ format?: 'adts' | 'aac';
17
+ }
18
+ export interface AudioEncoderInit {
19
+ output: (chunk: EncodedAudioChunk, metadata?: AudioEncoderOutputMetadata) => void;
20
+ error: (error: Error) => void;
21
+ }
22
+ export interface AudioEncoderOutputMetadata {
23
+ decoderConfig?: {
24
+ codec: string;
25
+ sampleRate: number;
26
+ numberOfChannels: number;
27
+ description?: Uint8Array;
28
+ };
29
+ }
30
+ export interface AudioEncoderSupport {
31
+ supported: boolean;
32
+ config: AudioEncoderConfig;
33
+ }
34
+ export declare class AudioEncoder extends EventEmitter {
35
+ private _state;
36
+ private _encodeQueueSize;
37
+ private _config;
38
+ private _outputCallback;
39
+ private _errorCallback;
40
+ private _process;
41
+ private _frameCount;
42
+ private _firstChunk;
43
+ private _accumulatedData;
44
+ private _ffmpegCodec;
45
+ private _bitstreamFormat;
46
+ private _codecDescription;
47
+ constructor(init: AudioEncoderInit);
48
+ get state(): CodecState;
49
+ get encodeQueueSize(): number;
50
+ private get _isProcessHealthy();
51
+ private _safeErrorCallback;
52
+ private _safeOutputCallback;
53
+ static isConfigSupported(config: AudioEncoderConfig): Promise<AudioEncoderSupport>;
54
+ configure(config: AudioEncoderConfig): void;
55
+ encode(data: AudioData): void;
56
+ flush(timeout?: number): Promise<void>;
57
+ reset(): void;
58
+ close(): void;
59
+ private _startFFmpeg;
60
+ private _stopFFmpeg;
61
+ private _audioDataToPCM;
62
+ private _parseEncodedFrames;
63
+ private _findFrameEnd;
64
+ private _findADTSFrame;
65
+ private _findMP3Frame;
66
+ private _findOggPage;
67
+ private _emitChunk;
68
+ }
69
+ //# sourceMappingURL=AudioEncoder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AudioEncoder.d.ts","sourceRoot":"","sources":["../../src/encoders/AudioEncoder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAcjE,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG,YAAY,GAAG,QAAQ,CAAC;AAElE,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IACtC,WAAW,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,QAAQ,CAAC,EAAE,0BAA0B,KAAK,IAAI,CAAC;IAClF,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,0BAA0B;IACzC,aAAa,CAAC,EAAE;QACd,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,gBAAgB,EAAE,MAAM,CAAC;QACzB,WAAW,CAAC,EAAE,UAAU,CAAC;KAC1B,CAAC;CACH;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAID,qBAAa,YAAa,SAAQ,YAAY;IAC5C,OAAO,CAAC,MAAM,CAA8B;IAC5C,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,eAAe,CAA4E;IACnG,OAAO,CAAC,cAAc,CAAyB;IAC/C,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,gBAAgB,CAA2B;IACnD,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,gBAAgB,CAA0B;IAClD,OAAO,CAAC,iBAAiB,CAA2B;gBAExC,IAAI,EAAE,gBAAgB;IAclC,IAAI,KAAK,IAAI,UAAU,CAAwB;IAC/C,IAAI,eAAe,IAAI,MAAM,CAAkC;IAE/D,OAAO,KAAK,iBAAiB,GAE5B;IAED,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,mBAAmB;WAQd,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAWxF,SAAS,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI;IAiD3C,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IA6BvB,KAAK,CAAC,OAAO,GAAE,MAA8B,GAAG,OAAO,CAAC,IAAI,CAAC;IAqDnE,KAAK,IAAI,IAAI;IAeb,KAAK,IAAI,IAAI;IAUb,OAAO,CAAC,YAAY;IA8DpB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,eAAe;IA+BvB,OAAO,CAAC,mBAAmB;IAgB3B,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,cAAc;IAqBtB,OAAO,CAAC,aAAa;IAgCrB,OAAO,CAAC,YAAY;IAyBpB,OAAO,CAAC,UAAU;CA8CnB"}
@@ -0,0 +1,425 @@
1
+ /**
2
+ * AudioEncoder - Encodes AudioData into EncodedAudioChunks
3
+ * https://developer.mozilla.org/en-US/docs/Web/API/AudioEncoder
4
+ */
5
+ import { EventEmitter } from 'events';
6
+ import { spawn } from 'child_process';
7
+ import { AudioData } from '../core/AudioData.js';
8
+ import { EncodedAudioChunk } from '../core/EncodedAudioChunk.js';
9
+ import { DOMException } from '../types/index.js';
10
+ import { createLogger } from '../utils/index.js';
11
+ import { getAudioEncoderCodec, getAudioEncoderFormat, getAudioFrameSize, AUDIO_ENCODER_CODEC_MAP, } from '../ffmpeg/audio-codecs.js';
12
+ import { buildAudioSpecificConfig, stripAdtsHeader } from '../utils/aac.js';
13
+ const logger = createLogger('AudioEncoder');
14
+ const DEFAULT_FLUSH_TIMEOUT = 30000;
15
+ export class AudioEncoder extends EventEmitter {
16
+ _state = 'unconfigured';
17
+ _encodeQueueSize = 0;
18
+ _config = null;
19
+ _outputCallback;
20
+ _errorCallback;
21
+ _process = null;
22
+ _frameCount = 0;
23
+ _firstChunk = true;
24
+ _accumulatedData = Buffer.alloc(0);
25
+ _ffmpegCodec = '';
26
+ _bitstreamFormat = 'adts';
27
+ _codecDescription = null;
28
+ constructor(init) {
29
+ super();
30
+ if (!init || typeof init.output !== 'function') {
31
+ throw new TypeError('output callback is required');
32
+ }
33
+ if (typeof init.error !== 'function') {
34
+ throw new TypeError('error callback is required');
35
+ }
36
+ this._outputCallback = init.output;
37
+ this._errorCallback = init.error;
38
+ }
39
+ get state() { return this._state; }
40
+ get encodeQueueSize() { return this._encodeQueueSize; }
41
+ get _isProcessHealthy() {
42
+ return this._process !== null && this._process.stdin?.writable === true;
43
+ }
44
+ _safeErrorCallback(error) {
45
+ try {
46
+ this._errorCallback(error);
47
+ }
48
+ catch {
49
+ this.emit('callbackError', error);
50
+ }
51
+ }
52
+ _safeOutputCallback(chunk, metadata) {
53
+ try {
54
+ this._outputCallback(chunk, metadata);
55
+ }
56
+ catch (err) {
57
+ this._safeErrorCallback(err instanceof Error ? err : new Error(String(err)));
58
+ }
59
+ }
60
+ static async isConfigSupported(config) {
61
+ if (!config.codec || !config.sampleRate || !config.numberOfChannels) {
62
+ return { supported: false, config };
63
+ }
64
+ const codecBase = config.codec.split('.')[0].toLowerCase();
65
+ const supported = codecBase in AUDIO_ENCODER_CODEC_MAP || config.codec in AUDIO_ENCODER_CODEC_MAP;
66
+ return { supported, config };
67
+ }
68
+ configure(config) {
69
+ if (this._state === 'closed') {
70
+ throw new DOMException('Encoder is closed', 'InvalidStateError');
71
+ }
72
+ if (!config || typeof config !== 'object') {
73
+ throw new TypeError('config must be an object');
74
+ }
75
+ if (typeof config.codec !== 'string' || config.codec.length === 0) {
76
+ throw new TypeError('codec must be a non-empty string');
77
+ }
78
+ if (typeof config.sampleRate !== 'number' || config.sampleRate <= 0 || !Number.isInteger(config.sampleRate)) {
79
+ throw new TypeError('sampleRate must be a positive integer');
80
+ }
81
+ if (typeof config.numberOfChannels !== 'number' || config.numberOfChannels <= 0 || !Number.isInteger(config.numberOfChannels)) {
82
+ throw new TypeError('numberOfChannels must be a positive integer');
83
+ }
84
+ if (config.bitrate !== undefined && (typeof config.bitrate !== 'number' || config.bitrate <= 0)) {
85
+ throw new TypeError('bitrate must be a positive number');
86
+ }
87
+ if (config.bitrateMode !== undefined && !['constant', 'variable'].includes(config.bitrateMode)) {
88
+ throw new TypeError("bitrateMode must be 'constant' or 'variable'");
89
+ }
90
+ if (config.latencyMode !== undefined && !['quality', 'realtime'].includes(config.latencyMode)) {
91
+ throw new TypeError("latencyMode must be 'quality' or 'realtime'");
92
+ }
93
+ const ffmpegCodec = getAudioEncoderCodec(config.codec);
94
+ if (!ffmpegCodec) {
95
+ throw new DOMException(`Codec '${config.codec}' is not supported`, 'NotSupportedError');
96
+ }
97
+ if (this._process) {
98
+ this._process.kill();
99
+ this._process = null;
100
+ }
101
+ this._config = { ...config };
102
+ this._state = 'configured';
103
+ this._frameCount = 0;
104
+ this._firstChunk = true;
105
+ this._accumulatedData = Buffer.alloc(0);
106
+ this._bitstreamFormat = config.format ?? 'adts';
107
+ this._codecDescription = null;
108
+ this._startFFmpeg();
109
+ }
110
+ encode(data) {
111
+ if (this._state !== 'configured') {
112
+ throw new DOMException('Encoder is not configured', 'InvalidStateError');
113
+ }
114
+ if (!(data instanceof AudioData)) {
115
+ throw new TypeError('data must be an AudioData');
116
+ }
117
+ if (!this._isProcessHealthy) {
118
+ this._safeErrorCallback(new Error('Encoder process is not healthy'));
119
+ return;
120
+ }
121
+ this._encodeQueueSize++;
122
+ const pcmData = this._audioDataToPCM(data);
123
+ try {
124
+ this._process.stdin.write(pcmData);
125
+ }
126
+ catch {
127
+ this._encodeQueueSize = Math.max(0, this._encodeQueueSize - 1);
128
+ this._safeErrorCallback(new Error('Failed to write audio data to encoder'));
129
+ return;
130
+ }
131
+ this._frameCount += data.numberOfFrames;
132
+ }
133
+ async flush(timeout = DEFAULT_FLUSH_TIMEOUT) {
134
+ if (this._state !== 'configured') {
135
+ throw new DOMException('Encoder is not configured', 'InvalidStateError');
136
+ }
137
+ return new Promise((resolve, reject) => {
138
+ if (!this._process) {
139
+ resolve();
140
+ return;
141
+ }
142
+ let timeoutId = null;
143
+ let resolved = false;
144
+ const cleanup = () => {
145
+ if (timeoutId) {
146
+ clearTimeout(timeoutId);
147
+ timeoutId = null;
148
+ }
149
+ };
150
+ const doResolve = () => {
151
+ if (resolved)
152
+ return;
153
+ resolved = true;
154
+ cleanup();
155
+ this._encodeQueueSize = 0;
156
+ this._frameCount = 0;
157
+ this._firstChunk = true;
158
+ this._accumulatedData = Buffer.alloc(0);
159
+ this._process = null;
160
+ if (this._config) {
161
+ this._startFFmpeg();
162
+ }
163
+ resolve();
164
+ };
165
+ const doReject = (err) => {
166
+ if (resolved)
167
+ return;
168
+ resolved = true;
169
+ cleanup();
170
+ reject(err);
171
+ };
172
+ timeoutId = setTimeout(() => {
173
+ doReject(new DOMException('Flush operation timed out', 'TimeoutError'));
174
+ }, timeout);
175
+ this._process.once('close', doResolve);
176
+ this._process.once('error', doReject);
177
+ this._process.stdin?.end();
178
+ });
179
+ }
180
+ reset() {
181
+ if (this._state === 'closed') {
182
+ throw new DOMException('Encoder is closed', 'InvalidStateError');
183
+ }
184
+ this._stopFFmpeg();
185
+ this._state = 'unconfigured';
186
+ this._config = null;
187
+ this._encodeQueueSize = 0;
188
+ this._frameCount = 0;
189
+ this._firstChunk = true;
190
+ this._accumulatedData = Buffer.alloc(0);
191
+ this._codecDescription = null;
192
+ }
193
+ close() {
194
+ if (this._state === 'closed')
195
+ return;
196
+ this._stopFFmpeg();
197
+ this._state = 'closed';
198
+ this._config = null;
199
+ this._encodeQueueSize = 0;
200
+ this._codecDescription = null;
201
+ }
202
+ _startFFmpeg() {
203
+ if (!this._config)
204
+ return;
205
+ // Codec was already validated in configure(), so we can safely use a fallback here
206
+ this._ffmpegCodec = getAudioEncoderCodec(this._config.codec) || 'aac';
207
+ const format = getAudioEncoderFormat(this._ffmpegCodec);
208
+ const args = [
209
+ '-hide_banner', '-loglevel', 'error',
210
+ '-f', 'f32le',
211
+ '-ar', String(this._config.sampleRate),
212
+ '-ac', String(this._config.numberOfChannels),
213
+ '-i', 'pipe:0',
214
+ '-c:a', this._ffmpegCodec,
215
+ ];
216
+ if (this._config.bitrate) {
217
+ args.push('-b:a', String(this._config.bitrate));
218
+ }
219
+ const isRealtime = this._config.latencyMode === 'realtime';
220
+ if (this._ffmpegCodec === 'libopus') {
221
+ args.push('-application', isRealtime ? 'voip' : 'audio');
222
+ if (isRealtime) {
223
+ args.push('-frame_duration', '10');
224
+ }
225
+ if (this._config.sampleRate !== 48000) {
226
+ args.push('-ar', '48000');
227
+ }
228
+ }
229
+ else if (this._ffmpegCodec === 'aac') {
230
+ if (isRealtime) {
231
+ args.push('-profile:a', 'aac_low');
232
+ }
233
+ }
234
+ args.push('-f', format, 'pipe:1');
235
+ this._process = spawn('ffmpeg', args, { stdio: ['pipe', 'pipe', 'pipe'] });
236
+ this._process.stdout?.on('data', (data) => {
237
+ this._accumulatedData = Buffer.concat([this._accumulatedData, data]);
238
+ this._parseEncodedFrames();
239
+ });
240
+ this._process.stderr?.on('data', (data) => {
241
+ const msg = data.toString();
242
+ if (!msg.includes('Discarding ID3')) {
243
+ logger.warn('FFmpeg stderr', { message: msg });
244
+ }
245
+ });
246
+ this._process.on('close', () => {
247
+ if (this._accumulatedData.length > 0) {
248
+ this._emitChunk(this._accumulatedData, 'key');
249
+ this._accumulatedData = Buffer.alloc(0);
250
+ }
251
+ });
252
+ this._process.stdin?.on('error', () => { });
253
+ }
254
+ _stopFFmpeg() {
255
+ if (this._process) {
256
+ this._process.kill('SIGTERM');
257
+ this._process = null;
258
+ }
259
+ }
260
+ _audioDataToPCM(data) {
261
+ const numFrames = data.numberOfFrames;
262
+ const numChannels = data.numberOfChannels;
263
+ const bufferSize = numFrames * numChannels * 4;
264
+ const buffer = Buffer.alloc(bufferSize);
265
+ const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
266
+ const isPlanar = data.format.endsWith('-planar');
267
+ const tempBuffer = new Float32Array(numFrames);
268
+ if (isPlanar) {
269
+ for (let ch = 0; ch < numChannels; ch++) {
270
+ data.copyTo(new Uint8Array(tempBuffer.buffer), {
271
+ planeIndex: ch,
272
+ format: 'f32-planar',
273
+ });
274
+ for (let frame = 0; frame < numFrames; frame++) {
275
+ const offset = (frame * numChannels + ch) * 4;
276
+ view.setFloat32(offset, tempBuffer[frame], true);
277
+ }
278
+ }
279
+ }
280
+ else {
281
+ const srcBuffer = new Uint8Array(bufferSize);
282
+ data.copyTo(srcBuffer, { planeIndex: 0, format: 'f32' });
283
+ buffer.set(srcBuffer);
284
+ }
285
+ return buffer;
286
+ }
287
+ _parseEncodedFrames() {
288
+ const minChunkSize = 64;
289
+ while (this._accumulatedData.length >= minChunkSize) {
290
+ let frameEnd = this._findFrameEnd();
291
+ if (frameEnd > 0) {
292
+ const frameData = Buffer.from(this._accumulatedData.subarray(0, frameEnd));
293
+ this._accumulatedData = this._accumulatedData.subarray(frameEnd);
294
+ this._emitChunk(frameData, 'key');
295
+ }
296
+ else {
297
+ break;
298
+ }
299
+ }
300
+ }
301
+ _findFrameEnd() {
302
+ if (this._ffmpegCodec === 'aac') {
303
+ return this._findADTSFrame();
304
+ }
305
+ else if (this._ffmpegCodec === 'libmp3lame') {
306
+ return this._findMP3Frame();
307
+ }
308
+ else if (this._ffmpegCodec === 'libopus' || this._ffmpegCodec === 'libvorbis') {
309
+ return this._findOggPage();
310
+ }
311
+ else {
312
+ return Math.min(this._accumulatedData.length, 4096);
313
+ }
314
+ }
315
+ _findADTSFrame() {
316
+ if (this._accumulatedData.length < 7)
317
+ return 0;
318
+ if ((this._accumulatedData[0] !== 0xFF) || ((this._accumulatedData[1] & 0xF0) !== 0xF0)) {
319
+ for (let i = 1; i < this._accumulatedData.length - 1; i++) {
320
+ if (this._accumulatedData[i] === 0xFF && (this._accumulatedData[i + 1] & 0xF0) === 0xF0) {
321
+ this._accumulatedData = this._accumulatedData.subarray(i);
322
+ return 0;
323
+ }
324
+ }
325
+ return 0;
326
+ }
327
+ const frameLength = ((this._accumulatedData[3] & 0x03) << 11) |
328
+ (this._accumulatedData[4] << 3) |
329
+ ((this._accumulatedData[5] & 0xE0) >> 5);
330
+ if (frameLength > this._accumulatedData.length)
331
+ return 0;
332
+ return frameLength;
333
+ }
334
+ _findMP3Frame() {
335
+ if (this._accumulatedData.length < 4)
336
+ return 0;
337
+ if (this._accumulatedData[0] !== 0xFF || (this._accumulatedData[1] & 0xE0) !== 0xE0) {
338
+ for (let i = 1; i < this._accumulatedData.length - 1; i++) {
339
+ if (this._accumulatedData[i] === 0xFF && (this._accumulatedData[i + 1] & 0xE0) === 0xE0) {
340
+ this._accumulatedData = this._accumulatedData.subarray(i);
341
+ return 0;
342
+ }
343
+ }
344
+ return 0;
345
+ }
346
+ const header = this._accumulatedData.readUInt32BE(0);
347
+ const bitrateIndex = (header >> 12) & 0x0F;
348
+ const samplingRateIndex = (header >> 10) & 0x03;
349
+ const padding = (header >> 9) & 0x01;
350
+ const bitrates = [0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0];
351
+ const sampleRates = [44100, 48000, 32000, 0];
352
+ const bitrate = bitrates[bitrateIndex] * 1000;
353
+ const sampleRate = sampleRates[samplingRateIndex];
354
+ if (bitrate === 0 || sampleRate === 0)
355
+ return 0;
356
+ const frameSize = Math.floor((144 * bitrate) / sampleRate) + padding;
357
+ if (frameSize > this._accumulatedData.length)
358
+ return 0;
359
+ return frameSize;
360
+ }
361
+ _findOggPage() {
362
+ if (this._accumulatedData.length < 27)
363
+ return 0;
364
+ if (this._accumulatedData.toString('ascii', 0, 4) !== 'OggS') {
365
+ for (let i = 1; i < this._accumulatedData.length - 3; i++) {
366
+ if (this._accumulatedData.toString('ascii', i, i + 4) === 'OggS') {
367
+ this._accumulatedData = this._accumulatedData.subarray(i);
368
+ return 0;
369
+ }
370
+ }
371
+ return this._accumulatedData.length;
372
+ }
373
+ const numSegments = this._accumulatedData[26];
374
+ if (this._accumulatedData.length < 27 + numSegments)
375
+ return 0;
376
+ let pageSize = 27 + numSegments;
377
+ for (let i = 0; i < numSegments; i++) {
378
+ pageSize += this._accumulatedData[27 + i];
379
+ }
380
+ if (pageSize > this._accumulatedData.length)
381
+ return 0;
382
+ return pageSize;
383
+ }
384
+ _emitChunk(data, type) {
385
+ if (!this._config || data.length === 0)
386
+ return;
387
+ const samplesPerFrame = getAudioFrameSize(this._ffmpegCodec) || 1024;
388
+ const timestamp = (this._frameCount * 1_000_000) / this._config.sampleRate;
389
+ const duration = (samplesPerFrame * 1_000_000) / this._config.sampleRate;
390
+ let payload = data;
391
+ const codecBase = this._config.codec.split('.')[0].toLowerCase();
392
+ const isAac = codecBase === 'mp4a' || codecBase === 'aac';
393
+ if (this._bitstreamFormat === 'aac' && isAac) {
394
+ const stripped = stripAdtsHeader(new Uint8Array(data));
395
+ payload = Buffer.from(stripped);
396
+ if (!this._codecDescription) {
397
+ this._codecDescription = buildAudioSpecificConfig({
398
+ samplingRate: this._config.sampleRate,
399
+ channelConfiguration: this._config.numberOfChannels,
400
+ });
401
+ }
402
+ }
403
+ const chunk = new EncodedAudioChunk({
404
+ type,
405
+ timestamp,
406
+ duration,
407
+ data: new Uint8Array(payload),
408
+ });
409
+ this._encodeQueueSize = Math.max(0, this._encodeQueueSize - 1);
410
+ this.emit('dequeue');
411
+ const metadata = this._firstChunk
412
+ ? {
413
+ decoderConfig: {
414
+ codec: this._config.codec,
415
+ sampleRate: this._config.sampleRate,
416
+ numberOfChannels: this._config.numberOfChannels,
417
+ description: this._codecDescription ?? undefined,
418
+ },
419
+ }
420
+ : undefined;
421
+ this._firstChunk = false;
422
+ this._safeOutputCallback(chunk, metadata);
423
+ }
424
+ }
425
+ //# sourceMappingURL=AudioEncoder.js.map