@gjsify/webrtc 0.52.0 → 0.54.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.
package/README.md CHANGED
@@ -14,6 +14,12 @@ npm install @gjsify/webrtc
14
14
  yarn add @gjsify/webrtc
15
15
  ```
16
16
 
17
+ The GStreamer side comes from the system: `webrtcbin` (gst-plugins-bad) and libnice's
18
+ GStreamer plugin for ICE. On Fedora `dnf install gstreamer1-plugins-bad-free libnice-gstreamer1`,
19
+ on Debian/Ubuntu `apt install gstreamer1.0-plugins-bad gstreamer1.0-nice`, on macOS
20
+ `brew install gstreamer libnice-gstreamer`. The native bridge (`@gjsify/webrtc-native`)
21
+ ships prebuilt for `linux-{x64,arm64,ppc64,s390x,riscv64}` and `darwin-{arm64,x64}`.
22
+
17
23
  ## Usage
18
24
 
19
25
  ```typescript
@@ -1 +1 @@
1
- import"./_virtual/_rolldown/runtime.js";import{Gst as e,ensureGstInit as t}from"./gst-init.js";import{MediaStreamTrack as n}from"./media-stream-track.js";import{MediaStream as r}from"./media-stream.js";async function getUserMedia(i){if(t(),!i.audio&&!i.video)throw TypeError(`Failed to execute 'getUserMedia': At least one of audio or video must be requested`);let a=[];if(i.audio){let t=typeof i.audio==`object`?i.audio:{},r=_createAudioSource(),o=new e.Pipeline;o.add(r);let s=_buildAudioCaps(t);if(s){let t=e.ElementFactory.make(`capsfilter`,null);t.caps=e.Caps.from_string(s),o.add(t),r.link(t)}a.push(new n({kind:`audio`,label:r.name??`audio`,_gst:{source:r,pipeline:o}}))}if(i.video){let t=typeof i.video==`object`?i.video:{},r=_createVideoSource(),o=new e.Pipeline;o.add(r);let s=_buildVideoCaps(t);if(s){let t=e.ElementFactory.make(`capsfilter`,null);t.caps=e.Caps.from_string(s),o.add(t),r.link(t)}a.push(new n({kind:`video`,label:r.name??`video`,_gst:{source:r,pipeline:o}}))}return new r(a)}function _buildAudioCaps(e){let t=[];return e.sampleRate!=null&&t.push(`rate=${Math.trunc(e.sampleRate)}`),e.channelCount!=null&&t.push(`channels=${Math.trunc(e.channelCount)}`),t.length===0?null:`audio/x-raw,${t.join(`,`)}`}function _buildVideoCaps(e){let t=[];return e.width!=null&&t.push(`width=${Math.trunc(e.width)}`),e.height!=null&&t.push(`height=${Math.trunc(e.height)}`),e.frameRate!=null&&t.push(`framerate=${Math.trunc(e.frameRate)}/1`),t.length===0?null:`video/x-raw,${t.join(`,`)}`}function _probeSource(t,n){let r=e.ElementFactory.make(t,null);if(!r)return null;let i=e.ElementFactory.make(n,null),a=e.ElementFactory.make(`fakesink`,null);if(!i||!a)return r;let o=new e.Pipeline;o.add(r),o.add(i),o.add(a),r.link(i),i.link(a);let s=o.set_state(e.State.PLAYING);return s!==e.StateChangeReturn.FAILURE&&(s=o.get_state(500*Number(e.MSECOND))[0]),o.set_state(e.State.NULL),r.unlink(i),o.remove(r),s===e.StateChangeReturn.FAILURE?null:r}const i=new Map;function _chooseSource(t,n,r,a){let o=i.get(t);if(o)return e.ElementFactory.make(o,null);for(let e of n){let n=_probeSource(e,r);if(n)return i.set(t,e),n}return i.set(t,a),e.ElementFactory.make(a,null)}function _createAudioSource(){let e=_chooseSource(`audio`,[`pipewiresrc`,`pulsesrc`,`autoaudiosrc`],`audioconvert`,`audiotestsrc`);try{e.is_live=!0}catch{}return i.get(`audio`)===`audiotestsrc`&&(e.wave=0),e}function _createVideoSource(){let e=_chooseSource(`video`,[`pipewiresrc`,`v4l2src`,`autovideosrc`],`videoconvert`,`videotestsrc`);return i.get(`video`)===`videotestsrc`&&(e.is_live=!0,e.pattern=0),e}export{getUserMedia};
1
+ import"./_virtual/_rolldown/runtime.js";import{Gst as e,ensureGstInit as t}from"./gst-init.js";import{MediaStreamTrack as n}from"./media-stream-track.js";import{MediaStream as r}from"./media-stream.js";async function getUserMedia(i){if(t(),!i.audio&&!i.video)throw TypeError(`Failed to execute 'getUserMedia': At least one of audio or video must be requested`);let a=[];if(i.audio){let t=typeof i.audio==`object`?i.audio:{},r=_createAudioSource(t),o=new e.Pipeline;o.add(r);let s=_buildAudioCaps(t);if(s){let t=e.ElementFactory.make(`capsfilter`,null);t.caps=e.Caps.from_string(s),o.add(t),r.link(t)}a.push(new n({kind:`audio`,label:r.name??`audio`,_gst:{source:r,pipeline:o}}))}if(i.video){let t=typeof i.video==`object`?i.video:{},r=_createVideoSource(t),o=new e.Pipeline;o.add(r);let s=_buildVideoCaps(t);if(s){let t=e.ElementFactory.make(`capsfilter`,null);t.caps=e.Caps.from_string(s),o.add(t),r.link(t)}a.push(new n({kind:`video`,label:r.name??`video`,_gst:{source:r,pipeline:o}}))}return new r(a)}function _buildAudioCaps(e){let t=[];return e.sampleRate!=null&&t.push(`rate=${Math.trunc(e.sampleRate)}`),e.channelCount!=null&&t.push(`channels=${Math.trunc(e.channelCount)}`),t.length===0?null:`audio/x-raw,${t.join(`,`)}`}function _buildVideoCaps(e){let t=[];return e.width!=null&&t.push(`width=${Math.trunc(e.width)}`),e.height!=null&&t.push(`height=${Math.trunc(e.height)}`),e.frameRate!=null&&t.push(`framerate=${Math.trunc(e.frameRate)}/1`),t.length===0?null:`video/x-raw,${t.join(`,`)}`}function _probeSource(t,n){let r=e.ElementFactory.make(t,null);if(!r)return null;let i=e.ElementFactory.make(n,null),a=e.ElementFactory.make(`fakesink`,null);if(!i||!a)return r;let o=new e.Pipeline;o.add(r),o.add(i),o.add(a),r.link(i),i.link(a);let s=o.set_state(e.State.PLAYING);return s!==e.StateChangeReturn.FAILURE&&(s=o.get_state(500*Number(e.MSECOND))[0]),o.set_state(e.State.NULL),r.unlink(i),o.remove(r),s===e.StateChangeReturn.FAILURE?null:r}const i=new Map;function _chooseSource(t,n,r,a){let o=i.get(t);if(o)return e.ElementFactory.make(o,null);for(let e of n){let n=_probeSource(e,r);if(n)return i.set(t,e),n}return i.set(t,a),e.ElementFactory.make(a,null)}const a=[`device`,`target_object`,`path`],o=new Set;function _bindDevice(e,t,n){if(n){for(let e of a)if(e in t){t[e]=n;return}o.has(e)||(o.add(e),console.warn(`getUserMedia: deviceId ${JSON.stringify(n)} ignored — ${t.name} has no device property, so the ${e} source is the host default. getSupportedConstraints() reports deviceId: true.`))}}function _createAudioSource(e){let t=_chooseSource(`audio`,[`pipewiresrc`,`pulsesrc`,`autoaudiosrc`],`audioconvert`,`audiotestsrc`);try{t.is_live=!0}catch{}return i.get(`audio`)===`audiotestsrc`&&(t.wave=0),_bindDevice(`audio`,t,e.deviceId),t}function _createVideoSource(e){let t=_chooseSource(`video`,[`pipewiresrc`,`v4l2src`,`autovideosrc`],`videoconvert`,`videotestsrc`);return i.get(`video`)===`videotestsrc`&&(t.is_live=!0,t.pattern=0),_bindDevice(`video`,t,e.deviceId),t}export{getUserMedia};
@@ -5,7 +5,9 @@ plugin — verify with: ls /usr/lib/gstreamer-1.0/libgstwebrtc.so
5
5
  Otherwise: install the plugin from source, or use a distro that ships it.`:`GStreamer element "webrtcbin" not available. Install gst-plugins-bad:
