@revizly/node-av 5.2.2-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. package/BUILD_LINUX.md +61 -0
  2. package/LICENSE.md +22 -0
  3. package/README.md +662 -0
  4. package/build_mac_local.sh +69 -0
  5. package/dist/api/audio-frame-buffer.d.ts +205 -0
  6. package/dist/api/audio-frame-buffer.js +287 -0
  7. package/dist/api/audio-frame-buffer.js.map +1 -0
  8. package/dist/api/bitstream-filter.d.ts +820 -0
  9. package/dist/api/bitstream-filter.js +1242 -0
  10. package/dist/api/bitstream-filter.js.map +1 -0
  11. package/dist/api/constants.d.ts +44 -0
  12. package/dist/api/constants.js +45 -0
  13. package/dist/api/constants.js.map +1 -0
  14. package/dist/api/data/test_av1.ivf +0 -0
  15. package/dist/api/data/test_h264.h264 +0 -0
  16. package/dist/api/data/test_hevc.h265 +0 -0
  17. package/dist/api/data/test_mjpeg.mjpeg +0 -0
  18. package/dist/api/data/test_vp8.ivf +0 -0
  19. package/dist/api/data/test_vp9.ivf +0 -0
  20. package/dist/api/decoder.d.ts +1088 -0
  21. package/dist/api/decoder.js +1775 -0
  22. package/dist/api/decoder.js.map +1 -0
  23. package/dist/api/demuxer.d.ts +1219 -0
  24. package/dist/api/demuxer.js +2081 -0
  25. package/dist/api/demuxer.js.map +1 -0
  26. package/dist/api/device.d.ts +586 -0
  27. package/dist/api/device.js +961 -0
  28. package/dist/api/device.js.map +1 -0
  29. package/dist/api/encoder.d.ts +1132 -0
  30. package/dist/api/encoder.js +1988 -0
  31. package/dist/api/encoder.js.map +1 -0
  32. package/dist/api/filter-complex.d.ts +821 -0
  33. package/dist/api/filter-complex.js +1604 -0
  34. package/dist/api/filter-complex.js.map +1 -0
  35. package/dist/api/filter-presets.d.ts +1286 -0
  36. package/dist/api/filter-presets.js +2152 -0
  37. package/dist/api/filter-presets.js.map +1 -0
  38. package/dist/api/filter.d.ts +1234 -0
  39. package/dist/api/filter.js +1976 -0
  40. package/dist/api/filter.js.map +1 -0
  41. package/dist/api/fmp4-stream.d.ts +426 -0
  42. package/dist/api/fmp4-stream.js +739 -0
  43. package/dist/api/fmp4-stream.js.map +1 -0
  44. package/dist/api/hardware.d.ts +651 -0
  45. package/dist/api/hardware.js +1260 -0
  46. package/dist/api/hardware.js.map +1 -0
  47. package/dist/api/index.d.ts +17 -0
  48. package/dist/api/index.js +32 -0
  49. package/dist/api/index.js.map +1 -0
  50. package/dist/api/io-stream.d.ts +307 -0
  51. package/dist/api/io-stream.js +282 -0
  52. package/dist/api/io-stream.js.map +1 -0
  53. package/dist/api/muxer.d.ts +957 -0
  54. package/dist/api/muxer.js +2002 -0
  55. package/dist/api/muxer.js.map +1 -0
  56. package/dist/api/pipeline.d.ts +607 -0
  57. package/dist/api/pipeline.js +1145 -0
  58. package/dist/api/pipeline.js.map +1 -0
  59. package/dist/api/utilities/async-queue.d.ts +120 -0
  60. package/dist/api/utilities/async-queue.js +211 -0
  61. package/dist/api/utilities/async-queue.js.map +1 -0
  62. package/dist/api/utilities/audio-sample.d.ts +117 -0
  63. package/dist/api/utilities/audio-sample.js +112 -0
  64. package/dist/api/utilities/audio-sample.js.map +1 -0
  65. package/dist/api/utilities/channel-layout.d.ts +76 -0
  66. package/dist/api/utilities/channel-layout.js +80 -0
  67. package/dist/api/utilities/channel-layout.js.map +1 -0
  68. package/dist/api/utilities/electron-shared-texture.d.ts +328 -0
  69. package/dist/api/utilities/electron-shared-texture.js +503 -0
  70. package/dist/api/utilities/electron-shared-texture.js.map +1 -0
  71. package/dist/api/utilities/image.d.ts +207 -0
  72. package/dist/api/utilities/image.js +213 -0
  73. package/dist/api/utilities/image.js.map +1 -0
  74. package/dist/api/utilities/index.d.ts +12 -0
  75. package/dist/api/utilities/index.js +25 -0
  76. package/dist/api/utilities/index.js.map +1 -0
  77. package/dist/api/utilities/media-type.d.ts +49 -0
  78. package/dist/api/utilities/media-type.js +53 -0
  79. package/dist/api/utilities/media-type.js.map +1 -0
  80. package/dist/api/utilities/pixel-format.d.ts +89 -0
  81. package/dist/api/utilities/pixel-format.js +97 -0
  82. package/dist/api/utilities/pixel-format.js.map +1 -0
  83. package/dist/api/utilities/sample-format.d.ts +129 -0
  84. package/dist/api/utilities/sample-format.js +141 -0
  85. package/dist/api/utilities/sample-format.js.map +1 -0
  86. package/dist/api/utilities/scheduler.d.ts +138 -0
  87. package/dist/api/utilities/scheduler.js +98 -0
  88. package/dist/api/utilities/scheduler.js.map +1 -0
  89. package/dist/api/utilities/streaming.d.ts +186 -0
  90. package/dist/api/utilities/streaming.js +309 -0
  91. package/dist/api/utilities/streaming.js.map +1 -0
  92. package/dist/api/utilities/timestamp.d.ts +193 -0
  93. package/dist/api/utilities/timestamp.js +206 -0
  94. package/dist/api/utilities/timestamp.js.map +1 -0
  95. package/dist/api/utilities/whisper-model.d.ts +310 -0
  96. package/dist/api/utilities/whisper-model.js +528 -0
  97. package/dist/api/utilities/whisper-model.js.map +1 -0
  98. package/dist/api/utils.d.ts +19 -0
  99. package/dist/api/utils.js +39 -0
  100. package/dist/api/utils.js.map +1 -0
  101. package/dist/api/whisper.d.ts +324 -0
  102. package/dist/api/whisper.js +362 -0
  103. package/dist/api/whisper.js.map +1 -0
  104. package/dist/constants/channel-layouts.d.ts +53 -0
  105. package/dist/constants/channel-layouts.js +57 -0
  106. package/dist/constants/channel-layouts.js.map +1 -0
  107. package/dist/constants/constants.d.ts +2325 -0
  108. package/dist/constants/constants.js +1887 -0
  109. package/dist/constants/constants.js.map +1 -0
  110. package/dist/constants/decoders.d.ts +633 -0
  111. package/dist/constants/decoders.js +641 -0
  112. package/dist/constants/decoders.js.map +1 -0
  113. package/dist/constants/encoders.d.ts +295 -0
  114. package/dist/constants/encoders.js +308 -0
  115. package/dist/constants/encoders.js.map +1 -0
  116. package/dist/constants/hardware.d.ts +26 -0
  117. package/dist/constants/hardware.js +27 -0
  118. package/dist/constants/hardware.js.map +1 -0
  119. package/dist/constants/index.d.ts +5 -0
  120. package/dist/constants/index.js +6 -0
  121. package/dist/constants/index.js.map +1 -0
  122. package/dist/ffmpeg/index.d.ts +99 -0
  123. package/dist/ffmpeg/index.js +115 -0
  124. package/dist/ffmpeg/index.js.map +1 -0
  125. package/dist/ffmpeg/utils.d.ts +31 -0
  126. package/dist/ffmpeg/utils.js +68 -0
  127. package/dist/ffmpeg/utils.js.map +1 -0
  128. package/dist/ffmpeg/version.d.ts +6 -0
  129. package/dist/ffmpeg/version.js +7 -0
  130. package/dist/ffmpeg/version.js.map +1 -0
  131. package/dist/index.d.ts +4 -0
  132. package/dist/index.js +9 -0
  133. package/dist/index.js.map +1 -0
  134. package/dist/lib/audio-fifo.d.ts +399 -0
  135. package/dist/lib/audio-fifo.js +431 -0
  136. package/dist/lib/audio-fifo.js.map +1 -0
  137. package/dist/lib/binding.d.ts +228 -0
  138. package/dist/lib/binding.js +60 -0
  139. package/dist/lib/binding.js.map +1 -0
  140. package/dist/lib/bitstream-filter-context.d.ts +379 -0
  141. package/dist/lib/bitstream-filter-context.js +441 -0
  142. package/dist/lib/bitstream-filter-context.js.map +1 -0
  143. package/dist/lib/bitstream-filter.d.ts +140 -0
  144. package/dist/lib/bitstream-filter.js +154 -0
  145. package/dist/lib/bitstream-filter.js.map +1 -0
  146. package/dist/lib/codec-context.d.ts +1071 -0
  147. package/dist/lib/codec-context.js +1354 -0
  148. package/dist/lib/codec-context.js.map +1 -0
  149. package/dist/lib/codec-parameters.d.ts +616 -0
  150. package/dist/lib/codec-parameters.js +761 -0
  151. package/dist/lib/codec-parameters.js.map +1 -0
  152. package/dist/lib/codec-parser.d.ts +201 -0
  153. package/dist/lib/codec-parser.js +213 -0
  154. package/dist/lib/codec-parser.js.map +1 -0
  155. package/dist/lib/codec.d.ts +586 -0
  156. package/dist/lib/codec.js +713 -0
  157. package/dist/lib/codec.js.map +1 -0
  158. package/dist/lib/device.d.ts +291 -0
  159. package/dist/lib/device.js +324 -0
  160. package/dist/lib/device.js.map +1 -0
  161. package/dist/lib/dictionary.d.ts +333 -0
  162. package/dist/lib/dictionary.js +372 -0
  163. package/dist/lib/dictionary.js.map +1 -0
  164. package/dist/lib/error.d.ts +242 -0
  165. package/dist/lib/error.js +303 -0
  166. package/dist/lib/error.js.map +1 -0
  167. package/dist/lib/fifo.d.ts +416 -0
  168. package/dist/lib/fifo.js +453 -0
  169. package/dist/lib/fifo.js.map +1 -0
  170. package/dist/lib/filter-context.d.ts +712 -0
  171. package/dist/lib/filter-context.js +789 -0
  172. package/dist/lib/filter-context.js.map +1 -0
  173. package/dist/lib/filter-graph-segment.d.ts +160 -0
  174. package/dist/lib/filter-graph-segment.js +171 -0
  175. package/dist/lib/filter-graph-segment.js.map +1 -0
  176. package/dist/lib/filter-graph.d.ts +641 -0
  177. package/dist/lib/filter-graph.js +704 -0
  178. package/dist/lib/filter-graph.js.map +1 -0
  179. package/dist/lib/filter-inout.d.ts +198 -0
  180. package/dist/lib/filter-inout.js +257 -0
  181. package/dist/lib/filter-inout.js.map +1 -0
  182. package/dist/lib/filter.d.ts +243 -0
  183. package/dist/lib/filter.js +272 -0
  184. package/dist/lib/filter.js.map +1 -0
  185. package/dist/lib/format-context.d.ts +1254 -0
  186. package/dist/lib/format-context.js +1379 -0
  187. package/dist/lib/format-context.js.map +1 -0
  188. package/dist/lib/frame-utils.d.ts +116 -0
  189. package/dist/lib/frame-utils.js +98 -0
  190. package/dist/lib/frame-utils.js.map +1 -0
  191. package/dist/lib/frame.d.ts +1222 -0
  192. package/dist/lib/frame.js +1435 -0
  193. package/dist/lib/frame.js.map +1 -0
  194. package/dist/lib/hardware-device-context.d.ts +362 -0
  195. package/dist/lib/hardware-device-context.js +383 -0
  196. package/dist/lib/hardware-device-context.js.map +1 -0
  197. package/dist/lib/hardware-frames-context.d.ts +419 -0
  198. package/dist/lib/hardware-frames-context.js +477 -0
  199. package/dist/lib/hardware-frames-context.js.map +1 -0
  200. package/dist/lib/index.d.ts +35 -0
  201. package/dist/lib/index.js +60 -0
  202. package/dist/lib/index.js.map +1 -0
  203. package/dist/lib/input-format.d.ts +249 -0
  204. package/dist/lib/input-format.js +306 -0
  205. package/dist/lib/input-format.js.map +1 -0
  206. package/dist/lib/io-context.d.ts +696 -0
  207. package/dist/lib/io-context.js +769 -0
  208. package/dist/lib/io-context.js.map +1 -0
  209. package/dist/lib/log.d.ts +174 -0
  210. package/dist/lib/log.js +184 -0
  211. package/dist/lib/log.js.map +1 -0
  212. package/dist/lib/native-types.d.ts +946 -0
  213. package/dist/lib/native-types.js +2 -0
  214. package/dist/lib/native-types.js.map +1 -0
  215. package/dist/lib/option.d.ts +927 -0
  216. package/dist/lib/option.js +1583 -0
  217. package/dist/lib/option.js.map +1 -0
  218. package/dist/lib/output-format.d.ts +180 -0
  219. package/dist/lib/output-format.js +213 -0
  220. package/dist/lib/output-format.js.map +1 -0
  221. package/dist/lib/packet.d.ts +501 -0
  222. package/dist/lib/packet.js +590 -0
  223. package/dist/lib/packet.js.map +1 -0
  224. package/dist/lib/rational.d.ts +251 -0
  225. package/dist/lib/rational.js +278 -0
  226. package/dist/lib/rational.js.map +1 -0
  227. package/dist/lib/software-resample-context.d.ts +552 -0
  228. package/dist/lib/software-resample-context.js +592 -0
  229. package/dist/lib/software-resample-context.js.map +1 -0
  230. package/dist/lib/software-scale-context.d.ts +344 -0
  231. package/dist/lib/software-scale-context.js +366 -0
  232. package/dist/lib/software-scale-context.js.map +1 -0
  233. package/dist/lib/stream.d.ts +379 -0
  234. package/dist/lib/stream.js +526 -0
  235. package/dist/lib/stream.js.map +1 -0
  236. package/dist/lib/sync-queue.d.ts +179 -0
  237. package/dist/lib/sync-queue.js +197 -0
  238. package/dist/lib/sync-queue.js.map +1 -0
  239. package/dist/lib/types.d.ts +34 -0
  240. package/dist/lib/types.js +2 -0
  241. package/dist/lib/types.js.map +1 -0
  242. package/dist/lib/utilities.d.ts +1127 -0
  243. package/dist/lib/utilities.js +1225 -0
  244. package/dist/lib/utilities.js.map +1 -0
  245. package/dist/utils/electron.d.ts +49 -0
  246. package/dist/utils/electron.js +63 -0
  247. package/dist/utils/electron.js.map +1 -0
  248. package/dist/utils/index.d.ts +4 -0
  249. package/dist/utils/index.js +5 -0
  250. package/dist/utils/index.js.map +1 -0
  251. package/install/check.js +121 -0
  252. package/install/ffmpeg.js +66 -0
  253. package/jellyfin-ffmpeg.patch +181 -0
  254. package/package.json +129 -0
