node-av 0.0.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 (175) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/LICENSE.md +22 -0
  3. package/README.md +377 -0
  4. package/binding.gyp +78 -0
  5. package/dist/api/bitstream-filter.d.ts +246 -0
  6. package/dist/api/bitstream-filter.js +369 -0
  7. package/dist/api/bitstream-filter.js.map +1 -0
  8. package/dist/api/decoder.d.ts +257 -0
  9. package/dist/api/decoder.js +424 -0
  10. package/dist/api/decoder.js.map +1 -0
  11. package/dist/api/encoder.d.ts +298 -0
  12. package/dist/api/encoder.js +574 -0
  13. package/dist/api/encoder.js.map +1 -0
  14. package/dist/api/filter.d.ts +457 -0
  15. package/dist/api/filter.js +876 -0
  16. package/dist/api/filter.js.map +1 -0
  17. package/dist/api/hardware.d.ts +318 -0
  18. package/dist/api/hardware.js +558 -0
  19. package/dist/api/hardware.js.map +1 -0
  20. package/dist/api/index.d.ts +12 -0
  21. package/dist/api/index.js +20 -0
  22. package/dist/api/index.js.map +1 -0
  23. package/dist/api/io-stream.d.ts +109 -0
  24. package/dist/api/io-stream.js +124 -0
  25. package/dist/api/io-stream.js.map +1 -0
  26. package/dist/api/media-input.d.ts +295 -0
  27. package/dist/api/media-input.js +456 -0
  28. package/dist/api/media-input.js.map +1 -0
  29. package/dist/api/media-output.d.ts +274 -0
  30. package/dist/api/media-output.js +486 -0
  31. package/dist/api/media-output.js.map +1 -0
  32. package/dist/api/pipeline.d.ts +117 -0
  33. package/dist/api/pipeline.js +836 -0
  34. package/dist/api/pipeline.js.map +1 -0
  35. package/dist/api/types.d.ts +440 -0
  36. package/dist/api/types.js +2 -0
  37. package/dist/api/types.js.map +1 -0
  38. package/dist/api/utilities/audio-sample.d.ts +115 -0
  39. package/dist/api/utilities/audio-sample.js +110 -0
  40. package/dist/api/utilities/audio-sample.js.map +1 -0
  41. package/dist/api/utilities/channel-layout.d.ts +83 -0
  42. package/dist/api/utilities/channel-layout.js +87 -0
  43. package/dist/api/utilities/channel-layout.js.map +1 -0
  44. package/dist/api/utilities/image.d.ts +177 -0
  45. package/dist/api/utilities/image.js +183 -0
  46. package/dist/api/utilities/image.js.map +1 -0
  47. package/dist/api/utilities/index.d.ts +8 -0
  48. package/dist/api/utilities/index.js +17 -0
  49. package/dist/api/utilities/index.js.map +1 -0
  50. package/dist/api/utilities/media-type.d.ts +56 -0
  51. package/dist/api/utilities/media-type.js +60 -0
  52. package/dist/api/utilities/media-type.js.map +1 -0
  53. package/dist/api/utilities/pixel-format.d.ts +94 -0
  54. package/dist/api/utilities/pixel-format.js +102 -0
  55. package/dist/api/utilities/pixel-format.js.map +1 -0
  56. package/dist/api/utilities/sample-format.d.ts +132 -0
  57. package/dist/api/utilities/sample-format.js +144 -0
  58. package/dist/api/utilities/sample-format.js.map +1 -0
  59. package/dist/api/utilities/streaming.d.ts +104 -0
  60. package/dist/api/utilities/streaming.js +137 -0
  61. package/dist/api/utilities/streaming.js.map +1 -0
  62. package/dist/api/utilities/timestamp.d.ts +187 -0
  63. package/dist/api/utilities/timestamp.js +200 -0
  64. package/dist/api/utilities/timestamp.js.map +1 -0
  65. package/dist/api/utils.d.ts +61 -0
  66. package/dist/api/utils.js +330 -0
  67. package/dist/api/utils.js.map +1 -0
  68. package/dist/index.d.ts +2 -0
  69. package/dist/index.js +5 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/lib/audio-fifo.d.ts +339 -0
  72. package/dist/lib/audio-fifo.js +365 -0
  73. package/dist/lib/audio-fifo.js.map +1 -0
  74. package/dist/lib/binding.d.ts +192 -0
  75. package/dist/lib/binding.js +70 -0
  76. package/dist/lib/binding.js.map +1 -0
  77. package/dist/lib/bitstream-filter-context.d.ts +345 -0
  78. package/dist/lib/bitstream-filter-context.js +407 -0
  79. package/dist/lib/bitstream-filter-context.js.map +1 -0
  80. package/dist/lib/bitstream-filter.d.ts +124 -0
  81. package/dist/lib/bitstream-filter.js +138 -0
  82. package/dist/lib/bitstream-filter.js.map +1 -0
  83. package/dist/lib/channel-layouts.d.ts +51 -0
  84. package/dist/lib/channel-layouts.js +55 -0
  85. package/dist/lib/channel-layouts.js.map +1 -0
  86. package/dist/lib/codec-context.d.ts +763 -0
  87. package/dist/lib/codec-context.js +974 -0
  88. package/dist/lib/codec-context.js.map +1 -0
  89. package/dist/lib/codec-parameters.d.ts +362 -0
  90. package/dist/lib/codec-parameters.js +460 -0
  91. package/dist/lib/codec-parameters.js.map +1 -0
  92. package/dist/lib/codec-parser.d.ts +185 -0
  93. package/dist/lib/codec-parser.js +193 -0
  94. package/dist/lib/codec-parser.js.map +1 -0
  95. package/dist/lib/codec.d.ts +432 -0
  96. package/dist/lib/codec.js +492 -0
  97. package/dist/lib/codec.js.map +1 -0
  98. package/dist/lib/constants.d.ts +2037 -0
  99. package/dist/lib/constants.js +1659 -0
  100. package/dist/lib/constants.js.map +1 -0
  101. package/dist/lib/dictionary.d.ts +371 -0
  102. package/dist/lib/dictionary.js +406 -0
  103. package/dist/lib/dictionary.js.map +1 -0
  104. package/dist/lib/error.d.ts +216 -0
  105. package/dist/lib/error.js +254 -0
  106. package/dist/lib/error.js.map +1 -0
  107. package/dist/lib/filter-context.d.ts +445 -0
  108. package/dist/lib/filter-context.js +505 -0
  109. package/dist/lib/filter-context.js.map +1 -0
  110. package/dist/lib/filter-graph.d.ts +556 -0
  111. package/dist/lib/filter-graph.js +608 -0
  112. package/dist/lib/filter-graph.js.map +1 -0
  113. package/dist/lib/filter-inout.d.ts +205 -0
  114. package/dist/lib/filter-inout.js +264 -0
  115. package/dist/lib/filter-inout.js.map +1 -0
  116. package/dist/lib/filter.d.ts +231 -0
  117. package/dist/lib/filter.js +260 -0
  118. package/dist/lib/filter.js.map +1 -0
  119. package/dist/lib/format-context.d.ts +798 -0
  120. package/dist/lib/format-context.js +845 -0
  121. package/dist/lib/format-context.js.map +1 -0
  122. package/dist/lib/frame.d.ts +784 -0
  123. package/dist/lib/frame.js +933 -0
  124. package/dist/lib/frame.js.map +1 -0
  125. package/dist/lib/hardware-device-context.d.ts +407 -0
  126. package/dist/lib/hardware-device-context.js +429 -0
  127. package/dist/lib/hardware-device-context.js.map +1 -0
  128. package/dist/lib/hardware-frames-context.d.ts +374 -0
  129. package/dist/lib/hardware-frames-context.js +430 -0
  130. package/dist/lib/hardware-frames-context.js.map +1 -0
  131. package/dist/lib/index.d.ts +31 -0
  132. package/dist/lib/index.js +54 -0
  133. package/dist/lib/index.js.map +1 -0
  134. package/dist/lib/input-format.d.ts +216 -0
  135. package/dist/lib/input-format.js +246 -0
  136. package/dist/lib/input-format.js.map +1 -0
  137. package/dist/lib/io-context.d.ts +495 -0
  138. package/dist/lib/io-context.js +550 -0
  139. package/dist/lib/io-context.js.map +1 -0
  140. package/dist/lib/log.d.ts +201 -0
  141. package/dist/lib/log.js +219 -0
  142. package/dist/lib/log.js.map +1 -0
  143. package/dist/lib/native-types.d.ts +719 -0
  144. package/dist/lib/native-types.js +2 -0
  145. package/dist/lib/native-types.js.map +1 -0
  146. package/dist/lib/option.d.ts +589 -0
  147. package/dist/lib/option.js +853 -0
  148. package/dist/lib/option.js.map +1 -0
  149. package/dist/lib/output-format.d.ts +179 -0
  150. package/dist/lib/output-format.js +205 -0
  151. package/dist/lib/output-format.js.map +1 -0
  152. package/dist/lib/packet.d.ts +487 -0
  153. package/dist/lib/packet.js +558 -0
  154. package/dist/lib/packet.js.map +1 -0
  155. package/dist/lib/rational.d.ts +210 -0
  156. package/dist/lib/rational.js +233 -0
  157. package/dist/lib/rational.js.map +1 -0
  158. package/dist/lib/software-resample-context.d.ts +572 -0
  159. package/dist/lib/software-resample-context.js +610 -0
  160. package/dist/lib/software-resample-context.js.map +1 -0
  161. package/dist/lib/software-scale-context.d.ts +290 -0
  162. package/dist/lib/software-scale-context.js +308 -0
  163. package/dist/lib/software-scale-context.js.map +1 -0
  164. package/dist/lib/stream.d.ts +322 -0
  165. package/dist/lib/stream.js +408 -0
  166. package/dist/lib/stream.js.map +1 -0
  167. package/dist/lib/types.d.ts +59 -0
  168. package/dist/lib/types.js +8 -0
  169. package/dist/lib/types.js.map +1 -0
  170. package/dist/lib/utilities.d.ts +346 -0
  171. package/dist/lib/utilities.js +424 -0
  172. package/dist/lib/utilities.js.map +1 -0
  173. package/install/check.js +113 -0
  174. package/install/ffmpeg.js +163 -0
  175. package/package.json +107 -0
