werift 0.22.9 → 0.24.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.
Files changed (173) hide show
  1. package/README.md +46 -0
  2. package/lib/common/src/transport.d.ts +22 -9
  3. package/lib/common/src/transport.js +152 -25
  4. package/lib/common/src/transport.js.map +1 -1
  5. package/lib/dtls/src/flight/server/flight6.js +12 -2
  6. package/lib/dtls/src/flight/server/flight6.js.map +1 -1
  7. package/lib/dtls/src/server.js +6 -1
  8. package/lib/dtls/src/server.js.map +1 -1
  9. package/lib/dtls/src/socket.d.ts +1 -0
  10. package/lib/dtls/src/socket.js +3 -0
  11. package/lib/dtls/src/socket.js.map +1 -1
  12. package/lib/ice/src/candidate.d.ts +16 -1
  13. package/lib/ice/src/candidate.js +99 -15
  14. package/lib/ice/src/candidate.js.map +1 -1
  15. package/lib/ice/src/ice.d.ts +2 -0
  16. package/lib/ice/src/ice.js +171 -41
  17. package/lib/ice/src/ice.js.map +1 -1
  18. package/lib/ice/src/iceBase.d.ts +23 -2
  19. package/lib/ice/src/iceBase.js +63 -1
  20. package/lib/ice/src/iceBase.js.map +1 -1
  21. package/lib/ice/src/index.d.ts +2 -0
  22. package/lib/ice/src/index.js +2 -0
  23. package/lib/ice/src/index.js.map +1 -1
  24. package/lib/ice/src/stun/const.d.ts +1 -26
  25. package/lib/ice/src/stun/const.js +15 -54
  26. package/lib/ice/src/stun/const.js.map +1 -1
  27. package/lib/ice/src/stun/message.d.ts +1 -25
  28. package/lib/ice/src/stun/message.js +15 -149
  29. package/lib/ice/src/stun/message.js.map +1 -1
  30. package/lib/ice/src/stun/protocol.d.ts +1 -1
  31. package/lib/ice/src/stun/protocol.js +2 -2
  32. package/lib/ice/src/stun/protocol.js.map +1 -1
  33. package/lib/ice/src/stun/tcpFrame.d.ts +5 -0
  34. package/lib/ice/src/stun/tcpFrame.js +26 -0
  35. package/lib/ice/src/stun/tcpFrame.js.map +1 -0
  36. package/lib/ice/src/stun/tcpProtocol.d.ts +51 -0
  37. package/lib/ice/src/stun/tcpProtocol.js +326 -0
  38. package/lib/ice/src/stun/tcpProtocol.js.map +1 -0
  39. package/lib/ice/src/stun/transaction.d.ts +2 -1
  40. package/lib/ice/src/stun/transaction.js +9 -3
  41. package/lib/ice/src/stun/transaction.js.map +1 -1
  42. package/lib/ice/src/turn/frame.d.ts +1 -0
  43. package/lib/ice/src/turn/frame.js +18 -0
  44. package/lib/ice/src/turn/frame.js.map +1 -0
  45. package/lib/ice/src/turn/protocol.d.ts +9 -7
  46. package/lib/ice/src/turn/protocol.js +32 -44
  47. package/lib/ice/src/turn/protocol.js.map +1 -1
  48. package/lib/ice/src/types/model.d.ts +1 -1
  49. package/lib/ice/src/types/model.js.map +1 -1
  50. package/lib/{ice → ice-server}/src/stun/attributes.d.ts +12 -5
  51. package/lib/{ice → ice-server}/src/stun/attributes.js +60 -19
  52. package/lib/ice-server/src/stun/attributes.js.map +1 -0
  53. package/lib/ice-server/src/stun/const.d.ts +28 -0
  54. package/lib/ice-server/src/stun/const.js +88 -0
  55. package/lib/ice-server/src/stun/const.js.map +1 -0
  56. package/lib/ice-server/src/stun/message.d.ts +37 -0
  57. package/lib/ice-server/src/stun/message.js +190 -0
  58. package/lib/ice-server/src/stun/message.js.map +1 -0
  59. package/lib/ice-server/src/turn/auth.d.ts +1 -0
  60. package/lib/ice-server/src/turn/auth.js +10 -0
  61. package/lib/ice-server/src/turn/auth.js.map +1 -0
  62. package/lib/ice-server/src/turn/frame.d.ts +13 -0
  63. package/lib/ice-server/src/turn/frame.js +69 -0
  64. package/lib/ice-server/src/turn/frame.js.map +1 -0
  65. package/lib/index.mjs +3075 -883
  66. package/lib/nonstandard/index.mjs +1964 -447
  67. package/lib/rtp/src/extra/container/mp4/container.d.ts +9 -6
  68. package/lib/rtp/src/extra/container/mp4/container.js +258 -173
  69. package/lib/rtp/src/extra/container/mp4/container.js.map +1 -1
  70. package/lib/rtp/src/extra/container/mp4/h264.d.ts +1 -0
  71. package/lib/rtp/src/extra/container/mp4/h264.js +13 -0
  72. package/lib/rtp/src/extra/container/mp4/h264.js.map +1 -1
  73. package/lib/rtp/src/extra/processor/mp4.d.ts +11 -7
  74. package/lib/rtp/src/extra/processor/mp4.js +115 -60
  75. package/lib/rtp/src/extra/processor/mp4.js.map +1 -1
  76. package/lib/rtp/src/extra/processor/mp4Callback.d.ts +2 -3
  77. package/lib/rtp/src/extra/processor/mp4Callback.js +5 -3
  78. package/lib/rtp/src/extra/processor/mp4Callback.js.map +1 -1
  79. package/lib/rtp/src/index.d.ts +1 -0
  80. package/lib/rtp/src/index.js +1 -0
  81. package/lib/rtp/src/index.js.map +1 -1
  82. package/lib/rtp/src/srtp/cipher/ctr.d.ts +3 -3
  83. package/lib/rtp/src/srtp/cipher/ctr.js +25 -14
  84. package/lib/rtp/src/srtp/cipher/ctr.js.map +1 -1
  85. package/lib/rtp/src/srtp/cipher/gcm.d.ts +3 -3
  86. package/lib/rtp/src/srtp/cipher/gcm.js +57 -20
  87. package/lib/rtp/src/srtp/cipher/gcm.js.map +1 -1
  88. package/lib/rtp/src/srtp/cipher/index.d.ts +1 -1
  89. package/lib/rtp/src/srtp/cipher/index.js +1 -1
  90. package/lib/rtp/src/srtp/cipher/index.js.map +1 -1
  91. package/lib/rtp/src/srtp/context/srtp.d.ts +2 -1
  92. package/lib/rtp/src/srtp/context/srtp.js +22 -5
  93. package/lib/rtp/src/srtp/context/srtp.js.map +1 -1
  94. package/lib/rtp/src/srtp/error.d.ts +3 -0
  95. package/lib/rtp/src/srtp/error.js +11 -0
  96. package/lib/rtp/src/srtp/error.js.map +1 -0
  97. package/lib/rtp/src/srtp/packet.d.ts +5 -0
  98. package/lib/rtp/src/srtp/packet.js +48 -0
  99. package/lib/rtp/src/srtp/packet.js.map +1 -0
  100. package/lib/webrtc/src/dataChannel.d.ts +4 -2
  101. package/lib/webrtc/src/dataChannel.js +14 -4
  102. package/lib/webrtc/src/dataChannel.js.map +1 -1
  103. package/lib/webrtc/src/errors.d.ts +3 -0
  104. package/lib/webrtc/src/errors.js +11 -0
  105. package/lib/webrtc/src/errors.js.map +1 -0
  106. package/lib/webrtc/src/helper.d.ts +5 -1
  107. package/lib/webrtc/src/helper.js +33 -1
  108. package/lib/webrtc/src/helper.js.map +1 -1
  109. package/lib/webrtc/src/media/receiver/statistics.d.ts +4 -1
  110. package/lib/webrtc/src/media/receiver/statistics.js +22 -0
  111. package/lib/webrtc/src/media/receiver/statistics.js.map +1 -1
  112. package/lib/webrtc/src/media/rtpReceiver.d.ts +15 -2
  113. package/lib/webrtc/src/media/rtpReceiver.js +135 -20
  114. package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
  115. package/lib/webrtc/src/media/rtpSender.d.ts +32 -7
  116. package/lib/webrtc/src/media/rtpSender.js +177 -28
  117. package/lib/webrtc/src/media/rtpSender.js.map +1 -1
  118. package/lib/webrtc/src/media/rtpTransceiver.d.ts +13 -4
  119. package/lib/webrtc/src/media/rtpTransceiver.js +26 -5
  120. package/lib/webrtc/src/media/rtpTransceiver.js.map +1 -1
  121. package/lib/webrtc/src/media/stats.d.ts +15 -1
  122. package/lib/webrtc/src/media/stats.js +55 -1
  123. package/lib/webrtc/src/media/stats.js.map +1 -1
  124. package/lib/webrtc/src/media/track.d.ts +2 -1
  125. package/lib/webrtc/src/media/track.js +7 -1
  126. package/lib/webrtc/src/media/track.js.map +1 -1
  127. package/lib/webrtc/src/nonstandard/dummyMedia.d.ts +19 -0
  128. package/lib/webrtc/src/nonstandard/dummyMedia.js +157 -0
  129. package/lib/webrtc/src/nonstandard/dummyMedia.js.map +1 -0
  130. package/lib/webrtc/src/nonstandard/navigator.d.ts +18 -8
  131. package/lib/webrtc/src/nonstandard/navigator.js +96 -32
  132. package/lib/webrtc/src/nonstandard/navigator.js.map +1 -1
  133. package/lib/webrtc/src/nonstandard/userMedia/packetizer.d.ts +16 -0
  134. package/lib/webrtc/src/nonstandard/userMedia/packetizer.js +360 -0
  135. package/lib/webrtc/src/nonstandard/userMedia/packetizer.js.map +1 -0
  136. package/lib/webrtc/src/nonstandard/userMedia.d.ts +71 -31
  137. package/lib/webrtc/src/nonstandard/userMedia.js +454 -108
  138. package/lib/webrtc/src/nonstandard/userMedia.js.map +1 -1
  139. package/lib/webrtc/src/peerConnection.d.ts +185 -49
  140. package/lib/webrtc/src/peerConnection.js +477 -107
  141. package/lib/webrtc/src/peerConnection.js.map +1 -1
  142. package/lib/webrtc/src/sctpManager.d.ts +2 -2
  143. package/lib/webrtc/src/sctpManager.js +30 -9
  144. package/lib/webrtc/src/sctpManager.js.map +1 -1
  145. package/lib/webrtc/src/sdp.d.ts +10 -7
  146. package/lib/webrtc/src/sdp.js +39 -9
  147. package/lib/webrtc/src/sdp.js.map +1 -1
  148. package/lib/webrtc/src/sdpManager.d.ts +5 -4
  149. package/lib/webrtc/src/sdpManager.js +53 -31
  150. package/lib/webrtc/src/sdpManager.js.map +1 -1
  151. package/lib/webrtc/src/secureTransportManager.d.ts +13 -4
  152. package/lib/webrtc/src/secureTransportManager.js +101 -23
  153. package/lib/webrtc/src/secureTransportManager.js.map +1 -1
  154. package/lib/webrtc/src/transceiverManager.d.ts +5 -4
  155. package/lib/webrtc/src/transceiverManager.js +64 -64
  156. package/lib/webrtc/src/transceiverManager.js.map +1 -1
  157. package/lib/webrtc/src/transport/dtls.d.ts +16 -4
  158. package/lib/webrtc/src/transport/dtls.js +208 -35
  159. package/lib/webrtc/src/transport/dtls.js.map +1 -1
  160. package/lib/webrtc/src/transport/ice.d.ts +21 -3
  161. package/lib/webrtc/src/transport/ice.js +159 -30
  162. package/lib/webrtc/src/transport/ice.js.map +1 -1
  163. package/lib/webrtc/src/transport/sctp.d.ts +10 -3
  164. package/lib/webrtc/src/transport/sctp.js +44 -13
  165. package/lib/webrtc/src/transport/sctp.js.map +1 -1
  166. package/lib/webrtc/src/utils.d.ts +14 -4
  167. package/lib/webrtc/src/utils.js +138 -16
  168. package/lib/webrtc/src/utils.js.map +1 -1
  169. package/package.json +7 -4
  170. package/lib/ice/src/stun/attributes.js.map +0 -1
  171. package/lib/rtp/src/extra/container/mp4/mp4box.d.ts +0 -5
  172. package/lib/rtp/src/extra/container/mp4/mp4box.js +0 -32
  173. package/lib/rtp/src/extra/container/mp4/mp4box.js.map +0 -1
