@revizly/node-av 5.2.2-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. package/BUILD_LINUX.md +61 -0
  2. package/LICENSE.md +22 -0
  3. package/README.md +662 -0
  4. package/build_mac_local.sh +69 -0
  5. package/dist/api/audio-frame-buffer.d.ts +205 -0
  6. package/dist/api/audio-frame-buffer.js +287 -0
  7. package/dist/api/audio-frame-buffer.js.map +1 -0
  8. package/dist/api/bitstream-filter.d.ts +820 -0
  9. package/dist/api/bitstream-filter.js +1242 -0
  10. package/dist/api/bitstream-filter.js.map +1 -0
  11. package/dist/api/constants.d.ts +44 -0
  12. package/dist/api/constants.js +45 -0
  13. package/dist/api/constants.js.map +1 -0
  14. package/dist/api/data/test_av1.ivf +0 -0
  15. package/dist/api/data/test_h264.h264 +0 -0
  16. package/dist/api/data/test_hevc.h265 +0 -0
  17. package/dist/api/data/test_mjpeg.mjpeg +0 -0
  18. package/dist/api/data/test_vp8.ivf +0 -0
  19. package/dist/api/data/test_vp9.ivf +0 -0
  20. package/dist/api/decoder.d.ts +1088 -0
  21. package/dist/api/decoder.js +1775 -0
  22. package/dist/api/decoder.js.map +1 -0
  23. package/dist/api/demuxer.d.ts +1219 -0
  24. package/dist/api/demuxer.js +2081 -0
  25. package/dist/api/demuxer.js.map +1 -0
  26. package/dist/api/device.d.ts +586 -0
  27. package/dist/api/device.js +961 -0
  28. package/dist/api/device.js.map +1 -0
  29. package/dist/api/encoder.d.ts +1132 -0
  30. package/dist/api/encoder.js +1988 -0
  31. package/dist/api/encoder.js.map +1 -0
  32. package/dist/api/filter-complex.d.ts +821 -0
  33. package/dist/api/filter-complex.js +1604 -0
  34. package/dist/api/filter-complex.js.map +1 -0
  35. package/dist/api/filter-presets.d.ts +1286 -0
  36. package/dist/api/filter-presets.js +2152 -0
  37. package/dist/api/filter-presets.js.map +1 -0
  38. package/dist/api/filter.d.ts +1234 -0
  39. package/dist/api/filter.js +1976 -0
  40. package/dist/api/filter.js.map +1 -0
  41. package/dist/api/fmp4-stream.d.ts +426 -0
  42. package/dist/api/fmp4-stream.js +739 -0
  43. package/dist/api/fmp4-stream.js.map +1 -0
  44. package/dist/api/hardware.d.ts +651 -0
  45. package/dist/api/hardware.js +1260 -0
  46. package/dist/api/hardware.js.map +1 -0
  47. package/dist/api/index.d.ts +17 -0
  48. package/dist/api/index.js +32 -0
  49. package/dist/api/index.js.map +1 -0
  50. package/dist/api/io-stream.d.ts +307 -0
  51. package/dist/api/io-stream.js +282 -0
  52. package/dist/api/io-stream.js.map +1 -0
  53. package/dist/api/muxer.d.ts +957 -0
  54. package/dist/api/muxer.js +2002 -0
  55. package/dist/api/muxer.js.map +1 -0
  56. package/dist/api/pipeline.d.ts +607 -0
  57. package/dist/api/pipeline.js +1145 -0
  58. package/dist/api/pipeline.js.map +1 -0
  59. package/dist/api/utilities/async-queue.d.ts +120 -0
  60. package/dist/api/utilities/async-queue.js +211 -0
  61. package/dist/api/utilities/async-queue.js.map +1 -0
  62. package/dist/api/utilities/audio-sample.d.ts +117 -0
  63. package/dist/api/utilities/audio-sample.js +112 -0
  64. package/dist/api/utilities/audio-sample.js.map +1 -0
  65. package/dist/api/utilities/channel-layout.d.ts +76 -0
  66. package/dist/api/utilities/channel-layout.js +80 -0
  67. package/dist/api/utilities/channel-layout.js.map +1 -0
  68. package/dist/api/utilities/electron-shared-texture.d.ts +328 -0
  69. package/dist/api/utilities/electron-shared-texture.js +503 -0
  70. package/dist/api/utilities/electron-shared-texture.js.map +1 -0
  71. package/dist/api/utilities/image.d.ts +207 -0
  72. package/dist/api/utilities/image.js +213 -0
  73. package/dist/api/utilities/image.js.map +1 -0
  74. package/dist/api/utilities/index.d.ts +12 -0
  75. package/dist/api/utilities/index.js +25 -0
  76. package/dist/api/utilities/index.js.map +1 -0
  77. package/dist/api/utilities/media-type.d.ts +49 -0
  78. package/dist/api/utilities/media-type.js +53 -0
  79. package/dist/api/utilities/media-type.js.map +1 -0
  80. package/dist/api/utilities/pixel-format.d.ts +89 -0
  81. package/dist/api/utilities/pixel-format.js +97 -0
  82. package/dist/api/utilities/pixel-format.js.map +1 -0
  83. package/dist/api/utilities/sample-format.d.ts +129 -0
  84. package/dist/api/utilities/sample-format.js +141 -0
  85. package/dist/api/utilities/sample-format.js.map +1 -0
  86. package/dist/api/utilities/scheduler.d.ts +138 -0
  87. package/dist/api/utilities/scheduler.js +98 -0
  88. package/dist/api/utilities/scheduler.js.map +1 -0
  89. package/dist/api/utilities/streaming.d.ts +186 -0
  90. package/dist/api/utilities/streaming.js +309 -0
  91. package/dist/api/utilities/streaming.js.map +1 -0
  92. package/dist/api/utilities/timestamp.d.ts +193 -0
  93. package/dist/api/utilities/timestamp.js +206 -0
  94. package/dist/api/utilities/timestamp.js.map +1 -0
  95. package/dist/api/utilities/whisper-model.d.ts +310 -0
  96. package/dist/api/utilities/whisper-model.js +528 -0
  97. package/dist/api/utilities/whisper-model.js.map +1 -0
  98. package/dist/api/utils.d.ts +19 -0
  99. package/dist/api/utils.js +39 -0
  100. package/dist/api/utils.js.map +1 -0
  101. package/dist/api/whisper.d.ts +324 -0
  102. package/dist/api/whisper.js +362 -0
  103. package/dist/api/whisper.js.map +1 -0
  104. package/dist/constants/channel-layouts.d.ts +53 -0
  105. package/dist/constants/channel-layouts.js +57 -0
  106. package/dist/constants/channel-layouts.js.map +1 -0
  107. package/dist/constants/constants.d.ts +2325 -0
  108. package/dist/constants/constants.js +1887 -0
  109. package/dist/constants/constants.js.map +1 -0
  110. package/dist/constants/decoders.d.ts +633 -0
  111. package/dist/constants/decoders.js +641 -0
  112. package/dist/constants/decoders.js.map +1 -0
  113. package/dist/constants/encoders.d.ts +295 -0
  114. package/dist/constants/encoders.js +308 -0
  115. package/dist/constants/encoders.js.map +1 -0
  116. package/dist/constants/hardware.d.ts +26 -0
  117. package/dist/constants/hardware.js +27 -0
  118. package/dist/constants/hardware.js.map +1 -0
  119. package/dist/constants/index.d.ts +5 -0
  120. package/dist/constants/index.js +6 -0
  121. package/dist/constants/index.js.map +1 -0
  122. package/dist/ffmpeg/index.d.ts +99 -0
  123. package/dist/ffmpeg/index.js +115 -0
  124. package/dist/ffmpeg/index.js.map +1 -0
  125. package/dist/ffmpeg/utils.d.ts +31 -0
  126. package/dist/ffmpeg/utils.js +68 -0
  127. package/dist/ffmpeg/utils.js.map +1 -0
  128. package/dist/ffmpeg/version.d.ts +6 -0
  129. package/dist/ffmpeg/version.js +7 -0
  130. package/dist/ffmpeg/version.js.map +1 -0
  131. package/dist/index.d.ts +4 -0
  132. package/dist/index.js +9 -0
  133. package/dist/index.js.map +1 -0
  134. package/dist/lib/audio-fifo.d.ts +399 -0
  135. package/dist/lib/audio-fifo.js +431 -0
  136. package/dist/lib/audio-fifo.js.map +1 -0
  137. package/dist/lib/binding.d.ts +228 -0
  138. package/dist/lib/binding.js +60 -0
  139. package/dist/lib/binding.js.map +1 -0
  140. package/dist/lib/bitstream-filter-context.d.ts +379 -0
  141. package/dist/lib/bitstream-filter-context.js +441 -0
  142. package/dist/lib/bitstream-filter-context.js.map +1 -0
  143. package/dist/lib/bitstream-filter.d.ts +140 -0
  144. package/dist/lib/bitstream-filter.js +154 -0
  145. package/dist/lib/bitstream-filter.js.map +1 -0
  146. package/dist/lib/codec-context.d.ts +1071 -0
  147. package/dist/lib/codec-context.js +1354 -0
  148. package/dist/lib/codec-context.js.map +1 -0
  149. package/dist/lib/codec-parameters.d.ts +616 -0
  150. package/dist/lib/codec-parameters.js +761 -0
  151. package/dist/lib/codec-parameters.js.map +1 -0
  152. package/dist/lib/codec-parser.d.ts +201 -0
  153. package/dist/lib/codec-parser.js +213 -0
  154. package/dist/lib/codec-parser.js.map +1 -0
  155. package/dist/lib/codec.d.ts +586 -0
  156. package/dist/lib/codec.js +713 -0
  157. package/dist/lib/codec.js.map +1 -0
  158. package/dist/lib/device.d.ts +291 -0
  159. package/dist/lib/device.js +324 -0
  160. package/dist/lib/device.js.map +1 -0
  161. package/dist/lib/dictionary.d.ts +333 -0
  162. package/dist/lib/dictionary.js +372 -0
  163. package/dist/lib/dictionary.js.map +1 -0
  164. package/dist/lib/error.d.ts +242 -0
  165. package/dist/lib/error.js +303 -0
  166. package/dist/lib/error.js.map +1 -0
  167. package/dist/lib/fifo.d.ts +416 -0
  168. package/dist/lib/fifo.js +453 -0
  169. package/dist/lib/fifo.js.map +1 -0
  170. package/dist/lib/filter-context.d.ts +712 -0
  171. package/dist/lib/filter-context.js +789 -0
  172. package/dist/lib/filter-context.js.map +1 -0
  173. package/dist/lib/filter-graph-segment.d.ts +160 -0
  174. package/dist/lib/filter-graph-segment.js +171 -0
  175. package/dist/lib/filter-graph-segment.js.map +1 -0
  176. package/dist/lib/filter-graph.d.ts +641 -0
  177. package/dist/lib/filter-graph.js +704 -0
  178. package/dist/lib/filter-graph.js.map +1 -0
  179. package/dist/lib/filter-inout.d.ts +198 -0
  180. package/dist/lib/filter-inout.js +257 -0
  181. package/dist/lib/filter-inout.js.map +1 -0
  182. package/dist/lib/filter.d.ts +243 -0
  183. package/dist/lib/filter.js +272 -0
  184. package/dist/lib/filter.js.map +1 -0
  185. package/dist/lib/format-context.d.ts +1254 -0
  186. package/dist/lib/format-context.js +1379 -0
  187. package/dist/lib/format-context.js.map +1 -0
  188. package/dist/lib/frame-utils.d.ts +116 -0
  189. package/dist/lib/frame-utils.js +98 -0
  190. package/dist/lib/frame-utils.js.map +1 -0
  191. package/dist/lib/frame.d.ts +1222 -0
  192. package/dist/lib/frame.js +1435 -0
  193. package/dist/lib/frame.js.map +1 -0
  194. package/dist/lib/hardware-device-context.d.ts +362 -0
  195. package/dist/lib/hardware-device-context.js +383 -0
  196. package/dist/lib/hardware-device-context.js.map +1 -0
  197. package/dist/lib/hardware-frames-context.d.ts +419 -0
  198. package/dist/lib/hardware-frames-context.js +477 -0
  199. package/dist/lib/hardware-frames-context.js.map +1 -0
  200. package/dist/lib/index.d.ts +35 -0
  201. package/dist/lib/index.js +60 -0
  202. package/dist/lib/index.js.map +1 -0
  203. package/dist/lib/input-format.d.ts +249 -0
  204. package/dist/lib/input-format.js +306 -0
  205. package/dist/lib/input-format.js.map +1 -0
  206. package/dist/lib/io-context.d.ts +696 -0
  207. package/dist/lib/io-context.js +769 -0
  208. package/dist/lib/io-context.js.map +1 -0
  209. package/dist/lib/log.d.ts +174 -0
  210. package/dist/lib/log.js +184 -0
  211. package/dist/lib/log.js.map +1 -0
  212. package/dist/lib/native-types.d.ts +946 -0
  213. package/dist/lib/native-types.js +2 -0
  214. package/dist/lib/native-types.js.map +1 -0
  215. package/dist/lib/option.d.ts +927 -0
  216. package/dist/lib/option.js +1583 -0
  217. package/dist/lib/option.js.map +1 -0
  218. package/dist/lib/output-format.d.ts +180 -0
  219. package/dist/lib/output-format.js +213 -0
  220. package/dist/lib/output-format.js.map +1 -0
  221. package/dist/lib/packet.d.ts +501 -0
  222. package/dist/lib/packet.js +590 -0
  223. package/dist/lib/packet.js.map +1 -0
  224. package/dist/lib/rational.d.ts +251 -0
  225. package/dist/lib/rational.js +278 -0
  226. package/dist/lib/rational.js.map +1 -0
  227. package/dist/lib/software-resample-context.d.ts +552 -0
  228. package/dist/lib/software-resample-context.js +592 -0
  229. package/dist/lib/software-resample-context.js.map +1 -0
  230. package/dist/lib/software-scale-context.d.ts +344 -0
  231. package/dist/lib/software-scale-context.js +366 -0
  232. package/dist/lib/software-scale-context.js.map +1 -0
  233. package/dist/lib/stream.d.ts +379 -0
  234. package/dist/lib/stream.js +526 -0
  235. package/dist/lib/stream.js.map +1 -0
  236. package/dist/lib/sync-queue.d.ts +179 -0
  237. package/dist/lib/sync-queue.js +197 -0
  238. package/dist/lib/sync-queue.js.map +1 -0
  239. package/dist/lib/types.d.ts +34 -0
  240. package/dist/lib/types.js +2 -0
  241. package/dist/lib/types.js.map +1 -0
  242. package/dist/lib/utilities.d.ts +1127 -0
  243. package/dist/lib/utilities.js +1225 -0
  244. package/dist/lib/utilities.js.map +1 -0
  245. package/dist/utils/electron.d.ts +49 -0
  246. package/dist/utils/electron.js +63 -0
  247. package/dist/utils/electron.js.map +1 -0
  248. package/dist/utils/index.d.ts +4 -0
  249. package/dist/utils/index.js +5 -0
  250. package/dist/utils/index.js.map +1 -0
  251. package/install/check.js +121 -0
  252. package/install/ffmpeg.js +66 -0
  253. package/jellyfin-ffmpeg.patch +181 -0
  254. package/package.json +129 -0
