@gjsify/webrtc 0.3.16 → 0.3.18
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 +1 -108
- package/lib/esm/gst-enum-maps.js +1 -84
- package/lib/esm/gst-init.js +6 -28
- package/lib/esm/gst-stats-parser.js +1 -106
- package/lib/esm/gst-utils.js +1 -27
- package/lib/esm/index.js +1 -23
- package/lib/esm/media-device-info.js +1 -24
- package/lib/esm/media-devices.js +1 -158
- package/lib/esm/media-stream-track.js +1 -139
- package/lib/esm/media-stream.js +1 -79
- package/lib/esm/register/data-channel.js +1 -12
- package/lib/esm/register/error.js +1 -12
- package/lib/esm/register/media-devices.js +1 -11
- package/lib/esm/register/media.js +1 -16
- package/lib/esm/register/peer-connection.js +1 -20
- package/lib/esm/register.js +1 -5
- package/lib/esm/rtc-certificate.js +1 -66
- package/lib/esm/rtc-data-channel.js +1 -250
- package/lib/esm/rtc-dtls-transport.js +1 -42
- package/lib/esm/rtc-dtmf-sender.js +1 -101
- package/lib/esm/rtc-error.js +1 -26
- package/lib/esm/rtc-events.js +1 -35
- package/lib/esm/rtc-ice-candidate.js +1 -74
- package/lib/esm/rtc-ice-transport.js +1 -97
- package/lib/esm/rtc-peer-connection.js +1 -812
- package/lib/esm/rtc-rtp-receiver.js +1 -93
- package/lib/esm/rtc-rtp-sender.js +1 -290
- package/lib/esm/rtc-rtp-transceiver.js +1 -96
- package/lib/esm/rtc-sctp-transport.js +1 -40
- package/lib/esm/rtc-session-description.js +1 -53
- package/lib/esm/rtc-stats-report.js +1 -40
- package/lib/esm/rtc-track-event.js +1 -31
- package/lib/esm/rtp-capabilities.js +1 -87
- package/lib/esm/tee-multiplexer.js +1 -60
- package/lib/esm/wpt-helpers.js +1 -138
- package/package.json +14 -14
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,87 +1 @@
|
|
|
1
|
-
|
|
2
|
-
const AUDIO_CAPABILITIES = {
|
|
3
|
-
codecs: [
|
|
4
|
-
{
|
|
5
|
-
mimeType: "audio/opus",
|
|
6
|
-
clockRate: 48e3,
|
|
7
|
-
channels: 2,
|
|
8
|
-
sdpFmtpLine: "minptime=10;useinbandfec=1"
|
|
9
|
-
},
|
|
10
|
-
{
|
|
11
|
-
mimeType: "audio/G722",
|
|
12
|
-
clockRate: 8e3,
|
|
13
|
-
channels: 1
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
mimeType: "audio/PCMU",
|
|
17
|
-
clockRate: 8e3,
|
|
18
|
-
channels: 1
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
mimeType: "audio/PCMA",
|
|
22
|
-
clockRate: 8e3,
|
|
23
|
-
channels: 1
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
mimeType: "audio/telephone-event",
|
|
27
|
-
clockRate: 8e3,
|
|
28
|
-
channels: 1
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
mimeType: "audio/red",
|
|
32
|
-
clockRate: 48e3,
|
|
33
|
-
channels: 2
|
|
34
|
-
}
|
|
35
|
-
],
|
|
36
|
-
headerExtensions: [
|
|
37
|
-
{ uri: "urn:ietf:params:rtp-hdrext:ssrc-audio-level" },
|
|
38
|
-
{ uri: "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time" },
|
|
39
|
-
{ uri: "urn:ietf:params:rtp-hdrext:sdes:mid" }
|
|
40
|
-
]
|
|
41
|
-
};
|
|
42
|
-
const VIDEO_CAPABILITIES = {
|
|
43
|
-
codecs: [
|
|
44
|
-
{
|
|
45
|
-
mimeType: "video/VP8",
|
|
46
|
-
clockRate: 9e4
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
mimeType: "video/rtx",
|
|
50
|
-
clockRate: 9e4
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
mimeType: "video/H264",
|
|
54
|
-
clockRate: 9e4,
|
|
55
|
-
sdpFmtpLine: "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f"
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
mimeType: "video/VP9",
|
|
59
|
-
clockRate: 9e4
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
mimeType: "video/red",
|
|
63
|
-
clockRate: 9e4
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
mimeType: "video/ulpfec",
|
|
67
|
-
clockRate: 9e4
|
|
68
|
-
}
|
|
69
|
-
],
|
|
70
|
-
headerExtensions: [
|
|
71
|
-
{ uri: "urn:ietf:params:rtp-hdrext:toffset" },
|
|
72
|
-
{ uri: "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time" },
|
|
73
|
-
{ uri: "urn:3gpp:video-orientation" },
|
|
74
|
-
{ uri: "urn:ietf:params:rtp-hdrext:sdes:mid" },
|
|
75
|
-
{ uri: "urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id" },
|
|
76
|
-
{ uri: "urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id" }
|
|
77
|
-
]
|
|
78
|
-
};
|
|
79
|
-
/** Shared implementation for RTCRtpSender.getCapabilities / RTCRtpReceiver.getCapabilities. */
|
|
80
|
-
function getRtpCapabilities(kind) {
|
|
81
|
-
if (kind === "audio") return AUDIO_CAPABILITIES;
|
|
82
|
-
if (kind === "video") return VIDEO_CAPABILITIES;
|
|
83
|
-
return null;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
//#endregion
|
|
87
|
-
export { getRtpCapabilities };
|
|
1
|
+
const e={codecs:[{mimeType:`audio/opus`,clockRate:48e3,channels:2,sdpFmtpLine:`minptime=10;useinbandfec=1`},{mimeType:`audio/G722`,clockRate:8e3,channels:1},{mimeType:`audio/PCMU`,clockRate:8e3,channels:1},{mimeType:`audio/PCMA`,clockRate:8e3,channels:1},{mimeType:`audio/telephone-event`,clockRate:8e3,channels:1},{mimeType:`audio/red`,clockRate:48e3,channels:2}],headerExtensions:[{uri:`urn:ietf:params:rtp-hdrext:ssrc-audio-level`},{uri:`http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time`},{uri:`urn:ietf:params:rtp-hdrext:sdes:mid`}]},t={codecs:[{mimeType:`video/VP8`,clockRate:9e4},{mimeType:`video/rtx`,clockRate:9e4},{mimeType:`video/H264`,clockRate:9e4,sdpFmtpLine:`level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f`},{mimeType:`video/VP9`,clockRate:9e4},{mimeType:`video/red`,clockRate:9e4},{mimeType:`video/ulpfec`,clockRate:9e4}],headerExtensions:[{uri:`urn:ietf:params:rtp-hdrext:toffset`},{uri:`http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time`},{uri:`urn:3gpp:video-orientation`},{uri:`urn:ietf:params:rtp-hdrext:sdes:mid`},{uri:`urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id`},{uri:`urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id`}]};function n(n){return n===`audio`?e:n===`video`?t:null}export{n as getRtpCapabilities};
|
|
@@ -1,60 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
//#region src/tee-multiplexer.ts
|
|
4
|
-
/**
|
|
5
|
-
* Manages a GStreamer `tee` element that fans out one source to multiple
|
|
6
|
-
* consumer branches. Each branch gets its own src pad from the tee.
|
|
7
|
-
*/
|
|
8
|
-
var TeeMultiplexer = class {
|
|
9
|
-
_tee;
|
|
10
|
-
_pipeline;
|
|
11
|
-
_branchCount = 0;
|
|
12
|
-
/**
|
|
13
|
-
* Create a tee in the given pipeline and link it to the source's output.
|
|
14
|
-
* The source must already be in the pipeline.
|
|
15
|
-
*/
|
|
16
|
-
constructor(pipeline, source) {
|
|
17
|
-
this._pipeline = pipeline;
|
|
18
|
-
this._tee = Gst.ElementFactory.make("tee", null);
|
|
19
|
-
this._tee.allow_not_linked = true;
|
|
20
|
-
pipeline.add(this._tee);
|
|
21
|
-
this._tee.sync_state_with_parent();
|
|
22
|
-
source.link(this._tee);
|
|
23
|
-
}
|
|
24
|
-
/** Request a new src pad from the tee for a consumer branch. */
|
|
25
|
-
requestSrcPad() {
|
|
26
|
-
const padName = "src_%u";
|
|
27
|
-
const srcPad = this._tee.request_pad_simple ? this._tee.request_pad_simple(padName) : this._tee.get_request_pad(padName);
|
|
28
|
-
if (srcPad) this._branchCount++;
|
|
29
|
-
return srcPad;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Release a branch's src pad from the tee.
|
|
33
|
-
* Adds a DROP probe before unlinking to prevent errors.
|
|
34
|
-
*/
|
|
35
|
-
releaseSrcPad(srcPad) {
|
|
36
|
-
if (!srcPad) return;
|
|
37
|
-
try {
|
|
38
|
-
srcPad.add_probe(Gst.PadProbeType.BLOCK_DOWNSTREAM, () => Gst.PadProbeReturn.DROP);
|
|
39
|
-
} catch {}
|
|
40
|
-
try {
|
|
41
|
-
const peer = srcPad.get_peer();
|
|
42
|
-
if (peer) srcPad.unlink(peer);
|
|
43
|
-
} catch {}
|
|
44
|
-
try {
|
|
45
|
-
this._tee.release_request_pad(srcPad);
|
|
46
|
-
} catch {}
|
|
47
|
-
this._branchCount--;
|
|
48
|
-
}
|
|
49
|
-
/** Number of active branches. */
|
|
50
|
-
get branchCount() {
|
|
51
|
-
return this._branchCount;
|
|
52
|
-
}
|
|
53
|
-
/** The tee element (for pipeline queries). */
|
|
54
|
-
get element() {
|
|
55
|
-
return this._tee;
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
//#endregion
|
|
60
|
-
export { TeeMultiplexer };
|
|
1
|
+
import{Gst as e}from"./gst-init.js";var t=class{_tee;_pipeline;_branchCount=0;constructor(t,n){this._pipeline=t,this._tee=e.ElementFactory.make(`tee`,null),this._tee.allow_not_linked=!0,t.add(this._tee),this._tee.sync_state_with_parent(),n.link(this._tee)}requestSrcPad(){let e=`src_%u`,t=this._tee.request_pad_simple?this._tee.request_pad_simple(e):this._tee.get_request_pad(e);return t&&this._branchCount++,t}releaseSrcPad(t){if(t){try{t.add_probe(e.PadProbeType.BLOCK_DOWNSTREAM,()=>e.PadProbeReturn.DROP)}catch{}try{let e=t.get_peer();e&&t.unlink(e)}catch{}try{this._tee.release_request_pad(t)}catch{}this._branchCount--}}get branchCount(){return this._branchCount}get element(){return this._tee}};export{t as TeeMultiplexer};
|
package/lib/esm/wpt-helpers.js
CHANGED
|
@@ -1,138 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import "./index.js";
|
|
3
|
-
|
|
4
|
-
//#region src/wpt-helpers.ts
|
|
5
|
-
/** Mirror WPT's `createPeerConnectionWithCleanup` — returns a fresh pc. */
|
|
6
|
-
function createPeerConnection() {
|
|
7
|
-
return new RTCPeerConnection();
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Mirror WPT's `exchangeOfferAnswer(pc1, pc2)` + `exchangeIceCandidates`.
|
|
11
|
-
* Runs the full handshake to completion.
|
|
12
|
-
*/
|
|
13
|
-
async function exchangeOfferAnswer(pc1, pc2) {
|
|
14
|
-
pc1.onicecandidate = (ev) => {
|
|
15
|
-
if (ev.candidate) pc2.addIceCandidate(ev.candidate.toJSON()).catch(() => {});
|
|
16
|
-
};
|
|
17
|
-
pc2.onicecandidate = (ev) => {
|
|
18
|
-
if (ev.candidate) pc1.addIceCandidate(ev.candidate.toJSON()).catch(() => {});
|
|
19
|
-
};
|
|
20
|
-
const offer = await pc1.createOffer();
|
|
21
|
-
await pc1.setLocalDescription(offer);
|
|
22
|
-
await pc2.setRemoteDescription(offer);
|
|
23
|
-
const answer = await pc2.createAnswer();
|
|
24
|
-
await pc2.setLocalDescription(answer);
|
|
25
|
-
await pc1.setRemoteDescription(answer);
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Port of WPT `createDataChannelPair(t, options, pc1, pc2)` — returns
|
|
29
|
-
* `[dc1, dc2]` both in `'open'` state, handshake complete. If `options.negotiated`
|
|
30
|
-
* both sides pre-create the channel with matching id; otherwise pc1 creates
|
|
31
|
-
* and pc2 receives via `ondatachannel`.
|
|
32
|
-
*/
|
|
33
|
-
async function createDataChannelPair(options = {}, pc1 = createPeerConnection(), pc2 = createPeerConnection(), label = "wpt") {
|
|
34
|
-
let pair;
|
|
35
|
-
let bothOpen;
|
|
36
|
-
if (options.negotiated) {
|
|
37
|
-
const dc1 = pc1.createDataChannel(label, options);
|
|
38
|
-
const dc2 = pc2.createDataChannel(label, options);
|
|
39
|
-
pair = [dc1, dc2];
|
|
40
|
-
bothOpen = Promise.all(pair.map((dc) => new Promise((res, rej) => {
|
|
41
|
-
if (dc.readyState === "open") return res();
|
|
42
|
-
dc.onopen = () => res();
|
|
43
|
-
dc.onerror = (ev) => rej(ev?.error ?? new Error("onerror"));
|
|
44
|
-
})));
|
|
45
|
-
} else {
|
|
46
|
-
const dc1 = pc1.createDataChannel(label, options);
|
|
47
|
-
bothOpen = Promise.all([new Promise((res, rej) => {
|
|
48
|
-
if (dc1.readyState === "open") return res();
|
|
49
|
-
dc1.onopen = () => res();
|
|
50
|
-
dc1.onerror = (ev) => rej(ev?.error ?? new Error("onerror"));
|
|
51
|
-
}), new Promise((res, rej) => {
|
|
52
|
-
pc2.ondatachannel = (ev) => {
|
|
53
|
-
const dc2 = ev.channel;
|
|
54
|
-
if (dc2.readyState === "open") return res(dc2);
|
|
55
|
-
dc2.onopen = () => res(dc2);
|
|
56
|
-
dc2.onerror = (e) => rej(e?.error ?? new Error("onerror"));
|
|
57
|
-
};
|
|
58
|
-
}).then((dc2) => {
|
|
59
|
-
pair[1] = dc2;
|
|
60
|
-
})]);
|
|
61
|
-
pair = [dc1, undefined];
|
|
62
|
-
}
|
|
63
|
-
await exchangeOfferAnswer(pc1, pc2);
|
|
64
|
-
await bothOpen;
|
|
65
|
-
return [
|
|
66
|
-
pair[0],
|
|
67
|
-
pair[1],
|
|
68
|
-
pc1,
|
|
69
|
-
pc2
|
|
70
|
-
];
|
|
71
|
-
}
|
|
72
|
-
/** Port of WPT `awaitMessage(channel)` — resolves with the next incoming data. */
|
|
73
|
-
function awaitMessage(channel) {
|
|
74
|
-
return new Promise((resolve, reject) => {
|
|
75
|
-
const messageHandler = (ev) => {
|
|
76
|
-
channel.removeEventListener("message", messageHandler);
|
|
77
|
-
channel.removeEventListener("error", errorHandler);
|
|
78
|
-
resolve(ev.data);
|
|
79
|
-
};
|
|
80
|
-
const errorHandler = (ev) => {
|
|
81
|
-
channel.removeEventListener("message", messageHandler);
|
|
82
|
-
channel.removeEventListener("error", errorHandler);
|
|
83
|
-
reject(ev?.error ?? new Error("channel error"));
|
|
84
|
-
};
|
|
85
|
-
channel.addEventListener("message", messageHandler);
|
|
86
|
-
channel.addEventListener("error", errorHandler);
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Mirror WPT's `EventWatcher(t, target, events)` — accumulates events in
|
|
91
|
-
* order and returns `wait_for(types)` that matches the expected sequence.
|
|
92
|
-
*/
|
|
93
|
-
var EventWatcher = class {
|
|
94
|
-
_events = [];
|
|
95
|
-
_waiters = [];
|
|
96
|
-
constructor(target, eventTypes) {
|
|
97
|
-
for (const type of eventTypes) {
|
|
98
|
-
target.addEventListener(type, () => {
|
|
99
|
-
this._events.push(type);
|
|
100
|
-
this._tryResolve();
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
wait_for(expected) {
|
|
105
|
-
const types = Array.isArray(expected) ? expected : [expected];
|
|
106
|
-
return new Promise((resolve, reject) => {
|
|
107
|
-
this._waiters.push({
|
|
108
|
-
types,
|
|
109
|
-
resolve,
|
|
110
|
-
reject
|
|
111
|
-
});
|
|
112
|
-
this._tryResolve();
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
_tryResolve() {
|
|
116
|
-
while (this._waiters.length > 0 && this._events.length >= this._waiters[0].types.length) {
|
|
117
|
-
const waiter = this._waiters.shift();
|
|
118
|
-
const got = this._events.splice(0, waiter.types.length);
|
|
119
|
-
const matches = waiter.types.every((t, i) => got[i] === t);
|
|
120
|
-
if (matches) {
|
|
121
|
-
waiter.resolve();
|
|
122
|
-
} else {
|
|
123
|
-
waiter.reject(new Error(`EventWatcher: expected ${JSON.stringify(waiter.types)}, got ${JSON.stringify(got)}`));
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
/** Close an array of RTCPeerConnection instances, ignoring errors. */
|
|
129
|
-
function closePeerConnections(...pcs) {
|
|
130
|
-
for (const pc of pcs) {
|
|
131
|
-
try {
|
|
132
|
-
pc?.close();
|
|
133
|
-
} catch {}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
//#endregion
|
|
138
|
-
export { EventWatcher, awaitMessage, closePeerConnections, createDataChannelPair, createPeerConnection, exchangeOfferAnswer };
|
|
1
|
+
import{RTCPeerConnection as e}from"./rtc-peer-connection.js";import"./index.js";function t(){return new e}async function n(e,t){e.onicecandidate=e=>{e.candidate&&t.addIceCandidate(e.candidate.toJSON()).catch(()=>{})},t.onicecandidate=t=>{t.candidate&&e.addIceCandidate(t.candidate.toJSON()).catch(()=>{})};let n=await e.createOffer();await e.setLocalDescription(n),await t.setRemoteDescription(n);let r=await t.createAnswer();await t.setLocalDescription(r),await e.setRemoteDescription(r)}async function r(e={},r=t(),i=t(),a=`wpt`){let o,s;if(e.negotiated)o=[r.createDataChannel(a,e),i.createDataChannel(a,e)],s=Promise.all(o.map(e=>new Promise((t,n)=>{if(e.readyState===`open`)return t();e.onopen=()=>t(),e.onerror=e=>n(e?.error??Error(`onerror`))})));else{let t=r.createDataChannel(a,e);s=Promise.all([new Promise((e,n)=>{if(t.readyState===`open`)return e();t.onopen=()=>e(),t.onerror=e=>n(e?.error??Error(`onerror`))}),new Promise((e,t)=>{i.ondatachannel=n=>{let r=n.channel;if(r.readyState===`open`)return e(r);r.onopen=()=>e(r),r.onerror=e=>t(e?.error??Error(`onerror`))}}).then(e=>{o[1]=e})]),o=[t,void 0]}return await n(r,i),await s,[o[0],o[1],r,i]}function i(e){return new Promise((t,n)=>{let r=n=>{e.removeEventListener(`message`,r),e.removeEventListener(`error`,i),t(n.data)},i=t=>{e.removeEventListener(`message`,r),e.removeEventListener(`error`,i),n(t?.error??Error(`channel error`))};e.addEventListener(`message`,r),e.addEventListener(`error`,i)})}var a=class{_events=[];_waiters=[];constructor(e,t){for(let n of t)e.addEventListener(n,()=>{this._events.push(n),this._tryResolve()})}wait_for(e){let t=Array.isArray(e)?e:[e];return new Promise((e,n)=>{this._waiters.push({types:t,resolve:e,reject:n}),this._tryResolve()})}_tryResolve(){for(;this._waiters.length>0&&this._events.length>=this._waiters[0].types.length;){let e=this._waiters.shift(),t=this._events.splice(0,e.types.length);e.types.every((e,n)=>t[n]===e)?e.resolve():e.reject(Error(`EventWatcher: expected ${JSON.stringify(e.types)}, got ${JSON.stringify(t)}`))}}};function o(...e){for(let t of e)try{t?.close()}catch{}}export{a as EventWatcher,i as awaitMessage,o as closePeerConnections,r as createDataChannelPair,t as createPeerConnection,n as exchangeOfferAnswer};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/webrtc",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.18",
|
|
4
4
|
"description": "W3C WebRTC API for GJS using GStreamer webrtcbin as the peer-connection backend",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "lib/esm/index.js",
|
|
@@ -55,21 +55,21 @@
|
|
|
55
55
|
"peer-connection"
|
|
56
56
|
],
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@gjsify/buffer": "^0.3.
|
|
59
|
-
"@gjsify/dom-events": "^0.3.
|
|
60
|
-
"@gjsify/dom-exception": "^0.3.
|
|
61
|
-
"@gjsify/webrtc-native": "^0.3.
|
|
58
|
+
"@gjsify/buffer": "^0.3.18",
|
|
59
|
+
"@gjsify/dom-events": "^0.3.18",
|
|
60
|
+
"@gjsify/dom-exception": "^0.3.18",
|
|
61
|
+
"@gjsify/webrtc-native": "^0.3.18"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
-
"@girs/gjs": "4.0.0-rc.
|
|
65
|
-
"@girs/glib-2.0": "2.88.0-4.0.0-rc.
|
|
66
|
-
"@girs/gobject-2.0": "2.88.0-4.0.0-rc.
|
|
67
|
-
"@girs/gst-1.0": "1.28.1-4.0.0-rc.
|
|
68
|
-
"@girs/gstsdp-1.0": "1.0.0-4.0.0-rc.
|
|
69
|
-
"@girs/gstwebrtc-1.0": "1.0.0-4.0.0-rc.
|
|
70
|
-
"@gjsify/cli": "^0.3.
|
|
71
|
-
"@gjsify/unit": "^0.3.
|
|
72
|
-
"@types/node": "^25.6.
|
|
64
|
+
"@girs/gjs": "4.0.0-rc.14",
|
|
65
|
+
"@girs/glib-2.0": "2.88.0-4.0.0-rc.14",
|
|
66
|
+
"@girs/gobject-2.0": "2.88.0-4.0.0-rc.14",
|
|
67
|
+
"@girs/gst-1.0": "1.28.1-4.0.0-rc.14",
|
|
68
|
+
"@girs/gstsdp-1.0": "1.0.0-4.0.0-rc.14",
|
|
69
|
+
"@girs/gstwebrtc-1.0": "1.0.0-4.0.0-rc.14",
|
|
70
|
+
"@gjsify/cli": "^0.3.18",
|
|
71
|
+
"@gjsify/unit": "^0.3.18",
|
|
72
|
+
"@types/node": "^25.6.2",
|
|
73
73
|
"typescript": "^6.0.3"
|
|
74
74
|
}
|
|
75
75
|
}
|