@mediaway/ffi 0.1.0
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/dist/index.d.ts +244 -0
- package/dist/index.js +294 -0
- package/native/mediaway_ffi.dll +0 -0
- package/package.json +36 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @mediaway/ffi — internal koffi glue over Mediaway's C ABI.
|
|
3
|
+
*
|
|
4
|
+
* Not part of the public DX contract (bindings/nodejs/README.md): this package
|
|
5
|
+
* exists only so @mediaway/container, @mediaway/encoder, and @mediaway/device
|
|
6
|
+
* share one set of struct layouts and function bindings. Everything here maps
|
|
7
|
+
* 1:1 to `crates/mediaway-*-ffi/include/mediaway/*.h`.
|
|
8
|
+
*
|
|
9
|
+
* Ownership rules (from the headers):
|
|
10
|
+
* - Borrowed inputs (extra_data, packet payload, push_bytes data, frame
|
|
11
|
+
* bytes) are caller-owned, valid for the call only — we copy in/out.
|
|
12
|
+
* - Owned outputs (poll_bytes buffers, demuxed packets/stream info, finish
|
|
13
|
+
* buffers, polled device frames) MUST be released through the matching
|
|
14
|
+
* `_free` — the public packages do this automatically.
|
|
15
|
+
*/
|
|
16
|
+
export declare function findLibrary(name: string): string;
|
|
17
|
+
export declare const containerLib: import("koffi").LibraryHandle;
|
|
18
|
+
export declare const pipelineLib: import("koffi").LibraryHandle;
|
|
19
|
+
export declare const deviceLib: import("koffi").LibraryHandle;
|
|
20
|
+
export declare const MwRational: import("koffi").TypeObject;
|
|
21
|
+
export declare const MwVideoTrackInfo: import("koffi").TypeObject;
|
|
22
|
+
export declare const MwAudioTrackInfo: import("koffi").TypeObject;
|
|
23
|
+
export declare const MwPacketView: import("koffi").TypeObject;
|
|
24
|
+
export declare const MwPacket: import("koffi").TypeObject;
|
|
25
|
+
export declare const MwStreamInfo: import("koffi").TypeObject;
|
|
26
|
+
export declare const MwGpuDeviceHandle: import("koffi").TypeObject;
|
|
27
|
+
export declare const MwGpuBufferHandle: import("koffi").TypeObject;
|
|
28
|
+
export declare const MwEncConfig: import("koffi").TypeObject;
|
|
29
|
+
export declare const MwPipelineFrame: import("koffi").TypeObject;
|
|
30
|
+
export declare const MwCameraConfig: import("koffi").TypeObject;
|
|
31
|
+
export declare const MwCameraFrame: import("koffi").TypeObject;
|
|
32
|
+
export declare const MwDesktopConfig: import("koffi").TypeObject;
|
|
33
|
+
export declare const MwDesktopFrame: import("koffi").TypeObject;
|
|
34
|
+
export declare const MwAudioConfig: import("koffi").TypeObject;
|
|
35
|
+
export declare const MwAudioFrame: import("koffi").TypeObject;
|
|
36
|
+
export declare const MwAudioEncodeConfig: import("koffi").TypeObject;
|
|
37
|
+
export declare const MwAudioFrameView: import("koffi").TypeObject;
|
|
38
|
+
export declare const MwAudioPacket: import("koffi").TypeObject;
|
|
39
|
+
export declare const MwAudioStreamInfo: import("koffi").TypeObject;
|
|
40
|
+
export declare const container: {
|
|
41
|
+
abiVersion: import("koffi").Callable;
|
|
42
|
+
muxerCreate: import("koffi").Callable;
|
|
43
|
+
muxerCreateWithBatch: import("koffi").Callable;
|
|
44
|
+
muxerAddVideoTrack: import("koffi").Callable;
|
|
45
|
+
muxerAddAudioTrack: import("koffi").Callable;
|
|
46
|
+
muxerBegin: import("koffi").Callable;
|
|
47
|
+
muxerPushPacket: import("koffi").Callable;
|
|
48
|
+
muxerFlush: import("koffi").Callable;
|
|
49
|
+
muxerPollBytes: import("koffi").Callable;
|
|
50
|
+
muxerClose: import("koffi").Callable;
|
|
51
|
+
demuxerCreate: import("koffi").Callable;
|
|
52
|
+
demuxerPushBytes: import("koffi").Callable;
|
|
53
|
+
demuxerStreamCount: import("koffi").Callable;
|
|
54
|
+
demuxerStreamAt: import("koffi").Callable;
|
|
55
|
+
demuxerPollPacket: import("koffi").Callable;
|
|
56
|
+
demuxerSetDecryptionKey: import("koffi").Callable;
|
|
57
|
+
demuxerClearDecryptionKey: import("koffi").Callable;
|
|
58
|
+
demuxerClose: import("koffi").Callable;
|
|
59
|
+
bufferFree: import("koffi").Callable;
|
|
60
|
+
packetFree: import("koffi").Callable;
|
|
61
|
+
streamInfoFree: import("koffi").Callable;
|
|
62
|
+
};
|
|
63
|
+
export declare const pipeline: {
|
|
64
|
+
abiVersion: import("koffi").Callable;
|
|
65
|
+
encConfigNew: import("koffi").Callable;
|
|
66
|
+
encConfigH264: import("koffi").Callable;
|
|
67
|
+
autoEncoderOpen: import("koffi").Callable;
|
|
68
|
+
autoEncoderClose: import("koffi").Callable;
|
|
69
|
+
sessionOpen: import("koffi").Callable;
|
|
70
|
+
sessionWriteFrame: import("koffi").Callable;
|
|
71
|
+
sessionFinish: import("koffi").Callable;
|
|
72
|
+
sessionClose: import("koffi").Callable;
|
|
73
|
+
bufferFree: import("koffi").Callable;
|
|
74
|
+
audioConfigAac: import("koffi").Callable;
|
|
75
|
+
audioEncoderOpen: import("koffi").Callable;
|
|
76
|
+
audioPushPcm: import("koffi").Callable;
|
|
77
|
+
audioPollPacket: import("koffi").Callable;
|
|
78
|
+
audioFlush: import("koffi").Callable;
|
|
79
|
+
audioStreamInfo: import("koffi").Callable;
|
|
80
|
+
audioSessionClose: import("koffi").Callable;
|
|
81
|
+
pipelinePacketFree: import("koffi").Callable;
|
|
82
|
+
pipelineStreamInfoFree: import("koffi").Callable;
|
|
83
|
+
};
|
|
84
|
+
export declare const device: {
|
|
85
|
+
abiVersion: import("koffi").Callable;
|
|
86
|
+
cameraConfigDefault: import("koffi").Callable;
|
|
87
|
+
cameraOpen: import("koffi").Callable;
|
|
88
|
+
cameraGeometry: import("koffi").Callable;
|
|
89
|
+
cameraPollFrame: import("koffi").Callable;
|
|
90
|
+
cameraPollFrameBlocking: import("koffi").Callable;
|
|
91
|
+
cameraReleaseFrame: import("koffi").Callable;
|
|
92
|
+
cameraClose: import("koffi").Callable;
|
|
93
|
+
cameraFrameFree: import("koffi").Callable;
|
|
94
|
+
desktopConfigScreen: import("koffi").Callable;
|
|
95
|
+
desktopOpen: import("koffi").Callable;
|
|
96
|
+
desktopGeometry: import("koffi").Callable;
|
|
97
|
+
desktopPollFrame: import("koffi").Callable;
|
|
98
|
+
desktopReleaseFrame: import("koffi").Callable;
|
|
99
|
+
desktopClose: import("koffi").Callable;
|
|
100
|
+
desktopFrameFree: import("koffi").Callable;
|
|
101
|
+
audioConfigMicrophone: import("koffi").Callable;
|
|
102
|
+
audioOpen: import("koffi").Callable;
|
|
103
|
+
audioFormat: import("koffi").Callable;
|
|
104
|
+
audioPollFrame: import("koffi").Callable;
|
|
105
|
+
audioClose: import("koffi").Callable;
|
|
106
|
+
audioFrameFree: import("koffi").Callable;
|
|
107
|
+
};
|
|
108
|
+
/** Copy `len` bytes out of a koffi pointer/opaque handle. */
|
|
109
|
+
export declare function copyBytes(ptr: unknown, len: number): Buffer;
|
|
110
|
+
/** `mediaway_rational_t` (u64 num / u32 den). */
|
|
111
|
+
export interface RawRational {
|
|
112
|
+
num: bigint | number;
|
|
113
|
+
den: number;
|
|
114
|
+
}
|
|
115
|
+
/** `mediaway_video_track_info_t` / `mediaway_audio_track_info_t`. */
|
|
116
|
+
export interface RawVideoTrackInfo {
|
|
117
|
+
id: number;
|
|
118
|
+
codec: number;
|
|
119
|
+
time_base: RawRational;
|
|
120
|
+
width: number;
|
|
121
|
+
height: number;
|
|
122
|
+
extra_data: unknown;
|
|
123
|
+
extra_data_len: number;
|
|
124
|
+
}
|
|
125
|
+
export interface RawAudioTrackInfo {
|
|
126
|
+
id: number;
|
|
127
|
+
codec: number;
|
|
128
|
+
time_base: RawRational;
|
|
129
|
+
sample_rate: number;
|
|
130
|
+
channels: number;
|
|
131
|
+
extra_data: unknown;
|
|
132
|
+
extra_data_len: number;
|
|
133
|
+
}
|
|
134
|
+
/** `mediaway_packet_view_t` (muxer input). */
|
|
135
|
+
export interface RawPacketView {
|
|
136
|
+
stream_id: number;
|
|
137
|
+
pts: bigint | number;
|
|
138
|
+
dts: bigint | number;
|
|
139
|
+
duration: bigint | number;
|
|
140
|
+
is_keyframe: boolean;
|
|
141
|
+
is_discard: boolean;
|
|
142
|
+
payload: unknown;
|
|
143
|
+
payload_len: number;
|
|
144
|
+
}
|
|
145
|
+
/** `mediaway_stream_info_t` (demuxer output; geometry vs. audio via has_geometry). */
|
|
146
|
+
export interface RawStreamInfo {
|
|
147
|
+
id: number;
|
|
148
|
+
codec: number;
|
|
149
|
+
time_base: RawRational;
|
|
150
|
+
has_geometry: boolean;
|
|
151
|
+
width: number;
|
|
152
|
+
height: number;
|
|
153
|
+
sample_rate: number;
|
|
154
|
+
channels: number;
|
|
155
|
+
extra_data: unknown;
|
|
156
|
+
extra_data_len: number;
|
|
157
|
+
}
|
|
158
|
+
/** `mediaway_packet_t` (demuxer output). */
|
|
159
|
+
export interface RawPacket {
|
|
160
|
+
stream_id: number;
|
|
161
|
+
pts: bigint | number;
|
|
162
|
+
duration: bigint | number;
|
|
163
|
+
is_keyframe: boolean;
|
|
164
|
+
is_discard: boolean;
|
|
165
|
+
payload: unknown;
|
|
166
|
+
payload_len: number;
|
|
167
|
+
}
|
|
168
|
+
/** ABI output structs — fields are filled by the ABI call; callers construct
|
|
169
|
+
* them empty (`{} as RawX`) and read the fields after the call. */
|
|
170
|
+
/** `mediaway_camera_frame_t` / `mediaway_audio_frame_t` (device outputs). */
|
|
171
|
+
export interface RawCameraFrame {
|
|
172
|
+
pts: bigint | number;
|
|
173
|
+
duration: bigint | number;
|
|
174
|
+
width: number;
|
|
175
|
+
height: number;
|
|
176
|
+
pixel_format: number;
|
|
177
|
+
data: unknown;
|
|
178
|
+
data_len: number;
|
|
179
|
+
}
|
|
180
|
+
export interface RawAudioFrame {
|
|
181
|
+
pts: bigint | number;
|
|
182
|
+
duration: bigint | number;
|
|
183
|
+
sample_rate: number;
|
|
184
|
+
channels: number;
|
|
185
|
+
sample_format: number;
|
|
186
|
+
data: unknown;
|
|
187
|
+
data_len: number;
|
|
188
|
+
}
|
|
189
|
+
/** `mediaway_pipeline_frame_t` (encode session input). */
|
|
190
|
+
export interface RawPipelineFrame {
|
|
191
|
+
pts: bigint | number;
|
|
192
|
+
duration: bigint | number;
|
|
193
|
+
width: number;
|
|
194
|
+
height: number;
|
|
195
|
+
pixel_format: number;
|
|
196
|
+
storage_kind: number;
|
|
197
|
+
raw_bytes: unknown;
|
|
198
|
+
raw_bytes_len: number;
|
|
199
|
+
gpu_buffer: RawGpuBufferHandle;
|
|
200
|
+
}
|
|
201
|
+
/** `mediaway_gpu_buffer_handle_t`. */
|
|
202
|
+
export interface RawGpuBufferHandle {
|
|
203
|
+
kind: number;
|
|
204
|
+
native_a: number | bigint;
|
|
205
|
+
native_b: number | bigint;
|
|
206
|
+
subresource: number;
|
|
207
|
+
webgpu_texture_id: number | bigint;
|
|
208
|
+
}
|
|
209
|
+
/** Audio ABI v2 config / frame view / packet (ADR-0003). */
|
|
210
|
+
export interface RawAudioEncodeConfig {
|
|
211
|
+
codec: number;
|
|
212
|
+
sample_rate: number;
|
|
213
|
+
channels: number;
|
|
214
|
+
sample_format: number;
|
|
215
|
+
time_base: RawRational;
|
|
216
|
+
bitrate_bps: number;
|
|
217
|
+
}
|
|
218
|
+
/** `mediaway_audio_stream_info_t` (encoder output). */
|
|
219
|
+
export interface RawAudioStreamInfo {
|
|
220
|
+
codec: number;
|
|
221
|
+
time_base: RawRational;
|
|
222
|
+
sample_rate: number;
|
|
223
|
+
channels: number;
|
|
224
|
+
extra_data: unknown;
|
|
225
|
+
extra_data_len: number;
|
|
226
|
+
}
|
|
227
|
+
export interface RawAudioFrameView {
|
|
228
|
+
pts: bigint | number;
|
|
229
|
+
duration: bigint | number;
|
|
230
|
+
sample_rate: number;
|
|
231
|
+
channels: number;
|
|
232
|
+
sample_format: number;
|
|
233
|
+
data: unknown;
|
|
234
|
+
data_len: number;
|
|
235
|
+
}
|
|
236
|
+
export interface RawAudioPacket {
|
|
237
|
+
pts: bigint | number;
|
|
238
|
+
dts: bigint | number;
|
|
239
|
+
duration: bigint | number;
|
|
240
|
+
is_keyframe: boolean;
|
|
241
|
+
is_discard: boolean;
|
|
242
|
+
payload: unknown;
|
|
243
|
+
payload_len: number;
|
|
244
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @mediaway/ffi — internal koffi glue over Mediaway's C ABI.
|
|
3
|
+
*
|
|
4
|
+
* Not part of the public DX contract (bindings/nodejs/README.md): this package
|
|
5
|
+
* exists only so @mediaway/container, @mediaway/encoder, and @mediaway/device
|
|
6
|
+
* share one set of struct layouts and function bindings. Everything here maps
|
|
7
|
+
* 1:1 to `crates/mediaway-*-ffi/include/mediaway/*.h`.
|
|
8
|
+
*
|
|
9
|
+
* Ownership rules (from the headers):
|
|
10
|
+
* - Borrowed inputs (extra_data, packet payload, push_bytes data, frame
|
|
11
|
+
* bytes) are caller-owned, valid for the call only — we copy in/out.
|
|
12
|
+
* - Owned outputs (poll_bytes buffers, demuxed packets/stream info, finish
|
|
13
|
+
* buffers, polled device frames) MUST be released through the matching
|
|
14
|
+
* `_free` — the public packages do this automatically.
|
|
15
|
+
*/
|
|
16
|
+
import koffi from "koffi";
|
|
17
|
+
import fs from "node:fs";
|
|
18
|
+
import path from "node:path";
|
|
19
|
+
import { fileURLToPath } from "node:url";
|
|
20
|
+
// ── Library discovery ──────────────────────────────────────────────────────────
|
|
21
|
+
// The cdylibs are Rust build artifacts, not installed system libraries. Search:
|
|
22
|
+
// 1. $MEDIAWAY_FFI_DIR
|
|
23
|
+
// 2. <this package>/native (DLLs bundled at pack time — the npm distribution)
|
|
24
|
+
// 3. <repo root>/target/x86_64-pc-windows-gnu/debug (GNU toolchain, dev runs)
|
|
25
|
+
// 4. <repo root>/target/debug (host/MSVC toolchain)
|
|
26
|
+
// 5. cwd
|
|
27
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
28
|
+
const repoRoot = path.resolve(here, "..", "..", "..", "..", "..");
|
|
29
|
+
const searchDirs = [
|
|
30
|
+
process.env.MEDIAWAY_FFI_DIR ?? "",
|
|
31
|
+
path.resolve(here, "..", "native"),
|
|
32
|
+
path.join(repoRoot, "target", "x86_64-pc-windows-gnu", "debug"),
|
|
33
|
+
path.join(repoRoot, "target", "debug"),
|
|
34
|
+
process.cwd(),
|
|
35
|
+
];
|
|
36
|
+
export function findLibrary(name) {
|
|
37
|
+
for (const dir of searchDirs) {
|
|
38
|
+
if (!dir)
|
|
39
|
+
continue;
|
|
40
|
+
const candidate = path.join(dir, name);
|
|
41
|
+
if (fs.existsSync(candidate))
|
|
42
|
+
return candidate;
|
|
43
|
+
}
|
|
44
|
+
throw new Error(`cannot find ${name}; set $MEDIAWAY_FFI_DIR or build the -ffi crates`);
|
|
45
|
+
}
|
|
46
|
+
function load(name) {
|
|
47
|
+
return koffi.load(findLibrary(name));
|
|
48
|
+
}
|
|
49
|
+
export const containerLib = load("mediaway_ffi.dll");
|
|
50
|
+
export const pipelineLib = load("mediaway_ffi.dll");
|
|
51
|
+
export const deviceLib = load("mediaway_ffi.dll");
|
|
52
|
+
// ── Structs (layouts mirror the headers exactly) ───────────────────────────────
|
|
53
|
+
export const MwRational = koffi.struct("MwRational", {
|
|
54
|
+
num: "uint64",
|
|
55
|
+
den: "uint32",
|
|
56
|
+
});
|
|
57
|
+
export const MwVideoTrackInfo = koffi.struct("MwVideoTrackInfo", {
|
|
58
|
+
id: "uint32",
|
|
59
|
+
codec: "int32",
|
|
60
|
+
time_base: MwRational,
|
|
61
|
+
width: "uint32",
|
|
62
|
+
height: "uint32",
|
|
63
|
+
extra_data: "uint8_t *",
|
|
64
|
+
extra_data_len: "size_t",
|
|
65
|
+
});
|
|
66
|
+
export const MwAudioTrackInfo = koffi.struct("MwAudioTrackInfo", {
|
|
67
|
+
id: "uint32",
|
|
68
|
+
codec: "int32",
|
|
69
|
+
time_base: MwRational,
|
|
70
|
+
sample_rate: "uint32",
|
|
71
|
+
channels: "uint16",
|
|
72
|
+
extra_data: "uint8_t *",
|
|
73
|
+
extra_data_len: "size_t",
|
|
74
|
+
});
|
|
75
|
+
export const MwPacketView = koffi.struct("MwPacketView", {
|
|
76
|
+
stream_id: "uint32",
|
|
77
|
+
pts: "int64",
|
|
78
|
+
dts: "int64",
|
|
79
|
+
duration: "uint64",
|
|
80
|
+
is_keyframe: "bool",
|
|
81
|
+
is_discard: "bool",
|
|
82
|
+
payload: "uint8_t *",
|
|
83
|
+
payload_len: "size_t",
|
|
84
|
+
});
|
|
85
|
+
export const MwPacket = koffi.struct("MwPacket", {
|
|
86
|
+
stream_id: "uint32",
|
|
87
|
+
pts: "int64",
|
|
88
|
+
dts: "int64",
|
|
89
|
+
duration: "uint64",
|
|
90
|
+
is_keyframe: "bool",
|
|
91
|
+
is_discard: "bool",
|
|
92
|
+
payload: "uint8_t *",
|
|
93
|
+
payload_len: "size_t",
|
|
94
|
+
});
|
|
95
|
+
export const MwStreamInfo = koffi.struct("MwStreamInfo", {
|
|
96
|
+
id: "uint32",
|
|
97
|
+
codec: "int32",
|
|
98
|
+
time_base: MwRational,
|
|
99
|
+
has_geometry: "bool",
|
|
100
|
+
width: "uint32",
|
|
101
|
+
height: "uint32",
|
|
102
|
+
sample_rate: "uint32",
|
|
103
|
+
channels: "uint16",
|
|
104
|
+
extra_data: "uint8_t *",
|
|
105
|
+
extra_data_len: "size_t",
|
|
106
|
+
});
|
|
107
|
+
export const MwGpuDeviceHandle = koffi.struct("MwGpuDeviceHandle", {
|
|
108
|
+
kind: "int32",
|
|
109
|
+
native: "uintptr_t",
|
|
110
|
+
webgpu_device_id: "uint64",
|
|
111
|
+
});
|
|
112
|
+
export const MwGpuBufferHandle = koffi.struct("MwGpuBufferHandle", {
|
|
113
|
+
kind: "int32",
|
|
114
|
+
native_a: "uintptr_t",
|
|
115
|
+
native_b: "uintptr_t",
|
|
116
|
+
subresource: "uint32",
|
|
117
|
+
webgpu_texture_id: "uint64",
|
|
118
|
+
});
|
|
119
|
+
export const MwEncConfig = koffi.struct("MwEncConfig", {
|
|
120
|
+
codec: "int32",
|
|
121
|
+
width: "uint32",
|
|
122
|
+
height: "uint32",
|
|
123
|
+
time_base: MwRational,
|
|
124
|
+
bitrate_bps: "uint32",
|
|
125
|
+
pixel_format: "int32",
|
|
126
|
+
gpu_device: MwGpuDeviceHandle,
|
|
127
|
+
});
|
|
128
|
+
export const MwPipelineFrame = koffi.struct("MwPipelineFrame", {
|
|
129
|
+
pts: "int64",
|
|
130
|
+
duration: "uint64",
|
|
131
|
+
width: "uint32",
|
|
132
|
+
height: "uint32",
|
|
133
|
+
pixel_format: "int32",
|
|
134
|
+
storage_kind: "int32",
|
|
135
|
+
raw_bytes: "uint8_t *",
|
|
136
|
+
raw_bytes_len: "size_t",
|
|
137
|
+
gpu_buffer: MwGpuBufferHandle,
|
|
138
|
+
});
|
|
139
|
+
export const MwCameraConfig = koffi.struct("MwCameraConfig", {
|
|
140
|
+
device_index: "uint32",
|
|
141
|
+
time_base: MwRational,
|
|
142
|
+
});
|
|
143
|
+
export const MwCameraFrame = koffi.struct("MwCameraFrame", {
|
|
144
|
+
pts: "int64",
|
|
145
|
+
duration: "uint64",
|
|
146
|
+
width: "uint32",
|
|
147
|
+
height: "uint32",
|
|
148
|
+
pixel_format: "int32",
|
|
149
|
+
data: "uint8_t *",
|
|
150
|
+
data_len: "size_t",
|
|
151
|
+
});
|
|
152
|
+
export const MwDesktopConfig = koffi.struct("MwDesktopConfig", {
|
|
153
|
+
source_kind: "int32",
|
|
154
|
+
source_index: "uint32",
|
|
155
|
+
time_base: MwRational,
|
|
156
|
+
gpu_device: MwGpuDeviceHandle,
|
|
157
|
+
});
|
|
158
|
+
export const MwDesktopFrame = koffi.struct("MwDesktopFrame", {
|
|
159
|
+
pts: "int64",
|
|
160
|
+
duration: "uint64",
|
|
161
|
+
width: "uint32",
|
|
162
|
+
height: "uint32",
|
|
163
|
+
pixel_format: "int32",
|
|
164
|
+
storage_kind: "int32",
|
|
165
|
+
data: "uint8_t *",
|
|
166
|
+
data_len: "size_t",
|
|
167
|
+
gpu_buffer: MwGpuBufferHandle,
|
|
168
|
+
});
|
|
169
|
+
export const MwAudioConfig = koffi.struct("MwAudioConfig", {
|
|
170
|
+
device_index: "uint32",
|
|
171
|
+
time_base: MwRational,
|
|
172
|
+
sample_format: "int32",
|
|
173
|
+
});
|
|
174
|
+
export const MwAudioFrame = koffi.struct("MwAudioFrame", {
|
|
175
|
+
pts: "int64",
|
|
176
|
+
duration: "uint64",
|
|
177
|
+
sample_rate: "uint32",
|
|
178
|
+
channels: "uint16",
|
|
179
|
+
sample_format: "int32",
|
|
180
|
+
data: "uint8_t *",
|
|
181
|
+
data_len: "size_t",
|
|
182
|
+
});
|
|
183
|
+
export const MwAudioEncodeConfig = koffi.struct("MwAudioEncodeConfig", {
|
|
184
|
+
codec: "int32",
|
|
185
|
+
sample_rate: "uint32",
|
|
186
|
+
channels: "uint16",
|
|
187
|
+
sample_format: "int32",
|
|
188
|
+
time_base: MwRational,
|
|
189
|
+
bitrate_bps: "uint32",
|
|
190
|
+
});
|
|
191
|
+
export const MwAudioFrameView = koffi.struct("MwAudioFrameView", {
|
|
192
|
+
pts: "int64",
|
|
193
|
+
duration: "uint64",
|
|
194
|
+
sample_rate: "uint32",
|
|
195
|
+
channels: "uint16",
|
|
196
|
+
sample_format: "int32",
|
|
197
|
+
data: "uint8_t *",
|
|
198
|
+
data_len: "size_t",
|
|
199
|
+
});
|
|
200
|
+
export const MwAudioPacket = koffi.struct("MwAudioPacket", {
|
|
201
|
+
pts: "int64",
|
|
202
|
+
dts: "int64",
|
|
203
|
+
duration: "uint64",
|
|
204
|
+
is_keyframe: "bool",
|
|
205
|
+
is_discard: "bool",
|
|
206
|
+
payload: "uint8_t *",
|
|
207
|
+
payload_len: "size_t",
|
|
208
|
+
});
|
|
209
|
+
export const MwAudioStreamInfo = koffi.struct("MwAudioStreamInfo", {
|
|
210
|
+
codec: "int32",
|
|
211
|
+
time_base: MwRational,
|
|
212
|
+
sample_rate: "uint32",
|
|
213
|
+
channels: "uint16",
|
|
214
|
+
extra_data: "uint8_t *",
|
|
215
|
+
extra_data_len: "size_t",
|
|
216
|
+
});
|
|
217
|
+
// ── Container functions ────────────────────────────────────────────────────────
|
|
218
|
+
export const container = {
|
|
219
|
+
abiVersion: containerLib.func("uint32_t mediaway_container_ffi_abi_version()"),
|
|
220
|
+
muxerCreate: containerLib.func("void *mediaway_muxer_create()"),
|
|
221
|
+
muxerCreateWithBatch: containerLib.func("void *mediaway_muxer_create_with_fragment_batch(size_t batch)"),
|
|
222
|
+
muxerAddVideoTrack: containerLib.func("int mediaway_muxer_add_video_track(void *muxer, MwVideoTrackInfo *info)"),
|
|
223
|
+
muxerAddAudioTrack: containerLib.func("int mediaway_muxer_add_audio_track(void *muxer, MwAudioTrackInfo *info)"),
|
|
224
|
+
muxerBegin: containerLib.func("int mediaway_muxer_begin(void *muxer)"),
|
|
225
|
+
muxerPushPacket: containerLib.func("int mediaway_muxer_push_packet(void *muxer, MwPacketView *packet)"),
|
|
226
|
+
muxerFlush: containerLib.func("int mediaway_muxer_flush(void *muxer)"),
|
|
227
|
+
muxerPollBytes: containerLib.func("int mediaway_muxer_poll_bytes(void *muxer, _Out_ uint8_t **out_data, _Out_ size_t *out_len)"),
|
|
228
|
+
muxerClose: containerLib.func("void mediaway_muxer_close(void *muxer)"),
|
|
229
|
+
demuxerCreate: containerLib.func("void *mediaway_demuxer_create()"),
|
|
230
|
+
demuxerPushBytes: containerLib.func("int mediaway_demuxer_push_bytes(void *demuxer, uint8_t *data, size_t len)"),
|
|
231
|
+
demuxerStreamCount: containerLib.func("size_t mediaway_demuxer_stream_count(void *demuxer)"),
|
|
232
|
+
demuxerStreamAt: containerLib.func("int mediaway_demuxer_stream_at(void *demuxer, size_t index, _Out_ MwStreamInfo *out_info)"),
|
|
233
|
+
demuxerPollPacket: containerLib.func("int mediaway_demuxer_poll_packet(void *demuxer, _Out_ MwPacket *out_packet, _Out_ bool *out_has)"),
|
|
234
|
+
demuxerSetDecryptionKey: containerLib.func("int mediaway_demuxer_set_decryption_key(void *demuxer, uint8_t *key, size_t key_len)"),
|
|
235
|
+
demuxerClearDecryptionKey: containerLib.func("int mediaway_demuxer_clear_decryption_key(void *demuxer)"),
|
|
236
|
+
demuxerClose: containerLib.func("void mediaway_demuxer_close(void *demuxer)"),
|
|
237
|
+
bufferFree: containerLib.func("void mediaway_buffer_free(uint8_t *data, size_t len)"),
|
|
238
|
+
packetFree: containerLib.func("void mediaway_packet_free(MwPacket *packet)"),
|
|
239
|
+
streamInfoFree: containerLib.func("void mediaway_stream_info_free(MwStreamInfo *info)"),
|
|
240
|
+
};
|
|
241
|
+
// ── Pipeline functions ─────────────────────────────────────────────────────────
|
|
242
|
+
export const pipeline = {
|
|
243
|
+
abiVersion: pipelineLib.func("uint32_t mediaway_pipeline_ffi_abi_version()"),
|
|
244
|
+
encConfigNew: pipelineLib.func("MwEncConfig mediaway_auto_video_encode_config_new(int codec, uint32_t width, uint32_t height, MwRational time_base)"),
|
|
245
|
+
encConfigH264: pipelineLib.func("MwEncConfig mediaway_auto_video_encode_config_h264(uint32_t width, uint32_t height, MwRational time_base)"),
|
|
246
|
+
autoEncoderOpen: pipelineLib.func("int mediaway_auto_encoder_open(MwEncConfig *config, _Out_ void **out_encoder)"),
|
|
247
|
+
autoEncoderClose: pipelineLib.func("void mediaway_auto_encoder_close(void *encoder)"),
|
|
248
|
+
sessionOpen: pipelineLib.func("int mediaway_encode_session_open(void *encoder, _Out_ void **out_session)"),
|
|
249
|
+
sessionWriteFrame: pipelineLib.func("int mediaway_encode_session_write_frame(void *session, MwPipelineFrame *frame)"),
|
|
250
|
+
sessionFinish: pipelineLib.func("int mediaway_encode_session_finish(void *session, _Out_ uint8_t **out_data, _Out_ size_t *out_len)"),
|
|
251
|
+
sessionClose: pipelineLib.func("void mediaway_encode_session_close(void *session)"),
|
|
252
|
+
bufferFree: pipelineLib.func("void mediaway_pipeline_ffi_buffer_free(uint8_t *data, size_t len)"),
|
|
253
|
+
audioConfigAac: pipelineLib.func("MwAudioEncodeConfig mediaway_audio_encode_config_aac(uint32_t sample_rate, MwRational time_base)"),
|
|
254
|
+
audioEncoderOpen: pipelineLib.func("int mediaway_audio_encoder_open(MwAudioEncodeConfig *config, _Out_ void **out_session)"),
|
|
255
|
+
audioPushPcm: pipelineLib.func("int mediaway_audio_encode_session_push_pcm(void *session, MwAudioFrameView *frame)"),
|
|
256
|
+
audioPollPacket: pipelineLib.func("int mediaway_audio_encode_session_poll_packet(void *session, _Out_ MwAudioPacket *out_packet, _Out_ bool *out_has)"),
|
|
257
|
+
audioFlush: pipelineLib.func("int mediaway_audio_encode_session_flush(void *session)"),
|
|
258
|
+
audioStreamInfo: pipelineLib.func("int mediaway_audio_encode_session_stream_info(void *session, _Out_ MwAudioStreamInfo *out_info)"),
|
|
259
|
+
audioSessionClose: pipelineLib.func("void mediaway_audio_encode_session_close(void *session)"),
|
|
260
|
+
pipelinePacketFree: pipelineLib.func("void mediaway_pipeline_ffi_packet_free(MwAudioPacket *packet)"),
|
|
261
|
+
pipelineStreamInfoFree: pipelineLib.func("void mediaway_pipeline_ffi_stream_info_free(MwAudioStreamInfo *info)"),
|
|
262
|
+
};
|
|
263
|
+
// ── Device functions ───────────────────────────────────────────────────────────
|
|
264
|
+
export const device = {
|
|
265
|
+
abiVersion: deviceLib.func("uint32_t mediaway_device_ffi_abi_version()"),
|
|
266
|
+
cameraConfigDefault: deviceLib.func("MwCameraConfig mediaway_camera_capture_config_default(uint32_t device_index, MwRational time_base)"),
|
|
267
|
+
cameraOpen: deviceLib.func("int mediaway_camera_capture_open(MwCameraConfig *config, _Out_ void **out_capture)"),
|
|
268
|
+
cameraGeometry: deviceLib.func("int mediaway_camera_capture_geometry(void *capture, _Out_ uint32_t *out_width, _Out_ uint32_t *out_height)"),
|
|
269
|
+
cameraPollFrame: deviceLib.func("int mediaway_camera_capture_poll_frame(void *capture, _Out_ MwCameraFrame *out_frame, _Out_ bool *out_has)"),
|
|
270
|
+
cameraPollFrameBlocking: deviceLib.func("int mediaway_camera_capture_poll_frame_blocking(void *capture, uint32_t timeout_ms, _Out_ MwCameraFrame *out_frame)"),
|
|
271
|
+
cameraReleaseFrame: deviceLib.func("int mediaway_camera_capture_release_frame(void *capture)"),
|
|
272
|
+
cameraClose: deviceLib.func("int mediaway_camera_capture_close(void *capture)"),
|
|
273
|
+
cameraFrameFree: deviceLib.func("void mediaway_camera_frame_free(MwCameraFrame *frame)"),
|
|
274
|
+
desktopConfigScreen: deviceLib.func("MwDesktopConfig mediaway_desktop_capture_config_screen(uint32_t output_index, MwRational time_base, MwGpuDeviceHandle gpu_device)"),
|
|
275
|
+
desktopOpen: deviceLib.func("int mediaway_desktop_capture_open(MwDesktopConfig *config, _Out_ void **out_capture)"),
|
|
276
|
+
desktopGeometry: deviceLib.func("int mediaway_desktop_capture_geometry(void *capture, _Out_ uint32_t *out_width, _Out_ uint32_t *out_height)"),
|
|
277
|
+
desktopPollFrame: deviceLib.func("int mediaway_desktop_capture_poll_frame(void *capture, _Out_ MwDesktopFrame *out_frame, _Out_ bool *out_has)"),
|
|
278
|
+
desktopReleaseFrame: deviceLib.func("int mediaway_desktop_capture_release_frame(void *capture)"),
|
|
279
|
+
desktopClose: deviceLib.func("int mediaway_desktop_capture_close(void *capture)"),
|
|
280
|
+
desktopFrameFree: deviceLib.func("void mediaway_desktop_frame_free(MwDesktopFrame *frame)"),
|
|
281
|
+
audioConfigMicrophone: deviceLib.func("MwAudioConfig mediaway_audio_capture_config_microphone(MwRational time_base)"),
|
|
282
|
+
audioOpen: deviceLib.func("int mediaway_audio_capture_open(MwAudioConfig *config, _Out_ void **out_capture)"),
|
|
283
|
+
audioFormat: deviceLib.func("int mediaway_audio_capture_format(void *capture, _Out_ uint32_t *out_sample_rate, _Out_ uint16_t *out_channels)"),
|
|
284
|
+
audioPollFrame: deviceLib.func("int mediaway_audio_capture_poll_frame(void *capture, _Out_ MwAudioFrame *out_frame, _Out_ bool *out_has)"),
|
|
285
|
+
audioClose: deviceLib.func("int mediaway_audio_capture_close(void *capture)"),
|
|
286
|
+
audioFrameFree: deviceLib.func("void mediaway_audio_frame_free(MwAudioFrame *frame)"),
|
|
287
|
+
};
|
|
288
|
+
// ── Copy helpers ───────────────────────────────────────────────────────────────
|
|
289
|
+
/** Copy `len` bytes out of a koffi pointer/opaque handle. */
|
|
290
|
+
export function copyBytes(ptr, len) {
|
|
291
|
+
if (!ptr || len <= 0)
|
|
292
|
+
return Buffer.alloc(0);
|
|
293
|
+
return Buffer.from(koffi.decode(ptr, "uint8_t", len));
|
|
294
|
+
}
|
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mediaway/ffi",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Internal koffi glue over Mediaway's C ABI (container/pipeline/device)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"native"
|
|
17
|
+
],
|
|
18
|
+
"license": "MIT OR Apache-2.0",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/nyxways/mediaway.git"
|
|
22
|
+
},
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsc -p tsconfig.json",
|
|
28
|
+
"prepack": "bun ../../../../tools/scripts/copy-native-dlls.ts"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"koffi": "^3.1.4"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"typescript": "^5.6.0"
|
|
35
|
+
}
|
|
36
|
+
}
|