@@ -0,0 +1,186 @@
1
+ import { FormatContext } from '../../lib/format-context.js';
2
+ import type { AVCodecID } from '../../constants/index.js';
3
+ import type { Muxer } from '../muxer.js';
4
+ /**
5
+ * Streaming protocol utilities.
6
+ *
7
+ * Provides static methods for SDP generation, RTP URL building, and
8
+ * network streaming helpers for RTP/RTSP protocols.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { StreamingUtils, Muxer } from 'node-av/api';
13
+ *
14
+ * // Create RTP outputs
15
+ * const videoOutput = await Muxer.open('rtp://127.0.0.1:5004');
16
+ * const audioOutput = await Muxer.open('rtp://127.0.0.1:5006');
17
+ *
18
+ * // Generate SDP for streaming
19
+ * const sdp = StreamingUtils.createSdp([videoOutput, audioOutput]);
20
+ * if (sdp) {
21
+ * console.log('SDP for streaming:', sdp);
22
+ * // Save to .sdp file or serve via RTSP server
23
+ * }
24
+ * ```
25
+ */
26
+ export declare class StreamingUtils {
27
+ /**
28
+ * Create an SDP (Session Description Protocol) string from demuxer/muxer
29
+ *
30
+ * Generates an SDP description for RTP/RTSP streaming from one or more
31
+ * configured demuxer/muxer. The inputs/outputs should be configured with RTP
32
+ * format and have their streams set up before calling this method.
33
+ *
34
+ * @param contexts - Alternatively, array of FormatContext objects
35
+ *
36
+ * @returns SDP string if successful, null if failed
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * // Set up RTP outputs with streams
41
+ * const output1 = await Muxer.open('rtp://239.0.0.1:5004');
42
+ * await output1.addStream(encoder1);
43
+ *
44
+ * const output2 = await Muxer.open('rtp://239.0.0.1:5006');
45
+ * await output2.addStream(encoder2);
46
+ *
47
+ * // Generate SDP for multicast streaming
48
+ * const sdp = StreamingUtils.createSdp([output1.getFormatContext(), output2.getFormatContext()]);
49
+ * if (sdp) {
50
+ * // Write to file for VLC or other players
51
+ * await fs.writeFile('stream.sdp', sdp);
52
+ * }
53
+ * ```
54
+ */
55
+ static createSdp(contexts: FormatContext[]): string | null;
56
+ /**
57
+ * Generate SDP for RTP/SRTP input using FFmpeg's native SDP generator
58
+ *
59
+ * Creates an RFC-compliant SDP description using FFmpeg's internal logic.
60
+ * This ensures correct codec names, clock rates, and formatting for all codecs.
61
+ *
62
+ * @param configs - Array of stream configurations
63
+ *
64
+ * @param sessionName - Optional session name for the SDP (default: 'RTP Stream')
65
+ *
66
+ * @returns SDP string with proper rtpmap and optional crypto attributes
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * import { StreamingUtils } from 'node-av/api';
71
+ * import { AV_CODEC_ID_OPUS, AV_CODEC_ID_H264 } from 'node-av/constants';
72
+ *
73
+ * // Single audio stream with SRTP
74
+ * const sdp = StreamingUtils.createInputSDP([{
75
+ * port: 5004,
76
+ * codecId: AV_CODEC_ID_OPUS,
77
+ * payloadType: 111,
78
+ * clockRate: 48000,
79
+ * channels: 2,
80
+ * srtp: {
81
+ * key: Buffer.alloc(16, 0x12),
82
+ * salt: Buffer.alloc(14, 0x34)
83
+ * }
84
+ * }]);
85
+ *
86
+ * // Multi-stream (video + audio)
87
+ * const sdp = StreamingUtils.createInputSDP([
88
+ * { port: 5006, codecId: AV_CODEC_ID_H264, payloadType: 96, clockRate: 90000 },
89
+ * { port: 5004, codecId: AV_CODEC_ID_OPUS, payloadType: 111, clockRate: 48000, channels: 2 }
90
+ * ], 'My Stream');
91
+ * ```
92
+ */
93
+ static createInputSDP(configs: {
94
+ port: number;
95
+ codecId: AVCodecID;
96
+ payloadType: number;
97
+ clockRate: number;
98
+ channels?: number;
99
+ fmtp?: string;
100
+ srtp?: {
101
+ key: Buffer;
102
+ salt: Buffer;
103
+ suite?: 'AES_CM_128_HMAC_SHA1_80' | 'AES_CM_256_HMAC_SHA1_80';
104
+ };
105
+ }[], sessionName?: string): string;
106
+ /**
107
+ * Validate if an output is configured for RTP streaming
108
+ *
109
+ * @param output - Muxer to check
110
+ *
111
+ * @returns true if configured for RTP
112
+ *
113
+ * @example
114
+ * ```typescript
115
+ * const output = await Muxer.open('rtp://127.0.0.1:5004');
116
+ * if (StreamingUtils.isRtpOutput(output)) {
117
+ * const sdp = StreamingUtils.createSdpForOutput(output);
118
+ * }
119
+ * ```
120
+ */
121
+ static isRtpOutput(output: Muxer): boolean;
122
+ /**
123
+ * Build RTP URL from components
124
+ *
125
+ * Helper to construct RTP URLs with proper formatting.
126
+ *
127
+ * @param host - IP address or hostname
128
+ *
129
+ * @param port - Port number
130
+ *
131
+ * @param options - Additional options
132
+ *
133
+ * @param options.ttl - Time-to-live for multicast
134
+ *
135
+ * @param options.localrtpport - Local RTP port
136
+ *
137
+ * @param options.localrtcpport - Local RTCP port
138
+ *
139
+ * @param options.pkt_size - Packet size
140
+ *
141
+ * @returns Formatted RTP URL
142
+ *
143
+ * @example
144
+ * ```typescript
145
+ * // Unicast
146
+ * const url1 = StreamingUtils.buildRtpUrl('127.0.0.1', 5004);
147
+ * // 'rtp://127.0.0.1:5004'
148
+ *
149
+ * // Multicast
150
+ * const url2 = StreamingUtils.buildRtpUrl('239.0.0.1', 5004, { ttl: 64 });
151
+ * // 'rtp://239.0.0.1:5004?ttl=64'
152
+ * ```
153
+ */
154
+ static buildRtpUrl(host: string, port: number, options?: {
155
+ ttl?: number;
156
+ localrtpport?: number;
157
+ localrtcpport?: number;
158
+ pkt_size?: number;
159
+ }): string;
160
+ /**
161
+ * Extract all UDP ports from SDP content
162
+ *
163
+ * @param sdp - SDP content string
164
+ *
165
+ * @returns Array of port numbers (one per stream)
166
+ *
167
+ * @example
168
+ * ```typescript
169
+ * import { StreamingUtils } from 'node-av/api';
170
+ *
171
+ * const sdp = `v=0
172
+ * o=- 0 0 IN IP4 127.0.0.1
173
+ * s=Test Stream
174
+ * c=IN IP4 127.0.0.1
175
+ * t=0 0
176
+ * m=audio 5004 RTP/AVP 111
177
+ * a=rtpmap:111 OPUS/48000/2
178
+ * m=video 5006 RTP/AVP 96
179
+ * a=rtpmap:96 H264/90000`;
180
+ *
181
+ * const ports = StreamingUtils.extractPortsFromSDP(sdp);
182
+ * console.log(ports); // [5004, 5006]
183
+ * ```
184
+ */
185
+ static extractPortsFromSDP(sdp: string): number[];
186
+ }
@@ -0,0 +1,309 @@
1
+ import { AVMEDIA_TYPE_VIDEO } from '../../constants/constants.js';
2
+ import { Codec } from '../../lib/codec.js';
3
+ import { FormatContext } from '../../lib/format-context.js';
4
+ import { Rational } from '../../lib/rational.js';
5
+ import { avSdpCreate } from '../../lib/utilities.js';
6
+ /**
7
+ * Streaming protocol utilities.
8
+ *
9
+ * Provides static methods for SDP generation, RTP URL building, and
10
+ * network streaming helpers for RTP/RTSP protocols.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * import { StreamingUtils, Muxer } from 'node-av/api';
15
+ *
16
+ * // Create RTP outputs
17
+ * const videoOutput = await Muxer.open('rtp://127.0.0.1:5004');
18
+ * const audioOutput = await Muxer.open('rtp://127.0.0.1:5006');
19
+ *
20
+ * // Generate SDP for streaming
21
+ * const sdp = StreamingUtils.createSdp([videoOutput, audioOutput]);
22
+ * if (sdp) {
23
+ * console.log('SDP for streaming:', sdp);
24
+ * // Save to .sdp file or serve via RTSP server
25
+ * }
26
+ * ```
27
+ */
28
+ export class StreamingUtils {
29
+ /**
30
+ * Create an SDP (Session Description Protocol) string from demuxer/muxer
31
+ *
32
+ * Generates an SDP description for RTP/RTSP streaming from one or more
33
+ * configured demuxer/muxer. The inputs/outputs should be configured with RTP
34
+ * format and have their streams set up before calling this method.
35
+ *
36
+ * @param contexts - Alternatively, array of FormatContext objects
37
+ *
38
+ * @returns SDP string if successful, null if failed
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * // Set up RTP outputs with streams
43
+ * const output1 = await Muxer.open('rtp://239.0.0.1:5004');
44
+ * await output1.addStream(encoder1);
45
+ *
46
+ * const output2 = await Muxer.open('rtp://239.0.0.1:5006');
47
+ * await output2.addStream(encoder2);
48
+ *
49
+ * // Generate SDP for multicast streaming
50
+ * const sdp = StreamingUtils.createSdp([output1.getFormatContext(), output2.getFormatContext()]);
51
+ * if (sdp) {
52
+ * // Write to file for VLC or other players
53
+ * await fs.writeFile('stream.sdp', sdp);
54
+ * }
55
+ * ```
56
+ */
57
+ static createSdp(contexts) {
58
+ if (contexts?.length === 0) {
59
+ return null;
60
+ }
61
+ return avSdpCreate(contexts);
62
+ }
63
+ /**
64
+ * Generate SDP for RTP/SRTP input using FFmpeg's native SDP generator
65
+ *
66
+ * Creates an RFC-compliant SDP description using FFmpeg's internal logic.
67
+ * This ensures correct codec names, clock rates, and formatting for all codecs.
68
+ *
69
+ * @param configs - Array of stream configurations
70
+ *
71
+ * @param sessionName - Optional session name for the SDP (default: 'RTP Stream')
72
+ *
73
+ * @returns SDP string with proper rtpmap and optional crypto attributes
74
+ *
75
+ * @example
76
+ * ```typescript
77
+ * import { StreamingUtils } from 'node-av/api';
78
+ * import { AV_CODEC_ID_OPUS, AV_CODEC_ID_H264 } from 'node-av/constants';
79
+ *
80
+ * // Single audio stream with SRTP
81
+ * const sdp = StreamingUtils.createInputSDP([{
82
+ * port: 5004,
83
+ * codecId: AV_CODEC_ID_OPUS,
84
+ * payloadType: 111,
85
+ * clockRate: 48000,
86
+ * channels: 2,
87
+ * srtp: {
88
+ * key: Buffer.alloc(16, 0x12),
89
+ * salt: Buffer.alloc(14, 0x34)
90
+ * }
91
+ * }]);
92
+ *
93
+ * // Multi-stream (video + audio)
94
+ * const sdp = StreamingUtils.createInputSDP([
95
+ * { port: 5006, codecId: AV_CODEC_ID_H264, payloadType: 96, clockRate: 90000 },
96
+ * { port: 5004, codecId: AV_CODEC_ID_OPUS, payloadType: 111, clockRate: 48000, channels: 2 }
97
+ * ], 'My Stream');
98
+ * ```
99
+ */
100
+ static createInputSDP(configs, sessionName = 'RTP Stream') {
101
+ const contexts = [];
102
+ try {
103
+ // Create one FormatContext per stream with individual URL (port)
104
+ for (const streamConfig of configs) {
105
+ const codec = Codec.findDecoder(streamConfig.codecId);
106
+ if (!codec) {
107
+ throw new Error(`Codec not found for codec ID: ${streamConfig.codecId}`);
108
+ }
109
+ // Create format context with URL containing the port
110
+ const ctx = new FormatContext();
111
+ ctx.allocContext();
112
+ ctx.url = `rtp://127.0.0.1:${streamConfig.port}`;
113
+ // Create stream with codec parameters
114
+ const stream = ctx.newStream(null);
115
+ stream.codecpar.codecId = streamConfig.codecId;
116
+ stream.codecpar.codecType = codec.type;
117
+ // Set audio-specific parameters
118
+ if (codec.type !== AVMEDIA_TYPE_VIDEO) {
119
+ if (streamConfig.clockRate) {
120
+ stream.codecpar.sampleRate = streamConfig.clockRate;
121
+ }
122
+ if (streamConfig.channels) {
123
+ stream.codecpar.channels = streamConfig.channels;
124
+ }
125
+ }
126
+ // Set time base (required for SDP generation)
127
+ stream.timeBase = new Rational(1, streamConfig.clockRate);
128
+ contexts.push(ctx);
129
+ }
130
+ // Generate SDP using FFmpeg's native generator
131
+ // FFmpeg will automatically use the port from each context's URL and generate RFC-compliant codec names
132
+ let sdp = avSdpCreate(contexts);
133
+ if (!sdp) {
134
+ throw new Error('Failed to generate SDP');
135
+ }
136
+ // Post-process: Replace session name if provided
137
+ if (sessionName !== 'RTP Stream') {
138
+ sdp = sdp.replace(/^s=.*$/m, `s=${sessionName}`);
139
+ }
140
+ // Post-process: Replace payload types, add SRTP crypto lines, and/or custom fmtp
141
+ // Note: We always need to process because FFmpeg assigns payload types automatically
142
+ const sdpLines = sdp.split('\n');
143
+ const newLines = [];
144
+ let streamIndex = -1;
145
+ for (let i = 0; i < sdpLines.length; i++) {
146
+ const line = sdpLines[i];
147
+ if (line.startsWith('m=')) {
148
+ // New media section
149
+ streamIndex++;
150
+ const streamCfg = configs[streamIndex];
151
+ // Replace FFmpeg's auto-assigned payload type with user-specified one
152
+ const replaced = line.replace(/RTP\/AVP\s+(\d+)/, `RTP/AVP ${streamCfg.payloadType}`);
153
+ newLines.push(replaced);
154
+ // Add SRTP crypto line right after m= line if configured
155
+ if (streamCfg?.srtp) {
156
+ const suite = streamCfg.srtp.suite ?? 'AES_CM_128_HMAC_SHA1_80';
157
+ const keyMaterial = Buffer.concat([streamCfg.srtp.key, streamCfg.srtp.salt]).toString('base64');
158
+ newLines.push(`a=crypto:1 ${suite} inline:${keyMaterial}`);
159
+ }
160
+ }
161
+ else if (line.startsWith('a=rtpmap:')) {
162
+ // Replace payload type in rtpmap line
163
+ const streamCfg = configs[streamIndex];
164
+ const replaced = line.replace(/^a=rtpmap:(\d+)/, `a=rtpmap:${streamCfg.payloadType}`);
165
+ newLines.push(replaced);
166
+ // If custom fmtp is provided but FFmpeg didn't generate one, add it
167
+ if (streamCfg?.fmtp && !sdpLines[i + 1]?.startsWith('a=fmtp:')) {
168
+ newLines.push(`a=fmtp:${streamCfg.payloadType} ${streamCfg.fmtp}`);
169
+ }
170
+ }
171
+ else if (line.startsWith('a=fmtp:')) {
172
+ // Replace payload type in fmtp line and optionally replace content
173
+ const streamCfg = configs[streamIndex];
174
+ if (streamCfg?.fmtp) {
175
+ newLines.push(`a=fmtp:${streamCfg.payloadType} ${streamCfg.fmtp}`);
176
+ }
177
+ else {
178
+ const replaced = line.replace(/^a=fmtp:(\d+)/, `a=fmtp:${streamCfg.payloadType}`);
179
+ newLines.push(replaced);
180
+ }
181
+ }
182
+ else {
183
+ newLines.push(line);
184
+ }
185
+ }
186
+ return newLines.join('\n');
187
+ }
188
+ finally {
189
+ // Cleanup all contexts
190
+ for (const ctx of contexts) {
191
+ ctx.freeContext();
192
+ }
193
+ }
194
+ }
195
+ /**
196
+ * Validate if an output is configured for RTP streaming
197
+ *
198
+ * @param output - Muxer to check
199
+ *
200
+ * @returns true if configured for RTP
201
+ *
202
+ * @example
203
+ * ```typescript
204
+ * const output = await Muxer.open('rtp://127.0.0.1:5004');
205
+ * if (StreamingUtils.isRtpOutput(output)) {
206
+ * const sdp = StreamingUtils.createSdpForOutput(output);
207
+ * }
208
+ * ```
209
+ */
210
+ static isRtpOutput(output) {
211
+ // Check if the output format is RTP
212
+ const formatContext = output.getFormatContext();
213
+ const oformat = formatContext?.oformat;
214
+ if (oformat) {
215
+ const name = oformat.name;
216
+ return name === 'rtp' || name === 'rtp_mpegts';
217
+ }
218
+ return false;
219
+ }
220
+ /**
221
+ * Build RTP URL from components
222
+ *
223
+ * Helper to construct RTP URLs with proper formatting.
224
+ *
225
+ * @param host - IP address or hostname
226
+ *
227
+ * @param port - Port number
228
+ *
229
+ * @param options - Additional options
230
+ *
231
+ * @param options.ttl - Time-to-live for multicast
232
+ *
233
+ * @param options.localrtpport - Local RTP port
234
+ *
235
+ * @param options.localrtcpport - Local RTCP port
236
+ *
237
+ * @param options.pkt_size - Packet size
238
+ *
239
+ * @returns Formatted RTP URL
240
+ *
241
+ * @example
242
+ * ```typescript
243
+ * // Unicast
244
+ * const url1 = StreamingUtils.buildRtpUrl('127.0.0.1', 5004);
245
+ * // 'rtp://127.0.0.1:5004'
246
+ *
247
+ * // Multicast
248
+ * const url2 = StreamingUtils.buildRtpUrl('239.0.0.1', 5004, { ttl: 64 });
249
+ * // 'rtp://239.0.0.1:5004?ttl=64'
250
+ * ```
251
+ */
252
+ static buildRtpUrl(host, port, options) {
253
+ let url = `rtp://${host}:${port}`;
254
+ if (options && Object.keys(options).length > 0) {
255
+ const params = new URLSearchParams();
256
+ for (const [key, value] of Object.entries(options)) {
257
+ if (value !== undefined) {
258
+ params.append(key, String(value));
259
+ }
260
+ }
261
+ const queryString = params.toString();
262
+ if (queryString) {
263
+ url += `?${queryString}`;
264
+ }
265
+ }
266
+ return url;
267
+ }
268
+ /**
269
+ * Extract all UDP ports from SDP content
270
+ *
271
+ * @param sdp - SDP content string
272
+ *
273
+ * @returns Array of port numbers (one per stream)
274
+ *
275
+ * @example
276
+ * ```typescript
277
+ * import { StreamingUtils } from 'node-av/api';
278
+ *
279
+ * const sdp = `v=0
280
+ * o=- 0 0 IN IP4 127.0.0.1
281
+ * s=Test Stream
282
+ * c=IN IP4 127.0.0.1
283
+ * t=0 0
284
+ * m=audio 5004 RTP/AVP 111
285
+ * a=rtpmap:111 OPUS/48000/2
286
+ * m=video 5006 RTP/AVP 96
287
+ * a=rtpmap:96 H264/90000`;
288
+ *
289
+ * const ports = StreamingUtils.extractPortsFromSDP(sdp);
290
+ * console.log(ports); // [5004, 5006]
291
+ * ```
292
+ */
293
+ static extractPortsFromSDP(sdp) {
294
+ const ports = [];
295
+ const lines = sdp.split('\n');
296
+ for (const line of lines) {
297
+ if (line.startsWith('m=')) {
298
+ // m=audio 5004 RTP/AVP 111
299
+ // m=video 5006 RTP/AVP 96
300
+ const match = /m=\w+\s+(\d+)/.exec(line);
301
+ if (match) {
302
+ ports.push(parseInt(match[1], 10));
303
+ }
304
+ }
305
+ }
306
+ return ports;
307
+ }
308
+ }
309
+ //# sourceMappingURL=streaming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming.js","sourceRoot":"","sources":["../../../src/api/utilities/streaming.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,193 @@
1
+ import type { AVRounding } from '../../constants/index.js';
2
+ import type { IRational } from '../../lib/types.js';
3
+ /**
4
+ * Timestamp and time base utilities.
5
+ *
6
+ * Provides static methods for converting, rescaling, and comparing timestamps.
7
+ * These utilities are essential for working with different time bases in
8
+ * multimedia streams.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { TimestampUtils } from 'node-av';
13
+ * import { AV_ROUND_NEAR_INF } from 'node-av/constants';
14
+ *
15
+ * // Convert timestamp to string representations
16
+ * const pts = 450000n;
17
+ * console.log(TimestampUtils.toString(pts)); // "450000"
18
+ *
19
+ * const timebase = { num: 1, den: 90000 };
20
+ * console.log(TimestampUtils.toTimeString(pts, timebase)); // "5.000000"
21
+ *
22
+ * // Rescale between time bases
23
+ * const srcTb = { num: 1, den: 90000 };
24
+ * const dstTb = { num: 1, den: 1000 };
25
+ * const rescaled = TimestampUtils.rescale(pts, srcTb, dstTb);
26
+ * console.log(rescaled); // 5000n
27
+ * ```
28
+ */
29
+ export declare class TimestampUtils {
30
+ private constructor();
31
+ /**
32
+ * Convert timestamp to string.
33
+ *
34
+ * Converts a timestamp value to its string representation.
35
+ * Handles special values like AV_NOPTS_VALUE.
36
+ * Direct mapping to av_ts2str()
37
+ *
38
+ * @param ts - Timestamp value (bigint or number), or null
39
+ *
40
+ * @returns String representation
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * import { TimestampUtils } from 'node-av';
45
+ * import { AV_NOPTS_VALUE } from 'node-av/constants';
46
+ *
47
+ * console.log(TimestampUtils.toString(12345n)); // "12345"
48
+ * console.log(TimestampUtils.toString(AV_NOPTS_VALUE)); // "NOPTS"
49
+ * console.log(TimestampUtils.toString(null)); // "NOPTS"
50
+ * ```
51
+ */
52
+ static toString(ts: bigint | number | null): string;
53
+ /**
54
+ * Convert timestamp to time string.
55
+ *
56
+ * Converts a timestamp to a time string in seconds using the provided time base.
57
+ * Direct mapping to av_ts2timestr()
58
+ *
59
+ * @param ts - Timestamp value
60
+ *
61
+ * @param timeBase - Time base for conversion
62
+ *
63
+ * @returns Time string in seconds with decimal places
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * import { TimestampUtils } from 'node-av';
68
+ *
69
+ * const pts = 450000n;
70
+ * const timebase = { num: 1, den: 90000 }; // 90kHz
71
+ *
72
+ * console.log(TimestampUtils.toTimeString(pts, timebase)); // "5.000000"
73
+ * console.log(TimestampUtils.toTimeString(90000n, timebase)); // "1.000000"
74
+ * ```
75
+ */
76
+ static toTimeString(ts: bigint | number | null, timeBase: IRational): string;
77
+ /**
78
+ * Compare timestamps from different time bases.
79
+ *
80
+ * Compares two timestamps that may have different time bases.
81
+ * Direct mapping to av_compare_ts()
82
+ *
83
+ * @param tsA - First timestamp
84
+ *
85
+ * @param tbA - Time base of first timestamp
86
+ *
87
+ * @param tsB - Second timestamp
88
+ *
89
+ * @param tbB - Time base of second timestamp
90
+ *
91
+ * @returns -1 if tsA < tsB, 0 if equal, 1 if tsA > tsB
92
+ *
93
+ * @example
94
+ * ```typescript
95
+ * import { TimestampUtils } from 'node-av';
96
+ *
97
+ * // Compare timestamps from different time bases
98
+ * const pts1 = 90000n;
99
+ * const tb1 = { num: 1, den: 90000 }; // 1 second in 90kHz
100
+ *
101
+ * const pts2 = 1000n;
102
+ * const tb2 = { num: 1, den: 1000 }; // 1 second in 1kHz
103
+ *
104
+ * const result = TimestampUtils.compare(pts1, tb1, pts2, tb2);
105
+ * console.log(result); // 0 (equal - both represent 1 second)
106
+ * ```
107
+ */
108
+ static compare(tsA: bigint | number | null, tbA: IRational, tsB: bigint | number | null, tbB: IRational): number;
109
+ /**
110
+ * Rescale timestamp from one time base to another.
111
+ *
112
+ * Converts a timestamp from source time base to destination time base.
113
+ * Uses AV_ROUND_NEAR_INF rounding.
114
+ * Direct mapping to av_rescale_q()
115
+ *
116
+ * @param a - Timestamp to rescale
117
+ *
118
+ * @param bq - Source time base
119
+ *
120
+ * @param cq - Destination time base
121
+ *
122
+ * @returns Rescaled timestamp
123
+ *
124
+ * @example
125
+ * ```typescript
126
+ * import { TimestampUtils } from 'node-av';
127
+ *
128
+ * // Convert from 90kHz to milliseconds
129
+ * const pts = 450000n;
130
+ * const srcTb = { num: 1, den: 90000 };
131
+ * const dstTb = { num: 1, den: 1000 };
132
+ *
133
+ * const rescaled = TimestampUtils.rescale(pts, srcTb, dstTb);
134
+ * console.log(rescaled); // 5000n (5000 milliseconds = 5 seconds)
135
+ * ```
136
+ */
137
+ static rescale(a: bigint | number | null, bq: IRational, cq: IRational): bigint;
138
+ /**
139
+ * Rescale with specified rounding.
140
+ *
141
+ * Rescales a value with explicit rounding mode.
142
+ * More general than rescale() as it doesn't use time bases.
143
+ * Direct mapping to av_rescale_rnd()
144
+ *
145
+ * @param a - Value to rescale
146
+ *
147
+ * @param b - Multiplier
148
+ *
149
+ * @param c - Divisor
150
+ *
151
+ * @param rnd - Rounding mode
152
+ *
153
+ * @returns Rescaled value: a * b / c
154
+ *
155
+ * @example
156
+ * ```typescript
157
+ * import { TimestampUtils } from 'node-av';
158
+ * import { AV_ROUND_UP, AV_ROUND_DOWN } from 'node-av/constants';
159
+ *
160
+ * // Scale with different rounding modes
161
+ * const value = 100n;
162
+ * const mul = 3n;
163
+ * const div = 7n;
164
+ *
165
+ * const roundUp = TimestampUtils.rescaleRounded(value, mul, div, AV_ROUND_UP);
166
+ * const roundDown = TimestampUtils.rescaleRounded(value, mul, div, AV_ROUND_DOWN);
167
+ *
168
+ * console.log(roundUp); // 43n (rounds up)
169
+ * console.log(roundDown); // 42n (rounds down)
170
+ * ```
171
+ */
172
+ static rescaleRounded(a: bigint | number, b: bigint | number, c: bigint | number, rnd: AVRounding): bigint;
173
+ /**
174
+ * Sleep for specified microseconds.
175
+ *
176
+ * Sleeps for the specified number of microseconds.
177
+ * Direct mapping to av_usleep()
178
+ *
179
+ * @param usec - Microseconds to sleep
180
+ *
181
+ * @example
182
+ * ```typescript
183
+ * import { TimestampUtils } from 'node-av';
184
+ *
185
+ * // Sleep for 100 milliseconds
186
+ * TimestampUtils.sleep(100000);
187
+ *
188
+ * // Sleep for 1 second
189
+ * TimestampUtils.sleep(1000000);
190
+ * ```
191
+ */
192
+ static sleep(usec: number): void;
193
+ }