werift 0.23.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -0
- package/lib/common/src/transport.d.ts +22 -9
- package/lib/common/src/transport.js +152 -25
- package/lib/common/src/transport.js.map +1 -1
- package/lib/ice/src/candidate.d.ts +16 -1
- package/lib/ice/src/candidate.js +99 -15
- package/lib/ice/src/candidate.js.map +1 -1
- package/lib/ice/src/ice.d.ts +2 -0
- package/lib/ice/src/ice.js +171 -41
- package/lib/ice/src/ice.js.map +1 -1
- package/lib/ice/src/iceBase.d.ts +23 -2
- package/lib/ice/src/iceBase.js +63 -1
- package/lib/ice/src/iceBase.js.map +1 -1
- package/lib/ice/src/index.d.ts +2 -0
- package/lib/ice/src/index.js +2 -0
- package/lib/ice/src/index.js.map +1 -1
- package/lib/ice/src/stun/const.d.ts +1 -26
- package/lib/ice/src/stun/const.js +15 -54
- package/lib/ice/src/stun/const.js.map +1 -1
- package/lib/ice/src/stun/message.d.ts +1 -25
- package/lib/ice/src/stun/message.js +15 -149
- package/lib/ice/src/stun/message.js.map +1 -1
- package/lib/ice/src/stun/protocol.d.ts +1 -1
- package/lib/ice/src/stun/protocol.js +2 -2
- package/lib/ice/src/stun/protocol.js.map +1 -1
- package/lib/ice/src/stun/tcpFrame.d.ts +5 -0
- package/lib/ice/src/stun/tcpFrame.js +26 -0
- package/lib/ice/src/stun/tcpFrame.js.map +1 -0
- package/lib/ice/src/stun/tcpProtocol.d.ts +51 -0
- package/lib/ice/src/stun/tcpProtocol.js +326 -0
- package/lib/ice/src/stun/tcpProtocol.js.map +1 -0
- package/lib/ice/src/stun/transaction.d.ts +2 -1
- package/lib/ice/src/stun/transaction.js +9 -3
- package/lib/ice/src/stun/transaction.js.map +1 -1
- package/lib/ice/src/turn/frame.d.ts +1 -0
- package/lib/ice/src/turn/frame.js +18 -0
- package/lib/ice/src/turn/frame.js.map +1 -0
- package/lib/ice/src/turn/protocol.d.ts +9 -7
- package/lib/ice/src/turn/protocol.js +32 -44
- package/lib/ice/src/turn/protocol.js.map +1 -1
- package/lib/ice/src/types/model.d.ts +1 -1
- package/lib/ice/src/types/model.js.map +1 -1
- package/lib/{ice → ice-server}/src/stun/attributes.d.ts +12 -5
- package/lib/{ice → ice-server}/src/stun/attributes.js +60 -19
- package/lib/ice-server/src/stun/attributes.js.map +1 -0
- package/lib/ice-server/src/stun/const.d.ts +28 -0
- package/lib/ice-server/src/stun/const.js +88 -0
- package/lib/ice-server/src/stun/const.js.map +1 -0
- package/lib/ice-server/src/stun/message.d.ts +37 -0
- package/lib/ice-server/src/stun/message.js +190 -0
- package/lib/ice-server/src/stun/message.js.map +1 -0
- package/lib/ice-server/src/turn/auth.d.ts +1 -0
- package/lib/ice-server/src/turn/auth.js +10 -0
- package/lib/ice-server/src/turn/auth.js.map +1 -0
- package/lib/ice-server/src/turn/frame.d.ts +13 -0
- package/lib/ice-server/src/turn/frame.js +69 -0
- package/lib/ice-server/src/turn/frame.js.map +1 -0
- package/lib/index.mjs +2688 -855
- package/lib/nonstandard/index.mjs +1753 -403
- package/lib/rtp/src/extra/container/mp4/container.d.ts +9 -6
- package/lib/rtp/src/extra/container/mp4/container.js +258 -173
- package/lib/rtp/src/extra/container/mp4/container.js.map +1 -1
- package/lib/rtp/src/extra/container/mp4/h264.d.ts +1 -0
- package/lib/rtp/src/extra/container/mp4/h264.js +13 -0
- package/lib/rtp/src/extra/container/mp4/h264.js.map +1 -1
- package/lib/rtp/src/extra/processor/mp4.d.ts +11 -7
- package/lib/rtp/src/extra/processor/mp4.js +115 -60
- package/lib/rtp/src/extra/processor/mp4.js.map +1 -1
- package/lib/rtp/src/extra/processor/mp4Callback.d.ts +2 -3
- package/lib/rtp/src/extra/processor/mp4Callback.js +5 -3
- package/lib/rtp/src/extra/processor/mp4Callback.js.map +1 -1
- package/lib/webrtc/src/dataChannel.d.ts +3 -2
- package/lib/webrtc/src/dataChannel.js +9 -2
- package/lib/webrtc/src/dataChannel.js.map +1 -1
- package/lib/webrtc/src/errors.d.ts +3 -0
- package/lib/webrtc/src/errors.js +11 -0
- package/lib/webrtc/src/errors.js.map +1 -0
- package/lib/webrtc/src/helper.d.ts +5 -1
- package/lib/webrtc/src/helper.js +33 -1
- package/lib/webrtc/src/helper.js.map +1 -1
- package/lib/webrtc/src/media/receiver/statistics.d.ts +4 -1
- package/lib/webrtc/src/media/receiver/statistics.js +22 -0
- package/lib/webrtc/src/media/receiver/statistics.js.map +1 -1
- package/lib/webrtc/src/media/rtpReceiver.d.ts +15 -2
- package/lib/webrtc/src/media/rtpReceiver.js +135 -20
- package/lib/webrtc/src/media/rtpReceiver.js.map +1 -1
- package/lib/webrtc/src/media/rtpSender.d.ts +32 -7
- package/lib/webrtc/src/media/rtpSender.js +177 -28
- package/lib/webrtc/src/media/rtpSender.js.map +1 -1
- package/lib/webrtc/src/media/rtpTransceiver.d.ts +13 -4
- package/lib/webrtc/src/media/rtpTransceiver.js +26 -5
- package/lib/webrtc/src/media/rtpTransceiver.js.map +1 -1
- package/lib/webrtc/src/media/stats.d.ts +15 -1
- package/lib/webrtc/src/media/stats.js +55 -1
- package/lib/webrtc/src/media/stats.js.map +1 -1
- package/lib/webrtc/src/media/track.d.ts +2 -1
- package/lib/webrtc/src/media/track.js +7 -1
- package/lib/webrtc/src/media/track.js.map +1 -1
- package/lib/webrtc/src/nonstandard/dummyMedia.d.ts +19 -0
- package/lib/webrtc/src/nonstandard/dummyMedia.js +157 -0
- package/lib/webrtc/src/nonstandard/dummyMedia.js.map +1 -0
- package/lib/webrtc/src/nonstandard/navigator.d.ts +18 -8
- package/lib/webrtc/src/nonstandard/navigator.js +96 -32
- package/lib/webrtc/src/nonstandard/navigator.js.map +1 -1
- package/lib/webrtc/src/nonstandard/userMedia/packetizer.d.ts +16 -0
- package/lib/webrtc/src/nonstandard/userMedia/packetizer.js +360 -0
- package/lib/webrtc/src/nonstandard/userMedia/packetizer.js.map +1 -0
- package/lib/webrtc/src/nonstandard/userMedia.d.ts +71 -31
- package/lib/webrtc/src/nonstandard/userMedia.js +454 -108
- package/lib/webrtc/src/nonstandard/userMedia.js.map +1 -1
- package/lib/webrtc/src/peerConnection.d.ts +183 -50
- package/lib/webrtc/src/peerConnection.js +458 -109
- package/lib/webrtc/src/peerConnection.js.map +1 -1
- package/lib/webrtc/src/sctpManager.d.ts +1 -1
- package/lib/webrtc/src/sctpManager.js +27 -7
- package/lib/webrtc/src/sctpManager.js.map +1 -1
- package/lib/webrtc/src/sdp.d.ts +10 -7
- package/lib/webrtc/src/sdp.js +39 -9
- package/lib/webrtc/src/sdp.js.map +1 -1
- package/lib/webrtc/src/sdpManager.d.ts +4 -3
- package/lib/webrtc/src/sdpManager.js +50 -27
- package/lib/webrtc/src/sdpManager.js.map +1 -1
- package/lib/webrtc/src/secureTransportManager.d.ts +13 -4
- package/lib/webrtc/src/secureTransportManager.js +100 -22
- package/lib/webrtc/src/secureTransportManager.js.map +1 -1
- package/lib/webrtc/src/transceiverManager.d.ts +5 -4
- package/lib/webrtc/src/transceiverManager.js +61 -62
- package/lib/webrtc/src/transceiverManager.js.map +1 -1
- package/lib/webrtc/src/transport/dtls.d.ts +15 -4
- package/lib/webrtc/src/transport/dtls.js +91 -23
- package/lib/webrtc/src/transport/dtls.js.map +1 -1
- package/lib/webrtc/src/transport/ice.d.ts +21 -3
- package/lib/webrtc/src/transport/ice.js +159 -30
- package/lib/webrtc/src/transport/ice.js.map +1 -1
- package/lib/webrtc/src/transport/sctp.d.ts +1 -0
- package/lib/webrtc/src/transport/sctp.js +9 -6
- package/lib/webrtc/src/transport/sctp.js.map +1 -1
- package/lib/webrtc/src/utils.d.ts +12 -4
- package/lib/webrtc/src/utils.js +118 -16
- package/lib/webrtc/src/utils.js.map +1 -1
- package/package.json +7 -4
- package/lib/ice/src/stun/attributes.js.map +0 -1
- package/lib/rtp/src/extra/container/mp4/mp4box.d.ts +0 -5
- package/lib/rtp/src/extra/container/mp4/mp4box.js +0 -32
- package/lib/rtp/src/extra/container/mp4/mp4box.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userMedia.js","sourceRoot":"","sources":["../../../../src/nonstandard/userMedia.ts"],"names":[],"mappings":"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","sourcesContent":["import { type ChildProcess, exec } from \"child_process\";\nimport { randomUUID } from \"crypto\";\nimport { createSocket } from \"dgram\";\nimport { setImmediate } from \"timers/promises\";\n\nimport { randomPort } from \"../imports/common\";\nimport { RtpPacket } from \"../imports/rtp\";\nimport { MediaStreamTrack } from \"../media/track\";\n\nexport const getUserMedia = async ({\n path,\n loop,\n width,\n height,\n}: {\n path: string;\n loop?: boolean;\n width?: number;\n height?: number;\n}) => {\n const audioPort = await randomPort();\n const videoPort = await randomPort();\n\n if (path.endsWith(\".mp4\")) {\n return new MediaPlayerMp4({\n audioPort,\n videoPort,\n path,\n loop,\n width,\n height,\n });\n } else {\n return new MediaPlayerWebm({\n audioPort,\n videoPort,\n path,\n loop,\n width,\n height,\n });\n }\n};\n\nabstract class MediaPlayer {\n protected streamId = randomUUID().toString();\n audio = new MediaStreamTrack({ kind: \"audio\", streamId: this.streamId });\n video = new MediaStreamTrack({ kind: \"video\", streamId: this.streamId });\n protected process!: ChildProcess;\n stopped = false;\n\n constructor(\n protected props: {\n videoPort: number;\n audioPort: number;\n path: string;\n loop?: boolean;\n width?: number;\n height?: number;\n },\n ) {\n this.setupTrack(props.audioPort, this.audio);\n this.setupTrack(props.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 stop() {\n this.stopped = true;\n this.process.kill(\"SIGINT\");\n }\n}\n\nexport class MediaPlayerMp4 extends MediaPlayer {\n async start() {\n let payloadType = 96;\n const run = async () => {\n if (payloadType > 100) payloadType = 96;\n\n let cmd = \"\";\n if (this.props.width && this.props.height) {\n cmd = `gst-launch-1.0 filesrc location= ${this.props.path} ! \\\ndecodebin ! videoscale ! video/x-raw,width=${this.props.width},height=${\n this.props.height\n } ! x264enc ! \\\nh264parse ! rtph264pay config-interval=10 pt=${payloadType++} ! \\\nudpsink host=127.0.0.1 port=${this.props.videoPort}`;\n } else {\n cmd = `gst-launch-1.0 filesrc location= ${this.props.path} ! \\\nqtdemux name=d ! \\\nqueue ! h264parse ! rtph264pay config-interval=10 pt=${payloadType++} ! \\\nudpsink host=127.0.0.1 port=${this.props.videoPort} d. ! \\\nqueue ! aacparse ! avdec_aac ! audioresample ! audioconvert ! opusenc ! rtpopuspay pt=${payloadType++} ! \\\nudpsink host=127.0.0.1 port=${this.props.audioPort}`;\n }\n console.log(cmd);\n this.process = exec(cmd);\n this.process.on(\"error\", (e) => console.error(\"gst error\", e));\n\n if (this.props.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\nexport class MediaPlayerWebm extends MediaPlayer {\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.props.path} ! matroskademux name=d \\\nd.video_0 ! queue ! rtpvp8pay pt=${payloadType++} ! \\\nudpsink host=127.0.0.1 port=${this.props.videoPort} \\\nd.audio_0 ! queue ! rtpopuspay pt=${payloadType++} ! \\\nudpsink host=127.0.0.1 port=${this.props.audioPort}`;\n this.process = exec(cmd);\n\n if (this.props.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"]}
|
|
1
|
+
{"version":3,"file":"userMedia.js","sourceRoot":"","sources":["../../../../src/nonstandard/userMedia.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"crypto\";\nimport { homedir } from \"os\";\nimport { isAbsolute, resolve } from \"path\";\nimport { Readable } from \"stream\";\nimport { readFile } from \"fs/promises\";\nimport {\n setImmediate as onNextTurn,\n setTimeout as wait,\n} from \"timers/promises\";\n\nimport {\n BufferSource,\n EncodedPacketSink,\n Input,\n type InputAudioTrack,\n type InputTrack,\n type InputVideoTrack,\n MP4,\n WEBM,\n} from \"mediabunny\";\n\nimport { Event } from \"../imports/common\";\nimport type { RTCRtpCodecParameters } from \"../media/parameters\";\nimport { MediaStreamTrack } from \"../media/track\";\nimport { codecParametersFromString } from \"../sdp\";\nimport {\n type SupportedSourceCodec,\n createPacketizer,\n supportedSourceCodecs,\n toSupportedMimeType,\n} from \"./userMedia/packetizer\";\n\ntype UserMediaSource =\n | { path: string; buffer?: never; stream?: never }\n | {\n path?: never;\n buffer: Buffer | ArrayBuffer | ArrayBufferView;\n stream?: never;\n }\n | {\n path?: never;\n buffer?: never;\n stream: Readable | ReadableStream<Uint8Array>;\n };\n\nexport type FileMediaTrackSource = UserMediaSource & {\n loop?: boolean;\n};\n\nexport const getUserMedia = async (options: FileMediaTrackSource) => {\n assertSupportedOptions(options);\n const replayableSource = await createReplayableSource(options);\n const input = await createInput(replayableSource);\n try {\n if (!(await input.canRead())) {\n throw new Error(\"Only MP4 and WebM file playback is supported\");\n }\n\n const streamId = randomUUID().toString();\n const playbackTracks = await selectPlaybackTracks(input, streamId);\n if (playbackTracks.length === 0) {\n throw new Error(\n \"The media source does not contain playable audio or video tracks\",\n );\n }\n\n const mediaStartTimestamp = await input.getFirstTimestamp(\n playbackTracks.map(({ inputTrack }) => inputTrack),\n );\n\n return new MediaPlayer({\n source: replayableSource,\n loop: options.loop ?? false,\n streamId,\n session: createPlaybackSession({\n input,\n mediaStartTimestamp,\n playbackTracks,\n }),\n });\n } catch (error) {\n input.dispose();\n throw error;\n }\n};\n\nclass MediaPlayer {\n readonly audio?: MediaStreamTrack;\n readonly video?: MediaStreamTrack;\n readonly onError = new Event<[Error]>();\n\n private readonly source: ReplayableUserMediaSource;\n private readonly loop: boolean;\n private readonly streamId: string;\n private session?: PlaybackSession;\n private running?: Promise<void>;\n private abortController?: AbortController;\n private hasStartedPlayback = false;\n private stopped = false;\n\n constructor({\n source,\n loop,\n streamId,\n session,\n }: {\n source: ReplayableUserMediaSource;\n loop: boolean;\n streamId: string;\n session: PlaybackSession;\n }) {\n this.source = source;\n this.loop = loop;\n this.streamId = streamId;\n this.session = session;\n\n this.audio = session.playbackTracks.find(\n ({ track }) => track.kind === \"audio\",\n )?.track;\n this.video = session.playbackTracks.find(\n ({ track }) => track.kind === \"video\",\n )?.track;\n }\n\n async start() {\n if (this.stopped) {\n throw new Error(\"The media source has already been stopped\");\n }\n if (this.running) {\n return;\n }\n\n const abortController = new AbortController();\n this.abortController = abortController;\n\n let startupPending = true;\n let session: PlaybackSession | undefined;\n const playback = (async () => {\n session = await this.getOrCreateSession();\n if (abortController.signal.aborted || this.stopped) {\n return;\n }\n\n session.runners.forEach((runner) => runner.assertReady());\n\n const initialSourceChanged = this.hasStartedPlayback;\n this.hasStartedPlayback = true;\n await this.run(session, abortController, initialSourceChanged);\n })();\n const observedPlayback = playback.catch((error) => {\n if (abortController.signal.aborted) {\n return;\n }\n\n this.onError.execute(toError(error));\n if (startupPending) {\n throw error;\n }\n });\n\n this.running = observedPlayback.finally(() => {\n if (this.abortController === abortController) {\n this.abortController = undefined;\n }\n this.running = undefined;\n this.disposeSession(session);\n });\n\n try {\n await Promise.race([this.running, onNextTurn()]);\n } finally {\n startupPending = false;\n }\n }\n\n stop() {\n if (this.stopped) {\n return;\n }\n // File playback mirrors the previous process-backed behavior: stop() is terminal.\n this.stopped = true;\n this.abortController?.abort();\n if (!this.running) {\n this.disposeSession();\n }\n }\n\n private async run(\n session: PlaybackSession,\n abortController: AbortController,\n initialSourceChanged: boolean,\n ) {\n let sourceChanged = initialSourceChanged;\n\n do {\n const startedAt = performance.now();\n await Promise.all(\n session.runners.map((runner) =>\n runner.play({\n startedAt,\n signal: abortController.signal,\n sourceChanged,\n }),\n ),\n );\n if (!this.loop || abortController.signal.aborted) {\n break;\n }\n sourceChanged = true;\n } while (!abortController.signal.aborted);\n }\n\n private async getOrCreateSession() {\n if (this.session) {\n return this.session;\n }\n\n const input = await createInput(this.source);\n try {\n if (!(await input.canRead())) {\n throw new Error(\"Only MP4 and WebM file playback is supported\");\n }\n\n const playbackTracks = await selectPlaybackTracks(\n input,\n this.streamId,\n buildExistingTrackMap(this.audio, this.video),\n );\n const mediaStartTimestamp = await input.getFirstTimestamp(\n playbackTracks.map(({ inputTrack }) => inputTrack),\n );\n\n const session = createPlaybackSession({\n input,\n mediaStartTimestamp,\n playbackTracks,\n });\n this.session = session;\n return session;\n } catch (error) {\n input.dispose();\n throw error;\n }\n }\n\n private disposeSession(session = this.session) {\n if (!session) {\n return;\n }\n\n session.input.dispose();\n if (this.session === session) {\n this.session = undefined;\n }\n }\n}\n\nclass TrackPlaybackRunner {\n constructor(\n private readonly props: PlaybackTrack & {\n mediaStartTimestamp: number;\n },\n ) {}\n\n async play({\n startedAt,\n signal,\n sourceChanged,\n }: {\n startedAt: number;\n signal: AbortSignal;\n sourceChanged: boolean;\n }) {\n const codec = this.requireNegotiatedCodec();\n const packetizer = createPacketizer({\n codec,\n sourceCodec: this.props.sourceCodec,\n decoderDescription: this.props.decoderDescription,\n });\n const packetSink = new EncodedPacketSink(this.props.inputTrack);\n let sourceChangeNotified = false;\n\n try {\n for await (const packet of packetSink.packets(undefined, undefined, {\n verifyKeyPackets: this.props.track.kind === \"video\",\n })) {\n signal.throwIfAborted?.();\n\n const dueAtMs =\n (packet.timestamp - this.props.mediaStartTimestamp) * 1_000;\n const remainingMs = dueAtMs - (performance.now() - startedAt);\n if (remainingMs > 0) {\n await wait(remainingMs, undefined, { signal });\n }\n\n const rtpTimestamp = toRtpTimestamp(\n packet.timestamp,\n this.props.mediaStartTimestamp,\n codec.clockRate,\n );\n const packets = packetizer.packetize(packet, rtpTimestamp);\n if (packets.length === 0) {\n continue;\n }\n\n if (sourceChanged && !sourceChangeNotified) {\n this.props.track.onSourceChanged.execute(packets[0].header);\n sourceChangeNotified = true;\n }\n\n for (const rtpPacket of packets) {\n this.props.track.writeRtp(rtpPacket);\n }\n }\n } catch (error) {\n if (signal.aborted || isAbortError(error)) {\n return;\n }\n throw error;\n }\n }\n\n assertReady() {\n const codec = this.requireNegotiatedCodec();\n createPacketizer({\n codec,\n sourceCodec: this.props.sourceCodec,\n decoderDescription: this.props.decoderDescription,\n });\n }\n\n private requireNegotiatedCodec() {\n const codec = this.props.track.codec;\n if (!codec) {\n throw new Error(\n `Cannot start ${this.props.track.kind} playback before the track is attached to an RTCRtpSender`,\n );\n }\n\n const expectedMimeType = toSupportedMimeType(this.props.sourceCodec);\n const negotiatedMimeType = normalizeMimeType(codec.mimeType);\n if (negotiatedMimeType !== expectedMimeType) {\n throw new Error(\n `Input ${this.props.track.kind} codec ${expectedMimeType} does not match negotiated codec ${codec.mimeType}`,\n );\n }\n\n const expectedClockRate =\n this.props.track.kind === \"audio\" ? 48_000 : 90_000;\n if (codec.clockRate !== expectedClockRate) {\n throw new Error(\n `Input ${this.props.track.kind} clock rate ${expectedClockRate} does not match negotiated clock rate ${codec.clockRate}`,\n );\n }\n\n assertCodecParameters({\n trackKind: this.props.track.kind === \"audio\" ? \"audio\" : \"video\",\n codec,\n sourceCodec: this.props.sourceCodec,\n decoderDescription: this.props.decoderDescription,\n sourceChannels: this.props.sourceChannels,\n });\n\n return codec;\n }\n}\n\ninterface PlaybackTrack {\n inputTrack: InputTrack;\n track: MediaStreamTrack;\n sourceCodec: SupportedSourceCodec;\n decoderDescription?: ArrayBuffer | ArrayBufferView | null;\n sourceChannels?: number;\n}\n\ninterface PlaybackSession {\n input: Input;\n mediaStartTimestamp: number;\n playbackTracks: PlaybackTrack[];\n runners: TrackPlaybackRunner[];\n}\n\nasync function selectPlaybackTracks(\n input: Input,\n streamId: string,\n existingTracks: Partial<Record<\"audio\" | \"video\", MediaStreamTrack>> = {},\n) {\n const primaryVideoTrack = await input.getPrimaryVideoTrack();\n const primaryAudioTrack = primaryVideoTrack\n ? ((await primaryVideoTrack.getPrimaryPairableAudioTrack()) ??\n (await input.getPrimaryAudioTrack()))\n : await input.getPrimaryAudioTrack();\n\n const playbackTracks: PlaybackTrack[] = [];\n if (primaryAudioTrack) {\n playbackTracks.push(\n await createPlaybackTrack(\n primaryAudioTrack,\n streamId,\n existingTracks.audio,\n ),\n );\n }\n if (primaryVideoTrack) {\n playbackTracks.push(\n await createPlaybackTrack(\n primaryVideoTrack,\n streamId,\n existingTracks.video,\n ),\n );\n }\n\n if (!primaryVideoTrack && !primaryAudioTrack) {\n const fallbackAudioTrack = await input.getPrimaryAudioTrack();\n if (fallbackAudioTrack) {\n playbackTracks.push(\n await createPlaybackTrack(\n fallbackAudioTrack,\n streamId,\n existingTracks.audio,\n ),\n );\n }\n }\n\n return playbackTracks;\n}\n\nasync function createPlaybackTrack(\n inputTrack: InputAudioTrack | InputVideoTrack,\n streamId: string,\n track?: MediaStreamTrack,\n): Promise<PlaybackTrack> {\n const sourceCodec = await requireSupportedCodec(inputTrack);\n const decoderConfig = await inputTrack.getDecoderConfig();\n const kind = inputTrack.isAudioTrack() ? \"audio\" : \"video\";\n\n return {\n inputTrack,\n sourceCodec,\n decoderDescription:\n decoderConfig && \"description\" in decoderConfig\n ? (decoderConfig.description ?? null)\n : null,\n sourceChannels:\n decoderConfig && \"numberOfChannels\" in decoderConfig\n ? decoderConfig.numberOfChannels\n : undefined,\n track:\n track ??\n new MediaStreamTrack({\n kind,\n streamId,\n }),\n };\n}\n\nasync function requireSupportedCodec(inputTrack: InputTrack) {\n const codec = await inputTrack.getCodec();\n if (codec && supportedSourceCodecs.includes(codec as SupportedSourceCodec)) {\n return codec as SupportedSourceCodec;\n }\n\n const codecLabel =\n codec ??\n (await inputTrack.getCodecParameterString()) ??\n String((await inputTrack.getInternalCodecId()) ?? \"unknown\");\n\n throw new Error(\n `Unsupported ${inputTrack.type} codec \"${codecLabel}\". File playback supports H264, VP8, VP9, AV1, and Opus only.`,\n );\n}\n\ntype ReplayableUserMediaSource =\n | { path: string; buffer?: never }\n | { path?: never; buffer: Buffer };\n\nasync function createReplayableSource(\n options: UserMediaSource,\n): Promise<ReplayableUserMediaSource> {\n if (typeof options.path === \"string\") {\n return { path: options.path };\n }\n\n const buffer =\n options.buffer != undefined\n ? toBuffer(options.buffer)\n : await readStreamToBuffer(options.stream);\n\n return { buffer };\n}\n\nasync function createInput(options: ReplayableUserMediaSource) {\n if (typeof options.path === \"string\") {\n const buffer = await readFile(resolveUserMediaPath(options.path));\n return new Input({\n source: new BufferSource(buffer),\n formats: [MP4, WEBM],\n });\n }\n\n return new Input({\n source: new BufferSource(options.buffer),\n formats: [MP4, WEBM],\n });\n}\n\nfunction resolveUserMediaPath(path: string) {\n if (path === \"~\") {\n return homedir();\n }\n if (path.startsWith(\"~/\")) {\n return resolve(homedir(), path.slice(2));\n }\n return isAbsolute(path) ? path : resolve(path);\n}\n\nasync function readStreamToBuffer(\n stream: Readable | ReadableStream<Uint8Array>,\n) {\n const chunks: Buffer[] = [];\n\n if (stream instanceof Readable) {\n for await (const chunk of stream) {\n chunks.push(toBuffer(chunk));\n }\n return Buffer.concat(chunks);\n }\n\n const reader = stream.getReader();\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n if (value) {\n chunks.push(\n Buffer.from(value.buffer, value.byteOffset, value.byteLength),\n );\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n return Buffer.concat(chunks);\n}\n\nfunction toBuffer(value: Buffer | ArrayBuffer | ArrayBufferView | string) {\n if (Buffer.isBuffer(value)) {\n return value;\n }\n if (typeof value === \"string\") {\n return Buffer.from(value);\n }\n if (ArrayBuffer.isView(value)) {\n return Buffer.from(value.buffer, value.byteOffset, value.byteLength);\n }\n return Buffer.from(new Uint8Array(value));\n}\n\nfunction normalizeMimeType(mimeType: string) {\n return mimeType.toLowerCase();\n}\n\nfunction assertSupportedOptions(options: FileMediaTrackSource) {\n const legacyOptions = options as FileMediaTrackSource & {\n width?: unknown;\n height?: unknown;\n };\n\n if (legacyOptions.width != undefined || legacyOptions.height != undefined) {\n throw new Error(\n \"getUserMedia({ width, height }) is no longer supported for file playback. Resize or re-encode the source before calling getUserMedia().\",\n );\n }\n}\n\nfunction createPlaybackSession({\n input,\n mediaStartTimestamp,\n playbackTracks,\n}: {\n input: Input;\n mediaStartTimestamp: number;\n playbackTracks: PlaybackTrack[];\n}): PlaybackSession {\n return {\n input,\n mediaStartTimestamp,\n playbackTracks,\n runners: playbackTracks.map(\n (playbackTrack) =>\n new TrackPlaybackRunner({\n mediaStartTimestamp,\n ...playbackTrack,\n }),\n ),\n };\n}\n\nfunction buildExistingTrackMap(\n audio?: MediaStreamTrack,\n video?: MediaStreamTrack,\n): Partial<Record<\"audio\" | \"video\", MediaStreamTrack>> {\n return {\n ...(audio ? { audio } : {}),\n ...(video ? { video } : {}),\n };\n}\n\nfunction assertCodecParameters({\n trackKind,\n codec,\n sourceCodec,\n decoderDescription,\n sourceChannels,\n}: {\n trackKind: \"audio\" | \"video\";\n codec: RTCRtpCodecParameters;\n sourceCodec: SupportedSourceCodec;\n decoderDescription?: ArrayBuffer | ArrayBufferView | null;\n sourceChannels?: number;\n}) {\n if (sourceCodec === \"opus\" && sourceChannels && codec.channels != undefined) {\n if (codec.channels !== sourceChannels) {\n throw new Error(\n `Input ${trackKind} channels ${sourceChannels} do not match negotiated channels ${codec.channels}`,\n );\n }\n return;\n }\n\n if (sourceCodec !== \"avc\") {\n // mediabunny exposes codec-specific decoder configuration for H264 only here.\n return;\n }\n\n const negotiatedParameters = codecParametersFromString(\n codec.parameters ?? \"\",\n );\n const negotiatedPacketizationMode = Number(\n negotiatedParameters[\"packetization-mode\"] ?? 1,\n );\n if (negotiatedPacketizationMode !== 1) {\n throw new Error(\n `Input ${trackKind} packetization-mode 1 does not match negotiated packetization-mode ${negotiatedPacketizationMode}`,\n );\n }\n\n const sourceProfileLevelId = getH264ProfileLevelId(decoderDescription);\n const negotiatedProfileLevelId = normalizeOptionalHexParameter(\n negotiatedParameters[\"profile-level-id\"],\n );\n\n if (!sourceProfileLevelId) {\n return;\n }\n\n if (!negotiatedProfileLevelId) {\n throw new Error(\n `Input ${trackKind} profile-level-id ${sourceProfileLevelId} does not match negotiated profile-level-id <missing>`,\n );\n }\n\n if (sourceProfileLevelId !== negotiatedProfileLevelId) {\n throw new Error(\n `Input ${trackKind} profile-level-id ${sourceProfileLevelId} does not match negotiated profile-level-id ${negotiatedProfileLevelId}`,\n );\n }\n}\n\nfunction getH264ProfileLevelId(\n decoderDescription?: ArrayBuffer | ArrayBufferView | null,\n) {\n if (!decoderDescription) {\n return undefined;\n }\n\n const description = toDescriptionBuffer(decoderDescription);\n if (description.length < 4) {\n throw new Error(\"invalid H264 decoder configuration\");\n }\n\n return description.subarray(1, 4).toString(\"hex\");\n}\n\nfunction normalizeOptionalHexParameter(value: unknown) {\n return typeof value === \"string\" ? value.toLowerCase() : undefined;\n}\n\nfunction toRtpTimestamp(\n packetTimestamp: number,\n mediaStartTimestamp: number,\n clockRate: number,\n) {\n const relativeSeconds = Math.max(0, packetTimestamp - mediaStartTimestamp);\n return Math.round(relativeSeconds * clockRate) >>> 0;\n}\n\nfunction isAbortError(error: unknown) {\n return (\n error instanceof Error &&\n (error.name === \"AbortError\" ||\n error.message === \"The operation was aborted\")\n );\n}\n\nfunction toError(error: unknown) {\n return error instanceof Error ? error : new Error(String(error));\n}\n\nfunction toDescriptionBuffer(\n decoderDescription: ArrayBuffer | ArrayBufferView,\n) {\n if (ArrayBuffer.isView(decoderDescription)) {\n return Buffer.from(\n decoderDescription.buffer,\n decoderDescription.byteOffset,\n decoderDescription.byteLength,\n );\n }\n\n return Buffer.from(decoderDescription);\n}\n"]}
|
|
@@ -1,16 +1,41 @@
|
|
|
1
1
|
import type { RTCDataChannel } from "./dataChannel";
|
|
2
2
|
import { EventTarget } from "./helper";
|
|
3
|
-
import { type Address, Event, type InterfaceAddresses } from "./imports/common";
|
|
3
|
+
import { type Address, Event, type InterfaceAddresses, type TlsConnectionOptions } from "./imports/common";
|
|
4
4
|
import type { CandidatePair, Message, Protocol } from "./imports/ice";
|
|
5
5
|
import { type MediaStream, type MediaStreamTrack, type RTCRtpCodecParameters, type RTCRtpHeaderExtensionParameters, type RTCRtpReceiver, type RTCRtpSender, type RTCRtpTransceiver, type TransceiverOptions } from "./media";
|
|
6
|
-
import { RTCStatsReport } from "./media/stats";
|
|
7
|
-
import { type BundlePolicy, SessionDescription } from "./sdp";
|
|
6
|
+
import { type RTCStatsReport } from "./media/stats";
|
|
7
|
+
import { type BundlePolicy, type RTCSessionDescription, SessionDescription } from "./sdp";
|
|
8
8
|
import { type RTCSessionDescriptionInit } from "./sdpManager";
|
|
9
|
-
import type { DtlsKeys, RTCDtlsTransport } from "./transport/dtls";
|
|
9
|
+
import type { DtlsKeys, RTCCertificate, RTCDtlsTransport } from "./transport/dtls";
|
|
10
10
|
import type { RTCIceCandidate, RTCIceCandidateInit, RTCIceTransport } from "./transport/ice";
|
|
11
|
+
import { type RTCSctpTransport } from "./transport/sctp";
|
|
11
12
|
import type { Kind, RTCSignalingState } from "./types/domain";
|
|
12
13
|
import type { Callback, CallbackWithValue } from "./types/util";
|
|
14
|
+
/**
|
|
15
|
+
* W3C compatibility notes kept near the public RTCPeerConnection surface so the
|
|
16
|
+
* reviewable diff does not depend on external PR text.
|
|
17
|
+
*
|
|
18
|
+
* - `current/pending*Description`, `canTrickleIceCandidates`, `sctp`,
|
|
19
|
+
* `addIceCandidate(null)`, and `RTCConfiguration` round-trip behavior are
|
|
20
|
+
* implemented here and covered by `tests/wpt/peerConnectionApiCompatibility.test.ts`.
|
|
21
|
+
* - `addIceCandidate()` also validates `sdpMid` / `sdpMLineIndex` /
|
|
22
|
+
* `usernameFragment` against the applied remote description and appends
|
|
23
|
+
* candidates or end-of-candidates markers to the corresponding m-section.
|
|
24
|
+
* The public API keeps werift's historical pre-SRD buffering behavior, while
|
|
25
|
+
* the WPT runner wraps the class to exercise strict spec rejection.
|
|
26
|
+
* - `bundlePolicy: "balanced"` is accepted for input compatibility but is
|
|
27
|
+
* normalized to werift's `"max-compat"` behavior, so `getConfiguration()`
|
|
28
|
+
* returns the normalized value.
|
|
29
|
+
* - `setLocalDescription()` keeps the historical `SessionDescription` return
|
|
30
|
+
* value for non-rollback calls, while `{ type: "rollback" }` resolves `void`
|
|
31
|
+
* to match the actual behavior without pretending to return a description.
|
|
32
|
+
* - API reference markdown is regenerated with `cd packages/webrtc && npm run doc`.
|
|
33
|
+
* The generated output lives under `packages/webrtc/doc/`; compatibility
|
|
34
|
+
* notes remain here and in the package README so review context is visible
|
|
35
|
+
* even when generated docs are not committed in the same change.
|
|
36
|
+
*/
|
|
13
37
|
export declare class RTCPeerConnection extends EventTarget {
|
|
38
|
+
readonly id: string;
|
|
14
39
|
readonly cname: string;
|
|
15
40
|
config: Required<PeerConfig>;
|
|
16
41
|
signalingState: RTCSignalingState;
|
|
@@ -23,41 +48,59 @@ export declare class RTCPeerConnection extends EventTarget {
|
|
|
23
48
|
private readonly secureManager;
|
|
24
49
|
private isClosed;
|
|
25
50
|
private shouldNegotiationneeded;
|
|
26
|
-
private
|
|
51
|
+
private lastCreatedAnswer?;
|
|
52
|
+
private lastCreatedOffer?;
|
|
53
|
+
private readonly pendingRemoteCandidates;
|
|
27
54
|
readonly iceGatheringStateChange: Event<["complete" | "new" | "gathering"]>;
|
|
28
|
-
readonly iceConnectionStateChange: Event<["
|
|
55
|
+
readonly iceConnectionStateChange: Event<["closed" | "disconnected" | "completed" | "new" | "connected" | "failed" | "checking"]>;
|
|
29
56
|
readonly signalingStateChange: Event<["closed" | "stable" | "have-local-offer" | "have-remote-offer" | "have-local-pranswer" | "have-remote-pranswer"]>;
|
|
30
|
-
readonly connectionStateChange: Event<["
|
|
57
|
+
readonly connectionStateChange: Event<["closed" | "disconnected" | "new" | "connected" | "connecting" | "failed"]>;
|
|
31
58
|
readonly onDataChannel: Event<[RTCDataChannel]>;
|
|
32
59
|
readonly onRemoteTransceiverAdded: Event<[RTCRtpTransceiver]>;
|
|
33
60
|
readonly onTransceiverAdded: Event<[RTCRtpTransceiver]>;
|
|
34
61
|
readonly onIceCandidate: Event<[RTCIceCandidate | undefined]>;
|
|
35
62
|
readonly onNegotiationneeded: Event<[]>;
|
|
36
63
|
readonly onTrack: Event<[MediaStreamTrack]>;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
get
|
|
64
|
+
private readonly eventHandlers;
|
|
65
|
+
get ondatachannel(): CallbackWithValue<RTCDataChannelEvent> | null;
|
|
66
|
+
set ondatachannel(value: CallbackWithValue<RTCDataChannelEvent> | null);
|
|
67
|
+
get onicecandidate(): CallbackWithValue<RTCPeerConnectionIceEvent> | null;
|
|
68
|
+
set onicecandidate(value: CallbackWithValue<RTCPeerConnectionIceEvent> | null);
|
|
69
|
+
get onicecandidateerror(): CallbackWithValue<any> | null;
|
|
70
|
+
set onicecandidateerror(value: CallbackWithValue<any> | null);
|
|
71
|
+
get onicegatheringstatechange(): CallbackWithValue<any> | null;
|
|
72
|
+
set onicegatheringstatechange(value: CallbackWithValue<any> | null);
|
|
73
|
+
get onnegotiationneeded(): CallbackWithValue<any> | null;
|
|
74
|
+
set onnegotiationneeded(value: CallbackWithValue<any> | null);
|
|
75
|
+
get onsignalingstatechange(): CallbackWithValue<any> | null;
|
|
76
|
+
set onsignalingstatechange(value: CallbackWithValue<any> | null);
|
|
77
|
+
get ontrack(): CallbackWithValue<RTCTrackEvent> | null;
|
|
78
|
+
set ontrack(value: CallbackWithValue<RTCTrackEvent> | null);
|
|
79
|
+
get onconnectionstatechange(): Callback | null;
|
|
80
|
+
set onconnectionstatechange(value: Callback | null);
|
|
81
|
+
get oniceconnectionstatechange(): Callback | null;
|
|
82
|
+
set oniceconnectionstatechange(value: Callback | null);
|
|
83
|
+
constructor(config?: RTCPeerConnectionConfig);
|
|
84
|
+
get connectionState(): "closed" | "disconnected" | "new" | "connected" | "connecting" | "failed";
|
|
85
|
+
get iceConnectionState(): "closed" | "disconnected" | "completed" | "new" | "connected" | "failed" | "checking";
|
|
49
86
|
get iceGathererState(): "complete" | "new" | "gathering";
|
|
50
87
|
get iceGatheringState(): "complete" | "new" | "gathering";
|
|
51
88
|
get dtlsTransports(): RTCDtlsTransport[];
|
|
52
|
-
get sctpTransport():
|
|
89
|
+
get sctpTransport(): RTCSctpTransport | undefined;
|
|
90
|
+
get sctp(): RTCSctpTransport | null;
|
|
53
91
|
get sctpRemotePort(): number | undefined;
|
|
54
92
|
get iceTransports(): RTCIceTransport[];
|
|
55
93
|
get extIdUriMap(): {
|
|
56
94
|
[id: number]: string;
|
|
57
95
|
};
|
|
58
96
|
get iceGeneration(): number;
|
|
59
|
-
get localDescription():
|
|
60
|
-
get
|
|
97
|
+
get localDescription(): RTCSessionDescription | null;
|
|
98
|
+
get currentLocalDescription(): RTCSessionDescription | null;
|
|
99
|
+
get pendingLocalDescription(): RTCSessionDescription | null;
|
|
100
|
+
get remoteDescription(): RTCSessionDescription | null;
|
|
101
|
+
get currentRemoteDescription(): RTCSessionDescription | null;
|
|
102
|
+
get pendingRemoteDescription(): RTCSessionDescription | null;
|
|
103
|
+
get canTrickleIceCandidates(): boolean | null;
|
|
61
104
|
get remoteIsBundled(): import("./sdp").GroupDescription | undefined;
|
|
62
105
|
/**@private */
|
|
63
106
|
get _localDescription(): SessionDescription | undefined;
|
|
@@ -66,11 +109,62 @@ export declare class RTCPeerConnection extends EventTarget {
|
|
|
66
109
|
getTransceivers(): RTCRtpTransceiver[];
|
|
67
110
|
getSenders(): RTCRtpSender[];
|
|
68
111
|
getReceivers(): RTCRtpReceiver[];
|
|
69
|
-
setConfiguration(config:
|
|
70
|
-
getConfiguration():
|
|
112
|
+
setConfiguration(config: RTCPeerConnectionConfig): void;
|
|
113
|
+
getConfiguration(): {
|
|
114
|
+
codecs: {
|
|
115
|
+
audio: RTCRtpCodecParameters[] | undefined;
|
|
116
|
+
video: RTCRtpCodecParameters[] | undefined;
|
|
117
|
+
};
|
|
118
|
+
headerExtensions: {
|
|
119
|
+
audio: RTCRtpHeaderExtensionParameters[] | undefined;
|
|
120
|
+
video: RTCRtpHeaderExtensionParameters[] | undefined;
|
|
121
|
+
};
|
|
122
|
+
iceServers: {
|
|
123
|
+
urls: string | string[];
|
|
124
|
+
username?: string;
|
|
125
|
+
credential?: string;
|
|
126
|
+
}[];
|
|
127
|
+
icePortRange: [number, number] | undefined;
|
|
128
|
+
iceAdditionalHostAddresses: string[] | undefined;
|
|
129
|
+
dtls: {
|
|
130
|
+
keys?: DtlsKeys | undefined;
|
|
131
|
+
};
|
|
132
|
+
certificates: RTCCertificate[];
|
|
133
|
+
debug: {
|
|
134
|
+
inboundPacketLoss?: number | undefined;
|
|
135
|
+
outboundPacketLoss?: number | undefined;
|
|
136
|
+
receiverReportDelay?: number | undefined;
|
|
137
|
+
disableSendNack?: boolean | undefined;
|
|
138
|
+
disableRecvRetransmit?: boolean | undefined;
|
|
139
|
+
};
|
|
140
|
+
iceTransportPolicy: "all" | "relay";
|
|
141
|
+
/** Advertise local ICE lite and operate in the controlled role. */
|
|
142
|
+
iceLite: boolean;
|
|
143
|
+
iceInterfaceAddresses: InterfaceAddresses | undefined;
|
|
144
|
+
iceUseIpv4: boolean;
|
|
145
|
+
iceUseIpv6: boolean;
|
|
146
|
+
iceUseTcp: boolean;
|
|
147
|
+
turnTransport: "udp" | "tcp" | "tls" | undefined;
|
|
148
|
+
turnTlsOptions: TlsConnectionOptions | undefined;
|
|
149
|
+
/** @deprecated Prefer turn URL transport parameters or turnTransport. */
|
|
150
|
+
forceTurnTCP: boolean;
|
|
151
|
+
/** such as google cloud run */
|
|
152
|
+
iceUseLinkLocalAddress: boolean | undefined;
|
|
153
|
+
/** If provided, is called on each STUN request.
|
|
154
|
+
* Return `true` if a STUN response should be sent, false if it should be skipped. */
|
|
155
|
+
iceFilterStunResponse: ((message: Message, addr: Address, protocol: Protocol) => boolean) | undefined;
|
|
156
|
+
iceFilterCandidatePair: ((pair: CandidatePair) => boolean) | undefined;
|
|
157
|
+
icePasswordPrefix: string | undefined;
|
|
158
|
+
bundlePolicy: BundlePolicy;
|
|
159
|
+
rtcpMuxPolicy: "require";
|
|
160
|
+
iceCandidatePoolSize: number;
|
|
161
|
+
midSuffix: boolean;
|
|
162
|
+
/** Advertised local SCTP max-message-size in SDP. Use 0 for unlimited. */
|
|
163
|
+
maxMessageSize: number;
|
|
164
|
+
};
|
|
71
165
|
createOffer({ iceRestart }?: {
|
|
72
166
|
iceRestart?: boolean;
|
|
73
|
-
}): Promise<
|
|
167
|
+
}): Promise<RTCSessionDescription>;
|
|
74
168
|
private createSctpTransport;
|
|
75
169
|
createDataChannel(label: string, options?: Partial<{
|
|
76
170
|
maxPacketLifeTime?: number;
|
|
@@ -82,27 +176,39 @@ export declare class RTCPeerConnection extends EventTarget {
|
|
|
82
176
|
}>): RTCDataChannel;
|
|
83
177
|
removeTrack(sender: RTCRtpSender): void;
|
|
84
178
|
private needNegotiation;
|
|
179
|
+
private invalidateLastCreatedDescriptions;
|
|
180
|
+
private waitForPendingDescriptionTask;
|
|
85
181
|
private findOrCreateTransport;
|
|
86
|
-
setLocalDescription(sessionDescription
|
|
87
|
-
type: "
|
|
88
|
-
|
|
89
|
-
|
|
182
|
+
setLocalDescription(sessionDescription: {
|
|
183
|
+
type: "rollback";
|
|
184
|
+
}): Promise<void>;
|
|
185
|
+
setLocalDescription(sessionDescription?: RTCLocalSessionDescriptionInit): Promise<SessionDescription>;
|
|
90
186
|
private gatherCandidates;
|
|
91
|
-
addIceCandidate(candidateMessage
|
|
187
|
+
addIceCandidate(candidateMessage?: RTCIceCandidate | RTCIceCandidateInit | null): Promise<void>;
|
|
188
|
+
private applyRemoteIceCandidate;
|
|
189
|
+
private flushPendingRemoteCandidates;
|
|
92
190
|
private connect;
|
|
93
191
|
restartIce(): void;
|
|
94
192
|
setRemoteDescription(sessionDescription: RTCSessionDescriptionInit): Promise<void>;
|
|
95
193
|
addTransceiver(trackOrKind: Kind | MediaStreamTrack, options?: Partial<TransceiverOptions>): RTCRtpTransceiver;
|
|
96
|
-
addTrack(track: MediaStreamTrack,
|
|
97
|
-
|
|
98
|
-
ms?: MediaStream): RTCRtpSender;
|
|
99
|
-
createAnswer(): Promise<import("./sdp").RTCSessionDescription>;
|
|
194
|
+
addTrack(track: MediaStreamTrack, ...streams: MediaStream[]): RTCRtpSender;
|
|
195
|
+
createAnswer(): Promise<RTCSessionDescription>;
|
|
100
196
|
private assertNotClosed;
|
|
101
197
|
private setSignalingState;
|
|
102
198
|
private createPeerConnectionStats;
|
|
103
199
|
getStats(selector?: MediaStreamTrack | null): Promise<RTCStatsReport>;
|
|
104
200
|
close(): Promise<void>;
|
|
105
201
|
}
|
|
202
|
+
export type DebugConfig = Partial<{
|
|
203
|
+
/**% */
|
|
204
|
+
inboundPacketLoss: number;
|
|
205
|
+
/**% */
|
|
206
|
+
outboundPacketLoss: number;
|
|
207
|
+
/**ms */
|
|
208
|
+
receiverReportDelay: number;
|
|
209
|
+
disableSendNack: boolean;
|
|
210
|
+
disableRecvRetransmit: boolean;
|
|
211
|
+
}>;
|
|
106
212
|
export interface PeerConfig {
|
|
107
213
|
codecs: Partial<{
|
|
108
214
|
/**
|
|
@@ -117,6 +223,8 @@ export interface PeerConfig {
|
|
|
117
223
|
video: RTCRtpHeaderExtensionParameters[];
|
|
118
224
|
}>;
|
|
119
225
|
iceTransportPolicy: "all" | "relay";
|
|
226
|
+
/** Advertise local ICE lite and operate in the controlled role. */
|
|
227
|
+
iceLite: boolean;
|
|
120
228
|
iceServers: RTCIceServer[];
|
|
121
229
|
/**Minimum port and Maximum port must not be the same value */
|
|
122
230
|
icePortRange: [number, number] | undefined;
|
|
@@ -127,6 +235,10 @@ export interface PeerConfig {
|
|
|
127
235
|
iceAdditionalHostAddresses: string[] | undefined;
|
|
128
236
|
iceUseIpv4: boolean;
|
|
129
237
|
iceUseIpv6: boolean;
|
|
238
|
+
iceUseTcp: boolean;
|
|
239
|
+
turnTransport: "udp" | "tcp" | "tls" | undefined;
|
|
240
|
+
turnTlsOptions: TlsConnectionOptions | undefined;
|
|
241
|
+
/** @deprecated Prefer turn URL transport parameters or turnTransport. */
|
|
130
242
|
forceTurnTCP: boolean;
|
|
131
243
|
/** such as google cloud run */
|
|
132
244
|
iceUseLinkLocalAddress: boolean | undefined;
|
|
@@ -139,36 +251,57 @@ export interface PeerConfig {
|
|
|
139
251
|
}>;
|
|
140
252
|
icePasswordPrefix: string | undefined;
|
|
141
253
|
bundlePolicy: BundlePolicy;
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
outboundPacketLoss: number;
|
|
147
|
-
/**ms */
|
|
148
|
-
receiverReportDelay: number;
|
|
149
|
-
disableSendNack: boolean;
|
|
150
|
-
disableRecvRetransmit: boolean;
|
|
151
|
-
}>;
|
|
254
|
+
rtcpMuxPolicy: "require";
|
|
255
|
+
iceCandidatePoolSize: number;
|
|
256
|
+
certificates: RTCCertificate[];
|
|
257
|
+
debug: DebugConfig;
|
|
152
258
|
midSuffix: boolean;
|
|
153
259
|
/** Advertised local SCTP max-message-size in SDP. Use 0 for unlimited. */
|
|
154
260
|
maxMessageSize: number;
|
|
155
261
|
}
|
|
156
262
|
export declare const findCodecByMimeType: (codecs: RTCRtpCodecParameters[], target: RTCRtpCodecParameters) => RTCRtpCodecParameters | undefined;
|
|
157
263
|
export type RTCIceServer = {
|
|
158
|
-
urls: string;
|
|
264
|
+
urls: string | string[];
|
|
159
265
|
username?: string;
|
|
160
266
|
credential?: string;
|
|
161
267
|
};
|
|
268
|
+
export type RTCBundlePolicy = "balanced" | "max-compat" | "max-bundle";
|
|
269
|
+
export type RTCRtcpMuxPolicy = "require";
|
|
270
|
+
export interface RTCConfiguration {
|
|
271
|
+
iceServers?: RTCIceServer[];
|
|
272
|
+
iceTransportPolicy?: PeerConfig["iceTransportPolicy"];
|
|
273
|
+
bundlePolicy?: RTCBundlePolicy;
|
|
274
|
+
rtcpMuxPolicy?: RTCRtcpMuxPolicy;
|
|
275
|
+
iceCandidatePoolSize?: number;
|
|
276
|
+
certificates?: RTCCertificate[];
|
|
277
|
+
}
|
|
278
|
+
export interface RTCLocalSessionDescriptionInit extends RTCSessionDescriptionInit {
|
|
279
|
+
type?: Exclude<RTCSessionDescriptionInit["type"], "rollback"> | "rollback";
|
|
280
|
+
}
|
|
281
|
+
type RTCPeerConnectionRTCConfiguration = Omit<RTCConfiguration, "bundlePolicy"> & {
|
|
282
|
+
bundlePolicy?: PeerConfig["bundlePolicy"] | RTCBundlePolicy;
|
|
283
|
+
};
|
|
284
|
+
export type RTCPeerConnectionConfig = Partial<Omit<PeerConfig, "bundlePolicy" | "rtcpMuxPolicy" | "iceCandidatePoolSize" | "certificates">> & RTCPeerConnectionRTCConfiguration;
|
|
162
285
|
export declare const defaultPeerConfig: PeerConfig;
|
|
163
|
-
export
|
|
164
|
-
track
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
286
|
+
export declare class RTCTrackEvent {
|
|
287
|
+
readonly type = "track";
|
|
288
|
+
readonly track: MediaStreamTrack;
|
|
289
|
+
readonly streams: MediaStream[];
|
|
290
|
+
readonly transceiver: RTCRtpTransceiver;
|
|
291
|
+
readonly receiver: RTCRtpReceiver;
|
|
292
|
+
constructor(init: {
|
|
293
|
+
track: MediaStreamTrack;
|
|
294
|
+
streams: MediaStream[];
|
|
295
|
+
transceiver: RTCRtpTransceiver;
|
|
296
|
+
receiver: RTCRtpReceiver;
|
|
297
|
+
});
|
|
168
298
|
}
|
|
169
299
|
export interface RTCDataChannelEvent {
|
|
300
|
+
type?: "datachannel";
|
|
170
301
|
channel: RTCDataChannel;
|
|
171
302
|
}
|
|
172
303
|
export interface RTCPeerConnectionIceEvent {
|
|
304
|
+
type?: "icecandidate";
|
|
173
305
|
candidate?: RTCIceCandidate;
|
|
174
306
|
}
|
|
307
|
+
export {};
|