@@ -0,0 +1,424 @@
1
+ /**
2
+ * FFmpeg utility functions collection.
3
+ *
4
+ * Provides direct mappings to various FFmpeg utility functions from libavutil.
5
+ * These functions handle common operations like timestamp conversion, image buffer
6
+ * allocation, sample format queries, and more.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { avImageAlloc, avTs2TimeStr, avRescaleQ, FFmpegError } from 'node-av';
11
+ * import { AV_PIX_FMT_YUV420P, IRational } from 'node-av';
12
+ *
13
+ * // Allocate image buffer
14
+ * const image = avImageAlloc(1920, 1080, AV_PIX_FMT_YUV420P, 32);
15
+ * console.log(`Allocated ${image.size} bytes`);
16
+ *
17
+ * // Convert timestamp to readable time
18
+ * const timebase: IRational = { num: 1, den: 90000 };
19
+ * const pts = 450000n;
20
+ * console.log(avTs2TimeStr(pts, timebase)); // "5.000000"
21
+ * ```
22
+ */
23
+ import { bindings } from './binding.js';
24
+ import { FFmpegError } from './error.js';
25
+ /**
26
+ * Get bytes per sample for a sample format.
27
+ *
28
+ * Returns the number of bytes required to store one sample in the given format.
29
+ *
30
+ * Direct mapping to av_get_bytes_per_sample()
31
+ *
32
+ * @param sampleFmt - Audio sample format
33
+ *
34
+ * @returns Number of bytes per sample, or 0 for invalid format
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * import { avGetBytesPerSample, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT } from 'node-av';
39
+ *
40
+ * console.log(avGetBytesPerSample(AV_SAMPLE_FMT_S16)); // 2
41
+ * console.log(avGetBytesPerSample(AV_SAMPLE_FMT_FLT)); // 4
42
+ * ```
43
+ */
44
+ export function avGetBytesPerSample(sampleFmt) {
45
+ return bindings.avGetBytesPerSample(sampleFmt);
46
+ }
47
+ /**
48
+ * Get the name of a sample format.
49
+ *
50
+ * Returns a string describing the sample format.
51
+ *
52
+ * Direct mapping to av_get_sample_fmt_name()
53
+ *
54
+ * @param sampleFmt - Audio sample format
55
+ *
56
+ * @returns Format name string, or null for invalid format
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * import { avGetSampleFmtName, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLTP } from 'node-av';
61
+ *
62
+ * console.log(avGetSampleFmtName(AV_SAMPLE_FMT_S16)); // "s16"
63
+ * console.log(avGetSampleFmtName(AV_SAMPLE_FMT_FLTP)); // "fltp"
64
+ * ```
65
+ */
66
+ export function avGetSampleFmtName(sampleFmt) {
67
+ return bindings.avGetSampleFmtName(sampleFmt);
68
+ }
69
+ /**
70
+ * Get packed sample format
71
+ * Direct mapping to av_get_packed_sample_fmt()
72
+ */
73
+ export function avGetPackedSampleFmt(sampleFmt) {
74
+ return bindings.avGetPackedSampleFmt(sampleFmt);
75
+ }
76
+ /**
77
+ * Get planar sample format
78
+ * Direct mapping to av_get_planar_sample_fmt()
79
+ */
80
+ export function avGetPlanarSampleFmt(sampleFmt) {
81
+ return bindings.avGetPlanarSampleFmt(sampleFmt);
82
+ }
83
+ /**
84
+ * Check if sample format is planar
85
+ * Direct mapping to av_sample_fmt_is_planar()
86
+ */
87
+ export function avSampleFmtIsPlanar(sampleFmt) {
88
+ return bindings.avSampleFmtIsPlanar(sampleFmt);
89
+ }
90
+ /**
91
+ * Get pixel format name
92
+ * Direct mapping to av_get_pix_fmt_name()
93
+ */
94
+ export function avGetPixFmtName(pixFmt) {
95
+ return bindings.avGetPixFmtName(pixFmt);
96
+ }
97
+ /**
98
+ * Get pixel format from name
99
+ * Direct mapping to av_get_pix_fmt()
100
+ */
101
+ export function avGetPixFmtFromName(name) {
102
+ return bindings.avGetPixFmtFromName(name);
103
+ }
104
+ /**
105
+ * Check if a pixel format is hardware-accelerated
106
+ * Direct mapping using av_pix_fmt_desc_get() and AV_PIX_FMT_FLAG_HWACCEL
107
+ */
108
+ export function avIsHardwarePixelFormat(pixFmt) {
109
+ return bindings.avIsHardwarePixelFormat(pixFmt);
110
+ }
111
+ /**
112
+ * Get media type string
113
+ * Direct mapping to av_get_media_type_string()
114
+ */
115
+ export function avGetMediaTypeString(mediaType) {
116
+ return bindings.avGetMediaTypeString(mediaType);
117
+ }
118
+ /**
119
+ * Allocate an image with size, pixel format and alignment.
120
+ *
121
+ * Allocates a buffer large enough to hold an image with the given parameters.
122
+ * The allocated buffer is properly aligned for optimal performance.
123
+ *
124
+ * Direct mapping to av_image_alloc()
125
+ *
126
+ * @param width - Image width in pixels
127
+ * @param height - Image height in pixels
128
+ * @param pixFmt - Pixel format
129
+ * @param align - Buffer alignment (1 for no alignment, 32 for SIMD)
130
+ *
131
+ * @returns Object containing:
132
+ * - buffer: Allocated image buffer
133
+ * - size: Total size in bytes
134
+ * - linesizes: Array of line sizes for each plane
135
+ *
136
+ * @throws {Error} If allocation fails
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * import { avImageAlloc, AV_PIX_FMT_YUV420P, FFmpegError } from 'node-av';
141
+ *
142
+ * try {
143
+ * const result = avImageAlloc(1920, 1080, AV_PIX_FMT_YUV420P, 32);
144
+ * console.log(`Allocated ${result.size} bytes`);
145
+ * console.log(`Y linesize: ${result.linesizes[0]}`);
146
+ * // Use result.buffer for image data
147
+ * } catch (error) {
148
+ * console.error('Failed to allocate image buffer');
149
+ * }
150
+ * ```
151
+ *
152
+ * @see {@link avImageGetBufferSize} To calculate required size without allocating
153
+ */
154
+ export function avImageAlloc(width, height, pixFmt, align) {
155
+ const result = bindings.avImageAlloc(width, height, pixFmt, align);
156
+ if (typeof result === 'number') {
157
+ // Error code returned instead of object
158
+ throw new FFmpegError(result);
159
+ }
160
+ return result;
161
+ }
162
+ /**
163
+ * Copy image data from src to dst
164
+ * Direct mapping to av_image_copy2()
165
+ *
166
+ * @param dstData - Destination data buffers (one per plane)
167
+ * @param dstLinesizes - Destination line sizes
168
+ * @param srcData - Source data buffers (one per plane)
169
+ * @param srcLinesizes - Source line sizes
170
+ * @param pixFmt - Pixel format
171
+ * @param width - Image width
172
+ * @param height - Image height
173
+ */
174
+ export function avImageCopy2(dstData, dstLinesizes, srcData, srcLinesizes, pixFmt, width, height) {
175
+ bindings.avImageCopy2(dstData, dstLinesizes, srcData, srcLinesizes, pixFmt, width, height);
176
+ }
177
+ /**
178
+ * Get the required buffer size for an image
179
+ * Direct mapping to av_image_get_buffer_size()
180
+ *
181
+ * @returns The required buffer size in bytes, or negative on error
182
+ */
183
+ export function avImageGetBufferSize(pixFmt, width, height, align) {
184
+ return bindings.avImageGetBufferSize(pixFmt, width, height, align);
185
+ }
186
+ /**
187
+ * Copy image data to a single buffer.
188
+ *
189
+ * Copies image data from separate planes into a single continuous buffer.
190
+ * Useful for serialization or when a single buffer is required.
191
+ *
192
+ * Direct mapping to av_image_copy_to_buffer()
193
+ *
194
+ * @param dst - Destination buffer
195
+ * @param dstSize - Size of destination buffer in bytes
196
+ * @param srcData - Array of source data planes
197
+ * @param srcLinesize - Array of source linesizes
198
+ * @param pixFmt - Pixel format
199
+ * @param width - Image width in pixels
200
+ * @param height - Image height in pixels
201
+ * @param align - Buffer alignment
202
+ *
203
+ * @returns Number of bytes written to dst, or negative AVERROR on error:
204
+ * - >0: Number of bytes written
205
+ * - AVERROR(EINVAL): Invalid parameters
206
+ * - AVERROR(ENOMEM): Destination buffer too small
207
+ *
208
+ * @example
209
+ * ```typescript
210
+ * import { avImageCopyToBuffer, avImageGetBufferSize, FFmpegError } from 'node-av';
211
+ * import { AV_PIX_FMT_RGB24 } from 'node-av';
212
+ *
213
+ * const width = 640, height = 480;
214
+ * const pixFmt = AV_PIX_FMT_RGB24;
215
+ *
216
+ * // Calculate required buffer size
217
+ * const dstSize = avImageGetBufferSize(pixFmt, width, height, 1);
218
+ * const dst = Buffer.alloc(dstSize);
219
+ *
220
+ * const ret = avImageCopyToBuffer(
221
+ * dst, dstSize,
222
+ * srcData, srcLinesize,
223
+ * pixFmt, width, height, 1
224
+ * );
225
+ *
226
+ * FFmpegError.throwIfError(ret, 'avImageCopyToBuffer');
227
+ * console.log(`Copied ${ret} bytes to buffer`);
228
+ * ```
229
+ */
230
+ export function avImageCopyToBuffer(dst, dstSize, srcData, srcLinesize, pixFmt, width, height, align) {
231
+ return bindings.avImageCopyToBuffer(dst, dstSize, srcData, srcLinesize, pixFmt, width, height, align);
232
+ }
233
+ /**
234
+ * Convert timestamp to string
235
+ * Direct mapping to av_ts2str()
236
+ */
237
+ export function avTs2Str(ts) {
238
+ return bindings.avTs2Str(ts);
239
+ }
240
+ /**
241
+ * Convert timestamp to time string
242
+ * Direct mapping to av_ts2timestr()
243
+ */
244
+ export function avTs2TimeStr(ts, timeBase) {
245
+ if (!timeBase) {
246
+ return avTs2Str(ts);
247
+ }
248
+ return bindings.avTs2TimeStr(ts, timeBase);
249
+ }
250
+ /**
251
+ * Helper to separate image allocation result into separate arrays
252
+ * This is useful when you need separate data and linesize arrays
253
+ */
254
+ export function avImageAllocArrays(width, height, pixFmt, align) {
255
+ const result = avImageAlloc(width, height, pixFmt, align);
256
+ // Split the buffer into planes based on pixel format
257
+ const data = [];
258
+ const linesizes = result.linesizes;
259
+ // For now, we'll treat it as a single buffer
260
+ // In a real implementation, we'd need to know the plane layout for each pixel format
261
+ data[0] = result.buffer;
262
+ return {
263
+ data,
264
+ linesizes,
265
+ size: result.size,
266
+ };
267
+ }
268
+ /**
269
+ * Compare two timestamps
270
+ * Direct mapping to av_compare_ts()
271
+ *
272
+ * @returns -1 if tsA < tsB, 0 if tsA == tsB, 1 if tsA > tsB
273
+ */
274
+ export function avCompareTs(tsA, tbA, tsB, tbB) {
275
+ return bindings.avCompareTs(tsA, tbA, tsB, tbB);
276
+ }
277
+ /**
278
+ * Rescale a timestamp from one timebase to another
279
+ * Direct mapping to av_rescale_q()
280
+ */
281
+ export function avRescaleQ(a, bq, cq) {
282
+ return bindings.avRescaleQ(a, bq, cq);
283
+ }
284
+ /**
285
+ * Sleep for a specified number of microseconds.
286
+ *
287
+ * Provides a cross-platform microsecond sleep function.
288
+ * Useful for timing operations or frame pacing.
289
+ *
290
+ * Direct mapping to av_usleep()
291
+ *
292
+ * @param usec - Number of microseconds to sleep
293
+ *
294
+ * @example
295
+ * ```typescript
296
+ * import { avUsleep } from 'node-av';
297
+ *
298
+ * // Sleep for 100ms (100,000 microseconds)
299
+ * avUsleep(100000);
300
+ *
301
+ * // Sleep for 1 second
302
+ * avUsleep(1000000);
303
+ *
304
+ * // Frame pacing for 30fps (33.33ms per frame)
305
+ * const frameTime = 1000000 / 30;
306
+ * avUsleep(frameTime);
307
+ * ```
308
+ */
309
+ export function avUsleep(usec) {
310
+ bindings.avUsleep(usec);
311
+ }
312
+ /**
313
+ * Rescale a timestamp with rounding
314
+ * Direct mapping to av_rescale_rnd()
315
+ *
316
+ * @param a - Value to rescale
317
+ * @param b - Numerator of scale factor
318
+ * @param c - Denominator of scale factor
319
+ * @param rnd - Rounding mode (AVRounding enum)
320
+ * @returns Rescaled value
321
+ */
322
+ export function avRescaleRnd(a, b, c, rnd) {
323
+ return bindings.avRescaleRnd(a, b, c, rnd);
324
+ }
325
+ /**
326
+ * Allocate audio sample buffers
327
+ * Direct mapping to av_samples_alloc()
328
+ *
329
+ * @param nbChannels - Number of channels
330
+ * @param nbSamples - Number of samples per channel
331
+ * @param sampleFmt - Sample format
332
+ * @param align - Buffer alignment (0 for default)
333
+ * @returns Object with allocated data buffers, linesize and total size, or error code
334
+ */
335
+ export function avSamplesAlloc(nbChannels, nbSamples, sampleFmt, align) {
336
+ const result = bindings.avSamplesAlloc(nbChannels, nbSamples, sampleFmt, align);
337
+ if (typeof result === 'number') {
338
+ throw new FFmpegError(result);
339
+ }
340
+ return result;
341
+ }
342
+ /**
343
+ * Get the required buffer size for audio samples
344
+ * Direct mapping to av_samples_get_buffer_size()
345
+ *
346
+ * @param nbChannels - Number of channels
347
+ * @param nbSamples - Number of samples per channel
348
+ * @param sampleFmt - Sample format
349
+ * @param align - Buffer alignment (0 for default)
350
+ * @returns Object with size and linesize, or error code
351
+ */
352
+ export function avSamplesGetBufferSize(nbChannels, nbSamples, sampleFmt, align) {
353
+ const result = bindings.avSamplesGetBufferSize(nbChannels, nbSamples, sampleFmt, align);
354
+ if (typeof result === 'number') {
355
+ throw new FFmpegError(result);
356
+ }
357
+ return result;
358
+ }
359
+ /**
360
+ * Get a string description of a channel layout.
361
+ * Direct mapping to av_channel_layout_describe()
362
+ *
363
+ * @param channelLayout - The channel layout object with order, nbChannels, and mask
364
+ * @returns String description of the channel layout, or null if invalid
365
+ */
366
+ export function avChannelLayoutDescribe(channelLayout) {
367
+ return bindings.avChannelLayoutDescribe(channelLayout);
368
+ }
369
+ /**
370
+ * Create an SDP (Session Description Protocol) string for RTP/RTSP streaming.
371
+ *
372
+ * Generates an SDP description from one or more FormatContext objects.
373
+ * Useful for RTP/RTSP streaming scenarios where you need to describe
374
+ * the media streams to clients.
375
+ *
376
+ * Direct mapping to av_sdp_create()
377
+ *
378
+ * @param contexts - Array of FormatContext objects to describe
379
+ * @returns SDP string on success, or null on failure
380
+ *
381
+ * @throws {FFmpegError} On invalid parameters or SDP creation failure
382
+ *
383
+ * @example
384
+ * ```typescript
385
+ * import { avSdpCreate, FormatContext, FFmpegError } from 'node-av';
386
+ *
387
+ * // Create format contexts for RTP output
388
+ * const contexts: FormatContext[] = [];
389
+ *
390
+ * const ctx = new FormatContext();
391
+ * // ... configure context for RTP output ...
392
+ * contexts.push(ctx);
393
+ *
394
+ * // Generate SDP
395
+ * const sdp = avSdpCreate(contexts);
396
+ * if (sdp) {
397
+ * console.log('SDP:', result);
398
+ * }
399
+ *
400
+ * // Use the SDP string for RTSP server or save to .sdp file
401
+ * ```
402
+ */
403
+ export function avSdpCreate(contexts) {
404
+ if (!Array.isArray(contexts) || contexts.length === 0) {
405
+ return null;
406
+ }
407
+ // Pass the native objects to the binding
408
+ const nativeContexts = contexts
409
+ .map((ctx) => {
410
+ if (ctx && typeof ctx.getNative === 'function') {
411
+ const nativeCtx = ctx.getNative();
412
+ if (nativeCtx) {
413
+ return nativeCtx;
414
+ }
415
+ }
416
+ })
417
+ .filter((ctx) => ctx !== undefined);
418
+ // If no valid contexts after filtering, return null
419
+ if (nativeContexts.length === 0) {
420
+ return null;
421
+ }
422
+ return bindings.avSdpCreate(nativeContexts);
423
+ }
424
+ //# sourceMappingURL=utilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utilities.js","sourceRoot":"","sources":["../../src/lib/utilities.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { getFFmpegLibraryVersions, globalFFmpegVersion, log, spawnRebuild, useGlobalFFmpeg } from './ffmpeg.js';
4
+
5
+ const buildFromSource = async (msg) => {
6
+ log(msg);
7
+ log('Building from source requires:');
8
+ log(' - FFmpeg 7.1+ with development headers');
9
+ log(' - Python 3.12+');
10
+ log(' - node-gyp and node-addon-api');
11
+
12
+ // Check for node-addon-api and node-gyp
13
+ let hasNodeAddonApi = false;
14
+ let hasNodeGyp = false;
15
+
16
+ try {
17
+ // @ts-expect-error
18
+ await import('node-addon-api');
19
+ hasNodeAddonApi = true;
20
+ } catch {
21
+ // Not installed
22
+ }
23
+
24
+ try {
25
+ // @ts-expect-error
26
+ await import('node-gyp');
27
+ hasNodeGyp = true;
28
+ } catch {
29
+ // Not installed
30
+ }
31
+
32
+ if (!hasNodeAddonApi || !hasNodeGyp) {
33
+ log('');
34
+ log('Missing build dependencies. Please install:');
35
+ log(' npm install --save-dev node-addon-api node-gyp');
36
+ log('');
37
+ log('Then run npm install again.');
38
+ process.exit(1);
39
+ }
40
+
41
+ log('Found required build dependencies');
42
+ log('Building native bindings...');
43
+
44
+ const status = spawnRebuild();
45
+ if (status !== 0) {
46
+ log('Build failed. Please ensure you have:');
47
+ log(' - FFmpeg 7.1+ libraries and headers installed');
48
+ log(' - Python 3.12+ installed');
49
+ log(' - A C++ compiler with C++17 support');
50
+ log('See https://github.com/seydx/av for detailed requirements');
51
+ process.exit(status);
52
+ }
53
+ };
54
+
55
+ (async () => {
56
+ try {
57
+ // Check if we should build from source
58
+ const shouldBuildFromSource = process.env.npm_config_build_from_source;
59
+
60
+ // Try to load the prebuilt binary first (unless explicitly building from source)
61
+ if (!shouldBuildFromSource) {
62
+ try {
63
+ // Check if platform-specific package exists (optionalDependencies)
64
+ const platform = process.platform;
65
+ const arch = process.arch;
66
+ const packageName = `@seydx/node-av-${platform}-${arch}`;
67
+
68
+ // Try to resolve the package
69
+ await import(`${packageName}/package.json`);
70
+ log(`Using prebuilt binary from ${packageName}`);
71
+ return;
72
+ } catch {
73
+ // No prebuilt binary available, will build from source
74
+ }
75
+ }
76
+
77
+ // No prebuilt binary or --build-from-source flag, check for system FFmpeg
78
+ if (useGlobalFFmpeg(log)) {
79
+ const versions = getFFmpegLibraryVersions();
80
+ if (versions && versions.length > 0) {
81
+ log('Detected globally-installed FFmpeg libraries:');
82
+ for (const lib of versions) {
83
+ log(` ✓ ${lib.name.padEnd(20)} v${lib.version} (${lib.description})`);
84
+ }
85
+ await buildFromSource('Building with system FFmpeg');
86
+ } else {
87
+ await buildFromSource(`Detected globally-installed FFmpeg v${globalFFmpegVersion()}`);
88
+ }
89
+ } else {
90
+ // No system FFmpeg found
91
+ if (shouldBuildFromSource) {
92
+ log('--build-from-source specified but no FFmpeg libraries found');
93
+ log('Please install FFmpeg 7.1+ with development headers');
94
+ process.exit(1);
95
+ } else {
96
+ log('No prebuilt binary available for your platform');
97
+ log('No system FFmpeg libraries found (requires v7.1+)');
98
+ log('');
99
+ log('Please install FFmpeg 7.1+ and build dependencies:');
100
+ log(' - FFmpeg development libraries');
101
+ log(' - Python 3.12+');
102
+ log(' - npm install --save-dev node-addon-api node-gyp');
103
+ log('');
104
+ log('Then run npm install again.');
105
+ process.exit(1);
106
+ }
107
+ }
108
+ } catch (err) {
109
+ const summary = err.message.split(/\n/).slice(0, 1);
110
+ console.log(`node-av: installation error: ${summary}`);
111
+ process.exit(1);
112
+ }
113
+ })();