@@ -1,6 +1,7 @@
1
1
  import { Event } from "../../../imports/common";
2
2
  type DecoderConfig = AudioDecoderConfig | VideoDecoderConfig;
3
3
  type EncodedChunk = EncodedAudioChunk | EncodedVideoChunk;
4
+ type TrackKind = "audio" | "video";
4
5
  export type DataType = "init" | "delta" | "key";
5
6
  export interface Mp4Data {
6
7
  type: DataType;
@@ -13,8 +14,13 @@ export declare class Mp4Container {
13
14
  #private;
14
15
  private props;
15
16
  audioTrack?: number;
17
+ frameBuffer: (EncodedChunk & {
18
+ track: TrackKind;
19
+ })[];
20
+ onData: Event<[Mp4Data | {
21
+ eol: true;
22
+ }]>;
16
23
  videoTrack?: number;
17
- onData: Event<[Mp4Data]>;
18
24
  constructor(props: {
19
25
  track: {
20
26
  audio: boolean;
@@ -23,12 +29,9 @@ export declare class Mp4Container {
23
29
  });
24
30
  get tracksReady(): boolean;
25
31
  write(frame: (DecoderConfig | EncodedChunk) & {
26
- track: "video" | "audio";
32
+ track: TrackKind;
27
33
  }): void;
28
- frameBuffer: (EncodedChunk & {
29
- track: "video" | "audio";
30
- })[];
31
- private _enqueue;
34
+ stop(): Promise<void>;
32
35
  }
33
36
  export interface AudioDecoderConfig {
34
37
  codec: string;
@@ -1,53 +1,20 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
2
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
+ };
35
7
  var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
36
8
  if (kind === "m") throw new TypeError("Private method is not writable");
37
9
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
38
10
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
39
11
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
40
12
  };
41
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
42
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
43
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
44
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
45
- };
46
- var _Mp4Container_instances, _Mp4Container_mp4, _Mp4Container_audioFrame, _Mp4Container_videoFrame, _Mp4Container_audioSegment, _Mp4Container_videoSegment, _Mp4Container_init, _Mp4Container_enqueue;
13
+ var _Mp4Container_instances, _Mp4Container_audioFrame, _Mp4Container_audioMeta, _Mp4Container_audioSource, _Mp4Container_currentFragment, _Mp4Container_ftyp, _Mp4Container_initializationEmitted, _Mp4Container_lastAudioDuration, _Mp4Container_lastMoof, _Mp4Container_lastMoofTimestamp, _Mp4Container_lastVideoDuration, _Mp4Container_moov, _Mp4Container_onDataOperation, _Mp4Container_operation, _Mp4Container_output, _Mp4Container_startPromise, _Mp4Container_stopPromise, _Mp4Container_stopped, _Mp4Container_videoFrame, _Mp4Container_videoMeta, _Mp4Container_videoSource, _Mp4Container_init, _Mp4Container_enqueue, _Mp4Container_drainFrameBuffer, _Mp4Container_ensureOutputStarted, _Mp4Container_emitInitializationSegment, _Mp4Container_emitData, _Mp4Container_flushOnData, _Mp4Container_enqueueOperation, _Mp4Container_defaultKind, _Mp4Container_flushPendingFrame, _Mp4Container_processFrame, _Mp4Container_writePacket, _Mp4Container_rememberFragmentPacket;
47
14
  Object.defineProperty(exports, "__esModule", { value: true });
48
15
  exports.mp4SupportedCodecs = exports.Mp4Container = void 0;
16
+ const mediabunny_1 = require("mediabunny");
49
17
  const common_1 = require("../../../imports/common");
50
- const MP4 = __importStar(require("./mp4box"));
51
18
  class Mp4Container {
52
19
  constructor(props) {
53
20
  _Mp4Container_instances.add(this);
@@ -57,37 +24,50 @@ class Mp4Container {
57
24
  writable: true,
58
25
  value: props
59
26
  });
60
- _Mp4Container_mp4.set(this, void 0);
61
27
  _Mp4Container_audioFrame.set(this, void 0);
62
- _Mp4Container_videoFrame.set(this, void 0); // 1 frame buffer
28
+ _Mp4Container_audioMeta.set(this, void 0);
29
+ _Mp4Container_audioSource.set(this, void 0);
30
+ _Mp4Container_currentFragment.set(this, void 0);
31
+ _Mp4Container_ftyp.set(this, void 0);
32
+ _Mp4Container_initializationEmitted.set(this, false);
33
+ _Mp4Container_lastAudioDuration.set(this, 0);
34
+ _Mp4Container_lastMoof.set(this, void 0);
35
+ _Mp4Container_lastMoofTimestamp.set(this, 0);
36
+ _Mp4Container_lastVideoDuration.set(this, 0);
37
+ _Mp4Container_moov.set(this, void 0);
38
+ _Mp4Container_onDataOperation.set(this, Promise.resolve());
39
+ _Mp4Container_operation.set(this, Promise.resolve());
40
+ _Mp4Container_output.set(this, void 0);
41
+ _Mp4Container_startPromise.set(this, void 0);
42
+ _Mp4Container_stopPromise.set(this, void 0);
43
+ _Mp4Container_stopped.set(this, false);
44
+ _Mp4Container_videoFrame.set(this, void 0);
45
+ _Mp4Container_videoMeta.set(this, void 0);
46
+ _Mp4Container_videoSource.set(this, void 0);
63
47
  Object.defineProperty(this, "audioTrack", {
64
48
  enumerable: true,
65
49
  configurable: true,
66
50
  writable: true,
67
51
  value: void 0
68
52
  });
69
- Object.defineProperty(this, "videoTrack", {
53
+ Object.defineProperty(this, "frameBuffer", {
70
54
  enumerable: true,
71
55
  configurable: true,
72
56
  writable: true,
73
- value: void 0
57
+ value: []
74
58
  });
75
- _Mp4Container_audioSegment.set(this, 0);
76
- _Mp4Container_videoSegment.set(this, 0);
77
59
  Object.defineProperty(this, "onData", {
78
60
  enumerable: true,
79
61
  configurable: true,
80
62
  writable: true,
81
63
  value: new common_1.Event()
82
64
  });
83
- Object.defineProperty(this, "frameBuffer", {
65
+ Object.defineProperty(this, "videoTrack", {
84
66
  enumerable: true,
85
67
  configurable: true,
86
68
  writable: true,
87
- value: []
69
+ value: void 0
88
70
  });
89
- __classPrivateFieldSet(this, _Mp4Container_mp4, new MP4.ISOFile(), "f");
90
- __classPrivateFieldGet(this, _Mp4Container_mp4, "f").init();
91
71
  }
92
72
  get tracksReady() {
93
73
  let ready = true;
@@ -107,156 +87,248 @@ class Mp4Container {
107
87
  return __classPrivateFieldGet(this, _Mp4Container_instances, "m", _Mp4Container_enqueue).call(this, frame);
108
88
  }
109
89
  }
110
- _enqueue(frame) {
111
- const track = frame.track === "audio" ? this.audioTrack : this.videoTrack;
112
- if (!track) {
113
- throw new Error("track missing");
114
- }
115
- // Check if we should create a new segment
116
- if (frame.track === "video") {
117
- if (frame.type == "key") {
118
- __classPrivateFieldSet(this, _Mp4Container_videoSegment, __classPrivateFieldGet(this, _Mp4Container_videoSegment, "f") + 1, "f");
119
- }
120
- else if (__classPrivateFieldGet(this, _Mp4Container_videoSegment, "f") == 0) {
121
- throw new Error("must start with keyframe");
122
- }
90
+ stop() {
91
+ if (__classPrivateFieldGet(this, _Mp4Container_stopPromise, "f")) {
92
+ return __classPrivateFieldGet(this, _Mp4Container_stopPromise, "f");
123
93
  }
124
- else {
125
- __classPrivateFieldSet(this, _Mp4Container_audioSegment, __classPrivateFieldGet(this, _Mp4Container_audioSegment, "f") + 1, "f");
126
- }
127
- // We need a one frame buffer to compute the duration
128
- if (frame.track === "video") {
129
- if (!__classPrivateFieldGet(this, _Mp4Container_videoFrame, "f")) {
130
- __classPrivateFieldSet(this, _Mp4Container_videoFrame, frame, "f");
94
+ __classPrivateFieldSet(this, _Mp4Container_stopped, true, "f");
95
+ __classPrivateFieldSet(this, _Mp4Container_stopPromise, __classPrivateFieldGet(this, _Mp4Container_instances, "m", _Mp4Container_enqueueOperation).call(this, async () => {
96
+ if (!this.tracksReady) {
97
+ this.frameBuffer = [];
131
98
  return;
132
99
  }
133
- }
134
- else {
135
- if (!__classPrivateFieldGet(this, _Mp4Container_audioFrame, "f")) {
136
- __classPrivateFieldSet(this, _Mp4Container_audioFrame, frame, "f");
137
- return;
100
+ await __classPrivateFieldGet(this, _Mp4Container_instances, "m", _Mp4Container_ensureOutputStarted).call(this);
101
+ await __classPrivateFieldGet(this, _Mp4Container_instances, "m", _Mp4Container_drainFrameBuffer).call(this);
102
+ await __classPrivateFieldGet(this, _Mp4Container_instances, "m", _Mp4Container_flushPendingFrame).call(this, "audio");
103
+ await __classPrivateFieldGet(this, _Mp4Container_instances, "m", _Mp4Container_flushPendingFrame).call(this, "video");
104
+ __classPrivateFieldGet(this, _Mp4Container_audioSource, "f")?.close();
105
+ __classPrivateFieldGet(this, _Mp4Container_videoSource, "f")?.close();
106
+ if (__classPrivateFieldGet(this, _Mp4Container_output, "f")) {
107
+ await __classPrivateFieldGet(this, _Mp4Container_output, "f").finalize();
138
108
  }
109
+ await __classPrivateFieldGet(this, _Mp4Container_instances, "m", _Mp4Container_flushOnData).call(this);
110
+ }), "f");
111
+ return __classPrivateFieldGet(this, _Mp4Container_stopPromise, "f");
112
+ }
113
+ }
114
+ exports.Mp4Container = Mp4Container;
115
+ _Mp4Container_audioFrame = new WeakMap(), _Mp4Container_audioMeta = new WeakMap(), _Mp4Container_audioSource = new WeakMap(), _Mp4Container_currentFragment = new WeakMap(), _Mp4Container_ftyp = new WeakMap(), _Mp4Container_initializationEmitted = new WeakMap(), _Mp4Container_lastAudioDuration = new WeakMap(), _Mp4Container_lastMoof = new WeakMap(), _Mp4Container_lastMoofTimestamp = new WeakMap(), _Mp4Container_lastVideoDuration = new WeakMap(), _Mp4Container_moov = new WeakMap(), _Mp4Container_onDataOperation = new WeakMap(), _Mp4Container_operation = new WeakMap(), _Mp4Container_output = new WeakMap(), _Mp4Container_startPromise = new WeakMap(), _Mp4Container_stopPromise = new WeakMap(), _Mp4Container_stopped = new WeakMap(), _Mp4Container_videoFrame = new WeakMap(), _Mp4Container_videoMeta = new WeakMap(), _Mp4Container_videoSource = new WeakMap(), _Mp4Container_instances = new WeakSet(), _Mp4Container_init = function _Mp4Container_init(frame) {
116
+ if (frame.track === "audio") {
117
+ if (isVideoConfig(frame)) {
118
+ throw new Error("audio track requires an audio decoder config");
139
119
  }
140
- const bufferFrame = frame.track === "video" ? __classPrivateFieldGet(this, _Mp4Container_videoFrame, "f") : __classPrivateFieldGet(this, _Mp4Container_audioFrame, "f");
141
- if (!bufferFrame) {
142
- throw new Error("bufferFrame missing");
120
+ if (frame.codec !== "opus") {
121
+ throw new Error(`unsupported codec: ${frame.codec}`);
143
122
  }
144
- const duration = frame.timestamp - bufferFrame.timestamp;
145
- // TODO avoid this extra copy by writing to the mdat directly
146
- // ...which means changing mp4box.js to take an offset instead of ArrayBuffer
147
- const buffer = new ArrayBuffer(bufferFrame.byteLength);
148
- bufferFrame.copyTo(buffer);
149
- // Add the sample to the container
150
- __classPrivateFieldGet(this, _Mp4Container_mp4, "f").addSample(track, buffer, {
151
- duration,
152
- dts: bufferFrame.timestamp,
153
- cts: bufferFrame.timestamp,
154
- is_sync: bufferFrame.type == "key",
155
- });
156
- const stream = new MP4.Stream(undefined, 0, MP4.Stream.BIG_ENDIAN);
157
- // Moof and mdat atoms are written in pairs.
158
- // TODO remove the moof/mdat from the Box to reclaim memory once everything works
159
- for (;;) {
160
- const moof = __classPrivateFieldGet(this, _Mp4Container_mp4, "f").moofs.shift();
161
- const mdat = __classPrivateFieldGet(this, _Mp4Container_mp4, "f").mdats.shift();
162
- if (!moof && !mdat)
163
- break;
164
- if (!moof)
165
- throw new Error("moof missing");
166
- if (!mdat)
167
- throw new Error("mdat missing");
168
- moof.write(stream);
169
- mdat.write(stream);
123
+ __classPrivateFieldSet(this, _Mp4Container_audioMeta, {
124
+ decoderConfig: {
125
+ codec: "opus",
126
+ description: frame.description != undefined
127
+ ? new Uint8Array(frame.description)
128
+ : undefined,
129
+ numberOfChannels: frame.numberOfChannels,
130
+ sampleRate: frame.sampleRate,
131
+ },
132
+ }, "f");
133
+ this.audioTrack = 1;
134
+ }
135
+ else {
136
+ if (!isVideoConfig(frame)) {
137
+ throw new Error("video track requires a video decoder config");
170
138
  }
171
- // TODO avoid this extra copy by writing to the buffer provided in copyTo
172
- const data = new Uint8Array(stream.buffer);
173
- if (frame.track === "video") {
174
- __classPrivateFieldSet(this, _Mp4Container_videoFrame, frame, "f");
139
+ if (!frame.codec.startsWith("avc1")) {
140
+ throw new Error(`unsupported codec: ${frame.codec}`);
175
141
  }
176
- else {
177
- __classPrivateFieldSet(this, _Mp4Container_audioFrame, frame, "f");
142
+ if (frame.codedWidth == undefined || frame.codedHeight == undefined) {
143
+ throw new Error("missing coded video dimensions");
178
144
  }
179
- const res = {
180
- type: bufferFrame.type,
181
- timestamp: bufferFrame.timestamp,
182
- kind: frame.track,
183
- duration,
184
- data,
185
- };
186
- this.onData.execute(res);
145
+ __classPrivateFieldSet(this, _Mp4Container_videoMeta, {
146
+ decoderConfig: {
147
+ codec: frame.codec,
148
+ codedHeight: frame.codedHeight,
149
+ codedWidth: frame.codedWidth,
150
+ description: frame.description != undefined
151
+ ? new Uint8Array(frame.description)
152
+ : undefined,
153
+ displayAspectHeight: frame.displayAspectHeight,
154
+ displayAspectWidth: frame.displayAspectWidth,
155
+ },
156
+ }, "f");
157
+ this.videoTrack = this.props.track.audio ? 2 : 1;
187
158
  }
188
- }
189
- exports.Mp4Container = Mp4Container;
190
- _Mp4Container_mp4 = new WeakMap(), _Mp4Container_audioFrame = new WeakMap(), _Mp4Container_videoFrame = new WeakMap(), _Mp4Container_audioSegment = new WeakMap(), _Mp4Container_videoSegment = new WeakMap(), _Mp4Container_instances = new WeakSet(), _Mp4Container_init = function _Mp4Container_init(frame) {
191
- let codec = frame.codec.substring(0, 4);
192
- if (codec == "opus") {
193
- codec = "Opus";
159
+ if (!this.tracksReady) {
160
+ return;
194
161
  }
195
- const options = {
196
- type: codec,
197
- timescale: 1000000,
198
- };
199
- if (isVideoConfig(frame)) {
200
- options.width = frame.codedWidth;
201
- options.height = frame.codedHeight;
162
+ void __classPrivateFieldGet(this, _Mp4Container_instances, "m", _Mp4Container_enqueueOperation).call(this, async () => {
163
+ await __classPrivateFieldGet(this, _Mp4Container_instances, "m", _Mp4Container_ensureOutputStarted).call(this);
164
+ await __classPrivateFieldGet(this, _Mp4Container_instances, "m", _Mp4Container_drainFrameBuffer).call(this);
165
+ });
166
+ }, _Mp4Container_enqueue = function _Mp4Container_enqueue(frame) {
167
+ this.frameBuffer.push(frame);
168
+ if (!this.tracksReady) {
169
+ return;
202
170
  }
203
- else {
204
- options.channel_count = frame.numberOfChannels;
205
- options.samplerate = frame.sampleRate;
206
- options.hdlr = "soun";
171
+ void __classPrivateFieldGet(this, _Mp4Container_instances, "m", _Mp4Container_enqueueOperation).call(this, async () => {
172
+ await __classPrivateFieldGet(this, _Mp4Container_instances, "m", _Mp4Container_ensureOutputStarted).call(this);
173
+ await __classPrivateFieldGet(this, _Mp4Container_instances, "m", _Mp4Container_drainFrameBuffer).call(this);
174
+ });
175
+ }, _Mp4Container_drainFrameBuffer = async function _Mp4Container_drainFrameBuffer() {
176
+ const frames = this.frameBuffer;
177
+ this.frameBuffer = [];
178
+ for (const frame of frames) {
179
+ await __classPrivateFieldGet(this, _Mp4Container_instances, "m", _Mp4Container_processFrame).call(this, frame);
207
180
  }
208
- if (!frame.description)
209
- throw new Error("missing frame description");
210
- const desc = frame.description;
211
- if (codec === "avc1") {
212
- options.avcDecoderConfigRecord = desc;
181
+ }, _Mp4Container_ensureOutputStarted = async function _Mp4Container_ensureOutputStarted() {
182
+ if (__classPrivateFieldGet(this, _Mp4Container_startPromise, "f")) {
183
+ await __classPrivateFieldGet(this, _Mp4Container_startPromise, "f");
184
+ return;
213
185
  }
214
- else if (codec === "hev1") {
215
- options.hevcDecoderConfigRecord = desc;
186
+ if (!this.tracksReady) {
187
+ return;
216
188
  }
217
- else if (codec === "Opus") {
218
- // description is an identification header: https://datatracker.ietf.org/doc/html/rfc7845#section-5.1
219
- // The first 8 bytes are the magic string "OpusHead", followed by what we actually want.
220
- const dops = new MP4.BoxParser.dOpsBox();
221
- // Annoyingly, the header is little endian while MP4 is big endian, so we have to parse.
222
- dops.parse(new MP4.Stream(desc, 8, MP4.Stream.LITTLE_ENDIAN));
223
- options.description = dops;
189
+ const output = new mediabunny_1.Output({
190
+ format: new mediabunny_1.Mp4OutputFormat({
191
+ fastStart: "fragmented",
192
+ minimumFragmentDuration: 0,
193
+ onFtyp: (data) => {
194
+ __classPrivateFieldSet(this, _Mp4Container_ftyp, copyBytes(data), "f");
195
+ },
196
+ onMdat: (data) => {
197
+ if (!__classPrivateFieldGet(this, _Mp4Container_lastMoof, "f")) {
198
+ throw new Error("moof missing before mdat");
199
+ }
200
+ const fragment = __classPrivateFieldGet(this, _Mp4Container_currentFragment, "f");
201
+ const timestamp = fragment
202
+ ? fragment.timestamp
203
+ : Math.round(__classPrivateFieldGet(this, _Mp4Container_lastMoofTimestamp, "f") * 1000000);
204
+ const duration = fragment?.duration ?? 0;
205
+ const kind = fragment?.kind ?? __classPrivateFieldGet(this, _Mp4Container_instances, "m", _Mp4Container_defaultKind).call(this);
206
+ const type = fragment?.type ?? "key";
207
+ const segment = concatBytes(__classPrivateFieldGet(this, _Mp4Container_lastMoof, "f"), data);
208
+ __classPrivateFieldSet(this, _Mp4Container_currentFragment, undefined, "f");
209
+ __classPrivateFieldSet(this, _Mp4Container_lastMoof, undefined, "f");
210
+ void __classPrivateFieldGet(this, _Mp4Container_instances, "m", _Mp4Container_emitData).call(this, {
211
+ type,
212
+ timestamp,
213
+ duration,
214
+ data: segment,
215
+ kind,
216
+ });
217
+ },
218
+ onMoof: (data, _position, timestamp) => {
219
+ __classPrivateFieldSet(this, _Mp4Container_lastMoof, copyBytes(data), "f");
220
+ __classPrivateFieldSet(this, _Mp4Container_lastMoofTimestamp, timestamp, "f");
221
+ },
222
+ onMoov: (data) => {
223
+ __classPrivateFieldSet(this, _Mp4Container_moov, copyBytes(data), "f");
224
+ __classPrivateFieldGet(this, _Mp4Container_instances, "m", _Mp4Container_emitInitializationSegment).call(this);
225
+ },
226
+ }),
227
+ target: new mediabunny_1.NullTarget(),
228
+ });
229
+ if (__classPrivateFieldGet(this, _Mp4Container_audioMeta, "f")) {
230
+ __classPrivateFieldSet(this, _Mp4Container_audioSource, new mediabunny_1.EncodedAudioPacketSource("opus"), "f");
231
+ output.addAudioTrack(__classPrivateFieldGet(this, _Mp4Container_audioSource, "f"));
232
+ }
233
+ if (__classPrivateFieldGet(this, _Mp4Container_videoMeta, "f")) {
234
+ __classPrivateFieldSet(this, _Mp4Container_videoSource, new mediabunny_1.EncodedVideoPacketSource("avc"), "f");
235
+ output.addVideoTrack(__classPrivateFieldGet(this, _Mp4Container_videoSource, "f"));
236
+ }
237
+ __classPrivateFieldSet(this, _Mp4Container_output, output, "f");
238
+ __classPrivateFieldSet(this, _Mp4Container_startPromise, output.start(), "f");
239
+ await __classPrivateFieldGet(this, _Mp4Container_startPromise, "f");
240
+ }, _Mp4Container_emitInitializationSegment = function _Mp4Container_emitInitializationSegment() {
241
+ if (__classPrivateFieldGet(this, _Mp4Container_initializationEmitted, "f") || !__classPrivateFieldGet(this, _Mp4Container_ftyp, "f") || !__classPrivateFieldGet(this, _Mp4Container_moov, "f")) {
242
+ return;
243
+ }
244
+ __classPrivateFieldSet(this, _Mp4Container_initializationEmitted, true, "f");
245
+ void __classPrivateFieldGet(this, _Mp4Container_instances, "m", _Mp4Container_emitData).call(this, {
246
+ type: "init",
247
+ timestamp: 0,
248
+ duration: 0,
249
+ data: concatBytes(__classPrivateFieldGet(this, _Mp4Container_ftyp, "f"), __classPrivateFieldGet(this, _Mp4Container_moov, "f")),
250
+ kind: __classPrivateFieldGet(this, _Mp4Container_instances, "m", _Mp4Container_defaultKind).call(this),
251
+ });
252
+ }, _Mp4Container_emitData = function _Mp4Container_emitData(data) {
253
+ const next = __classPrivateFieldGet(this, _Mp4Container_onDataOperation, "f").then(() => this.onData.execute(data));
254
+ __classPrivateFieldSet(this, _Mp4Container_onDataOperation, next, "f");
255
+ return next;
256
+ }, _Mp4Container_flushOnData = async function _Mp4Container_flushOnData() {
257
+ await __classPrivateFieldGet(this, _Mp4Container_onDataOperation, "f");
258
+ }, _Mp4Container_enqueueOperation = function _Mp4Container_enqueueOperation(operation) {
259
+ const next = __classPrivateFieldGet(this, _Mp4Container_operation, "f").then(operation);
260
+ __classPrivateFieldSet(this, _Mp4Container_operation, next, "f");
261
+ return next;
262
+ }, _Mp4Container_defaultKind = function _Mp4Container_defaultKind() {
263
+ return this.props.track.video ? "video" : "audio";
264
+ }, _Mp4Container_flushPendingFrame = async function _Mp4Container_flushPendingFrame(track) {
265
+ const buffered = track === "audio" ? __classPrivateFieldGet(this, _Mp4Container_audioFrame, "f") : __classPrivateFieldGet(this, _Mp4Container_videoFrame, "f");
266
+ if (!buffered) {
267
+ return;
268
+ }
269
+ const duration = track === "audio" ? __classPrivateFieldGet(this, _Mp4Container_lastAudioDuration, "f") : __classPrivateFieldGet(this, _Mp4Container_lastVideoDuration, "f");
270
+ await __classPrivateFieldGet(this, _Mp4Container_instances, "m", _Mp4Container_writePacket).call(this, buffered, duration);
271
+ if (track === "audio") {
272
+ __classPrivateFieldSet(this, _Mp4Container_audioFrame, undefined, "f");
224
273
  }
225
274
  else {
226
- throw new Error(`unsupported codec: ${codec}`);
275
+ __classPrivateFieldSet(this, _Mp4Container_videoFrame, undefined, "f");
227
276
  }
228
- const track = __classPrivateFieldGet(this, _Mp4Container_mp4, "f").addTrack(options);
229
- if (track == undefined) {
230
- throw new Error("failed to initialize MP4 track");
277
+ }, _Mp4Container_processFrame = async function _Mp4Container_processFrame(frame) {
278
+ const buffered = frame.track === "audio" ? __classPrivateFieldGet(this, _Mp4Container_audioFrame, "f") : __classPrivateFieldGet(this, _Mp4Container_videoFrame, "f");
279
+ if (!buffered) {
280
+ if (frame.track === "audio") {
281
+ __classPrivateFieldSet(this, _Mp4Container_audioFrame, frame, "f");
282
+ }
283
+ else {
284
+ __classPrivateFieldSet(this, _Mp4Container_videoFrame, frame, "f");
285
+ }
286
+ return;
231
287
  }
288
+ const duration = Math.max(frame.timestamp - buffered.timestamp, 0);
289
+ await __classPrivateFieldGet(this, _Mp4Container_instances, "m", _Mp4Container_writePacket).call(this, buffered, duration);
232
290
  if (frame.track === "audio") {
233
- this.audioTrack = track;
291
+ __classPrivateFieldSet(this, _Mp4Container_audioFrame, frame, "f");
292
+ __classPrivateFieldSet(this, _Mp4Container_lastAudioDuration, duration, "f");
234
293
  }
235
294
  else {
236
- this.videoTrack = track;
295
+ __classPrivateFieldSet(this, _Mp4Container_videoFrame, frame, "f");
296
+ __classPrivateFieldSet(this, _Mp4Container_lastVideoDuration, duration, "f");
237
297
  }
238
- if (!this.tracksReady) {
239
- return;
298
+ }, _Mp4Container_writePacket = async function _Mp4Container_writePacket(frame, duration) {
299
+ const data = new Uint8Array(frame.byteLength);
300
+ frame.copyTo(data.buffer);
301
+ const packet = new mediabunny_1.EncodedPacket(data, frame.type, frame.timestamp / 1000000, duration / 1000000);
302
+ if (frame.track === "audio") {
303
+ if (!__classPrivateFieldGet(this, _Mp4Container_audioSource, "f") || !__classPrivateFieldGet(this, _Mp4Container_audioMeta, "f")) {
304
+ throw new Error("audio track missing");
305
+ }
306
+ await __classPrivateFieldGet(this, _Mp4Container_audioSource, "f").add(packet, __classPrivateFieldGet(this, _Mp4Container_audioMeta, "f"));
240
307
  }
241
- const buffer = MP4.ISOFile.writeInitializationSegment(__classPrivateFieldGet(this, _Mp4Container_mp4, "f").ftyp, __classPrivateFieldGet(this, _Mp4Container_mp4, "f").moov, 0, 0);
242
- const data = new Uint8Array(buffer);
243
- const res = {
244
- type: "init",
245
- timestamp: 0,
246
- duration: 0,
247
- data,
248
- kind: frame.track,
249
- };
250
- this.onData.execute(res);
251
- }, _Mp4Container_enqueue = function _Mp4Container_enqueue(frame) {
252
- this.frameBuffer.push(frame);
253
- if (!this.tracksReady) {
308
+ else {
309
+ if (!__classPrivateFieldGet(this, _Mp4Container_videoSource, "f") || !__classPrivateFieldGet(this, _Mp4Container_videoMeta, "f")) {
310
+ throw new Error("video track missing");
311
+ }
312
+ await __classPrivateFieldGet(this, _Mp4Container_videoSource, "f").add(packet, __classPrivateFieldGet(this, _Mp4Container_videoMeta, "f"));
313
+ }
314
+ __classPrivateFieldGet(this, _Mp4Container_instances, "m", _Mp4Container_rememberFragmentPacket).call(this, frame.track, frame.type, frame.timestamp, duration);
315
+ }, _Mp4Container_rememberFragmentPacket = function _Mp4Container_rememberFragmentPacket(kind, type, timestamp, duration) {
316
+ const end = timestamp + duration;
317
+ if (!__classPrivateFieldGet(this, _Mp4Container_currentFragment, "f")) {
318
+ __classPrivateFieldSet(this, _Mp4Container_currentFragment, {
319
+ kind,
320
+ type,
321
+ timestamp,
322
+ duration,
323
+ }, "f");
254
324
  return;
255
325
  }
256
- for (const frame of this.frameBuffer) {
257
- this._enqueue(frame);
326
+ if (kind === "video" && type === "key") {
327
+ __classPrivateFieldGet(this, _Mp4Container_currentFragment, "f").type = "key";
258
328
  }
259
- this.frameBuffer = [];
329
+ const fragmentEnd = Math.max(__classPrivateFieldGet(this, _Mp4Container_currentFragment, "f").timestamp + __classPrivateFieldGet(this, _Mp4Container_currentFragment, "f").duration, end);
330
+ __classPrivateFieldGet(this, _Mp4Container_currentFragment, "f").duration =
331
+ fragmentEnd - __classPrivateFieldGet(this, _Mp4Container_currentFragment, "f").timestamp;
260
332
  };
261
333
  function isDecoderConfig(frame) {
262
334
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
@@ -266,4 +338,17 @@ function isVideoConfig(frame) {
266
338
  return frame.codedWidth !== undefined;
267
339
  }
268
340
  exports.mp4SupportedCodecs = ["avc1", "opus"];
341
+ function concatBytes(...parts) {
342
+ const size = parts.reduce((sum, part) => sum + part.byteLength, 0);
343
+ const combined = new Uint8Array(size);
344
+ let offset = 0;
345
+ for (const part of parts) {
346
+ combined.set(part, offset);
347
+ offset += part.byteLength;
348
+ }
349
+ return combined;
350
+ }
351
+ function copyBytes(data) {
352
+ return new Uint8Array(data);
353
+ }
269
354
  //# sourceMappingURL=container.js.map