6
6
  Fedora: dnf install gstreamer1-plugins-bad-free gstreamer1-plugins-bad-free-extras
7
7
  Ubuntu/Debian: apt install gstreamer1.0-plugins-bad
8
- Alpine/postmarketOS: apk add gst-plugins-bad`),e.ElementFactory.find(`nicesrc`)||throwNotSupported(`GStreamer "nice" plugin (libnice-gstreamer) not available — required by webrtcbin.
8
+ Alpine/postmarketOS: apk add gst-plugins-bad
9
+ macOS (Homebrew): brew install gstreamer`),e.ElementFactory.find(`nicesrc`)||throwNotSupported(`GStreamer "nice" plugin (libnice-gstreamer) not available — required by webrtcbin.
9
10
  Fedora: dnf install libnice-gstreamer1
10
11
  Ubuntu/Debian: apt install gstreamer1.0-nice
12
+ macOS: brew install libnice-gstreamer
11
13
  Verify with: gst-inspect-1.0 nicesrc`)}function throwNotSupported(e){throw new n(e,`NotSupportedError`)}export{e as Gst,ensureGstInit,ensureWebrtcbinAvailable,excludeUnboundedAutodetectCandidates};
@@ -1 +1 @@
1
- import{MediaDevices as e}from"../media-devices.js";const t=globalThis;t.navigator===void 0&&(t.navigator={}),t.navigator.mediaDevices===void 0&&(t.navigator.mediaDevices=new e);
1
+ import{MediaDevices as e}from"../media-devices.js";import"@gjsify/node-globals/register/navigator";const t=globalThis;t.navigator.mediaDevices===void 0&&(t.navigator.mediaDevices=new e);
@@ -1 +1 @@
1
- import"./_virtual/_rolldown/runtime.js";import{Gst as e}from"./gst-init.js";import{getRtcpCname as t}from"./gst-utils.js";import{asCapsFilterElement as n,asRtpPayloaderElement as r,asValveElement as i,asVp8EncElement as a,asWebRtcBin as o}from"./internal/gst-types.js";import{getRtpCapabilities as s}from"./rtp-capabilities.js";import{parseMediaSectionParams as c}from"./sdp-params.js";import{RTCDTMFSender as l}from"./rtc-dtmf-sender.js";import{TeeMultiplexer as u}from"./tee-multiplexer.js";let d=0;var RTCRtpSender=class{_gstSender;_track=null;_lastParams=null;_pipeline=null;_webrtcbin=null;_mlineIndex=-1;_elements=[];_valve=null;_linked=!1;_teeSrcPad=null;_getStatsForTrack=null;_transport=null;_dtmf=null;_kind=null;_transceiver=null;_onPipelineChanged=null;constructor(e,t,n){this._gstSender=e,this._pipeline=t??null,this._webrtcbin=n??null}get track(){return this._track}get dtmf(){if((this._track?.kind??this._kind)!==`audio`)return null;if(!this._dtmf){let e=new l;e._isStopped=()=>this._transceiver?.stopped??!1,e._getCurrentDirection=()=>this._transceiver?.currentDirection??null,this._dtmf=e}return this._dtmf}get transport(){return this._transport}_setTrack(e){e===null&&this._linked&&this._teardownPipeline(),this._track=e}_setMlineIndex(e){this._mlineIndex=e}_wirePipeline(t){if(this._linked||!this._pipeline||!this._webrtcbin)return;let o=t._gstSource;if(!o)return;let s=t,c;if(s._gstTee&&s._gstPipeline&&s._gstPipeline!==this._pipeline){let t=s._gstPipeline,n=s._gstTee;this._webrtcbin.get_parent()===this._pipeline&&(this._pipeline.set_state(e.State.NULL),this._pipeline.remove(this._webrtcbin)),t.add(this._webrtcbin),this._webrtcbin.sync_state_with_parent(),this._pipeline=t,this._onPipelineChanged?.(t);let r=n.request_pad_simple?n.request_pad_simple(`src_%u`):n.get_request_pad(`src_%u`);this._teeSrcPad=r,c=null}else if(s._teeMultiplexer){let e=s._teeMultiplexer.requestSrcPad();this._teeSrcPad=e,c=null}else if(s._gstPipeline&&s._gstPipeline!==this._pipeline&&s._senderConsumers>0){let t=s._gstPipeline,n=o.get_static_pad(`src`),r=n?.get_peer?.();r&&n.unlink(r),o.set_state(e.State.NULL),t.remove(o),this._pipeline.add(o),s._gstPipeline=this._pipeline;let i=new u(this._pipeline,o);if(s._teeMultiplexer=i,r){let e=i.requestSrcPad();e&&e.link(r)}let a=i.requestSrcPad();this._teeSrcPad=a,c=null}else{let t=s._gstPipeline;t&&t!==this._pipeline&&(o.set_state(e.State.NULL),t.remove(o),s._gstPipeline=this._pipeline),o.get_parent()!==this._pipeline&&this._pipeline.add(o),c=o}let l=i(e.ElementFactory.make(`valve`,null));l.drop=!t.enabled,this._valve=l,this._pipeline.add(l);let d=[l],f;if(t.kind===`audio`){let t=e.ElementFactory.make(`audioconvert`,null),i=e.ElementFactory.make(`audioresample`,null),a=e.ElementFactory.make(`opusenc`,null),o=r(e.ElementFactory.make(`rtpopuspay`,null));o.pt=111;let s=n(e.ElementFactory.make(`capsfilter`,null));s.caps=e.Caps.from_string(`application/x-rtp,media=audio,encoding-name=OPUS,clock-rate=48000,payload=111`),d.push(t,i,a,o,s);for(let e of d)this._pipeline.add(e);if(this._teeSrcPad){let e=l.get_static_pad(`sink`);this._teeSrcPad.link(e)}else c&&c.link(l);l.link(t),t.link(i),i.link(a),a.link(o),o.link(s),f=s}else{let t=e.ElementFactory.make(`videoconvert`,null),i=e.ElementFactory.make(`videoscale`,null),o=a(e.ElementFactory.make(`vp8enc`,null));o.deadline=1,o.keyframe_max_dist=60;let s=r(e.ElementFactory.make(`rtpvp8pay`,null));s.pt=96;let u=n(e.ElementFactory.make(`capsfilter`,null));u.caps=e.Caps.from_string(`application/x-rtp,media=video,encoding-name=VP8,clock-rate=90000,payload=96`),d.push(t,i,o,s,u);for(let e of d)this._pipeline.add(e);if(this._teeSrcPad){let e=l.get_static_pad(`sink`);this._teeSrcPad.link(e)}else c&&c.link(l);l.link(t),t.link(i),i.link(o),o.link(s),s.link(u),f=u}let p=this._mlineIndex>=0?`sink_${this._mlineIndex}`:`sink_%u`,m=this._webrtcbin.request_pad_simple?this._webrtcbin.request_pad_simple(p):this._webrtcbin.get_request_pad(p);m&&f.get_static_pad(`src`).link(m);let h=this._teeSrcPad?d:[o,...d];for(let e of h)e.sync_state_with_parent();this._elements=h,this._linked=!0,t._senderConsumers++,t._setEnableCallback(e=>{this._valve&&(this._valve.drop=!e)})}_teardownPipeline(){if(this._linked){if(this._track&&(this._track._setEnableCallback(null),this._track._senderConsumers=Math.max(0,this._track._senderConsumers-1)),this._teeSrcPad&&this._track?._teeMultiplexer){try{this._track._teeMultiplexer.releaseSrcPad(this._teeSrcPad)}catch{}this._teeSrcPad=null}for(let t of[...this._elements].reverse())try{t.set_state(e.State.NULL),this._pipeline?.remove(t)}catch{}this._elements=[],this._valve=null,this._linked=!1}}getParameters(){let e=this._negotiatedParams();this._lastParams?(this._lastParams.codecs=e.codecs,this._lastParams.headerExtensions=e.headerExtensions,this._lastParams.rtcp=e.rtcp):this._lastParams={transactionId:String(++d),encodings:[],...e};let t=this._lastParams;return{...t,encodings:[...t.encodings],codecs:t.codecs.map(e=>({...e})),headerExtensions:t.headerExtensions.map(e=>({...e})),rtcp:{...t.rtcp}}}_negotiatedParams(){let e={},n={codecs:[],headerExtensions:[],rtcp:e};if(!this._webrtcbin)return n;let r=t(this._webrtcbin);r!==void 0&&(e.cname=r);let i=o(this._webrtcbin),a=(i.current_remote_description??i.current_local_description)?.sdp?.as_text?.()??``;if(!a)return n;let s=this._track?.kind??this._kind,l=c(a,{mid:this._transceiver?.mid??void 0,mlineIndex:this._mlineIndex>=0?this._mlineIndex:void 0,kind:s??void 0});return l?(n.codecs=l.codecs,n.headerExtensions=l.headerExtensions,e.reducedSize=l.reducedSize,n):n}async setParameters(e){if(!this._lastParams)throw new DOMException(`getParameters must be called before setParameters`,`InvalidStateError`);if(e.transactionId!==this._lastParams.transactionId)throw new DOMException(`transactionId mismatch`,`InvalidModificationError`);this._lastParams=null}async replaceTrack(t){if(t===null){this._teardownPipeline(),this._track=null;return}if(this._track!==null&&t.kind!==this._track.kind)throw TypeError(`Cannot replace track with different kind`);let n=t;if(this._linked&&n._gstSource){let t=this._elements[0],r=n._gstSource,i=n._gstPipeline;i&&i!==this._pipeline&&(r.set_state(e.State.NULL),i.remove(r),n._gstPipeline=this._pipeline),t.set_state(e.State.NULL),this._valve&&t.unlink(this._valve),this._pipeline?.remove(t),this._pipeline?.add(r),this._valve&&r.link(this._valve),r.sync_state_with_parent(),this._elements[0]=r}else n._gstSource&&this._wirePipeline(t);this._track&&this._track._setEnableCallback(null),this._track=t,this._linked&&t._setEnableCallback(e=>{this._valve&&(this._valve.drop=!e)})}async getStats(){if(this._getStatsForTrack&&this._track)return this._getStatsForTrack(this._track);let{RTCStatsReport:e}=await import(`./rtc-stats-report.js`);return new e}setStreams(...e){}static getCapabilities(e){return s(e)}};export{RTCRtpSender};
1
+ import"./_virtual/_rolldown/runtime.js";import{Gst as e}from"./gst-init.js";import{getRtcpCname as t}from"./gst-utils.js";import{asCapsFilterElement as n,asRtpPayloaderElement as r,asValveElement as i,asVp8EncElement as a,asWebRtcBin as o}from"./internal/gst-types.js";import{getRtpCapabilities as s}from"./rtp-capabilities.js";import{parseMediaSectionParams as c}from"./sdp-params.js";import{RTCDTMFSender as l}from"./rtc-dtmf-sender.js";import{TeeMultiplexer as u}from"./tee-multiplexer.js";let d=0;function releaseDownstreamStreamingThread(t){if(!t)return;let n=e.Event.new_flush_start();t.direction===e.PadDirection.SRC?t.push_event(n):t.send_event(n)}var RTCRtpSender=class{_gstSender;_track=null;_lastParams=null;_pipeline=null;_webrtcbin=null;_mlineIndex=-1;_elements=[];_valve=null;_linked=!1;_teeSrcPad=null;_getStatsForTrack=null;_transport=null;_dtmf=null;_kind=null;_transceiver=null;_onPipelineChanged=null;constructor(e,t,n){this._gstSender=e,this._pipeline=t??null,this._webrtcbin=n??null}get track(){return this._track}get dtmf(){if((this._track?.kind??this._kind)!==`audio`)return null;if(!this._dtmf){let e=new l;e._isStopped=()=>this._transceiver?.stopped??!1,e._getCurrentDirection=()=>this._transceiver?.currentDirection??null,this._dtmf=e}return this._dtmf}get transport(){return this._transport}_setTrack(e){e===null&&this._linked&&this._teardownPipeline(),this._track=e}_setMlineIndex(e){this._mlineIndex=e}_wirePipeline(t){if(this._linked||!this._pipeline||!this._webrtcbin)return;let o=t._gstSource;if(!o)return;let s=t,c;if(s._gstTee&&s._gstPipeline&&s._gstPipeline!==this._pipeline){let t=s._gstPipeline,n=s._gstTee;this._webrtcbin.get_parent()===this._pipeline&&(this._pipeline.set_state(e.State.NULL),this._pipeline.remove(this._webrtcbin)),t.add(this._webrtcbin),this._webrtcbin.sync_state_with_parent(),this._pipeline=t,this._onPipelineChanged?.(t);let r=n.request_pad_simple?n.request_pad_simple(`src_%u`):n.get_request_pad(`src_%u`);this._teeSrcPad=r,c=null}else if(s._teeMultiplexer){let e=s._teeMultiplexer.requestSrcPad();this._teeSrcPad=e,c=null}else if(s._gstPipeline&&s._gstPipeline!==this._pipeline&&s._senderConsumers>0){let t=s._gstPipeline,n=o.get_static_pad(`src`),r=n?.get_peer?.();r&&(releaseDownstreamStreamingThread(n),n.unlink(r)),o.set_state(e.State.NULL),t.remove(o),this._pipeline.add(o),s._gstPipeline=this._pipeline;let i=new u(this._pipeline,o);if(s._teeMultiplexer=i,r){let t=i.requestSrcPad();t&&t.link(r),r.send_event(e.Event.new_flush_stop(!0))}let a=i.requestSrcPad();this._teeSrcPad=a,c=null}else{let t=s._gstPipeline;t&&t!==this._pipeline&&(o.set_state(e.State.NULL),t.remove(o),s._gstPipeline=this._pipeline),o.get_parent()!==this._pipeline&&this._pipeline.add(o),c=o}let l=i(e.ElementFactory.make(`valve`,null));l.drop=!t.enabled,this._valve=l,this._pipeline.add(l);let d=[l],f;if(t.kind===`audio`){let t=e.ElementFactory.make(`audioconvert`,null),i=e.ElementFactory.make(`audioresample`,null),a=e.ElementFactory.make(`opusenc`,null),o=r(e.ElementFactory.make(`rtpopuspay`,null));o.pt=111;let s=n(e.ElementFactory.make(`capsfilter`,null));s.caps=e.Caps.from_string(`application/x-rtp,media=audio,encoding-name=OPUS,clock-rate=48000,payload=111`),d.push(t,i,a,o,s);for(let e of d)this._pipeline.add(e);if(this._teeSrcPad){let e=l.get_static_pad(`sink`);this._teeSrcPad.link(e)}else c&&c.link(l);l.link(t),t.link(i),i.link(a),a.link(o),o.link(s),f=s}else{let t=e.ElementFactory.make(`videoconvert`,null),i=e.ElementFactory.make(`videoscale`,null),o=a(e.ElementFactory.make(`vp8enc`,null));o.deadline=1,o.keyframe_max_dist=60;let s=r(e.ElementFactory.make(`rtpvp8pay`,null));s.pt=96;let u=n(e.ElementFactory.make(`capsfilter`,null));u.caps=e.Caps.from_string(`application/x-rtp,media=video,encoding-name=VP8,clock-rate=90000,payload=96`),d.push(t,i,o,s,u);for(let e of d)this._pipeline.add(e);if(this._teeSrcPad){let e=l.get_static_pad(`sink`);this._teeSrcPad.link(e)}else c&&c.link(l);l.link(t),t.link(i),i.link(o),o.link(s),s.link(u),f=u}let p=this._mlineIndex>=0?`sink_${this._mlineIndex}`:`sink_%u`,m=this._webrtcbin.request_pad_simple?this._webrtcbin.request_pad_simple(p):this._webrtcbin.get_request_pad(p);m&&f.get_static_pad(`src`).link(m);let h=this._teeSrcPad?d:[o,...d];for(let e of h)e.sync_state_with_parent();this._elements=h,this._linked=!0,t._senderConsumers++,t._setEnableCallback(e=>{this._valve&&(this._valve.drop=!e)})}_teardownPipeline(){if(this._linked){if(this._track&&(this._track._setEnableCallback(null),this._track._senderConsumers=Math.max(0,this._track._senderConsumers-1)),releaseDownstreamStreamingThread(this._valve?.get_static_pad(`sink`)),this._teeSrcPad&&this._track?._teeMultiplexer){try{this._track._teeMultiplexer.releaseSrcPad(this._teeSrcPad)}catch{}this._teeSrcPad=null}for(let t of[...this._elements].reverse())try{t.set_state(e.State.NULL),this._pipeline?.remove(t)}catch{}this._elements=[],this._valve=null,this._linked=!1}}getParameters(){let e=this._negotiatedParams();this._lastParams?(this._lastParams.codecs=e.codecs,this._lastParams.headerExtensions=e.headerExtensions,this._lastParams.rtcp=e.rtcp):this._lastParams={transactionId:String(++d),encodings:[],...e};let t=this._lastParams;return{...t,encodings:[...t.encodings],codecs:t.codecs.map(e=>({...e})),headerExtensions:t.headerExtensions.map(e=>({...e})),rtcp:{...t.rtcp}}}_negotiatedParams(){let e={},n={codecs:[],headerExtensions:[],rtcp:e};if(!this._webrtcbin)return n;let r=t(this._webrtcbin);r!==void 0&&(e.cname=r);let i=o(this._webrtcbin),a=(i.current_remote_description??i.current_local_description)?.sdp?.as_text?.()??``;if(!a)return n;let s=this._track?.kind??this._kind,l=c(a,{mid:this._transceiver?.mid??void 0,mlineIndex:this._mlineIndex>=0?this._mlineIndex:void 0,kind:s??void 0});return l?(n.codecs=l.codecs,n.headerExtensions=l.headerExtensions,e.reducedSize=l.reducedSize,n):n}async setParameters(e){if(!this._lastParams)throw new DOMException(`getParameters must be called before setParameters`,`InvalidStateError`);if(e.transactionId!==this._lastParams.transactionId)throw new DOMException(`transactionId mismatch`,`InvalidModificationError`);this._lastParams=null}async replaceTrack(t){if(t===null){this._teardownPipeline(),this._track=null;return}if(this._track!==null&&t.kind!==this._track.kind)throw TypeError(`Cannot replace track with different kind`);let n=t;if(this._linked&&n._gstSource){let t=this._elements[0],r=n._gstSource,i=n._gstPipeline;i&&i!==this._pipeline&&(r.set_state(e.State.NULL),i.remove(r),n._gstPipeline=this._pipeline),t.set_state(e.State.NULL),this._valve&&t.unlink(this._valve),this._pipeline?.remove(t),this._pipeline?.add(r),this._valve&&r.link(this._valve),r.sync_state_with_parent(),this._elements[0]=r}else n._gstSource&&this._wirePipeline(t);this._track&&this._track._setEnableCallback(null),this._track=t,this._linked&&t._setEnableCallback(e=>{this._valve&&(this._valve.drop=!e)})}async getStats(){if(this._getStatsForTrack&&this._track)return this._getStatsForTrack(this._track);let{RTCStatsReport:e}=await import(`./rtc-stats-report.js`);return new e}setStreams(...e){}static getCapabilities(e){return s(e)}};export{RTCRtpSender};
@@ -0,0 +1,2 @@
1
+ declare const _default: () => Promise<void>;
2
+ export default _default;
@@ -1 +1 @@
1
- export {};
1
+ import '@gjsify/node-globals/register/navigator';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/webrtc",
3
- "version": "0.52.0",
3
+ "version": "0.54.0",
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",
@@ -61,22 +61,23 @@
61
61
  "peer-connection"
62
62
  ],
63
63
  "dependencies": {
64
- "@gjsify/buffer": "^0.52.0",
65
- "@gjsify/dom-events": "^0.52.0",
66
- "@gjsify/dom-exception": "^0.52.0",
67
- "@gjsify/webcrypto": "^0.52.0",
68
- "@gjsify/webrtc-native": "^0.52.0"
64
+ "@gjsify/buffer": "^0.54.0",
65
+ "@gjsify/dom-events": "^0.54.0",
66
+ "@gjsify/dom-exception": "^0.54.0",
67
+ "@gjsify/node-globals": "^0.54.0",
68
+ "@gjsify/webcrypto": "^0.54.0",
69
+ "@gjsify/webrtc-native": "^0.54.0"
69
70
  },
70
71
  "devDependencies": {
72
+ "@girs/gio-2.0": "5.4.0",
71
73
  "@girs/gjs": "5.4.0",
72
74
  "@girs/glib-2.0": "5.4.0",
73
75
  "@girs/gobject-2.0": "5.4.0",
74
76
  "@girs/gst-1.0": "5.4.0",
75
77
  "@girs/gstsdp-1.0": "5.4.0",
76
78
  "@girs/gstwebrtc-1.0": "5.4.0",
77
- "@gjsify/child_process": "^0.52.0",
78
- "@gjsify/cli": "^0.52.0",
79
- "@gjsify/unit": "^0.52.0",
79
+ "@gjsify/cli": "^0.54.0",
80
+ "@gjsify/unit": "^0.54.0",
80
81
  "@types/node": "^25.9.2",
81
82
  "typescript": "^6.0.3"
82
83
  },