werift 0.17.0 → 0.17.2
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/ice/src/ice.d.ts +10 -1
- package/lib/ice/src/ice.js +15 -3
- package/lib/ice/src/ice.js.map +1 -1
- package/lib/rtp/src/container/ebml/ebml.d.ts +32 -0
- package/lib/rtp/src/container/ebml/ebml.js +115 -0
- package/lib/rtp/src/container/ebml/ebml.js.map +1 -0
- package/lib/rtp/src/container/ebml/id.d.ts +221 -0
- package/lib/rtp/src/container/ebml/id.js +225 -0
- package/lib/rtp/src/container/ebml/id.js.map +1 -0
- package/lib/rtp/src/container/ebml/index.d.ts +3 -0
- package/lib/rtp/src/container/ebml/index.js +20 -0
- package/lib/rtp/src/container/ebml/index.js.map +1 -0
- package/lib/rtp/src/container/ebml/typedArrayUtils.d.ts +7 -0
- package/lib/rtp/src/container/ebml/typedArrayUtils.js +109 -0
- package/lib/rtp/src/container/ebml/typedArrayUtils.js.map +1 -0
- package/lib/rtp/src/container/webm.d.ts +10 -4
- package/lib/rtp/src/container/webm.js +56 -7
- package/lib/rtp/src/container/webm.js.map +1 -1
- package/lib/rtp/src/index.d.ts +1 -0
- package/lib/rtp/src/index.js +1 -0
- package/lib/rtp/src/index.js.map +1 -1
- package/lib/rtp/src/processor/avBuffer.d.ts +28 -0
- package/lib/rtp/src/processor/avBuffer.js +91 -0
- package/lib/rtp/src/processor/avBuffer.js.map +1 -0
- package/lib/rtp/src/processor/avBufferCallback.d.ts +10 -0
- package/lib/rtp/src/processor/avBufferCallback.js +27 -0
- package/lib/rtp/src/processor/avBufferCallback.js.map +1 -0
- package/lib/rtp/src/processor/depacketizer.d.ts +1 -1
- package/lib/rtp/src/processor/depacketizer.js.map +1 -1
- package/lib/rtp/src/processor/depacketizerCallback.d.ts +1 -3
- package/lib/rtp/src/processor/depacketizerCallback.js +2 -2
- package/lib/rtp/src/processor/depacketizerCallback.js.map +1 -1
- package/lib/rtp/src/processor/depacketizerTransformer.d.ts +1 -1
- package/lib/rtp/src/processor/index.d.ts +3 -0
- package/lib/rtp/src/processor/index.js +3 -0
- package/lib/rtp/src/processor/index.js.map +1 -1
- package/lib/rtp/src/processor/jitterBuffer.d.ts +1 -1
- package/lib/rtp/src/processor/jitterBuffer.js.map +1 -1
- package/lib/rtp/src/processor/jitterBufferCallback.d.ts +1 -3
- package/lib/rtp/src/processor/jitterBufferCallback.js +2 -2
- package/lib/rtp/src/processor/jitterBufferCallback.js.map +1 -1
- package/lib/rtp/src/processor/jitterBufferTransformer.d.ts +1 -1
- package/lib/rtp/src/processor/source/index.d.ts +2 -2
- package/lib/rtp/src/processor/source/index.js +16 -3
- package/lib/rtp/src/processor/source/index.js.map +1 -1
- package/lib/rtp/src/processor/source/rtpCallback.d.ts +17 -0
- package/lib/rtp/src/processor/source/rtpCallback.js +33 -0
- package/lib/rtp/src/processor/source/rtpCallback.js.map +1 -0
- package/lib/rtp/src/processor/source/{rtp.d.ts → rtpStream.d.ts} +2 -5
- package/lib/rtp/src/processor/source/{rtp.js → rtpStream.js} +12 -12
- package/lib/rtp/src/processor/source/rtpStream.js.map +1 -0
- package/lib/rtp/src/processor/webm.d.ts +17 -2
- package/lib/rtp/src/processor/webm.js +83 -33
- package/lib/rtp/src/processor/webm.js.map +1 -1
- package/lib/rtp/src/processor/webmCallback.d.ts +16 -0
- package/lib/rtp/src/processor/webmCallback.js +21 -0
- package/lib/rtp/src/processor/webmCallback.js.map +1 -0
- package/lib/rtp/src/processor/webmStream.d.ts +5 -16
- package/lib/rtp/src/processor/webmStream.js.map +1 -1
- package/lib/{webrtc/src/media/receiver/red.d.ts → rtp/src/rtp/red/handler.d.ts} +2 -2
- package/lib/{webrtc/src/media/receiver/red.js → rtp/src/rtp/red/handler.js} +10 -10
- package/lib/rtp/src/rtp/red/handler.js.map +1 -0
- package/lib/webrtc/src/const.d.ts +1 -1
- package/lib/webrtc/src/const.js +2 -2
- package/lib/webrtc/src/const.js.map +1 -1
- package/lib/webrtc/src/media/receiver/nack.d.ts +1 -0
- package/lib/webrtc/src/media/receiver/nack.js +29 -16
- package/lib/webrtc/src/media/receiver/nack.js.map +1 -1
- package/lib/webrtc/src/media/router.js +17 -13
- package/lib/webrtc/src/media/router.js.map +1 -1
- package/lib/webrtc/src/media/rtpReceiver.d.ts +1 -1
- package/lib/webrtc/src/media/rtpReceiver.js +14 -9
- package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
- package/lib/webrtc/src/media/rtpTransceiver.d.ts +10 -6
- package/lib/webrtc/src/media/rtpTransceiver.js +23 -14
- package/lib/webrtc/src/media/rtpTransceiver.js.map +1 -1
- package/lib/webrtc/src/media/track.js +3 -2
- package/lib/webrtc/src/media/track.js.map +1 -1
- package/lib/webrtc/src/nonstandard/recorder/writer/webm.js.map +1 -1
- package/lib/webrtc/src/nonstandard/userMedia.d.ts +20 -3
- package/lib/webrtc/src/nonstandard/userMedia.js +79 -8
- package/lib/webrtc/src/nonstandard/userMedia.js.map +1 -1
- package/lib/webrtc/src/peerConnection.d.ts +5 -2
- package/lib/webrtc/src/peerConnection.js +72 -46
- package/lib/webrtc/src/peerConnection.js.map +1 -1
- package/lib/webrtc/src/sdp.js +2 -2
- package/lib/webrtc/src/sdp.js.map +1 -1
- package/lib/webrtc/src/transport/ice.js +10 -3
- package/lib/webrtc/src/transport/ice.js.map +1 -1
- package/lib/webrtc/src/utils.d.ts +0 -1
- package/lib/webrtc/src/utils.js +1 -3
- package/lib/webrtc/src/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/const.ts +1 -1
- package/src/media/receiver/nack.ts +33 -17
- package/src/media/router.ts +16 -13
- package/src/media/rtpReceiver.ts +21 -9
- package/src/media/rtpTransceiver.ts +28 -15
- package/src/media/track.ts +3 -2
- package/src/nonstandard/recorder/writer/webm.ts +2 -2
- package/src/nonstandard/userMedia.ts +89 -7
- package/src/peerConnection.ts +88 -51
- package/src/sdp.ts +2 -2
- package/src/transport/ice.ts +13 -3
- package/src/utils.ts +0 -3
- package/lib/rtp/src/processor/source/rtp.js.map +0 -1
- package/lib/webrtc/src/media/receiver/red.js.map +0 -1
- package/src/media/receiver/red.ts +0 -70
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rtpTransceiver.js","sourceRoot":"","sources":["../../../../src/media/rtpTransceiver.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,sDAA4B;AAC5B,2CAA6B;AAG7B,oCAA4C;AAU5C,MAAa,iBAAiB;
|
|
1
|
+
{"version":3,"file":"rtpTransceiver.js","sourceRoot":"","sources":["../../../../src/media/rtpTransceiver.ts"],"names":[],"mappings":"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","sourcesContent":["import Event from \"rx.mini\";\nimport * as uuid from \"uuid\";\n\nimport { RTCDtlsTransport } from \"..\";\nimport { SenderDirections } from \"../const\";\nimport { Kind } from \"../types/domain\";\nimport {\n RTCRtpCodecParameters,\n RTCRtpHeaderExtensionParameters,\n} from \"./parameters\";\nimport { RTCRtpReceiver } from \"./rtpReceiver\";\nimport { RTCRtpSender } from \"./rtpSender\";\nimport { MediaStreamTrack } from \"./track\";\n\nexport class RTCRtpTransceiver {\n readonly id = uuid.v4();\n readonly onTrack = new Event<[MediaStreamTrack, RTCRtpTransceiver]>();\n mid?: string;\n mLineIndex?: number;\n /**should not be reused because it has been used for sending before. */\n usedForSender = false;\n private _currentDirection?: Direction;\n offerDirection!: Direction;\n _codecs: RTCRtpCodecParameters[] = [];\n set codecs(codecs: RTCRtpCodecParameters[]) {\n this._codecs = codecs;\n }\n get codecs() {\n return this._codecs;\n }\n headerExtensions: RTCRtpHeaderExtensionParameters[] = [];\n options: Partial<TransceiverOptions> = {};\n stopping = false;\n stopped = false;\n\n constructor(\n public readonly kind: Kind,\n dtlsTransport: RTCDtlsTransport,\n public receiver: RTCRtpReceiver,\n public sender: RTCRtpSender,\n /**RFC 8829 4.2.4. direction the transceiver was initialized with */\n private _direction: Direction\n ) {\n this.setDtlsTransport(dtlsTransport);\n }\n\n get dtlsTransport() {\n return this.receiver.dtlsTransport;\n }\n\n /**RFC 8829 4.2.4. setDirectionに渡された最後の値を示します */\n get direction() {\n return this._direction;\n }\n\n setDirection(direction: Direction) {\n this._direction = direction;\n if (SenderDirections.includes(this._currentDirection ?? \"\")) {\n this.usedForSender = true;\n }\n }\n\n /**RFC 8829 4.2.5. last negotiated direction */\n get currentDirection(): Direction | undefined {\n return this._currentDirection;\n }\n\n setCurrentDirection(direction: Direction | undefined) {\n this._currentDirection = direction;\n }\n\n setDtlsTransport(dtls: RTCDtlsTransport) {\n this.receiver.setDtlsTransport(dtls);\n this.sender.setDtlsTransport(dtls);\n }\n\n get msid() {\n return `${this.sender.streamId} ${this.sender.trackId}`;\n }\n\n addTrack(track: MediaStreamTrack) {\n const res = this.receiver.addTrack(track);\n if (res) {\n this.onTrack.execute(track, this);\n }\n }\n\n // todo impl\n // https://www.w3.org/TR/webrtc/#methods-8\n stop() {\n if (this.stopping) {\n return;\n }\n\n // todo Stop sending and receiving with transceiver.\n\n this.stopping = true;\n }\n\n getPayloadType(mimeType: string) {\n return this.codecs.find((codec) =>\n codec.mimeType.toLowerCase().includes(mimeType.toLowerCase())\n )?.payloadType;\n }\n}\n\nexport const Inactive = \"inactive\";\nexport const Sendonly = \"sendonly\";\nexport const Recvonly = \"recvonly\";\nexport const Sendrecv = \"sendrecv\";\n\nexport const Directions = [Inactive, Sendonly, Recvonly, Sendrecv] as const;\n\nexport type Direction = typeof Directions[number];\n\ntype SimulcastDirection = \"send\" | \"recv\";\n\nexport interface TransceiverOptions {\n direction: Direction;\n simulcast: { direction: SimulcastDirection; rid: string }[];\n}\n"]}
|
|
@@ -29,11 +29,12 @@ class MediaStreamTrack extends helper_1.EventTarget {
|
|
|
29
29
|
if (this.remote) {
|
|
30
30
|
throw new Error("this is remoteTrack");
|
|
31
31
|
}
|
|
32
|
-
if (
|
|
32
|
+
if (this.stopped) {
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
35
35
|
const packet = Buffer.isBuffer(rtp) ? src_1.RtpPacket.deSerialize(rtp) : rtp;
|
|
36
|
-
packet.header.payloadType =
|
|
36
|
+
packet.header.payloadType =
|
|
37
|
+
this.codec?.payloadType ?? packet.header.payloadType;
|
|
37
38
|
this.onReceiveRtp.execute(packet);
|
|
38
39
|
};
|
|
39
40
|
Object.assign(this, props);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"track.js","sourceRoot":"","sources":["../../../../src/media/track.ts"],"names":[],"mappings":";;;;;;AAAA,sDAA4B;AAC5B,+BAA0B;AAE1B,0CAAoE;AACpE,sCAAwC;AAIxC,MAAa,gBAAiB,SAAQ,oBAAW;IAyB/C,YACE,KAAiE;QAEjE,KAAK,EAAE,CAAC;QA3BD,SAAI,GAAG,IAAA,SAAE,GAAE,CAAC;QAGrB,WAAM,GAAG,KAAK,CAAC;QASf,eAAe;QACf,YAAO,GAAG,IAAI,CAAC;QAEN,iBAAY,GAAG,IAAI,iBAAK,EAAe,CAAC;QACxC,kBAAa,GAAG,IAAI,iBAAK,EAAgB,CAAC;QAC1C,oBAAe,GAAG,IAAI,iBAAK,EAEjC,CAAC;QAEJ,YAAO,GAAG,KAAK,CAAC;QAChB,UAAK,GAAG,IAAI,CAAC;QAgBb,SAAI,GAAG,GAAG,EAAE;YACV,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YAClB,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;QAC/B,CAAC,CAAC;QAEF,aAAQ,GAAG,CAAC,GAAuB,EAAE,EAAE;YACrC,IAAI,IAAI,CAAC,MAAM,EAAE;gBACf,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;aACxC;YACD,IAAI,
|
|
1
|
+
{"version":3,"file":"track.js","sourceRoot":"","sources":["../../../../src/media/track.ts"],"names":[],"mappings":";;;;;;AAAA,sDAA4B;AAC5B,+BAA0B;AAE1B,0CAAoE;AACpE,sCAAwC;AAIxC,MAAa,gBAAiB,SAAQ,oBAAW;IAyB/C,YACE,KAAiE;QAEjE,KAAK,EAAE,CAAC;QA3BD,SAAI,GAAG,IAAA,SAAE,GAAE,CAAC;QAGrB,WAAM,GAAG,KAAK,CAAC;QASf,eAAe;QACf,YAAO,GAAG,IAAI,CAAC;QAEN,iBAAY,GAAG,IAAI,iBAAK,EAAe,CAAC;QACxC,kBAAa,GAAG,IAAI,iBAAK,EAAgB,CAAC;QAC1C,oBAAe,GAAG,IAAI,iBAAK,EAEjC,CAAC;QAEJ,YAAO,GAAG,KAAK,CAAC;QAChB,UAAK,GAAG,IAAI,CAAC;QAgBb,SAAI,GAAG,GAAG,EAAE;YACV,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YAClB,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;QAC/B,CAAC,CAAC;QAEF,aAAQ,GAAG,CAAC,GAAuB,EAAE,EAAE;YACrC,IAAI,IAAI,CAAC,MAAM,EAAE;gBACf,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;aACxC;YACD,IAAI,IAAI,CAAC,OAAO,EAAE;gBAChB,OAAO;aACR;YAED,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,eAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YACvE,MAAM,CAAC,MAAM,CAAC,WAAW;gBACvB,IAAI,CAAC,KAAK,EAAE,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC;YACvD,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC,CAAC;QA5BA,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAE3B,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE;YAClC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;YACnB,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;IAClE,CAAC;CAqBF;AA1DD,4CA0DC;AAED,MAAa,WAAW;IAItB,YAAY,KAAqD;QAFjE,WAAM,GAAuB,EAAE,CAAC;QAG9B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED,QAAQ,CAAC,KAAuB;QAC9B,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;CACF;AAhBD,kCAgBC","sourcesContent":["import Event from \"rx.mini\";\nimport { v4 } from \"uuid\";\n\nimport { RtcpPacket, RtpHeader, RtpPacket } from \"../../../rtp/src\";\nimport { EventTarget } from \"../helper\";\nimport { Kind } from \"../types/domain\";\nimport { RTCRtpCodecParameters } from \"./parameters\";\n\nexport class MediaStreamTrack extends EventTarget {\n readonly uuid = v4();\n /**MediaStream ID*/\n streamId?: string;\n remote = false;\n label: string;\n kind!: Kind;\n id?: string;\n /**mediaSsrc */\n ssrc?: number;\n rid?: string;\n header?: RtpHeader;\n codec?: RTCRtpCodecParameters;\n /**todo impl */\n enabled = true;\n\n readonly onReceiveRtp = new Event<[RtpPacket]>();\n readonly onReceiveRtcp = new Event<[RtcpPacket]>();\n readonly onSourceChanged = new Event<\n [Pick<RtpHeader, \"sequenceNumber\" | \"timestamp\">]\n >();\n\n stopped = false;\n muted = true;\n\n constructor(\n props: Partial<MediaStreamTrack> & Pick<MediaStreamTrack, \"kind\">\n ) {\n super();\n Object.assign(this, props);\n\n this.onReceiveRtp.subscribe((rtp) => {\n this.muted = false;\n this.header = rtp.header;\n });\n\n this.label = `${this.remote ? \"remote\" : \"local\"} ${this.kind}`;\n }\n\n stop = () => {\n this.stopped = true;\n this.muted = true;\n this.onReceiveRtp.complete();\n };\n\n writeRtp = (rtp: RtpPacket | Buffer) => {\n if (this.remote) {\n throw new Error(\"this is remoteTrack\");\n }\n if (this.stopped) {\n return;\n }\n\n const packet = Buffer.isBuffer(rtp) ? RtpPacket.deSerialize(rtp) : rtp;\n packet.header.payloadType =\n this.codec?.payloadType ?? packet.header.payloadType;\n this.onReceiveRtp.execute(packet);\n };\n}\n\nexport class MediaStream {\n id!: string;\n tracks: MediaStreamTrack[] = [];\n\n constructor(props: Partial<MediaStream> & Pick<MediaStream, \"id\">) {\n Object.assign(this, props);\n }\n\n addTrack(track: MediaStreamTrack) {\n track.streamId = this.id;\n this.tracks.push(track);\n }\n\n getTracks() {\n return this.tracks;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webm.js","sourceRoot":"","sources":["../../../../../../src/nonstandard/recorder/writer/webm.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"webm.js","sourceRoot":"","sources":["../../../../../../src/nonstandard/recorder/writer/webm.ts"],"names":[],"mappings":"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","sourcesContent":["import { appendFile, open, unlink } from \"fs/promises\";\nimport { ReadableStreamDefaultReadResult } from \"stream/web\";\n\nimport { SupportedCodec } from \"../../../../../rtp/src/container/webm\";\nimport {\n depacketizeTransformer,\n jitterBufferTransformer,\n MediaStreamTrack,\n RtpSourceStream,\n WebmStream,\n WebmStreamOutput,\n WeriftError,\n} from \"../../..\";\nimport { MediaWriter } from \".\";\n\nconst sourcePath = \"packages/webrtc/src/nonstandard/recorder/writer/webm.ts\";\n\nexport class WebmFactory extends MediaWriter {\n rtpSources: RtpSourceStream[] = [];\n\n async start(tracks: MediaStreamTrack[]) {\n await unlink(this.path).catch((e) => e);\n\n const inputTracks = tracks.map((track, i) => {\n const trackNumber = i + 1;\n const payloadType = track.codec!.payloadType;\n\n if (track.kind === \"video\") {\n const codec = ((): SupportedCodec => {\n switch (track.codec?.name.toLowerCase() as SupportedVideoCodec) {\n case \"vp8\":\n return \"VP8\";\n case \"vp9\":\n return \"VP9\";\n case \"h264\":\n return \"MPEG4/ISO/AVC\";\n case \"av1x\":\n return \"AV1\";\n default:\n throw new WeriftError({\n message: \"unsupported codec\",\n payload: { track, path: sourcePath },\n });\n }\n })();\n return {\n kind: \"video\" as const,\n codec,\n clockRate: 90000,\n trackNumber,\n width: this.options.width,\n height: this.options.height,\n payloadType,\n track,\n };\n } else {\n return {\n kind: \"audio\" as const,\n codec: \"OPUS\" as const,\n clockRate: 48000,\n trackNumber,\n payloadType,\n track,\n };\n }\n });\n\n const webm = new WebmStream(inputTracks, {\n duration: this.options.defaultDuration ?? 1000 * 60 * 60 * 24,\n });\n\n this.rtpSources = inputTracks.map(({ track, clockRate, codec }) => {\n const rtpSource = new RtpSourceStream();\n track.onReceiveRtp.subscribe((r) => rtpSource.push(r));\n\n const jitterBuffer = jitterBufferTransformer(clockRate, {\n latency: this.options.jitterBufferLatency,\n bufferSize: this.options.jitterBufferSize,\n });\n\n if (track.kind === \"video\") {\n rtpSource.readable\n .pipeThrough(jitterBuffer)\n .pipeThrough(\n depacketizeTransformer(codec, {\n waitForKeyframe: this.options.waitForKeyframe,\n isFinalPacketInSequence: (h) => h.marker,\n })\n )\n .pipeTo(webm.videoStream);\n } else {\n rtpSource.readable\n .pipeThrough(jitterBuffer)\n .pipeThrough(depacketizeTransformer(codec))\n .pipeTo(webm.audioStream);\n }\n\n return rtpSource;\n });\n\n const reader = webm.webmStream.getReader();\n const readChunk = async ({\n value,\n done,\n }: ReadableStreamDefaultReadResult<WebmStreamOutput>) => {\n if (done) return;\n\n if (value.saveToFile) {\n await appendFile(this.path, value.saveToFile);\n } else if (value.eol) {\n const { durationElement } = value.eol;\n const handler = await open(this.path, \"r+\");\n await handler.write(durationElement, 0, durationElement.length, 83);\n await handler.close();\n }\n reader.read().then(readChunk);\n };\n reader.read().then(readChunk);\n }\n\n async stop() {\n await Promise.all(this.rtpSources.map((r) => r.stop()));\n }\n}\n\nconst supportedVideoCodecs = [\"h264\", \"vp8\", \"vp9\", \"av1x\"] as const;\ntype SupportedVideoCodec = typeof supportedVideoCodecs[number];\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MediaStreamTrack } from "../media/track";
|
|
2
|
-
export declare const
|
|
3
|
-
declare class
|
|
2
|
+
export declare const getUserMedia: (path: string, loop?: boolean) => Promise<MediaPlayerMp4 | MediaPlayerWebm>;
|
|
3
|
+
export declare class MediaPlayerMp4 {
|
|
4
4
|
private videoPort;
|
|
5
5
|
private audioPort;
|
|
6
6
|
private path;
|
|
@@ -8,8 +8,25 @@ declare class MediaMp4 {
|
|
|
8
8
|
private streamId;
|
|
9
9
|
audio: MediaStreamTrack;
|
|
10
10
|
video: MediaStreamTrack;
|
|
11
|
+
private process;
|
|
12
|
+
stopped: boolean;
|
|
11
13
|
constructor(videoPort: number, audioPort: number, path: string, loop?: boolean | undefined);
|
|
12
14
|
private setupTrack;
|
|
13
15
|
start(): Promise<void>;
|
|
16
|
+
stop(): void;
|
|
17
|
+
}
|
|
18
|
+
export declare class MediaPlayerWebm {
|
|
19
|
+
private videoPort;
|
|
20
|
+
private audioPort;
|
|
21
|
+
private path;
|
|
22
|
+
private loop?;
|
|
23
|
+
private streamId;
|
|
24
|
+
audio: MediaStreamTrack;
|
|
25
|
+
video: MediaStreamTrack;
|
|
26
|
+
private process;
|
|
27
|
+
stopped: boolean;
|
|
28
|
+
constructor(videoPort: number, audioPort: number, path: string, loop?: boolean | undefined);
|
|
29
|
+
private setupTrack;
|
|
30
|
+
start(): Promise<void>;
|
|
31
|
+
stop(): void;
|
|
14
32
|
}
|
|
15
|
-
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.MediaPlayerWebm = exports.MediaPlayerMp4 = exports.getUserMedia = void 0;
|
|
4
4
|
const child_process_1 = require("child_process");
|
|
5
5
|
const dgram_1 = require("dgram");
|
|
6
6
|
const promises_1 = require("timers/promises");
|
|
@@ -8,13 +8,18 @@ const uuid_1 = require("uuid");
|
|
|
8
8
|
const src_1 = require("../../../common/src");
|
|
9
9
|
const src_2 = require("../../../rtp/src");
|
|
10
10
|
const track_1 = require("../media/track");
|
|
11
|
-
const
|
|
11
|
+
const getUserMedia = async (path, loop) => {
|
|
12
12
|
const audioPort = await (0, src_1.randomPort)();
|
|
13
13
|
const videoPort = await (0, src_1.randomPort)();
|
|
14
|
-
|
|
14
|
+
if (path.endsWith(".mp4")) {
|
|
15
|
+
return new MediaPlayerMp4(audioPort, videoPort, path, loop);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
return new MediaPlayerWebm(audioPort, videoPort, path, loop);
|
|
19
|
+
}
|
|
15
20
|
};
|
|
16
|
-
exports.
|
|
17
|
-
class
|
|
21
|
+
exports.getUserMedia = getUserMedia;
|
|
22
|
+
class MediaPlayerMp4 {
|
|
18
23
|
constructor(videoPort, audioPort, path, loop) {
|
|
19
24
|
this.videoPort = videoPort;
|
|
20
25
|
this.audioPort = audioPort;
|
|
@@ -23,6 +28,7 @@ class MediaMp4 {
|
|
|
23
28
|
this.streamId = (0, uuid_1.v4)();
|
|
24
29
|
this.audio = new track_1.MediaStreamTrack({ kind: "audio", streamId: this.streamId });
|
|
25
30
|
this.video = new track_1.MediaStreamTrack({ kind: "video", streamId: this.streamId });
|
|
31
|
+
this.stopped = false;
|
|
26
32
|
this.setupTrack = (port, track) => {
|
|
27
33
|
let payloadType = 0;
|
|
28
34
|
const socket = (0, dgram_1.createSocket)("udp4");
|
|
@@ -54,14 +60,79 @@ queue ! h264parse ! rtph264pay config-interval=10 pt=${payloadType++} ! \
|
|
|
54
60
|
udpsink host=127.0.0.1 port=${this.videoPort} d. ! \
|
|
55
61
|
queue ! aacparse ! avdec_aac ! audioresample ! audioconvert ! opusenc ! rtpopuspay pt=${payloadType++} ! \
|
|
56
62
|
udpsink host=127.0.0.1 port=${this.audioPort}`;
|
|
57
|
-
|
|
63
|
+
this.process = (0, child_process_1.exec)(cmd);
|
|
58
64
|
if (this.loop) {
|
|
59
|
-
await new Promise((r) => process.on("close", r));
|
|
60
|
-
|
|
65
|
+
await new Promise((r) => this.process.on("close", r));
|
|
66
|
+
if (!this.stopped) {
|
|
67
|
+
run();
|
|
68
|
+
}
|
|
61
69
|
}
|
|
62
70
|
};
|
|
63
71
|
await (0, promises_1.setImmediate)();
|
|
64
72
|
run();
|
|
65
73
|
}
|
|
74
|
+
stop() {
|
|
75
|
+
this.stopped = true;
|
|
76
|
+
this.process.kill("SIGINT");
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.MediaPlayerMp4 = MediaPlayerMp4;
|
|
80
|
+
class MediaPlayerWebm {
|
|
81
|
+
constructor(videoPort, audioPort, path, loop) {
|
|
82
|
+
this.videoPort = videoPort;
|
|
83
|
+
this.audioPort = audioPort;
|
|
84
|
+
this.path = path;
|
|
85
|
+
this.loop = loop;
|
|
86
|
+
this.streamId = (0, uuid_1.v4)();
|
|
87
|
+
this.audio = new track_1.MediaStreamTrack({ kind: "audio", streamId: this.streamId });
|
|
88
|
+
this.video = new track_1.MediaStreamTrack({ kind: "video", streamId: this.streamId });
|
|
89
|
+
this.stopped = false;
|
|
90
|
+
this.setupTrack = (port, track) => {
|
|
91
|
+
let payloadType = 0;
|
|
92
|
+
const socket = (0, dgram_1.createSocket)("udp4");
|
|
93
|
+
socket.bind(port);
|
|
94
|
+
socket.on("message", async (buf) => {
|
|
95
|
+
const rtp = src_2.RtpPacket.deSerialize(buf);
|
|
96
|
+
if (!payloadType) {
|
|
97
|
+
payloadType = rtp.header.payloadType;
|
|
98
|
+
}
|
|
99
|
+
// detect gStreamer restarted
|
|
100
|
+
if (payloadType !== rtp.header.payloadType) {
|
|
101
|
+
payloadType = rtp.header.payloadType;
|
|
102
|
+
track.onSourceChanged.execute(rtp.header);
|
|
103
|
+
}
|
|
104
|
+
track.writeRtp(buf);
|
|
105
|
+
});
|
|
106
|
+
};
|
|
107
|
+
this.setupTrack(audioPort, this.audio);
|
|
108
|
+
this.setupTrack(videoPort, this.video);
|
|
109
|
+
}
|
|
110
|
+
async start() {
|
|
111
|
+
let payloadType = 96;
|
|
112
|
+
const run = async () => {
|
|
113
|
+
if (payloadType > 100)
|
|
114
|
+
payloadType = 96;
|
|
115
|
+
const cmd = `gst-launch-1.0 filesrc location=${this.path} ! matroskademux name=d \
|
|
116
|
+
d.video_0 ! queue ! rtpvp8pay pt=${payloadType++} ! \
|
|
117
|
+
udpsink host=127.0.0.1 port=${this.videoPort} \
|
|
118
|
+
d.audio_0 ! queue ! rtpopuspay pt=${payloadType++} ! \
|
|
119
|
+
udpsink host=127.0.0.1 port=${this.audioPort}`;
|
|
120
|
+
this.process = (0, child_process_1.exec)(cmd);
|
|
121
|
+
console.log(cmd);
|
|
122
|
+
if (this.loop) {
|
|
123
|
+
await new Promise((r) => this.process.on("close", r));
|
|
124
|
+
if (!this.stopped) {
|
|
125
|
+
run();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
await (0, promises_1.setImmediate)();
|
|
130
|
+
run();
|
|
131
|
+
}
|
|
132
|
+
stop() {
|
|
133
|
+
this.stopped = true;
|
|
134
|
+
this.process.kill("SIGINT");
|
|
135
|
+
}
|
|
66
136
|
}
|
|
137
|
+
exports.MediaPlayerWebm = MediaPlayerWebm;
|
|
67
138
|
//# sourceMappingURL=userMedia.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userMedia.js","sourceRoot":"","sources":["../../../../src/nonstandard/userMedia.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"userMedia.js","sourceRoot":"","sources":["../../../../src/nonstandard/userMedia.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChildProcess, exec } from \"child_process\";\nimport { createSocket } from \"dgram\";\nimport { setImmediate } from \"timers/promises\";\nimport { v4 } from \"uuid\";\n\nimport { randomPort } from \"../../../common/src\";\nimport { RtpPacket } from \"../../../rtp/src\";\nimport { MediaStreamTrack } from \"../media/track\";\n\nexport const getUserMedia = async (path: string, loop?: boolean) => {\n const audioPort = await randomPort();\n const videoPort = await randomPort();\n\n if (path.endsWith(\".mp4\")) {\n return new MediaPlayerMp4(audioPort, videoPort, path, loop);\n } else {\n return new MediaPlayerWebm(audioPort, videoPort, path, loop);\n }\n};\n\nexport class MediaPlayerMp4 {\n private streamId = v4();\n audio = new MediaStreamTrack({ kind: \"audio\", streamId: this.streamId });\n video = new MediaStreamTrack({ kind: \"video\", streamId: this.streamId });\n private process!: ChildProcess;\n stopped = false;\n\n constructor(\n private videoPort: number,\n private audioPort: number,\n private path: string,\n private loop?: boolean\n ) {\n this.setupTrack(audioPort, this.audio);\n this.setupTrack(videoPort, this.video);\n }\n\n private setupTrack = (port: number, track: MediaStreamTrack) => {\n let payloadType = 0;\n\n const socket = createSocket(\"udp4\");\n socket.bind(port);\n socket.on(\"message\", async (buf) => {\n const rtp = RtpPacket.deSerialize(buf);\n if (!payloadType) {\n payloadType = rtp.header.payloadType;\n }\n\n // detect gStreamer restarted\n if (payloadType !== rtp.header.payloadType) {\n payloadType = rtp.header.payloadType;\n track.onSourceChanged.execute(rtp.header);\n }\n\n track.writeRtp(buf);\n });\n };\n\n async start() {\n let payloadType = 96;\n const run = async () => {\n if (payloadType > 100) payloadType = 96;\n\n const cmd = `gst-launch-1.0 filesrc location= ${this.path} ! \\\nqtdemux name=d ! \\\nqueue ! h264parse ! rtph264pay config-interval=10 pt=${payloadType++} ! \\\nudpsink host=127.0.0.1 port=${this.videoPort} d. ! \\\nqueue ! aacparse ! avdec_aac ! audioresample ! audioconvert ! opusenc ! rtpopuspay pt=${payloadType++} ! \\\nudpsink host=127.0.0.1 port=${this.audioPort}`;\n this.process = exec(cmd);\n\n if (this.loop) {\n await new Promise((r) => this.process.on(\"close\", r));\n if (!this.stopped) {\n run();\n }\n }\n };\n await setImmediate();\n run();\n }\n\n stop() {\n this.stopped = true;\n this.process.kill(\"SIGINT\");\n }\n}\n\nexport class MediaPlayerWebm {\n private streamId = v4();\n audio = new MediaStreamTrack({ kind: \"audio\", streamId: this.streamId });\n video = new MediaStreamTrack({ kind: \"video\", streamId: this.streamId });\n private process!: ChildProcess;\n stopped = false;\n\n constructor(\n private videoPort: number,\n private audioPort: number,\n private path: string,\n private loop?: boolean\n ) {\n this.setupTrack(audioPort, this.audio);\n this.setupTrack(videoPort, this.video);\n }\n\n private setupTrack = (port: number, track: MediaStreamTrack) => {\n let payloadType = 0;\n\n const socket = createSocket(\"udp4\");\n socket.bind(port);\n socket.on(\"message\", async (buf) => {\n const rtp = RtpPacket.deSerialize(buf);\n if (!payloadType) {\n payloadType = rtp.header.payloadType;\n }\n\n // detect gStreamer restarted\n if (payloadType !== rtp.header.payloadType) {\n payloadType = rtp.header.payloadType;\n track.onSourceChanged.execute(rtp.header);\n }\n track.writeRtp(buf);\n });\n };\n\n async start() {\n let payloadType = 96;\n const run = async () => {\n if (payloadType > 100) payloadType = 96;\n\n const cmd = `gst-launch-1.0 filesrc location=${\n this.path\n } ! matroskademux name=d \\\nd.video_0 ! queue ! rtpvp8pay pt=${payloadType++} ! \\\nudpsink host=127.0.0.1 port=${this.videoPort} \\\nd.audio_0 ! queue ! rtpopuspay pt=${payloadType++} ! \\\nudpsink host=127.0.0.1 port=${this.audioPort}`;\n this.process = exec(cmd);\n console.log(cmd);\n\n if (this.loop) {\n await new Promise((r) => this.process.on(\"close\", r));\n if (!this.stopped) {\n run();\n }\n }\n };\n await setImmediate();\n run();\n }\n\n stop() {\n this.stopped = true;\n this.process.kill(\"SIGINT\");\n }\n}\n"]}
|
|
@@ -19,14 +19,16 @@ import { Callback, CallbackWithValue } from "./types/util";
|
|
|
19
19
|
export declare class RTCPeerConnection extends EventTarget {
|
|
20
20
|
readonly cname: string;
|
|
21
21
|
sctpTransport?: RTCSctpTransport;
|
|
22
|
-
|
|
22
|
+
transportEstablished: boolean;
|
|
23
23
|
config: Required<PeerConfig>;
|
|
24
24
|
connectionState: ConnectionState;
|
|
25
25
|
iceConnectionState: RTCIceConnectionState;
|
|
26
26
|
iceGatheringState: IceGathererState;
|
|
27
27
|
signalingState: RTCSignalingState;
|
|
28
28
|
negotiationneeded: boolean;
|
|
29
|
-
readonly transceivers
|
|
29
|
+
private readonly transceivers;
|
|
30
|
+
private pushTransceiver;
|
|
31
|
+
private replaceTransceiver;
|
|
30
32
|
candidatesSent: Set<string>;
|
|
31
33
|
readonly iceGatheringStateChange: Event<["new" | "complete" | "gathering"]>;
|
|
32
34
|
readonly iceConnectionStateChange: Event<["disconnected" | "closed" | "completed" | "new" | "connected" | "failed" | "checking"]>;
|
|
@@ -99,6 +101,7 @@ export declare class RTCPeerConnection extends EventTarget {
|
|
|
99
101
|
private validateDescription;
|
|
100
102
|
private fireOnTrack;
|
|
101
103
|
addTransceiver(trackOrKind: Kind | MediaStreamTrack, options?: Partial<TransceiverOptions>): RTCRtpTransceiver;
|
|
104
|
+
private _addTransceiver;
|
|
102
105
|
getTransceivers(): RTCRtpTransceiver[];
|
|
103
106
|
getSenders(): RTCRtpSender[];
|
|
104
107
|
getReceivers(): RTCRtpReceiver[];
|
|
@@ -53,7 +53,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
53
53
|
constructor(config = {}) {
|
|
54
54
|
super();
|
|
55
55
|
this.cname = uuid.v4();
|
|
56
|
-
this.
|
|
56
|
+
this.transportEstablished = false;
|
|
57
57
|
this.config = (0, cloneDeep_1.default)(exports.defaultPeerConfig);
|
|
58
58
|
this.connectionState = "new";
|
|
59
59
|
this.iceConnectionState = "new";
|
|
@@ -145,6 +145,12 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
145
145
|
}
|
|
146
146
|
});
|
|
147
147
|
}
|
|
148
|
+
pushTransceiver(t) {
|
|
149
|
+
this.transceivers.push(t);
|
|
150
|
+
}
|
|
151
|
+
replaceTransceiver(t, index) {
|
|
152
|
+
this.transceivers[index] = t;
|
|
153
|
+
}
|
|
148
154
|
get dtlsTransports() {
|
|
149
155
|
const transports = this.transceivers.map((t) => t.dtlsTransport);
|
|
150
156
|
if (this.sctpTransport) {
|
|
@@ -191,12 +197,12 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
191
197
|
const codecs = this.config.codecs[transceiver.kind].filter((codecCandidate) => {
|
|
192
198
|
switch (codecCandidate.direction) {
|
|
193
199
|
case "recvonly": {
|
|
194
|
-
if (
|
|
200
|
+
if (const_1.ReceiverDirection.includes(transceiver.direction))
|
|
195
201
|
return true;
|
|
196
202
|
return false;
|
|
197
203
|
}
|
|
198
204
|
case "sendonly": {
|
|
199
|
-
if (
|
|
205
|
+
if (const_1.SenderDirections.includes(transceiver.direction))
|
|
200
206
|
return true;
|
|
201
207
|
return false;
|
|
202
208
|
}
|
|
@@ -320,8 +326,9 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
320
326
|
removeTrack(sender) {
|
|
321
327
|
if (this.isClosed)
|
|
322
328
|
throw new Error("peer closed");
|
|
323
|
-
if (!this.getSenders().find(({ ssrc }) => sender.ssrc === ssrc))
|
|
329
|
+
if (!this.getSenders().find(({ ssrc }) => sender.ssrc === ssrc)) {
|
|
324
330
|
throw new Error("unExist");
|
|
331
|
+
}
|
|
325
332
|
const transceiver = this.transceivers.find(({ sender: { ssrc } }) => sender.ssrc === ssrc);
|
|
326
333
|
if (!transceiver)
|
|
327
334
|
throw new Error("unExist");
|
|
@@ -331,15 +338,15 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
331
338
|
return;
|
|
332
339
|
}
|
|
333
340
|
if (transceiver.stopping || transceiver.stopped) {
|
|
334
|
-
transceiver.
|
|
341
|
+
transceiver.setDirection("inactive");
|
|
335
342
|
}
|
|
336
343
|
else {
|
|
337
344
|
if (transceiver.direction === "sendrecv") {
|
|
338
|
-
transceiver.
|
|
345
|
+
transceiver.setDirection("recvonly");
|
|
339
346
|
}
|
|
340
347
|
else if (transceiver.direction === "sendonly" ||
|
|
341
348
|
transceiver.direction === "recvonly") {
|
|
342
|
-
transceiver.
|
|
349
|
+
transceiver.setDirection("inactive");
|
|
343
350
|
}
|
|
344
351
|
}
|
|
345
352
|
this.needNegotiation();
|
|
@@ -485,24 +492,30 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
485
492
|
};
|
|
486
493
|
this.dtlsTransports.forEach((d) => setupRole(d));
|
|
487
494
|
// # configure direction
|
|
488
|
-
|
|
489
|
-
|
|
495
|
+
if (["answer", "pranswer"].includes(description.type)) {
|
|
496
|
+
this.transceivers.forEach((t) => {
|
|
490
497
|
const direction = (0, utils_1.andDirection)(t.direction, t.offerDirection);
|
|
491
|
-
t.
|
|
492
|
-
}
|
|
493
|
-
}
|
|
498
|
+
t.setCurrentDirection(direction);
|
|
499
|
+
});
|
|
500
|
+
}
|
|
494
501
|
// for trickle ice
|
|
495
502
|
this.setLocal(description);
|
|
496
503
|
// connect transports
|
|
497
504
|
if (description.type === "answer") {
|
|
498
|
-
log("callee start connect");
|
|
499
505
|
this.connect().catch((err) => {
|
|
500
506
|
log("connect failed", err);
|
|
501
507
|
this.setConnectionState("failed");
|
|
502
508
|
});
|
|
503
509
|
}
|
|
504
510
|
// # gather candidates
|
|
505
|
-
|
|
511
|
+
const connected = this.iceTransports.find((transport) => transport.state === "connected");
|
|
512
|
+
if (this.remoteIsBundled && connected) {
|
|
513
|
+
// no need to gather ice candidates on an existing bundled connection
|
|
514
|
+
await connected.iceGather.gather();
|
|
515
|
+
}
|
|
516
|
+
else {
|
|
517
|
+
await Promise.all(this.iceTransports.map((iceTransport) => iceTransport.iceGather.gather()));
|
|
518
|
+
}
|
|
506
519
|
description.media
|
|
507
520
|
.filter((m) => ["audio", "video"].includes(m.kind))
|
|
508
521
|
.forEach((m, i) => {
|
|
@@ -570,8 +583,10 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
570
583
|
}
|
|
571
584
|
}
|
|
572
585
|
async connect() {
|
|
573
|
-
if (this.
|
|
586
|
+
if (this.transportEstablished) {
|
|
574
587
|
return;
|
|
588
|
+
}
|
|
589
|
+
log("start connect");
|
|
575
590
|
this.setConnectionState("connecting");
|
|
576
591
|
await Promise.all(this.dtlsTransports.map(async (dtlsTransport) => {
|
|
577
592
|
const { iceTransport } = dtlsTransport;
|
|
@@ -591,7 +606,7 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
591
606
|
log("sctp connected");
|
|
592
607
|
}
|
|
593
608
|
}));
|
|
594
|
-
this.
|
|
609
|
+
this.transportEstablished = true;
|
|
595
610
|
this.setConnectionState("connected");
|
|
596
611
|
}
|
|
597
612
|
getLocalRtpParams(transceiver) {
|
|
@@ -652,13 +667,13 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
652
667
|
// # apply description
|
|
653
668
|
const matchTransceiverWithMedia = (transceiver, media) => transceiver.kind === media.kind &&
|
|
654
669
|
[undefined, media.rtp.muxId].includes(transceiver.mid);
|
|
655
|
-
let transports =
|
|
670
|
+
let transports = remoteSdp.media.map((remoteMedia, i) => {
|
|
656
671
|
let dtlsTransport;
|
|
657
672
|
if (["audio", "video"].includes(remoteMedia.kind)) {
|
|
658
673
|
let transceiver = this.transceivers.find((t) => matchTransceiverWithMedia(t, remoteMedia));
|
|
659
674
|
if (!transceiver) {
|
|
660
675
|
// create remote transceiver
|
|
661
|
-
transceiver = this.
|
|
676
|
+
transceiver = this._addTransceiver(remoteMedia.kind, {
|
|
662
677
|
direction: "recvonly",
|
|
663
678
|
});
|
|
664
679
|
transceiver.mid = remoteMedia.rtp.muxId;
|
|
@@ -667,7 +682,9 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
667
682
|
else {
|
|
668
683
|
if (transceiver.direction === "inactive" && transceiver.stopping) {
|
|
669
684
|
transceiver.stopped = true;
|
|
670
|
-
|
|
685
|
+
if (sessionDescription.type === "answer") {
|
|
686
|
+
transceiver.setCurrentDirection("inactive");
|
|
687
|
+
}
|
|
671
688
|
return;
|
|
672
689
|
}
|
|
673
690
|
}
|
|
@@ -749,9 +766,14 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
749
766
|
this.setConnectionState("failed");
|
|
750
767
|
});
|
|
751
768
|
}
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
769
|
+
const connected = this.iceTransports.find((transport) => transport.state === "connected");
|
|
770
|
+
if (this.remoteIsBundled && connected) {
|
|
771
|
+
// no need to gather ice candidates on an existing bundled connection
|
|
772
|
+
await connected.iceGather.gather();
|
|
773
|
+
}
|
|
774
|
+
else {
|
|
775
|
+
await Promise.all(transports.map((iceTransport) => iceTransport.iceGather.gather()));
|
|
776
|
+
}
|
|
755
777
|
this.negotiationneeded = false;
|
|
756
778
|
if (this.shouldNegotiationneeded) {
|
|
757
779
|
this.needNegotiation();
|
|
@@ -760,8 +782,8 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
760
782
|
setRemoteRTP(transceiver, remoteMedia, type, mLineIndex) {
|
|
761
783
|
if (!transceiver.mid) {
|
|
762
784
|
transceiver.mid = remoteMedia.rtp.muxId;
|
|
763
|
-
transceiver.mLineIndex = mLineIndex;
|
|
764
785
|
}
|
|
786
|
+
transceiver.mLineIndex = mLineIndex;
|
|
765
787
|
// # negotiate codecs
|
|
766
788
|
transceiver.codecs = remoteMedia.rtp.codecs.filter((remoteCodec) => {
|
|
767
789
|
const localCodecs = this.config.codecs[remoteMedia.kind] || [];
|
|
@@ -784,10 +806,10 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
784
806
|
}
|
|
785
807
|
transceiver.headerExtensions = remoteMedia.rtp.headerExtensions.filter((extension) => (this.config.headerExtensions[remoteMedia.kind] || []).find((v) => v.uri === extension.uri));
|
|
786
808
|
// # configure direction
|
|
787
|
-
const mediaDirection = remoteMedia.direction
|
|
809
|
+
const mediaDirection = remoteMedia.direction ?? "inactive";
|
|
788
810
|
const direction = (0, utils_1.reverseDirection)(mediaDirection);
|
|
789
811
|
if (["answer", "pranswer"].includes(type)) {
|
|
790
|
-
transceiver.
|
|
812
|
+
transceiver.setCurrentDirection(direction);
|
|
791
813
|
}
|
|
792
814
|
else {
|
|
793
815
|
transceiver.offerDirection = direction;
|
|
@@ -888,6 +910,9 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
888
910
|
this.ontrack(event);
|
|
889
911
|
}
|
|
890
912
|
addTransceiver(trackOrKind, options = {}) {
|
|
913
|
+
return this._addTransceiver(trackOrKind, options);
|
|
914
|
+
}
|
|
915
|
+
_addTransceiver(trackOrKind, options = {}) {
|
|
891
916
|
const kind = typeof trackOrKind === "string" ? trackOrKind : trackOrKind.kind;
|
|
892
917
|
const direction = options.direction || "sendrecv";
|
|
893
918
|
const dtlsTransport = this.createTransport([
|
|
@@ -896,24 +921,24 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
896
921
|
]);
|
|
897
922
|
const sender = new rtpSender_1.RTCRtpSender(trackOrKind);
|
|
898
923
|
const receiver = new rtpReceiver_1.RTCRtpReceiver(this.config, kind, sender.ssrc);
|
|
899
|
-
const
|
|
900
|
-
|
|
901
|
-
this.router.registerRtpSender(
|
|
924
|
+
const newTransceiver = new rtpTransceiver_1.RTCRtpTransceiver(kind, dtlsTransport, receiver, sender, direction);
|
|
925
|
+
newTransceiver.options = options;
|
|
926
|
+
this.router.registerRtpSender(newTransceiver.sender);
|
|
902
927
|
// reuse inactive
|
|
903
928
|
const inactiveTransceiverIndex = this.transceivers.findIndex((t) => t.currentDirection === "inactive");
|
|
904
929
|
const inactiveTransceiver = this.transceivers.find((t) => t.currentDirection === "inactive");
|
|
905
|
-
if (inactiveTransceiverIndex > -1) {
|
|
906
|
-
this.
|
|
907
|
-
|
|
908
|
-
inactiveTransceiver.
|
|
930
|
+
if (inactiveTransceiverIndex > -1 && inactiveTransceiver) {
|
|
931
|
+
this.replaceTransceiver(newTransceiver, inactiveTransceiverIndex);
|
|
932
|
+
newTransceiver.mLineIndex = inactiveTransceiver.mLineIndex;
|
|
933
|
+
inactiveTransceiver.setCurrentDirection(undefined);
|
|
909
934
|
}
|
|
910
935
|
else {
|
|
911
|
-
this.
|
|
936
|
+
this.pushTransceiver(newTransceiver);
|
|
912
937
|
}
|
|
913
|
-
this.onTransceiverAdded.execute(
|
|
938
|
+
this.onTransceiverAdded.execute(newTransceiver);
|
|
914
939
|
this.updateIceConnectionState();
|
|
915
940
|
this.needNegotiation();
|
|
916
|
-
return
|
|
941
|
+
return newTransceiver;
|
|
917
942
|
}
|
|
918
943
|
getTransceivers() {
|
|
919
944
|
return this.transceivers;
|
|
@@ -951,17 +976,19 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
951
976
|
sender.registerTrack(track);
|
|
952
977
|
switch (notSendTransceiver.direction) {
|
|
953
978
|
case "recvonly":
|
|
954
|
-
notSendTransceiver.
|
|
979
|
+
notSendTransceiver.setDirection("sendrecv");
|
|
955
980
|
break;
|
|
956
981
|
case "inactive":
|
|
957
|
-
notSendTransceiver.
|
|
982
|
+
notSendTransceiver.setDirection("sendonly");
|
|
958
983
|
break;
|
|
959
984
|
}
|
|
960
985
|
this.needNegotiation();
|
|
961
986
|
return sender;
|
|
962
987
|
}
|
|
963
988
|
else {
|
|
964
|
-
const transceiver = this.
|
|
989
|
+
const transceiver = this._addTransceiver(track, {
|
|
990
|
+
direction: "sendrecv",
|
|
991
|
+
});
|
|
965
992
|
this.needNegotiation();
|
|
966
993
|
return transceiver.sender;
|
|
967
994
|
}
|
|
@@ -1014,14 +1041,13 @@ class RTCPeerConnection extends helper_1.EventTarget {
|
|
|
1014
1041
|
throw new Error("invalid kind");
|
|
1015
1042
|
}
|
|
1016
1043
|
// # determine DTLS role, or preserve the currently configured role
|
|
1017
|
-
if (
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
media.dtlsParams.role = dtlsTransport.role;
|
|
1044
|
+
if (media.dtlsParams) {
|
|
1045
|
+
if (dtlsTransport.role === "auto") {
|
|
1046
|
+
media.dtlsParams.role = "client";
|
|
1047
|
+
}
|
|
1048
|
+
else {
|
|
1049
|
+
media.dtlsParams.role = dtlsTransport.role;
|
|
1050
|
+
}
|
|
1025
1051
|
}
|
|
1026
1052
|
media.simulcastParameters = remoteMedia.simulcastParameters.map((v) => ({
|
|
1027
1053
|
...v,
|