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,686 @@
1
+ /**
2
+ * ImageDecoder - Decodes encoded image data to VideoFrames
3
+ * https://developer.mozilla.org/en-US/docs/Web/API/ImageDecoder
4
+ */
5
+ import { spawn } from 'child_process';
6
+ import { VideoFrame } from '../core/VideoFrame.js';
7
+ import { DOMException } from '../types/index.js';
8
+ import { createLogger } from '../utils/index.js';
9
+ import { parseWebPHeader } from '../formats/index.js';
10
+ const logger = createLogger('ImageDecoder');
11
+ /**
12
+ * ImageTrack - Represents an individual image track
13
+ */
14
+ export class ImageTrack {
15
+ _animated;
16
+ _frameCount;
17
+ _repetitionCount;
18
+ _selected;
19
+ constructor(options) {
20
+ this._animated = options.animated;
21
+ this._frameCount = options.frameCount;
22
+ this._repetitionCount = options.repetitionCount;
23
+ this._selected = options.selected;
24
+ }
25
+ get animated() { return this._animated; }
26
+ get frameCount() { return this._frameCount; }
27
+ get repetitionCount() { return this._repetitionCount; }
28
+ get selected() { return this._selected; }
29
+ }
30
+ /**
31
+ * ImageTrackList - A list of image tracks
32
+ */
33
+ export class ImageTrackList {
34
+ _tracks = [];
35
+ _selectedIndex = -1;
36
+ _ready;
37
+ _resolveReady;
38
+ constructor() {
39
+ this._ready = new Promise((resolve) => {
40
+ this._resolveReady = resolve;
41
+ });
42
+ }
43
+ get ready() { return this._ready; }
44
+ get length() { return this._tracks.length; }
45
+ get selectedIndex() { return this._selectedIndex; }
46
+ get selectedTrack() {
47
+ if (this._selectedIndex >= 0 && this._selectedIndex < this._tracks.length) {
48
+ return this._tracks[this._selectedIndex];
49
+ }
50
+ return null;
51
+ }
52
+ /** @internal */
53
+ _addTrack(track) {
54
+ const index = this._tracks.length;
55
+ this._tracks.push(track);
56
+ if (track.selected && this._selectedIndex === -1) {
57
+ this._selectedIndex = index;
58
+ }
59
+ }
60
+ /** @internal */
61
+ _markReady() {
62
+ this._resolveReady();
63
+ }
64
+ [Symbol.iterator]() {
65
+ return this._tracks[Symbol.iterator]();
66
+ }
67
+ }
68
+ // MIME type to FFmpeg format mapping
69
+ const MIME_TO_CODEC = {
70
+ 'image/png': { format: 'png_pipe' },
71
+ 'image/apng': { format: 'apng' },
72
+ 'image/jpeg': { format: 'jpeg_pipe' },
73
+ 'image/jpg': { format: 'jpeg_pipe' },
74
+ 'image/webp': { format: 'webp_pipe', autoDetect: true },
75
+ 'image/gif': { format: 'gif' },
76
+ 'image/bmp': { format: 'bmp_pipe' },
77
+ 'image/avif': { format: 'avif', autoDetect: true },
78
+ 'image/tiff': { format: 'tiff_pipe' },
79
+ };
80
+ const SUPPORTED_TYPES = new Set(Object.keys(MIME_TO_CODEC));
81
+ function isReadableStream(obj) {
82
+ return typeof obj === 'object' && obj !== null && typeof obj.getReader === 'function';
83
+ }
84
+ export class ImageDecoder {
85
+ _type;
86
+ _data = null;
87
+ _complete = false;
88
+ _completed;
89
+ _resolveCompleted;
90
+ _rejectCompleted;
91
+ _tracks;
92
+ _closed = false;
93
+ _colorSpaceConversion;
94
+ _premultiplyAlpha;
95
+ _desiredWidth;
96
+ _desiredHeight;
97
+ _preferAnimation;
98
+ _visibleFrameCount = 0;
99
+ _visibleAnimated = false;
100
+ _visibleRepetitionCount = 1;
101
+ _preferredColorSpace;
102
+ _orientation = 1;
103
+ _orientationEvaluated = false;
104
+ _frames = [];
105
+ _framesParsed = false;
106
+ _repetitionCount = 0;
107
+ _frameDurations = [];
108
+ constructor(init) {
109
+ if (!init || typeof init !== 'object') {
110
+ throw new TypeError('init must be an object');
111
+ }
112
+ if (!init.type || typeof init.type !== 'string') {
113
+ throw new TypeError('type is required and must be a string');
114
+ }
115
+ if (!init.data) {
116
+ throw new TypeError('data is required');
117
+ }
118
+ this._type = init.type;
119
+ this._colorSpaceConversion = init.colorSpaceConversion ?? 'default';
120
+ this._premultiplyAlpha = init.premultiplyAlpha ?? 'default';
121
+ this._desiredWidth = init.desiredWidth;
122
+ this._desiredHeight = init.desiredHeight;
123
+ this._preferAnimation = init.preferAnimation ?? false;
124
+ this._preferredColorSpace = this._colorSpaceConversion === 'default'
125
+ ? { primaries: 'bt709', transfer: 'iec61966-2-1', matrix: 'rgb', fullRange: true }
126
+ : undefined;
127
+ this._tracks = new ImageTrackList();
128
+ this._completed = new Promise((resolve, reject) => {
129
+ this._resolveCompleted = resolve;
130
+ this._rejectCompleted = reject;
131
+ });
132
+ const transferSet = new Set(init.transfer || []);
133
+ if (init.data instanceof ArrayBuffer) {
134
+ if (transferSet.has(init.data)) {
135
+ this._data = new Uint8Array(init.data);
136
+ }
137
+ else {
138
+ this._data = new Uint8Array(init.data.slice(0));
139
+ }
140
+ this._complete = true;
141
+ this._initializeTracks();
142
+ }
143
+ else if (ArrayBuffer.isView(init.data)) {
144
+ const view = init.data;
145
+ if (view.buffer instanceof ArrayBuffer && transferSet.has(view.buffer)) {
146
+ this._data = new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
147
+ }
148
+ else {
149
+ this._data = new Uint8Array(view.byteLength);
150
+ this._data.set(new Uint8Array(view.buffer, view.byteOffset, view.byteLength));
151
+ }
152
+ this._complete = true;
153
+ this._initializeTracks();
154
+ }
155
+ else if (isReadableStream(init.data)) {
156
+ this._readStream(init.data);
157
+ }
158
+ else {
159
+ throw new TypeError('data must be ArrayBuffer, ArrayBufferView, or ReadableStream');
160
+ }
161
+ }
162
+ async _readStream(stream) {
163
+ const reader = stream.getReader();
164
+ const chunks = [];
165
+ try {
166
+ while (true) {
167
+ const { done, value } = await reader.read();
168
+ if (done)
169
+ break;
170
+ if (value) {
171
+ chunks.push(new Uint8Array(value.buffer, value.byteOffset, value.byteLength));
172
+ }
173
+ }
174
+ const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
175
+ this._data = new Uint8Array(totalLength);
176
+ let offset = 0;
177
+ for (const chunk of chunks) {
178
+ this._data.set(chunk, offset);
179
+ offset += chunk.length;
180
+ }
181
+ this._complete = true;
182
+ this._initializeTracks();
183
+ }
184
+ catch (error) {
185
+ this._rejectCompleted(error);
186
+ }
187
+ }
188
+ async _initializeTracks() {
189
+ try {
190
+ this._evaluateOrientation();
191
+ await this._parseImage();
192
+ this._tracks._markReady();
193
+ this._resolveCompleted();
194
+ }
195
+ catch (error) {
196
+ this._rejectCompleted(error);
197
+ }
198
+ }
199
+ async _parseImage() {
200
+ if (!this._data || this._framesParsed)
201
+ return;
202
+ const codecInfo = MIME_TO_CODEC[this._type.toLowerCase()];
203
+ if (!codecInfo) {
204
+ throw new DOMException(`Unsupported image type: ${this._type}`, 'NotSupportedError');
205
+ }
206
+ await this._probeAnimationMetadata();
207
+ await this._decodeAllFramesDirect();
208
+ this._framesParsed = true;
209
+ this._updateVisibleTrackInfo();
210
+ const track = new ImageTrack({
211
+ animated: this._visibleAnimated,
212
+ frameCount: this._visibleFrameCount,
213
+ repetitionCount: this._visibleRepetitionCount,
214
+ selected: true,
215
+ });
216
+ this._tracks._addTrack(track);
217
+ }
218
+ async _probeAnimationMetadata() {
219
+ if (!this._data)
220
+ return;
221
+ const codecInfo = MIME_TO_CODEC[this._type.toLowerCase()];
222
+ const isAnimatedFormat = ['image/gif', 'image/apng', 'image/webp'].includes(this._type.toLowerCase());
223
+ if (!isAnimatedFormat)
224
+ return;
225
+ return new Promise((resolve) => {
226
+ const args = [
227
+ '-hide_banner', '-v', 'error',
228
+ '-select_streams', 'v:0',
229
+ '-show_entries', 'frame=pkt_duration_time,pkt_pts_time',
230
+ '-show_entries', 'format_tags=loop',
231
+ '-show_entries', 'stream_tags=loop',
232
+ '-of', 'json',
233
+ ];
234
+ if (!codecInfo.autoDetect) {
235
+ args.push('-f', codecInfo.format);
236
+ }
237
+ args.push('pipe:0');
238
+ const process = spawn('ffprobe', args, { stdio: ['pipe', 'pipe', 'pipe'] });
239
+ let stdout = '';
240
+ process.stdout?.on('data', (data) => { stdout += data.toString(); });
241
+ process.stderr?.on('data', () => { });
242
+ process.on('close', () => {
243
+ try {
244
+ const info = JSON.parse(stdout);
245
+ const loopValue = info.format?.tags?.loop ?? info.streams?.[0]?.tags?.loop;
246
+ if (loopValue !== undefined) {
247
+ const loopNum = parseInt(loopValue, 10);
248
+ this._repetitionCount = loopNum === 0 ? Infinity : loopNum;
249
+ }
250
+ else {
251
+ this._repetitionCount = this._type.toLowerCase() === 'image/gif' ? Infinity : 1;
252
+ }
253
+ if (info.frames && Array.isArray(info.frames)) {
254
+ for (const frame of info.frames) {
255
+ const durationSec = parseFloat(frame.pkt_duration_time || '0.1');
256
+ this._frameDurations.push(Math.round(durationSec * 1_000_000));
257
+ }
258
+ }
259
+ }
260
+ catch {
261
+ this._repetitionCount = this._type.toLowerCase() === 'image/gif' ? Infinity : 1;
262
+ }
263
+ resolve();
264
+ });
265
+ process.stdin?.on('error', () => { });
266
+ process.stdin?.write(Buffer.from(this._data.buffer, this._data.byteOffset, this._data.byteLength));
267
+ process.stdin?.end();
268
+ });
269
+ }
270
+ _frameTypeSupportsAlpha() {
271
+ const type = this._type.toLowerCase();
272
+ return ['image/png', 'image/apng', 'image/webp', 'image/gif', 'image/avif'].includes(type);
273
+ }
274
+ _evaluateOrientation() {
275
+ if (this._orientationEvaluated) {
276
+ return;
277
+ }
278
+ this._orientationEvaluated = true;
279
+ if (!this._data) {
280
+ return;
281
+ }
282
+ const type = this._type.toLowerCase();
283
+ if (type !== 'image/jpeg' && type !== 'image/jpg') {
284
+ return;
285
+ }
286
+ const orientation = this._parseExifOrientation(this._data);
287
+ if (orientation && orientation >= 1 && orientation <= 8) {
288
+ this._orientation = orientation;
289
+ }
290
+ }
291
+ _shouldPremultiplyAlpha() {
292
+ if (this._premultiplyAlpha === 'premultiply') {
293
+ return true;
294
+ }
295
+ if (this._premultiplyAlpha === 'none') {
296
+ return false;
297
+ }
298
+ return this._frameTypeSupportsAlpha();
299
+ }
300
+ _processFrameData(data) {
301
+ if (!this._shouldPremultiplyAlpha()) {
302
+ return data;
303
+ }
304
+ for (let i = 0; i < data.length; i += 4) {
305
+ const alpha = data[i + 3];
306
+ if (alpha === 0) {
307
+ data[i] = 0;
308
+ data[i + 1] = 0;
309
+ data[i + 2] = 0;
310
+ continue;
311
+ }
312
+ const factor = alpha / 255;
313
+ data[i] = Math.round(data[i] * factor);
314
+ data[i + 1] = Math.round(data[i + 1] * factor);
315
+ data[i + 2] = Math.round(data[i + 2] * factor);
316
+ }
317
+ return data;
318
+ }
319
+ _updateVisibleTrackInfo() {
320
+ const totalFrames = this._frames.length;
321
+ this._visibleFrameCount = totalFrames;
322
+ this._visibleAnimated = totalFrames > 1;
323
+ this._visibleRepetitionCount = this._repetitionCount || 1;
324
+ }
325
+ _parseExifOrientation(data) {
326
+ if (data.length < 4 || data[0] !== 0xFF || data[1] !== 0xD8) {
327
+ return null;
328
+ }
329
+ const readUint16 = (buffer, offset, littleEndian) => {
330
+ if (littleEndian) {
331
+ return buffer[offset] | (buffer[offset + 1] << 8);
332
+ }
333
+ return (buffer[offset] << 8) | buffer[offset + 1];
334
+ };
335
+ const readUint32 = (buffer, offset, littleEndian) => {
336
+ if (littleEndian) {
337
+ return (buffer[offset] |
338
+ (buffer[offset + 1] << 8) |
339
+ (buffer[offset + 2] << 16) |
340
+ (buffer[offset + 3] << 24));
341
+ }
342
+ return ((buffer[offset] << 24) |
343
+ (buffer[offset + 1] << 16) |
344
+ (buffer[offset + 2] << 8) |
345
+ buffer[offset + 3]);
346
+ };
347
+ let offset = 2;
348
+ while (offset + 4 < data.length) {
349
+ if (data[offset] !== 0xFF) {
350
+ break;
351
+ }
352
+ const marker = data[offset + 1];
353
+ offset += 2;
354
+ if (marker === 0xD9 || marker === 0xDA) {
355
+ break;
356
+ }
357
+ if (offset + 2 > data.length) {
358
+ break;
359
+ }
360
+ const segmentLength = (data[offset] << 8) | data[offset + 1];
361
+ if (segmentLength < 2) {
362
+ break;
363
+ }
364
+ const segmentStart = offset + 2;
365
+ const segmentEnd = segmentStart + segmentLength - 2;
366
+ if (segmentEnd > data.length) {
367
+ break;
368
+ }
369
+ if (marker === 0xE1 && segmentLength >= 8) {
370
+ const hasExifHeader = data[segmentStart] === 0x45 && // E
371
+ data[segmentStart + 1] === 0x78 && // x
372
+ data[segmentStart + 2] === 0x69 && // i
373
+ data[segmentStart + 3] === 0x66 && // f
374
+ data[segmentStart + 4] === 0x00 &&
375
+ data[segmentStart + 5] === 0x00;
376
+ if (hasExifHeader) {
377
+ const tiffStart = segmentStart + 6;
378
+ if (tiffStart + 8 > data.length) {
379
+ return null;
380
+ }
381
+ const byteOrder = String.fromCharCode(data[tiffStart], data[tiffStart + 1]);
382
+ const littleEndian = byteOrder === 'II';
383
+ const bigEndian = byteOrder === 'MM';
384
+ if (!littleEndian && !bigEndian) {
385
+ return null;
386
+ }
387
+ const isLittleEndian = littleEndian;
388
+ const firstIFDOffset = readUint32(data, tiffStart + 4, isLittleEndian);
389
+ let ifdOffset = tiffStart + firstIFDOffset;
390
+ if (ifdOffset < tiffStart || ifdOffset + 2 > data.length) {
391
+ return null;
392
+ }
393
+ let entryCount = readUint16(data, ifdOffset, isLittleEndian);
394
+ const entrySize = 12;
395
+ const maxEntries = Math.floor((data.length - (ifdOffset + 2)) / entrySize);
396
+ if (entryCount > maxEntries) {
397
+ entryCount = maxEntries;
398
+ }
399
+ for (let i = 0; i < entryCount; i++) {
400
+ const entryOffset = ifdOffset + 2 + i * entrySize;
401
+ if (entryOffset + entrySize > data.length) {
402
+ break;
403
+ }
404
+ const tag = readUint16(data, entryOffset, isLittleEndian);
405
+ if (tag !== 0x0112) {
406
+ continue;
407
+ }
408
+ const type = readUint16(data, entryOffset + 2, isLittleEndian);
409
+ const count = readUint32(data, entryOffset + 4, isLittleEndian);
410
+ if (type !== 3 || count < 1) {
411
+ return null;
412
+ }
413
+ const valueOffset = entryOffset + 8;
414
+ if (valueOffset + 2 > data.length) {
415
+ return null;
416
+ }
417
+ const orientation = readUint16(data, valueOffset, isLittleEndian);
418
+ return orientation;
419
+ }
420
+ }
421
+ }
422
+ offset = segmentEnd;
423
+ }
424
+ return null;
425
+ }
426
+ _applyOrientation(data, width, height) {
427
+ const orientation = this._orientation;
428
+ if (orientation === 1 || orientation < 1 || orientation > 8) {
429
+ return { data, width, height };
430
+ }
431
+ const shouldSwapDimensions = orientation >= 5 && orientation <= 8;
432
+ const newWidth = shouldSwapDimensions ? height : width;
433
+ const newHeight = shouldSwapDimensions ? width : height;
434
+ const transformed = new Uint8Array(newWidth * newHeight * 4);
435
+ const copyPixel = (destX, destY, srcIndex) => {
436
+ const destIndex = (destY * newWidth + destX) * 4;
437
+ transformed[destIndex] = data[srcIndex];
438
+ transformed[destIndex + 1] = data[srcIndex + 1];
439
+ transformed[destIndex + 2] = data[srcIndex + 2];
440
+ transformed[destIndex + 3] = data[srcIndex + 3];
441
+ };
442
+ for (let y = 0; y < height; y++) {
443
+ for (let x = 0; x < width; x++) {
444
+ const srcIndex = (y * width + x) * 4;
445
+ let destX = x;
446
+ let destY = y;
447
+ switch (orientation) {
448
+ case 2:
449
+ destX = width - 1 - x;
450
+ destY = y;
451
+ break;
452
+ case 3:
453
+ destX = width - 1 - x;
454
+ destY = height - 1 - y;
455
+ break;
456
+ case 4:
457
+ destX = x;
458
+ destY = height - 1 - y;
459
+ break;
460
+ case 5:
461
+ destX = y;
462
+ destY = x;
463
+ break;
464
+ case 6:
465
+ destX = height - 1 - y;
466
+ destY = x;
467
+ break;
468
+ case 7:
469
+ destX = height - 1 - y;
470
+ destY = width - 1 - x;
471
+ break;
472
+ case 8:
473
+ destX = y;
474
+ destY = width - 1 - x;
475
+ break;
476
+ default:
477
+ destX = x;
478
+ destY = y;
479
+ break;
480
+ }
481
+ copyPixel(destX, destY, srcIndex);
482
+ }
483
+ }
484
+ return { data: transformed, width: newWidth, height: newHeight };
485
+ }
486
+ async _decodeAllFramesDirect() {
487
+ if (!this._data)
488
+ return;
489
+ const codecInfo = MIME_TO_CODEC[this._type.toLowerCase()];
490
+ const dimensions = await this._probeDimensions();
491
+ if (dimensions.width === 0 || dimensions.height === 0) {
492
+ throw new Error(`Could not determine image dimensions for ${this._type}`);
493
+ }
494
+ const args = ['-hide_banner', '-loglevel', 'error', '-noautorotate'];
495
+ if (!codecInfo.autoDetect) {
496
+ args.push('-f', codecInfo.format);
497
+ }
498
+ args.push('-i', 'pipe:0');
499
+ if (this._desiredWidth || this._desiredHeight) {
500
+ args.push('-vf', `scale=${this._desiredWidth || -1}:${this._desiredHeight || -1}`);
501
+ }
502
+ args.push('-f', 'rawvideo', '-pix_fmt', 'rgba', 'pipe:1');
503
+ const width = this._desiredWidth || dimensions.width;
504
+ const height = this._desiredHeight || dimensions.height;
505
+ const frameSize = width * height * 4;
506
+ if (frameSize === 0) {
507
+ throw new Error('Failed to determine frame size');
508
+ }
509
+ const defaultDuration = 100000;
510
+ const hasFrameDurations = this._frameDurations.length > 0;
511
+ return new Promise((resolve, reject) => {
512
+ const process = spawn('ffmpeg', args, { stdio: ['pipe', 'pipe', 'pipe'] });
513
+ let buffer = Buffer.alloc(0);
514
+ let timestamp = 0;
515
+ let frameIndex = 0;
516
+ const emitFrameFromBuffer = (frameBuffer) => {
517
+ const treatAsAnimated = hasFrameDurations || frameIndex > 0;
518
+ const duration = treatAsAnimated
519
+ ? (this._frameDurations[frameIndex] ?? defaultDuration)
520
+ : 0;
521
+ const frameTimestamp = timestamp;
522
+ timestamp += duration;
523
+ const frameBytes = new Uint8Array(frameBuffer);
524
+ const processed = this._processFrameData(frameBytes);
525
+ const oriented = this._applyOrientation(processed, width, height);
526
+ this._frames.push({
527
+ data: oriented.data,
528
+ width: oriented.width,
529
+ height: oriented.height,
530
+ timestamp: frameTimestamp,
531
+ duration,
532
+ complete: true,
533
+ colorSpace: this._preferredColorSpace,
534
+ });
535
+ frameIndex++;
536
+ };
537
+ process.stdout?.on('data', (data) => {
538
+ if (!data || data.length === 0) {
539
+ return;
540
+ }
541
+ buffer = buffer.length === 0 ? Buffer.from(data) : Buffer.concat([buffer, data]);
542
+ while (buffer.length >= frameSize) {
543
+ const frameChunk = buffer.subarray(0, frameSize);
544
+ emitFrameFromBuffer(frameChunk);
545
+ buffer = buffer.subarray(frameSize);
546
+ }
547
+ });
548
+ process.stderr?.on('data', (data) => {
549
+ const msg = data.toString();
550
+ if (msg.toLowerCase().includes('error') && !msg.includes('Invalid data')) {
551
+ logger.warn('FFmpeg stderr', { message: msg });
552
+ }
553
+ });
554
+ process.on('close', (code) => {
555
+ buffer = Buffer.alloc(0);
556
+ if (code !== 0 && this._frames.length === 0) {
557
+ reject(new Error(`FFmpeg failed with code ${code}`));
558
+ return;
559
+ }
560
+ if (this._frames.length === 0) {
561
+ reject(new Error('No frames decoded'));
562
+ }
563
+ else {
564
+ resolve();
565
+ }
566
+ });
567
+ process.stdin?.on('error', () => { });
568
+ process.stdin?.write(this._data);
569
+ process.stdin?.end();
570
+ });
571
+ }
572
+ async _probeDimensions() {
573
+ if (!this._data)
574
+ return { width: 0, height: 0 };
575
+ // For WebP, try native header parsing first
576
+ if (this._type.toLowerCase() === 'image/webp') {
577
+ const webpInfo = parseWebPHeader(this._data);
578
+ if (webpInfo && webpInfo.width > 0 && webpInfo.height > 0) {
579
+ return { width: webpInfo.width, height: webpInfo.height };
580
+ }
581
+ }
582
+ const codecInfo = MIME_TO_CODEC[this._type.toLowerCase()];
583
+ const tryAutoDetect = codecInfo.autoDetect;
584
+ const attemptProbe = (useFormat) => {
585
+ return new Promise((resolve) => {
586
+ const args = ['-hide_banner'];
587
+ if (useFormat && !tryAutoDetect) {
588
+ args.push('-f', codecInfo.format);
589
+ }
590
+ args.push('-i', 'pipe:0', '-frames:v', '1', '-f', 'null', '-');
591
+ const process = spawn('ffmpeg', args, { stdio: ['pipe', 'pipe', 'pipe'] });
592
+ let stderr = '';
593
+ process.stderr?.on('data', (data) => { stderr += data.toString(); });
594
+ process.on('close', () => {
595
+ const match = stderr.match(/\b(\d{2,5})x(\d{2,5})\b/);
596
+ if (match) {
597
+ resolve({ width: parseInt(match[1], 10), height: parseInt(match[2], 10) });
598
+ }
599
+ else {
600
+ resolve({ width: 0, height: 0 });
601
+ }
602
+ });
603
+ process.stdin?.on('error', () => { });
604
+ process.stdin?.write(Buffer.from(this._data.buffer, this._data.byteOffset, this._data.byteLength));
605
+ process.stdin?.end();
606
+ });
607
+ };
608
+ let result = await attemptProbe(!tryAutoDetect);
609
+ if ((result.width === 0 || result.height === 0) && tryAutoDetect) {
610
+ result = await attemptProbe(true);
611
+ }
612
+ if ((result.width === 0 || result.height === 0) && !tryAutoDetect) {
613
+ result = await attemptProbe(false);
614
+ }
615
+ return result;
616
+ }
617
+ get complete() { return this._complete; }
618
+ get completed() { return this._completed; }
619
+ get tracks() { return this._tracks; }
620
+ get type() { return this._type; }
621
+ static async isTypeSupported(type) {
622
+ return SUPPORTED_TYPES.has(type.toLowerCase());
623
+ }
624
+ async decode(options) {
625
+ if (this._closed) {
626
+ throw new DOMException('ImageDecoder is closed', 'InvalidStateError');
627
+ }
628
+ await this._completed;
629
+ const frameIndex = options?.frameIndex ?? 0;
630
+ const availableFrames = this._frames.length;
631
+ if (availableFrames === 0) {
632
+ throw new DOMException('No frames available', 'InvalidStateError');
633
+ }
634
+ if (frameIndex < 0 || frameIndex >= availableFrames) {
635
+ throw new DOMException(`Frame index ${frameIndex} out of range (0-${availableFrames - 1})`, 'InvalidStateError');
636
+ }
637
+ const frame = this._frames[frameIndex];
638
+ const requireComplete = options?.completeFramesOnly ?? true;
639
+ const frameComplete = frame.complete ?? true;
640
+ if (requireComplete && !frameComplete) {
641
+ throw new DOMException('Requested frame is not fully decoded', 'InvalidStateError');
642
+ }
643
+ const videoFrame = new VideoFrame(frame.data, {
644
+ format: 'RGBA',
645
+ codedWidth: frame.width,
646
+ codedHeight: frame.height,
647
+ timestamp: frame.timestamp,
648
+ duration: frame.duration,
649
+ colorSpace: frame.colorSpace,
650
+ });
651
+ return { image: videoFrame, complete: frameComplete };
652
+ }
653
+ reset() {
654
+ if (this._closed) {
655
+ throw new DOMException('ImageDecoder is closed', 'InvalidStateError');
656
+ }
657
+ if (!this._data) {
658
+ return;
659
+ }
660
+ this._frames = [];
661
+ this._framesParsed = false;
662
+ this._repetitionCount = 0;
663
+ this._frameDurations = [];
664
+ this._visibleFrameCount = 0;
665
+ this._visibleAnimated = false;
666
+ this._visibleRepetitionCount = 1;
667
+ this._tracks = new ImageTrackList();
668
+ this._complete = false;
669
+ this._completed = new Promise((resolve, reject) => {
670
+ this._resolveCompleted = resolve;
671
+ this._rejectCompleted = reject;
672
+ });
673
+ this._initializeTracks();
674
+ }
675
+ close() {
676
+ if (this._closed)
677
+ return;
678
+ this._closed = true;
679
+ this._data = null;
680
+ this._frames = [];
681
+ this._visibleFrameCount = 0;
682
+ this._visibleAnimated = false;
683
+ this._visibleRepetitionCount = 1;
684
+ }
685
+ }
686
+ //# sourceMappingURL=ImageDecoder.js.map