@gjsify/webrtc 0.3.20 → 0.4.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/lib/esm/_virtual/_rolldown/runtime.js +1 -0
- package/lib/esm/get-user-media.js +1 -1
- package/lib/esm/gst-enum-maps.js +1 -1
- package/lib/esm/gst-init.js +3 -3
- package/lib/esm/gst-stats-parser.js +1 -1
- package/lib/esm/gst-utils.js +1 -1
- package/lib/esm/internal/gst-types.js +1 -0
- package/lib/esm/media-device-info.js +1 -1
- package/lib/esm/media-devices.js +1 -1
- package/lib/esm/media-stream-track.js +1 -1
- package/lib/esm/media-stream.js +1 -1
- package/lib/esm/rtc-certificate.js +1 -1
- package/lib/esm/rtc-data-channel.js +1 -1
- package/lib/esm/rtc-dtls-transport.js +1 -1
- package/lib/esm/rtc-dtmf-sender.js +1 -1
- package/lib/esm/rtc-error.js +1 -1
- package/lib/esm/rtc-events.js +1 -1
- package/lib/esm/rtc-ice-candidate.js +1 -1
- package/lib/esm/rtc-ice-transport.js +1 -1
- package/lib/esm/rtc-peer-connection.js +1 -1
- package/lib/esm/rtc-rtp-receiver.js +1 -1
- package/lib/esm/rtc-rtp-sender.js +1 -1
- package/lib/esm/rtc-rtp-transceiver.js +1 -1
- package/lib/esm/rtc-sctp-transport.js +1 -1
- package/lib/esm/rtc-session-description.js +1 -1
- package/lib/esm/rtc-stats-report.js +1 -1
- package/lib/esm/rtc-track-event.js +1 -1
- package/lib/esm/rtp-capabilities.js +1 -1
- package/lib/esm/tee-multiplexer.js +1 -1
- package/lib/esm/wpt-helpers.js +1 -1
- package/lib/types/gst-enum-maps.d.ts +2 -1
- package/lib/types/internal/gst-types.d.ts +83 -0
- package/lib/types/rtc-rtp-sender.d.ts +3 -2
- package/package.json +13 -13
- package/src/gst-enum-maps.ts +1 -1
- package/src/internal/gst-types.ts +122 -0
- package/src/rtc-peer-connection.ts +44 -28
- package/src/rtc-rtp-sender.ts +76 -49
- package/src/rtc-rtp-transceiver.ts +8 -4
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=Object.defineProperty,__name=(t,n)=>e(t,`name`,{value:n,configurable:!0});export{__name};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
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
|
|
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 _createAudioSource(){for(let t of[`pipewiresrc`,`pulsesrc`,`autoaudiosrc`]){let n=e.ElementFactory.make(t,null);if(n){try{n.is_live=!0}catch{}return n}}let t=e.ElementFactory.make(`audiotestsrc`,null);return t.is_live=!0,t.wave=0,t}function _createVideoSource(){for(let t of[`pipewiresrc`,`v4l2src`,`autovideosrc`]){let n=e.ElementFactory.make(t,null);if(n)return n}let t=e.ElementFactory.make(`videotestsrc`,null);return t.is_live=!0,t.pattern=0,t}export{getUserMedia};
|
package/lib/esm/gst-enum-maps.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"gi://GstWebRTC?version=1.0";const t={[e.WebRTCSignalingState.STABLE]:`stable`,[e.WebRTCSignalingState.CLOSED]:`closed`,[e.WebRTCSignalingState.HAVE_LOCAL_OFFER]:`have-local-offer`,[e.WebRTCSignalingState.HAVE_REMOTE_OFFER]:`have-remote-offer`,[e.WebRTCSignalingState.HAVE_LOCAL_PRANSWER]:`have-local-pranswer`,[e.WebRTCSignalingState.HAVE_REMOTE_PRANSWER]:`have-remote-pranswer`};function
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import e from"gi://GstWebRTC?version=1.0";const t={[e.WebRTCSignalingState.STABLE]:`stable`,[e.WebRTCSignalingState.CLOSED]:`closed`,[e.WebRTCSignalingState.HAVE_LOCAL_OFFER]:`have-local-offer`,[e.WebRTCSignalingState.HAVE_REMOTE_OFFER]:`have-remote-offer`,[e.WebRTCSignalingState.HAVE_LOCAL_PRANSWER]:`have-local-pranswer`,[e.WebRTCSignalingState.HAVE_REMOTE_PRANSWER]:`have-remote-pranswer`};function gstToSignalingState(e){return t[e]??`stable`}const n={[e.WebRTCPeerConnectionState.NEW]:`new`,[e.WebRTCPeerConnectionState.CONNECTING]:`connecting`,[e.WebRTCPeerConnectionState.CONNECTED]:`connected`,[e.WebRTCPeerConnectionState.DISCONNECTED]:`disconnected`,[e.WebRTCPeerConnectionState.FAILED]:`failed`,[e.WebRTCPeerConnectionState.CLOSED]:`closed`};function gstToConnectionState(e){return n[e]??`new`}const r={[e.WebRTCICEConnectionState.NEW]:`new`,[e.WebRTCICEConnectionState.CHECKING]:`checking`,[e.WebRTCICEConnectionState.CONNECTED]:`connected`,[e.WebRTCICEConnectionState.COMPLETED]:`completed`,[e.WebRTCICEConnectionState.FAILED]:`failed`,[e.WebRTCICEConnectionState.DISCONNECTED]:`disconnected`,[e.WebRTCICEConnectionState.CLOSED]:`closed`};function gstToIceConnectionState(e){return r[e]??`new`}const i={[e.WebRTCICEGatheringState.NEW]:`new`,[e.WebRTCICEGatheringState.GATHERING]:`gathering`,[e.WebRTCICEGatheringState.COMPLETE]:`complete`};function gstToIceGatheringState(e){return i[e]??`new`}const a={[e.WebRTCRTPTransceiverDirection.SENDRECV]:`sendrecv`,[e.WebRTCRTPTransceiverDirection.SENDONLY]:`sendonly`,[e.WebRTCRTPTransceiverDirection.RECVONLY]:`recvonly`},o={sendrecv:e.WebRTCRTPTransceiverDirection.SENDRECV,sendonly:e.WebRTCRTPTransceiverDirection.SENDONLY,recvonly:e.WebRTCRTPTransceiverDirection.RECVONLY,inactive:e.WebRTCRTPTransceiverDirection.NONE};function gstDirectionToW3C(e){return a[e]??`inactive`}function w3cDirectionToGst(t){return o[t]??e.WebRTCRTPTransceiverDirection.NONE}const s={[e.WebRTCStatsType.CODEC]:`codec`,[e.WebRTCStatsType.INBOUND_RTP]:`inbound-rtp`,[e.WebRTCStatsType.OUTBOUND_RTP]:`outbound-rtp`,[e.WebRTCStatsType.REMOTE_INBOUND_RTP]:`remote-inbound-rtp`,[e.WebRTCStatsType.REMOTE_OUTBOUND_RTP]:`remote-outbound-rtp`,[e.WebRTCStatsType.CSRC]:`csrc`,[e.WebRTCStatsType.PEER_CONNECTION]:`peer-connection`,[e.WebRTCStatsType.DATA_CHANNEL]:`data-channel`,[e.WebRTCStatsType.STREAM]:`stream`,[e.WebRTCStatsType.TRANSPORT]:`transport`,[e.WebRTCStatsType.CANDIDATE_PAIR]:`candidate-pair`,[e.WebRTCStatsType.LOCAL_CANDIDATE]:`local-candidate`,[e.WebRTCStatsType.REMOTE_CANDIDATE]:`remote-candidate`,[e.WebRTCStatsType.CERTIFICATE]:`certificate`};function gstToStatsType(e){return s[e]}export{gstDirectionToW3C,gstToConnectionState,gstToIceConnectionState,gstToIceGatheringState,gstToSignalingState,gstToStatsType,w3cDirectionToGst};
|
package/lib/esm/gst-init.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import e from"gi://Gst?version=1.0";import{DOMException as t}from"@gjsify/dom-exception";let n=!1;function
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import e from"gi://Gst?version=1.0";import{DOMException as t}from"@gjsify/dom-exception";let n=!1;function ensureGstInit(){n||=(e.init(null),!0)}function ensureWebrtcbinAvailable(){ensureGstInit(),e.ElementFactory.find(`webrtcbin`)||throwNotSupported(`GStreamer element "webrtcbin" not available. Install gst-plugins-bad:
|
|
2
2
|
Fedora: dnf install gstreamer1-plugins-bad-free gstreamer1-plugins-bad-free-extras
|
|
3
|
-
Ubuntu/Debian: apt install gstreamer1.0-plugins-bad`),e.ElementFactory.find(`nicesrc`)||
|
|
3
|
+
Ubuntu/Debian: apt install gstreamer1.0-plugins-bad`),e.ElementFactory.find(`nicesrc`)||throwNotSupported(`GStreamer "nice" plugin (libnice-gstreamer) not available — required by webrtcbin.
|
|
4
4
|
Fedora: dnf install libnice-gstreamer1
|
|
5
5
|
Ubuntu/Debian: apt install gstreamer1.0-nice
|
|
6
|
-
Verify with: gst-inspect-1.0 nicesrc`)}function
|
|
6
|
+
Verify with: gst-inspect-1.0 nicesrc`)}function throwNotSupported(e){throw new t(e,`NotSupportedError`)}export{e as Gst,ensureGstInit,ensureWebrtcbinAvailable};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{gstToStatsType as e}from"./gst-enum-maps.js";import{RTCStatsReport as t}from"./rtc-stats-report.js";function
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{gstToStatsType as e}from"./gst-enum-maps.js";import{RTCStatsReport as t}from"./rtc-stats-report.js";function snakeToCamel(e){return e.replace(/-([a-z])/g,(e,t)=>t.toUpperCase())}function extractFields(e){let t={},n=e.n_fields();for(let r=0;r<n;r++){let n=e.nth_field_name(r);try{t[n]=e.get_value(n)}catch{}}return t}function parseStatsEntry(t){let n=extractFields(t),r=n.type;if(r==null)return null;let i=e(Number(r));if(!i)return null;let a=String(n.id??t.get_name()??``),o=n.timestamp,s={type:i,id:a,timestamp:o==null?performance.now():Number(o)/1e6};for(let[e,t]of Object.entries(n)){if(e===`type`||e===`id`||e===`timestamp`)continue;let n=snakeToCamel(e);s[n]=t}return s}function parseGstStats(e){if(!e)return new t;let n=[],r=e.n_fields();for(let t=0;t<r;t++){let r=e.nth_field_name(t);try{let t=e.get_value(r);if(t&&typeof t.n_fields==`function`){let e=parseStatsEntry(t);e&&n.push([e.id,e])}}catch{}}return new t(n)}function filterStatsByTrackId(e,n){let r=[],i=new Set;for(let[t,a]of e)if(a.trackIdentifier===n){r.push([t,a]),i.add(t);for(let t of Object.values(a))typeof t==`string`&&e.has(t)&&i.add(t)}for(let[t,n]of e)i.has(t)&&!r.some(([e])=>e===t)&&r.push([t,n]);return new t(r)}export{filterStatsByTrackId,parseGstStats};
|
package/lib/esm/gst-utils.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{PromiseBridge as e}from"@gjsify/webrtc-native";function
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{PromiseBridge as e}from"@gjsify/webrtc-native";function withGstPromise(t){return new Promise((n,r)=>{let i=new e;i.connect(`replied`,(e,t)=>{n(t)}),i.connect(`rejected`,(e,t)=>{r(Error(t))}),t(i.promise)})}export{withGstPromise};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";const asWebRtcBin=e=>e,asWebRtcSrcPad=e=>e,asValveElement=e=>e,asRtpPayloaderElement=e=>e,asCapsFilterElement=e=>e,asVp8EncElement=e=>e;export{asCapsFilterElement,asRtpPayloaderElement,asValveElement,asVp8EncElement,asWebRtcBin,asWebRtcSrcPad};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";var MediaDeviceInfo=class{deviceId;kind;label;groupId;constructor(e){this.deviceId=e.deviceId,this.kind=e.kind,this.label=e.label,this.groupId=e.groupId??``}toJSON(){return{deviceId:this.deviceId,kind:this.kind,label:this.label,groupId:this.groupId}}};export{MediaDeviceInfo};
|
package/lib/esm/media-devices.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Gst as e,ensureGstInit as t}from"./gst-init.js";import{getUserMedia as n}from"./get-user-media.js";import{MediaDeviceInfo as r}from"./media-device-info.js";import"@gjsify/dom-events/register/event-target";const i={"Audio/Source":`audioinput`,"Video/Source":`videoinput`,"Audio/Sink":`audiooutput`};let a=!1;function
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{Gst as e,ensureGstInit as t}from"./gst-init.js";import{getUserMedia as n}from"./get-user-media.js";import{MediaDeviceInfo as r}from"./media-device-info.js";import"@gjsify/dom-events/register/event-target";const i={"Audio/Source":`audioinput`,"Video/Source":`videoinput`,"Audio/Sink":`audiooutput`};let a=!1;function isDeviceMonitorSafe(){try{let e=imports.gi.GLib;return!(e.getenv(`CI`)||!e.getenv(`DISPLAY`)&&!e.getenv(`WAYLAND_DISPLAY`))}catch{return!1}}var MediaDevices=class extends EventTarget{_ondevicechange=null;get ondevicechange(){return this._ondevicechange}set ondevicechange(e){this._ondevicechange=e}async getUserMedia(e){if(!e)throw TypeError(`Failed to execute 'getUserMedia' on 'MediaDevices': At least one of audio or video must be requested`);let t=await n(e);return a=!0,t}async enumerateDevices(){t();let n=null,o=[];try{if(!isDeviceMonitorSafe())return o;n=new e.DeviceMonitor,n.set_show_all_devices(!0);let t=e.Caps.from_string(`audio/x-raw`),s=e.Caps.from_string(`video/x-raw`);if(t&&(n.add_filter(`Audio/Source`,t),n.add_filter(`Audio/Sink`,t)),s&&n.add_filter(`Video/Source`,s),!n.start())return o;let c;try{c=n.get_devices()??[]}catch{return o}for(let e of c){let t=i[e.get_device_class?.()??``];if(!t)continue;let n=e.get_display_name?.()??``,s=``,c=``;try{let t=e.get_properties?.();if(t){let e=t.n_fields();for(let n=0;n<e;n++){let e=t.nth_field_name(n);if(e===`persistent-id`||e===`node.name`){let n=t.get_value(e);n&&!s&&(s=String(n))}if(e===`group-id`){let n=t.get_value(e);n&&(c=String(n))}}}}catch{}s||=n||`${t}-${o.length}`,a?o.push(new r({deviceId:s,kind:t,label:n,groupId:c})):o.some(e=>e.kind===t)||o.push(new r({deviceId:``,kind:t,label:``,groupId:``}))}}catch{return o}finally{try{n?.stop()}catch{}}let s={audioinput:0,videoinput:1,audiooutput:2};return o.sort((e,t)=>(s[e.kind]??3)-(s[t.kind]??3)),o}getSupportedConstraints(){return{deviceId:!0,width:!0,height:!0,frameRate:!0,sampleRate:!0,channelCount:!0,aspectRatio:!1,facingMode:!1,resizeMode:!1,echoCancellation:!1,autoGainControl:!1,noiseSuppression:!1,latency:!1,groupId:!1}}};export{MediaDevices};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Gst as e}from"./gst-init.js";import"@gjsify/dom-events/register/event-target";import t from"gi://GLib?version=2.0";var n=class
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{Gst as e}from"./gst-init.js";import"@gjsify/dom-events/register/event-target";import t from"gi://GLib?version=2.0";var n=class MediaStreamTrack extends EventTarget{id;kind;label;_enabled=!0;_muted;_ended=!1;_contentHint=``;_onended=null;_onmute=null;_onunmute=null;_gstSource=null;_gstPipeline=null;_gstTee=null;_teeMultiplexer=null;_enableCallback=null;constructor(e){super(),this.id=e.id??t.uuid_string_random(),this.kind=e.kind,this.label=e.label??``,this._muted=e.muted??!1,e._gst&&(this._gstSource=e._gst.source,this._gstPipeline=e._gst.pipeline)}get enabled(){return this._enabled}set enabled(e){let t=!!e;this._enabled!==t&&(this._enabled=t,this._enableCallback?.(t))}get muted(){return this._muted}get readyState(){return this._ended?`ended`:`live`}get contentHint(){return this._contentHint}set contentHint(e){if(this.kind===`audio`){if(e!==``&&e!==`speech`&&e!==`speech-recognition`&&e!==`music`)return}else if(e!==``&&e!==`motion`&&e!==`detail`&&e!==`text`)return;this._contentHint=e}get onended(){return this._onended}set onended(e){this._onended=e}get onmute(){return this._onmute}set onmute(e){this._onmute=e}get onunmute(){return this._onunmute}set onunmute(e){this._onunmute=e}clone(){let e=new MediaStreamTrack({kind:this.kind,label:this.label,muted:this._muted});return e._enabled=this._enabled,e}stop(){if(this._ended)return;if(this._ended=!0,this._gstSource||this._gstPipeline){try{this._gstPipeline?.set_state(e.State.NULL)}catch{}try{this._gstSource?.set_state(e.State.NULL)}catch{}this._gstSource=null,this._gstPipeline=null}let t=new Event(`ended`);this._onended?.call(this,t),this.dispatchEvent(t)}getCapabilities(){return{}}getConstraints(){return{}}getSettings(){return{}}applyConstraints(e){return Promise.reject(new DOMException(`applyConstraints is not supported`,`NotSupportedError`))}_setMuted(e){if(this._muted===e)return;this._muted=e;let t=new Event(e?`mute`:`unmute`);e?this._onmute?.call(this,t):this._onunmute?.call(this,t),this.dispatchEvent(t)}_setEnableCallback(e){this._enableCallback=e}};export{n as MediaStreamTrack};
|
package/lib/esm/media-stream.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"@gjsify/dom-events/register/event-target";import e from"gi://GLib?version=2.0";var t=class
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import"@gjsify/dom-events/register/event-target";import e from"gi://GLib?version=2.0";var t=class MediaStream extends EventTarget{id;_tracks=new Map;_onaddtrack=null;_onremovetrack=null;constructor(t){if(super(),this.id=e.uuid_string_random(),t instanceof MediaStream)for(let e of t.getTracks())this._tracks.set(e.id,e.clone());else if(Array.isArray(t))for(let e of t)this._tracks.set(e.id,e)}get active(){for(let e of this._tracks.values())if(e.readyState===`live`)return!0;return!1}get onaddtrack(){return this._onaddtrack}set onaddtrack(e){this._onaddtrack=e}get onremovetrack(){return this._onremovetrack}set onremovetrack(e){this._onremovetrack=e}getTracks(){return[...this._tracks.values()]}getAudioTracks(){return this.getTracks().filter(e=>e.kind===`audio`)}getVideoTracks(){return this.getTracks().filter(e=>e.kind===`video`)}getTrackById(e){return this._tracks.get(e)??null}addTrack(e){if(this._tracks.has(e.id))return;this._tracks.set(e.id,e);let t=new MediaStreamTrackEvent(`addtrack`,{track:e});this._onaddtrack?.call(this,t),this.dispatchEvent(t)}removeTrack(e){if(!this._tracks.delete(e.id))return;let t=new MediaStreamTrackEvent(`removetrack`,{track:e});this._onremovetrack?.call(this,t),this.dispatchEvent(t)}clone(){return new MediaStream(this)}},MediaStreamTrackEvent=class extends Event{track;constructor(e,t){super(e,t),this.track=t.track}};export{t as MediaStream,MediaStreamTrackEvent};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"gi://GLib?version=2.0";var
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import e from"gi://GLib?version=2.0";var RTCCertificate=class{expires;_fingerprints;_algorithm;constructor(e,t,n){this._algorithm=e,this.expires=t,this._fingerprints=n}getFingerprints(){return[...this._fingerprints]}get _algorithmName(){return this._algorithm}};async function generateCertificate(t){let n;if(typeof t==`string`)n=t.toLowerCase();else if(t&&typeof t==`object`&&typeof t.name==`string`)n=t.name.toLowerCase();else throw new DOMException(`generateCertificate: algorithm must have a name property`,`NotSupportedError`);if(n===`ecdsa`){let e=t.namedCurve;if(e&&e!==`P-256`)throw new DOMException(`generateCertificate: unsupported ECDSA curve '${e}'`,`NotSupportedError`)}else if(n===`rsassa-pkcs1-v1_5`){let e=t.hash,n=typeof e==`string`?e:e?.name;if(n&&n.toUpperCase()===`SHA-1`)throw new DOMException(`generateCertificate: SHA-1 is not supported for RSA certificates`,`NotSupportedError`)}else throw new DOMException(`generateCertificate: unsupported algorithm '${n}'`,`NotSupportedError`);let r=e.uuid_string_random(),i=e.Checksum.new(e.ChecksumType.SHA256);i.update(new TextEncoder().encode(r+Date.now()));let a=i.get_string().slice(0,64).match(/.{2}/g).join(`:`).toUpperCase(),o=Date.now()+2592e6;return new RTCCertificate(n,o,[{algorithm:`sha-256`,value:a}])}export{RTCCertificate,generateCertificate};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{RTCError as e}from"./rtc-error.js";import{RTCErrorEvent as t}from"./rtc-events.js";import{DOMException as n}from"@gjsify/dom-exception";import r from"gi://GLib?version=2.0";import{DataChannelBridge as i}from"@gjsify/webrtc-native";import{Blob as a}from"@gjsify/buffer";const o={1:`connecting`,2:`open`,3:`closing`,4:`closed`};function
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{RTCError as e}from"./rtc-error.js";import{RTCErrorEvent as t}from"./rtc-events.js";import{DOMException as n}from"@gjsify/dom-exception";import r from"gi://GLib?version=2.0";import{DataChannelBridge as i}from"@gjsify/webrtc-native";import{Blob as a}from"@gjsify/buffer";const o={1:`connecting`,2:`open`,3:`closing`,4:`closed`};function toGBytes(e){let t;return t=ArrayBuffer.isView(e)?new Uint8Array(e.buffer,e.byteOffset,e.byteLength):new Uint8Array(e),new r.Bytes(t)}function bytesToArrayBuffer(e){let t=e.toArray?.();if(t instanceof Uint8Array)return t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength);let n=e.get_data?.();return n instanceof Uint8Array?n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength):new ArrayBuffer(0)}var RTCDataChannel=class extends EventTarget{_native;_bridge;_binaryType=`arraybuffer`;_bufferedAmount=0;_closed=!1;_onopen=null;_onclose=null;_onerror=null;_onmessage=null;_onbufferedamountlow=null;_onclosing=null;constructor(e){super(),e.channel!==void 0&&e.dispose_bridge?(this._bridge=e,this._native=this._bridge.channel):(this._native=e,this._bridge=new i({channel:this._native})),this._bridge.connect(`opened`,()=>this._handleOpen()),this._bridge.connect(`closed`,()=>this._handleClose()),this._bridge.connect(`error-occurred`,(e,t)=>this._handleError(t)),this._bridge.connect(`message-string`,(e,t)=>this._handleString(t)),this._bridge.connect(`message-data`,(e,t)=>this._handleData(t)),this._bridge.connect(`buffered-amount-low`,()=>this._handleBufferedAmountLow()),this._bridge.connect(`ready-state-changed`,()=>this._handleReadyStateChange())}get label(){return this._native.label}get ordered(){return this._native.ordered}get protocol(){return this._native.protocol}get negotiated(){return this._native.negotiated}get id(){return this._native.id>=0?this._native.id:null}get maxPacketLifeTime(){let e=this._native.max_packet_lifetime;return e>=0?e:null}get maxRetransmits(){let e=this._native.max_retransmits;return e>=0?e:null}get readyState(){return this._closed?`closed`:o[this._native.ready_state]??`connecting`}get bufferedAmount(){try{return Number(this._native.buffered_amount)||this._bufferedAmount}catch{return this._bufferedAmount}}get bufferedAmountLowThreshold(){return Number(this._native.buffered_amount_low_threshold)||0}set bufferedAmountLowThreshold(e){this._native.buffered_amount_low_threshold=e}get binaryType(){return this._binaryType}set binaryType(e){e!==`arraybuffer`&&e!==`blob`||(this._binaryType=e)}get onopen(){return this._onopen}set onopen(e){this._onopen=e}get onclose(){return this._onclose}set onclose(e){this._onclose=e}get onclosing(){return this._onclosing}set onclosing(e){this._onclosing=e}get onerror(){return this._onerror}set onerror(e){this._onerror=e}get onmessage(){return this._onmessage}set onmessage(e){this._onmessage=e}get onbufferedamountlow(){return this._onbufferedamountlow}set onbufferedamountlow(e){this._onbufferedamountlow=e}send(e){let t=this.readyState;if(t!==`open`)throw new n(`RTCDataChannel.send: readyState is '${t}', expected 'open'`,`InvalidStateError`);if(typeof e==`string`){this._native.send_string(e),this._bufferedAmount+=new TextEncoder().encode(e).byteLength;return}if(e instanceof a){e.arrayBuffer().then(e=>{try{this._native.send_data(toGBytes(e)),this._bufferedAmount+=e.byteLength}catch{}});return}if(ArrayBuffer.isView(e)){let t=toGBytes(e);this._native.send_data(t),this._bufferedAmount+=e.byteLength;return}if(e instanceof ArrayBuffer){let t=toGBytes(e);this._native.send_data(t),this._bufferedAmount+=e.byteLength;return}throw TypeError(`RTCDataChannel.send: unsupported data type`)}close(){if(!this._closed){try{this._native.close()}catch{}this._disconnectSignals(),this._closed=!0}}_disconnectSignals(){try{this._bridge.dispose_bridge()}catch{}}_handleOpen(){let e=new Event(`open`);this._onopen?.call(this,e),this.dispatchEvent(e)}_handleClose(){this._closed=!0;let e=new Event(`close`);this._onclose?.call(this,e),this.dispatchEvent(e)}_handleError(n){let r=new t(`error`,{error:new e({errorDetail:`data-channel-failure`},n||`RTCDataChannel error`)});this._onerror?.call(this,r),this.dispatchEvent(r)}_handleString(e){let t=new MessageEvent(`message`,{data:e});this._onmessage?.call(this,t),this.dispatchEvent(t)}_handleData(e){if(!e)return;let t=bytesToArrayBuffer(e),n=this._binaryType===`blob`?new a([t]):t,r=new MessageEvent(`message`,{data:n});this._onmessage?.call(this,r),this.dispatchEvent(r)}_handleBufferedAmountLow(){this._bufferedAmount=Number(this._native.buffered_amount)||0;let e=new Event(`bufferedamountlow`);this._onbufferedamountlow?.call(this,e),this.dispatchEvent(e)}_handleReadyStateChange(){if(this.readyState===`closing`){let e=new Event(`closing`);this._onclosing?.call(this,e),this.dispatchEvent(e)}}};export{RTCDataChannel};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"@gjsify/dom-events/register/event-target";var
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import"@gjsify/dom-events/register/event-target";var RTCDtlsTransport=class extends EventTarget{iceTransport;_state=`new`;_onstatechange=null;_onerror=null;constructor(e){super(),this.iceTransport=e}get state(){return this._state}get onstatechange(){return this._onstatechange}set onstatechange(e){this._onstatechange=e}get onerror(){return this._onerror}set onerror(e){this._onerror=e}getRemoteCertificates(){return[]}_setState(e){if(this._state===e)return;this._state=e;let t=new Event(`statechange`);this._onstatechange?.call(this,t),this.dispatchEvent(t)}};export{RTCDtlsTransport};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"@gjsify/dom-events/register/event-target";const e=new Set(`0123456789ABCDabcd#*,`);var
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import"@gjsify/dom-events/register/event-target";const e=new Set(`0123456789ABCDabcd#*,`);var RTCDTMFToneChangeEvent=class extends Event{tone;constructor(e,t={}){super(e,t),this.tone=t.tone??``}},RTCDTMFSender=class extends EventTarget{_toneBuffer=``;_duration=100;_interToneGap=70;_timerId=null;_canInsert=!0;_ontonechange=null;_isStopped=()=>!1;_getCurrentDirection=()=>null;get toneBuffer(){return this._toneBuffer}get canInsertDTMF(){return this._canInsert}get ontonechange(){return this._ontonechange}set ontonechange(e){this._ontonechange=e}insertDTMF(t,n,r){if(this._isStopped())throw new DOMException(`Failed to execute 'insertDTMF': The associated transceiver is stopped`,`InvalidStateError`);let i=this._getCurrentDirection();if(i===`recvonly`||i===`inactive`)throw new DOMException(`Failed to execute 'insertDTMF': The associated transceiver direction does not allow sending`,`InvalidStateError`);for(let n of t)if(!e.has(n))throw new DOMException(`Failed to execute 'insertDTMF': Invalid DTMF character '${n}'`,`InvalidCharacterError`);t=t.replace(/[a-d]/g,e=>e.toUpperCase());let a=n??100;this._duration=Math.max(40,Math.min(6e3,a));let o=r??70;this._interToneGap=Math.max(30,o),this._toneBuffer=t,this._timerId!==null&&(clearTimeout(this._timerId),this._timerId=null),t.length>0&&this._scheduleNextTone(0)}_scheduleNextTone(e){this._timerId=setTimeout(()=>{this._timerId=null,this._playNextTone()},e)}_playNextTone(){if(this._toneBuffer.length===0){this._fireToneChange(``);return}let e=this._toneBuffer[0];this._toneBuffer=this._toneBuffer.slice(1),this._fireToneChange(e);let t=e===`,`?2e3:this._duration+this._interToneGap;this._scheduleNextTone(t)}_fireToneChange(e){let t=new RTCDTMFToneChangeEvent(`tonechange`,{tone:e});this._ontonechange?.call(this,t),this.dispatchEvent(t)}_stop(){this._timerId!==null&&(clearTimeout(this._timerId),this._timerId=null),this._toneBuffer=``,this._canInsert=!1}};export{RTCDTMFSender,RTCDTMFToneChangeEvent};
|
package/lib/esm/rtc-error.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"@gjsify/dom-exception/register";var
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import"@gjsify/dom-exception/register";var RTCError=class extends DOMException{errorDetail;sdpLineNumber;sctpCauseCode;receivedAlert;sentAlert;httpRequestStatusCode;constructor(e,t){if(super(t??e.errorDetail,`OperationError`),!e||!e.errorDetail)throw TypeError(`RTCError: errorDetail is required`);this.errorDetail=e.errorDetail,this.sdpLineNumber=e.sdpLineNumber??null,this.sctpCauseCode=e.sctpCauseCode??null,this.receivedAlert=e.receivedAlert??null,this.sentAlert=e.sentAlert??null,this.httpRequestStatusCode=e.httpRequestStatusCode??null}};export{RTCError};
|
package/lib/esm/rtc-events.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"@gjsify/dom-events/register/event-target";var
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import"@gjsify/dom-events/register/event-target";var RTCPeerConnectionIceEvent=class extends Event{candidate;url;constructor(e,t={}){super(e,t),this.candidate=t.candidate??null,this.url=t.url??null}},RTCDataChannelEvent=class extends Event{channel;constructor(e,t){if(super(e,t),!t||!t.channel)throw TypeError("RTCDataChannelEvent requires a `channel` member");this.channel=t.channel}},RTCErrorEvent=class extends Event{error;constructor(e,t){if(super(e,t),!t||!t.error)throw TypeError("RTCErrorEvent requires an `error` member");this.error=t.error}};export{RTCDataChannelEvent,RTCErrorEvent,RTCPeerConnectionIceEvent};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";function parseCandidate(e){let t=e.trim();t.startsWith(`a=`)&&(t=t.slice(2)),t.startsWith(`candidate:`)&&(t=t.slice(10));let n=t.split(/\s+/);if(n.length<8)return{};let r=n[2]?.toLowerCase(),i=n.indexOf(`typ`),a=i>=0?n[i+1]:void 0,o=n.indexOf(`raddr`),s=n.indexOf(`rport`),c=n.indexOf(`tcptype`),l=Number(n[1]);return{foundation:n[0],component:l===1?`rtp`:l===2?`rtcp`:null,priority:Number(n[3])||null,protocol:r===`udp`||r===`tcp`?r:null,address:n[4]??null,port:Number(n[5])||null,type:a===`host`||a===`srflx`||a===`prflx`||a===`relay`?a:null,relatedAddress:o>=0?n[o+1]??null:null,relatedPort:s>=0&&Number(n[s+1])||null,tcpType:c>=0?n[c+1]:null}}var RTCIceCandidate=class{candidate;sdpMid;sdpMLineIndex;usernameFragment;foundation;component;priority;protocol;address;port;type;tcpType;relatedAddress;relatedPort;constructor(e={}){if(e.sdpMid==null&&e.sdpMLineIndex==null)throw TypeError(`RTCIceCandidate requires either sdpMid or sdpMLineIndex`);this.candidate=e.candidate??``,this.sdpMid=e.sdpMid??null,this.sdpMLineIndex=e.sdpMLineIndex??null,this.usernameFragment=e.usernameFragment??null;let t=parseCandidate(this.candidate);this.foundation=t.foundation??null,this.component=t.component??null,this.priority=t.priority??null,this.protocol=t.protocol??null,this.address=t.address??null,this.port=t.port??null,this.type=t.type??null,this.tcpType=t.tcpType??null,this.relatedAddress=t.relatedAddress??null,this.relatedPort=t.relatedPort??null}toJSON(){return{candidate:this.candidate,sdpMid:this.sdpMid,sdpMLineIndex:this.sdpMLineIndex,usernameFragment:this.usernameFragment}}};export{RTCIceCandidate};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{RTCIceCandidate as e}from"./rtc-ice-candidate.js";import"@gjsify/dom-events/register/event-target";var
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{RTCIceCandidate as e}from"./rtc-ice-candidate.js";import"@gjsify/dom-events/register/event-target";var RTCIceTransport=class extends EventTarget{_state=`new`;_gatheringState=`new`;_role=`unknown`;_component=`rtp`;_localCandidates=[];_remoteCandidates=[];_localParams=null;_remoteParams=null;_onstatechange=null;_ongatheringstatechange=null;_onselectedcandidatepairchange=null;get state(){return this._state}get gatheringState(){return this._gatheringState}get role(){return this._role}get component(){return this._component}get onstatechange(){return this._onstatechange}set onstatechange(e){this._onstatechange=e}get ongatheringstatechange(){return this._ongatheringstatechange}set ongatheringstatechange(e){this._ongatheringstatechange=e}get onselectedcandidatepairchange(){return this._onselectedcandidatepairchange}set onselectedcandidatepairchange(e){this._onselectedcandidatepairchange=e}getLocalCandidates(){return[...this._localCandidates]}getRemoteCandidates(){return[...this._remoteCandidates]}getSelectedCandidatePair(){return null}getLocalParameters(){return this._localParams}getRemoteParameters(){return this._remoteParams}_setState(e){if(this._state===e)return;this._state=e;let t=new Event(`statechange`);this._onstatechange?.call(this,t),this.dispatchEvent(t)}_setGatheringState(e){if(this._gatheringState===e)return;this._gatheringState=e;let t=new Event(`gatheringstatechange`);this._ongatheringstatechange?.call(this,t),this.dispatchEvent(t)}_addLocalCandidate(t){this._localCandidates.push(new e(t))}_addRemoteCandidate(t){this._remoteCandidates.push(new e(t))}_setLocalParameters(e){this._localParams=e}_setRemoteParameters(e){this._remoteParams=e}};export{RTCIceTransport};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Gst as e,ensureWebrtcbinAvailable as t}from"./gst-init.js";import{MediaStreamTrack as n}from"./media-stream-track.js";import{MediaStream as r}from"./media-stream.js";import{gstToConnectionState as i,gstToIceConnectionState as a,gstToIceGatheringState as o,gstToSignalingState as s,w3cDirectionToGst as c}from"./gst-enum-maps.js";import{filterStatsByTrackId as l,parseGstStats as u}from"./gst-stats-parser.js";import{withGstPromise as d}from"./gst-utils.js";import{RTCSessionDescription as f}from"./rtc-session-description.js";import{RTCIceCandidate as p}from"./rtc-ice-candidate.js";import{RTCDataChannelEvent as m,RTCPeerConnectionIceEvent as h}from"./rtc-events.js";import{RTCDataChannel as g}from"./rtc-data-channel.js";import{RTCRtpSender as _}from"./rtc-rtp-sender.js";import{RTCRtpReceiver as v}from"./rtc-rtp-receiver.js";import{RTCRtpTransceiver as y}from"./rtc-rtp-transceiver.js";import{RTCTrackEvent as b}from"./rtc-track-event.js";import{RTCIceTransport as x}from"./rtc-ice-transport.js";import{RTCDtlsTransport as S}from"./rtc-dtls-transport.js";import{RTCSctpTransport as C}from"./rtc-sctp-transport.js";import{RTCCertificate as w,generateCertificate as T}from"./rtc-certificate.js";import{DOMException as E}from"@gjsify/dom-exception";import D from"gi://GLib?version=2.0";import O from"gi://GstWebRTC?version=1.0";import{WebrtcbinBridge as k}from"@gjsify/webrtc-native";import A from"gi://GObject?version=2.0";function j(e,t){let n=Number(t);if(!Number.isFinite(n))throw TypeError(`createDataChannel: ${e} must be a finite number, got ${String(t)}`);let r=Math.trunc(n);if(r<0||r>65535)throw TypeError(`createDataChannel: ${e}=${r} is outside the [0, 65535] range`);return r}let M=0;var N=class extends EventTarget{_pipeline;_webrtcbin;_bridge;_conf;_closed=!1;_iceRestartNeeded=!1;_hasNegotiated=!1;_dataChannels=new Map;_transceivers=new Map;_senders=[];_receivers=[];_iceTransport=null;_dtlsTransport=null;_sctpTransport=null;canTrickleIceCandidates=!0;constructor(n){super(),t();let[r,i]=e.version();if(r<1||r===1&&i<20)throw new E(`@gjsify/webrtc requires GStreamer >= 1.20 (you have ${r}.${i}). webrtcbin is only stable from 1.20 onward.`,`NotSupportedError`);let a=++M;this._pipeline=new e.Pipeline({name:`gjsify-webrtc-pipeline-${a}`});let o=e.ElementFactory.make(`webrtcbin`,`gjsify-webrtcbin-${a}`);if(!o)throw Error(`Failed to create webrtcbin element`);if(this._webrtcbin=o,this._conf={...n},n?.certificates){for(let e of n.certificates)if(e instanceof w&&e.expires<=Date.now())throw new E(`RTCPeerConnection: one of the provided certificates has expired`,`InvalidAccessError`)}this._applyIceServers(n?.iceServers??[]),this._applyIceTransportPolicy(n?.iceTransportPolicy),this._applyBundlePolicy(n?.bundlePolicy),this._pipeline.add(this._webrtcbin),this._bridge=new k({bin:this._webrtcbin}),this._bridge.connect(`negotiation-needed`,()=>this._handleNegotiationNeeded()),this._bridge.connect(`icecandidate`,(e,t,n)=>this._handleIceCandidate(t,n)),this._bridge.connect(`datachannel`,(e,t)=>this._handleDataChannel(t)),this._bridge.connect(`new-transceiver`,(e,t)=>this._handleNewTransceiver(t)),this._bridge.connect(`pad-added`,(e,t)=>this._handlePadAdded(t)),this._bridge.connect(`connection-state-changed`,()=>this._dispatchStateChange(`connectionstatechange`)),this._bridge.connect(`ice-connection-state-changed`,()=>this._dispatchStateChange(`iceconnectionstatechange`)),this._bridge.connect(`ice-gathering-state-changed`,()=>this._dispatchStateChange(`icegatheringstatechange`)),this._bridge.connect(`signaling-state-changed`,()=>this._dispatchStateChange(`signalingstatechange`)),this._pipeline.set_state(e.State.PLAYING)}_applyIceServers(e){let t=!1;for(let n of e){let e=Array.isArray(n.urls)?n.urls:[n.urls];if(e.length===0)throw SyntaxError(`RTCIceServer.urls must not be empty`);for(let r of e){if(typeof r!=`string`||r.length===0)throw TypeError(`RTCIceServer.urls entries must be non-empty strings`);let e=r.indexOf(`:`);if(e<0)throw TypeError(`Invalid ICE server URL "${r}"`);let i=r.slice(0,e+1),a=r.slice(e+1);if(i===`stun:`||i===`stuns:`){if(t)continue;this._webrtcbin.stun_server=`${i}//${a}`,t=!0}else if(i===`turn:`||i===`turns:`){if(typeof n.username!=`string`||typeof n.credential!=`string`)throw TypeError(`TURN server credential for ${r} missing`);let e=`${i}//${encodeURIComponent(n.username)}:${encodeURIComponent(n.credential)}@${a}`;try{this._webrtcbin.emit(`add-turn-server`,e)}catch{this._webrtcbin.turn_server=e}}else throw TypeError(`Unsupported ICE server protocol "${i}"`)}}}_applyIceTransportPolicy(e){if(!e)return;let t=e===`relay`?O.WebRTCICETransportPolicy.RELAY:O.WebRTCICETransportPolicy.ALL;try{this._webrtcbin.ice_transport_policy=t}catch{}}_applyBundlePolicy(e){if(!e)return;let t;switch(e){case`balanced`:t=O.WebRTCBundlePolicy.BALANCED;break;case`max-compat`:t=O.WebRTCBundlePolicy.MAX_COMPAT;break;case`max-bundle`:t=O.WebRTCBundlePolicy.MAX_BUNDLE;break;default:return}try{this._webrtcbin.bundle_policy=t}catch{}}get signalingState(){if(this._closed)return`closed`;try{return s(this._webrtcbin.signaling_state)}catch{return`stable`}}get connectionState(){if(this._closed)return`closed`;try{return i(this._webrtcbin.connection_state)}catch{return`new`}}get iceConnectionState(){if(this._closed)return`closed`;try{return a(this._webrtcbin.ice_connection_state)}catch{return`new`}}get iceGatheringState(){try{return o(this._webrtcbin.ice_gathering_state)}catch{return`new`}}_descProp(e){try{let t=this._webrtcbin[e];return t?f.fromGstDesc(t):null}catch{return null}}get localDescription(){return this._descProp(`local_description`)}get remoteDescription(){return this._descProp(`remote_description`)}get currentLocalDescription(){return this._descProp(`current_local_description`)}get currentRemoteDescription(){return this._descProp(`current_remote_description`)}get pendingLocalDescription(){return this._descProp(`pending_local_description`)}get pendingRemoteDescription(){return this._descProp(`pending_remote_description`)}get sctp(){return this._sctpTransport}get peerIdentity(){return Promise.reject(TypeError(`peerIdentity assertions are not implemented`))}get idpErrorInfo(){return null}get idpLoginUrl(){return null}_rejectIfClosed(e){if(this._closed)throw new E(`RTCPeerConnection.${e}: connection is closed`,`InvalidStateError`)}async createOffer(t){this._rejectIfClosed(`createOffer`);let n=e.Structure.new_empty(`offer-options`);this._iceRestartNeeded&&=(this._setStructureField(n,`ice-restart`,`boolean`,!0),!1);let r=(await d(e=>{this._webrtcbin.emit(`create-offer`,n,e)})).get_value(`offer`);return f.fromGstDesc(r).toJSON()}async createAnswer(t){this._rejectIfClosed(`createAnswer`);let n=e.Structure.new_empty(`answer-options`),r=(await d(e=>{this._webrtcbin.emit(`create-answer`,n,e)})).get_value(`answer`);return f.fromGstDesc(r).toJSON()}async setLocalDescription(t){if(this._rejectIfClosed(`setLocalDescription`),!t||!t.type||!t.sdp){let e=this.signalingState;if(e===`stable`||e===`have-local-offer`)t=await this.createOffer();else if(e===`have-remote-offer`||e===`have-remote-pranswer`)t=await this.createAnswer();else throw new E(`setLocalDescription: cannot auto-create SDP in signalingState '${e}'`,`InvalidStateError`)}this._pipeline.set_state(e.State.PLAYING);let n=new f(t).toGstDesc();await d(e=>{this._webrtcbin.emit(`set-local-description`,n,e)})}async setRemoteDescription(t){if(this._rejectIfClosed(`setRemoteDescription`),!t||!t.sdp||!t.type)throw TypeError(`setRemoteDescription requires an RTCSessionDescriptionInit with sdp and type`);this._pipeline.set_state(e.State.PLAYING);let n=new f(t).toGstDesc();await d(e=>{this._webrtcbin.emit(`set-remote-description`,n,e)}),this.signalingState===`stable`&&(this._hasNegotiated=!0)}async addIceCandidate(e){if(this._rejectIfClosed(`addIceCandidate`),!e)return;let{candidate:t,sdpMLineIndex:n}=e;typeof t!=`string`||typeof n!=`number`||this._webrtcbin.emit(`add-ice-candidate`,n,t)}createDataChannel(t,n={}){if(this._closed)throw new E(`Cannot create a data channel on a closed RTCPeerConnection`,`InvalidStateError`);if(typeof t!=`string`)throw TypeError(`createDataChannel: label must be a string`);if(new TextEncoder().encode(t).byteLength>65535)throw TypeError(`createDataChannel: label too long (> 65535 bytes)`);let r=n.maxPacketLifeTime==null?void 0:j(`maxPacketLifeTime`,n.maxPacketLifeTime),i=n.maxRetransmits==null?void 0:j(`maxRetransmits`,n.maxRetransmits),a=n.id==null?void 0:j(`id`,n.id);if(r!==void 0&&i!==void 0)throw TypeError(`createDataChannel: maxPacketLifeTime and maxRetransmits are mutually exclusive`);if(n.negotiated===!0&&a===void 0)throw TypeError(`createDataChannel: negotiated=true requires an id`);if(a===65535)throw TypeError(`createDataChannel: id 65535 is reserved`);let o=e.Structure.new_empty(`data-channel-opts`);this._setStructureField(o,`ordered`,`boolean`,n.ordered),this._setStructureField(o,`max-packet-lifetime`,`int`,r),this._setStructureField(o,`max-retransmits`,`int`,i),this._setStructureField(o,`protocol`,`string`,n.protocol),this._setStructureField(o,`negotiated`,`boolean`,n.negotiated),this._setStructureField(o,`id`,`int`,a);let s=null;try{s=this._webrtcbin.emit(`create-data-channel`,t,o)}catch(e){throw Error(`create-data-channel failed: ${e?.message??e}`)}if(!s)throw Error(`webrtcbin returned null data channel (check id/label/options)`);this._ensureSctpTransport();let c=new g(s);return this._dataChannels.set(s,c),c.addEventListener(`close`,()=>{this._dataChannels.delete(s)}),c}_setStructureField(e,t,n,r){if(r==null)return;let i=new A.Value;n===`boolean`?(i.init(A.TYPE_BOOLEAN),i.set_boolean(!!r)):n===`int`?(i.init(A.TYPE_INT),i.set_int(Number(r))):n===`string`&&(i.init(A.TYPE_STRING),i.set_string(String(r))),e.set_value(t,i),i.unset()}getConfiguration(){return{...this._conf}}close(){this._closed||(this._closed=!0,D.idle_add(D.PRIORITY_DEFAULT,()=>{try{this._pipeline.set_state(e.State.NULL)}catch{}for(let e of this._dataChannels.values())try{e._disconnectSignals()}catch{}this._dataChannels.clear();for(let e of this._senders)try{e._teardownPipeline()}catch{}for(let e of this._receivers)try{e._dispose()}catch{}this._transceivers.clear(),this._senders.length=0,this._receivers.length=0,this._dtlsTransport&&this._dtlsTransport._setState(`closed`),this._iceTransport&&this._iceTransport._setState(`closed`),this._sctpTransport&&this._sctpTransport._setState(`closed`);try{this._bridge.dispose_bridge()}catch{}return D.SOURCE_REMOVE}))}addTransceiver(t,r){this._rejectIfClosed(`addTransceiver`);let i;if(typeof t==`string`){if(t!==`audio`&&t!==`video`)throw TypeError(`Failed to execute 'addTransceiver' on 'RTCPeerConnection': The provided value '${t}' is not a valid enum value of type MediaStreamTrackKind.`);i=t}else if(t instanceof n)i=t.kind;else throw TypeError(`Failed to execute 'addTransceiver' on 'RTCPeerConnection': parameter 1 is not of type 'MediaStreamTrack' or a valid MediaStreamTrackKind.`);if(r?.sendEncodings){let e=new Set;for(let t of r.sendEncodings){if(t.rid!==void 0){if(typeof t.rid!=`string`||t.rid.length===0||t.rid.length>16||!/^[a-zA-Z0-9]+$/.test(t.rid))throw TypeError(`Invalid RID value: ${t.rid}`);if(e.has(t.rid))throw TypeError(`Duplicate RID: ${t.rid}`);e.add(t.rid)}if(t.scaleResolutionDownBy!==void 0&&t.scaleResolutionDownBy<1)throw RangeError(`scaleResolutionDownBy must be >= 1.0`)}}let a=r?.direction??`sendrecv`;if(![`sendrecv`,`sendonly`,`recvonly`,`inactive`].includes(a))throw TypeError(`Failed to execute 'addTransceiver' on 'RTCPeerConnection': The provided value '${a}' is not a valid enum value of type RTCRtpTransceiverDirection.`);let o=t instanceof n&&t._gstSource,s=a===`sendrecv`||a===`sendonly`,l,u;if(o&&s){let e=t,n=new _(null,this._pipeline,this._webrtcbin);if(n._kind=i,n._onPipelineChanged=e=>{this._pipeline=e},n._setTrack(e),n._wirePipeline(e),l=this._findNewGstTransceiver(),!l)throw Error(`webrtcbin did not create a transceiver for the send pad`);let r=l.receiver??null,o=new v(i,r,this._pipeline),s=e=>this.getStats(e);n._getStatsForTrack=s,o._getStatsForTrack=s;let d=this._ensureTransports();n._transport=d,o._transport=d,u=new y(l,n,o),n._transceiver=u,this._transceivers.set(l,u),this._senders.push(n),this._receivers.push(o),l.direction=c(a)}else{let r=e.Caps.from_string(`application/x-rtp,media=${i}`),o=c(a===`inactive`?`sendrecv`:a);if(l=this._webrtcbin.emit(`add-transceiver`,o,r),!l)throw Error(`webrtcbin did not create a transceiver`);u=this._transceivers.get(l),u||=this._createTransceiverWrapper(l),l.direction=c(a),t instanceof n&&u.sender._setTrack(t)}return u}addTrack(e,...t){if(this._rejectIfClosed(`addTrack`),!(e instanceof n))throw TypeError(`Failed to execute 'addTrack' on 'RTCPeerConnection': parameter 1 is not a MediaStreamTrack`);if(this._senders.find(t=>t.track===e))throw new E(`Track already exists in a sender of this connection`,`InvalidAccessError`);let r;for(let t of this._transceivers.values())if(t.sender.track===null&&!t.stopped&&t.direction!==`stopped`&&t.receiver.track.kind===e.kind){let e=t.direction;if(e===`recvonly`||e===`inactive`){r=t;break}}if(r){let t=r.direction;return r.direction=t===`recvonly`?`sendrecv`:`sendonly`,r.sender._setTrack(e),r.sender}return this.addTransceiver(e,{direction:`sendrecv`}).sender}removeTrack(e){if(this._rejectIfClosed(`removeTrack`),!this._senders.includes(e))throw new E(`sender was not created by this connection`,`InvalidAccessError`);e._setTrack(null)}getSenders(){return[...this._senders]}getReceivers(){return[...this._receivers]}getTransceivers(){return[...this._transceivers.values()]}async getStats(e){if(this._rejectIfClosed(`getStats`),e!=null&&e instanceof n){let t=this._senders.some(t=>t.track===e),n=this._receivers.some(t=>t.track===e);if(!t&&!n)throw new E(`The selector track is not associated with a sender or receiver of this connection`,`InvalidAccessError`)}let t=u(await d(e=>{this._webrtcbin.emit(`get-stats`,null,e)}));return e!=null&&e instanceof n?l(t,e.id):t}restartIce(){this._closed||(this._iceRestartNeeded=!0,this._hasNegotiated&&Promise.resolve().then(()=>{this._closed||this._handleNegotiationNeeded()}))}setConfiguration(e){if(this._rejectIfClosed(`setConfiguration`),e.bundlePolicy&&e.bundlePolicy!==(this._conf.bundlePolicy??`balanced`))throw new E(`setConfiguration: bundlePolicy cannot be changed`,`InvalidModificationError`);if(e.rtcpMuxPolicy&&e.rtcpMuxPolicy!==(this._conf.rtcpMuxPolicy??`require`))throw new E(`setConfiguration: rtcpMuxPolicy cannot be changed`,`InvalidModificationError`);e.iceServers&&this._applyIceServers(e.iceServers),e.iceTransportPolicy&&this._applyIceTransportPolicy(e.iceTransportPolicy),this._conf={...this._conf,...e}}getIdentityAssertion(){return Promise.reject(Error(`getIdentityAssertion is not implemented`))}_findNewGstTransceiver(){for(let e=0;;e++){let t=this._webrtcbin.emit(`get-transceiver`,e);if(!t)return null;if(!this._transceivers.has(t))return t}}_ensureTransports(){return this._dtlsTransport||=(this._iceTransport=new x,new S(this._iceTransport)),this._dtlsTransport}_ensureSctpTransport(){if(this._sctpTransport)return;let e=this._ensureTransports();this._sctpTransport=new C(e)}_createTransceiverWrapper(e){let t=`audio`;try{e.kind===O.WebRTCKind.VIDEO&&(t=`video`)}catch{}let n=e.receiver??null,r=e.sender??null,i=new v(t,n,this._pipeline),a=new _(r,this._pipeline,this._webrtcbin);a._kind=t,a._onPipelineChanged=e=>{this._pipeline=e};let o=e=>this.getStats(e);a._getStatsForTrack=o,i._getStatsForTrack=o;let s=this._ensureTransports();a._transport=s,i._transport=s;try{let t=e.mlineindex;typeof t==`number`&&t>=0&&a._setMlineIndex(t)}catch{}let c=new y(e,a,i);return a._transceiver=c,this._transceivers.set(e,c),this._senders.push(a),this._receivers.push(i),c}_handleNegotiationNeeded(){let e=new Event(`negotiationneeded`);this._onnegotiationneeded?.call(this,e),this.dispatchEvent(e)}_handleIceCandidate(e,t){let n=new h(`icecandidate`,{candidate:new p({candidate:t,sdpMLineIndex:e})});this._onicecandidate?.call(this,n),this.dispatchEvent(n)}_handleNewTransceiver(e){this._closed||this._transceivers.has(e)||this._createTransceiverWrapper(e)}_handlePadAdded(t){if(this._closed||t.direction!==e.PadDirection.SRC)return;let n=t.transceiver;if(!n)return;let i=this._transceivers.get(n);i||=this._createTransceiverWrapper(n),i.receiver._connectToPad(t);let a=new r([i.receiver.track]),o=new b(`track`,{receiver:i.receiver,track:i.receiver.track,streams:[a],transceiver:i});this._ontrack?.call(this,o),this.dispatchEvent(o)}_handleDataChannel(e){this._ensureSctpTransport();let t=e.channel,n=this._dataChannels.get(t);n||(n=new g(e),this._dataChannels.set(t,n),n.addEventListener(`close`,()=>{this._dataChannels.delete(t)}));let r=new m(`datachannel`,{channel:n});this._ondatachannel?.call(this,r),this.dispatchEvent(r)}_dispatchStateChange(e){e===`connectionstatechange`?this._syncDtlsState():e===`iceconnectionstatechange`?this._syncIceState():e===`icegatheringstatechange`&&this._syncIceGatheringState();let t=new Event(e);switch(e){case`connectionstatechange`:this._onconnectionstatechange?.call(this,t);break;case`iceconnectionstatechange`:this._oniceconnectionstatechange?.call(this,t);break;case`icegatheringstatechange`:this._onicegatheringstatechange?.call(this,t);break;case`signalingstatechange`:this._onsignalingstatechange?.call(this,t);break}this.dispatchEvent(t)}_syncDtlsState(){if(!this._dtlsTransport)return;let e=this.connectionState;this._dtlsTransport._setState({new:`new`,connecting:`connecting`,connected:`connected`,disconnected:`connected`,failed:`failed`,closed:`closed`}[e]??`new`),e===`connected`&&this._sctpTransport&&this._sctpTransport._setState(`connected`)}_syncIceState(){if(!this._iceTransport)return;let e=this.iceConnectionState;this._iceTransport._setState(e)}_syncIceGatheringState(){if(!this._iceTransport)return;let e=this.iceGatheringState;this._iceTransport._setGatheringState(e)}_onconnectionstatechange=null;_ondatachannel=null;_onicecandidate=null;_oniceconnectionstatechange=null;_onicegatheringstatechange=null;_onnegotiationneeded=null;_onsignalingstatechange=null;get onconnectionstatechange(){return this._onconnectionstatechange}set onconnectionstatechange(e){this._onconnectionstatechange=e}get ondatachannel(){return this._ondatachannel}set ondatachannel(e){this._ondatachannel=e}get onicecandidate(){return this._onicecandidate}set onicecandidate(e){this._onicecandidate=e}get oniceconnectionstatechange(){return this._oniceconnectionstatechange}set oniceconnectionstatechange(e){this._oniceconnectionstatechange=e}get onicegatheringstatechange(){return this._onicegatheringstatechange}set onicegatheringstatechange(e){this._onicegatheringstatechange=e}get onnegotiationneeded(){return this._onnegotiationneeded}set onnegotiationneeded(e){this._onnegotiationneeded=e}get onsignalingstatechange(){return this._onsignalingstatechange}set onsignalingstatechange(e){this._onsignalingstatechange=e}_ontrack=null;get ontrack(){return this._ontrack}set ontrack(e){this._ontrack=e}get onicecandidateerror(){return null}set onicecandidateerror(e){}static generateCertificate(e){return T(e)}};export{N as RTCPeerConnection};
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{Gst as e,ensureWebrtcbinAvailable as t}from"./gst-init.js";import{MediaStreamTrack as n}from"./media-stream-track.js";import{MediaStream as r}from"./media-stream.js";import{gstToConnectionState as i,gstToIceConnectionState as a,gstToIceGatheringState as o,gstToSignalingState as s,w3cDirectionToGst as c}from"./gst-enum-maps.js";import{filterStatsByTrackId as l,parseGstStats as u}from"./gst-stats-parser.js";import{withGstPromise as d}from"./gst-utils.js";import{asWebRtcBin as f,asWebRtcSrcPad as p}from"./internal/gst-types.js";import{RTCSessionDescription as m}from"./rtc-session-description.js";import{RTCIceCandidate as h}from"./rtc-ice-candidate.js";import{RTCDataChannelEvent as g,RTCPeerConnectionIceEvent as _}from"./rtc-events.js";import{RTCDataChannel as v}from"./rtc-data-channel.js";import{RTCRtpSender as y}from"./rtc-rtp-sender.js";import{RTCRtpReceiver as b}from"./rtc-rtp-receiver.js";import{RTCRtpTransceiver as x}from"./rtc-rtp-transceiver.js";import{RTCTrackEvent as S}from"./rtc-track-event.js";import{RTCIceTransport as C}from"./rtc-ice-transport.js";import{RTCDtlsTransport as w}from"./rtc-dtls-transport.js";import{RTCSctpTransport as T}from"./rtc-sctp-transport.js";import{RTCCertificate as E,generateCertificate as D}from"./rtc-certificate.js";import{DOMException as O}from"@gjsify/dom-exception";import k from"gi://GLib?version=2.0";import A from"gi://GstWebRTC?version=1.0";import{WebrtcbinBridge as j}from"@gjsify/webrtc-native";import M from"gi://GObject?version=2.0";function coerceUnsignedShort(e,t){let n=Number(t);if(!Number.isFinite(n))throw TypeError(`createDataChannel: ${e} must be a finite number, got ${String(t)}`);let r=Math.trunc(n);if(r<0||r>65535)throw TypeError(`createDataChannel: ${e}=${r} is outside the [0, 65535] range`);return r}let N=0;var RTCPeerConnection=class extends EventTarget{_pipeline;_webrtcbin;_bridge;_conf;_closed=!1;_iceRestartNeeded=!1;_hasNegotiated=!1;_dataChannels=new Map;_transceivers=new Map;_senders=[];_receivers=[];_iceTransport=null;_dtlsTransport=null;_sctpTransport=null;canTrickleIceCandidates=!0;constructor(n){super(),t();let[r,i]=e.version();if(r<1||r===1&&i<20)throw new O(`@gjsify/webrtc requires GStreamer >= 1.20 (you have ${r}.${i}). webrtcbin is only stable from 1.20 onward.`,`NotSupportedError`);let a=++N;this._pipeline=new e.Pipeline({name:`gjsify-webrtc-pipeline-${a}`});let o=e.ElementFactory.make(`webrtcbin`,`gjsify-webrtcbin-${a}`);if(!o)throw Error(`Failed to create webrtcbin element`);if(this._webrtcbin=o,this._conf={...n},n?.certificates){for(let e of n.certificates)if(e instanceof E&&e.expires<=Date.now())throw new O(`RTCPeerConnection: one of the provided certificates has expired`,`InvalidAccessError`)}this._applyIceServers(n?.iceServers??[]),this._applyIceTransportPolicy(n?.iceTransportPolicy),this._applyBundlePolicy(n?.bundlePolicy),this._pipeline.add(this._webrtcbin),this._bridge=new j({bin:this._webrtcbin}),this._bridge.connect(`negotiation-needed`,()=>this._handleNegotiationNeeded()),this._bridge.connect(`icecandidate`,(e,t,n)=>this._handleIceCandidate(t,n)),this._bridge.connect(`datachannel`,(e,t)=>this._handleDataChannel(t)),this._bridge.connect(`new-transceiver`,(e,t)=>this._handleNewTransceiver(t)),this._bridge.connect(`pad-added`,(e,t)=>this._handlePadAdded(t)),this._bridge.connect(`connection-state-changed`,()=>this._dispatchStateChange(`connectionstatechange`)),this._bridge.connect(`ice-connection-state-changed`,()=>this._dispatchStateChange(`iceconnectionstatechange`)),this._bridge.connect(`ice-gathering-state-changed`,()=>this._dispatchStateChange(`icegatheringstatechange`)),this._bridge.connect(`signaling-state-changed`,()=>this._dispatchStateChange(`signalingstatechange`)),this._pipeline.set_state(e.State.PLAYING)}_applyIceServers(e){let t=!1;for(let n of e){let e=Array.isArray(n.urls)?n.urls:[n.urls];if(e.length===0)throw SyntaxError(`RTCIceServer.urls must not be empty`);for(let r of e){if(typeof r!=`string`||r.length===0)throw TypeError(`RTCIceServer.urls entries must be non-empty strings`);let e=r.indexOf(`:`);if(e<0)throw TypeError(`Invalid ICE server URL "${r}"`);let i=r.slice(0,e+1),a=r.slice(e+1);if(i===`stun:`||i===`stuns:`){if(t)continue;f(this._webrtcbin).stun_server=`${i}//${a}`,t=!0}else if(i===`turn:`||i===`turns:`){if(typeof n.username!=`string`||typeof n.credential!=`string`)throw TypeError(`TURN server credential for ${r} missing`);let e=`${i}//${encodeURIComponent(n.username)}:${encodeURIComponent(n.credential)}@${a}`;try{this._webrtcbin.emit(`add-turn-server`,e)}catch{f(this._webrtcbin).turn_server=e}}else throw TypeError(`Unsupported ICE server protocol "${i}"`)}}}_applyIceTransportPolicy(e){if(!e)return;let t=e===`relay`?A.WebRTCICETransportPolicy.RELAY:A.WebRTCICETransportPolicy.ALL;try{f(this._webrtcbin).ice_transport_policy=t}catch{}}_applyBundlePolicy(e){if(!e)return;let t;switch(e){case`balanced`:t=A.WebRTCBundlePolicy.BALANCED;break;case`max-compat`:t=A.WebRTCBundlePolicy.MAX_COMPAT;break;case`max-bundle`:t=A.WebRTCBundlePolicy.MAX_BUNDLE;break;default:return}try{f(this._webrtcbin).bundle_policy=t}catch{}}get signalingState(){if(this._closed)return`closed`;try{return s(f(this._webrtcbin).signaling_state)}catch{return`stable`}}get connectionState(){if(this._closed)return`closed`;try{return i(f(this._webrtcbin).connection_state)}catch{return`new`}}get iceConnectionState(){if(this._closed)return`closed`;try{return a(f(this._webrtcbin).ice_connection_state)}catch{return`new`}}get iceGatheringState(){try{return o(f(this._webrtcbin).ice_gathering_state)}catch{return`new`}}_descProp(e){try{let t=f(this._webrtcbin)[e];return t?m.fromGstDesc(t):null}catch{return null}}get localDescription(){return this._descProp(`local_description`)}get remoteDescription(){return this._descProp(`remote_description`)}get currentLocalDescription(){return this._descProp(`current_local_description`)}get currentRemoteDescription(){return this._descProp(`current_remote_description`)}get pendingLocalDescription(){return this._descProp(`pending_local_description`)}get pendingRemoteDescription(){return this._descProp(`pending_remote_description`)}get sctp(){return this._sctpTransport}get peerIdentity(){return Promise.reject(TypeError(`peerIdentity assertions are not implemented`))}get idpErrorInfo(){return null}get idpLoginUrl(){return null}_rejectIfClosed(e){if(this._closed)throw new O(`RTCPeerConnection.${e}: connection is closed`,`InvalidStateError`)}async createOffer(t){this._rejectIfClosed(`createOffer`);let n=e.Structure.new_empty(`offer-options`);this._iceRestartNeeded&&=(this._setStructureField(n,`ice-restart`,`boolean`,!0),!1);let r=(await d(e=>{this._webrtcbin.emit(`create-offer`,n,e)})).get_value(`offer`);return m.fromGstDesc(r).toJSON()}async createAnswer(t){this._rejectIfClosed(`createAnswer`);let n=e.Structure.new_empty(`answer-options`),r=(await d(e=>{this._webrtcbin.emit(`create-answer`,n,e)})).get_value(`answer`);return m.fromGstDesc(r).toJSON()}async setLocalDescription(t){if(this._rejectIfClosed(`setLocalDescription`),!t||!t.type||!t.sdp){let e=this.signalingState;if(e===`stable`||e===`have-local-offer`)t=await this.createOffer();else if(e===`have-remote-offer`||e===`have-remote-pranswer`)t=await this.createAnswer();else throw new O(`setLocalDescription: cannot auto-create SDP in signalingState '${e}'`,`InvalidStateError`)}this._pipeline.set_state(e.State.PLAYING);let n=new m(t).toGstDesc();await d(e=>{this._webrtcbin.emit(`set-local-description`,n,e)})}async setRemoteDescription(t){if(this._rejectIfClosed(`setRemoteDescription`),!t||!t.sdp||!t.type)throw TypeError(`setRemoteDescription requires an RTCSessionDescriptionInit with sdp and type`);this._pipeline.set_state(e.State.PLAYING);let n=new m(t).toGstDesc();await d(e=>{this._webrtcbin.emit(`set-remote-description`,n,e)}),this.signalingState===`stable`&&(this._hasNegotiated=!0)}async addIceCandidate(e){if(this._rejectIfClosed(`addIceCandidate`),!e)return;let{candidate:t,sdpMLineIndex:n}=e;typeof t!=`string`||typeof n!=`number`||this._webrtcbin.emit(`add-ice-candidate`,n,t)}createDataChannel(t,n={}){if(this._closed)throw new O(`Cannot create a data channel on a closed RTCPeerConnection`,`InvalidStateError`);if(typeof t!=`string`)throw TypeError(`createDataChannel: label must be a string`);if(new TextEncoder().encode(t).byteLength>65535)throw TypeError(`createDataChannel: label too long (> 65535 bytes)`);let r=n.maxPacketLifeTime==null?void 0:coerceUnsignedShort(`maxPacketLifeTime`,n.maxPacketLifeTime),i=n.maxRetransmits==null?void 0:coerceUnsignedShort(`maxRetransmits`,n.maxRetransmits),a=n.id==null?void 0:coerceUnsignedShort(`id`,n.id);if(r!==void 0&&i!==void 0)throw TypeError(`createDataChannel: maxPacketLifeTime and maxRetransmits are mutually exclusive`);if(n.negotiated===!0&&a===void 0)throw TypeError(`createDataChannel: negotiated=true requires an id`);if(a===65535)throw TypeError(`createDataChannel: id 65535 is reserved`);let o=e.Structure.new_empty(`data-channel-opts`);this._setStructureField(o,`ordered`,`boolean`,n.ordered),this._setStructureField(o,`max-packet-lifetime`,`int`,r),this._setStructureField(o,`max-retransmits`,`int`,i),this._setStructureField(o,`protocol`,`string`,n.protocol),this._setStructureField(o,`negotiated`,`boolean`,n.negotiated),this._setStructureField(o,`id`,`int`,a);let s=null;try{s=this._webrtcbin.emit(`create-data-channel`,t,o)}catch(e){throw Error(`create-data-channel failed: ${e?.message??e}`)}if(!s)throw Error(`webrtcbin returned null data channel (check id/label/options)`);this._ensureSctpTransport();let c=new v(s);return this._dataChannels.set(s,c),c.addEventListener(`close`,()=>{this._dataChannels.delete(s)}),c}_setStructureField(e,t,n,r){if(r==null)return;let i=new M.Value;n===`boolean`?(i.init(M.TYPE_BOOLEAN),i.set_boolean(!!r)):n===`int`?(i.init(M.TYPE_INT),i.set_int(Number(r))):n===`string`&&(i.init(M.TYPE_STRING),i.set_string(String(r))),e.set_value(t,i),i.unset()}getConfiguration(){return{...this._conf}}close(){this._closed||(this._closed=!0,k.idle_add(k.PRIORITY_DEFAULT,()=>{try{this._pipeline.set_state(e.State.NULL)}catch{}for(let e of this._dataChannels.values())try{e._disconnectSignals()}catch{}this._dataChannels.clear();for(let e of this._senders)try{e._teardownPipeline()}catch{}for(let e of this._receivers)try{e._dispose()}catch{}this._transceivers.clear(),this._senders.length=0,this._receivers.length=0,this._dtlsTransport&&this._dtlsTransport._setState(`closed`),this._iceTransport&&this._iceTransport._setState(`closed`),this._sctpTransport&&this._sctpTransport._setState(`closed`);try{this._bridge.dispose_bridge()}catch{}return k.SOURCE_REMOVE}))}addTransceiver(t,r){this._rejectIfClosed(`addTransceiver`);let i;if(typeof t==`string`){if(t!==`audio`&&t!==`video`)throw TypeError(`Failed to execute 'addTransceiver' on 'RTCPeerConnection': The provided value '${t}' is not a valid enum value of type MediaStreamTrackKind.`);i=t}else if(t instanceof n)i=t.kind;else throw TypeError(`Failed to execute 'addTransceiver' on 'RTCPeerConnection': parameter 1 is not of type 'MediaStreamTrack' or a valid MediaStreamTrackKind.`);if(r?.sendEncodings){let e=new Set;for(let t of r.sendEncodings){if(t.rid!==void 0){if(typeof t.rid!=`string`||t.rid.length===0||t.rid.length>16||!/^[a-zA-Z0-9]+$/.test(t.rid))throw TypeError(`Invalid RID value: ${t.rid}`);if(e.has(t.rid))throw TypeError(`Duplicate RID: ${t.rid}`);e.add(t.rid)}if(t.scaleResolutionDownBy!==void 0&&t.scaleResolutionDownBy<1)throw RangeError(`scaleResolutionDownBy must be >= 1.0`)}}let a=r?.direction??`sendrecv`;if(![`sendrecv`,`sendonly`,`recvonly`,`inactive`].includes(a))throw TypeError(`Failed to execute 'addTransceiver' on 'RTCPeerConnection': The provided value '${a}' is not a valid enum value of type RTCRtpTransceiverDirection.`);let o=t instanceof n&&t._gstSource,s=a===`sendrecv`||a===`sendonly`,l,u;if(o&&s){let e=t,n=new y(null,this._pipeline,this._webrtcbin);n._kind=i,n._onPipelineChanged=e=>{this._pipeline=e},n._setTrack(e),n._wirePipeline(e);let r=this._findNewGstTransceiver();if(!r)throw Error(`webrtcbin did not create a transceiver for the send pad`);l=r;let o=l.receiver??null,s=new b(i,o,this._pipeline),statsDelegate=e=>this.getStats(e);n._getStatsForTrack=statsDelegate,s._getStatsForTrack=statsDelegate;let d=this._ensureTransports();n._transport=d,s._transport=d,u=new x(l,n,s),n._transceiver=u,this._transceivers.set(l,u),this._senders.push(n),this._receivers.push(s),l.direction=c(a)}else{let r=e.Caps.from_string(`application/x-rtp,media=${i}`),o=c(a===`inactive`?`sendrecv`:a),s=this._webrtcbin.emit(`add-transceiver`,o,r);if(!s)throw Error(`webrtcbin did not create a transceiver`);l=s,u=this._transceivers.get(l),u||=this._createTransceiverWrapper(l),l.direction=c(a),t instanceof n&&u.sender._setTrack(t)}return u}addTrack(e,...t){if(this._rejectIfClosed(`addTrack`),!(e instanceof n))throw TypeError(`Failed to execute 'addTrack' on 'RTCPeerConnection': parameter 1 is not a MediaStreamTrack`);if(this._senders.find(t=>t.track===e))throw new O(`Track already exists in a sender of this connection`,`InvalidAccessError`);let r;for(let t of this._transceivers.values())if(t.sender.track===null&&!t.stopped&&t.direction!==`stopped`&&t.receiver.track.kind===e.kind){let e=t.direction;if(e===`recvonly`||e===`inactive`){r=t;break}}if(r){let t=r.direction;return r.direction=t===`recvonly`?`sendrecv`:`sendonly`,r.sender._setTrack(e),r.sender}return this.addTransceiver(e,{direction:`sendrecv`}).sender}removeTrack(e){if(this._rejectIfClosed(`removeTrack`),!this._senders.includes(e))throw new O(`sender was not created by this connection`,`InvalidAccessError`);e._setTrack(null)}getSenders(){return[...this._senders]}getReceivers(){return[...this._receivers]}getTransceivers(){return[...this._transceivers.values()]}async getStats(e){if(this._rejectIfClosed(`getStats`),e!=null&&e instanceof n){let t=this._senders.some(t=>t.track===e),n=this._receivers.some(t=>t.track===e);if(!t&&!n)throw new O(`The selector track is not associated with a sender or receiver of this connection`,`InvalidAccessError`)}let t=u(await d(e=>{this._webrtcbin.emit(`get-stats`,null,e)}));return e!=null&&e instanceof n?l(t,e.id):t}restartIce(){this._closed||(this._iceRestartNeeded=!0,this._hasNegotiated&&Promise.resolve().then(()=>{this._closed||this._handleNegotiationNeeded()}))}setConfiguration(e){if(this._rejectIfClosed(`setConfiguration`),e.bundlePolicy&&e.bundlePolicy!==(this._conf.bundlePolicy??`balanced`))throw new O(`setConfiguration: bundlePolicy cannot be changed`,`InvalidModificationError`);if(e.rtcpMuxPolicy&&e.rtcpMuxPolicy!==(this._conf.rtcpMuxPolicy??`require`))throw new O(`setConfiguration: rtcpMuxPolicy cannot be changed`,`InvalidModificationError`);e.iceServers&&this._applyIceServers(e.iceServers),e.iceTransportPolicy&&this._applyIceTransportPolicy(e.iceTransportPolicy),this._conf={...this._conf,...e}}getIdentityAssertion(){return Promise.reject(Error(`getIdentityAssertion is not implemented`))}_findNewGstTransceiver(){for(let e=0;;e++){let t=this._webrtcbin.emit(`get-transceiver`,e);if(!t)return null;if(!this._transceivers.has(t))return t}}_ensureTransports(){return this._dtlsTransport||=(this._iceTransport=new C,new w(this._iceTransport)),this._dtlsTransport}_ensureSctpTransport(){if(this._sctpTransport)return;let e=this._ensureTransports();this._sctpTransport=new T(e)}_createTransceiverWrapper(e){let t=`audio`;try{e.kind===A.WebRTCKind.VIDEO&&(t=`video`)}catch{}let n=e.receiver??null,r=e.sender??null,i=new b(t,n,this._pipeline),a=new y(r,this._pipeline,this._webrtcbin);a._kind=t,a._onPipelineChanged=e=>{this._pipeline=e};let statsDelegate=e=>this.getStats(e);a._getStatsForTrack=statsDelegate,i._getStatsForTrack=statsDelegate;let o=this._ensureTransports();a._transport=o,i._transport=o;try{let t=e.mlineindex;typeof t==`number`&&t>=0&&a._setMlineIndex(t)}catch{}let s=new x(e,a,i);return a._transceiver=s,this._transceivers.set(e,s),this._senders.push(a),this._receivers.push(i),s}_handleNegotiationNeeded(){let e=new Event(`negotiationneeded`);this._onnegotiationneeded?.call(this,e),this.dispatchEvent(e)}_handleIceCandidate(e,t){let n=new _(`icecandidate`,{candidate:new h({candidate:t,sdpMLineIndex:e})});this._onicecandidate?.call(this,n),this.dispatchEvent(n)}_handleNewTransceiver(e){this._closed||this._transceivers.has(e)||this._createTransceiverWrapper(e)}_handlePadAdded(t){if(this._closed||t.direction!==e.PadDirection.SRC)return;let n=p(t).transceiver;if(!n)return;let i=this._transceivers.get(n);i||=this._createTransceiverWrapper(n),i.receiver._connectToPad(t);let a=new r([i.receiver.track]),o=new S(`track`,{receiver:i.receiver,track:i.receiver.track,streams:[a],transceiver:i});this._ontrack?.call(this,o),this.dispatchEvent(o)}_handleDataChannel(e){this._ensureSctpTransport();let t=e.channel,n=this._dataChannels.get(t);n||(n=new v(e),this._dataChannels.set(t,n),n.addEventListener(`close`,()=>{this._dataChannels.delete(t)}));let r=new g(`datachannel`,{channel:n});this._ondatachannel?.call(this,r),this.dispatchEvent(r)}_dispatchStateChange(e){e===`connectionstatechange`?this._syncDtlsState():e===`iceconnectionstatechange`?this._syncIceState():e===`icegatheringstatechange`&&this._syncIceGatheringState();let t=new Event(e);switch(e){case`connectionstatechange`:this._onconnectionstatechange?.call(this,t);break;case`iceconnectionstatechange`:this._oniceconnectionstatechange?.call(this,t);break;case`icegatheringstatechange`:this._onicegatheringstatechange?.call(this,t);break;case`signalingstatechange`:this._onsignalingstatechange?.call(this,t);break}this.dispatchEvent(t)}_syncDtlsState(){if(!this._dtlsTransport)return;let e=this.connectionState;this._dtlsTransport._setState({new:`new`,connecting:`connecting`,connected:`connected`,disconnected:`connected`,failed:`failed`,closed:`closed`}[e]??`new`),e===`connected`&&this._sctpTransport&&this._sctpTransport._setState(`connected`)}_syncIceState(){if(!this._iceTransport)return;let e=this.iceConnectionState;this._iceTransport._setState(e)}_syncIceGatheringState(){if(!this._iceTransport)return;let e=this.iceGatheringState;this._iceTransport._setGatheringState(e)}_onconnectionstatechange=null;_ondatachannel=null;_onicecandidate=null;_oniceconnectionstatechange=null;_onicegatheringstatechange=null;_onnegotiationneeded=null;_onsignalingstatechange=null;get onconnectionstatechange(){return this._onconnectionstatechange}set onconnectionstatechange(e){this._onconnectionstatechange=e}get ondatachannel(){return this._ondatachannel}set ondatachannel(e){this._ondatachannel=e}get onicecandidate(){return this._onicecandidate}set onicecandidate(e){this._onicecandidate=e}get oniceconnectionstatechange(){return this._oniceconnectionstatechange}set oniceconnectionstatechange(e){this._oniceconnectionstatechange=e}get onicegatheringstatechange(){return this._onicegatheringstatechange}set onicegatheringstatechange(e){this._onicegatheringstatechange=e}get onnegotiationneeded(){return this._onnegotiationneeded}set onnegotiationneeded(e){this._onnegotiationneeded=e}get onsignalingstatechange(){return this._onsignalingstatechange}set onsignalingstatechange(e){this._onsignalingstatechange=e}_ontrack=null;get ontrack(){return this._ontrack}set ontrack(e){this._ontrack=e}get onicecandidateerror(){return null}set onicecandidateerror(e){}static generateCertificate(e){return D(e)}};export{RTCPeerConnection};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{MediaStreamTrack as e}from"./media-stream-track.js";import{getRtpCapabilities as t}from"./rtp-capabilities.js";import{ReceiverBridge as n}from"@gjsify/webrtc-native";const r=4e3;var
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{MediaStreamTrack as e}from"./media-stream-track.js";import{getRtpCapabilities as t}from"./rtp-capabilities.js";import{ReceiverBridge as n}from"@gjsify/webrtc-native";const r=4e3;var RTCRtpReceiver=class{_gstReceiver;_track;_jitterBufferTarget=null;_pipeline=null;_receiverBridge=null;_getStatsForTrack=null;constructor(t,n,r){this._gstReceiver=n,this._pipeline=r??null,this._track=new e({kind:t,muted:!0})}_connectToPad(e){!this._pipeline||this._receiverBridge||(this._receiverBridge=new n({pipeline:this._pipeline,kind:this._track.kind}),this._receiverBridge.connect_to_pad(e),this._receiverBridge.connect(`media-flowing`,()=>{this._track._setMuted(!1)}))}_dispose(){try{this._receiverBridge?.dispose_bridge()}catch{}this._receiverBridge=null}_transport=null;get track(){return this._track}get transport(){return this._transport}get jitterBufferTarget(){return this._jitterBufferTarget}set jitterBufferTarget(e){if(e===null){this._jitterBufferTarget=null;return}let t=Number(e);if(!Number.isFinite(t)||t<0)throw RangeError(`Failed to set jitterBufferTarget: ${e} is negative or not finite`);if(t>r)throw RangeError(`Failed to set jitterBufferTarget: ${e} exceeds maximum of ${r}`);this._jitterBufferTarget=t}getParameters(){return{codecs:[],headerExtensions:[],rtcp:{}}}getContributingSources(){return[]}getSynchronizationSources(){return[]}async getStats(){if(this._getStatsForTrack&&this._track)return this._getStatsForTrack(this._track);let{RTCStatsReport:e}=await import(`./rtc-stats-report.js`);return new e}static getCapabilities(e){return t(e)}};export{RTCRtpReceiver};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Gst as e}from"./gst-init.js";import{
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{Gst as e}from"./gst-init.js";import{asCapsFilterElement as t,asRtpPayloaderElement as n,asValveElement as r,asVp8EncElement as i}from"./internal/gst-types.js";import{getRtpCapabilities as a}from"./rtp-capabilities.js";import{RTCDTMFSender as o}from"./rtc-dtmf-sender.js";import{TeeMultiplexer as s}from"./tee-multiplexer.js";let c=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 o;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(a){if(this._linked||!this._pipeline||!this._webrtcbin)return;let o=a._gstSource;if(!o)return;let c=a,l;if(c._gstTee&&c._gstPipeline&&c._gstPipeline!==this._pipeline){let t=c._gstPipeline,n=c._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,l=null}else if(c._teeMultiplexer){let e=c._teeMultiplexer.requestSrcPad();this._teeSrcPad=e,l=null}else if(c._gstPipeline&&c._gstPipeline!==this._pipeline){let t=c._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),c._gstPipeline=this._pipeline;let i=new s(this._pipeline,o);if(c._teeMultiplexer=i,r){let e=i.requestSrcPad();e&&e.link(r)}let a=i.requestSrcPad();this._teeSrcPad=a,l=null}else{let t=c._gstPipeline;t&&t!==this._pipeline&&(o.set_state(e.State.NULL),t.remove(o),c._gstPipeline=this._pipeline),o.get_parent()!==this._pipeline&&this._pipeline.add(o),l=o}let u=r(e.ElementFactory.make(`valve`,null));u.drop=!a.enabled,this._valve=u,this._pipeline.add(u);let d=[u],f;if(a.kind===`audio`){let r=e.ElementFactory.make(`audioconvert`,null),i=e.ElementFactory.make(`audioresample`,null),a=e.ElementFactory.make(`opusenc`,null),o=n(e.ElementFactory.make(`rtpopuspay`,null));o.pt=111;let s=t(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(r,i,a,o,s);for(let e of d)this._pipeline.add(e);if(this._teeSrcPad){let e=u.get_static_pad(`sink`);this._teeSrcPad.link(e)}else l&&l.link(u);u.link(r),r.link(i),i.link(a),a.link(o),o.link(s),f=s}else{let r=e.ElementFactory.make(`videoconvert`,null),a=e.ElementFactory.make(`videoscale`,null),o=i(e.ElementFactory.make(`vp8enc`,null));o.deadline=1,o.keyframe_max_dist=60;let s=n(e.ElementFactory.make(`rtpvp8pay`,null));s.pt=96;let c=t(e.ElementFactory.make(`capsfilter`,null));c.caps=e.Caps.from_string(`application/x-rtp,media=video,encoding-name=VP8,clock-rate=90000,payload=96`),d.push(r,a,o,s,c);for(let e of d)this._pipeline.add(e);if(this._teeSrcPad){let e=u.get_static_pad(`sink`);this._teeSrcPad.link(e)}else l&&l.link(u);u.link(r),r.link(a),a.link(o),o.link(s),s.link(c),f=c}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,a._setEnableCallback(e=>{this._valve&&(this._valve.drop=!e)})}_teardownPipeline(){if(this._linked){if(this._track&&this._track._setEnableCallback(null),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(){return this._lastParams||={transactionId:String(++c),encodings:[],codecs:[],headerExtensions:[],rtcp:{}},{...this._lastParams,encodings:[...this._lastParams.encodings]}}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 a(e)}};export{RTCRtpSender};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{gstDirectionToW3C as e,w3cDirectionToGst as t}from"./gst-enum-maps.js";import{RTCRtpSender as n}from"./rtc-rtp-sender.js";import{RTCRtpReceiver as r}from"./rtc-rtp-receiver.js";var
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{gstDirectionToW3C as e,w3cDirectionToGst as t}from"./gst-enum-maps.js";import{RTCRtpSender as n}from"./rtc-rtp-sender.js";import{RTCRtpReceiver as r}from"./rtc-rtp-receiver.js";var RTCRtpTransceiver=class{_gstTrans;sender;receiver;_stopped=!1;_codecPreferences=[];constructor(e,t,n){this._gstTrans=e,this.sender=t,this.receiver=n}get mid(){if(this._stopped)return null;let e=this._gstTrans.mid;return e===``||e==null?null:String(e)}get direction(){return this._stopped?`stopped`:e(this._gstTrans.direction)}set direction(e){if(this._stopped)throw new DOMException(`Cannot set direction on a stopped transceiver`,`InvalidStateError`);if(e===`stopped`)throw TypeError(`The provided value 'stopped' is not a valid enum value of type RTCRtpTransceiverDirection.`);if(![`sendrecv`,`sendonly`,`recvonly`,`inactive`].includes(e))throw TypeError(`The provided value '${e}' is not a valid enum value of type RTCRtpTransceiverDirection.`);this._gstTrans.direction=t(e)}get currentDirection(){if(this._stopped)return null;let t=this._gstTrans.current_direction??this._gstTrans.currentDirection;if(t==null)return null;let n=e(t);return n===`inactive`?null:n}get stopped(){return this._stopped}stop(){this._stopped||=!0}setCodecPreferences(e){if(!Array.isArray(e))throw TypeError(`codecs must be an array`);if(e.length===0){this._codecPreferences=[];return}let t=this.receiver.track.kind,i=r.getCapabilities(t),a=n.getCapabilities(t);if(!i||!a)throw new DOMException(`No capabilities available`,`InvalidModificationError`);let o=[...i.codecs,...a.codecs];for(let t of e){if(!t||typeof t!=`object`)throw TypeError(`Each codec must be an object`);if(typeof t.mimeType!=`string`||typeof t.clockRate!=`number`)throw TypeError(`codec must have mimeType (string) and clockRate (number)`);if(!/\/(rtx|red|ulpfec)$/i.test(t.mimeType)&&!o.find(e=>e.mimeType.toLowerCase()===t.mimeType.toLowerCase()&&e.clockRate===t.clockRate&&(t.channels===void 0||e.channels===t.channels)&&(t.sdpFmtpLine===void 0||e.sdpFmtpLine===t.sdpFmtpLine)))throw new DOMException(`Codec ${t.mimeType} ${t.clockRate} is not in capabilities`,`InvalidModificationError`)}this._codecPreferences=[...e]}get _nativeTransceiver(){return this._gstTrans}};export{RTCRtpTransceiver};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"@gjsify/dom-events/register/event-target";var
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import"@gjsify/dom-events/register/event-target";var RTCSctpTransport=class extends EventTarget{transport;_state=`connecting`;_maxMessageSize=262144;_maxChannels=65535;_onstatechange=null;constructor(e){super(),this.transport=e}get state(){return this._state}get maxMessageSize(){return this._maxMessageSize}get maxChannels(){return this._maxChannels}get onstatechange(){return this._onstatechange}set onstatechange(e){this._onstatechange=e}_setState(e){if(this._state===e)return;this._state=e;let t=new Event(`statechange`);this._onstatechange?.call(this,t),this.dispatchEvent(t)}};export{RTCSctpTransport};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"gi://GstWebRTC?version=1.0";import t from"gi://GstSdp?version=1.0";function
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import e from"gi://GstWebRTC?version=1.0";import t from"gi://GstSdp?version=1.0";function sdpTypeToGst(t){switch(t){case`offer`:return e.WebRTCSDPType.OFFER;case`pranswer`:return e.WebRTCSDPType.PRANSWER;case`answer`:return e.WebRTCSDPType.ANSWER;case`rollback`:return e.WebRTCSDPType.ROLLBACK}}function sdpTypeFromGst(t){switch(t){case e.WebRTCSDPType.OFFER:return`offer`;case e.WebRTCSDPType.PRANSWER:return`pranswer`;case e.WebRTCSDPType.ANSWER:return`answer`;case e.WebRTCSDPType.ROLLBACK:return`rollback`;default:return`offer`}}var n=class RTCSessionDescription{type;sdp;constructor(e){this.type=e?.type??`offer`,this.sdp=e?.sdp??``}toJSON(){return{type:this.type,sdp:this.sdp}}toGstDesc(){let[n,r]=t.SDPMessage.new_from_text(this.sdp);if(n!==t.SDPResult.OK)throw Error(`Failed to parse SDP text (GstSDPResult=${n})`);return e.WebRTCSessionDescription.new(sdpTypeToGst(this.type),r)}static fromGstDesc(e){let t=e.sdp?.as_text?.()??``;return new RTCSessionDescription({type:sdpTypeFromGst(e.type),sdp:t})}};export{n as RTCSessionDescription};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";var RTCStatsReport=class{_map;constructor(e){this._map=new Map(e)}get size(){return this._map.size}get(e){return this._map.get(e)}has(e){return this._map.has(e)}forEach(e,t){this._map.forEach((n,r)=>{e.call(t,n,r,this)})}entries(){return this._map.entries()}keys(){return this._map.keys()}values(){return this._map.values()}[Symbol.iterator](){return this._map.entries()}};export{RTCStatsReport};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"@gjsify/dom-events/register/event-target";var
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import"@gjsify/dom-events/register/event-target";var RTCTrackEvent=class extends Event{receiver;track;streams;transceiver;constructor(e,t){if(super(e,t),!t||typeof t!=`object`)throw TypeError(`RTCTrackEventInit is required`);if(!(`receiver`in t))throw TypeError(`Failed to construct 'RTCTrackEvent': required member receiver is not provided.`);if(!(`track`in t))throw TypeError(`Failed to construct 'RTCTrackEvent': required member track is not provided.`);if(!(`transceiver`in t))throw TypeError(`Failed to construct 'RTCTrackEvent': required member transceiver is not provided.`);this.receiver=t.receiver,this.track=t.track,this.streams=Object.freeze(t.streams?[...t.streams]:[]),this.transceiver=t.transceiver}};export{RTCTrackEvent};
|
|
@@ -1 +1 @@
|
|
|
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
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";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 getRtpCapabilities(n){return n===`audio`?e:n===`video`?t:null}export{getRtpCapabilities};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Gst as e}from"./gst-init.js";var
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{Gst as e}from"./gst-init.js";var TeeMultiplexer=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{TeeMultiplexer};
|
package/lib/esm/wpt-helpers.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{RTCPeerConnection as e}from"./rtc-peer-connection.js";import"./index.js";function
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{RTCPeerConnection as e}from"./rtc-peer-connection.js";import"./index.js";function createPeerConnection(){return new e}async function exchangeOfferAnswer(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 createDataChannelPair(e={},t=createPeerConnection(),n=createPeerConnection(),r=`wpt`){let i,a;if(e.negotiated)i=[t.createDataChannel(r,e),n.createDataChannel(r,e)],a=Promise.all(i.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 o=t.createDataChannel(r,e);a=Promise.all([new Promise((e,t)=>{if(o.readyState===`open`)return e();o.onopen=()=>e(),o.onerror=e=>t(e?.error??Error(`onerror`))}),new Promise((e,t)=>{n.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=>{i[1]=e})]),i=[o,void 0]}return await exchangeOfferAnswer(t,n),await a,[i[0],i[1],t,n]}function awaitMessage(e){return new Promise((t,n)=>{let messageHandler=n=>{e.removeEventListener(`message`,messageHandler),e.removeEventListener(`error`,errorHandler),t(n.data)},errorHandler=t=>{e.removeEventListener(`message`,messageHandler),e.removeEventListener(`error`,errorHandler),n(t?.error??Error(`channel error`))};e.addEventListener(`message`,messageHandler),e.addEventListener(`error`,errorHandler)})}var EventWatcher=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 closePeerConnections(...e){for(let t of e)try{t?.close()}catch{}}export{EventWatcher,awaitMessage,closePeerConnections,createDataChannelPair,createPeerConnection,exchangeOfferAnswer};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import GstWebRTC from 'gi://GstWebRTC?version=1.0';
|
|
1
2
|
import type { RTCSignalingState, RTCPeerConnectionState, RTCIceConnectionState, RTCIceGatheringState } from './rtc-peer-connection.js';
|
|
2
3
|
import type { RTCRtpTransceiverDirection } from './rtc-rtp-sender.js';
|
|
3
4
|
export declare function gstToSignalingState(v: number): RTCSignalingState;
|
|
@@ -5,6 +6,6 @@ export declare function gstToConnectionState(v: number): RTCPeerConnectionState;
|
|
|
5
6
|
export declare function gstToIceConnectionState(v: number): RTCIceConnectionState;
|
|
6
7
|
export declare function gstToIceGatheringState(v: number): RTCIceGatheringState;
|
|
7
8
|
export declare function gstDirectionToW3C(v: number): RTCRtpTransceiverDirection;
|
|
8
|
-
export declare function w3cDirectionToGst(d: RTCRtpTransceiverDirection):
|
|
9
|
+
export declare function w3cDirectionToGst(d: RTCRtpTransceiverDirection): GstWebRTC.WebRTCRTPTransceiverDirection;
|
|
9
10
|
export type RTCStatsType = 'codec' | 'inbound-rtp' | 'outbound-rtp' | 'remote-inbound-rtp' | 'remote-outbound-rtp' | 'csrc' | 'peer-connection' | 'data-channel' | 'stream' | 'transport' | 'candidate-pair' | 'local-candidate' | 'remote-candidate' | 'certificate';
|
|
10
11
|
export declare function gstToStatsType(v: number): RTCStatsType | undefined;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type Gst from 'gi://Gst?version=1.0';
|
|
2
|
+
import type GstWebRTC from 'gi://GstWebRTC?version=1.0';
|
|
3
|
+
/**
|
|
4
|
+
* The `webrtcbin` GStreamer element — declares every GObject property
|
|
5
|
+
* our implementation accesses. The base `Gst.Element` class is preserved
|
|
6
|
+
* so all the inherited methods (`emit`, `get_parent`, `set_state`,
|
|
7
|
+
* `request_pad_simple`, `sync_state_with_parent`, …) keep their proper
|
|
8
|
+
* typings.
|
|
9
|
+
*
|
|
10
|
+
* All properties below correspond to runtime GObject properties on
|
|
11
|
+
* `webrtcbin` (verify with `gst-inspect-1.0 webrtcbin`).
|
|
12
|
+
*/
|
|
13
|
+
export interface WebRtcBin extends Gst.Element {
|
|
14
|
+
stun_server: string | null;
|
|
15
|
+
turn_server: string | null;
|
|
16
|
+
ice_transport_policy: GstWebRTC.WebRTCICETransportPolicy;
|
|
17
|
+
bundle_policy: GstWebRTC.WebRTCBundlePolicy;
|
|
18
|
+
signaling_state: GstWebRTC.WebRTCSignalingState;
|
|
19
|
+
connection_state: GstWebRTC.WebRTCPeerConnectionState;
|
|
20
|
+
ice_connection_state: GstWebRTC.WebRTCICEConnectionState;
|
|
21
|
+
ice_gathering_state: GstWebRTC.WebRTCICEGatheringState;
|
|
22
|
+
local_description: GstWebRTC.WebRTCSessionDescription | null;
|
|
23
|
+
remote_description: GstWebRTC.WebRTCSessionDescription | null;
|
|
24
|
+
current_local_description: GstWebRTC.WebRTCSessionDescription | null;
|
|
25
|
+
current_remote_description: GstWebRTC.WebRTCSessionDescription | null;
|
|
26
|
+
pending_local_description: GstWebRTC.WebRTCSessionDescription | null;
|
|
27
|
+
pending_remote_description: GstWebRTC.WebRTCSessionDescription | null;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Narrow a `Gst.Element` returned by `Gst.ElementFactory.make('webrtcbin', …)`
|
|
31
|
+
* to the augmented `WebRtcBin` shape. Pure type-level cast — no runtime
|
|
32
|
+
* validation is performed because every webrtcbin instance has these
|
|
33
|
+
* properties (they are class-installed by GstWebRTCBin).
|
|
34
|
+
*/
|
|
35
|
+
export declare const asWebRtcBin: (el: Gst.Element) => WebRtcBin;
|
|
36
|
+
/**
|
|
37
|
+
* GStreamer pad augmented with the `transceiver` field that webrtcbin's
|
|
38
|
+
* SRC pads carry. The base `Gst.Pad` typing has no concept of this — it
|
|
39
|
+
* is set at pad-creation time inside webrtcbin and points back to the
|
|
40
|
+
* `GstWebRTCRTPTransceiver` the pad serves.
|
|
41
|
+
*/
|
|
42
|
+
export interface WebRtcSrcPad extends Gst.Pad {
|
|
43
|
+
transceiver: GstWebRTC.WebRTCRTPTransceiver | null;
|
|
44
|
+
}
|
|
45
|
+
/** Narrow a webrtcbin SRC `Gst.Pad` to the augmented shape. */
|
|
46
|
+
export declare const asWebRtcSrcPad: (pad: Gst.Pad) => WebRtcSrcPad;
|
|
47
|
+
/**
|
|
48
|
+
* GStreamer element with a settable `drop` GObject property — the
|
|
49
|
+
* `valve` element used to gate media flow when a track is disabled.
|
|
50
|
+
*/
|
|
51
|
+
export interface ValveElement extends Gst.Element {
|
|
52
|
+
drop: boolean;
|
|
53
|
+
}
|
|
54
|
+
/** Narrow a `valve` element to the augmented shape. */
|
|
55
|
+
export declare const asValveElement: (el: Gst.Element) => ValveElement;
|
|
56
|
+
/**
|
|
57
|
+
* GStreamer element with a settable `pt` GObject property — RTP payloader
|
|
58
|
+
* elements (`rtpopuspay`, `rtpvp8pay`, …) accept the payload type.
|
|
59
|
+
*/
|
|
60
|
+
export interface RtpPayloaderElement extends Gst.Element {
|
|
61
|
+
pt: number;
|
|
62
|
+
}
|
|
63
|
+
/** Narrow an RTP payloader element to the augmented shape. */
|
|
64
|
+
export declare const asRtpPayloaderElement: (el: Gst.Element) => RtpPayloaderElement;
|
|
65
|
+
/**
|
|
66
|
+
* GStreamer `capsfilter` element — exposes a settable `caps` property
|
|
67
|
+
* that pins the negotiated caps of a pipeline branch.
|
|
68
|
+
*/
|
|
69
|
+
export interface CapsFilterElement extends Gst.Element {
|
|
70
|
+
caps: Gst.Caps;
|
|
71
|
+
}
|
|
72
|
+
/** Narrow a `capsfilter` element to the augmented shape. */
|
|
73
|
+
export declare const asCapsFilterElement: (el: Gst.Element) => CapsFilterElement;
|
|
74
|
+
/**
|
|
75
|
+
* GStreamer `vp8enc` encoder — the small set of properties we tune for
|
|
76
|
+
* realtime WebRTC video encoding.
|
|
77
|
+
*/
|
|
78
|
+
export interface Vp8EncElement extends Gst.Element {
|
|
79
|
+
deadline: number;
|
|
80
|
+
keyframe_max_dist: number;
|
|
81
|
+
}
|
|
82
|
+
/** Narrow a `vp8enc` element to the augmented shape. */
|
|
83
|
+
export declare const asVp8EncElement: (el: Gst.Element) => Vp8EncElement;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type GstNs from 'gi://Gst?version=1.0';
|
|
1
2
|
import type GstWebRTC from 'gi://GstWebRTC?version=1.0';
|
|
2
3
|
import { RTCDTMFSender } from './rtc-dtmf-sender.js';
|
|
3
4
|
import type { RTCStatsReport } from './rtc-stats-report.js';
|
|
@@ -75,8 +76,8 @@ export declare class RTCRtpSender {
|
|
|
75
76
|
currentDirection: string | null;
|
|
76
77
|
} | null;
|
|
77
78
|
/** @internal — callback to notify RTCPeerConnection when pipeline changes (cross-pipeline fix) */
|
|
78
|
-
_onPipelineChanged: ((newPipeline:
|
|
79
|
-
constructor(gstSender: GstWebRTC.WebRTCRTPSender | null, pipeline?:
|
|
79
|
+
_onPipelineChanged: ((newPipeline: GstNs.Pipeline) => void) | null;
|
|
80
|
+
constructor(gstSender: GstWebRTC.WebRTCRTPSender | null, pipeline?: GstNs.Pipeline, webrtcbin?: GstNs.Element);
|
|
80
81
|
get track(): MediaStreamTrack | null;
|
|
81
82
|
/** Returns the DTMF sender for audio senders, null for video. */
|
|
82
83
|
get dtmf(): RTCDTMFSender | null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/webrtc",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.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",
|
|
@@ -55,20 +55,20 @@
|
|
|
55
55
|
"peer-connection"
|
|
56
56
|
],
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@gjsify/buffer": "^0.
|
|
59
|
-
"@gjsify/dom-events": "^0.
|
|
60
|
-
"@gjsify/dom-exception": "^0.
|
|
61
|
-
"@gjsify/webrtc-native": "^0.
|
|
58
|
+
"@gjsify/buffer": "^0.4.0",
|
|
59
|
+
"@gjsify/dom-events": "^0.4.0",
|
|
60
|
+
"@gjsify/dom-exception": "^0.4.0",
|
|
61
|
+
"@gjsify/webrtc-native": "^0.4.0"
|
|
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.
|
|
71
|
-
"@gjsify/unit": "^0.
|
|
64
|
+
"@girs/gjs": "4.0.0-rc.15",
|
|
65
|
+
"@girs/glib-2.0": "2.88.0-4.0.0-rc.15",
|
|
66
|
+
"@girs/gobject-2.0": "2.88.0-4.0.0-rc.15",
|
|
67
|
+
"@girs/gst-1.0": "1.28.1-4.0.0-rc.15",
|
|
68
|
+
"@girs/gstsdp-1.0": "1.0.0-4.0.0-rc.15",
|
|
69
|
+
"@girs/gstwebrtc-1.0": "1.0.0-4.0.0-rc.15",
|
|
70
|
+
"@gjsify/cli": "^0.4.0",
|
|
71
|
+
"@gjsify/unit": "^0.4.0",
|
|
72
72
|
"@types/node": "^25.6.2",
|
|
73
73
|
"typescript": "^6.0.3"
|
|
74
74
|
}
|