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.
- package/CHANGELOG.md +8 -0
- package/LICENSE.md +22 -0
- package/README.md +377 -0
- package/binding.gyp +78 -0
- package/dist/api/bitstream-filter.d.ts +246 -0
- package/dist/api/bitstream-filter.js +369 -0
- package/dist/api/bitstream-filter.js.map +1 -0
- package/dist/api/decoder.d.ts +257 -0
- package/dist/api/decoder.js +424 -0
- package/dist/api/decoder.js.map +1 -0
- package/dist/api/encoder.d.ts +298 -0
- package/dist/api/encoder.js +574 -0
- package/dist/api/encoder.js.map +1 -0
- package/dist/api/filter.d.ts +457 -0
- package/dist/api/filter.js +876 -0
- package/dist/api/filter.js.map +1 -0
- package/dist/api/hardware.d.ts +318 -0
- package/dist/api/hardware.js +558 -0
- package/dist/api/hardware.js.map +1 -0
- package/dist/api/index.d.ts +12 -0
- package/dist/api/index.js +20 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/io-stream.d.ts +109 -0
- package/dist/api/io-stream.js +124 -0
- package/dist/api/io-stream.js.map +1 -0
- package/dist/api/media-input.d.ts +295 -0
- package/dist/api/media-input.js +456 -0
- package/dist/api/media-input.js.map +1 -0
- package/dist/api/media-output.d.ts +274 -0
- package/dist/api/media-output.js +486 -0
- package/dist/api/media-output.js.map +1 -0
- package/dist/api/pipeline.d.ts +117 -0
- package/dist/api/pipeline.js +836 -0
- package/dist/api/pipeline.js.map +1 -0
- package/dist/api/types.d.ts +440 -0
- package/dist/api/types.js +2 -0
- package/dist/api/types.js.map +1 -0
- package/dist/api/utilities/audio-sample.d.ts +115 -0
- package/dist/api/utilities/audio-sample.js +110 -0
- package/dist/api/utilities/audio-sample.js.map +1 -0
- package/dist/api/utilities/channel-layout.d.ts +83 -0
- package/dist/api/utilities/channel-layout.js +87 -0
- package/dist/api/utilities/channel-layout.js.map +1 -0
- package/dist/api/utilities/image.d.ts +177 -0
- package/dist/api/utilities/image.js +183 -0
- package/dist/api/utilities/image.js.map +1 -0
- package/dist/api/utilities/index.d.ts +8 -0
- package/dist/api/utilities/index.js +17 -0
- package/dist/api/utilities/index.js.map +1 -0
- package/dist/api/utilities/media-type.d.ts +56 -0
- package/dist/api/utilities/media-type.js +60 -0
- package/dist/api/utilities/media-type.js.map +1 -0
- package/dist/api/utilities/pixel-format.d.ts +94 -0
- package/dist/api/utilities/pixel-format.js +102 -0
- package/dist/api/utilities/pixel-format.js.map +1 -0
- package/dist/api/utilities/sample-format.d.ts +132 -0
- package/dist/api/utilities/sample-format.js +144 -0
- package/dist/api/utilities/sample-format.js.map +1 -0
- package/dist/api/utilities/streaming.d.ts +104 -0
- package/dist/api/utilities/streaming.js +137 -0
- package/dist/api/utilities/streaming.js.map +1 -0
- package/dist/api/utilities/timestamp.d.ts +187 -0
- package/dist/api/utilities/timestamp.js +200 -0
- package/dist/api/utilities/timestamp.js.map +1 -0
- package/dist/api/utils.d.ts +61 -0
- package/dist/api/utils.js +330 -0
- package/dist/api/utils.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/audio-fifo.d.ts +339 -0
- package/dist/lib/audio-fifo.js +365 -0
- package/dist/lib/audio-fifo.js.map +1 -0
- package/dist/lib/binding.d.ts +192 -0
- package/dist/lib/binding.js +70 -0
- package/dist/lib/binding.js.map +1 -0
- package/dist/lib/bitstream-filter-context.d.ts +345 -0
- package/dist/lib/bitstream-filter-context.js +407 -0
- package/dist/lib/bitstream-filter-context.js.map +1 -0
- package/dist/lib/bitstream-filter.d.ts +124 -0
- package/dist/lib/bitstream-filter.js +138 -0
- package/dist/lib/bitstream-filter.js.map +1 -0
- package/dist/lib/channel-layouts.d.ts +51 -0
- package/dist/lib/channel-layouts.js +55 -0
- package/dist/lib/channel-layouts.js.map +1 -0
- package/dist/lib/codec-context.d.ts +763 -0
- package/dist/lib/codec-context.js +974 -0
- package/dist/lib/codec-context.js.map +1 -0
- package/dist/lib/codec-parameters.d.ts +362 -0
- package/dist/lib/codec-parameters.js +460 -0
- package/dist/lib/codec-parameters.js.map +1 -0
- package/dist/lib/codec-parser.d.ts +185 -0
- package/dist/lib/codec-parser.js +193 -0
- package/dist/lib/codec-parser.js.map +1 -0
- package/dist/lib/codec.d.ts +432 -0
- package/dist/lib/codec.js +492 -0
- package/dist/lib/codec.js.map +1 -0
- package/dist/lib/constants.d.ts +2037 -0
- package/dist/lib/constants.js +1659 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/dictionary.d.ts +371 -0
- package/dist/lib/dictionary.js +406 -0
- package/dist/lib/dictionary.js.map +1 -0
- package/dist/lib/error.d.ts +216 -0
- package/dist/lib/error.js +254 -0
- package/dist/lib/error.js.map +1 -0
- package/dist/lib/filter-context.d.ts +445 -0
- package/dist/lib/filter-context.js +505 -0
- package/dist/lib/filter-context.js.map +1 -0
- package/dist/lib/filter-graph.d.ts +556 -0
- package/dist/lib/filter-graph.js +608 -0
- package/dist/lib/filter-graph.js.map +1 -0
- package/dist/lib/filter-inout.d.ts +205 -0
- package/dist/lib/filter-inout.js +264 -0
- package/dist/lib/filter-inout.js.map +1 -0
- package/dist/lib/filter.d.ts +231 -0
- package/dist/lib/filter.js +260 -0
- package/dist/lib/filter.js.map +1 -0
- package/dist/lib/format-context.d.ts +798 -0
- package/dist/lib/format-context.js +845 -0
- package/dist/lib/format-context.js.map +1 -0
- package/dist/lib/frame.d.ts +784 -0
- package/dist/lib/frame.js +933 -0
- package/dist/lib/frame.js.map +1 -0
- package/dist/lib/hardware-device-context.d.ts +407 -0
- package/dist/lib/hardware-device-context.js +429 -0
- package/dist/lib/hardware-device-context.js.map +1 -0
- package/dist/lib/hardware-frames-context.d.ts +374 -0
- package/dist/lib/hardware-frames-context.js +430 -0
- package/dist/lib/hardware-frames-context.js.map +1 -0
- package/dist/lib/index.d.ts +31 -0
- package/dist/lib/index.js +54 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/input-format.d.ts +216 -0
- package/dist/lib/input-format.js +246 -0
- package/dist/lib/input-format.js.map +1 -0
- package/dist/lib/io-context.d.ts +495 -0
- package/dist/lib/io-context.js +550 -0
- package/dist/lib/io-context.js.map +1 -0
- package/dist/lib/log.d.ts +201 -0
- package/dist/lib/log.js +219 -0
- package/dist/lib/log.js.map +1 -0
- package/dist/lib/native-types.d.ts +719 -0
- package/dist/lib/native-types.js +2 -0
- package/dist/lib/native-types.js.map +1 -0
- package/dist/lib/option.d.ts +589 -0
- package/dist/lib/option.js +853 -0
- package/dist/lib/option.js.map +1 -0
- package/dist/lib/output-format.d.ts +179 -0
- package/dist/lib/output-format.js +205 -0
- package/dist/lib/output-format.js.map +1 -0
- package/dist/lib/packet.d.ts +487 -0
- package/dist/lib/packet.js +558 -0
- package/dist/lib/packet.js.map +1 -0
- package/dist/lib/rational.d.ts +210 -0
- package/dist/lib/rational.js +233 -0
- package/dist/lib/rational.js.map +1 -0
- package/dist/lib/software-resample-context.d.ts +572 -0
- package/dist/lib/software-resample-context.js +610 -0
- package/dist/lib/software-resample-context.js.map +1 -0
- package/dist/lib/software-scale-context.d.ts +290 -0
- package/dist/lib/software-scale-context.js +308 -0
- package/dist/lib/software-scale-context.js.map +1 -0
- package/dist/lib/stream.d.ts +322 -0
- package/dist/lib/stream.js +408 -0
- package/dist/lib/stream.js.map +1 -0
- package/dist/lib/types.d.ts +59 -0
- package/dist/lib/types.js +8 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/utilities.d.ts +346 -0
- package/dist/lib/utilities.js +424 -0
- package/dist/lib/utilities.js.map +1 -0
- package/install/check.js +113 -0
- package/install/ffmpeg.js +163 -0
- 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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"}
|
package/install/check.js
ADDED
|
@@ -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
|
+
})();
|