piixishstream 0.0.0-stage → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/README.md +124 -2
  2. package/dist/client/GatewayEvents.d.ts +30 -0
  3. package/dist/client/GatewayEvents.js +2 -0
  4. package/dist/client/GatewayEvents.js.map +1 -0
  5. package/dist/client/GatewayOpCodes.d.ts +40 -0
  6. package/dist/client/GatewayOpCodes.js +42 -0
  7. package/dist/client/GatewayOpCodes.js.map +1 -0
  8. package/dist/client/Streamer.d.ts +30 -0
  9. package/dist/client/Streamer.js +188 -0
  10. package/dist/client/Streamer.js.map +1 -0
  11. package/dist/client/index.d.ts +3 -0
  12. package/dist/client/index.js +4 -0
  13. package/dist/client/index.js.map +1 -0
  14. package/dist/client/processing/AnnexBBitstreamReaderWriter.d.ts +23 -0
  15. package/dist/client/processing/AnnexBBitstreamReaderWriter.js +149 -0
  16. package/dist/client/processing/AnnexBBitstreamReaderWriter.js.map +1 -0
  17. package/dist/client/processing/AnnexBHelper.d.ts +93 -0
  18. package/dist/client/processing/AnnexBHelper.js +127 -0
  19. package/dist/client/processing/AnnexBHelper.js.map +1 -0
  20. package/dist/client/processing/SPSVUIRewriter.d.ts +1 -0
  21. package/dist/client/processing/SPSVUIRewriter.js +297 -0
  22. package/dist/client/processing/SPSVUIRewriter.js.map +1 -0
  23. package/dist/client/voice/BaseMediaConnection.d.ts +80 -0
  24. package/dist/client/voice/BaseMediaConnection.js +552 -0
  25. package/dist/client/voice/BaseMediaConnection.js.map +1 -0
  26. package/dist/client/voice/CodecPayloadType.d.ts +59 -0
  27. package/dist/client/voice/CodecPayloadType.js +60 -0
  28. package/dist/client/voice/CodecPayloadType.js.map +1 -0
  29. package/dist/client/voice/StreamConnection.d.ts +11 -0
  30. package/dist/client/voice/StreamConnection.js +34 -0
  31. package/dist/client/voice/StreamConnection.js.map +1 -0
  32. package/dist/client/voice/VoiceConnection.d.ts +8 -0
  33. package/dist/client/voice/VoiceConnection.js +15 -0
  34. package/dist/client/voice/VoiceConnection.js.map +1 -0
  35. package/dist/client/voice/VoiceMessageTypes.d.ts +178 -0
  36. package/dist/client/voice/VoiceMessageTypes.js +2 -0
  37. package/dist/client/voice/VoiceMessageTypes.js.map +1 -0
  38. package/dist/client/voice/VoiceOpCodes.d.ts +35 -0
  39. package/dist/client/voice/VoiceOpCodes.js +38 -0
  40. package/dist/client/voice/VoiceOpCodes.js.map +1 -0
  41. package/dist/client/voice/WebRtcWrapper.d.ts +23 -0
  42. package/dist/client/voice/WebRtcWrapper.js +159 -0
  43. package/dist/client/voice/WebRtcWrapper.js.map +1 -0
  44. package/dist/client/voice/index.d.ts +4 -0
  45. package/dist/client/voice/index.js +6 -0
  46. package/dist/client/voice/index.js.map +1 -0
  47. package/dist/index.d.ts +3 -0
  48. package/dist/index.js +4 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/media/AudioStream.d.ts +7 -0
  51. package/dist/media/AudioStream.js +12 -0
  52. package/dist/media/AudioStream.js.map +1 -0
  53. package/dist/media/BaseMediaStream.d.ts +31 -0
  54. package/dist/media/BaseMediaStream.js +164 -0
  55. package/dist/media/BaseMediaStream.js.map +1 -0
  56. package/dist/media/LibavCodecId.d.ts +541 -0
  57. package/dist/media/LibavCodecId.js +553 -0
  58. package/dist/media/LibavCodecId.js.map +1 -0
  59. package/dist/media/LibavDecoder.d.ts +5 -0
  60. package/dist/media/LibavDecoder.js +43 -0
  61. package/dist/media/LibavDecoder.js.map +1 -0
  62. package/dist/media/LibavDemuxer.d.ts +44 -0
  63. package/dist/media/LibavDemuxer.js +231 -0
  64. package/dist/media/LibavDemuxer.js.map +1 -0
  65. package/dist/media/VideoStream.d.ts +7 -0
  66. package/dist/media/VideoStream.js +12 -0
  67. package/dist/media/VideoStream.js.map +1 -0
  68. package/dist/media/encoders/index.d.ts +26 -0
  69. package/dist/media/encoders/index.js +12 -0
  70. package/dist/media/encoders/index.js.map +1 -0
  71. package/dist/media/encoders/merge.d.ts +3 -0
  72. package/dist/media/encoders/merge.js +10 -0
  73. package/dist/media/encoders/merge.js.map +1 -0
  74. package/dist/media/encoders/nvenc.d.ts +10 -0
  75. package/dist/media/encoders/nvenc.js +23 -0
  76. package/dist/media/encoders/nvenc.js.map +1 -0
  77. package/dist/media/encoders/software.d.ts +17 -0
  78. package/dist/media/encoders/software.js +31 -0
  79. package/dist/media/encoders/software.js.map +1 -0
  80. package/dist/media/encoders/vaapi.d.ts +6 -0
  81. package/dist/media/encoders/vaapi.js +22 -0
  82. package/dist/media/encoders/vaapi.js.map +1 -0
  83. package/dist/media/index.d.ts +4 -0
  84. package/dist/media/index.js +5 -0
  85. package/dist/media/index.js.map +1 -0
  86. package/dist/media/newApi.d.ts +130 -0
  87. package/dist/media/newApi.js +409 -0
  88. package/dist/media/newApi.js.map +1 -0
  89. package/dist/utils.d.ts +25 -0
  90. package/dist/utils.js +65 -0
  91. package/dist/utils.js.map +1 -0
  92. package/package.json +82 -5
  93. package/src/client/GatewayEvents.ts +48 -0
  94. package/src/client/GatewayOpCodes.ts +40 -0
  95. package/src/client/Streamer.ts +259 -0
  96. package/src/client/index.ts +3 -0
  97. package/src/client/processing/AnnexBBitstreamReaderWriter.ts +148 -0
  98. package/src/client/processing/AnnexBHelper.ts +134 -0
  99. package/src/client/processing/SPSVUIRewriter.ts +332 -0
  100. package/src/client/voice/BaseMediaConnection.ts +639 -0
  101. package/src/client/voice/CodecPayloadType.ts +59 -0
  102. package/src/client/voice/MediaUdp.ts.bak +171 -0
  103. package/src/client/voice/StreamConnection.ts +38 -0
  104. package/src/client/voice/VoiceConnection.ts +19 -0
  105. package/src/client/voice/VoiceMessageTypes.ts +263 -0
  106. package/src/client/voice/VoiceOpCodes.ts +36 -0
  107. package/src/client/voice/WebRtcWrapper.ts +218 -0
  108. package/src/client/voice/index.ts +5 -0
  109. package/src/index.ts +3 -0
  110. package/src/media/AudioStream.ts +18 -0
  111. package/src/media/BaseMediaStream.ts +198 -0
  112. package/src/media/LibavCodecId.ts +564 -0
  113. package/src/media/LibavDecoder.ts +47 -0
  114. package/src/media/LibavDemuxer.ts +293 -0
  115. package/src/media/VideoStream.ts +17 -0
  116. package/src/media/encoders/index.ts +27 -0
  117. package/src/media/encoders/merge.ts +14 -0
  118. package/src/media/encoders/nvenc.ts +38 -0
  119. package/src/media/encoders/software.ts +76 -0
  120. package/src/media/encoders/vaapi.ts +29 -0
  121. package/src/media/index.ts +4 -0
  122. package/src/media/newApi.ts +642 -0
  123. package/src/utils.ts +101 -0
