@gjsify/webrtc 0.3.13 → 0.3.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/esm/get-user-media.js +95 -80
- package/lib/esm/gst-enum-maps.js +55 -59
- package/lib/esm/gst-init.js +19 -22
- package/lib/esm/gst-stats-parser.js +94 -67
- package/lib/esm/gst-utils.js +24 -13
- package/lib/esm/index.js +13 -43
- package/lib/esm/media-device-info.js +23 -22
- package/lib/esm/media-devices.js +150 -139
- package/lib/esm/media-stream-track.js +136 -139
- package/lib/esm/media-stream.js +76 -75
- package/lib/esm/register/data-channel.js +7 -3
- package/lib/esm/register/error.js +6 -2
- package/lib/esm/register/media-devices.js +6 -2
- package/lib/esm/register/media.js +8 -4
- package/lib/esm/register/peer-connection.js +9 -5
- package/lib/esm/rtc-certificate.js +62 -66
- package/lib/esm/rtc-data-channel.js +240 -251
- package/lib/esm/rtc-dtls-transport.js +40 -39
- package/lib/esm/rtc-dtmf-sender.js +92 -100
- package/lib/esm/rtc-error.js +24 -22
- package/lib/esm/rtc-events.js +33 -33
- package/lib/esm/rtc-ice-candidate.js +71 -72
- package/lib/esm/rtc-ice-transport.js +95 -94
- package/lib/esm/rtc-peer-connection.js +796 -845
- package/lib/esm/rtc-rtp-receiver.js +89 -87
- package/lib/esm/rtc-rtp-sender.js +282 -290
- package/lib/esm/rtc-rtp-transceiver.js +92 -93
- package/lib/esm/rtc-sctp-transport.js +38 -38
- package/lib/esm/rtc-session-description.js +47 -51
- package/lib/esm/rtc-stats-report.js +39 -34
- package/lib/esm/rtc-track-event.js +29 -27
- package/lib/esm/rtp-capabilities.js +81 -35
- package/lib/esm/tee-multiplexer.js +58 -60
- package/lib/esm/wpt-helpers.js +128 -112
- package/package.json +13 -13
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -2,297 +2,289 @@ import { Gst } from "./gst-init.js";
|
|
|
2
2
|
import { getRtpCapabilities } from "./rtp-capabilities.js";
|
|
3
3
|
import { RTCDTMFSender } from "./rtc-dtmf-sender.js";
|
|
4
4
|
import { TeeMultiplexer } from "./tee-multiplexer.js";
|
|
5
|
+
|
|
6
|
+
//#region src/rtc-rtp-sender.ts
|
|
5
7
|
const OPUS_PAYLOAD_TYPE = 111;
|
|
6
8
|
const VP8_PAYLOAD_TYPE = 96;
|
|
7
9
|
let _txCounter = 0;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
return this._getStatsForTrack(this._track);
|
|
286
|
-
}
|
|
287
|
-
const { RTCStatsReport: Report } = await import("./rtc-stats-report.js");
|
|
288
|
-
return new Report();
|
|
289
|
-
}
|
|
290
|
-
setStreams(..._streams) {
|
|
291
|
-
}
|
|
292
|
-
static getCapabilities(kind) {
|
|
293
|
-
return getRtpCapabilities(kind);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
export {
|
|
297
|
-
RTCRtpSender
|
|
10
|
+
var RTCRtpSender = class {
|
|
11
|
+
_gstSender;
|
|
12
|
+
_track = null;
|
|
13
|
+
_lastParams = null;
|
|
14
|
+
/** @internal GStreamer pipeline references (set by RTCPeerConnection) */
|
|
15
|
+
_pipeline = null;
|
|
16
|
+
_webrtcbin = null;
|
|
17
|
+
_mlineIndex = -1;
|
|
18
|
+
_elements = [];
|
|
19
|
+
_valve = null;
|
|
20
|
+
_linked = false;
|
|
21
|
+
/** @internal — tee src pad if this sender uses a shared source */
|
|
22
|
+
_teeSrcPad = null;
|
|
23
|
+
/** @internal — stats callback set by RTCPeerConnection */
|
|
24
|
+
_getStatsForTrack = null;
|
|
25
|
+
/** @internal — set by RTCPeerConnection */
|
|
26
|
+
_transport = null;
|
|
27
|
+
/** @internal — DTMF sender, created lazily for audio senders */
|
|
28
|
+
_dtmf = null;
|
|
29
|
+
/** @internal — the kind of media this sender handles */
|
|
30
|
+
_kind = null;
|
|
31
|
+
/** @internal — back-reference for DTMF stopped/direction checks */
|
|
32
|
+
_transceiver = null;
|
|
33
|
+
/** @internal — callback to notify RTCPeerConnection when pipeline changes (cross-pipeline fix) */
|
|
34
|
+
_onPipelineChanged = null;
|
|
35
|
+
constructor(gstSender, pipeline, webrtcbin) {
|
|
36
|
+
this._gstSender = gstSender;
|
|
37
|
+
this._pipeline = pipeline ?? null;
|
|
38
|
+
this._webrtcbin = webrtcbin ?? null;
|
|
39
|
+
}
|
|
40
|
+
get track() {
|
|
41
|
+
return this._track;
|
|
42
|
+
}
|
|
43
|
+
/** Returns the DTMF sender for audio senders, null for video. */
|
|
44
|
+
get dtmf() {
|
|
45
|
+
const kind = this._track?.kind ?? this._kind;
|
|
46
|
+
if (kind !== "audio") return null;
|
|
47
|
+
if (!this._dtmf) {
|
|
48
|
+
const dtmf = new RTCDTMFSender();
|
|
49
|
+
dtmf._isStopped = () => this._transceiver?.stopped ?? false;
|
|
50
|
+
dtmf._getCurrentDirection = () => this._transceiver?.currentDirection ?? null;
|
|
51
|
+
this._dtmf = dtmf;
|
|
52
|
+
}
|
|
53
|
+
return this._dtmf;
|
|
54
|
+
}
|
|
55
|
+
get transport() {
|
|
56
|
+
return this._transport;
|
|
57
|
+
}
|
|
58
|
+
/** @internal */
|
|
59
|
+
_setTrack(track) {
|
|
60
|
+
if (track === null && this._linked) {
|
|
61
|
+
this._teardownPipeline();
|
|
62
|
+
}
|
|
63
|
+
this._track = track;
|
|
64
|
+
}
|
|
65
|
+
/** @internal — called by RTCPeerConnection._createTransceiverWrapper */
|
|
66
|
+
_setMlineIndex(index) {
|
|
67
|
+
this._mlineIndex = index;
|
|
68
|
+
}
|
|
69
|
+
/** @internal — build the outgoing encoder chain and link to webrtcbin */
|
|
70
|
+
_wirePipeline(track) {
|
|
71
|
+
if (this._linked || !this._pipeline || !this._webrtcbin) return;
|
|
72
|
+
const source = track._gstSource;
|
|
73
|
+
if (!source) return;
|
|
74
|
+
const trackAny = track;
|
|
75
|
+
let sourceForChain;
|
|
76
|
+
if (trackAny._gstTee && trackAny._gstPipeline && trackAny._gstPipeline !== this._pipeline) {
|
|
77
|
+
const sourcePipeline = trackAny._gstPipeline;
|
|
78
|
+
const tee = trackAny._gstTee;
|
|
79
|
+
if (this._webrtcbin.get_parent() === this._pipeline) {
|
|
80
|
+
this._pipeline.set_state(Gst.State.NULL);
|
|
81
|
+
this._pipeline.remove(this._webrtcbin);
|
|
82
|
+
}
|
|
83
|
+
sourcePipeline.add(this._webrtcbin);
|
|
84
|
+
this._webrtcbin.sync_state_with_parent();
|
|
85
|
+
this._pipeline = sourcePipeline;
|
|
86
|
+
this._onPipelineChanged?.(sourcePipeline);
|
|
87
|
+
const teeSrcPad = tee.request_pad_simple ? tee.request_pad_simple("src_%u") : tee.get_request_pad("src_%u");
|
|
88
|
+
this._teeSrcPad = teeSrcPad;
|
|
89
|
+
sourceForChain = null;
|
|
90
|
+
} else if (trackAny._teeMultiplexer) {
|
|
91
|
+
const tee = trackAny._teeMultiplexer;
|
|
92
|
+
const teeSrcPad = tee.requestSrcPad();
|
|
93
|
+
this._teeSrcPad = teeSrcPad;
|
|
94
|
+
sourceForChain = null;
|
|
95
|
+
} else if (trackAny._gstPipeline && trackAny._gstPipeline !== this._pipeline) {
|
|
96
|
+
const oldPipeline = trackAny._gstPipeline;
|
|
97
|
+
const sourceSrcPad = source.get_static_pad("src");
|
|
98
|
+
const oldPeer = sourceSrcPad?.get_peer?.();
|
|
99
|
+
if (oldPeer) sourceSrcPad.unlink(oldPeer);
|
|
100
|
+
source.set_state(Gst.State.NULL);
|
|
101
|
+
oldPipeline.remove(source);
|
|
102
|
+
this._pipeline.add(source);
|
|
103
|
+
trackAny._gstPipeline = this._pipeline;
|
|
104
|
+
const tee = new TeeMultiplexer(this._pipeline, source);
|
|
105
|
+
trackAny._teeMultiplexer = tee;
|
|
106
|
+
if (oldPeer) {
|
|
107
|
+
const firstBranch = tee.requestSrcPad();
|
|
108
|
+
if (firstBranch) firstBranch.link(oldPeer);
|
|
109
|
+
}
|
|
110
|
+
const teeSrcPad = tee.requestSrcPad();
|
|
111
|
+
this._teeSrcPad = teeSrcPad;
|
|
112
|
+
sourceForChain = null;
|
|
113
|
+
} else {
|
|
114
|
+
const oldPipeline = trackAny._gstPipeline;
|
|
115
|
+
if (oldPipeline && oldPipeline !== this._pipeline) {
|
|
116
|
+
source.set_state(Gst.State.NULL);
|
|
117
|
+
oldPipeline.remove(source);
|
|
118
|
+
trackAny._gstPipeline = this._pipeline;
|
|
119
|
+
}
|
|
120
|
+
if (source.get_parent() !== this._pipeline) {
|
|
121
|
+
this._pipeline.add(source);
|
|
122
|
+
}
|
|
123
|
+
sourceForChain = source;
|
|
124
|
+
}
|
|
125
|
+
const valve = Gst.ElementFactory.make("valve", null);
|
|
126
|
+
valve.drop = !track.enabled;
|
|
127
|
+
this._valve = valve;
|
|
128
|
+
this._pipeline.add(valve);
|
|
129
|
+
const elements = [valve];
|
|
130
|
+
let lastElement;
|
|
131
|
+
if (track.kind === "audio") {
|
|
132
|
+
const convert = Gst.ElementFactory.make("audioconvert", null);
|
|
133
|
+
const resample = Gst.ElementFactory.make("audioresample", null);
|
|
134
|
+
const encoder = Gst.ElementFactory.make("opusenc", null);
|
|
135
|
+
const payloader = Gst.ElementFactory.make("rtpopuspay", null);
|
|
136
|
+
payloader.pt = OPUS_PAYLOAD_TYPE;
|
|
137
|
+
const capsfilter = Gst.ElementFactory.make("capsfilter", null);
|
|
138
|
+
capsfilter.caps = Gst.Caps.from_string(`application/x-rtp,media=audio,encoding-name=OPUS,clock-rate=48000,payload=${OPUS_PAYLOAD_TYPE}`);
|
|
139
|
+
elements.push(convert, resample, encoder, payloader, capsfilter);
|
|
140
|
+
for (const el of elements) this._pipeline.add(el);
|
|
141
|
+
if (this._teeSrcPad) {
|
|
142
|
+
const valveSinkPad = valve.get_static_pad("sink");
|
|
143
|
+
this._teeSrcPad.link(valveSinkPad);
|
|
144
|
+
} else if (sourceForChain) {
|
|
145
|
+
sourceForChain.link(valve);
|
|
146
|
+
}
|
|
147
|
+
valve.link(convert);
|
|
148
|
+
convert.link(resample);
|
|
149
|
+
resample.link(encoder);
|
|
150
|
+
encoder.link(payloader);
|
|
151
|
+
payloader.link(capsfilter);
|
|
152
|
+
lastElement = capsfilter;
|
|
153
|
+
} else {
|
|
154
|
+
const convert = Gst.ElementFactory.make("videoconvert", null);
|
|
155
|
+
const scale = Gst.ElementFactory.make("videoscale", null);
|
|
156
|
+
const encoder = Gst.ElementFactory.make("vp8enc", null);
|
|
157
|
+
encoder.deadline = 1;
|
|
158
|
+
encoder.keyframe_max_dist = 60;
|
|
159
|
+
const payloader = Gst.ElementFactory.make("rtpvp8pay", null);
|
|
160
|
+
payloader.pt = VP8_PAYLOAD_TYPE;
|
|
161
|
+
const capsfilter = Gst.ElementFactory.make("capsfilter", null);
|
|
162
|
+
capsfilter.caps = Gst.Caps.from_string(`application/x-rtp,media=video,encoding-name=VP8,clock-rate=90000,payload=${VP8_PAYLOAD_TYPE}`);
|
|
163
|
+
elements.push(convert, scale, encoder, payloader, capsfilter);
|
|
164
|
+
for (const el of elements) this._pipeline.add(el);
|
|
165
|
+
if (this._teeSrcPad) {
|
|
166
|
+
const valveSinkPad = valve.get_static_pad("sink");
|
|
167
|
+
this._teeSrcPad.link(valveSinkPad);
|
|
168
|
+
} else if (sourceForChain) {
|
|
169
|
+
sourceForChain.link(valve);
|
|
170
|
+
}
|
|
171
|
+
valve.link(convert);
|
|
172
|
+
convert.link(scale);
|
|
173
|
+
scale.link(encoder);
|
|
174
|
+
encoder.link(payloader);
|
|
175
|
+
payloader.link(capsfilter);
|
|
176
|
+
lastElement = capsfilter;
|
|
177
|
+
}
|
|
178
|
+
const padName = this._mlineIndex >= 0 ? `sink_${this._mlineIndex}` : "sink_%u";
|
|
179
|
+
const sinkPad = this._webrtcbin.request_pad_simple ? this._webrtcbin.request_pad_simple(padName) : this._webrtcbin.get_request_pad(padName);
|
|
180
|
+
if (sinkPad) {
|
|
181
|
+
const srcPad = lastElement.get_static_pad("src");
|
|
182
|
+
srcPad.link(sinkPad);
|
|
183
|
+
}
|
|
184
|
+
const ownedElements = this._teeSrcPad ? elements : [source, ...elements];
|
|
185
|
+
for (const el of ownedElements) {
|
|
186
|
+
el.sync_state_with_parent();
|
|
187
|
+
}
|
|
188
|
+
this._elements = ownedElements;
|
|
189
|
+
this._linked = true;
|
|
190
|
+
track._setEnableCallback((enabled) => {
|
|
191
|
+
if (this._valve) this._valve.drop = !enabled;
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
/** @internal — tear down the encoder chain on close/removeTrack */
|
|
195
|
+
_teardownPipeline() {
|
|
196
|
+
if (!this._linked) return;
|
|
197
|
+
if (this._track) {
|
|
198
|
+
this._track._setEnableCallback(null);
|
|
199
|
+
}
|
|
200
|
+
if (this._teeSrcPad && this._track?._teeMultiplexer) {
|
|
201
|
+
try {
|
|
202
|
+
this._track._teeMultiplexer.releaseSrcPad(this._teeSrcPad);
|
|
203
|
+
} catch {}
|
|
204
|
+
this._teeSrcPad = null;
|
|
205
|
+
}
|
|
206
|
+
for (const el of [...this._elements].reverse()) {
|
|
207
|
+
try {
|
|
208
|
+
el.set_state(Gst.State.NULL);
|
|
209
|
+
this._pipeline?.remove(el);
|
|
210
|
+
} catch {}
|
|
211
|
+
}
|
|
212
|
+
this._elements = [];
|
|
213
|
+
this._valve = null;
|
|
214
|
+
this._linked = false;
|
|
215
|
+
}
|
|
216
|
+
getParameters() {
|
|
217
|
+
if (!this._lastParams) {
|
|
218
|
+
this._lastParams = {
|
|
219
|
+
transactionId: String(++_txCounter),
|
|
220
|
+
encodings: [],
|
|
221
|
+
codecs: [],
|
|
222
|
+
headerExtensions: [],
|
|
223
|
+
rtcp: {}
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
...this._lastParams,
|
|
228
|
+
encodings: [...this._lastParams.encodings]
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
async setParameters(params) {
|
|
232
|
+
if (!this._lastParams) {
|
|
233
|
+
throw new DOMException("getParameters must be called before setParameters", "InvalidStateError");
|
|
234
|
+
}
|
|
235
|
+
if (params.transactionId !== this._lastParams.transactionId) {
|
|
236
|
+
throw new DOMException("transactionId mismatch", "InvalidModificationError");
|
|
237
|
+
}
|
|
238
|
+
this._lastParams = null;
|
|
239
|
+
}
|
|
240
|
+
async replaceTrack(track) {
|
|
241
|
+
if (track === null) {
|
|
242
|
+
this._teardownPipeline();
|
|
243
|
+
this._track = null;
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
if (this._track !== null && track.kind !== this._track.kind) {
|
|
247
|
+
throw new TypeError("Cannot replace track with different kind");
|
|
248
|
+
}
|
|
249
|
+
if (this._linked && track._gstSource) {
|
|
250
|
+
const oldSource = this._elements[0];
|
|
251
|
+
const newSource = track._gstSource;
|
|
252
|
+
const oldPipeline = track._gstPipeline;
|
|
253
|
+
if (oldPipeline && oldPipeline !== this._pipeline) {
|
|
254
|
+
newSource.set_state(Gst.State.NULL);
|
|
255
|
+
oldPipeline.remove(newSource);
|
|
256
|
+
track._gstPipeline = this._pipeline;
|
|
257
|
+
}
|
|
258
|
+
oldSource.set_state(Gst.State.NULL);
|
|
259
|
+
oldSource.unlink(this._valve);
|
|
260
|
+
this._pipeline.remove(oldSource);
|
|
261
|
+
this._pipeline.add(newSource);
|
|
262
|
+
newSource.link(this._valve);
|
|
263
|
+
newSource.sync_state_with_parent();
|
|
264
|
+
this._elements[0] = newSource;
|
|
265
|
+
} else if (track._gstSource) {
|
|
266
|
+
this._wirePipeline(track);
|
|
267
|
+
}
|
|
268
|
+
if (this._track) this._track._setEnableCallback(null);
|
|
269
|
+
this._track = track;
|
|
270
|
+
if (this._linked) {
|
|
271
|
+
track._setEnableCallback((enabled) => {
|
|
272
|
+
if (this._valve) this._valve.drop = !enabled;
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
async getStats() {
|
|
277
|
+
if (this._getStatsForTrack && this._track) {
|
|
278
|
+
return this._getStatsForTrack(this._track);
|
|
279
|
+
}
|
|
280
|
+
const { RTCStatsReport: Report } = await import("./rtc-stats-report.js");
|
|
281
|
+
return new Report();
|
|
282
|
+
}
|
|
283
|
+
setStreams(..._streams) {}
|
|
284
|
+
static getCapabilities(kind) {
|
|
285
|
+
return getRtpCapabilities(kind);
|
|
286
|
+
}
|
|
298
287
|
};
|
|
288
|
+
|
|
289
|
+
//#endregion
|
|
290
|
+
export { RTCRtpSender };
|