package/README.md ADDED
@@ -0,0 +1,662 @@
1
+ <p align="center">
2
+ <img src="https://github.com/seydx/node-av/blob/main/docs/logo.png?raw=true" width="250px">
3
+ </p>
4
+
5
+ # NodeAV
6
+
7
+ [![npm version](https://img.shields.io/npm/v/node-av.svg)](https://www.npmjs.com/package/node-av)
8
+ [![npm downloads](https://img.shields.io/npm/dt/node-av.svg)](https://www.npmjs.com/package/node-av)
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
10
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
11
+ [![FFmpeg](https://img.shields.io/badge/FFmpeg-8-green.svg)](https://ffmpeg.org)
12
+ [![Platform](https://img.shields.io/badge/platform-Windows%20(MSVC%20%7C%20MinGW)%20%7C%20macOS%20%7C%20Linux-lightgrey.svg)](https://github.com/seydx/node-av)
13
+
14
+ Native Node.js bindings for FFmpeg with full TypeScript support. Provides direct access to FFmpeg's C APIs through N-API. Includes both raw FFmpeg bindings for full control and higher-level abstractions. Automatic resource management via Disposable pattern, hardware acceleration support and prebuilt binaries for Windows, Linux, and macOS.
15
+
16
+ 📚 **[Documentation](https://seydx.github.io/node-av)**
17
+
18
+ ## Table of Contents
19
+
20
+ - [Installation](#installation)
21
+ - [Quick Start](#quick-start)
22
+ - [Low-Level API](#low-level-api)
23
+ - [High-Level API](#high-level-api)
24
+ - [Pipeline API](#pipeline-api)
25
+ - [Hardware Acceleration](#hardware-acceleration)
26
+ - [Auto-Detection](#auto-detection)
27
+ - [Specific Hardware](#specific-hardware)
28
+ - [Stream Processing](#stream-processing)
29
+ - [From Files or Network](#from-files-or-network)
30
+ - [From Buffers](#from-buffers)
31
+ - [Raw Media Processing](#raw-media-processing)
32
+ - [Device Capture](#device-capture)
33
+ - [FFmpeg Binary Access](#ffmpeg-binary-access)
34
+ - [Resource Management](#resource-management)
35
+ - [Imports and Tree Shaking](#imports-and-tree-shaking)
36
+ - [Key Features](#key-features)
37
+ - [Performance](#performance)
38
+ - [Benchmarks](#benchmarks)
39
+ - [Sync vs Async Operations](#sync-vs-async-operations)
40
+ - [Memory Safety Considerations](#memory-safety-considerations)
41
+ - [Electron](#electron)
42
+ - [Examples](#examples)
43
+ - [Prebuilt Binaries](#prebuilt-binaries)
44
+ - [Troubleshooting](#troubleshooting)
45
+ - [License](#license)
46
+ - [Contributing](#contributing)
47
+ - [Support](#support)
48
+ - [See Also](#see-also)
49
+
50
+ ## Installation
51
+
52
+ ```bash
53
+ npm install node-av
54
+ ```
55
+
56
+ ## Quick Start
57
+
58
+ ### Low-Level API
59
+
60
+ Direct access to FFmpeg's C APIs with minimal abstractions. Perfect when you need full control over FFmpeg functionality.
61
+
62
+ ```typescript
63
+ import { AVERROR_EOF, AVMEDIA_TYPE_VIDEO } from 'node-av/constants';
64
+ import { Codec, CodecContext, FFmpegError, FormatContext, Frame, Packet, Rational } from 'node-av/lib';
65
+
66
+ // Open input file
67
+ await using ifmtCtx = new FormatContext();
68
+
69
+ let ret = await ifmtCtx.openInput('input.mp4');
70
+ FFmpegError.throwIfError(ret, 'Could not open input file');
71
+
72
+ ret = await ifmtCtx.findStreamInfo();
73
+ FFmpegError.throwIfError(ret, 'Could not find stream info');
74
+
75
+ // Find video stream
76
+ const videoStreamIndex = ifmtCtx.findBestStream(AVMEDIA_TYPE_VIDEO);
77
+ const videoStream = ifmtCtx.streams?.[videoStreamIndex];
78
+
79
+ if (!videoStream) {
80
+ throw new Error('No video stream found');
81
+ }
82
+
83
+ // Create codec
84
+ const codec = Codec.findDecoder(videoStream.codecpar.codecId);
85
+ if (!codec) {
86
+ throw new Error('Codec not found');
87
+ }
88
+
89
+ // Allocate codec context for the decoder
90
+ using decoderCtx = new CodecContext();
91
+ decoderCtx.allocContext3(codec);
92
+
93
+ ret = decoderCtx.parametersToContext(videoStream.codecpar);
94
+ FFmpegError.throwIfError(ret, 'Could not copy codec parameters to decoder context');
95
+
96
+ // Open decoder context
97
+ ret = await decoderCtx.open2(codec, null);
98
+ FFmpegError.throwIfError(ret, 'Could not open codec');
99
+
100
+ // Process packets
101
+ using packet = new Packet();
102
+ packet.alloc();
103
+
104
+ using frame = new Frame();
105
+ frame.alloc();
106
+
107
+ while (true) {
108
+ let ret = await ifmtCtx.readFrame(packet);
109
+ if (ret < 0) {
110
+ break;
111
+ }
112
+
113
+ if (packet.streamIndex === videoStreamIndex) {
114
+ // Send packet to decoder
115
+ ret = await decoderCtx.sendPacket(packet);
116
+ if (ret < 0 && ret !== AVERROR_EOF) {
117
+ FFmpegError.throwIfError(ret, 'Error sending packet to decoder');
118
+ }
119
+
120
+ // Receive decoded frames
121
+ while (true) {
122
+ const ret = await decoderCtx.receiveFrame(frame);
123
+ if (ret === AVERROR_EOF || ret < 0) {
124
+ break;
125
+ }
126
+
127
+ console.log(`Decoded frame ${frame.pts}, size: ${frame.width}x${frame.height}`);
128
+
129
+ // Process frame data...
130
+ }
131
+ }
132
+
133
+ packet.unref();
134
+ }
135
+ ```
136
+
137
+ ### High-Level API
138
+
139
+ Higher-level abstractions for common tasks like decoding, encoding, filtering, and transcoding. Easier to use while still providing access to low-level details when needed.
140
+
141
+ ```typescript
142
+ import { Decoder, Demuxer, Encoder, HardwareContext, Muxer } from 'node-av/api';
143
+ import { FF_ENCODER_LIBX264 } from 'node-av/constants';
144
+
145
+ // Open Demuxer
146
+ await using input = await Demuxer.open('input.mp4');
147
+
148
+ // Get video stream
149
+ const videoStream = input.video()!;
150
+
151
+ // Optional, setup hardware acceleration
152
+ using hw = HardwareContext.auto();
153
+
154
+ // Create decoder
155
+ using decoder = await Decoder.create(videoStream, {
156
+ hardware: hw, // Optional, use hardware acceleration if available
157
+ });
158
+
159
+ // Create encoder
160
+ using encoder = await Encoder.create(FF_ENCODER_LIBX264, {
161
+ decoder, // Optional, copy settings from decoder
162
+ });
163
+
164
+ // Open Muxer
165
+ await using output = await Muxer.open('output.mp4', {
166
+ input, // Optional, used to copy global headers and metadata
167
+ });
168
+
169
+ // Add stream to output
170
+ const outputIndex = output.addStream(encoder, {
171
+ inputStream: videoStream, // Optional, copy settings from input stream
172
+ });
173
+
174
+ // Create processing generators
175
+ const inputGenerator = input.packets(videoStream.index);
176
+ const decoderGenerator = decoder.frames(inputGenerator);
177
+ const encoderGenerator = encoder.packets(decoderGenerator);
178
+
179
+ // Process packets
180
+ for await (using packet of encoderGenerator) {
181
+ await output.writePacket(packet, outputIndex);
182
+ }
183
+
184
+ // Done
185
+ ```
186
+
187
+ ### Pipeline API
188
+
189
+ A simple way to chain together multiple processing steps like decoding, filtering, encoding, and muxing.
190
+
191
+ ```typescript
192
+ import { Decoder, Demuxer, Encoder, HardwareContext, Muxer, pipeline } from 'node-av/api';
193
+ import { FF_ENCODER_LIBX264 } from 'node-av/constants';
194
+
195
+ // Simple transcode pipeline: input → decoder → encoder → output
196
+
197
+ // Open Demuxer
198
+ await using input = await Demuxer.open('input.mp4');
199
+
200
+ // Get video stream
201
+ const videoStream = input.video()!;
202
+
203
+ // Optional, setup hardware acceleration
204
+ using hw = HardwareContext.auto();
205
+
206
+ // Create decoder
207
+ using decoder = await Decoder.create(videoStream, {
208
+ hardware: hw, // Optional, use hardware acceleration if available
209
+ });
210
+
211
+ // Create encoder
212
+ using encoder = await Encoder.create(FF_ENCODER_LIBX264, {
213
+ decoder, // Optional, copy settings from decoder
214
+ });
215
+
216
+ // Open Muxer
217
+ await using output = await Muxer.open('output.mp4', {
218
+ input, // Optional, used to copy global headers and metadata
219
+ });
220
+
221
+ const control = pipeline(input, decoder, encoder, output);
222
+ await control.completion;
223
+ ```
224
+
225
+ ## Hardware Acceleration
226
+
227
+ The library supports all hardware acceleration methods available in FFmpeg. The specific hardware types available depend on your FFmpeg build and system configuration.
228
+
229
+ ### Auto-Detection
230
+
231
+ ```typescript
232
+ import { HardwareContext } from 'node-av/api';
233
+ import { FF_ENCODER_LIBX264 } from 'node-av/constants';
234
+
235
+ // Automatically detect best available hardware
236
+ const hw = HardwareContext.auto();
237
+ console.log(`Using hardware: ${hw.deviceTypeName}`);
238
+
239
+ // Use with decoder
240
+ const decoder = await Decoder.create(stream, {
241
+ hardware: hw
242
+ });
243
+
244
+ // Use with encoder (use hardware-specific codec)
245
+ const encoderCodec = hw?.getEncoderCodec('h264') ?? FF_ENCODER_LIBX264;
246
+ const encoder = await Encoder.create(encoderCodec, {
247
+ decoder,
248
+ });
249
+ ```
250
+
251
+ ### Specific Hardware
252
+
253
+ ```typescript
254
+ import { AV_HWDEVICE_TYPE_CUDA, AV_HWDEVICE_TYPE_VAAPI } from 'node-av/constants';
255
+
256
+ // Use specific hardware type
257
+ const cuda = HardwareContext.create(AV_HWDEVICE_TYPE_CUDA);
258
+ const vaapi = HardwareContext.create(AV_HWDEVICE_TYPE_VAAPI, '/dev/dri/renderD128');
259
+ ```
260
+
261
+ ## Stream Processing
262
+
263
+ ### From Files or Network
264
+
265
+ ```typescript
266
+ const media = await Demuxer.open('input.mp4');
267
+
268
+ // or
269
+
270
+ const media = await Demuxer.open('rtsp://example.com/stream');
271
+ ```
272
+
273
+ ### From Buffers
274
+
275
+ ```typescript
276
+ import { readFile } from 'fs/promises';
277
+
278
+ const buffer = await readFile('input.mp4');
279
+ const media = await Demuxer.open(buffer);
280
+ ```
281
+
282
+ ### Custom I/O Callbacks
283
+
284
+ ```typescript
285
+ import type { IOInputCallbacks, IOOutputCallbacks } from 'node-av/api';
286
+
287
+ // Custom input source
288
+ const inputCallbacks: IOInputCallbacks = {
289
+ read: (size: number) => {
290
+ // Read from your custom source
291
+ return buffer; // or null for EOF
292
+ },
293
+ seek: (offset: bigint, whence: number) => {
294
+ // Seek in your custom source
295
+ return newPosition;
296
+ }
297
+ };
298
+
299
+ await using input = await Demuxer.open(inputCallbacks, {
300
+ format: 'mp4'
301
+ });
302
+ ```
303
+
304
+ ### Raw Media Processing
305
+
306
+ ```typescript
307
+ // Raw video input
308
+ const rawVideo = await Demuxer.open({
309
+ type: 'video',
310
+ input: 'input.yuv',
311
+ width: 1280,
312
+ height: 720,
313
+ pixelFormat: AV_PIX_FMT_YUV420P,
314
+ frameRate: { num: 30, den: 1 }
315
+ });
316
+
317
+ // Raw audio input
318
+ const rawAudio = await Demuxer.open({
319
+ type: 'audio',
320
+ input: 'input.pcm',
321
+ sampleRate: 48000,
322
+ channels: 2,
323
+ sampleFormat: AV_SAMPLE_FMT_S16
324
+ }, {
325
+ format: 's16le'
326
+ });
327
+ ```
328
+
329
+ ## Device Capture
330
+
331
+ Capture video, audio, and screen content directly from system devices. Platform-specific formats are handled automatically.
332
+
333
+ ```typescript
334
+ import { DeviceAPI } from 'node-av/api';
335
+
336
+ // List devices and query capabilities
337
+ const devices = await DeviceAPI.list();
338
+ const modes = await DeviceAPI.modes(devices.find(d => d.type === 'video')!.name);
339
+
340
+ // Camera
341
+ await using camera = await DeviceAPI.openCamera({ videoDevice: 0, width: 1280, height: 720, frameRate: 30 });
342
+
343
+ // Microphone
344
+ await using mic = await DeviceAPI.openMicrophone({ audioDevice: 0, sampleRate: 48000, channels: 2 });
345
+
346
+ // Combined video + audio (macOS/Windows)
347
+ await using device = await DeviceAPI.openDevice({ videoDevice: 0, audioDevice: 0, width: 1280, height: 720, frameRate: 30 });
348
+
349
+ // Screen capture
350
+ await using screen = await DeviceAPI.openScreen({ frameRate: 30, drawMouse: true });
351
+
352
+ // Screen capture with system audio (macOS 13.0+)
353
+ await using screen2 = await DeviceAPI.openScreen({
354
+ frameRate: 30,
355
+ avfoundation: { captureSystemAudio: true, audioSampleRate: 48000, audioChannels: 2 },
356
+ });
357
+ ```
358
+
359
+ | Platform | Video | Audio | Screen |
360
+ |----------|-------|-------|--------|
361
+ | macOS | AVFoundation | AVFoundation | AVFoundation (ScreenCaptureKit) |
362
+ | Linux | V4L2 | ALSA | x11grab |
363
+ | Windows | DirectShow | DirectShow | GDIGrab |
364
+
365
+ ## FFmpeg Binary Access
366
+
367
+ Need direct access to the FFmpeg binary? The library provides an easy way to get FFmpeg binaries that automatically downloads and manages platform-specific builds.
368
+
369
+ ```typescript
370
+ import { ffmpegPath, isFfmpegAvailable } from 'node-av/ffmpeg';
371
+ import { execFile } from 'node:child_process';
372
+ import { promisify } from 'node:util';
373
+
374
+ const execFileAsync = promisify(execFile);
375
+
376
+ // Check if FFmpeg binary is available
377
+ if (isFfmpegAvailable()) {
378
+ console.log('FFmpeg binary found at:', ffmpegPath());
379
+
380
+ // Use FFmpeg binary directly
381
+ const { stdout } = await execFileAsync(ffmpegPath(), ['-version']);
382
+ console.log(stdout);
383
+ } else {
384
+ console.log('FFmpeg binary not available - install may have failed');
385
+ }
386
+
387
+ // Direct usage example
388
+ async function convertVideo(input: string, output: string) {
389
+ const args = [
390
+ '-i', input,
391
+ '-c:v', 'libx264',
392
+ '-crf', '23',
393
+ '-c:a', 'aac',
394
+ output
395
+ ];
396
+
397
+ await execFileAsync(ffmpegPath(), args);
398
+ }
399
+ ```
400
+
401
+ The FFmpeg binary is automatically downloaded during installation from GitHub releases and matches the same build used by the native bindings.
402
+
403
+ ## Resource Management
404
+
405
+ The library supports automatic resource cleanup using the Disposable pattern:
406
+
407
+ ```typescript
408
+ // Automatic cleanup with 'using'
409
+ {
410
+ await using media = await Demuxer.open('input.mp4');
411
+ using decoder = await Decoder.create(media.video());
412
+ // Resources automatically cleaned up at end of scope
413
+ }
414
+
415
+ // Manual cleanup
416
+ const media = await Demuxer.open('input.mp4');
417
+ try {
418
+ // Process media
419
+ } finally {
420
+ await media.close();
421
+ }
422
+ ```
423
+
424
+ ## Imports and Tree Shaking
425
+
426
+ The library provides multiple entry points for optimal tree shaking:
427
+
428
+ ```typescript
429
+ // High-Level API only - Recommended for most use cases
430
+ import { Demuxer, Muxer, Decoder, Encoder } from 'node-av/api';
431
+
432
+ // Low-Level API only - Direct FFmpeg bindings
433
+ import { FormatContext, CodecContext, Frame, Packet } from 'node-av/lib';
434
+
435
+ // Constants only - When you just need FFmpeg constants
436
+ import { AV_PIX_FMT_YUV420P, AV_CODEC_ID_H264 } from 'node-av/constants';
437
+
438
+ // Channel layouts only - For audio channel configurations
439
+ import { AV_CHANNEL_LAYOUT_STEREO, AV_CHANNEL_LAYOUT_5POINT1 } from 'node-av/layouts';
440
+
441
+ // Default export - Includes everything
442
+ import * as ffmpeg from 'node-av';
443
+ ```
444
+
445
+ ## Key Features
446
+
447
+ Beyond basic transcoding, NodeAV provides advanced media processing capabilities:
448
+
449
+ **Speech Recognition with Whisper**
450
+ Integrate automatic speech-to-text transcription using OpenAI's Whisper model through the whisper.cpp implementation. The library handles automatic model downloading from HuggingFace, supports multiple model sizes (tiny, base, small, medium, large) for different accuracy/performance tradeoffs, and provides hardware-accelerated inference through Metal (macOS), Vulkan (cross-platform), or OpenCL backends. Transcription results include precise timestamps and can be processed in real-time from any audio source.
451
+
452
+ **Advanced Video Filtering with FilterComplexAPI**
453
+ Build sophisticated video processing pipelines using FFmpeg's complete filter ecosystem. The FilterComplexAPI provides direct access to complex filtergraphs with multiple inputs and outputs, enabling advanced operations like picture-in-picture overlays, multi-stream composition (side-by-side, grid layouts), real-time video effects, and custom processing chains. All filters support hardware acceleration where available, and filter configurations can be dynamically constructed based on runtime requirements.
454
+
455
+ **Browser Streaming**
456
+ Stream any media source directly to web browsers through fragmented MP4 (fMP4) or WebRTC protocols. The library can process inputs from RTSP cameras, local files, network streams, or custom sources and package them for browser consumption with minimal latency. Complete examples demonstrate both Media Source Extensions (MSE) based playback for on-demand content and WebRTC integration for real-time streaming scenarios.
457
+
458
+ **RTSP Backchannel / Talkback**
459
+ Implements bidirectional RTSP communication for IP camera integration. The library provides native support for RTSP backchannel streams, enabling audio transmission to camera devices. Transport is handled automatically with support for both TCP (interleaved mode) and UDP protocols, with proper RTP packet formatting and stream synchronization.
460
+
461
+ See the [Examples](#examples) section for complete implementations.
462
+
463
+ ## Performance
464
+
465
+ NodeAV executes all media operations directly through FFmpeg's native C libraries. The Node.js bindings add minimal overhead - mostly just the JavaScript-to-C boundary crossings. During typical operations like transcoding or filtering, most processing time is spent in FFmpeg's optimized C code.
466
+
467
+ ### Benchmarks
468
+
469
+ Performance comparison with FFmpeg CLI (4K 60fps, 30s test files on Apple M3 Max):
470
+
471
+ | Operation | FFmpeg CLI (FPS) | node-av (FPS) | FFmpeg CLI (Time) | node-av (Time) | Diff |
472
+ |-----------|------------------|---------------|-------------------|----------------|------|
473
+ | SW H.264 Transcode | 96 fps | 96 fps | 18.7s | 18.7s | ≈0% |
474
+ | SW H.265 Transcode | 40 fps | 41 fps | 44.5s | 43.7s | **+1.5%** |
475
+ | HW H.264 Transcode | 55 fps | 55 fps | 33.0s | 32.8s | **+0.5%** |
476
+ | Stream Copy (Remux) | 48k fps | 31k fps | 38ms | 106ms | -35% |
477
+
478
+ **Memory Usage:**
479
+ | Operation | FFmpeg CLI | node-av | Difference |
480
+ |-----------|-----------|---------|------------|
481
+ | H.264 Transcode (4K) | 3.6 GB | 3.4 GB | **-5%** |
482
+ | Stream Copy | 28 MB | 1 MB | **-96%** |
483
+
484
+ 📊 **[Full benchmark results](https://github.com/seydx/node-av/tree/main/BENCHMARK.md)**
485
+
486
+ ### Sync vs Async Operations
487
+
488
+ Every async method in NodeAV has a corresponding synchronous variant with the `Sync` suffix:
489
+
490
+ - **Async methods** (default) - Non-blocking operations using N-API's AsyncWorker. Methods like `decode()`, `encode()`, `read()`, `packets()` return Promises or AsyncGenerators.
491
+
492
+ - **Sync methods** - Direct FFmpeg calls without AsyncWorker overhead. Same methods with `Sync` suffix: `decodeSync()`, `encodeSync()`, `readSync()`, `packetsSync()`.
493
+
494
+ The key difference: Async methods don't block the Node.js event loop, allowing other operations to run concurrently. Sync methods block until completion but avoid AsyncWorker overhead, making them faster for sequential processing.
495
+
496
+ ## Memory Safety Considerations
497
+
498
+ NodeAV provides direct bindings to FFmpeg's C APIs, which work with raw memory pointers. The high-level API adds safety abstractions and automatic resource management, but incorrect usage can still cause crashes. Common issues include mismatched video dimensions, incompatible pixel formats, or improper frame buffer handling. The library validates parameters where possible, but can't guarantee complete memory safety without limiting functionality. When using the low-level API, pay attention to parameter consistency, resource cleanup, and format compatibility. Following the documented patterns helps avoid memory-related issues.
499
+
500
+ ## Electron
501
+
502
+ NodeAV fully supports Electron applications. The prebuilt binaries are ABI-compatible with Electron, so no native rebuild is required during packaging. Both the native bindings and the bundled FFmpeg CLI binaries work seamlessly within Electron's main process.
503
+
504
+ NodeAV also supports Electron's [offscreen rendering with shared textures](https://www.electronjs.org/docs/latest/tutorial/offscreen-rendering), enabling zero-copy GPU texture import for hardware-accelerated encoding. See the [Electron Builder](https://github.com/seydx/node-av/tree/main/examples/electron/builder) and [Electron Forge](https://github.com/seydx/node-av/tree/main/examples/electron/forge) examples for complete implementations.
505
+
506
+ If you encounter module resolution errors like `Cannot find module 'lib/binary-stream'`, add this override to your project's `package.json`:
507
+
508
+ ```json
509
+ {
510
+ "overrides": {
511
+ "@shinyoshiaki/binary-data": "npm:@seydx/binary-data@0.6.2"
512
+ }
513
+ }
514
+ ```
515
+
516
+ ## Examples
517
+
518
+ | Example | FFmpeg | Low-Level API | High-Level API |
519
+ |---------|--------|---------------|----------------|
520
+ | `browser-fmp4` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/browser/fmp4) |
521
+ | `browser-webrtc` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/browser/webrtc) |
522
+ | `electron-builder` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/electron/builder) |
523
+ | `electron-forge` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/electron/forge) |
524
+ | `api-abort-signal` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-abort-signal.ts) |
525
+ | `api-dash` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-dash.ts) |
526
+ | `api-device-capture` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-device-capture.ts) |
527
+ | `api-encode-decode` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-encode-decode.ts) |
528
+ | `api-filter-complex` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-filter-complex.ts) |
529
+ | `api-filter-complex-grid` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-filter-complex-grid.ts) |
530
+ | `api-fmp4` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-fmp4.ts) |
531
+ | `api-frame-extract` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-frame-extract.ts) |
532
+ | `api-hw-codecs` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-hw-codecs.ts) |
533
+ | `api-hw-decode-sw-encode` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-hw-decode-sw-encode.ts) |
534
+ | `api-hw-raw` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-hw-raw.ts) |
535
+ | `api-hw-raw-output` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-hw-raw-output.ts) |
536
+ | `api-hw-rtsp` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-hw-rtsp.ts) |
537
+ | `api-hw-stream-custom-io` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-hw-stream-custom-io.ts) |
538
+ | `api-hw-transcode` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-hw-transcode.ts) |
539
+ | `api-hw-filter-sync` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-hw-filter-sync.ts) |
540
+ | `api-muxing` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-muxing.ts) |
541
+ | `api-pipeline-hw-rtsp` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-pipeline-hw-rtsp.ts) |
542
+ | `api-pipeline-raw-muxing` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-pipeline-raw-muxing.ts) |
543
+ | `api-rtp` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-rtp.ts) |
544
+ | `api-sdp-custom` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-sdp-custom.ts) |
545
+ | `api-sdp-input` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-sdp-input.ts) |
546
+ | `api-stream-input` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-stream-input.ts) |
547
+ | `api-sw-decode-hw-encode` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-sw-decode-hw-encode.ts) |
548
+ | `api-sw-transcode` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-sw-transcode.ts) |
549
+ | `api-whisper-subtitles` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-whisper-subtitles.ts) |
550
+ | `api-whisper-transcribe` | | | [✓](https://github.com/seydx/node-av/tree/main/examples/api-whisper-transcribe.ts) |
551
+ | `frame-utils` | | [✓](https://github.com/seydx/node-av/tree/main/examples/frame-utils.ts) | |
552
+ | `avio-read-callback` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/avio_read_callback.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/avio-read-callback.ts) | |
553
+ | `avio-async-read-callback` | | [✓](https://github.com/seydx/node-av/tree/main/examples/avio-async-read-callback.ts) | |
554
+ | `decode-audio` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/decode_audio.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/decode-audio.ts) | |
555
+ | `decode-filter-audio` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/decode_filter_audio.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/decode-filter-audio.ts) | |
556
+ | `decode-filter-video` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/decode_filter_video.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/decode-filter-video.ts) | |
557
+ | `decode-video` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/decode_video.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/decode-video.ts) | |
558
+ | `demux-decode` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/demux_decode.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/demux-decode.ts) | |
559
+ | `encode-audio` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/encode_audio.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/encode-audio.ts) | |
560
+ | `encode-video` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/encode_video.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/encode-video.ts) | |
561
+ | `ffprobe-metadata` | | [✓](https://github.com/seydx/node-av/tree/main/examples/ffprobe-metadata.ts) | |
562
+ | `filter-audio` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/filter_audio.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/filter-audio.ts) | |
563
+ | `hw-decode` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/hw_decode.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/hw-decode.ts) | |
564
+ | `hw-encode` | | [✓](https://github.com/seydx/node-av/tree/main/examples/hw-encode.ts) | |
565
+ | `hw-transcode` | | [✓](https://github.com/seydx/node-av/tree/main/examples/hw-transcode.ts) | |
566
+ | `qsv-decode` | [✓](https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/qsv_decode.c) | | |
567
+ | `qsv-transcode` | [✓](https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/qsv_transcode.c) | | |
568
+ | `vaapi-encode` | [✓](https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/vaapi_encode.c) | | |
569
+ | `vaapi-transcode` | [✓](https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/vaapi_transcode.c) | | |
570
+ | `mux` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/mux.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/mux.ts) | |
571
+ | `remux` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/remux.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/remux.ts) | |
572
+ | `resample-audio` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/resample_audio.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/resample-audio.ts) | |
573
+ | `rtsp-stream-info` | | [✓](https://github.com/seydx/node-av/tree/main/examples/rtsp-stream-info.ts) | |
574
+ | `scale-video` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/scale_video.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/scale-video.ts) | |
575
+ | `show-metadata` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/show_metadata.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/show-metadata.ts) | |
576
+ | `transcode-aac` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/transcode_aac.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/transcode-aac.ts) | |
577
+ | `transcode` | [✓](https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples/transcode.c) | [✓](https://github.com/seydx/node-av/tree/main/examples/transcode.ts) | |
578
+
579
+ ## Prebuilt Binaries
580
+
581
+ Prebuilt binaries are available for multiple platforms:
582
+
583
+ - **macOS**: x64, ARM64
584
+ - **Linux**: x64, ARM64
585
+ - **Windows**: x64, ARM64 (automatic MSVC/MinGW selection)
586
+
587
+ ## Troubleshooting
588
+
589
+ ### Hardware Acceleration on Linux (Intel/VAAPI)
590
+
591
+ For hardware-accelerated video processing with Intel GPUs on Linux, you need to install specific system packages. The FFmpeg binaries included with this library are built with **libva 2.20**, which requires **Ubuntu 24.04+** or **Debian 13+** as minimum OS versions.
592
+
593
+ #### Installation Steps
594
+
595
+ 1. **Add Kisak-Mesa PPA** (recommended for newer Mesa versions with better hardware support):
596
+
597
+ ```bash
598
+ sudo add-apt-repository ppa:kisak/kisak-mesa
599
+ sudo apt update
600
+ ```
601
+
602
+ 2. **Install required packages**:
603
+
604
+ ```bash
605
+ sudo apt install libmfx-gen1.2 mesa-va-drivers mesa-vulkan-drivers libva2 libva-drm2 vainfo libvulkan1 vulkan-tools
606
+ ```
607
+
608
+ After installation, verify hardware acceleration is working:
609
+
610
+ ```bash
611
+ # Check VAAPI support
612
+ vainfo
613
+
614
+ # Check Vulkan support
615
+ vulkaninfo
616
+
617
+ # Should show available profiles and entrypoints for your Intel GPU
618
+ ```
619
+
620
+ **Note**: If you're running an older Ubuntu version (< 24.04) or Debian version (< 13), you'll need to upgrade your OS to use hardware acceleration with this library.
621
+
622
+ ## License
623
+
624
+ This project is licensed under the MIT License. See the LICENSE file for details.
625
+
626
+ **Important**: FFmpeg itself is licensed under LGPL/GPL. Please ensure compliance with FFmpeg's license terms when using this library. The FFmpeg libraries themselves retain their original licenses, and this wrapper library does not change those terms. See [FFmpeg License](https://ffmpeg.org/legal.html) for details.
627
+
628
+ ## Contributing
629
+
630
+ Contributions are welcome! Please read [CONTRIBUTING.md](https://github.com/seydx/node-av/tree/main/CONTRIBUTING.md) for development setup, code standards, and contribution guidelines before submitting pull requests.
631
+
632
+ ## Support
633
+
634
+ For issues and questions, please use the GitHub issue tracker.
635
+
636
+ ## See Also
637
+
638
+ - [FFmpeg Documentation](https://ffmpeg.org/documentation.html)
639
+ - [FFmpeg Doxygen](https://ffmpeg.org/doxygen/trunk/)
640
+ - [Jellyfin FFmpeg](https://github.com/seydx/jellyfin-ffmpeg)
641
+ - [FFmpeg MSVC](https://github.com/seydx/ffmpeg-msvc-prebuilt)
642
+
643
+ ## Star History
644
+
645
+ <picture>
646
+ <source
647
+ media="(prefers-color-scheme: dark)"
648
+ srcset="
649
+ https://api.star-history.com/svg?repos=seydx/node-av&type=Date&theme=dark
650
+ "
651
+ />
652
+ <source
653
+ media="(prefers-color-scheme: light)"
654
+ srcset="
655
+ https://api.star-history.com/svg?repos=seydx/node-av&type=Date
656
+ "
657
+ />
658
+ <img
659
+ alt="Star History Chart"
660
+ src="https://api.star-history.com/svg?repos=seydx/node-av&type=Date"
661
+ />
662
+ </picture>