@@ -0,0 +1,293 @@
1
+ import pDebounce from "p-debounce";
2
+ import {
3
+ BitStreamFilterAPI,
4
+ Demuxer,
5
+ avGetCodecName,
6
+ type Stream,
7
+ } from "node-av";
8
+ import { Log } from "debug-level";
9
+ import { randomUUID } from "node:crypto";
10
+ import { AVCodecID } from "./LibavCodecId.js";
11
+ import { once } from "node:events";
12
+ import { PassThrough } from "node:stream";
13
+ import { finished } from "node:stream/promises";
14
+ import type { CodecParameters, Packet } from "node-av";
15
+ import type { Readable } from "node:stream";
16
+
17
+ type MediaStreamInfoCommon = {
18
+ index: number;
19
+ codec: AVCodecID;
20
+ codecpar: CodecParameters;
21
+ avStream: Stream;
22
+ };
23
+
24
+ export type VideoStreamInfo = MediaStreamInfoCommon & {
25
+ width: number;
26
+ height: number;
27
+ framerate_num: number;
28
+ framerate_den: number;
29
+ };
30
+ export type AudioStreamInfo = MediaStreamInfoCommon & {
31
+ sample_rate: number;
32
+ };
33
+
34
+ const allowedVideoCodec = new Set([
35
+ AVCodecID.AV_CODEC_ID_H264,
36
+ AVCodecID.AV_CODEC_ID_H265,
37
+ AVCodecID.AV_CODEC_ID_VP8,
38
+ AVCodecID.AV_CODEC_ID_VP9,
39
+ AVCodecID.AV_CODEC_ID_AV1,
40
+ ]);
41
+
42
+ const allowedAudioCodec = new Set([AVCodecID.AV_CODEC_ID_OPUS]);
43
+
44
+ function parseOpusPacketDuration(frame: Uint8Array) {
45
+ // https://datatracker.ietf.org/doc/html/rfc6716#section-3.1
46
+ const frameSizes = [
47
+ // SILK only, narrow band
48
+ 10, 20, 40, 60,
49
+
50
+ // SILK only, medium band
51
+ 10, 20, 40, 60,
52
+
53
+ // SILK only, wide band
54
+ 10, 20, 40, 60,
55
+
56
+ // Hybrid, super wide band
57
+ 10, 20,
58
+
59
+ // Hybrid, full band
60
+ 10, 20,
61
+
62
+ // CELT only, narrow band
63
+ 2.5, 5, 10, 20,
64
+
65
+ // CELT only, wide band
66
+ 2.5, 5, 10, 20,
67
+
68
+ // CELT only, super wide band
69
+ 2.5, 5, 10, 20,
70
+
71
+ // CELT only, full band
72
+ 2.5, 5, 10, 20,
73
+ ];
74
+
75
+ const frameSize = (48000 / 1000) * frameSizes[frame[0] >> 3];
76
+
77
+ let frameCount = 0;
78
+ const c = frame[0] & 0b11;
79
+ switch (c) {
80
+ case 0:
81
+ frameCount = 1;
82
+ break;
83
+
84
+ case 1:
85
+ case 2:
86
+ frameCount = 2;
87
+ break;
88
+
89
+ case 3:
90
+ frameCount = frame[1] & 0b111111;
91
+ break;
92
+ }
93
+
94
+ return frameSize * frameCount;
95
+ }
96
+
97
+ type DemuxerOptions = {
98
+ format: "matroska" | "nut";
99
+ };
100
+
101
+ export async function demux(input: Readable, { format }: DemuxerOptions) {
102
+ const loggerFormat = new Log("demux:format");
103
+ const loggerFrameCommon = new Log("demux:frame:common");
104
+ const loggerFrameVideo = new Log("demux:frame:video");
105
+ const loggerFrameAudio = new Log("demux:frame:audio");
106
+
107
+ const filename = randomUUID();
108
+ const demuxer = await Demuxer.open(input, {
109
+ options: {
110
+ fflags: "nobuffer",
111
+ },
112
+ format,
113
+ bufferSize: 8192,
114
+ });
115
+
116
+ const cleanup = () => {
117
+ input.destroy();
118
+ demuxer.close();
119
+ vPipe.off("drain", readFrame);
120
+ aPipe.off("drain", readFrame);
121
+ vPipe.end();
122
+ aPipe.end();
123
+ vbsf.forEach((e) => {
124
+ e.close();
125
+ });
126
+ };
127
+
128
+ const vStream = demuxer.video();
129
+ const aStream = demuxer.audio();
130
+
131
+ let vInfo: VideoStreamInfo | undefined;
132
+ let aInfo: AudioStreamInfo | undefined;
133
+ const vPipe = new PassThrough({
134
+ objectMode: true,
135
+ writableHighWaterMark: 128,
136
+ });
137
+ const aPipe = new PassThrough({
138
+ objectMode: true,
139
+ writableHighWaterMark: 128,
140
+ });
141
+
142
+ const vbsf: BitStreamFilterAPI[] = [];
143
+ if (vStream) {
144
+ const codecId = vStream.codecpar.codecId;
145
+ if (!allowedVideoCodec.has(codecId)) {
146
+ const codecName = avGetCodecName(codecId);
147
+ cleanup();
148
+ throw new Error(`Video codec ${codecName} is not allowed`);
149
+ }
150
+ try {
151
+ switch (codecId) {
152
+ case AVCodecID.AV_CODEC_ID_H264:
153
+ vbsf.push(BitStreamFilterAPI.create("h264_mp4toannexb", vStream));
154
+ vbsf.push(
155
+ BitStreamFilterAPI.create("h264_metadata", vStream, {
156
+ options: {
157
+ aud: "remove",
158
+ },
159
+ }),
160
+ );
161
+ vbsf.push(BitStreamFilterAPI.create("dump_extra", vStream));
162
+ break;
163
+ case AVCodecID.AV_CODEC_ID_HEVC:
164
+ vbsf.push(BitStreamFilterAPI.create("hevc_mp4toannexb", vStream));
165
+ vbsf.push(
166
+ BitStreamFilterAPI.create("hevc_metadata", vStream, {
167
+ options: {
168
+ aud: "remove",
169
+ },
170
+ }),
171
+ );
172
+ vbsf.push(BitStreamFilterAPI.create("dump_extra", vStream));
173
+ break;
174
+ default:
175
+ vbsf.push(BitStreamFilterAPI.create("null", vStream));
176
+ break;
177
+ }
178
+ } catch (e) {
179
+ cleanup();
180
+ throw new Error(`Failed to construct bitstream filterchain`, {
181
+ cause: (e as Error).cause,
182
+ });
183
+ }
184
+
185
+ const codecpar = vbsf.at(-1)?.outputCodecParameters ?? vStream.codecpar;
186
+ vInfo = {
187
+ index: vStream.index,
188
+ codec: codecId,
189
+ codecpar,
190
+ width: codecpar.width ?? 0,
191
+ height: codecpar.height ?? 0,
192
+ framerate_num: codecpar.frameRate.num,
193
+ framerate_den: codecpar.frameRate.den,
194
+ avStream: vStream,
195
+ };
196
+ loggerFormat.info(
197
+ {
198
+ info: vInfo,
199
+ },
200
+ `Found video stream in input ${filename}`,
201
+ );
202
+ }
203
+ if (aStream) {
204
+ const codecId = aStream.codecpar.codecId;
205
+ if (!allowedAudioCodec.has(codecId)) {
206
+ const codecName = avGetCodecName(codecId);
207
+ cleanup();
208
+ throw new Error(`Audio codec ${codecName} is not allowed`);
209
+ }
210
+ aInfo = {
211
+ index: aStream.index,
212
+ codec: codecId,
213
+ codecpar: aStream.codecpar,
214
+ sample_rate: aStream.codecpar.sampleRate || 0,
215
+ avStream: aStream,
216
+ };
217
+ loggerFormat.info(
218
+ {
219
+ info: aInfo,
220
+ },
221
+ `Found audio stream in input ${filename}`,
222
+ );
223
+ }
224
+
225
+ const packetIterator = demuxer.packets();
226
+ const applyBitStreamFilters = async (
227
+ input: Packet | null,
228
+ filters: BitStreamFilterAPI[],
229
+ ) => {
230
+ let packets = [input];
231
+ for (const filter of filters) {
232
+ let newPackets: (Packet | null)[] = [];
233
+ for (const packet of packets) {
234
+ newPackets = [...newPackets, ...(await filter.filterAll(packet))];
235
+ packet?.free();
236
+ }
237
+ if (!input) newPackets.push(null);
238
+ packets = newPackets;
239
+ }
240
+ return packets;
241
+ };
242
+ const readFrame = pDebounce.promise(async () => {
243
+ let resume = true;
244
+ while (resume) {
245
+ try {
246
+ const { value: inPacket, done } = await packetIterator.next();
247
+ if (done) {
248
+ loggerFrameCommon.info("Reached end of stream. Stopping");
249
+ const packets = await applyBitStreamFilters(null, vbsf);
250
+ for (const packet of packets) {
251
+ if (packet) vPipe.write(packet);
252
+ }
253
+ cleanup();
254
+ return;
255
+ } else if (inPacket) {
256
+ const streamIndex = inPacket.streamIndex;
257
+ if (vInfo && vInfo.index === streamIndex) {
258
+ loggerFrameVideo.trace("Received a video packet");
259
+ const packets = await applyBitStreamFilters(inPacket.clone(), vbsf);
260
+ for (const packet of packets) {
261
+ if (packet) resume &&= vPipe.write(packet);
262
+ }
263
+ } else if (aInfo && aInfo.index === streamIndex) {
264
+ const packet = inPacket.clone()!;
265
+ packet.duration ||= BigInt(parseOpusPacketDuration(packet.data!));
266
+ resume &&= aPipe.write(packet);
267
+ }
268
+ inPacket.free();
269
+ }
270
+ } catch (e) {
271
+ loggerFrameCommon.info(
272
+ { error: e },
273
+ "Received an error during frame extraction. Stopping",
274
+ );
275
+ cleanup();
276
+ return;
277
+ }
278
+ }
279
+ });
280
+ vPipe.on("drain", () => {
281
+ loggerFrameVideo.trace("Video pipe drained");
282
+ readFrame();
283
+ });
284
+ aPipe.on("drain", () => {
285
+ loggerFrameAudio.trace("Audio pipe drained");
286
+ readFrame();
287
+ });
288
+ readFrame();
289
+ return {
290
+ video: vInfo ? { ...vInfo, stream: vPipe as Readable } : undefined,
291
+ audio: aInfo ? { ...aInfo, stream: aPipe as Readable } : undefined,
292
+ };
293
+ }
@@ -0,0 +1,17 @@
1
+ import { BaseMediaStream } from "./BaseMediaStream.js";
2
+ import type { WebRtcConnWrapper } from "../client/voice/WebRtcWrapper.js";
3
+
4
+ export class VideoStream extends BaseMediaStream {
5
+ private _conn: WebRtcConnWrapper;
6
+ constructor(conn: WebRtcConnWrapper, noSleep = false) {
7
+ super("video", noSleep);
8
+ this._conn = conn;
9
+ }
10
+
11
+ protected override async _sendFrame(
12
+ frame: Buffer,
13
+ frametime: number,
14
+ ): Promise<void> {
15
+ this._conn.sendVideoFrame(frame, frametime);
16
+ }
17
+ }
@@ -0,0 +1,27 @@
1
+ import type { SupportedVideoCodec } from "../../utils.js";
2
+
3
+ export type EncoderSettings = {
4
+ name: string;
5
+ options: string[];
6
+ globalOptions?: string[];
7
+ outFilters?: string[];
8
+ };
9
+
10
+ export type EncoderSettingsGetter = (
11
+ bitrate: number,
12
+ bitrateMax: number,
13
+ ) => Partial<Record<SupportedVideoCodec, EncoderSettings>>;
14
+
15
+ import { software } from "./software.js";
16
+ import { nvenc } from "./nvenc.js";
17
+ import { vaapi } from "./vaapi.js";
18
+ import { merge } from "./merge.js";
19
+
20
+ const Encoders = {
21
+ software,
22
+ nvenc,
23
+ vaapi,
24
+ merge,
25
+ };
26
+
27
+ export { Encoders };
@@ -0,0 +1,14 @@
1
+ import type { EncoderSettingsGetter } from "./index.js";
2
+ import type { SupportedVideoCodec } from "../../utils.js";
3
+
4
+ export const merge = (
5
+ encoder: Partial<Record<SupportedVideoCodec, EncoderSettingsGetter>>,
6
+ ) => {
7
+ return ((bitrate, bitrateMax) => ({
8
+ H264: encoder.H264?.(bitrate, bitrateMax),
9
+ H265: encoder.H265?.(bitrate, bitrateMax),
10
+ VP8: encoder.VP8?.(bitrate, bitrateMax),
11
+ VP9: encoder.VP9?.(bitrate, bitrateMax),
12
+ AV1: encoder.AV1?.(bitrate, bitrateMax),
13
+ })) as EncoderSettingsGetter;
14
+ };
@@ -0,0 +1,38 @@
1
+ import type { EncoderSettingsGetter } from "./index.js";
2
+
3
+ type NvencPreset = "p1" | "p2" | "p3" | "p4" | "p5" | "p6" | "p7";
4
+
5
+ type NvencSettings = {
6
+ preset: NvencPreset;
7
+ spatialAq: boolean;
8
+ temporalAq: boolean;
9
+ gpu: number;
10
+ };
11
+
12
+ export function nvenc({
13
+ preset = "p4",
14
+ spatialAq = false,
15
+ temporalAq = false,
16
+ gpu,
17
+ }: Partial<NvencSettings> = {}) {
18
+ const options = [
19
+ `-preset ${preset}`,
20
+ `-spatial-aq ${spatialAq}`,
21
+ `-temporal-aq ${temporalAq}`,
22
+ ...(gpu !== undefined ? [`-gpu ${gpu}`] : []),
23
+ ];
24
+ return (() => ({
25
+ H264: {
26
+ name: "h264_nvenc",
27
+ options,
28
+ },
29
+ H265: {
30
+ name: "hevc_nvenc",
31
+ options,
32
+ },
33
+ AV1: {
34
+ name: "av1_nvenc",
35
+ options,
36
+ },
37
+ })) as EncoderSettingsGetter;
38
+ }
@@ -0,0 +1,76 @@
1
+ import type { EncoderSettingsGetter } from "./index.js";
2
+
3
+ type DeepPartial<T> = T extends unknown[]
4
+ ? T
5
+ : { [P in keyof T]?: DeepPartial<T[P]> };
6
+ type x26xPreset =
7
+ | "ultrafast"
8
+ | "superfast"
9
+ | "veryfast"
10
+ | "faster"
11
+ | "fast"
12
+ | "medium"
13
+ | "slow"
14
+ | "slower"
15
+ | "veryslow"
16
+ | "placebo";
17
+
18
+ export type SoftwareEncoderSettings = {
19
+ x264: {
20
+ preset: x26xPreset;
21
+ tune:
22
+ | "film"
23
+ | "animation"
24
+ | "grain"
25
+ | "stillimage"
26
+ | "fastdecode"
27
+ | "zerolatency"
28
+ | "psnr"
29
+ | "ssim";
30
+ };
31
+ x265: {
32
+ preset: x26xPreset;
33
+ tune:
34
+ | "psnr"
35
+ | "ssim"
36
+ | "grain"
37
+ | "fastdecode"
38
+ | "zerolatency"
39
+ | "animation";
40
+ };
41
+ };
42
+
43
+ export const software = ({
44
+ x264,
45
+ x265,
46
+ }: DeepPartial<SoftwareEncoderSettings> = {}) => {
47
+ const { preset: x264Preset = "superfast", tune: x264Tune = "film" } =
48
+ x264 ?? {};
49
+ const { preset: x265Preset = "superfast", tune: x265Tune } = x265 ?? {};
50
+ return (() => ({
51
+ H264: {
52
+ name: "libx264",
53
+ options: ["-forced-idr 1", `-tune ${x264Tune}`, `-preset ${x264Preset}`],
54
+ },
55
+ H265: {
56
+ name: "libx265",
57
+ options: [
58
+ "-forced-idr 1",
59
+ ...(x265Tune ? [`-tune ${x265Tune}`] : []),
60
+ `-preset ${x265Preset}`,
61
+ ],
62
+ },
63
+ VP8: {
64
+ name: "libvpx",
65
+ options: ["-deadline 20000"],
66
+ },
67
+ VP9: {
68
+ name: "libvpx-vp9",
69
+ options: ["-deadline 20000"],
70
+ },
71
+ AV1: {
72
+ name: "libsvtav1",
73
+ options: [],
74
+ },
75
+ })) as EncoderSettingsGetter;
76
+ };
@@ -0,0 +1,29 @@
1
+ import type { EncoderSettingsGetter } from "./index.js";
2
+
3
+ type VaapiSettings = {
4
+ device?: string;
5
+ };
6
+
7
+ export function vaapi({
8
+ device = "/dev/dri/renderD128",
9
+ }: Partial<VaapiSettings> = {}) {
10
+ const props = {
11
+ options: [],
12
+ globalOptions: ["-vaapi_device", device],
13
+ outFilters: ["format=nv12|vaapi", "hwupload"],
14
+ };
15
+ return (() => ({
16
+ H264: {
17
+ name: "h264_vaapi",
18
+ ...props,
19
+ },
20
+ H265: {
21
+ name: "hevc_vaapi",
22
+ ...props,
23
+ },
24
+ AV1: {
25
+ name: "av1_vaapi",
26
+ ...props,
27
+ },
28
+ })) as EncoderSettingsGetter;
29
+ }
@@ -0,0 +1,4 @@
1
+ export * from "./LibavDemuxer.js";
2
+ export * from "./newApi.js";
3
+ export * as NewApi from "./newApi.js";
4
+ export * from "./encoders/index.js";