@openclaw/matrix 2026.7.1-beta.1 → 2026.7.1-beta.4
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/dist/{account-selection-Bv_ZuOu4.js → account-selection-5e4mHR1m.js} +1 -1
- package/dist/api.js +5 -5
- package/dist/{approval-handler.runtime-GpL8SxX2.js → approval-handler.runtime-DI5x9r8I.js} +5 -5
- package/dist/{approval-ids-DIKCZewR.js → approval-ids-ZgqbspmS.js} +1 -1
- package/dist/{approval-reaction-auth-DhBxqiQQ.js → approval-reaction-auth-D9LijQhr.js} +2 -2
- package/dist/{approval-reactions-BRGQgOu2.js → approval-reactions-BdUaUXVw.js} +24 -73
- package/dist/auth-presence.js +1 -1
- package/dist/{channel-CGc6D4tf.js → channel-jUTBsjHU.js} +21 -23
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-CPu_uwsn.js → channel.runtime-DO1Nv9ed.js} +26 -17
- package/dist/{cli-BfwYmyEc.js → cli-CEfWwCKx.js} +10 -17
- package/dist/{cli-metadata-FO-fJqf0.js → cli-metadata-CfiEO-CE.js} +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/{client-CVluBRDh.js → client-FRuyCNju.js} +2 -2
- package/dist/{client-bootstrap-1cbA9aSs.js → client-bootstrap-DjFJ7e0N.js} +6 -10
- package/dist/{client-Cb5ILtpE.js → client-tgnlQJk4.js} +2 -2
- package/dist/{config-schema-DFRmUTAG.js → config-schema-DtnhNYd-.js} +1 -1
- package/dist/contract-api.js +2 -2
- package/dist/{create-client-8YNurIAr.js → create-client-CNakT7zF.js} +7 -10
- package/dist/{credentials-G8lNmiME.js → credentials-Ds9V1mn2.js} +1 -1
- package/dist/{credentials-read-TzTOQPOM.js → credentials-read-BlkvsNFg.js} +1 -1
- package/dist/{credentials-write.runtime-cZhhyGAZ.js → credentials-write.runtime-CTqqxcut.js} +2 -5
- package/dist/{crypto-runtime-hMMmqNr1.js → crypto-runtime-B74cTS6A.js} +11 -9
- package/dist/{crypto-state-store-DK2tcEyP.js → crypto-state-store-Jy3qwhdy.js} +1 -1
- package/dist/{deps-D3bkh48_.js → deps-CdjHvnmh.js} +20 -2
- package/dist/{directory-live-pjbvjDz2.js → directory-live-Ufd4qSpX.js} +2 -2
- package/dist/{doctor-BRSDNU5C.js → doctor-DfaOqFtr.js} +3 -3
- package/dist/{doctor-contract-Dq8OZWHF.js → doctor-contract-BAja_fmb.js} +1 -1
- package/dist/doctor-contract-api.js +8 -14
- package/dist/{draft-stream-Djasj65z.js → draft-stream-D4EH25gv.js} +1 -1
- package/dist/{encryption-guidance-Bg3IRYoX.js → encryption-guidance-D8walY04.js} +1 -1
- package/dist/{file-sync-store-BWLVB01Y.js → file-sync-store-DVm0ACml.js} +3 -3
- package/dist/helper-api.js +1 -1
- package/dist/{idb-persistence-BGY1CJ7J.js → idb-persistence-BHm97th-.js} +1 -1
- package/dist/index.js +3 -6
- package/dist/{legacy-crypto-inspector-D_8iylBq.js → legacy-crypto-inspector-vzXSkm18.js} +1 -1
- package/dist/{legacy-crypto-restore-B0gcIEkE.js → legacy-crypto-restore-CIBfOmLn.js} +2 -2
- package/dist/{matrix-migration.runtime-Ctlb_rZl.js → matrix-migration.runtime-BMCyrANT.js} +3 -3
- package/dist/{media-text-CUFW_BP5.js → media-text-p-LP21qs.js} +1 -1
- package/dist/{messages-C1dIZHKy.js → messages-DRKkiEY-.js} +6 -5
- package/dist/{monitor-BMGnvIbg.js → monitor-CsGOGdwu.js} +89 -119
- package/dist/plugin-entry.handlers.runtime.js +2 -5
- package/dist/probe.runtime-2MZLc6ng.js +3 -0
- package/dist/{profile-update-BaEk4COs.js → profile-update-Ucc8RrJL.js} +2 -2
- package/dist/{reaction-events-n69MjKzG.js → reaction-events-DentrVii.js} +5 -12
- package/dist/{recovery-key-store-BGk8c_gf.js → recovery-key-store-DSeLFvNx.js} +1 -1
- package/dist/{resolve-targets-DyGW9WzC.js → resolve-targets-DcV_KfgX.js} +1 -1
- package/dist/{resolver.runtime-DhZV369r.js → resolver.runtime-Hr6bO5zl.js} +1 -1
- package/dist/runtime-api.js +2 -2
- package/dist/runtime-heavy-api.js +1 -1
- package/dist/{sdk-DOxaiBRE.js → sdk-AZYVl34z.js} +12 -13
- package/dist/{send-C0NwpZ-c.js → send-D92v6Yy0.js} +22 -12
- package/dist/session-binding-contract-api.js +1 -1
- package/dist/{setup-bootstrap-DbWPVINS.js → setup-bootstrap-Da564w5f.js} +2 -2
- package/dist/{setup-core-DVkrIoax.js → setup-core-BGgbrdaJ.js} +5 -8
- package/dist/setup-plugin-api.js +3 -3
- package/dist/{setup-surface-CN7DEvpg.js → setup-surface-iJ6pd-t5.js} +6 -6
- package/dist/{shared-iLI-9tb9.js → shared-DkFfq7mH.js} +16 -32
- package/dist/{startup-verification-Bd31KqLv.js → startup-verification-BKMAXvcV.js} +2 -2
- package/dist/{storage-t5S-5c_5.js → storage-CQdyKcGg.js} +5 -5
- package/dist/subagent-hooks-api.js +2 -5
- package/dist/{thread-bindings-D73QFTXW.js → thread-bindings-BX5nmWpw.js} +3 -3
- package/dist/{tool-actions.runtime-BCCPq_aO.js → tool-actions.runtime-C1d5fxE_.js} +12 -12
- package/dist/{verification-C0KvXyHK.js → verification-BGCMiO1p.js} +2 -2
- package/node_modules/@babel/runtime/package.json +468 -1089
- package/node_modules/@matrix-org/matrix-sdk-crypto-nodejs/.cargo/config.toml +2 -0
- package/node_modules/@matrix-org/matrix-sdk-crypto-nodejs/CHANGELOG.md +12 -3
- package/node_modules/@matrix-org/matrix-sdk-crypto-nodejs/README.md +17 -0
- package/node_modules/@matrix-org/matrix-sdk-crypto-nodejs/download-lib.js +10 -2
- package/node_modules/@matrix-org/matrix-sdk-crypto-nodejs/package.json +1 -1
- package/node_modules/@matrix-org/matrix-sdk-crypto-nodejs/xtask/.idea/modules.xml +8 -0
- package/node_modules/@matrix-org/matrix-sdk-crypto-nodejs/xtask/.idea/vcs.xml +6 -0
- package/node_modules/@matrix-org/matrix-sdk-crypto-nodejs/xtask/.idea/xtask.iml +11 -0
- package/node_modules/@matrix-org/matrix-sdk-crypto-wasm/package.json +1 -1
- package/node_modules/@matrix-org/matrix-sdk-crypto-wasm/pkg/matrix_sdk_crypto_wasm_bg.cjs +28 -28
- package/node_modules/@matrix-org/matrix-sdk-crypto-wasm/pkg/matrix_sdk_crypto_wasm_bg.js +24 -24
- package/node_modules/@matrix-org/matrix-sdk-crypto-wasm/pkg/matrix_sdk_crypto_wasm_bg.wasm +0 -0
- package/node_modules/@matrix-org/matrix-sdk-crypto-wasm/pkg/matrix_sdk_crypto_wasm_bg.wasm.d.ts +58 -58
- package/node_modules/content-type/README.md +32 -57
- package/node_modules/content-type/dist/index.d.ts +26 -0
- package/node_modules/content-type/dist/index.js +170 -0
- package/node_modules/content-type/dist/index.js.map +1 -0
- package/node_modules/content-type/package.json +35 -25
- package/node_modules/linkify-it/README.md +3 -4
- package/node_modules/linkify-it/build/index.cjs.js +44 -41
- package/node_modules/linkify-it/index.mjs +10 -11
- package/node_modules/linkify-it/lib/re.mjs +34 -30
- package/node_modules/linkify-it/package.json +10 -15
- package/node_modules/markdown-it/dist/index.cjs.js +3652 -5378
- package/node_modules/markdown-it/dist/index.cjs.js.map +1 -0
- package/node_modules/markdown-it/dist/markdown-it.js +1399 -4479
- package/node_modules/markdown-it/dist/markdown-it.js.map +1 -0
- package/node_modules/markdown-it/dist/markdown-it.min.js +3 -2
- package/node_modules/markdown-it/dist/markdown-it.min.js.map +1 -0
- package/node_modules/markdown-it/lib/common/html_re.mjs +9 -9
- package/node_modules/markdown-it/lib/common/utils.mjs +2 -11
- package/node_modules/markdown-it/lib/parser_block.mjs +9 -9
- package/node_modules/markdown-it/lib/parser_core.mjs +7 -7
- package/node_modules/markdown-it/lib/parser_inline.mjs +16 -16
- package/node_modules/markdown-it/lib/renderer.mjs +2 -2
- package/node_modules/markdown-it/lib/rules_block/blockquote.mjs +6 -6
- package/node_modules/markdown-it/lib/rules_block/code.mjs +2 -2
- package/node_modules/markdown-it/lib/rules_block/fence.mjs +4 -4
- package/node_modules/markdown-it/lib/rules_block/heading.mjs +7 -7
- package/node_modules/markdown-it/lib/rules_block/hr.mjs +2 -2
- package/node_modules/markdown-it/lib/rules_block/html_block.mjs +6 -6
- package/node_modules/markdown-it/lib/rules_block/lheading.mjs +8 -8
- package/node_modules/markdown-it/lib/rules_block/list.mjs +6 -6
- package/node_modules/markdown-it/lib/rules_block/paragraph.mjs +5 -5
- package/node_modules/markdown-it/lib/rules_block/reference.mjs +1 -1
- package/node_modules/markdown-it/lib/rules_block/state_block.mjs +6 -6
- package/node_modules/markdown-it/lib/rules_block/table.mjs +4 -4
- package/node_modules/markdown-it/lib/rules_core/block.mjs +3 -3
- package/node_modules/markdown-it/lib/rules_core/linkify.mjs +15 -15
- package/node_modules/markdown-it/lib/rules_core/normalize.mjs +2 -2
- package/node_modules/markdown-it/lib/rules_inline/autolink.mjs +17 -17
- package/node_modules/markdown-it/lib/rules_inline/balance_pairs.mjs +2 -2
- package/node_modules/markdown-it/lib/rules_inline/emphasis.mjs +8 -8
- package/node_modules/markdown-it/lib/rules_inline/entity.mjs +7 -7
- package/node_modules/markdown-it/lib/rules_inline/escape.mjs +15 -1
- package/node_modules/markdown-it/lib/rules_inline/html_inline.mjs +1 -1
- package/node_modules/markdown-it/lib/rules_inline/link.mjs +1 -1
- package/node_modules/markdown-it/lib/rules_inline/state_inline.mjs +2 -2
- package/node_modules/markdown-it/lib/rules_inline/strikethrough.mjs +10 -10
- package/node_modules/markdown-it/lib/token.mjs +12 -12
- package/node_modules/markdown-it/package.json +25 -34
- package/node_modules/matrix-js-sdk/CHANGELOG.md +24 -0
- package/node_modules/matrix-js-sdk/README.md +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/AESEncryptedSecretStoragePayload.js +3 -1
- package/node_modules/matrix-js-sdk/lib/@types/IIdentityServerProvider.js +3 -1
- package/node_modules/matrix-js-sdk/lib/@types/PushRules.js +7 -7
- package/node_modules/matrix-js-sdk/lib/@types/PushRules.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/auth.js +4 -4
- package/node_modules/matrix-js-sdk/lib/@types/auth.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/beacon.js +2 -2
- package/node_modules/matrix-js-sdk/lib/@types/beacon.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/common.js +3 -1
- package/node_modules/matrix-js-sdk/lib/@types/crypto.js +3 -1
- package/node_modules/matrix-js-sdk/lib/@types/event.d.ts +6 -1
- package/node_modules/matrix-js-sdk/lib/@types/event.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/event.js +23 -20
- package/node_modules/matrix-js-sdk/lib/@types/event.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/events.js +3 -1
- package/node_modules/matrix-js-sdk/lib/@types/extensible_events.js +6 -6
- package/node_modules/matrix-js-sdk/lib/@types/extensible_events.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/global.d.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/json.js +3 -1
- package/node_modules/matrix-js-sdk/lib/@types/local_notifications.js +3 -1
- package/node_modules/matrix-js-sdk/lib/@types/location.js +4 -4
- package/node_modules/matrix-js-sdk/lib/@types/location.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/matrix-sdk-crypto-wasm.d.js +3 -1
- package/node_modules/matrix-js-sdk/lib/@types/media.js +3 -1
- package/node_modules/matrix-js-sdk/lib/@types/membership.js +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/membership.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/partials.js +6 -6
- package/node_modules/matrix-js-sdk/lib/@types/partials.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/polls.js +5 -5
- package/node_modules/matrix-js-sdk/lib/@types/polls.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/read_receipts.js +2 -2
- package/node_modules/matrix-js-sdk/lib/@types/read_receipts.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/registration.js +3 -1
- package/node_modules/matrix-js-sdk/lib/@types/requests.js +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/requests.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/retention.d.ts +15 -0
- package/node_modules/matrix-js-sdk/lib/@types/retention.d.ts.map +1 -0
- package/node_modules/matrix-js-sdk/lib/@types/retention.js +13 -0
- package/node_modules/matrix-js-sdk/lib/@types/retention.js.map +1 -0
- package/node_modules/matrix-js-sdk/lib/@types/search.js +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/search.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/signed.js +3 -1
- package/node_modules/matrix-js-sdk/lib/@types/spaces.js +3 -1
- package/node_modules/matrix-js-sdk/lib/@types/state_events.js +3 -1
- package/node_modules/matrix-js-sdk/lib/@types/synapse.js +3 -1
- package/node_modules/matrix-js-sdk/lib/@types/sync.js +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/sync.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/threepids.js +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/threepids.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/topic.js +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/topic.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/@types/uia.js +3 -1
- package/node_modules/matrix-js-sdk/lib/NamespacedValue.js +8 -8
- package/node_modules/matrix-js-sdk/lib/NamespacedValue.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/ReEmitter.js +8 -15
- package/node_modules/matrix-js-sdk/lib/ReEmitter.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/ToDeviceMessageQueue.js +47 -55
- package/node_modules/matrix-js-sdk/lib/ToDeviceMessageQueue.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/autodiscovery.js +233 -247
- package/node_modules/matrix-js-sdk/lib/autodiscovery.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/base64.js +1 -1
- package/node_modules/matrix-js-sdk/lib/base64.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/browser-index.d.ts +2 -2
- package/node_modules/matrix-js-sdk/lib/browser-index.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/browser-index.js +5 -5
- package/node_modules/matrix-js-sdk/lib/browser-index.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/capabilityPoller.d.ts +38 -0
- package/node_modules/matrix-js-sdk/lib/capabilityPoller.d.ts.map +1 -0
- package/node_modules/matrix-js-sdk/lib/capabilityPoller.js +93 -0
- package/node_modules/matrix-js-sdk/lib/capabilityPoller.js.map +1 -0
- package/node_modules/matrix-js-sdk/lib/client.d.ts +9 -8
- package/node_modules/matrix-js-sdk/lib/client.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/client.js +2123 -2483
- package/node_modules/matrix-js-sdk/lib/client.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/common-crypto/CryptoBackend.js +3 -1
- package/node_modules/matrix-js-sdk/lib/common-crypto/CryptoBackend.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/common-crypto/key-passphrase.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/content-helpers.js +43 -48
- package/node_modules/matrix-js-sdk/lib/content-helpers.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/content-repo.js +14 -24
- package/node_modules/matrix-js-sdk/lib/content-repo.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/crypto/store/base.js +6 -6
- package/node_modules/matrix-js-sdk/lib/crypto/store/base.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.js +189 -237
- package/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store-backend.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.js +25 -28
- package/node_modules/matrix-js-sdk/lib/crypto/store/indexeddb-crypto-store.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.js +113 -145
- package/node_modules/matrix-js-sdk/lib/crypto/store/localStorage-crypto-store.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.js +74 -105
- package/node_modules/matrix-js-sdk/lib/crypto/store/memory-crypto-store.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/crypto-api/CryptoEvent.js +1 -1
- package/node_modules/matrix-js-sdk/lib/crypto-api/CryptoEvent.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/crypto-api/CryptoEventHandlerMap.js +3 -1
- package/node_modules/matrix-js-sdk/lib/crypto-api/index.d.ts +15 -6
- package/node_modules/matrix-js-sdk/lib/crypto-api/index.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/crypto-api/index.js +76 -76
- package/node_modules/matrix-js-sdk/lib/crypto-api/index.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/crypto-api/key-passphrase.js +15 -23
- package/node_modules/matrix-js-sdk/lib/crypto-api/key-passphrase.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/crypto-api/keybackup.js +3 -1
- package/node_modules/matrix-js-sdk/lib/crypto-api/recovery-key.js +11 -12
- package/node_modules/matrix-js-sdk/lib/crypto-api/recovery-key.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/crypto-api/verification.js +3 -3
- package/node_modules/matrix-js-sdk/lib/crypto-api/verification.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/digest.js +7 -14
- package/node_modules/matrix-js-sdk/lib/digest.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/embedded.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/embedded.js +379 -500
- package/node_modules/matrix-js-sdk/lib/embedded.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/errors.js +2 -2
- package/node_modules/matrix-js-sdk/lib/errors.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/event-mapper.js +10 -12
- package/node_modules/matrix-js-sdk/lib/event-mapper.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/extensible_events_v1/ExtensibleEvent.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/extensible_events_v1/InvalidEventError.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/extensible_events_v1/MessageEvent.js +26 -28
- package/node_modules/matrix-js-sdk/lib/extensible_events_v1/MessageEvent.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/extensible_events_v1/PollEndEvent.js +11 -12
- package/node_modules/matrix-js-sdk/lib/extensible_events_v1/PollEndEvent.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/extensible_events_v1/PollResponseEvent.js +6 -6
- package/node_modules/matrix-js-sdk/lib/extensible_events_v1/PollResponseEvent.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/extensible_events_v1/PollStartEvent.js +36 -38
- package/node_modules/matrix-js-sdk/lib/extensible_events_v1/PollStartEvent.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/extensible_events_v1/utilities.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/feature.js +18 -31
- package/node_modules/matrix-js-sdk/lib/feature.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/filter-component.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/filter-component.js +20 -26
- package/node_modules/matrix-js-sdk/lib/filter-component.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/filter.js +14 -15
- package/node_modules/matrix-js-sdk/lib/filter.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/http-api/errors.js +41 -56
- package/node_modules/matrix-js-sdk/lib/http-api/errors.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/http-api/fetch.js +140 -157
- package/node_modules/matrix-js-sdk/lib/http-api/fetch.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/http-api/index.js +17 -20
- package/node_modules/matrix-js-sdk/lib/http-api/index.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/http-api/interface.js +1 -1
- package/node_modules/matrix-js-sdk/lib/http-api/interface.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/http-api/method.js +1 -1
- package/node_modules/matrix-js-sdk/lib/http-api/method.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/http-api/prefix.js +3 -3
- package/node_modules/matrix-js-sdk/lib/http-api/prefix.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/http-api/refresh.js +80 -99
- package/node_modules/matrix-js-sdk/lib/http-api/refresh.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/http-api/utils.d.ts +1 -1
- package/node_modules/matrix-js-sdk/lib/http-api/utils.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/http-api/utils.js +35 -47
- package/node_modules/matrix-js-sdk/lib/http-api/utils.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/index.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/indexeddb-helpers.js +3 -3
- package/node_modules/matrix-js-sdk/lib/indexeddb-helpers.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/indexeddb-worker.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/interactive-auth.d.ts +5 -5
- package/node_modules/matrix-js-sdk/lib/interactive-auth.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/interactive-auth.js +181 -203
- package/node_modules/matrix-js-sdk/lib/interactive-auth.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/logger.js +22 -56
- package/node_modules/matrix-js-sdk/lib/logger.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/matrix.d.ts +1 -0
- package/node_modules/matrix-js-sdk/lib/matrix.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/matrix.js +8 -11
- package/node_modules/matrix-js-sdk/lib/matrix.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/CallMembership.js +83 -76
- package/node_modules/matrix-js-sdk/lib/matrixrtc/CallMembership.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/EncryptionManager.js +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/EncryptionManager.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/IKeyTransport.js +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/IKeyTransport.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/IMembershipManager.js +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/IMembershipManager.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/LivekitTransport.d.ts +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/LivekitTransport.js +4 -4
- package/node_modules/matrix-js-sdk/lib/matrixrtc/LivekitTransport.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/MatrixRTCSession.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/MatrixRTCSession.js +144 -184
- package/node_modules/matrix-js-sdk/lib/matrixrtc/MatrixRTCSession.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/MatrixRTCSessionManager.js +35 -39
- package/node_modules/matrix-js-sdk/lib/matrixrtc/MatrixRTCSessionManager.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/MembershipManager.d.ts +2 -0
- package/node_modules/matrix-js-sdk/lib/matrixrtc/MembershipManager.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/MembershipManager.js +346 -383
- package/node_modules/matrix-js-sdk/lib/matrixrtc/MembershipManager.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/MembershipManagerActionScheduler.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/MembershipManagerActionScheduler.js +54 -59
- package/node_modules/matrix-js-sdk/lib/matrixrtc/MembershipManagerActionScheduler.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/RTCEncryptionManager.js +117 -139
- package/node_modules/matrix-js-sdk/lib/matrixrtc/RTCEncryptionManager.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/ToDeviceKeyTransport.js +49 -54
- package/node_modules/matrix-js-sdk/lib/matrixrtc/ToDeviceKeyTransport.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/index.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/membershipData/common.js +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/membershipData/common.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/membershipData/index.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/membershipData/rtc.js +15 -23
- package/node_modules/matrix-js-sdk/lib/matrixrtc/membershipData/rtc.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/membershipData/session.js +4 -5
- package/node_modules/matrix-js-sdk/lib/matrixrtc/membershipData/session.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/types.js +4 -6
- package/node_modules/matrix-js-sdk/lib/matrixrtc/types.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/matrixrtc/utils.js +4 -11
- package/node_modules/matrix-js-sdk/lib/matrixrtc/utils.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/MSC3089Branch.js +91 -116
- package/node_modules/matrix-js-sdk/lib/models/MSC3089Branch.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/MSC3089TreeSpace.js +209 -244
- package/node_modules/matrix-js-sdk/lib/models/MSC3089TreeSpace.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/ToDeviceMessage.js +3 -1
- package/node_modules/matrix-js-sdk/lib/models/beacon.js +20 -15
- package/node_modules/matrix-js-sdk/lib/models/beacon.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/compare-event-ordering.js +13 -13
- package/node_modules/matrix-js-sdk/lib/models/compare-event-ordering.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/device.js +10 -3
- package/node_modules/matrix-js-sdk/lib/models/device.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/event-context.js +5 -7
- package/node_modules/matrix-js-sdk/lib/models/event-context.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/event-status.js +1 -1
- package/node_modules/matrix-js-sdk/lib/models/event-status.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/event-timeline-set.js +91 -91
- package/node_modules/matrix-js-sdk/lib/models/event-timeline-set.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/event-timeline.js +31 -29
- package/node_modules/matrix-js-sdk/lib/models/event-timeline.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/event.js +215 -235
- package/node_modules/matrix-js-sdk/lib/models/event.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/invites-ignorer-types.js +4 -4
- package/node_modules/matrix-js-sdk/lib/models/invites-ignorer-types.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/invites-ignorer.js +159 -179
- package/node_modules/matrix-js-sdk/lib/models/invites-ignorer.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/poll.js +72 -78
- package/node_modules/matrix-js-sdk/lib/models/poll.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/profile-keys.js +2 -2
- package/node_modules/matrix-js-sdk/lib/models/profile-keys.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/read-receipt.js +40 -56
- package/node_modules/matrix-js-sdk/lib/models/read-receipt.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/related-relations.js +2 -0
- package/node_modules/matrix-js-sdk/lib/models/related-relations.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/relations-container.js +20 -21
- package/node_modules/matrix-js-sdk/lib/models/relations-container.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/relations.js +131 -156
- package/node_modules/matrix-js-sdk/lib/models/relations.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/room-member.js +44 -27
- package/node_modules/matrix-js-sdk/lib/models/room-member.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/room-receipts.js +48 -55
- package/node_modules/matrix-js-sdk/lib/models/room-receipts.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/room-retention.d.ts +28 -0
- package/node_modules/matrix-js-sdk/lib/models/room-retention.d.ts.map +1 -0
- package/node_modules/matrix-js-sdk/lib/models/room-retention.js +192 -0
- package/node_modules/matrix-js-sdk/lib/models/room-retention.js.map +1 -0
- package/node_modules/matrix-js-sdk/lib/models/room-state.js +141 -170
- package/node_modules/matrix-js-sdk/lib/models/room-state.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/room-sticky-events.d.ts +1 -0
- package/node_modules/matrix-js-sdk/lib/models/room-sticky-events.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/room-sticky-events.js +46 -65
- package/node_modules/matrix-js-sdk/lib/models/room-sticky-events.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/room-summary.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/room.d.ts +2 -1
- package/node_modules/matrix-js-sdk/lib/models/room.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/room.js +800 -887
- package/node_modules/matrix-js-sdk/lib/models/room.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/search-result.js +5 -5
- package/node_modules/matrix-js-sdk/lib/models/search-result.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/thread.js +267 -283
- package/node_modules/matrix-js-sdk/lib/models/thread.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/typed-event-emitter.js +7 -18
- package/node_modules/matrix-js-sdk/lib/models/typed-event-emitter.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/models/user.js +26 -7
- package/node_modules/matrix-js-sdk/lib/models/user.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/oidc/authorize.js +208 -241
- package/node_modules/matrix-js-sdk/lib/oidc/authorize.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/oidc/discovery.js +23 -36
- package/node_modules/matrix-js-sdk/lib/oidc/discovery.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/oidc/error.js +1 -1
- package/node_modules/matrix-js-sdk/lib/oidc/error.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/oidc/index.js +1 -0
- package/node_modules/matrix-js-sdk/lib/oidc/index.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/oidc/register.js +60 -66
- package/node_modules/matrix-js-sdk/lib/oidc/register.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/oidc/tokenRefresher.js +83 -94
- package/node_modules/matrix-js-sdk/lib/oidc/tokenRefresher.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/oidc/validate.js +18 -18
- package/node_modules/matrix-js-sdk/lib/oidc/validate.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/pushprocessor.js +70 -81
- package/node_modules/matrix-js-sdk/lib/pushprocessor.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/randomstring.js +9 -9
- package/node_modules/matrix-js-sdk/lib/randomstring.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/realtime-callbacks.js +25 -28
- package/node_modules/matrix-js-sdk/lib/realtime-callbacks.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/receipt-accumulator.d.ts +2 -0
- package/node_modules/matrix-js-sdk/lib/receipt-accumulator.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/receipt-accumulator.js +14 -22
- package/node_modules/matrix-js-sdk/lib/receipt-accumulator.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rendezvous/MSC4108SignInWithQR.js +272 -298
- package/node_modules/matrix-js-sdk/lib/rendezvous/MSC4108SignInWithQR.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rendezvous/RendezvousChannel.js +3 -1
- package/node_modules/matrix-js-sdk/lib/rendezvous/RendezvousCode.js +3 -1
- package/node_modules/matrix-js-sdk/lib/rendezvous/RendezvousError.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rendezvous/RendezvousFailureReason.js +2 -2
- package/node_modules/matrix-js-sdk/lib/rendezvous/RendezvousFailureReason.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rendezvous/RendezvousIntent.js +1 -1
- package/node_modules/matrix-js-sdk/lib/rendezvous/RendezvousIntent.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rendezvous/RendezvousTransport.js +3 -1
- package/node_modules/matrix-js-sdk/lib/rendezvous/channels/MSC4108SecureChannel.js +122 -144
- package/node_modules/matrix-js-sdk/lib/rendezvous/channels/MSC4108SecureChannel.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rendezvous/index.js +44 -69
- package/node_modules/matrix-js-sdk/lib/rendezvous/index.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rendezvous/transports/MSC4108RendezvousSession.d.ts +1 -1
- package/node_modules/matrix-js-sdk/lib/rendezvous/transports/MSC4108RendezvousSession.js +142 -152
- package/node_modules/matrix-js-sdk/lib/rendezvous/transports/MSC4108RendezvousSession.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/retentionPolicy.d.ts +33 -0
- package/node_modules/matrix-js-sdk/lib/retentionPolicy.d.ts.map +1 -0
- package/node_modules/matrix-js-sdk/lib/retentionPolicy.js +39 -0
- package/node_modules/matrix-js-sdk/lib/retentionPolicy.js.map +1 -0
- package/node_modules/matrix-js-sdk/lib/room-hierarchy.js +52 -56
- package/node_modules/matrix-js-sdk/lib/room-hierarchy.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rust-crypto/CrossSigningIdentity.js +94 -104
- package/node_modules/matrix-js-sdk/lib/rust-crypto/CrossSigningIdentity.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rust-crypto/DehydratedDeviceManager.js +158 -190
- package/node_modules/matrix-js-sdk/lib/rust-crypto/DehydratedDeviceManager.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rust-crypto/KeyClaimManager.js +17 -20
- package/node_modules/matrix-js-sdk/lib/rust-crypto/KeyClaimManager.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rust-crypto/OutgoingRequestProcessor.js +109 -139
- package/node_modules/matrix-js-sdk/lib/rust-crypto/OutgoingRequestProcessor.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rust-crypto/OutgoingRequestsManager.js +72 -86
- package/node_modules/matrix-js-sdk/lib/rust-crypto/OutgoingRequestsManager.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rust-crypto/PerSessionKeyBackupDownloader.d.ts +1 -1
- package/node_modules/matrix-js-sdk/lib/rust-crypto/PerSessionKeyBackupDownloader.js +195 -221
- package/node_modules/matrix-js-sdk/lib/rust-crypto/PerSessionKeyBackupDownloader.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rust-crypto/RoomEncryptor.js +121 -137
- package/node_modules/matrix-js-sdk/lib/rust-crypto/RoomEncryptor.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rust-crypto/backup.d.ts +7 -2
- package/node_modules/matrix-js-sdk/lib/rust-crypto/backup.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rust-crypto/backup.js +459 -544
- package/node_modules/matrix-js-sdk/lib/rust-crypto/backup.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rust-crypto/constants.js +1 -1
- package/node_modules/matrix-js-sdk/lib/rust-crypto/constants.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rust-crypto/device-converter.js +15 -28
- package/node_modules/matrix-js-sdk/lib/rust-crypto/device-converter.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rust-crypto/index.js +103 -116
- package/node_modules/matrix-js-sdk/lib/rust-crypto/index.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rust-crypto/libolm_migration.js +303 -365
- package/node_modules/matrix-js-sdk/lib/rust-crypto/libolm_migration.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rust-crypto/rust-crypto.d.ts +5 -1
- package/node_modules/matrix-js-sdk/lib/rust-crypto/rust-crypto.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rust-crypto/rust-crypto.js +1065 -1322
- package/node_modules/matrix-js-sdk/lib/rust-crypto/rust-crypto.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rust-crypto/secret-storage.js +12 -25
- package/node_modules/matrix-js-sdk/lib/rust-crypto/secret-storage.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/rust-crypto/verification.js +134 -184
- package/node_modules/matrix-js-sdk/lib/rust-crypto/verification.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/scheduler.js +42 -17
- package/node_modules/matrix-js-sdk/lib/scheduler.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/secret-storage.js +179 -213
- package/node_modules/matrix-js-sdk/lib/secret-storage.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/serverCapabilities.d.ts +4 -23
- package/node_modules/matrix-js-sdk/lib/serverCapabilities.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/serverCapabilities.js +9 -62
- package/node_modules/matrix-js-sdk/lib/serverCapabilities.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/service-types.js +1 -1
- package/node_modules/matrix-js-sdk/lib/service-types.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/sliding-sync-sdk.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/sliding-sync-sdk.js +368 -421
- package/node_modules/matrix-js-sdk/lib/sliding-sync-sdk.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/sliding-sync.js +136 -167
- package/node_modules/matrix-js-sdk/lib/sliding-sync.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/store/index.d.ts +7 -0
- package/node_modules/matrix-js-sdk/lib/store/index.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/store/index.js +3 -1
- package/node_modules/matrix-js-sdk/lib/store/index.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/store/indexeddb-backend.js +3 -1
- package/node_modules/matrix-js-sdk/lib/store/indexeddb-local-backend.d.ts +1 -0
- package/node_modules/matrix-js-sdk/lib/store/indexeddb-local-backend.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/store/indexeddb-local-backend.js +197 -240
- package/node_modules/matrix-js-sdk/lib/store/indexeddb-local-backend.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/store/indexeddb-remote-backend.d.ts +3 -1
- package/node_modules/matrix-js-sdk/lib/store/indexeddb-remote-backend.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/store/indexeddb-remote-backend.js +51 -59
- package/node_modules/matrix-js-sdk/lib/store/indexeddb-remote-backend.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/store/indexeddb-store-worker.js +22 -22
- package/node_modules/matrix-js-sdk/lib/store/indexeddb-store-worker.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/store/indexeddb.d.ts +7 -5
- package/node_modules/matrix-js-sdk/lib/store/indexeddb.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/store/indexeddb.js +63 -79
- package/node_modules/matrix-js-sdk/lib/store/indexeddb.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/store/local-storage-events-emitter.js +2 -2
- package/node_modules/matrix-js-sdk/lib/store/local-storage-events-emitter.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/store/memory.d.ts +1 -0
- package/node_modules/matrix-js-sdk/lib/store/memory.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/store/memory.js +38 -54
- package/node_modules/matrix-js-sdk/lib/store/memory.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/store/stub.d.ts +1 -0
- package/node_modules/matrix-js-sdk/lib/store/stub.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/store/stub.js +22 -32
- package/node_modules/matrix-js-sdk/lib/store/stub.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/sync-accumulator.d.ts +1 -0
- package/node_modules/matrix-js-sdk/lib/sync-accumulator.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/sync-accumulator.js +57 -65
- package/node_modules/matrix-js-sdk/lib/sync-accumulator.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/sync.d.ts.map +1 -1
- package/node_modules/matrix-js-sdk/lib/sync.js +914 -991
- package/node_modules/matrix-js-sdk/lib/sync.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/testing.js +63 -105
- package/node_modules/matrix-js-sdk/lib/testing.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/thread-utils.js +1 -4
- package/node_modules/matrix-js-sdk/lib/thread-utils.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/timeline-window.js +90 -99
- package/node_modules/matrix-js-sdk/lib/timeline-window.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/types.js +1 -1
- package/node_modules/matrix-js-sdk/lib/types.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/utils/decryptAESSecretStorageItem.js +14 -25
- package/node_modules/matrix-js-sdk/lib/utils/decryptAESSecretStorageItem.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/utils/encryptAESSecretStorageItem.js +27 -38
- package/node_modules/matrix-js-sdk/lib/utils/encryptAESSecretStorageItem.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/utils/internal/deriveKeys.js +25 -32
- package/node_modules/matrix-js-sdk/lib/utils/internal/deriveKeys.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/utils/roomVersion.js +1 -1
- package/node_modules/matrix-js-sdk/lib/utils/roomVersion.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/utils.js +83 -135
- package/node_modules/matrix-js-sdk/lib/utils.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/version-support.js +3 -3
- package/node_modules/matrix-js-sdk/lib/version-support.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/audioContext.js +5 -6
- package/node_modules/matrix-js-sdk/lib/webrtc/audioContext.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/call.js +1123 -1256
- package/node_modules/matrix-js-sdk/lib/webrtc/call.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/callEventHandler.js +207 -214
- package/node_modules/matrix-js-sdk/lib/webrtc/callEventHandler.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/callEventTypes.js +2 -2
- package/node_modules/matrix-js-sdk/lib/webrtc/callEventTypes.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/callFeed.js +33 -20
- package/node_modules/matrix-js-sdk/lib/webrtc/callFeed.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/groupCall.js +521 -594
- package/node_modules/matrix-js-sdk/lib/webrtc/groupCall.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/groupCallEventHandler.js +58 -61
- package/node_modules/matrix-js-sdk/lib/webrtc/groupCallEventHandler.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/mediaHandler.js +203 -233
- package/node_modules/matrix-js-sdk/lib/webrtc/mediaHandler.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/callFeedStatsReporter.js +16 -20
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/callFeedStatsReporter.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/callStatsReportGatherer.js +65 -70
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/callStatsReportGatherer.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/callStatsReportSummary.js +3 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/connectionStats.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/connectionStatsBuilder.js +2 -2
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/connectionStatsBuilder.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/connectionStatsReportBuilder.js +20 -24
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/connectionStatsReportBuilder.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/groupCallStats.js +4 -5
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/groupCallStats.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/media/mediaSsrcHandler.js +7 -8
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/media/mediaSsrcHandler.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/media/mediaTrackHandler.js +7 -9
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/media/mediaTrackHandler.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/media/mediaTrackStats.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/media/mediaTrackStatsHandler.js +6 -6
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/media/mediaTrackStatsHandler.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/statsReport.js +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/statsReport.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/statsReportEmitter.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/summaryStatsReportGatherer.js +14 -14
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/summaryStatsReportGatherer.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/trackStatsBuilder.js +32 -34
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/trackStatsBuilder.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/transportStats.js +3 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/transportStatsBuilder.js +9 -9
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/transportStatsBuilder.js.map +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/valueFormatter.js +1 -1
- package/node_modules/matrix-js-sdk/lib/webrtc/stats/valueFormatter.js.map +1 -1
- package/node_modules/matrix-js-sdk/package.json +110 -138
- package/node_modules/matrix-js-sdk/src/@types/event.ts +9 -0
- package/node_modules/matrix-js-sdk/src/@types/global.d.ts +2 -2
- package/node_modules/matrix-js-sdk/src/@types/retention.ts +16 -0
- package/node_modules/matrix-js-sdk/src/ToDeviceMessageQueue.ts +2 -2
- package/node_modules/matrix-js-sdk/src/browser-index.ts +4 -4
- package/node_modules/matrix-js-sdk/src/capabilityPoller.ts +102 -0
- package/node_modules/matrix-js-sdk/src/client.ts +37 -25
- package/node_modules/matrix-js-sdk/src/crypto-api/index.ts +17 -6
- package/node_modules/matrix-js-sdk/src/embedded.ts +4 -6
- package/node_modules/matrix-js-sdk/src/filter-component.ts +1 -0
- package/node_modules/matrix-js-sdk/src/http-api/utils.ts +5 -10
- package/node_modules/matrix-js-sdk/src/interactive-auth.ts +11 -5
- package/node_modules/matrix-js-sdk/src/matrix.ts +1 -0
- package/node_modules/matrix-js-sdk/src/matrixrtc/LivekitTransport.ts +1 -1
- package/node_modules/matrix-js-sdk/src/matrixrtc/MatrixRTCSession.ts +5 -4
- package/node_modules/matrix-js-sdk/src/matrixrtc/MembershipManager.ts +2 -0
- package/node_modules/matrix-js-sdk/src/matrixrtc/MembershipManagerActionScheduler.ts +4 -1
- package/node_modules/matrix-js-sdk/src/models/MSC3089Branch.ts +1 -1
- package/node_modules/matrix-js-sdk/src/models/room-retention.ts +230 -0
- package/node_modules/matrix-js-sdk/src/models/room-sticky-events.ts +1 -0
- package/node_modules/matrix-js-sdk/src/models/room.ts +26 -12
- package/node_modules/matrix-js-sdk/src/receipt-accumulator.ts +2 -0
- package/node_modules/matrix-js-sdk/src/rendezvous/index.ts +1 -1
- package/node_modules/matrix-js-sdk/src/rendezvous/transports/MSC4108RendezvousSession.ts +2 -2
- package/node_modules/matrix-js-sdk/src/retentionPolicy.ts +65 -0
- package/node_modules/matrix-js-sdk/src/rust-crypto/PerSessionKeyBackupDownloader.ts +1 -1
- package/node_modules/matrix-js-sdk/src/rust-crypto/backup.ts +15 -4
- package/node_modules/matrix-js-sdk/src/rust-crypto/index.ts +6 -6
- package/node_modules/matrix-js-sdk/src/rust-crypto/rust-crypto.ts +31 -7
- package/node_modules/matrix-js-sdk/src/rust-crypto/verification.ts +1 -1
- package/node_modules/matrix-js-sdk/src/serverCapabilities.ts +8 -67
- package/node_modules/matrix-js-sdk/src/sliding-sync-sdk.ts +5 -7
- package/node_modules/matrix-js-sdk/src/store/index.ts +8 -0
- package/node_modules/matrix-js-sdk/src/store/indexeddb-local-backend.ts +12 -2
- package/node_modules/matrix-js-sdk/src/store/indexeddb-remote-backend.ts +24 -5
- package/node_modules/matrix-js-sdk/src/store/indexeddb.ts +20 -8
- package/node_modules/matrix-js-sdk/src/store/memory.ts +4 -0
- package/node_modules/matrix-js-sdk/src/store/stub.ts +3 -0
- package/node_modules/matrix-js-sdk/src/sync-accumulator.ts +9 -0
- package/node_modules/matrix-js-sdk/src/sync.ts +11 -9
- package/node_modules/media-typer/README.md +19 -33
- package/node_modules/media-typer/dist/index.d.ts +29 -0
- package/node_modules/media-typer/dist/index.js +64 -0
- package/node_modules/media-typer/dist/index.js.map +1 -0
- package/node_modules/media-typer/package.json +37 -22
- package/node_modules/music-metadata/lib/id3v1/ID3v1Parser.js +2 -2
- package/node_modules/music-metadata/lib/mp4/AtomToken.js +65 -13
- package/node_modules/music-metadata/lib/wav/WaveChunk.d.ts +10 -0
- package/node_modules/music-metadata/lib/wav/WaveChunk.js +13 -3
- package/node_modules/music-metadata/lib/wav/WaveParser.d.ts +1 -0
- package/node_modules/music-metadata/lib/wav/WaveParser.js +6 -5
- package/node_modules/music-metadata/package.json +5 -5
- package/node_modules/typebox/build/compile/validator.d.mts +2 -7
- package/node_modules/typebox/build/compile/validator.mjs +6 -36
- package/node_modules/typebox/build/error/errors.d.mts +1 -7
- package/node_modules/typebox/build/format/_idna.mjs +36 -6
- package/node_modules/typebox/build/format/_puny.mjs +4 -1
- package/node_modules/typebox/build/format/uuid.d.mts +2 -2
- package/node_modules/typebox/build/format/uuid.mjs +3 -3
- package/node_modules/typebox/build/guard/emit.d.mts +0 -4
- package/node_modules/typebox/build/guard/emit.mjs +0 -8
- package/node_modules/typebox/build/guard/guard.d.mts +4 -8
- package/node_modules/typebox/build/guard/guard.mjs +5 -13
- package/node_modules/typebox/build/schema/engine/boolean.d.mts +3 -3
- package/node_modules/typebox/build/schema/engine/boolean.mjs +4 -4
- package/node_modules/typebox/build/schema/engine/index.d.mts +0 -1
- package/node_modules/typebox/build/schema/engine/index.mjs +0 -1
- package/node_modules/typebox/build/schema/engine/schema.mjs +5 -10
- package/node_modules/typebox/build/schema/engine/type.mjs +14 -18
- package/node_modules/typebox/build/schema/types/dependencies.mjs +1 -1
- package/node_modules/typebox/build/schema/types/index.d.mts +0 -1
- package/node_modules/typebox/build/schema/types/index.mjs +0 -1
- package/node_modules/typebox/build/schema/types/schema.d.mts +1 -1
- package/node_modules/typebox/build/schema/types/schema.mjs +2 -2
- package/node_modules/typebox/build/system/locale/ar_001.mjs +0 -1
- package/node_modules/typebox/build/system/locale/bn_BD.mjs +0 -1
- package/node_modules/typebox/build/system/locale/cs_CZ.mjs +0 -1
- package/node_modules/typebox/build/system/locale/de_DE.mjs +0 -1
- package/node_modules/typebox/build/system/locale/el_GR.mjs +0 -1
- package/node_modules/typebox/build/system/locale/en_US.mjs +0 -1
- package/node_modules/typebox/build/system/locale/es_419.mjs +0 -1
- package/node_modules/typebox/build/system/locale/es_AR.mjs +0 -1
- package/node_modules/typebox/build/system/locale/es_ES.mjs +0 -1
- package/node_modules/typebox/build/system/locale/es_MX.mjs +0 -1
- package/node_modules/typebox/build/system/locale/fa_IR.mjs +0 -1
- package/node_modules/typebox/build/system/locale/fil_PH.mjs +0 -1
- package/node_modules/typebox/build/system/locale/fr_CA.mjs +0 -1
- package/node_modules/typebox/build/system/locale/fr_FR.mjs +0 -1
- package/node_modules/typebox/build/system/locale/ha_NG.mjs +0 -1
- package/node_modules/typebox/build/system/locale/hi_IN.mjs +0 -1
- package/node_modules/typebox/build/system/locale/hu_HU.mjs +0 -1
- package/node_modules/typebox/build/system/locale/id_ID.mjs +0 -1
- package/node_modules/typebox/build/system/locale/it_IT.mjs +0 -1
- package/node_modules/typebox/build/system/locale/ja_JP.mjs +0 -1
- package/node_modules/typebox/build/system/locale/ko_KR.mjs +0 -1
- package/node_modules/typebox/build/system/locale/ms_MY.mjs +0 -1
- package/node_modules/typebox/build/system/locale/nl_NL.mjs +0 -1
- package/node_modules/typebox/build/system/locale/pl_PL.mjs +0 -1
- package/node_modules/typebox/build/system/locale/pt_BR.mjs +0 -1
- package/node_modules/typebox/build/system/locale/pt_PT.mjs +0 -1
- package/node_modules/typebox/build/system/locale/ro_RO.mjs +0 -1
- package/node_modules/typebox/build/system/locale/ru_RU.mjs +0 -1
- package/node_modules/typebox/build/system/locale/sv_SE.mjs +0 -1
- package/node_modules/typebox/build/system/locale/sw_TZ.mjs +0 -1
- package/node_modules/typebox/build/system/locale/th_TH.mjs +0 -1
- package/node_modules/typebox/build/system/locale/tr_TR.mjs +0 -1
- package/node_modules/typebox/build/system/locale/uk_UA.mjs +0 -1
- package/node_modules/typebox/build/system/locale/ur_PK.mjs +0 -1
- package/node_modules/typebox/build/system/locale/vi_VN.mjs +0 -1
- package/node_modules/typebox/build/system/locale/yo_NG.mjs +0 -1
- package/node_modules/typebox/build/system/locale/zh_Hans.mjs +0 -1
- package/node_modules/typebox/build/system/locale/zh_Hant.mjs +0 -1
- package/node_modules/typebox/build/system/memory/clone.d.mts +2 -3
- package/node_modules/typebox/build/system/memory/clone.mjs +73 -26
- package/node_modules/typebox/build/system/settings/settings.d.mts +15 -0
- package/node_modules/typebox/build/system/settings/settings.mjs +3 -1
- package/node_modules/typebox/build/type/action/_add_immutable.d.mts +11 -0
- package/node_modules/typebox/build/type/action/_add_immutable.mjs +11 -0
- package/node_modules/typebox/build/type/action/_add_optional.d.mts +11 -0
- package/node_modules/typebox/build/type/action/_add_optional.mjs +11 -0
- package/node_modules/typebox/build/type/action/_add_readonly.d.mts +11 -0
- package/node_modules/typebox/build/type/action/_add_readonly.mjs +11 -0
- package/node_modules/typebox/build/type/action/_remove_immutable.d.mts +11 -0
- package/node_modules/typebox/build/type/action/_remove_immutable.mjs +11 -0
- package/node_modules/typebox/build/type/action/_remove_optional.d.mts +11 -0
- package/node_modules/typebox/build/type/action/_remove_optional.mjs +11 -0
- package/node_modules/typebox/build/type/action/_remove_readonly.d.mts +11 -0
- package/node_modules/typebox/build/type/action/_remove_readonly.mjs +11 -0
- package/node_modules/typebox/build/type/action/conditional.d.mts +2 -3
- package/node_modules/typebox/build/type/action/conditional.mjs +2 -1
- package/node_modules/typebox/build/type/action/index.d.mts +7 -4
- package/node_modules/typebox/build/type/action/index.mjs +7 -4
- package/node_modules/typebox/build/type/action/mapped.d.mts +2 -3
- package/node_modules/typebox/build/type/action/mapped.mjs +2 -1
- package/node_modules/typebox/build/type/action/module.d.mts +8 -7
- package/node_modules/typebox/build/type/action/module.mjs +7 -6
- package/node_modules/typebox/build/type/action/readonly_object.d.mts +0 -5
- package/node_modules/typebox/build/type/action/readonly_object.mjs +0 -5
- package/node_modules/typebox/build/type/action/with.d.mts +11 -0
- package/node_modules/typebox/build/type/action/with.mjs +11 -0
- package/node_modules/typebox/build/type/engine/call/distribute_arguments.mjs +1 -1
- package/node_modules/typebox/build/type/engine/call/instantiate.d.mts +1 -3
- package/node_modules/typebox/build/type/engine/call/instantiate.mjs +3 -2
- package/node_modules/typebox/build/type/engine/call/resolve_arguments.mjs +2 -2
- package/node_modules/typebox/build/type/engine/constructor_parameters/instantiate.d.mts +3 -4
- package/node_modules/typebox/build/type/engine/constructor_parameters/instantiate.mjs +2 -1
- package/node_modules/typebox/build/type/engine/cyclic/candidates.d.mts +2 -3
- package/node_modules/typebox/build/type/engine/cyclic/candidates.mjs +3 -6
- package/node_modules/typebox/build/type/engine/cyclic/check.d.mts +6 -9
- package/node_modules/typebox/build/type/engine/cyclic/check.mjs +10 -16
- package/node_modules/typebox/build/type/engine/cyclic/dependencies.d.mts +1 -4
- package/node_modules/typebox/build/type/engine/cyclic/dependencies.mjs +9 -15
- package/node_modules/typebox/build/type/engine/cyclic/extends.d.mts +1 -4
- package/node_modules/typebox/build/type/engine/cyclic/extends.mjs +8 -14
- package/node_modules/typebox/build/type/engine/cyclic/instantiate.d.mts +2 -5
- package/node_modules/typebox/build/type/engine/cyclic/instantiate.mjs +3 -2
- package/node_modules/typebox/build/type/engine/enum/index.d.mts +0 -1
- package/node_modules/typebox/build/type/engine/enum/index.mjs +0 -1
- package/node_modules/typebox/build/type/engine/evaluate/broaden.d.mts +1 -2
- package/node_modules/typebox/build/type/engine/evaluate/broaden.mjs +2 -6
- package/node_modules/typebox/build/type/engine/evaluate/composite.d.mts +10 -6
- package/node_modules/typebox/build/type/engine/evaluate/composite.mjs +10 -6
- package/node_modules/typebox/build/type/engine/evaluate/distribute.d.mts +2 -1
- package/node_modules/typebox/build/type/engine/evaluate/distribute.mjs +3 -3
- package/node_modules/typebox/build/type/engine/evaluate/evaluate.d.mts +17 -5
- package/node_modules/typebox/build/type/engine/evaluate/evaluate.mjs +34 -8
- package/node_modules/typebox/build/type/engine/exclude/operation.d.mts +5 -6
- package/node_modules/typebox/build/type/engine/exclude/operation.mjs +11 -12
- package/node_modules/typebox/build/type/engine/extract/operation.d.mts +5 -6
- package/node_modules/typebox/build/type/engine/extract/operation.mjs +11 -12
- package/node_modules/typebox/build/type/engine/immutable/instantiate_add.d.mts +10 -0
- package/node_modules/typebox/build/type/engine/immutable/instantiate_add.mjs +14 -0
- package/node_modules/typebox/build/type/engine/immutable/instantiate_remove.d.mts +10 -0
- package/node_modules/typebox/build/type/engine/immutable/instantiate_remove.mjs +14 -0
- package/node_modules/typebox/build/type/engine/index.d.mts +2 -2
- package/node_modules/typebox/build/type/engine/index.mjs +2 -2
- package/node_modules/typebox/build/type/engine/indexable/from_dependent.d.mts +5 -0
- package/node_modules/typebox/build/type/engine/indexable/from_dependent.mjs +8 -0
- package/node_modules/typebox/build/type/engine/indexable/from_enum.d.mts +3 -3
- package/node_modules/typebox/build/type/engine/indexable/from_enum.mjs +4 -4
- package/node_modules/typebox/build/type/engine/indexable/from_template_literal.d.mts +2 -2
- package/node_modules/typebox/build/type/engine/indexable/from_template_literal.mjs +3 -3
- package/node_modules/typebox/build/type/engine/indexable/from_type.d.mts +3 -1
- package/node_modules/typebox/build/type/engine/indexable/from_type.mjs +9 -6
- package/node_modules/typebox/build/type/engine/indexed/instantiate.d.mts +2 -1
- package/node_modules/typebox/build/type/engine/indexed/instantiate.mjs +5 -2
- package/node_modules/typebox/build/type/engine/instantiate.d.mts +44 -31
- package/node_modules/typebox/build/type/engine/instantiate.mjs +82 -83
- package/node_modules/typebox/build/type/engine/interface/instantiate.d.mts +3 -6
- package/node_modules/typebox/build/type/engine/intrinsics/from_template_literal.d.mts +2 -2
- package/node_modules/typebox/build/type/engine/intrinsics/from_template_literal.mjs +3 -3
- package/node_modules/typebox/build/type/engine/keyof/instantiate.d.mts +2 -1
- package/node_modules/typebox/build/type/engine/keyof/instantiate.mjs +5 -1
- package/node_modules/typebox/build/type/engine/mapped/mapped_operation.d.mts +4 -4
- package/node_modules/typebox/build/type/engine/mapped/mapped_operation.mjs +3 -3
- package/node_modules/typebox/build/type/engine/mapped/mapped_variants.d.mts +5 -4
- package/node_modules/typebox/build/type/engine/mapped/mapped_variants.mjs +10 -5
- package/node_modules/typebox/build/type/engine/module/instantiate.d.mts +7 -9
- package/node_modules/typebox/build/type/engine/module/instantiate.mjs +17 -15
- package/node_modules/typebox/build/type/engine/object/from_dependent.d.mts +5 -0
- package/node_modules/typebox/build/type/engine/object/from_dependent.mjs +8 -0
- package/node_modules/typebox/build/type/engine/object/from_type.d.mts +3 -1
- package/node_modules/typebox/build/type/engine/object/from_type.mjs +8 -5
- package/node_modules/typebox/build/type/engine/object/from_union.mjs +2 -2
- package/node_modules/typebox/build/type/engine/optional/instantiate_add.d.mts +10 -0
- package/node_modules/typebox/build/type/engine/optional/instantiate_add.mjs +14 -0
- package/node_modules/typebox/build/type/engine/optional/instantiate_remove.d.mts +10 -0
- package/node_modules/typebox/build/type/engine/optional/instantiate_remove.mjs +14 -0
- package/node_modules/typebox/build/type/engine/parameters/instantiate.d.mts +3 -4
- package/node_modules/typebox/build/type/engine/parameters/instantiate.mjs +2 -1
- package/node_modules/typebox/build/type/engine/partial/from_dependent.d.mts +5 -0
- package/node_modules/typebox/build/type/engine/partial/from_dependent.mjs +8 -0
- package/node_modules/typebox/build/type/engine/partial/from_intersect.d.mts +1 -1
- package/node_modules/typebox/build/type/engine/partial/from_intersect.mjs +3 -2
- package/node_modules/typebox/build/type/engine/partial/from_object.d.mts +2 -2
- package/node_modules/typebox/build/type/engine/partial/from_object.mjs +2 -2
- package/node_modules/typebox/build/type/engine/partial/from_type.d.mts +3 -1
- package/node_modules/typebox/build/type/engine/partial/from_type.mjs +7 -4
- package/node_modules/typebox/build/type/engine/priority/index.d.mts +1 -0
- package/node_modules/typebox/build/type/engine/priority/index.mjs +1 -0
- package/node_modules/typebox/build/type/engine/priority/priority.d.mts +20 -0
- package/node_modules/typebox/build/type/engine/priority/priority.mjs +28 -0
- package/node_modules/typebox/build/type/engine/readonly/instantiate_add.d.mts +10 -0
- package/node_modules/typebox/build/type/engine/readonly/instantiate_add.mjs +14 -0
- package/node_modules/typebox/build/type/engine/readonly/instantiate_remove.d.mts +10 -0
- package/node_modules/typebox/build/type/engine/readonly/instantiate_remove.mjs +14 -0
- package/node_modules/typebox/build/type/engine/readonly_object/from_array.d.mts +2 -2
- package/node_modules/typebox/build/type/engine/readonly_object/from_array.mjs +2 -2
- package/node_modules/typebox/build/type/engine/readonly_object/from_dependent.d.mts +5 -0
- package/node_modules/typebox/build/type/engine/readonly_object/from_dependent.mjs +8 -0
- package/node_modules/typebox/build/type/engine/readonly_object/from_intersect.d.mts +1 -1
- package/node_modules/typebox/build/type/engine/readonly_object/from_intersect.mjs +3 -2
- package/node_modules/typebox/build/type/engine/readonly_object/from_object.d.mts +2 -2
- package/node_modules/typebox/build/type/engine/readonly_object/from_object.mjs +2 -2
- package/node_modules/typebox/build/type/engine/readonly_object/from_tuple.d.mts +2 -2
- package/node_modules/typebox/build/type/engine/readonly_object/from_tuple.mjs +2 -2
- package/node_modules/typebox/build/type/engine/readonly_object/from_type.d.mts +3 -1
- package/node_modules/typebox/build/type/engine/readonly_object/from_type.mjs +8 -5
- package/node_modules/typebox/build/type/engine/record/from_key_enum.d.mts +2 -2
- package/node_modules/typebox/build/type/engine/record/from_key_enum.mjs +2 -2
- package/node_modules/typebox/build/type/engine/record/from_key_template_literal.d.mts +2 -2
- package/node_modules/typebox/build/type/engine/record/from_key_template_literal.mjs +2 -2
- package/node_modules/typebox/build/type/engine/ref/instantiate.d.mts +3 -3
- package/node_modules/typebox/build/type/engine/ref/instantiate.mjs +6 -6
- package/node_modules/typebox/build/type/engine/required/from_dependent.d.mts +5 -0
- package/node_modules/typebox/build/type/engine/required/from_dependent.mjs +8 -0
- package/node_modules/typebox/build/type/engine/required/from_intersect.d.mts +1 -1
- package/node_modules/typebox/build/type/engine/required/from_intersect.mjs +3 -2
- package/node_modules/typebox/build/type/engine/required/from_object.d.mts +2 -2
- package/node_modules/typebox/build/type/engine/required/from_object.mjs +2 -2
- package/node_modules/typebox/build/type/engine/required/from_type.d.mts +3 -1
- package/node_modules/typebox/build/type/engine/required/from_type.mjs +7 -4
- package/node_modules/typebox/build/type/engine/template_literal/decode.mjs +3 -3
- package/node_modules/typebox/build/type/engine/template_literal/encode.d.mts +2 -2
- package/node_modules/typebox/build/type/engine/template_literal/encode.mjs +6 -6
- package/node_modules/typebox/build/type/engine/template_literal/is_finite.mjs +1 -1
- package/node_modules/typebox/build/type/engine/template_literal/is_pattern.mjs +1 -0
- package/node_modules/typebox/build/type/engine/this/expand_this.d.mts +1 -4
- package/node_modules/typebox/build/type/engine/this/expand_this.mjs +7 -13
- package/node_modules/typebox/build/type/engine/with/instantiate.d.mts +8 -0
- package/node_modules/typebox/build/type/engine/{options → with}/instantiate.mjs +5 -5
- package/node_modules/typebox/build/type/extends/dependent.d.mts +6 -0
- package/node_modules/typebox/build/type/extends/dependent.mjs +6 -0
- package/node_modules/typebox/build/type/extends/enum.d.mts +4 -4
- package/node_modules/typebox/build/type/extends/enum.mjs +3 -2
- package/node_modules/typebox/build/type/extends/extends_left.d.mts +5 -7
- package/node_modules/typebox/build/type/extends/extends_left.mjs +24 -27
- package/node_modules/typebox/build/type/extends/extends_right.d.mts +7 -5
- package/node_modules/typebox/build/type/extends/extends_right.mjs +20 -15
- package/node_modules/typebox/build/type/extends/inference.mjs +1 -1
- package/node_modules/typebox/build/type/extends/object.d.mts +8 -1
- package/node_modules/typebox/build/type/extends/object.mjs +25 -3
- package/node_modules/typebox/build/type/extends/parameters.mjs +2 -2
- package/node_modules/typebox/build/type/extends/record.d.mts +13 -0
- package/node_modules/typebox/build/type/extends/record.mjs +23 -0
- package/node_modules/typebox/build/type/extends/template_literal.d.mts +3 -3
- package/node_modules/typebox/build/type/extends/template_literal.mjs +3 -3
- package/node_modules/typebox/build/type/extends/tuple.d.mts +3 -6
- package/node_modules/typebox/build/type/extends/tuple.mjs +6 -5
- package/node_modules/typebox/build/type/extends/union.mjs +2 -2
- package/node_modules/typebox/build/type/script/mapping.d.mts +84 -99
- package/node_modules/typebox/build/type/script/mapping.mjs +81 -85
- package/node_modules/typebox/build/type/script/parser.d.mts +40 -40
- package/node_modules/typebox/build/type/script/parser.mjs +22 -22
- package/node_modules/typebox/build/type/script/script.d.mts +3 -4
- package/node_modules/typebox/build/type/script/script.mjs +3 -2
- package/node_modules/typebox/build/type/script/token/internal/guard.d.mts +1 -1
- package/node_modules/typebox/build/type/script/token/internal/guard.mjs +1 -1
- package/node_modules/typebox/build/type/script/token/internal/take.mjs +1 -1
- package/node_modules/typebox/build/type/script/token/until.mjs +2 -2
- package/node_modules/typebox/build/type/types/_codec.d.mts +12 -12
- package/node_modules/typebox/build/type/types/_codec.mjs +0 -1
- package/node_modules/typebox/build/type/types/_immutable.d.mts +2 -9
- package/node_modules/typebox/build/type/types/_immutable.mjs +2 -10
- package/node_modules/typebox/build/type/types/_optional.d.mts +2 -9
- package/node_modules/typebox/build/type/types/_optional.mjs +2 -11
- package/node_modules/typebox/build/type/types/_readonly.d.mts +2 -9
- package/node_modules/typebox/build/type/types/_readonly.mjs +2 -10
- package/node_modules/typebox/build/type/types/_refine.d.mts +8 -10
- package/node_modules/typebox/build/type/types/_refine.mjs +1 -2
- package/node_modules/typebox/build/type/types/call.d.mts +3 -3
- package/node_modules/typebox/build/type/types/call.mjs +3 -2
- package/node_modules/typebox/build/type/types/deferred.d.mts +1 -0
- package/node_modules/typebox/build/type/types/deferred.mjs +1 -1
- package/node_modules/typebox/build/type/types/dependent.d.mts +17 -0
- package/node_modules/typebox/build/type/types/dependent.mjs +24 -0
- package/node_modules/typebox/build/type/types/enum.d.mts +3 -1
- package/node_modules/typebox/build/type/types/enum.mjs +5 -0
- package/node_modules/typebox/build/type/types/index.d.mts +1 -4
- package/node_modules/typebox/build/type/types/index.mjs +1 -4
- package/node_modules/typebox/build/type/types/number.d.mts +1 -1
- package/node_modules/typebox/build/type/types/number.mjs +1 -1
- package/node_modules/typebox/build/type/types/record.d.mts +13 -7
- package/node_modules/typebox/build/type/types/record.mjs +15 -9
- package/node_modules/typebox/build/type/types/static.d.mts +2 -5
- package/node_modules/typebox/build/typebox.d.mts +4 -8
- package/node_modules/typebox/build/typebox.mjs +4 -8
- package/node_modules/typebox/build/value/clean/clean.mjs +4 -2
- package/node_modules/typebox/build/value/clean/from_intersect.mjs +2 -2
- package/node_modules/typebox/build/value/clean/from_type.mjs +8 -10
- package/node_modules/typebox/build/value/clean/from_union.d.mts +1 -1
- package/node_modules/typebox/build/value/clean/from_union.mjs +1 -2
- package/node_modules/typebox/build/value/clone/clone.mjs +2 -73
- package/node_modules/typebox/build/value/codec/decode.mjs +4 -2
- package/node_modules/typebox/build/value/codec/encode.mjs +4 -2
- package/node_modules/typebox/build/value/codec/from_array.mjs +1 -4
- package/node_modules/typebox/build/value/codec/from_object.mjs +1 -4
- package/node_modules/typebox/build/value/codec/from_record.mjs +2 -7
- package/node_modules/typebox/build/value/codec/from_tuple.mjs +1 -4
- package/node_modules/typebox/build/value/codec/from_union.mjs +2 -3
- package/node_modules/typebox/build/value/convert/from_enum.mjs +3 -4
- package/node_modules/typebox/build/value/convert/from_template_literal.d.mts +1 -1
- package/node_modules/typebox/build/value/convert/from_template_literal.mjs +2 -3
- package/node_modules/typebox/build/value/convert/from_type.mjs +19 -21
- package/node_modules/typebox/build/value/create/from_enum.mjs +2 -2
- package/node_modules/typebox/build/value/create/from_type.mjs +23 -31
- package/node_modules/typebox/build/value/default/from_object.mjs +1 -1
- package/node_modules/typebox/build/value/default/from_type.mjs +8 -10
- package/node_modules/typebox/build/value/index.d.mts +0 -1
- package/node_modules/typebox/build/value/index.mjs +0 -1
- package/node_modules/typebox/build/value/repair/from_enum.mjs +2 -3
- package/node_modules/typebox/build/value/repair/from_type.mjs +24 -22
- package/node_modules/typebox/build/value/shared/union_priority_sort.d.mts +6 -2
- package/node_modules/typebox/build/value/shared/union_priority_sort.mjs +62 -26
- package/node_modules/typebox/build/value/value.d.mts +0 -1
- package/node_modules/typebox/build/value/value.mjs +0 -1
- package/node_modules/typebox/package.json +25 -25
- package/node_modules/typebox/readme.md +97 -80
- package/npm-shrinkwrap.json +59 -54
- package/package.json +10 -10
- package/dist/probe.runtime-DFt7PIoE.js +0 -3
- package/node_modules/@babel/runtime/helpers/AwaitValue.js +0 -4
- package/node_modules/@babel/runtime/helpers/applyDecs.js +0 -236
- package/node_modules/@babel/runtime/helpers/applyDecs2203.js +0 -184
- package/node_modules/@babel/runtime/helpers/applyDecs2203R.js +0 -191
- package/node_modules/@babel/runtime/helpers/applyDecs2301.js +0 -222
- package/node_modules/@babel/runtime/helpers/applyDecs2305.js +0 -133
- package/node_modules/@babel/runtime/helpers/classApplyDescriptorDestructureSet.js +0 -10
- package/node_modules/@babel/runtime/helpers/classApplyDescriptorGet.js +0 -4
- package/node_modules/@babel/runtime/helpers/classApplyDescriptorSet.js +0 -7
- package/node_modules/@babel/runtime/helpers/classCheckPrivateStaticAccess.js +0 -5
- package/node_modules/@babel/runtime/helpers/classCheckPrivateStaticFieldDescriptor.js +0 -4
- package/node_modules/@babel/runtime/helpers/classExtractFieldDescriptor.js +0 -5
- package/node_modules/@babel/runtime/helpers/classPrivateFieldDestructureSet.js +0 -7
- package/node_modules/@babel/runtime/helpers/classPrivateFieldGet.js +0 -7
- package/node_modules/@babel/runtime/helpers/classPrivateFieldSet.js +0 -7
- package/node_modules/@babel/runtime/helpers/classPrivateMethodGet.js +0 -5
- package/node_modules/@babel/runtime/helpers/classPrivateMethodSet.js +0 -4
- package/node_modules/@babel/runtime/helpers/classStaticPrivateFieldDestructureSet.js +0 -7
- package/node_modules/@babel/runtime/helpers/classStaticPrivateFieldSpecGet.js +0 -7
- package/node_modules/@babel/runtime/helpers/classStaticPrivateFieldSpecSet.js +0 -7
- package/node_modules/@babel/runtime/helpers/classStaticPrivateMethodSet.js +0 -4
- package/node_modules/@babel/runtime/helpers/decorate.js +0 -250
- package/node_modules/@babel/runtime/helpers/defineEnumerableProperties.js +0 -12
- package/node_modules/@babel/runtime/helpers/dispose.js +0 -28
- package/node_modules/@babel/runtime/helpers/esm/AwaitValue.js +0 -4
- package/node_modules/@babel/runtime/helpers/esm/applyDecs.js +0 -236
- package/node_modules/@babel/runtime/helpers/esm/applyDecs2203.js +0 -184
- package/node_modules/@babel/runtime/helpers/esm/applyDecs2203R.js +0 -191
- package/node_modules/@babel/runtime/helpers/esm/applyDecs2301.js +0 -222
- package/node_modules/@babel/runtime/helpers/esm/applyDecs2305.js +0 -133
- package/node_modules/@babel/runtime/helpers/esm/classApplyDescriptorDestructureSet.js +0 -10
- package/node_modules/@babel/runtime/helpers/esm/classApplyDescriptorGet.js +0 -4
- package/node_modules/@babel/runtime/helpers/esm/classApplyDescriptorSet.js +0 -7
- package/node_modules/@babel/runtime/helpers/esm/classCheckPrivateStaticAccess.js +0 -5
- package/node_modules/@babel/runtime/helpers/esm/classCheckPrivateStaticFieldDescriptor.js +0 -4
- package/node_modules/@babel/runtime/helpers/esm/classExtractFieldDescriptor.js +0 -5
- package/node_modules/@babel/runtime/helpers/esm/classPrivateFieldDestructureSet.js +0 -7
- package/node_modules/@babel/runtime/helpers/esm/classPrivateFieldGet.js +0 -7
- package/node_modules/@babel/runtime/helpers/esm/classPrivateFieldSet.js +0 -7
- package/node_modules/@babel/runtime/helpers/esm/classPrivateMethodGet.js +0 -5
- package/node_modules/@babel/runtime/helpers/esm/classPrivateMethodSet.js +0 -4
- package/node_modules/@babel/runtime/helpers/esm/classStaticPrivateFieldDestructureSet.js +0 -7
- package/node_modules/@babel/runtime/helpers/esm/classStaticPrivateFieldSpecGet.js +0 -7
- package/node_modules/@babel/runtime/helpers/esm/classStaticPrivateFieldSpecSet.js +0 -7
- package/node_modules/@babel/runtime/helpers/esm/classStaticPrivateMethodSet.js +0 -4
- package/node_modules/@babel/runtime/helpers/esm/decorate.js +0 -250
- package/node_modules/@babel/runtime/helpers/esm/defineEnumerableProperties.js +0 -12
- package/node_modules/@babel/runtime/helpers/esm/dispose.js +0 -28
- package/node_modules/@babel/runtime/helpers/esm/objectSpread.js +0 -14
- package/node_modules/@babel/runtime/helpers/esm/regeneratorRuntime.js +0 -77
- package/node_modules/@babel/runtime/helpers/esm/using.js +0 -12
- package/node_modules/@babel/runtime/helpers/objectSpread.js +0 -14
- package/node_modules/@babel/runtime/helpers/regeneratorRuntime.js +0 -77
- package/node_modules/@babel/runtime/helpers/using.js +0 -12
- package/node_modules/@babel/runtime/regenerator/index.js +0 -15
- package/node_modules/content-type/HISTORY.md +0 -29
- package/node_modules/content-type/index.js +0 -225
- package/node_modules/media-typer/HISTORY.md +0 -50
- package/node_modules/media-typer/index.js +0 -143
- package/node_modules/typebox/build/schema/engine/_guard.d.mts +0 -6
- package/node_modules/typebox/build/schema/engine/_guard.mjs +0 -26
- package/node_modules/typebox/build/schema/types/_guard.d.mts +0 -10
- package/node_modules/typebox/build/schema/types/_guard.mjs +0 -16
- package/node_modules/typebox/build/type/action/_optional.d.mts +0 -19
- package/node_modules/typebox/build/type/action/_optional.mjs +0 -40
- package/node_modules/typebox/build/type/action/_readonly.d.mts +0 -19
- package/node_modules/typebox/build/type/action/_readonly.mjs +0 -40
- package/node_modules/typebox/build/type/action/awaited.d.mts +0 -15
- package/node_modules/typebox/build/type/action/awaited.mjs +0 -15
- package/node_modules/typebox/build/type/action/options.d.mts +0 -11
- package/node_modules/typebox/build/type/action/options.mjs +0 -11
- package/node_modules/typebox/build/type/engine/awaited/instantiate.d.mts +0 -11
- package/node_modules/typebox/build/type/engine/awaited/instantiate.mjs +0 -20
- package/node_modules/typebox/build/type/engine/enum/enum_to_union.d.mts +0 -14
- package/node_modules/typebox/build/type/engine/enum/enum_to_union.mjs +0 -24
- package/node_modules/typebox/build/type/engine/options/index.d.mts +0 -1
- package/node_modules/typebox/build/type/engine/options/index.mjs +0 -1
- package/node_modules/typebox/build/type/engine/options/instantiate.d.mts +0 -8
- package/node_modules/typebox/build/type/extends/async_iterator.d.mts +0 -7
- package/node_modules/typebox/build/type/extends/async_iterator.mjs +0 -9
- package/node_modules/typebox/build/type/extends/iterator.d.mts +0 -7
- package/node_modules/typebox/build/type/extends/iterator.mjs +0 -9
- package/node_modules/typebox/build/type/extends/promise.d.mts +0 -7
- package/node_modules/typebox/build/type/extends/promise.mjs +0 -9
- package/node_modules/typebox/build/type/types/async_iterator.d.mts +0 -20
- package/node_modules/typebox/build/type/types/async_iterator.mjs +0 -28
- package/node_modules/typebox/build/type/types/base.d.mts +0 -50
- package/node_modules/typebox/build/type/types/base.mjs +0 -84
- package/node_modules/typebox/build/type/types/iterator.d.mts +0 -20
- package/node_modules/typebox/build/type/types/iterator.mjs +0 -28
- package/node_modules/typebox/build/type/types/promise.d.mts +0 -21
- package/node_modules/typebox/build/type/types/promise.mjs +0 -29
- package/node_modules/typebox/build/value/clean/from_base.d.mts +0 -2
- package/node_modules/typebox/build/value/clean/from_base.mjs +0 -4
- package/node_modules/typebox/build/value/convert/from_base.d.mts +0 -2
- package/node_modules/typebox/build/value/convert/from_base.mjs +0 -4
- package/node_modules/typebox/build/value/create/from_async_iterator.d.mts +0 -2
- package/node_modules/typebox/build/value/create/from_async_iterator.mjs +0 -5
- package/node_modules/typebox/build/value/create/from_base.d.mts +0 -2
- package/node_modules/typebox/build/value/create/from_base.mjs +0 -4
- package/node_modules/typebox/build/value/create/from_iterator.d.mts +0 -2
- package/node_modules/typebox/build/value/create/from_iterator.mjs +0 -5
- package/node_modules/typebox/build/value/create/from_promise.d.mts +0 -2
- package/node_modules/typebox/build/value/create/from_promise.mjs +0 -5
- package/node_modules/typebox/build/value/default/from_base.d.mts +0 -2
- package/node_modules/typebox/build/value/default/from_base.mjs +0 -5
- package/node_modules/typebox/build/value/mutate/error.d.mts +0 -3
- package/node_modules/typebox/build/value/mutate/error.mjs +0 -6
- package/node_modules/typebox/build/value/mutate/from_array.d.mts +0 -2
- package/node_modules/typebox/build/value/mutate/from_array.mjs +0 -16
- package/node_modules/typebox/build/value/mutate/from_object.d.mts +0 -2
- package/node_modules/typebox/build/value/mutate/from_object.mjs +0 -40
- package/node_modules/typebox/build/value/mutate/from_unknown.d.mts +0 -2
- package/node_modules/typebox/build/value/mutate/from_unknown.mjs +0 -7
- package/node_modules/typebox/build/value/mutate/from_value.d.mts +0 -2
- package/node_modules/typebox/build/value/mutate/from_value.mjs +0 -12
- package/node_modules/typebox/build/value/mutate/index.d.mts +0 -1
- package/node_modules/typebox/build/value/mutate/index.mjs +0 -1
- package/node_modules/typebox/build/value/mutate/mutate.d.mts +0 -11
- package/node_modules/typebox/build/value/mutate/mutate.mjs +0 -41
- package/node_modules/typebox/build/value/repair/from_base.d.mts +0 -2
- package/node_modules/typebox/build/value/repair/from_base.mjs +0 -8
- /package/node_modules/typebox/build/type/engine/{awaited → with}/index.d.mts +0 -0
- /package/node_modules/typebox/build/type/engine/{awaited → with}/index.mjs +0 -0
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/objectSpread2";
|
|
3
2
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
4
|
-
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
5
|
-
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
6
3
|
/*
|
|
7
4
|
Copyright 2015, 2016 OpenMarket Ltd
|
|
8
5
|
Copyright 2017 New Vector Ltd
|
|
@@ -45,7 +42,7 @@ var CodecName = /*#__PURE__*/function (CodecName) {
|
|
|
45
42
|
CodecName["OPUS"] = "opus"; // add more as needed
|
|
46
43
|
return CodecName;
|
|
47
44
|
}(CodecName || {}); // Used internally to specify modifications to codec parameters in SDP
|
|
48
|
-
export
|
|
45
|
+
export let CallState = /*#__PURE__*/function (CallState) {
|
|
49
46
|
CallState["Fledgling"] = "fledgling";
|
|
50
47
|
CallState["InviteSent"] = "invite_sent";
|
|
51
48
|
CallState["WaitLocalMedia"] = "wait_local_media";
|
|
@@ -57,22 +54,22 @@ export var CallState = /*#__PURE__*/function (CallState) {
|
|
|
57
54
|
CallState["Ended"] = "ended";
|
|
58
55
|
return CallState;
|
|
59
56
|
}({});
|
|
60
|
-
export
|
|
57
|
+
export let CallType = /*#__PURE__*/function (CallType) {
|
|
61
58
|
CallType["Voice"] = "voice";
|
|
62
59
|
CallType["Video"] = "video";
|
|
63
60
|
return CallType;
|
|
64
61
|
}({});
|
|
65
|
-
export
|
|
62
|
+
export let CallDirection = /*#__PURE__*/function (CallDirection) {
|
|
66
63
|
CallDirection["Inbound"] = "inbound";
|
|
67
64
|
CallDirection["Outbound"] = "outbound";
|
|
68
65
|
return CallDirection;
|
|
69
66
|
}({});
|
|
70
|
-
export
|
|
67
|
+
export let CallParty = /*#__PURE__*/function (CallParty) {
|
|
71
68
|
CallParty["Local"] = "local";
|
|
72
69
|
CallParty["Remote"] = "remote";
|
|
73
70
|
return CallParty;
|
|
74
71
|
}({});
|
|
75
|
-
export
|
|
72
|
+
export let CallEvent = /*#__PURE__*/function (CallEvent) {
|
|
76
73
|
CallEvent["Hangup"] = "hangup";
|
|
77
74
|
CallEvent["State"] = "state";
|
|
78
75
|
CallEvent["Error"] = "error";
|
|
@@ -94,7 +91,7 @@ export var CallEvent = /*#__PURE__*/function (CallEvent) {
|
|
|
94
91
|
CallEvent["PeerConnectionCreated"] = "peer_connection_created";
|
|
95
92
|
return CallEvent;
|
|
96
93
|
}({});
|
|
97
|
-
export
|
|
94
|
+
export let CallErrorCode = /*#__PURE__*/function (CallErrorCode) {
|
|
98
95
|
/** The user chose to end the call */
|
|
99
96
|
CallErrorCode["UserHangup"] = "user_hangup";
|
|
100
97
|
/** An error code when the local client failed to create an offer. */
|
|
@@ -173,23 +170,24 @@ export var CallErrorCode = /*#__PURE__*/function (CallErrorCode) {
|
|
|
173
170
|
/**
|
|
174
171
|
* The version field that we set in m.call.* events
|
|
175
172
|
*/
|
|
176
|
-
|
|
173
|
+
const VOIP_PROTO_VERSION = "1";
|
|
177
174
|
|
|
178
175
|
/** The fallback ICE server to use for STUN or TURN protocols. */
|
|
179
|
-
export
|
|
176
|
+
export const FALLBACK_ICE_SERVER = "stun:turn.matrix.org";
|
|
180
177
|
|
|
181
178
|
/** The length of time a call can be ringing for. */
|
|
182
|
-
|
|
179
|
+
const CALL_TIMEOUT_MS = 60 * 1000; // ms
|
|
183
180
|
/** The time after which we increment callLength */
|
|
184
|
-
|
|
181
|
+
const CALL_LENGTH_INTERVAL = 1000; // ms
|
|
185
182
|
/** The time after which we end the call, if ICE got disconnected */
|
|
186
|
-
|
|
183
|
+
const ICE_DISCONNECTED_TIMEOUT = 30 * 1000; // ms
|
|
187
184
|
/** The time after which we try a ICE restart, if ICE got disconnected */
|
|
188
|
-
|
|
185
|
+
const ICE_RECONNECTING_TIMEOUT = 2 * 1000; // ms
|
|
189
186
|
export class CallError extends Error {
|
|
190
187
|
constructor(code, msg, err) {
|
|
191
188
|
// Still don't think there's any way to have proper nested errors
|
|
192
189
|
super(msg + ": " + err);
|
|
190
|
+
_defineProperty(this, "code", void 0);
|
|
193
191
|
this.code = code;
|
|
194
192
|
}
|
|
195
193
|
}
|
|
@@ -197,7 +195,7 @@ export function genCallID() {
|
|
|
197
195
|
return Date.now().toString() + secureRandomString(16);
|
|
198
196
|
}
|
|
199
197
|
function getCodecParamMods(isPtt) {
|
|
200
|
-
|
|
198
|
+
const mods = [{
|
|
201
199
|
mediaType: "audio",
|
|
202
200
|
codec: "opus",
|
|
203
201
|
enableDtx: true,
|
|
@@ -230,25 +228,28 @@ function getTransceiverKey(purpose, kind) {
|
|
|
230
228
|
return purpose + ":" + kind;
|
|
231
229
|
}
|
|
232
230
|
export class MatrixCall extends TypedEventEmitter {
|
|
233
|
-
// Used to keep the timer for the delay before actually stopping our
|
|
234
|
-
// video track after muting (see setLocalVideoMuted)
|
|
235
|
-
|
|
236
|
-
// Used to allow connection without Video and Audio. To establish a webrtc connection without media a Data channel is
|
|
237
|
-
// needed At the moment this property is true if we allow MatrixClient with isVoipWithNoMediaAllowed = true
|
|
238
|
-
|
|
239
231
|
/**
|
|
240
232
|
* Construct a new Matrix Call.
|
|
241
233
|
* @param opts - Config options.
|
|
242
234
|
*/
|
|
243
235
|
constructor(opts) {
|
|
244
|
-
var _this, _opts$forceTURN;
|
|
245
236
|
super();
|
|
246
|
-
|
|
237
|
+
_defineProperty(this, "roomId", void 0);
|
|
238
|
+
_defineProperty(this, "callId", void 0);
|
|
239
|
+
_defineProperty(this, "invitee", void 0);
|
|
240
|
+
_defineProperty(this, "hangupParty", void 0);
|
|
241
|
+
_defineProperty(this, "hangupReason", void 0);
|
|
242
|
+
_defineProperty(this, "direction", void 0);
|
|
243
|
+
_defineProperty(this, "ourPartyId", void 0);
|
|
244
|
+
_defineProperty(this, "peerConn", void 0);
|
|
247
245
|
_defineProperty(this, "toDeviceSeq", 0);
|
|
248
246
|
// whether this call should have push-to-talk semantics
|
|
249
247
|
// This should be set by the consumer on incoming & outgoing calls.
|
|
250
248
|
_defineProperty(this, "isPtt", false);
|
|
251
249
|
_defineProperty(this, "_state", CallState.Fledgling);
|
|
250
|
+
_defineProperty(this, "client", void 0);
|
|
251
|
+
_defineProperty(this, "forceTURN", void 0);
|
|
252
|
+
_defineProperty(this, "turnServers", void 0);
|
|
252
253
|
// A queue for candidates waiting to go out.
|
|
253
254
|
// We try to amalgamate candidates into a single candidate message where
|
|
254
255
|
// possible
|
|
@@ -260,27 +261,57 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
260
261
|
_defineProperty(this, "transceivers", new Map());
|
|
261
262
|
_defineProperty(this, "inviteOrAnswerSent", false);
|
|
262
263
|
_defineProperty(this, "waitForLocalAVStream", false);
|
|
264
|
+
_defineProperty(this, "successor", void 0);
|
|
265
|
+
_defineProperty(this, "opponentMember", void 0);
|
|
266
|
+
_defineProperty(this, "opponentVersion", void 0);
|
|
267
|
+
// The party ID of the other side: undefined if we haven't chosen a partner
|
|
268
|
+
// yet, null if we have but they didn't send a party ID.
|
|
269
|
+
_defineProperty(this, "opponentPartyId", void 0);
|
|
270
|
+
_defineProperty(this, "opponentCaps", void 0);
|
|
271
|
+
_defineProperty(this, "iceDisconnectedTimeout", void 0);
|
|
272
|
+
_defineProperty(this, "iceReconnectionTimeOut", void 0);
|
|
273
|
+
_defineProperty(this, "inviteTimeout", void 0);
|
|
263
274
|
_defineProperty(this, "removeTrackListeners", new Map());
|
|
264
275
|
// The logic of when & if a call is on hold is nontrivial and explained in is*OnHold
|
|
265
276
|
// This flag represents whether we want the other party to be on hold
|
|
266
277
|
_defineProperty(this, "remoteOnHold", false);
|
|
278
|
+
// the stats for the call at the point it ended. We can't get these after we
|
|
279
|
+
// tear the call down, so we just grab a snapshot before we stop the call.
|
|
280
|
+
// The typescript definitions have this type as 'any' :(
|
|
281
|
+
_defineProperty(this, "callStatsAtEnd", void 0);
|
|
267
282
|
// Perfect negotiation state: https://www.w3.org/TR/webrtc/#perfect-negotiation-example
|
|
268
283
|
_defineProperty(this, "makingOffer", false);
|
|
269
284
|
_defineProperty(this, "ignoreOffer", false);
|
|
270
285
|
_defineProperty(this, "isSettingRemoteAnswerPending", false);
|
|
286
|
+
_defineProperty(this, "responsePromiseChain", void 0);
|
|
271
287
|
// If candidates arrive before we've picked an opponent (which, in particular,
|
|
272
288
|
// will happen if the opponent sends candidates eagerly before the user answers
|
|
273
289
|
// the call) we buffer them up here so we can then add the ones from the party we pick
|
|
274
290
|
_defineProperty(this, "remoteCandidateBuffer", new Map());
|
|
291
|
+
_defineProperty(this, "remoteAssertedIdentity", void 0);
|
|
292
|
+
_defineProperty(this, "remoteSDPStreamMetadata", void 0);
|
|
293
|
+
_defineProperty(this, "callLengthInterval", void 0);
|
|
294
|
+
_defineProperty(this, "callStartTime", void 0);
|
|
295
|
+
_defineProperty(this, "opponentDeviceId", void 0);
|
|
296
|
+
_defineProperty(this, "hasOpponentDeviceInfo", void 0);
|
|
297
|
+
_defineProperty(this, "opponentSessionId", void 0);
|
|
298
|
+
_defineProperty(this, "groupCallId", void 0);
|
|
299
|
+
// Used to keep the timer for the delay before actually stopping our
|
|
300
|
+
// video track after muting (see setLocalVideoMuted)
|
|
301
|
+
_defineProperty(this, "stopVideoTrackTimer", void 0);
|
|
302
|
+
// Used to allow connection without Video and Audio. To establish a webrtc connection without media a Data channel is
|
|
303
|
+
// needed At the moment this property is true if we allow MatrixClient with isVoipWithNoMediaAllowed = true
|
|
304
|
+
_defineProperty(this, "isOnlyDataChannelAllowed", void 0);
|
|
305
|
+
_defineProperty(this, "stats", void 0);
|
|
275
306
|
/**
|
|
276
307
|
* Internal
|
|
277
308
|
*/
|
|
278
309
|
_defineProperty(this, "gotLocalIceCandidate", event => {
|
|
279
310
|
if (event.candidate) {
|
|
280
311
|
if (this.candidatesEnded) {
|
|
281
|
-
logger.warn(
|
|
312
|
+
logger.warn(`Call ${this.callId} gotLocalIceCandidate() got candidate after candidates have ended!`);
|
|
282
313
|
}
|
|
283
|
-
logger.debug(
|
|
314
|
+
logger.debug(`Call ${this.callId} got local ICE ${event.candidate.sdpMid} ${event.candidate.candidate}`);
|
|
284
315
|
if (this.callHasEnded()) return;
|
|
285
316
|
|
|
286
317
|
// As with the offer, note we need to make a copy of this object, not
|
|
@@ -293,15 +324,14 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
293
324
|
}
|
|
294
325
|
});
|
|
295
326
|
_defineProperty(this, "onIceGatheringStateChange", event => {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
if (((_this$peerConn = this.peerConn) === null || _this$peerConn === void 0 ? void 0 : _this$peerConn.iceGatheringState) === "complete") {
|
|
327
|
+
logger.debug(`Call ${this.callId} onIceGatheringStateChange() ice gathering state changed to ${this.peerConn.iceGatheringState}`);
|
|
328
|
+
if (this.peerConn?.iceGatheringState === "complete") {
|
|
299
329
|
this.queueCandidate(null); // We should leave it to WebRTC to announce the end
|
|
300
|
-
logger.debug(
|
|
330
|
+
logger.debug(`Call ${this.callId} onIceGatheringStateChange() ice gathering state complete, set candidates have ended`);
|
|
301
331
|
}
|
|
302
332
|
});
|
|
303
333
|
_defineProperty(this, "getLocalOfferFailed", err => {
|
|
304
|
-
logger.error(
|
|
334
|
+
logger.error(`Call ${this.callId} getLocalOfferFailed() running`, err);
|
|
305
335
|
this.emit(CallEvent.Error, new CallError(CallErrorCode.LocalOfferFailed, "Failed to get local offer!", err), this);
|
|
306
336
|
this.terminate(CallParty.Local, CallErrorCode.LocalOfferFailed, false);
|
|
307
337
|
});
|
|
@@ -310,7 +340,7 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
310
340
|
this.successor.getUserMediaFailed(err);
|
|
311
341
|
return;
|
|
312
342
|
}
|
|
313
|
-
logger.warn(
|
|
343
|
+
logger.warn(`Call ${this.callId} getUserMediaFailed() failed to get user media - ending call`, err);
|
|
314
344
|
this.emit(CallEvent.Error, new CallError(CallErrorCode.NoUserMedia, "Couldn't start capturing media! Is your microphone set up and does this app have permission?", err), this);
|
|
315
345
|
this.terminate(CallParty.Local, CallErrorCode.NoUserMedia, false);
|
|
316
346
|
});
|
|
@@ -319,20 +349,19 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
319
349
|
this.successor.placeCallFailed(err);
|
|
320
350
|
return;
|
|
321
351
|
}
|
|
322
|
-
logger.warn(
|
|
352
|
+
logger.warn(`Call ${this.callId} placeCallWithCallFeeds() failed - ending call`, err);
|
|
323
353
|
this.emit(CallEvent.Error, new CallError(CallErrorCode.IceFailed, "Couldn't start call! Invalid ICE server configuration.", err), this);
|
|
324
354
|
this.terminate(CallParty.Local, CallErrorCode.IceFailed, false);
|
|
325
355
|
});
|
|
326
356
|
_defineProperty(this, "onIceConnectionStateChanged", () => {
|
|
327
|
-
var _this$peerConn2, _this$peerConn3, _this$peerConn$iceCon, _this$peerConn4, _this$peerConn5, _this$peerConn8;
|
|
328
357
|
if (this.callHasEnded()) {
|
|
329
358
|
return; // because ICE can still complete as we're ending the call
|
|
330
359
|
}
|
|
331
|
-
logger.debug(
|
|
360
|
+
logger.debug(`Call ${this.callId} onIceConnectionStateChanged() running (state=${this.peerConn?.iceConnectionState}, conn=${this.peerConn?.connectionState})`);
|
|
332
361
|
|
|
333
362
|
// ideally we'd consider the call to be connected when we get media but
|
|
334
363
|
// chrome doesn't implement any of the 'onstarted' events yet
|
|
335
|
-
if (["connected", "completed"].includes(
|
|
364
|
+
if (["connected", "completed"].includes(this.peerConn?.iceConnectionState ?? "")) {
|
|
336
365
|
clearTimeout(this.iceDisconnectedTimeout);
|
|
337
366
|
this.iceDisconnectedTimeout = undefined;
|
|
338
367
|
if (this.iceReconnectionTimeOut) {
|
|
@@ -345,34 +374,31 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
345
374
|
this.emit(CallEvent.LengthChanged, Math.round((Date.now() - this.callStartTime) / 1000), this);
|
|
346
375
|
}, CALL_LENGTH_INTERVAL);
|
|
347
376
|
}
|
|
348
|
-
} else if (
|
|
349
|
-
var _this$peerConn6;
|
|
377
|
+
} else if (this.peerConn?.iceConnectionState == "failed") {
|
|
350
378
|
this.candidatesEnded = false;
|
|
351
379
|
// Firefox for Android does not yet have support for restartIce()
|
|
352
380
|
// (the types say it's always defined though, so we have to cast
|
|
353
381
|
// to prevent typescript from warning).
|
|
354
|
-
if (
|
|
355
|
-
var _this$peerConn7;
|
|
382
|
+
if (this.peerConn?.restartIce) {
|
|
356
383
|
this.candidatesEnded = false;
|
|
357
|
-
logger.debug(
|
|
384
|
+
logger.debug(`Call ${this.callId} onIceConnectionStateChanged() ice restart (state=${this.peerConn?.iceConnectionState})`);
|
|
358
385
|
this.peerConn.restartIce();
|
|
359
386
|
} else {
|
|
360
|
-
logger.info(
|
|
387
|
+
logger.info(`Call ${this.callId} onIceConnectionStateChanged() hanging up call (ICE failed and no ICE restart method)`);
|
|
361
388
|
this.hangup(CallErrorCode.IceFailed, false);
|
|
362
389
|
}
|
|
363
|
-
} else if (
|
|
390
|
+
} else if (this.peerConn?.iceConnectionState == "disconnected") {
|
|
364
391
|
this.candidatesEnded = false;
|
|
365
392
|
this.iceReconnectionTimeOut = setTimeout(() => {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
if ((_this$peerConn1 = this.peerConn) !== null && _this$peerConn1 !== void 0 && _this$peerConn1.restartIce) {
|
|
393
|
+
logger.info(`Call ${this.callId} onIceConnectionStateChanged() ICE restarting because of ICE disconnected, (state=${this.peerConn?.iceConnectionState}, conn=${this.peerConn?.connectionState})`);
|
|
394
|
+
if (this.peerConn?.restartIce) {
|
|
369
395
|
this.candidatesEnded = false;
|
|
370
396
|
this.peerConn.restartIce();
|
|
371
397
|
}
|
|
372
398
|
this.iceReconnectionTimeOut = undefined;
|
|
373
399
|
}, ICE_RECONNECTING_TIMEOUT);
|
|
374
400
|
this.iceDisconnectedTimeout = setTimeout(() => {
|
|
375
|
-
logger.info(
|
|
401
|
+
logger.info(`Call ${this.callId} onIceConnectionStateChanged() hanging up call (ICE disconnected for too long)`);
|
|
376
402
|
this.hangup(CallErrorCode.IceFailed, false);
|
|
377
403
|
}, ICE_DISCONNECTED_TIMEOUT);
|
|
378
404
|
this.state = CallState.Connecting;
|
|
@@ -383,26 +409,25 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
383
409
|
// Experimenting in Chrome, this happens after 5 or 6 seconds, which is probably
|
|
384
410
|
// fast enough.
|
|
385
411
|
if (this.isPtt && ["failed", "disconnected"].includes(this.peerConn.iceConnectionState)) {
|
|
386
|
-
for (
|
|
412
|
+
for (const feed of this.getRemoteFeeds()) {
|
|
387
413
|
feed.setAudioVideoMuted(true, true);
|
|
388
414
|
}
|
|
389
415
|
}
|
|
390
416
|
});
|
|
391
417
|
_defineProperty(this, "onSignallingStateChanged", () => {
|
|
392
|
-
|
|
393
|
-
logger.debug("Call ".concat(this.callId, " onSignallingStateChanged() running (state=").concat((_this$peerConn10 = this.peerConn) === null || _this$peerConn10 === void 0 ? void 0 : _this$peerConn10.signalingState, ")"));
|
|
418
|
+
logger.debug(`Call ${this.callId} onSignallingStateChanged() running (state=${this.peerConn?.signalingState})`);
|
|
394
419
|
});
|
|
395
420
|
_defineProperty(this, "onTrack", ev => {
|
|
396
421
|
if (ev.streams.length === 0) {
|
|
397
|
-
logger.warn(
|
|
422
|
+
logger.warn(`Call ${this.callId} onTrack() called with streamless track streamless (kind=${ev.track.kind})`);
|
|
398
423
|
return;
|
|
399
424
|
}
|
|
400
|
-
|
|
425
|
+
const stream = ev.streams[0];
|
|
401
426
|
this.pushRemoteFeed(stream);
|
|
402
427
|
if (!this.removeTrackListeners.has(stream)) {
|
|
403
|
-
|
|
428
|
+
const onRemoveTrack = () => {
|
|
404
429
|
if (stream.getTracks().length === 0) {
|
|
405
|
-
logger.info(
|
|
430
|
+
logger.info(`Call ${this.callId} onTrack() removing track (streamId=${stream.id})`);
|
|
406
431
|
this.deleteFeedByStream(stream);
|
|
407
432
|
stream.removeEventListener("removetrack", onRemoveTrack);
|
|
408
433
|
this.removeTrackListeners.delete(stream);
|
|
@@ -415,16 +440,16 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
415
440
|
_defineProperty(this, "onDataChannel", ev => {
|
|
416
441
|
this.emit(CallEvent.DataChannel, ev.channel, this);
|
|
417
442
|
});
|
|
418
|
-
_defineProperty(this, "onNegotiationNeeded",
|
|
419
|
-
logger.info(
|
|
420
|
-
if (
|
|
421
|
-
logger.info(
|
|
443
|
+
_defineProperty(this, "onNegotiationNeeded", async () => {
|
|
444
|
+
logger.info(`Call ${this.callId} onNegotiationNeeded() negotiation is needed!`);
|
|
445
|
+
if (this.state !== CallState.CreateOffer && this.opponentVersion === 0) {
|
|
446
|
+
logger.info(`Call ${this.callId} onNegotiationNeeded() opponent does not support renegotiation: ignoring negotiationneeded event`);
|
|
422
447
|
return;
|
|
423
448
|
}
|
|
424
|
-
|
|
425
|
-
})
|
|
449
|
+
this.queueGotLocalOffer();
|
|
450
|
+
});
|
|
426
451
|
_defineProperty(this, "onHangupReceived", msg => {
|
|
427
|
-
logger.debug(
|
|
452
|
+
logger.debug(`Call ${this.callId} onHangupReceived() running`);
|
|
428
453
|
|
|
429
454
|
// party ID must match (our chosen partner hanging up the call) or be undefined (we haven't chosen
|
|
430
455
|
// a partner yet but we're treating the hangup as a reject as per VoIP v0)
|
|
@@ -432,16 +457,16 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
432
457
|
// default reason is user_hangup
|
|
433
458
|
this.terminate(CallParty.Remote, msg.reason || CallErrorCode.UserHangup, true);
|
|
434
459
|
} else {
|
|
435
|
-
logger.info(
|
|
460
|
+
logger.info(`Call ${this.callId} onHangupReceived() ignoring message from party ID ${msg.party_id}: our partner is ${this.opponentPartyId}`);
|
|
436
461
|
}
|
|
437
462
|
});
|
|
438
463
|
_defineProperty(this, "onRejectReceived", msg => {
|
|
439
|
-
logger.debug(
|
|
464
|
+
logger.debug(`Call ${this.callId} onRejectReceived() running`);
|
|
440
465
|
|
|
441
466
|
// No need to check party_id for reject because if we'd received either
|
|
442
467
|
// an answer or reject, we wouldn't be in state InviteSent
|
|
443
468
|
|
|
444
|
-
|
|
469
|
+
const shouldTerminate =
|
|
445
470
|
// reject events also end the call if it's ringing: it's another of
|
|
446
471
|
// our devices rejecting the call.
|
|
447
472
|
[CallState.InviteSent, CallState.Ringing].includes(this.state) ||
|
|
@@ -451,18 +476,18 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
451
476
|
if (shouldTerminate) {
|
|
452
477
|
this.terminate(CallParty.Remote, msg.reason || CallErrorCode.UserHangup, true);
|
|
453
478
|
} else {
|
|
454
|
-
logger.debug(
|
|
479
|
+
logger.debug(`Call ${this.callId} onRejectReceived() called in wrong state (state=${this.state})`);
|
|
455
480
|
}
|
|
456
481
|
});
|
|
457
482
|
_defineProperty(this, "onAnsweredElsewhere", msg => {
|
|
458
|
-
logger.debug(
|
|
483
|
+
logger.debug(`Call ${this.callId} onAnsweredElsewhere() running`);
|
|
459
484
|
this.terminate(CallParty.Remote, CallErrorCode.AnsweredElsewhere, true);
|
|
460
485
|
});
|
|
461
486
|
this.roomId = opts.roomId;
|
|
462
487
|
this.invitee = opts.invitee;
|
|
463
488
|
this.client = opts.client;
|
|
464
489
|
if (!this.client.deviceId) throw new Error("Client must have a device ID to start calls");
|
|
465
|
-
this.forceTURN =
|
|
490
|
+
this.forceTURN = opts.forceTURN ?? false;
|
|
466
491
|
this.ourPartyId = this.client.deviceId;
|
|
467
492
|
this.opponentDeviceId = opts.opponentDeviceId;
|
|
468
493
|
this.opponentSessionId = opts.opponentSessionId;
|
|
@@ -474,7 +499,7 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
474
499
|
urls: [FALLBACK_ICE_SERVER]
|
|
475
500
|
});
|
|
476
501
|
}
|
|
477
|
-
for (
|
|
502
|
+
for (const server of this.turnServers) {
|
|
478
503
|
checkObjectHasKeys(server, ["urls"]);
|
|
479
504
|
}
|
|
480
505
|
this.callId = genCallID();
|
|
@@ -486,22 +511,16 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
486
511
|
* Place a voice call to this room.
|
|
487
512
|
* @throws If you have not specified a listener for 'error' events.
|
|
488
513
|
*/
|
|
489
|
-
placeVoiceCall() {
|
|
490
|
-
|
|
491
|
-
return _asyncToGenerator(function* () {
|
|
492
|
-
yield _this2.placeCall(true, false);
|
|
493
|
-
})();
|
|
514
|
+
async placeVoiceCall() {
|
|
515
|
+
await this.placeCall(true, false);
|
|
494
516
|
}
|
|
495
517
|
|
|
496
518
|
/**
|
|
497
519
|
* Place a video call to this room.
|
|
498
520
|
* @throws If you have not specified a listener for 'error' events.
|
|
499
521
|
*/
|
|
500
|
-
placeVideoCall() {
|
|
501
|
-
|
|
502
|
-
return _asyncToGenerator(function* () {
|
|
503
|
-
yield _this3.placeCall(true, true);
|
|
504
|
-
})();
|
|
522
|
+
async placeVideoCall() {
|
|
523
|
+
await this.placeCall(true, true);
|
|
505
524
|
}
|
|
506
525
|
|
|
507
526
|
/**
|
|
@@ -510,7 +529,7 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
510
529
|
* @param options - An object providing configuration options for the data channel.
|
|
511
530
|
*/
|
|
512
531
|
createDataChannel(label, options) {
|
|
513
|
-
|
|
532
|
+
const dataChannel = this.peerConn.createDataChannel(label, options);
|
|
514
533
|
this.emit(CallEvent.DataChannel, dataChannel, this);
|
|
515
534
|
return dataChannel;
|
|
516
535
|
}
|
|
@@ -536,7 +555,7 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
536
555
|
return this._state;
|
|
537
556
|
}
|
|
538
557
|
set state(state) {
|
|
539
|
-
|
|
558
|
+
const oldState = this._state;
|
|
540
559
|
this._state = state;
|
|
541
560
|
this.emit(CallEvent.State, state, oldState, this);
|
|
542
561
|
}
|
|
@@ -546,32 +565,26 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
546
565
|
return this.hasUserMediaVideoSender || this.hasRemoteUserMediaVideoTrack ? CallType.Video : CallType.Voice;
|
|
547
566
|
}
|
|
548
567
|
get hasLocalUserMediaVideoTrack() {
|
|
549
|
-
|
|
550
|
-
return !!((_this$localUsermediaS = this.localUsermediaStream) !== null && _this$localUsermediaS !== void 0 && _this$localUsermediaS.getVideoTracks().length);
|
|
568
|
+
return !!this.localUsermediaStream?.getVideoTracks().length;
|
|
551
569
|
}
|
|
552
570
|
get hasRemoteUserMediaVideoTrack() {
|
|
553
571
|
return this.getRemoteFeeds().some(feed => {
|
|
554
|
-
|
|
555
|
-
return feed.purpose === SDPStreamMetadataPurpose.Usermedia && ((_feed$stream = feed.stream) === null || _feed$stream === void 0 ? void 0 : _feed$stream.getVideoTracks().length);
|
|
572
|
+
return feed.purpose === SDPStreamMetadataPurpose.Usermedia && feed.stream?.getVideoTracks().length;
|
|
556
573
|
});
|
|
557
574
|
}
|
|
558
575
|
get hasLocalUserMediaAudioTrack() {
|
|
559
|
-
|
|
560
|
-
return !!((_this$localUsermediaS2 = this.localUsermediaStream) !== null && _this$localUsermediaS2 !== void 0 && _this$localUsermediaS2.getAudioTracks().length);
|
|
576
|
+
return !!this.localUsermediaStream?.getAudioTracks().length;
|
|
561
577
|
}
|
|
562
578
|
get hasRemoteUserMediaAudioTrack() {
|
|
563
579
|
return this.getRemoteFeeds().some(feed => {
|
|
564
|
-
|
|
565
|
-
return feed.purpose === SDPStreamMetadataPurpose.Usermedia && !!((_feed$stream2 = feed.stream) !== null && _feed$stream2 !== void 0 && _feed$stream2.getAudioTracks().length);
|
|
580
|
+
return feed.purpose === SDPStreamMetadataPurpose.Usermedia && !!feed.stream?.getAudioTracks().length;
|
|
566
581
|
});
|
|
567
582
|
}
|
|
568
583
|
get hasUserMediaAudioSender() {
|
|
569
|
-
|
|
570
|
-
return Boolean((_this$transceivers$ge = this.transceivers.get(getTransceiverKey(SDPStreamMetadataPurpose.Usermedia, "audio"))) === null || _this$transceivers$ge === void 0 ? void 0 : _this$transceivers$ge.sender);
|
|
584
|
+
return Boolean(this.transceivers.get(getTransceiverKey(SDPStreamMetadataPurpose.Usermedia, "audio"))?.sender);
|
|
571
585
|
}
|
|
572
586
|
get hasUserMediaVideoSender() {
|
|
573
|
-
|
|
574
|
-
return Boolean((_this$transceivers$ge2 = this.transceivers.get(getTransceiverKey(SDPStreamMetadataPurpose.Usermedia, "video"))) === null || _this$transceivers$ge2 === void 0 ? void 0 : _this$transceivers$ge2.sender);
|
|
587
|
+
return Boolean(this.transceivers.get(getTransceiverKey(SDPStreamMetadataPurpose.Usermedia, "video"))?.sender);
|
|
575
588
|
}
|
|
576
589
|
get localUsermediaFeed() {
|
|
577
590
|
return this.getLocalFeeds().find(feed => feed.purpose === SDPStreamMetadataPurpose.Usermedia);
|
|
@@ -580,12 +593,10 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
580
593
|
return this.getLocalFeeds().find(feed => feed.purpose === SDPStreamMetadataPurpose.Screenshare);
|
|
581
594
|
}
|
|
582
595
|
get localUsermediaStream() {
|
|
583
|
-
|
|
584
|
-
return (_this$localUsermediaF = this.localUsermediaFeed) === null || _this$localUsermediaF === void 0 ? void 0 : _this$localUsermediaF.stream;
|
|
596
|
+
return this.localUsermediaFeed?.stream;
|
|
585
597
|
}
|
|
586
598
|
get localScreensharingStream() {
|
|
587
|
-
|
|
588
|
-
return (_this$localScreenshar = this.localScreensharingFeed) === null || _this$localScreenshar === void 0 ? void 0 : _this$localScreenshar.stream;
|
|
599
|
+
return this.localScreensharingFeed?.stream;
|
|
589
600
|
}
|
|
590
601
|
get remoteUsermediaFeed() {
|
|
591
602
|
return this.getRemoteFeeds().find(feed => feed.purpose === SDPStreamMetadataPurpose.Usermedia);
|
|
@@ -594,12 +605,10 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
594
605
|
return this.getRemoteFeeds().find(feed => feed.purpose === SDPStreamMetadataPurpose.Screenshare);
|
|
595
606
|
}
|
|
596
607
|
get remoteUsermediaStream() {
|
|
597
|
-
|
|
598
|
-
return (_this$remoteUsermedia = this.remoteUsermediaFeed) === null || _this$remoteUsermedia === void 0 ? void 0 : _this$remoteUsermedia.stream;
|
|
608
|
+
return this.remoteUsermediaFeed?.stream;
|
|
599
609
|
}
|
|
600
610
|
get remoteScreensharingStream() {
|
|
601
|
-
|
|
602
|
-
return (_this$remoteScreensha = this.remoteScreensharingFeed) === null || _this$remoteScreensha === void 0 ? void 0 : _this$remoteScreensha.stream;
|
|
611
|
+
return this.remoteScreensharingFeed?.stream;
|
|
603
612
|
}
|
|
604
613
|
getFeedByStreamId(streamId) {
|
|
605
614
|
return this.getFeeds().find(feed => feed.stream.id === streamId);
|
|
@@ -628,36 +637,31 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
628
637
|
getRemoteFeeds() {
|
|
629
638
|
return this.feeds.filter(feed => !feed.isLocal());
|
|
630
639
|
}
|
|
631
|
-
initOpponentCrypto() {
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
//
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
}
|
|
644
|
-
var userId = _this4.invitee || ((_this4$getOpponentMem = _this4.getOpponentMember()) === null || _this4$getOpponentMem === void 0 ? void 0 : _this4$getOpponentMem.userId);
|
|
645
|
-
if (!userId) throw new Error("Couldn't find opponent user ID to init crypto");
|
|
640
|
+
async initOpponentCrypto() {
|
|
641
|
+
if (!this.opponentDeviceId) return;
|
|
642
|
+
if (!this.client.getUseE2eForGroupCall()) return;
|
|
643
|
+
// It's possible to want E2EE and yet not have the means to manage E2EE
|
|
644
|
+
// ourselves (for example if the client is a RoomWidgetClient)
|
|
645
|
+
if (!this.client.getCrypto()) {
|
|
646
|
+
// All we know is the device ID
|
|
647
|
+
this.hasOpponentDeviceInfo = true;
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
650
|
+
const userId = this.invitee || this.getOpponentMember()?.userId;
|
|
651
|
+
if (!userId) throw new Error("Couldn't find opponent user ID to init crypto");
|
|
646
652
|
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
})();
|
|
653
|
+
// Here we were calling `MatrixClient.crypto.deviceList.downloadKeys` which is not supported by the rust cryptography.
|
|
654
|
+
this.hasOpponentDeviceInfo = false;
|
|
655
|
+
throw new GroupCallUnknownDeviceError(userId);
|
|
651
656
|
}
|
|
652
657
|
|
|
653
658
|
/**
|
|
654
659
|
* Generates and returns localSDPStreamMetadata
|
|
655
660
|
* @returns localSDPStreamMetadata
|
|
656
661
|
*/
|
|
657
|
-
getLocalSDPStreamMetadata() {
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
for (var localFeed of this.getLocalFeeds()) {
|
|
662
|
+
getLocalSDPStreamMetadata(updateStreamIds = false) {
|
|
663
|
+
const metadata = {};
|
|
664
|
+
for (const localFeed of this.getLocalFeeds()) {
|
|
661
665
|
if (updateStreamIds) {
|
|
662
666
|
localFeed.sdpMetadataStreamId = localFeed.stream.id;
|
|
663
667
|
}
|
|
@@ -684,16 +688,16 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
684
688
|
this.pushRemoteFeedWithoutMetadata(stream);
|
|
685
689
|
return;
|
|
686
690
|
}
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
+
const userId = this.getOpponentMember().userId;
|
|
692
|
+
const purpose = this.remoteSDPStreamMetadata[stream.id].purpose;
|
|
693
|
+
const audioMuted = this.remoteSDPStreamMetadata[stream.id].audio_muted;
|
|
694
|
+
const videoMuted = this.remoteSDPStreamMetadata[stream.id].video_muted;
|
|
691
695
|
if (!purpose) {
|
|
692
|
-
logger.warn(
|
|
696
|
+
logger.warn(`Call ${this.callId} pushRemoteFeed() ignoring stream because we didn't get any metadata about it (streamId=${stream.id})`);
|
|
693
697
|
return;
|
|
694
698
|
}
|
|
695
699
|
if (this.getFeedByStreamId(stream.id)) {
|
|
696
|
-
logger.warn(
|
|
700
|
+
logger.warn(`Call ${this.callId} pushRemoteFeed() ignoring stream because we already have a feed for it (streamId=${stream.id})`);
|
|
697
701
|
return;
|
|
698
702
|
}
|
|
699
703
|
this.feeds.push(new CallFeed({
|
|
@@ -708,29 +712,28 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
708
712
|
videoMuted
|
|
709
713
|
}));
|
|
710
714
|
this.emit(CallEvent.FeedsChanged, this.feeds, this);
|
|
711
|
-
logger.info(
|
|
715
|
+
logger.info(`Call ${this.callId} pushRemoteFeed() pushed stream (streamId=${stream.id}, active=${stream.active}, purpose=${purpose})`);
|
|
712
716
|
}
|
|
713
717
|
|
|
714
718
|
/**
|
|
715
719
|
* This method is used ONLY if the other client doesn't support sending SDPStreamMetadata
|
|
716
720
|
*/
|
|
717
721
|
pushRemoteFeedWithoutMetadata(stream) {
|
|
718
|
-
|
|
719
|
-
var userId = this.getOpponentMember().userId;
|
|
722
|
+
const userId = this.getOpponentMember().userId;
|
|
720
723
|
// We can guess the purpose here since the other client can only send one stream
|
|
721
|
-
|
|
722
|
-
|
|
724
|
+
const purpose = SDPStreamMetadataPurpose.Usermedia;
|
|
725
|
+
const oldRemoteStream = this.feeds.find(feed => !feed.isLocal())?.stream;
|
|
723
726
|
|
|
724
727
|
// Note that we check by ID and always set the remote stream: Chrome appears
|
|
725
728
|
// to make new stream objects when transceiver directionality is changed and the 'active'
|
|
726
729
|
// status of streams change - Dave
|
|
727
730
|
// If we already have a stream, check this stream has the same id
|
|
728
731
|
if (oldRemoteStream && stream.id !== oldRemoteStream.id) {
|
|
729
|
-
logger.warn(
|
|
732
|
+
logger.warn(`Call ${this.callId} pushRemoteFeedWithoutMetadata() ignoring new stream because we already have stream (streamId=${stream.id})`);
|
|
730
733
|
return;
|
|
731
734
|
}
|
|
732
735
|
if (this.getFeedByStreamId(stream.id)) {
|
|
733
|
-
logger.warn(
|
|
736
|
+
logger.warn(`Call ${this.callId} pushRemoteFeedWithoutMetadata() ignoring stream because we already have a feed for it (streamId=${stream.id})`);
|
|
734
737
|
return;
|
|
735
738
|
}
|
|
736
739
|
this.feeds.push(new CallFeed({
|
|
@@ -745,11 +748,10 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
745
748
|
purpose
|
|
746
749
|
}));
|
|
747
750
|
this.emit(CallEvent.FeedsChanged, this.feeds, this);
|
|
748
|
-
logger.info(
|
|
751
|
+
logger.info(`Call ${this.callId} pushRemoteFeedWithoutMetadata() pushed stream (streamId=${stream.id}, active=${stream.active})`);
|
|
749
752
|
}
|
|
750
|
-
pushNewLocalFeed(stream, purpose) {
|
|
751
|
-
|
|
752
|
-
var userId = this.client.getUserId();
|
|
753
|
+
pushNewLocalFeed(stream, purpose, addToPeerConnection = true) {
|
|
754
|
+
const userId = this.client.getUserId();
|
|
753
755
|
|
|
754
756
|
// Tracks don't always start off enabled, eg. chrome will give a disabled
|
|
755
757
|
// audio track if you ask for user media audio and already had one that
|
|
@@ -757,7 +759,7 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
757
759
|
setTracksEnabled(stream.getAudioTracks(), true);
|
|
758
760
|
setTracksEnabled(stream.getVideoTracks(), true);
|
|
759
761
|
if (this.getFeedByStreamId(stream.id)) {
|
|
760
|
-
logger.warn(
|
|
762
|
+
logger.warn(`Call ${this.callId} pushNewLocalFeed() ignoring stream because we already have a feed for it (streamId=${stream.id})`);
|
|
761
763
|
return;
|
|
762
764
|
}
|
|
763
765
|
this.pushLocalFeed(new CallFeed({
|
|
@@ -777,25 +779,23 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
777
779
|
* @param callFeed - to push
|
|
778
780
|
* @param addToPeerConnection - whether to add the tracks to the peer connection
|
|
779
781
|
*/
|
|
780
|
-
pushLocalFeed(callFeed) {
|
|
781
|
-
var _this5 = this;
|
|
782
|
-
var addToPeerConnection = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
782
|
+
pushLocalFeed(callFeed, addToPeerConnection = true) {
|
|
783
783
|
if (this.feeds.some(feed => callFeed.stream.id === feed.stream.id)) {
|
|
784
|
-
logger.info(
|
|
784
|
+
logger.info(`Call ${this.callId} pushLocalFeed() ignoring duplicate local stream (streamId=${callFeed.stream.id})`);
|
|
785
785
|
return;
|
|
786
786
|
}
|
|
787
787
|
this.feeds.push(callFeed);
|
|
788
788
|
if (addToPeerConnection) {
|
|
789
|
-
|
|
790
|
-
logger.info(
|
|
791
|
-
|
|
792
|
-
if (
|
|
789
|
+
for (const track of callFeed.stream.getTracks()) {
|
|
790
|
+
logger.info(`Call ${this.callId} pushLocalFeed() adding track to peer connection (id=${track.id}, kind=${track.kind}, streamId=${callFeed.stream.id}, streamPurpose=${callFeed.purpose}, enabled=${track.enabled})`);
|
|
791
|
+
const tKey = getTransceiverKey(callFeed.purpose, track.kind);
|
|
792
|
+
if (this.transceivers.has(tKey)) {
|
|
793
793
|
// we already have a sender, so we re-use it. We try to re-use transceivers as much
|
|
794
794
|
// as possible because they can't be removed once added, so otherwise they just
|
|
795
795
|
// accumulate which makes the SDP very large very quickly: in fact it only takes
|
|
796
796
|
// about 6 video tracks to exceed the maximum size of an Olm-encrypted
|
|
797
797
|
// Matrix event.
|
|
798
|
-
|
|
798
|
+
const transceiver = this.transceivers.get(tKey);
|
|
799
799
|
transceiver.sender.replaceTrack(track);
|
|
800
800
|
// set the direction to indicate we're going to start sending again
|
|
801
801
|
// (this will trigger the re-negotiation)
|
|
@@ -805,22 +805,19 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
805
805
|
// doesn't yet implement RTCRTPSender.setStreams()
|
|
806
806
|
// (https://bugzilla.mozilla.org/show_bug.cgi?id=1510802) so we'd have no way to group the
|
|
807
807
|
// two tracks together into a stream.
|
|
808
|
-
|
|
808
|
+
const newSender = this.peerConn.addTrack(track, callFeed.stream);
|
|
809
809
|
|
|
810
810
|
// now go & fish for the new transceiver
|
|
811
|
-
|
|
811
|
+
const newTransceiver = this.peerConn.getTransceivers().find(t => t.sender === newSender);
|
|
812
812
|
if (newTransceiver) {
|
|
813
|
-
|
|
813
|
+
this.transceivers.set(tKey, newTransceiver);
|
|
814
814
|
} else {
|
|
815
|
-
logger.warn(
|
|
815
|
+
logger.warn(`Call ${this.callId} pushLocalFeed() didn't find a matching transceiver after adding track!`);
|
|
816
816
|
}
|
|
817
817
|
}
|
|
818
|
-
};
|
|
819
|
-
for (var track of callFeed.stream.getTracks()) {
|
|
820
|
-
_loop();
|
|
821
818
|
}
|
|
822
819
|
}
|
|
823
|
-
logger.info(
|
|
820
|
+
logger.info(`Call ${this.callId} pushLocalFeed() pushed stream (id=${callFeed.stream.id}, active=${callFeed.stream.active}, purpose=${callFeed.purpose})`);
|
|
824
821
|
this.emit(CallEvent.FeedsChanged, this.feeds, this);
|
|
825
822
|
}
|
|
826
823
|
|
|
@@ -830,14 +827,14 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
830
827
|
* @param callFeed - to remove
|
|
831
828
|
*/
|
|
832
829
|
removeLocalFeed(callFeed) {
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
for (
|
|
830
|
+
const audioTransceiverKey = getTransceiverKey(callFeed.purpose, "audio");
|
|
831
|
+
const videoTransceiverKey = getTransceiverKey(callFeed.purpose, "video");
|
|
832
|
+
for (const transceiverKey of [audioTransceiverKey, videoTransceiverKey]) {
|
|
836
833
|
// this is slightly mixing the track and transceiver API but is basically just shorthand.
|
|
837
834
|
// There is no way to actually remove a transceiver, so this just sets it to inactive
|
|
838
835
|
// (or recvonly) and replaces the source with nothing.
|
|
839
836
|
if (this.transceivers.has(transceiverKey)) {
|
|
840
|
-
|
|
837
|
+
const transceiver = this.transceivers.get(transceiverKey);
|
|
841
838
|
if (transceiver.sender) this.peerConn.removeTrack(transceiver.sender);
|
|
842
839
|
}
|
|
843
840
|
}
|
|
@@ -847,7 +844,7 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
847
844
|
this.deleteFeed(callFeed);
|
|
848
845
|
}
|
|
849
846
|
deleteAllFeeds() {
|
|
850
|
-
for (
|
|
847
|
+
for (const feed of this.feeds) {
|
|
851
848
|
if (!feed.isLocal() || !this.groupCallId) {
|
|
852
849
|
feed.dispose();
|
|
853
850
|
}
|
|
@@ -856,9 +853,9 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
856
853
|
this.emit(CallEvent.FeedsChanged, this.feeds, this);
|
|
857
854
|
}
|
|
858
855
|
deleteFeedByStream(stream) {
|
|
859
|
-
|
|
856
|
+
const feed = this.getFeedByStreamId(stream.id);
|
|
860
857
|
if (!feed) {
|
|
861
|
-
logger.warn(
|
|
858
|
+
logger.warn(`Call ${this.callId} deleteFeedByStream() didn't find the feed to delete (streamId=${stream.id})`);
|
|
862
859
|
return;
|
|
863
860
|
}
|
|
864
861
|
this.deleteFeed(feed);
|
|
@@ -870,109 +867,98 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
870
867
|
}
|
|
871
868
|
|
|
872
869
|
// The typescript definitions have this type as 'any' :(
|
|
873
|
-
getCurrentCallStats() {
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
var stats = [];
|
|
890
|
-
statsReport.forEach(item => {
|
|
891
|
-
stats.push(item);
|
|
892
|
-
});
|
|
893
|
-
return stats;
|
|
894
|
-
})();
|
|
870
|
+
async getCurrentCallStats() {
|
|
871
|
+
if (this.callHasEnded()) {
|
|
872
|
+
return this.callStatsAtEnd;
|
|
873
|
+
}
|
|
874
|
+
return this.collectCallStats();
|
|
875
|
+
}
|
|
876
|
+
async collectCallStats() {
|
|
877
|
+
// This happens when the call fails before it starts.
|
|
878
|
+
// For example when we fail to get capture sources
|
|
879
|
+
if (!this.peerConn) return;
|
|
880
|
+
const statsReport = await this.peerConn.getStats();
|
|
881
|
+
const stats = [];
|
|
882
|
+
statsReport.forEach(item => {
|
|
883
|
+
stats.push(item);
|
|
884
|
+
});
|
|
885
|
+
return stats;
|
|
895
886
|
}
|
|
896
887
|
|
|
897
888
|
/**
|
|
898
889
|
* Configure this call from an invite event. Used by MatrixClient.
|
|
899
890
|
* @param event - The m.call.invite event
|
|
900
891
|
*/
|
|
901
|
-
initWithInvite(event) {
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
_this8.state = CallState.Ended;
|
|
959
|
-
_this8.stopAllMedia();
|
|
960
|
-
if (_this8.peerConn.signalingState != "closed") {
|
|
961
|
-
_this8.peerConn.close();
|
|
962
|
-
}
|
|
963
|
-
(_this8$stats = _this8.stats) === null || _this8$stats === void 0 || _this8$stats.removeStatsReportGatherer(_this8.callId);
|
|
964
|
-
_this8.emit(CallEvent.Hangup, _this8);
|
|
965
|
-
}
|
|
966
|
-
}, invite.lifetime - event.getLocalAge());
|
|
967
|
-
var onState = state => {
|
|
968
|
-
if (state !== CallState.Ringing) {
|
|
969
|
-
clearTimeout(ringingTimer);
|
|
970
|
-
_this8.off(CallEvent.State, onState);
|
|
892
|
+
async initWithInvite(event) {
|
|
893
|
+
const invite = event.getContent();
|
|
894
|
+
this.direction = CallDirection.Inbound;
|
|
895
|
+
|
|
896
|
+
// make sure we have valid turn creds. Unless something's gone wrong, it should
|
|
897
|
+
// poll and keep the credentials valid so this should be instant.
|
|
898
|
+
const haveTurnCreds = await this.client.checkTurnServers();
|
|
899
|
+
if (!haveTurnCreds) {
|
|
900
|
+
logger.warn(`Call ${this.callId} initWithInvite() failed to get TURN credentials! Proceeding with call anyway...`);
|
|
901
|
+
}
|
|
902
|
+
const sdpStreamMetadata = SDPStreamMetadataKey.findIn(invite);
|
|
903
|
+
if (sdpStreamMetadata) {
|
|
904
|
+
this.updateRemoteSDPStreamMetadata(sdpStreamMetadata);
|
|
905
|
+
} else {
|
|
906
|
+
logger.debug(`Call ${this.callId} initWithInvite() did not get any SDPStreamMetadata! Can not send/receive multiple streams`);
|
|
907
|
+
}
|
|
908
|
+
this.peerConn = this.createPeerConnection();
|
|
909
|
+
this.emit(CallEvent.PeerConnectionCreated, this.peerConn, this);
|
|
910
|
+
// we must set the party ID before await-ing on anything: the call event
|
|
911
|
+
// handler will start giving us more call events (eg. candidates) so if
|
|
912
|
+
// we haven't set the party ID, we'll ignore them.
|
|
913
|
+
this.chooseOpponent(event);
|
|
914
|
+
await this.initOpponentCrypto();
|
|
915
|
+
try {
|
|
916
|
+
await this.peerConn.setRemoteDescription(invite.offer);
|
|
917
|
+
logger.debug(`Call ${this.callId} initWithInvite() set remote description: ${invite.offer.type}`);
|
|
918
|
+
await this.addBufferedIceCandidates();
|
|
919
|
+
} catch (e) {
|
|
920
|
+
logger.debug(`Call ${this.callId} initWithInvite() failed to set remote description`, e);
|
|
921
|
+
this.terminate(CallParty.Local, CallErrorCode.SetRemoteDescription, false);
|
|
922
|
+
return;
|
|
923
|
+
}
|
|
924
|
+
const remoteStream = this.feeds.find(feed => !feed.isLocal())?.stream;
|
|
925
|
+
|
|
926
|
+
// According to previous comments in this file, firefox at some point did not
|
|
927
|
+
// add streams until media started arriving on them. Testing latest firefox
|
|
928
|
+
// (81 at time of writing), this is no longer a problem, so let's do it the correct way.
|
|
929
|
+
//
|
|
930
|
+
// For example in case of no media webrtc connections like screen share only call we have to allow webrtc
|
|
931
|
+
// connections without remote media. In this case we always use a data channel. At the moment we allow as well
|
|
932
|
+
// only data channel as media in the WebRTC connection with this setup here.
|
|
933
|
+
if (!this.isOnlyDataChannelAllowed && (!remoteStream || remoteStream.getTracks().length === 0)) {
|
|
934
|
+
logger.error(`Call ${this.callId} initWithInvite() no remote stream or no tracks after setting remote description!`);
|
|
935
|
+
this.terminate(CallParty.Local, CallErrorCode.SetRemoteDescription, false);
|
|
936
|
+
return;
|
|
937
|
+
}
|
|
938
|
+
this.state = CallState.Ringing;
|
|
939
|
+
if (event.getLocalAge()) {
|
|
940
|
+
// Time out the call if it's ringing for too long
|
|
941
|
+
const ringingTimer = setTimeout(() => {
|
|
942
|
+
if (this.state == CallState.Ringing) {
|
|
943
|
+
logger.debug(`Call ${this.callId} initWithInvite() invite has expired. Hanging up.`);
|
|
944
|
+
this.hangupParty = CallParty.Remote; // effectively
|
|
945
|
+
this.state = CallState.Ended;
|
|
946
|
+
this.stopAllMedia();
|
|
947
|
+
if (this.peerConn.signalingState != "closed") {
|
|
948
|
+
this.peerConn.close();
|
|
971
949
|
}
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
950
|
+
this.stats?.removeStatsReportGatherer(this.callId);
|
|
951
|
+
this.emit(CallEvent.Hangup, this);
|
|
952
|
+
}
|
|
953
|
+
}, invite.lifetime - event.getLocalAge());
|
|
954
|
+
const onState = state => {
|
|
955
|
+
if (state !== CallState.Ringing) {
|
|
956
|
+
clearTimeout(ringingTimer);
|
|
957
|
+
this.off(CallEvent.State, onState);
|
|
958
|
+
}
|
|
959
|
+
};
|
|
960
|
+
this.on(CallEvent.State, onState);
|
|
961
|
+
}
|
|
976
962
|
}
|
|
977
963
|
|
|
978
964
|
/**
|
|
@@ -988,65 +974,61 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
988
974
|
shouldAnswerWithMediaType(wantedValue, valueOfTheOtherSide, type) {
|
|
989
975
|
if (wantedValue && !valueOfTheOtherSide) {
|
|
990
976
|
// TODO: Figure out how to do this
|
|
991
|
-
logger.warn(
|
|
977
|
+
logger.warn(`Call ${this.callId} shouldAnswerWithMediaType() unable to answer with ${type} because the other side isn't sending it either.`);
|
|
992
978
|
return false;
|
|
993
979
|
} else if (!isNullOrUndefined(wantedValue) && wantedValue !== valueOfTheOtherSide && !this.opponentSupportsSDPStreamMetadata()) {
|
|
994
|
-
logger.warn(
|
|
980
|
+
logger.warn(`Call ${this.callId} shouldAnswerWithMediaType() unable to answer with ${type}=${wantedValue} because the other side doesn't support it. Answering with ${type}=${valueOfTheOtherSide}.`);
|
|
995
981
|
return valueOfTheOtherSide;
|
|
996
982
|
}
|
|
997
|
-
return wantedValue
|
|
983
|
+
return wantedValue ?? valueOfTheOtherSide;
|
|
998
984
|
}
|
|
999
985
|
|
|
1000
986
|
/**
|
|
1001
987
|
* Answer a call.
|
|
1002
988
|
*/
|
|
1003
|
-
answer(audio, video) {
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
} else {
|
|
1042
|
-
_this9.getUserMediaFailed(e);
|
|
1043
|
-
return;
|
|
1044
|
-
}
|
|
989
|
+
async answer(audio, video) {
|
|
990
|
+
if (this.inviteOrAnswerSent) return;
|
|
991
|
+
// TODO: Figure out how to do this
|
|
992
|
+
if (audio === false && video === false) throw new Error("You CANNOT answer a call without media");
|
|
993
|
+
if (!this.localUsermediaStream && !this.waitForLocalAVStream) {
|
|
994
|
+
const prevState = this.state;
|
|
995
|
+
const answerWithAudio = this.shouldAnswerWithMediaType(audio, this.hasRemoteUserMediaAudioTrack, "audio");
|
|
996
|
+
const answerWithVideo = this.shouldAnswerWithMediaType(video, this.hasRemoteUserMediaVideoTrack, "video");
|
|
997
|
+
this.state = CallState.WaitLocalMedia;
|
|
998
|
+
this.waitForLocalAVStream = true;
|
|
999
|
+
try {
|
|
1000
|
+
const stream = await this.client.getMediaHandler().getUserMediaStream(answerWithAudio, answerWithVideo);
|
|
1001
|
+
this.waitForLocalAVStream = false;
|
|
1002
|
+
const usermediaFeed = new CallFeed({
|
|
1003
|
+
client: this.client,
|
|
1004
|
+
roomId: this.roomId,
|
|
1005
|
+
userId: this.client.getUserId(),
|
|
1006
|
+
deviceId: this.client.getDeviceId() ?? undefined,
|
|
1007
|
+
stream,
|
|
1008
|
+
purpose: SDPStreamMetadataPurpose.Usermedia,
|
|
1009
|
+
audioMuted: false,
|
|
1010
|
+
videoMuted: false
|
|
1011
|
+
});
|
|
1012
|
+
const feeds = [usermediaFeed];
|
|
1013
|
+
if (this.localScreensharingFeed) {
|
|
1014
|
+
feeds.push(this.localScreensharingFeed);
|
|
1015
|
+
}
|
|
1016
|
+
this.answerWithCallFeeds(feeds);
|
|
1017
|
+
} catch (e) {
|
|
1018
|
+
if (answerWithVideo) {
|
|
1019
|
+
// Try to answer without video
|
|
1020
|
+
logger.warn(`Call ${this.callId} answer() failed to getUserMedia(), trying to getUserMedia() without video`);
|
|
1021
|
+
this.state = prevState;
|
|
1022
|
+
this.waitForLocalAVStream = false;
|
|
1023
|
+
await this.answer(answerWithAudio, false);
|
|
1024
|
+
} else {
|
|
1025
|
+
this.getUserMediaFailed(e);
|
|
1026
|
+
return;
|
|
1045
1027
|
}
|
|
1046
|
-
} else if (_this9.waitForLocalAVStream) {
|
|
1047
|
-
_this9.state = CallState.WaitLocalMedia;
|
|
1048
1028
|
}
|
|
1049
|
-
}
|
|
1029
|
+
} else if (this.waitForLocalAVStream) {
|
|
1030
|
+
this.state = CallState.WaitLocalMedia;
|
|
1031
|
+
}
|
|
1050
1032
|
}
|
|
1051
1033
|
answerWithCallFeeds(callFeeds) {
|
|
1052
1034
|
if (this.inviteOrAnswerSent) return;
|
|
@@ -1059,15 +1041,15 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
1059
1041
|
* @param newCall - The new call.
|
|
1060
1042
|
*/
|
|
1061
1043
|
replacedBy(newCall) {
|
|
1062
|
-
logger.debug(
|
|
1044
|
+
logger.debug(`Call ${this.callId} replacedBy() running (newCallId=${newCall.callId})`);
|
|
1063
1045
|
if (this.state === CallState.WaitLocalMedia) {
|
|
1064
|
-
logger.debug(
|
|
1046
|
+
logger.debug(`Call ${this.callId} replacedBy() telling new call to wait for local media (newCallId=${newCall.callId})`);
|
|
1065
1047
|
newCall.waitForLocalAVStream = true;
|
|
1066
1048
|
} else if ([CallState.CreateOffer, CallState.InviteSent].includes(this.state)) {
|
|
1067
1049
|
if (newCall.direction === CallDirection.Outbound) {
|
|
1068
1050
|
newCall.queueGotCallFeedsForAnswer([]);
|
|
1069
1051
|
} else {
|
|
1070
|
-
logger.debug(
|
|
1052
|
+
logger.debug(`Call ${this.callId} replacedBy() handing local stream to new call(newCallId=${newCall.callId})`);
|
|
1071
1053
|
newCall.queueGotCallFeedsForAnswer(this.getLocalFeeds().map(feed => feed.clone()));
|
|
1072
1054
|
}
|
|
1073
1055
|
}
|
|
@@ -1083,11 +1065,11 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
1083
1065
|
*/
|
|
1084
1066
|
hangup(reason, suppressEvent) {
|
|
1085
1067
|
if (this.callHasEnded()) return;
|
|
1086
|
-
logger.debug(
|
|
1068
|
+
logger.debug(`Call ${this.callId} hangup() ending call (reason=${reason})`);
|
|
1087
1069
|
this.terminate(CallParty.Local, reason, !suppressEvent);
|
|
1088
1070
|
// We don't want to send hangup here if we didn't even get to sending an invite
|
|
1089
1071
|
if ([CallState.Fledgling, CallState.WaitLocalMedia].includes(this.state)) return;
|
|
1090
|
-
|
|
1072
|
+
const content = {};
|
|
1091
1073
|
// Don't send UserHangup reason to older clients
|
|
1092
1074
|
if (this.opponentVersion && this.opponentVersion !== 0 || reason !== CallErrorCode.UserHangup) {
|
|
1093
1075
|
content["reason"] = reason;
|
|
@@ -1105,7 +1087,7 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
1105
1087
|
throw Error("Call must be in 'ringing' state to reject!");
|
|
1106
1088
|
}
|
|
1107
1089
|
if (this.opponentVersion === 0) {
|
|
1108
|
-
logger.info(
|
|
1090
|
+
logger.info(`Call ${this.callId} reject() opponent version is less than 1: sending hangup instead of reject (opponentVersion=${this.opponentVersion})`);
|
|
1109
1091
|
this.hangup(CallErrorCode.UserHangup, true);
|
|
1110
1092
|
return;
|
|
1111
1093
|
}
|
|
@@ -1119,26 +1101,23 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
1119
1101
|
* @param audio - should add an audio track
|
|
1120
1102
|
* @param video - should add an video track
|
|
1121
1103
|
*/
|
|
1122
|
-
upgradeCall(audio, video) {
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
_this0.emit(CallEvent.Error, new CallError(CallErrorCode.NoUserMedia, "Failed to get camera access: ", error), _this0);
|
|
1140
|
-
}
|
|
1141
|
-
})();
|
|
1104
|
+
async upgradeCall(audio, video) {
|
|
1105
|
+
// We don't do call downgrades
|
|
1106
|
+
if (!audio && !video) return;
|
|
1107
|
+
if (!this.opponentSupportsSDPStreamMetadata()) return;
|
|
1108
|
+
try {
|
|
1109
|
+
logger.debug(`Call ${this.callId} upgradeCall() upgrading call (audio=${audio}, video=${video})`);
|
|
1110
|
+
const getAudio = audio || this.hasLocalUserMediaAudioTrack;
|
|
1111
|
+
const getVideo = video || this.hasLocalUserMediaVideoTrack;
|
|
1112
|
+
|
|
1113
|
+
// updateLocalUsermediaStream() will take the tracks, use them as
|
|
1114
|
+
// replacement and throw the stream away, so it isn't reusable
|
|
1115
|
+
const stream = await this.client.getMediaHandler().getUserMediaStream(getAudio, getVideo, false);
|
|
1116
|
+
await this.updateLocalUsermediaStream(stream, audio, video);
|
|
1117
|
+
} catch (error) {
|
|
1118
|
+
logger.error(`Call ${this.callId} upgradeCall() failed to upgrade the call`, error);
|
|
1119
|
+
this.emit(CallEvent.Error, new CallError(CallErrorCode.NoUserMedia, "Failed to get camera access: ", error), this);
|
|
1120
|
+
}
|
|
1142
1121
|
}
|
|
1143
1122
|
|
|
1144
1123
|
/**
|
|
@@ -1163,46 +1142,43 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
1163
1142
|
* @param opts - screen sharing options
|
|
1164
1143
|
* @returns new screensharing state
|
|
1165
1144
|
*/
|
|
1166
|
-
setScreensharingEnabled(enabled, opts) {
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
return false;
|
|
1176
|
-
}
|
|
1145
|
+
async setScreensharingEnabled(enabled, opts) {
|
|
1146
|
+
// Skip if there is nothing to do
|
|
1147
|
+
if (enabled && this.isScreensharing()) {
|
|
1148
|
+
logger.warn(`Call ${this.callId} setScreensharingEnabled() there is already a screensharing stream - there is nothing to do!`);
|
|
1149
|
+
return true;
|
|
1150
|
+
} else if (!enabled && !this.isScreensharing()) {
|
|
1151
|
+
logger.warn(`Call ${this.callId} setScreensharingEnabled() there already isn't a screensharing stream - there is nothing to do!`);
|
|
1152
|
+
return false;
|
|
1153
|
+
}
|
|
1177
1154
|
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
return false;
|
|
1192
|
-
}
|
|
1193
|
-
} else {
|
|
1194
|
-
var audioTransceiver = _this1.transceivers.get(getTransceiverKey(SDPStreamMetadataPurpose.Screenshare, "audio"));
|
|
1195
|
-
var videoTransceiver = _this1.transceivers.get(getTransceiverKey(SDPStreamMetadataPurpose.Screenshare, "video"));
|
|
1196
|
-
for (var transceiver of [audioTransceiver, videoTransceiver]) {
|
|
1197
|
-
// this is slightly mixing the track and transceiver API but is basically just shorthand
|
|
1198
|
-
// for removing the sender.
|
|
1199
|
-
if (transceiver && transceiver.sender) _this1.peerConn.removeTrack(transceiver.sender);
|
|
1200
|
-
}
|
|
1201
|
-
_this1.client.getMediaHandler().stopScreensharingStream(_this1.localScreensharingStream);
|
|
1202
|
-
_this1.deleteFeedByStream(_this1.localScreensharingStream);
|
|
1155
|
+
// Fallback to replaceTrack()
|
|
1156
|
+
if (!this.opponentSupportsSDPStreamMetadata()) {
|
|
1157
|
+
return this.setScreensharingEnabledWithoutMetadataSupport(enabled, opts);
|
|
1158
|
+
}
|
|
1159
|
+
logger.debug(`Call ${this.callId} setScreensharingEnabled() running (enabled=${enabled})`);
|
|
1160
|
+
if (enabled) {
|
|
1161
|
+
try {
|
|
1162
|
+
const stream = await this.client.getMediaHandler().getScreensharingStream(opts);
|
|
1163
|
+
if (!stream) return false;
|
|
1164
|
+
this.pushNewLocalFeed(stream, SDPStreamMetadataPurpose.Screenshare);
|
|
1165
|
+
return true;
|
|
1166
|
+
} catch (err) {
|
|
1167
|
+
logger.error(`Call ${this.callId} setScreensharingEnabled() failed to get screen-sharing stream:`, err);
|
|
1203
1168
|
return false;
|
|
1204
1169
|
}
|
|
1205
|
-
}
|
|
1170
|
+
} else {
|
|
1171
|
+
const audioTransceiver = this.transceivers.get(getTransceiverKey(SDPStreamMetadataPurpose.Screenshare, "audio"));
|
|
1172
|
+
const videoTransceiver = this.transceivers.get(getTransceiverKey(SDPStreamMetadataPurpose.Screenshare, "video"));
|
|
1173
|
+
for (const transceiver of [audioTransceiver, videoTransceiver]) {
|
|
1174
|
+
// this is slightly mixing the track and transceiver API but is basically just shorthand
|
|
1175
|
+
// for removing the sender.
|
|
1176
|
+
if (transceiver && transceiver.sender) this.peerConn.removeTrack(transceiver.sender);
|
|
1177
|
+
}
|
|
1178
|
+
this.client.getMediaHandler().stopScreensharingStream(this.localScreensharingStream);
|
|
1179
|
+
this.deleteFeedByStream(this.localScreensharingStream);
|
|
1180
|
+
return false;
|
|
1181
|
+
}
|
|
1206
1182
|
}
|
|
1207
1183
|
|
|
1208
1184
|
/**
|
|
@@ -1212,99 +1188,85 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
1212
1188
|
* @param opts - screen sharing options
|
|
1213
1189
|
* @returns new screensharing state
|
|
1214
1190
|
*/
|
|
1215
|
-
setScreensharingEnabledWithoutMetadataSupport(enabled, opts) {
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
return true;
|
|
1229
|
-
} catch (err) {
|
|
1230
|
-
logger.error("Call ".concat(_this10.callId, " setScreensharingEnabledWithoutMetadataSupport() failed to get screen-sharing stream:"), err);
|
|
1231
|
-
return false;
|
|
1232
|
-
}
|
|
1233
|
-
} else {
|
|
1234
|
-
var _this10$localUsermedi, _this10$transceivers$2;
|
|
1235
|
-
var _track = (_this10$localUsermedi = _this10.localUsermediaStream) === null || _this10$localUsermedi === void 0 ? void 0 : _this10$localUsermedi.getTracks().find(track => track.kind === "video");
|
|
1236
|
-
var _sender = (_this10$transceivers$2 = _this10.transceivers.get(getTransceiverKey(SDPStreamMetadataPurpose.Usermedia, "video"))) === null || _this10$transceivers$2 === void 0 ? void 0 : _this10$transceivers$2.sender;
|
|
1237
|
-
_sender === null || _sender === void 0 || _sender.replaceTrack(_track !== null && _track !== void 0 ? _track : null);
|
|
1238
|
-
_this10.client.getMediaHandler().stopScreensharingStream(_this10.localScreensharingStream);
|
|
1239
|
-
_this10.deleteFeedByStream(_this10.localScreensharingStream);
|
|
1191
|
+
async setScreensharingEnabledWithoutMetadataSupport(enabled, opts) {
|
|
1192
|
+
logger.debug(`Call ${this.callId} setScreensharingEnabledWithoutMetadataSupport() running (enabled=${enabled})`);
|
|
1193
|
+
if (enabled) {
|
|
1194
|
+
try {
|
|
1195
|
+
const stream = await this.client.getMediaHandler().getScreensharingStream(opts);
|
|
1196
|
+
if (!stream) return false;
|
|
1197
|
+
const track = stream.getTracks().find(track => track.kind === "video");
|
|
1198
|
+
const sender = this.transceivers.get(getTransceiverKey(SDPStreamMetadataPurpose.Usermedia, "video"))?.sender;
|
|
1199
|
+
sender?.replaceTrack(track ?? null);
|
|
1200
|
+
this.pushNewLocalFeed(stream, SDPStreamMetadataPurpose.Screenshare, false);
|
|
1201
|
+
return true;
|
|
1202
|
+
} catch (err) {
|
|
1203
|
+
logger.error(`Call ${this.callId} setScreensharingEnabledWithoutMetadataSupport() failed to get screen-sharing stream:`, err);
|
|
1240
1204
|
return false;
|
|
1241
1205
|
}
|
|
1242
|
-
}
|
|
1206
|
+
} else {
|
|
1207
|
+
const track = this.localUsermediaStream?.getTracks().find(track => track.kind === "video");
|
|
1208
|
+
const sender = this.transceivers.get(getTransceiverKey(SDPStreamMetadataPurpose.Usermedia, "video"))?.sender;
|
|
1209
|
+
sender?.replaceTrack(track ?? null);
|
|
1210
|
+
this.client.getMediaHandler().stopScreensharingStream(this.localScreensharingStream);
|
|
1211
|
+
this.deleteFeedByStream(this.localScreensharingStream);
|
|
1212
|
+
return false;
|
|
1213
|
+
}
|
|
1243
1214
|
}
|
|
1244
1215
|
|
|
1245
1216
|
/**
|
|
1246
1217
|
* Replaces/adds the tracks from the passed stream to the localUsermediaStream
|
|
1247
1218
|
* @param stream - to use a replacement for the local usermedia stream
|
|
1248
1219
|
*/
|
|
1249
|
-
updateLocalUsermediaStream(stream) {
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
track.stop();
|
|
1269
|
-
}
|
|
1270
|
-
for (var _track2 of stream.getTracks()) {
|
|
1271
|
-
_this11.localUsermediaStream.addTrack(_track2);
|
|
1272
|
-
}
|
|
1220
|
+
async updateLocalUsermediaStream(stream, forceAudio = false, forceVideo = false) {
|
|
1221
|
+
const callFeed = this.localUsermediaFeed;
|
|
1222
|
+
const audioEnabled = forceAudio || !callFeed.isAudioMuted() && !this.remoteOnHold;
|
|
1223
|
+
const videoEnabled = forceVideo || !callFeed.isVideoMuted() && !this.remoteOnHold;
|
|
1224
|
+
logger.log(`Call ${this.callId} updateLocalUsermediaStream() running (streamId=${stream.id}, audio=${audioEnabled}, video=${videoEnabled})`);
|
|
1225
|
+
setTracksEnabled(stream.getAudioTracks(), audioEnabled);
|
|
1226
|
+
setTracksEnabled(stream.getVideoTracks(), videoEnabled);
|
|
1227
|
+
|
|
1228
|
+
// We want to keep the same stream id, so we replace the tracks rather
|
|
1229
|
+
// than the whole stream.
|
|
1230
|
+
|
|
1231
|
+
// Firstly, we replace the tracks in our localUsermediaStream.
|
|
1232
|
+
for (const track of this.localUsermediaStream.getTracks()) {
|
|
1233
|
+
this.localUsermediaStream.removeTrack(track);
|
|
1234
|
+
track.stop();
|
|
1235
|
+
}
|
|
1236
|
+
for (const track of stream.getTracks()) {
|
|
1237
|
+
this.localUsermediaStream.addTrack(track);
|
|
1238
|
+
}
|
|
1273
1239
|
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
}
|
|
1240
|
+
// Then replace the old tracks, if possible.
|
|
1241
|
+
for (const track of stream.getTracks()) {
|
|
1242
|
+
const tKey = getTransceiverKey(SDPStreamMetadataPurpose.Usermedia, track.kind);
|
|
1243
|
+
const transceiver = this.transceivers.get(tKey);
|
|
1244
|
+
const oldSender = transceiver?.sender;
|
|
1245
|
+
let added = false;
|
|
1246
|
+
if (oldSender) {
|
|
1247
|
+
try {
|
|
1248
|
+
logger.info(`Call ${this.callId} updateLocalUsermediaStream() replacing track (id=${track.id}, kind=${track.kind}, streamId=${stream.id}, streamPurpose=${callFeed.purpose})`);
|
|
1249
|
+
await oldSender.replaceTrack(track);
|
|
1250
|
+
// Set the direction to indicate we're going to be sending.
|
|
1251
|
+
// This is only necessary in the cases where we're upgrading
|
|
1252
|
+
// the call to video after downgrading it.
|
|
1253
|
+
transceiver.direction = transceiver.direction === "inactive" ? "sendonly" : "sendrecv";
|
|
1254
|
+
added = true;
|
|
1255
|
+
} catch (error) {
|
|
1256
|
+
logger.warn(`Call ${this.callId} updateLocalUsermediaStream() replaceTrack failed: adding new transceiver instead`, error);
|
|
1292
1257
|
}
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
}
|
|
1258
|
+
}
|
|
1259
|
+
if (!added) {
|
|
1260
|
+
logger.info(`Call ${this.callId} updateLocalUsermediaStream() adding track to peer connection (id=${track.id}, kind=${track.kind}, streamId=${stream.id}, streamPurpose=${callFeed.purpose})`);
|
|
1261
|
+
const newSender = this.peerConn.addTrack(track, this.localUsermediaStream);
|
|
1262
|
+
const newTransceiver = this.peerConn.getTransceivers().find(t => t.sender === newSender);
|
|
1263
|
+
if (newTransceiver) {
|
|
1264
|
+
this.transceivers.set(tKey, newTransceiver);
|
|
1265
|
+
} else {
|
|
1266
|
+
logger.warn(`Call ${this.callId} updateLocalUsermediaStream() couldn't find matching transceiver for newly added track!`);
|
|
1302
1267
|
}
|
|
1303
|
-
};
|
|
1304
|
-
for (var _track3 of stream.getTracks()) {
|
|
1305
|
-
yield* _loop2();
|
|
1306
1268
|
}
|
|
1307
|
-
}
|
|
1269
|
+
}
|
|
1308
1270
|
}
|
|
1309
1271
|
|
|
1310
1272
|
/**
|
|
@@ -1312,55 +1274,50 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
1312
1274
|
* @param muted - True to mute the outbound video.
|
|
1313
1275
|
* @returns the new mute state
|
|
1314
1276
|
*/
|
|
1315
|
-
setLocalVideoMuted(muted) {
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
(_this12$localUsermedi = _this12.localUsermediaFeed) === null || _this12$localUsermedi === void 0 || _this12$localUsermedi.setAudioVideoMuted(null, muted);
|
|
1333
|
-
yield _this12.upgradeCall(false, true);
|
|
1334
|
-
return _this12.isLocalVideoMuted();
|
|
1335
|
-
}
|
|
1277
|
+
async setLocalVideoMuted(muted) {
|
|
1278
|
+
logger.log(`Call ${this.callId} setLocalVideoMuted() running ${muted}`);
|
|
1279
|
+
|
|
1280
|
+
// if we were still thinking about stopping and removing the video
|
|
1281
|
+
// track: don't, because we want it back.
|
|
1282
|
+
if (!muted && this.stopVideoTrackTimer !== undefined) {
|
|
1283
|
+
clearTimeout(this.stopVideoTrackTimer);
|
|
1284
|
+
this.stopVideoTrackTimer = undefined;
|
|
1285
|
+
}
|
|
1286
|
+
if (!(await this.client.getMediaHandler().hasVideoDevice())) {
|
|
1287
|
+
return this.isLocalVideoMuted();
|
|
1288
|
+
}
|
|
1289
|
+
if (!this.hasUserMediaVideoSender && !muted) {
|
|
1290
|
+
this.localUsermediaFeed?.setAudioVideoMuted(null, muted);
|
|
1291
|
+
await this.upgradeCall(false, true);
|
|
1292
|
+
return this.isLocalVideoMuted();
|
|
1293
|
+
}
|
|
1336
1294
|
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
})();
|
|
1295
|
+
// we may not have a video track - if not, re-request usermedia
|
|
1296
|
+
if (!muted && this.localUsermediaStream.getVideoTracks().length === 0) {
|
|
1297
|
+
const stream = await this.client.getMediaHandler().getUserMediaStream(true, true);
|
|
1298
|
+
await this.updateLocalUsermediaStream(stream);
|
|
1299
|
+
}
|
|
1300
|
+
this.localUsermediaFeed?.setAudioVideoMuted(null, muted);
|
|
1301
|
+
this.updateMuteStatus();
|
|
1302
|
+
await this.sendMetadataUpdate();
|
|
1303
|
+
|
|
1304
|
+
// if we're muting video, set a timeout to stop & remove the video track so we release
|
|
1305
|
+
// the camera. We wait a short time to do this because when we disable a track, WebRTC
|
|
1306
|
+
// will send black video for it. If we just stop and remove it straight away, the video
|
|
1307
|
+
// will just freeze which means that when we unmute video, the other side will briefly
|
|
1308
|
+
// get a static frame of us from before we muted. This way, the still frame is just black.
|
|
1309
|
+
// A very small delay is not always enough so the theory here is that it needs to be long
|
|
1310
|
+
// enough for WebRTC to encode a frame: 120ms should be long enough even if we're only
|
|
1311
|
+
// doing 10fps.
|
|
1312
|
+
if (muted) {
|
|
1313
|
+
this.stopVideoTrackTimer = setTimeout(() => {
|
|
1314
|
+
for (const t of this.localUsermediaStream.getVideoTracks()) {
|
|
1315
|
+
t.stop();
|
|
1316
|
+
this.localUsermediaStream.removeTrack(t);
|
|
1317
|
+
}
|
|
1318
|
+
}, 120);
|
|
1319
|
+
}
|
|
1320
|
+
return this.isLocalVideoMuted();
|
|
1364
1321
|
}
|
|
1365
1322
|
|
|
1366
1323
|
/**
|
|
@@ -1373,8 +1330,7 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
1373
1330
|
* (including if the call is not set up yet).
|
|
1374
1331
|
*/
|
|
1375
1332
|
isLocalVideoMuted() {
|
|
1376
|
-
|
|
1377
|
-
return (_this$localUsermediaF2 = (_this$localUsermediaF3 = this.localUsermediaFeed) === null || _this$localUsermediaF3 === void 0 ? void 0 : _this$localUsermediaF3.isVideoMuted()) !== null && _this$localUsermediaF2 !== void 0 ? _this$localUsermediaF2 : false;
|
|
1333
|
+
return this.localUsermediaFeed?.isVideoMuted() ?? false;
|
|
1378
1334
|
}
|
|
1379
1335
|
|
|
1380
1336
|
/**
|
|
@@ -1382,23 +1338,19 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
1382
1338
|
* @param muted - True to mute the mic.
|
|
1383
1339
|
* @returns the new mute state
|
|
1384
1340
|
*/
|
|
1385
|
-
setMicrophoneMuted(muted) {
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
_this13.updateMuteStatus();
|
|
1399
|
-
yield _this13.sendMetadataUpdate();
|
|
1400
|
-
return _this13.isMicrophoneMuted();
|
|
1401
|
-
})();
|
|
1341
|
+
async setMicrophoneMuted(muted) {
|
|
1342
|
+
logger.log(`Call ${this.callId} setMicrophoneMuted() running ${muted}`);
|
|
1343
|
+
if (!(await this.client.getMediaHandler().hasAudioDevice())) {
|
|
1344
|
+
return this.isMicrophoneMuted();
|
|
1345
|
+
}
|
|
1346
|
+
if (!muted && (!this.hasUserMediaAudioSender || !this.hasLocalUserMediaAudioTrack)) {
|
|
1347
|
+
await this.upgradeCall(true, false);
|
|
1348
|
+
return this.isMicrophoneMuted();
|
|
1349
|
+
}
|
|
1350
|
+
this.localUsermediaFeed?.setAudioVideoMuted(muted, null);
|
|
1351
|
+
this.updateMuteStatus();
|
|
1352
|
+
await this.sendMetadataUpdate();
|
|
1353
|
+
return this.isMicrophoneMuted();
|
|
1402
1354
|
}
|
|
1403
1355
|
|
|
1404
1356
|
/**
|
|
@@ -1411,8 +1363,7 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
1411
1363
|
* is not set up yet).
|
|
1412
1364
|
*/
|
|
1413
1365
|
isMicrophoneMuted() {
|
|
1414
|
-
|
|
1415
|
-
return (_this$localUsermediaF4 = (_this$localUsermediaF5 = this.localUsermediaFeed) === null || _this$localUsermediaF5 === void 0 ? void 0 : _this$localUsermediaF5.isAudioMuted()) !== null && _this$localUsermediaF4 !== void 0 ? _this$localUsermediaF4 : false;
|
|
1366
|
+
return this.localUsermediaFeed?.isAudioMuted() ?? false;
|
|
1416
1367
|
}
|
|
1417
1368
|
|
|
1418
1369
|
/**
|
|
@@ -1425,7 +1376,7 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
1425
1376
|
setRemoteOnHold(onHold) {
|
|
1426
1377
|
if (this.isRemoteOnHold() === onHold) return;
|
|
1427
1378
|
this.remoteOnHold = onHold;
|
|
1428
|
-
for (
|
|
1379
|
+
for (const transceiver of this.peerConn.getTransceivers()) {
|
|
1429
1380
|
// We don't send hold music or anything so we're not actually
|
|
1430
1381
|
// sending anything, but sendrecv is fairly standard for hold and
|
|
1431
1382
|
// it makes it a lot easier to figure out who's put who on hold.
|
|
@@ -1443,12 +1394,12 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
1443
1394
|
*/
|
|
1444
1395
|
isLocalOnHold() {
|
|
1445
1396
|
if (this.state !== CallState.Connected) return false;
|
|
1446
|
-
|
|
1397
|
+
let callOnHold = true;
|
|
1447
1398
|
|
|
1448
1399
|
// We consider a call to be on hold only if *all* the tracks are on hold
|
|
1449
1400
|
// (is this the right thing to do?)
|
|
1450
|
-
for (
|
|
1451
|
-
|
|
1401
|
+
for (const transceiver of this.peerConn.getTransceivers()) {
|
|
1402
|
+
const trackOnHold = ["inactive", "recvonly"].includes(transceiver.currentDirection);
|
|
1452
1403
|
if (!trackOnHold) callOnHold = false;
|
|
1453
1404
|
}
|
|
1454
1405
|
return callOnHold;
|
|
@@ -1459,9 +1410,8 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
1459
1410
|
* @param digit - The digit (nb. string - '#' and '*' are dtmf too)
|
|
1460
1411
|
*/
|
|
1461
1412
|
sendDtmfDigit(digit) {
|
|
1462
|
-
for (
|
|
1463
|
-
|
|
1464
|
-
if (((_sender$track = sender.track) === null || _sender$track === void 0 ? void 0 : _sender$track.kind) === "audio" && sender.dtmf) {
|
|
1413
|
+
for (const sender of this.peerConn.getSenders()) {
|
|
1414
|
+
if (sender.track?.kind === "audio" && sender.dtmf) {
|
|
1465
1415
|
sender.dtmf.insertDTMF(digit);
|
|
1466
1416
|
return;
|
|
1467
1417
|
}
|
|
@@ -1469,22 +1419,18 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
1469
1419
|
throw new Error("Unable to find a track to send DTMF on");
|
|
1470
1420
|
}
|
|
1471
1421
|
updateMuteStatus() {
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
logger.log(
|
|
1422
|
+
const micShouldBeMuted = this.isMicrophoneMuted() || this.remoteOnHold;
|
|
1423
|
+
const vidShouldBeMuted = this.isLocalVideoMuted() || this.remoteOnHold;
|
|
1424
|
+
logger.log(`Call ${this.callId} updateMuteStatus stream ${this.localUsermediaStream.id} micShouldBeMuted ${micShouldBeMuted} vidShouldBeMuted ${vidShouldBeMuted}`);
|
|
1475
1425
|
setTracksEnabled(this.localUsermediaStream.getAudioTracks(), !micShouldBeMuted);
|
|
1476
1426
|
setTracksEnabled(this.localUsermediaStream.getVideoTracks(), !vidShouldBeMuted);
|
|
1477
1427
|
}
|
|
1478
|
-
sendMetadataUpdate() {
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
[SDPStreamMetadataKey.name]: _this14.getLocalSDPStreamMetadata()
|
|
1483
|
-
});
|
|
1484
|
-
})();
|
|
1428
|
+
async sendMetadataUpdate() {
|
|
1429
|
+
await this.sendVoipEvent(EventType.CallSDPStreamMetadataChanged, {
|
|
1430
|
+
[SDPStreamMetadataKey.name]: this.getLocalSDPStreamMetadata()
|
|
1431
|
+
});
|
|
1485
1432
|
}
|
|
1486
|
-
gotCallFeedsForInvite(callFeeds) {
|
|
1487
|
-
var requestScreenshareFeed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
1433
|
+
gotCallFeedsForInvite(callFeeds, requestScreenshareFeed = false) {
|
|
1488
1434
|
if (this.successor) {
|
|
1489
1435
|
this.successor.queueGotCallFeedsForAnswer(callFeeds);
|
|
1490
1436
|
return;
|
|
@@ -1493,7 +1439,7 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
1493
1439
|
this.stopAllMedia();
|
|
1494
1440
|
return;
|
|
1495
1441
|
}
|
|
1496
|
-
for (
|
|
1442
|
+
for (const feed of callFeeds) {
|
|
1497
1443
|
this.pushLocalFeed(feed);
|
|
1498
1444
|
}
|
|
1499
1445
|
if (requestScreenshareFeed) {
|
|
@@ -1502,54 +1448,51 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
1502
1448
|
});
|
|
1503
1449
|
}
|
|
1504
1450
|
this.state = CallState.CreateOffer;
|
|
1505
|
-
logger.debug(
|
|
1451
|
+
logger.debug(`Call ${this.callId} gotUserMediaForInvite() run`);
|
|
1506
1452
|
// Now we wait for the negotiationneeded event
|
|
1507
1453
|
}
|
|
1508
|
-
sendAnswer() {
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
throw error;
|
|
1547
|
-
}
|
|
1454
|
+
async sendAnswer() {
|
|
1455
|
+
const answerContent = {
|
|
1456
|
+
answer: {
|
|
1457
|
+
sdp: this.peerConn.localDescription.sdp,
|
|
1458
|
+
// type is now deprecated as of Matrix VoIP v1, but
|
|
1459
|
+
// required to still be sent for backwards compat
|
|
1460
|
+
type: this.peerConn.localDescription.type
|
|
1461
|
+
},
|
|
1462
|
+
[SDPStreamMetadataKey.name]: this.getLocalSDPStreamMetadata(true)
|
|
1463
|
+
};
|
|
1464
|
+
answerContent.capabilities = {
|
|
1465
|
+
"m.call.transferee": this.client.supportsCallTransfer,
|
|
1466
|
+
"m.call.dtmf": false
|
|
1467
|
+
};
|
|
1468
|
+
|
|
1469
|
+
// We have just taken the local description from the peerConn which will
|
|
1470
|
+
// contain all the local candidates added so far, so we can discard any candidates
|
|
1471
|
+
// we had queued up because they'll be in the answer.
|
|
1472
|
+
const discardCount = this.discardDuplicateCandidates();
|
|
1473
|
+
logger.info(`Call ${this.callId} sendAnswer() discarding ${discardCount} candidates that will be sent in answer`);
|
|
1474
|
+
try {
|
|
1475
|
+
await this.sendVoipEvent(EventType.CallAnswer, answerContent);
|
|
1476
|
+
// If this isn't the first time we've tried to send the answer,
|
|
1477
|
+
// we may have candidates queued up, so send them now.
|
|
1478
|
+
this.inviteOrAnswerSent = true;
|
|
1479
|
+
} catch (error) {
|
|
1480
|
+
// We've failed to answer: back to the ringing state
|
|
1481
|
+
this.state = CallState.Ringing;
|
|
1482
|
+
if (error instanceof MatrixError && error.event) this.client.cancelPendingEvent(error.event);
|
|
1483
|
+
let code = CallErrorCode.SendAnswer;
|
|
1484
|
+
let message = "Failed to send answer";
|
|
1485
|
+
if (error.name == "UnknownDeviceError") {
|
|
1486
|
+
code = CallErrorCode.UnknownDevices;
|
|
1487
|
+
message = "Unknown devices present in the room";
|
|
1488
|
+
}
|
|
1489
|
+
this.emit(CallEvent.Error, new CallError(code, message, error), this);
|
|
1490
|
+
throw error;
|
|
1491
|
+
}
|
|
1548
1492
|
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
})();
|
|
1493
|
+
// error handler re-throws so this won't happen on error, but
|
|
1494
|
+
// we don't want the same error handling on the candidate queue
|
|
1495
|
+
this.sendCandidateQueue();
|
|
1553
1496
|
}
|
|
1554
1497
|
queueGotCallFeedsForAnswer(callFeeds) {
|
|
1555
1498
|
// Ensure only one negotiate/answer event is being processed at a time.
|
|
@@ -1564,29 +1507,29 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
1564
1507
|
// bandwidth when transmitting silence
|
|
1565
1508
|
mungeSdp(description, mods) {
|
|
1566
1509
|
// The only way to enable DTX at this time is through SDP munging
|
|
1567
|
-
|
|
1510
|
+
const sdp = parseSdp(description.sdp);
|
|
1568
1511
|
sdp.media.forEach(media => {
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
for (
|
|
1512
|
+
const payloadTypeToCodecMap = new Map();
|
|
1513
|
+
const codecToPayloadTypeMap = new Map();
|
|
1514
|
+
for (const rtp of media.rtp) {
|
|
1572
1515
|
payloadTypeToCodecMap.set(rtp.payload, rtp.codec);
|
|
1573
1516
|
codecToPayloadTypeMap.set(rtp.codec, rtp.payload);
|
|
1574
1517
|
}
|
|
1575
|
-
for (
|
|
1518
|
+
for (const mod of mods) {
|
|
1576
1519
|
if (mod.mediaType !== media.type) continue;
|
|
1577
1520
|
if (!codecToPayloadTypeMap.has(mod.codec)) {
|
|
1578
|
-
logger.info(
|
|
1521
|
+
logger.info(`Call ${this.callId} mungeSdp() ignoring SDP modifications for ${mod.codec} as it's not present.`);
|
|
1579
1522
|
continue;
|
|
1580
1523
|
}
|
|
1581
|
-
|
|
1524
|
+
const extraConfig = [];
|
|
1582
1525
|
if (mod.enableDtx !== undefined) {
|
|
1583
|
-
extraConfig.push(
|
|
1526
|
+
extraConfig.push(`usedtx=${mod.enableDtx ? "1" : "0"}`);
|
|
1584
1527
|
}
|
|
1585
1528
|
if (mod.maxAverageBitrate !== undefined) {
|
|
1586
|
-
extraConfig.push(
|
|
1529
|
+
extraConfig.push(`maxaveragebitrate=${mod.maxAverageBitrate}`);
|
|
1587
1530
|
}
|
|
1588
|
-
|
|
1589
|
-
for (
|
|
1531
|
+
let found = false;
|
|
1532
|
+
for (const fmtp of media.fmtp) {
|
|
1590
1533
|
if (payloadTypeToCodecMap.get(fmtp.payload) === mod.codec) {
|
|
1591
1534
|
found = true;
|
|
1592
1535
|
fmtp.config += ";" + extraConfig.join(";");
|
|
@@ -1602,260 +1545,234 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
1602
1545
|
});
|
|
1603
1546
|
description.sdp = writeSdp(sdp);
|
|
1604
1547
|
}
|
|
1605
|
-
createOffer() {
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
answer = yield _this18.createAnswer();
|
|
1634
|
-
} catch (err) {
|
|
1635
|
-
logger.debug("Call ".concat(_this18.callId, " gotCallFeedsForAnswer() failed to create answer: "), err);
|
|
1636
|
-
_this18.terminate(CallParty.Local, CallErrorCode.CreateAnswer, true);
|
|
1637
|
-
return;
|
|
1638
|
-
}
|
|
1639
|
-
try {
|
|
1640
|
-
yield _this18.peerConn.setLocalDescription(answer);
|
|
1548
|
+
async createOffer() {
|
|
1549
|
+
const offer = await this.peerConn.createOffer();
|
|
1550
|
+
this.mungeSdp(offer, getCodecParamMods(this.isPtt));
|
|
1551
|
+
return offer;
|
|
1552
|
+
}
|
|
1553
|
+
async createAnswer() {
|
|
1554
|
+
const answer = await this.peerConn.createAnswer();
|
|
1555
|
+
this.mungeSdp(answer, getCodecParamMods(this.isPtt));
|
|
1556
|
+
return answer;
|
|
1557
|
+
}
|
|
1558
|
+
async gotCallFeedsForAnswer(callFeeds) {
|
|
1559
|
+
if (this.callHasEnded()) return;
|
|
1560
|
+
this.waitForLocalAVStream = false;
|
|
1561
|
+
for (const feed of callFeeds) {
|
|
1562
|
+
this.pushLocalFeed(feed);
|
|
1563
|
+
}
|
|
1564
|
+
this.state = CallState.CreateAnswer;
|
|
1565
|
+
let answer;
|
|
1566
|
+
try {
|
|
1567
|
+
this.getRidOfRTXCodecs();
|
|
1568
|
+
answer = await this.createAnswer();
|
|
1569
|
+
} catch (err) {
|
|
1570
|
+
logger.debug(`Call ${this.callId} gotCallFeedsForAnswer() failed to create answer: `, err);
|
|
1571
|
+
this.terminate(CallParty.Local, CallErrorCode.CreateAnswer, true);
|
|
1572
|
+
return;
|
|
1573
|
+
}
|
|
1574
|
+
try {
|
|
1575
|
+
await this.peerConn.setLocalDescription(answer);
|
|
1641
1576
|
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1577
|
+
// make sure we're still going
|
|
1578
|
+
if (this.callHasEnded()) return;
|
|
1579
|
+
this.state = CallState.Connecting;
|
|
1645
1580
|
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1581
|
+
// Allow a short time for initial candidates to be gathered
|
|
1582
|
+
await new Promise(resolve => {
|
|
1583
|
+
setTimeout(resolve, 200);
|
|
1584
|
+
});
|
|
1650
1585
|
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
})();
|
|
1586
|
+
// make sure the call hasn't ended before we continue
|
|
1587
|
+
if (this.callHasEnded()) return;
|
|
1588
|
+
this.sendAnswer();
|
|
1589
|
+
} catch (err) {
|
|
1590
|
+
logger.debug(`Call ${this.callId} gotCallFeedsForAnswer() error setting local description!`, err);
|
|
1591
|
+
this.terminate(CallParty.Local, CallErrorCode.SetLocalDescription, true);
|
|
1592
|
+
return;
|
|
1593
|
+
}
|
|
1660
1594
|
}
|
|
1661
|
-
onRemoteIceCandidatesReceived(ev) {
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
if (
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
bufferedCandidates.push(...candidates);
|
|
1681
|
-
_this19.remoteCandidateBuffer.set(fromPartyId, bufferedCandidates);
|
|
1682
|
-
}
|
|
1683
|
-
return;
|
|
1684
|
-
}
|
|
1685
|
-
if (!_this19.partyIdMatches(content)) {
|
|
1686
|
-
logger.info("Call ".concat(_this19.callId, " onRemoteIceCandidatesReceived() ignoring candidates from party ID ").concat(content.party_id, ": we have chosen party ID ").concat(_this19.opponentPartyId));
|
|
1687
|
-
return;
|
|
1595
|
+
async onRemoteIceCandidatesReceived(ev) {
|
|
1596
|
+
if (this.callHasEnded()) {
|
|
1597
|
+
//debuglog("Ignoring remote ICE candidate because call has ended");
|
|
1598
|
+
return;
|
|
1599
|
+
}
|
|
1600
|
+
const content = ev.getContent();
|
|
1601
|
+
const candidates = content.candidates;
|
|
1602
|
+
if (!candidates) {
|
|
1603
|
+
logger.info(`Call ${this.callId} onRemoteIceCandidatesReceived() ignoring candidates event with no candidates!`);
|
|
1604
|
+
return;
|
|
1605
|
+
}
|
|
1606
|
+
const fromPartyId = content.version === 0 ? null : content.party_id || null;
|
|
1607
|
+
if (this.opponentPartyId === undefined) {
|
|
1608
|
+
// we haven't picked an opponent yet so save the candidates
|
|
1609
|
+
if (fromPartyId) {
|
|
1610
|
+
logger.info(`Call ${this.callId} onRemoteIceCandidatesReceived() buffering ${candidates.length} candidates until we pick an opponent`);
|
|
1611
|
+
const bufferedCandidates = this.remoteCandidateBuffer.get(fromPartyId) || [];
|
|
1612
|
+
bufferedCandidates.push(...candidates);
|
|
1613
|
+
this.remoteCandidateBuffer.set(fromPartyId, bufferedCandidates);
|
|
1688
1614
|
}
|
|
1689
|
-
|
|
1690
|
-
}
|
|
1615
|
+
return;
|
|
1616
|
+
}
|
|
1617
|
+
if (!this.partyIdMatches(content)) {
|
|
1618
|
+
logger.info(`Call ${this.callId} onRemoteIceCandidatesReceived() ignoring candidates from party ID ${content.party_id}: we have chosen party ID ${this.opponentPartyId}`);
|
|
1619
|
+
return;
|
|
1620
|
+
}
|
|
1621
|
+
await this.addIceCandidates(candidates);
|
|
1691
1622
|
}
|
|
1692
1623
|
|
|
1693
1624
|
/**
|
|
1694
1625
|
* Used by MatrixClient.
|
|
1695
1626
|
*/
|
|
1696
|
-
onAnswerReceived(event) {
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
logger.debug(
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
}
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1627
|
+
async onAnswerReceived(event) {
|
|
1628
|
+
const content = event.getContent();
|
|
1629
|
+
logger.debug(`Call ${this.callId} onAnswerReceived() running (hangupParty=${content.party_id})`);
|
|
1630
|
+
if (this.callHasEnded()) {
|
|
1631
|
+
logger.debug(`Call ${this.callId} onAnswerReceived() ignoring answer because call has ended`);
|
|
1632
|
+
return;
|
|
1633
|
+
}
|
|
1634
|
+
if (this.opponentPartyId !== undefined) {
|
|
1635
|
+
logger.info(`Call ${this.callId} onAnswerReceived() ignoring answer from party ID ${content.party_id}: we already have an answer/reject from ${this.opponentPartyId}`);
|
|
1636
|
+
return;
|
|
1637
|
+
}
|
|
1638
|
+
this.chooseOpponent(event);
|
|
1639
|
+
await this.addBufferedIceCandidates();
|
|
1640
|
+
this.state = CallState.Connecting;
|
|
1641
|
+
const sdpStreamMetadata = SDPStreamMetadataKey.findIn(content);
|
|
1642
|
+
if (sdpStreamMetadata) {
|
|
1643
|
+
this.updateRemoteSDPStreamMetadata(sdpStreamMetadata);
|
|
1644
|
+
} else {
|
|
1645
|
+
logger.warn(`Call ${this.callId} onAnswerReceived() did not get any SDPStreamMetadata! Can not send/receive multiple streams`);
|
|
1646
|
+
}
|
|
1647
|
+
try {
|
|
1648
|
+
this.isSettingRemoteAnswerPending = true;
|
|
1649
|
+
await this.peerConn.setRemoteDescription(content.answer);
|
|
1650
|
+
this.isSettingRemoteAnswerPending = false;
|
|
1651
|
+
logger.debug(`Call ${this.callId} onAnswerReceived() set remote description: ${content.answer.type}`);
|
|
1652
|
+
} catch (e) {
|
|
1653
|
+
this.isSettingRemoteAnswerPending = false;
|
|
1654
|
+
logger.debug(`Call ${this.callId} onAnswerReceived() failed to set remote description`, e);
|
|
1655
|
+
this.terminate(CallParty.Local, CallErrorCode.SetRemoteDescription, false);
|
|
1656
|
+
return;
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
// If the answer we selected has a party_id, send a select_answer event
|
|
1660
|
+
// We do this after setting the remote description since otherwise we'd block
|
|
1661
|
+
// call setup on it
|
|
1662
|
+
if (this.opponentPartyId !== null) {
|
|
1718
1663
|
try {
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
logger.
|
|
1726
|
-
_this20.terminate(CallParty.Local, CallErrorCode.SetRemoteDescription, false);
|
|
1727
|
-
return;
|
|
1664
|
+
await this.sendVoipEvent(EventType.CallSelectAnswer, {
|
|
1665
|
+
selected_party_id: this.opponentPartyId
|
|
1666
|
+
});
|
|
1667
|
+
} catch (err) {
|
|
1668
|
+
// This isn't fatal, and will just mean that if another party has raced to answer
|
|
1669
|
+
// the call, they won't know they got rejected, so we carry on & don't retry.
|
|
1670
|
+
logger.warn(`Call ${this.callId} onAnswerReceived() failed to send select_answer event`, err);
|
|
1728
1671
|
}
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1672
|
+
}
|
|
1673
|
+
}
|
|
1674
|
+
async onSelectAnswerReceived(event) {
|
|
1675
|
+
if (this.direction !== CallDirection.Inbound) {
|
|
1676
|
+
logger.warn(`Call ${this.callId} onSelectAnswerReceived() got select_answer for an outbound call: ignoring`);
|
|
1677
|
+
return;
|
|
1678
|
+
}
|
|
1679
|
+
const selectedPartyId = event.getContent().selected_party_id;
|
|
1680
|
+
if (selectedPartyId === undefined || selectedPartyId === null) {
|
|
1681
|
+
logger.warn(`Call ${this.callId} onSelectAnswerReceived() got nonsensical select_answer with null/undefined selected_party_id: ignoring`);
|
|
1682
|
+
return;
|
|
1683
|
+
}
|
|
1684
|
+
if (selectedPartyId !== this.ourPartyId) {
|
|
1685
|
+
logger.info(`Call ${this.callId} onSelectAnswerReceived() got select_answer for party ID ${selectedPartyId}: we are party ID ${this.ourPartyId}.`);
|
|
1686
|
+
// The other party has picked somebody else's answer
|
|
1687
|
+
await this.terminate(CallParty.Remote, CallErrorCode.AnsweredElsewhere, true);
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1690
|
+
async onNegotiateReceived(event) {
|
|
1691
|
+
const content = event.getContent();
|
|
1692
|
+
const description = content.description;
|
|
1693
|
+
if (!description || !description.sdp || !description.type) {
|
|
1694
|
+
logger.info(`Call ${this.callId} onNegotiateReceived() ignoring invalid m.call.negotiate event`);
|
|
1695
|
+
return;
|
|
1696
|
+
}
|
|
1697
|
+
// Politeness always follows the direction of the call: in a glare situation,
|
|
1698
|
+
// we pick either the inbound or outbound call, so one side will always be
|
|
1699
|
+
// inbound and one outbound
|
|
1700
|
+
const polite = this.direction === CallDirection.Inbound;
|
|
1701
|
+
|
|
1702
|
+
// Here we follow the perfect negotiation logic from
|
|
1703
|
+
// https://w3c.github.io/webrtc-pc/#perfect-negotiation-example
|
|
1704
|
+
const readyForOffer = !this.makingOffer && (this.peerConn.signalingState === "stable" || this.isSettingRemoteAnswerPending);
|
|
1705
|
+
const offerCollision = description.type === "offer" && !readyForOffer;
|
|
1706
|
+
this.ignoreOffer = !polite && offerCollision;
|
|
1707
|
+
if (this.ignoreOffer) {
|
|
1708
|
+
logger.info(`Call ${this.callId} onNegotiateReceived() ignoring colliding negotiate event because we're impolite`);
|
|
1709
|
+
return;
|
|
1710
|
+
}
|
|
1711
|
+
const prevLocalOnHold = this.isLocalOnHold();
|
|
1712
|
+
const sdpStreamMetadata = SDPStreamMetadataKey.findIn(content);
|
|
1713
|
+
if (sdpStreamMetadata) {
|
|
1714
|
+
this.updateRemoteSDPStreamMetadata(sdpStreamMetadata);
|
|
1715
|
+
} else {
|
|
1716
|
+
logger.warn(`Call ${this.callId} onNegotiateReceived() received negotiation event without SDPStreamMetadata!`);
|
|
1717
|
+
}
|
|
1718
|
+
try {
|
|
1719
|
+
this.isSettingRemoteAnswerPending = description.type == "answer";
|
|
1720
|
+
await this.peerConn.setRemoteDescription(description); // SRD rolls back as needed
|
|
1721
|
+
this.isSettingRemoteAnswerPending = false;
|
|
1722
|
+
logger.debug(`Call ${this.callId} onNegotiateReceived() set remote description: ${description.type}`);
|
|
1723
|
+
if (description.type === "offer") {
|
|
1724
|
+
let answer;
|
|
1734
1725
|
try {
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
});
|
|
1726
|
+
this.getRidOfRTXCodecs();
|
|
1727
|
+
answer = await this.createAnswer();
|
|
1738
1728
|
} catch (err) {
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
}
|
|
1743
|
-
}
|
|
1744
|
-
})();
|
|
1745
|
-
}
|
|
1746
|
-
onSelectAnswerReceived(event) {
|
|
1747
|
-
var _this21 = this;
|
|
1748
|
-
return _asyncToGenerator(function* () {
|
|
1749
|
-
if (_this21.direction !== CallDirection.Inbound) {
|
|
1750
|
-
logger.warn("Call ".concat(_this21.callId, " onSelectAnswerReceived() got select_answer for an outbound call: ignoring"));
|
|
1751
|
-
return;
|
|
1752
|
-
}
|
|
1753
|
-
var selectedPartyId = event.getContent().selected_party_id;
|
|
1754
|
-
if (selectedPartyId === undefined || selectedPartyId === null) {
|
|
1755
|
-
logger.warn("Call ".concat(_this21.callId, " onSelectAnswerReceived() got nonsensical select_answer with null/undefined selected_party_id: ignoring"));
|
|
1756
|
-
return;
|
|
1757
|
-
}
|
|
1758
|
-
if (selectedPartyId !== _this21.ourPartyId) {
|
|
1759
|
-
logger.info("Call ".concat(_this21.callId, " onSelectAnswerReceived() got select_answer for party ID ").concat(selectedPartyId, ": we are party ID ").concat(_this21.ourPartyId, "."));
|
|
1760
|
-
// The other party has picked somebody else's answer
|
|
1761
|
-
yield _this21.terminate(CallParty.Remote, CallErrorCode.AnsweredElsewhere, true);
|
|
1762
|
-
}
|
|
1763
|
-
})();
|
|
1764
|
-
}
|
|
1765
|
-
onNegotiateReceived(event) {
|
|
1766
|
-
var _this22 = this;
|
|
1767
|
-
return _asyncToGenerator(function* () {
|
|
1768
|
-
var content = event.getContent();
|
|
1769
|
-
var description = content.description;
|
|
1770
|
-
if (!description || !description.sdp || !description.type) {
|
|
1771
|
-
logger.info("Call ".concat(_this22.callId, " onNegotiateReceived() ignoring invalid m.call.negotiate event"));
|
|
1772
|
-
return;
|
|
1773
|
-
}
|
|
1774
|
-
// Politeness always follows the direction of the call: in a glare situation,
|
|
1775
|
-
// we pick either the inbound or outbound call, so one side will always be
|
|
1776
|
-
// inbound and one outbound
|
|
1777
|
-
var polite = _this22.direction === CallDirection.Inbound;
|
|
1778
|
-
|
|
1779
|
-
// Here we follow the perfect negotiation logic from
|
|
1780
|
-
// https://w3c.github.io/webrtc-pc/#perfect-negotiation-example
|
|
1781
|
-
var readyForOffer = !_this22.makingOffer && (_this22.peerConn.signalingState === "stable" || _this22.isSettingRemoteAnswerPending);
|
|
1782
|
-
var offerCollision = description.type === "offer" && !readyForOffer;
|
|
1783
|
-
_this22.ignoreOffer = !polite && offerCollision;
|
|
1784
|
-
if (_this22.ignoreOffer) {
|
|
1785
|
-
logger.info("Call ".concat(_this22.callId, " onNegotiateReceived() ignoring colliding negotiate event because we're impolite"));
|
|
1786
|
-
return;
|
|
1787
|
-
}
|
|
1788
|
-
var prevLocalOnHold = _this22.isLocalOnHold();
|
|
1789
|
-
var sdpStreamMetadata = SDPStreamMetadataKey.findIn(content);
|
|
1790
|
-
if (sdpStreamMetadata) {
|
|
1791
|
-
_this22.updateRemoteSDPStreamMetadata(sdpStreamMetadata);
|
|
1792
|
-
} else {
|
|
1793
|
-
logger.warn("Call ".concat(_this22.callId, " onNegotiateReceived() received negotiation event without SDPStreamMetadata!"));
|
|
1794
|
-
}
|
|
1795
|
-
try {
|
|
1796
|
-
_this22.isSettingRemoteAnswerPending = description.type == "answer";
|
|
1797
|
-
yield _this22.peerConn.setRemoteDescription(description); // SRD rolls back as needed
|
|
1798
|
-
_this22.isSettingRemoteAnswerPending = false;
|
|
1799
|
-
logger.debug("Call ".concat(_this22.callId, " onNegotiateReceived() set remote description: ").concat(description.type));
|
|
1800
|
-
if (description.type === "offer") {
|
|
1801
|
-
var _localDescription;
|
|
1802
|
-
var answer;
|
|
1803
|
-
try {
|
|
1804
|
-
_this22.getRidOfRTXCodecs();
|
|
1805
|
-
answer = yield _this22.createAnswer();
|
|
1806
|
-
} catch (err) {
|
|
1807
|
-
logger.debug("Call ".concat(_this22.callId, " onNegotiateReceived() failed to create answer: "), err);
|
|
1808
|
-
_this22.terminate(CallParty.Local, CallErrorCode.CreateAnswer, true);
|
|
1809
|
-
return;
|
|
1810
|
-
}
|
|
1811
|
-
yield _this22.peerConn.setLocalDescription(answer);
|
|
1812
|
-
logger.debug("Call ".concat(_this22.callId, " onNegotiateReceived() create an answer"));
|
|
1813
|
-
_this22.sendVoipEvent(EventType.CallNegotiate, {
|
|
1814
|
-
lifetime: CALL_TIMEOUT_MS,
|
|
1815
|
-
description: (_localDescription = _this22.peerConn.localDescription) === null || _localDescription === void 0 ? void 0 : _localDescription.toJSON(),
|
|
1816
|
-
[SDPStreamMetadataKey.name]: _this22.getLocalSDPStreamMetadata(true)
|
|
1817
|
-
});
|
|
1729
|
+
logger.debug(`Call ${this.callId} onNegotiateReceived() failed to create answer: `, err);
|
|
1730
|
+
this.terminate(CallParty.Local, CallErrorCode.CreateAnswer, true);
|
|
1731
|
+
return;
|
|
1818
1732
|
}
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
// also this one for backwards compat
|
|
1827
|
-
_this22.emit(CallEvent.HoldUnhold, newLocalOnHold);
|
|
1733
|
+
await this.peerConn.setLocalDescription(answer);
|
|
1734
|
+
logger.debug(`Call ${this.callId} onNegotiateReceived() create an answer`);
|
|
1735
|
+
this.sendVoipEvent(EventType.CallNegotiate, {
|
|
1736
|
+
lifetime: CALL_TIMEOUT_MS,
|
|
1737
|
+
description: this.peerConn.localDescription?.toJSON(),
|
|
1738
|
+
[SDPStreamMetadataKey.name]: this.getLocalSDPStreamMetadata(true)
|
|
1739
|
+
});
|
|
1828
1740
|
}
|
|
1829
|
-
}
|
|
1741
|
+
} catch (err) {
|
|
1742
|
+
this.isSettingRemoteAnswerPending = false;
|
|
1743
|
+
logger.warn(`Call ${this.callId} onNegotiateReceived() failed to complete negotiation`, err);
|
|
1744
|
+
}
|
|
1745
|
+
const newLocalOnHold = this.isLocalOnHold();
|
|
1746
|
+
if (prevLocalOnHold !== newLocalOnHold) {
|
|
1747
|
+
this.emit(CallEvent.LocalHoldUnhold, newLocalOnHold, this);
|
|
1748
|
+
// also this one for backwards compat
|
|
1749
|
+
this.emit(CallEvent.HoldUnhold, newLocalOnHold);
|
|
1750
|
+
}
|
|
1830
1751
|
}
|
|
1831
1752
|
updateRemoteSDPStreamMetadata(metadata) {
|
|
1832
1753
|
this.remoteSDPStreamMetadata = recursivelyAssign(this.remoteSDPStreamMetadata || {}, metadata, true);
|
|
1833
|
-
for (
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
feed.
|
|
1838
|
-
feed.purpose = (_streamId = this.remoteSDPStreamMetadata[streamId]) === null || _streamId === void 0 ? void 0 : _streamId.purpose;
|
|
1754
|
+
for (const feed of this.getRemoteFeeds()) {
|
|
1755
|
+
const streamId = feed.stream.id;
|
|
1756
|
+
const metadata = this.remoteSDPStreamMetadata[streamId];
|
|
1757
|
+
feed.setAudioVideoMuted(metadata?.audio_muted, metadata?.video_muted);
|
|
1758
|
+
feed.purpose = this.remoteSDPStreamMetadata[streamId]?.purpose;
|
|
1839
1759
|
}
|
|
1840
1760
|
}
|
|
1841
1761
|
onSDPStreamMetadataChangedReceived(event) {
|
|
1842
|
-
|
|
1843
|
-
|
|
1762
|
+
const content = event.getContent();
|
|
1763
|
+
const metadata = SDPStreamMetadataKey.findIn(content);
|
|
1844
1764
|
if (metadata) {
|
|
1845
1765
|
this.updateRemoteSDPStreamMetadata(metadata);
|
|
1846
1766
|
}
|
|
1847
1767
|
}
|
|
1848
|
-
onAssertedIdentityReceived(event) {
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
};
|
|
1857
|
-
_this23.emit(CallEvent.AssertedIdentityChanged, _this23);
|
|
1858
|
-
})();
|
|
1768
|
+
async onAssertedIdentityReceived(event) {
|
|
1769
|
+
const content = event.getContent();
|
|
1770
|
+
if (!content.asserted_identity) return;
|
|
1771
|
+
this.remoteAssertedIdentity = {
|
|
1772
|
+
id: content.asserted_identity.id,
|
|
1773
|
+
displayName: content.asserted_identity.display_name
|
|
1774
|
+
};
|
|
1775
|
+
this.emit(CallEvent.AssertedIdentityChanged, this);
|
|
1859
1776
|
}
|
|
1860
1777
|
callHasEnded() {
|
|
1861
1778
|
// This exists as workaround to typescript trying to be clever and erroring
|
|
@@ -1871,117 +1788,109 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
1871
1788
|
this.responsePromiseChain = this.wrappedGotLocalOffer();
|
|
1872
1789
|
}
|
|
1873
1790
|
}
|
|
1874
|
-
wrappedGotLocalOffer() {
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
}
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
}
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
lifetime: CALL_TIMEOUT_MS
|
|
1928
|
-
};
|
|
1929
|
-
if (eventType === EventType.CallInvite && _this25.invitee) {
|
|
1930
|
-
content.invitee = _this25.invitee;
|
|
1931
|
-
}
|
|
1932
|
-
|
|
1933
|
-
// clunky because TypeScript can't follow the types through if we use an expression as the key
|
|
1934
|
-
if (_this25.state === CallState.CreateOffer) {
|
|
1935
|
-
var _localDescription2;
|
|
1936
|
-
content.offer = (_localDescription2 = _this25.peerConn.localDescription) === null || _localDescription2 === void 0 ? void 0 : _localDescription2.toJSON();
|
|
1937
|
-
} else {
|
|
1938
|
-
var _localDescription3;
|
|
1939
|
-
content.description = (_localDescription3 = _this25.peerConn.localDescription) === null || _localDescription3 === void 0 ? void 0 : _localDescription3.toJSON();
|
|
1940
|
-
}
|
|
1941
|
-
content.capabilities = {
|
|
1942
|
-
"m.call.transferee": _this25.client.supportsCallTransfer,
|
|
1943
|
-
"m.call.dtmf": false
|
|
1944
|
-
};
|
|
1945
|
-
content[SDPStreamMetadataKey.name] = _this25.getLocalSDPStreamMetadata(true);
|
|
1791
|
+
async wrappedGotLocalOffer() {
|
|
1792
|
+
this.makingOffer = true;
|
|
1793
|
+
try {
|
|
1794
|
+
// XXX: in what situations do we believe gotLocalOffer actually throws? It appears
|
|
1795
|
+
// to handle most of its exceptions itself and terminate the call. I'm not entirely
|
|
1796
|
+
// sure it would ever throw, so I can't add a test for these lines.
|
|
1797
|
+
// Also the tense is different between "gotLocalOffer" and "getLocalOfferFailed" so
|
|
1798
|
+
// it's not entirely clear whether getLocalOfferFailed is just misnamed or whether
|
|
1799
|
+
// they've been cross-polinated somehow at some point.
|
|
1800
|
+
await this.gotLocalOffer();
|
|
1801
|
+
} catch (e) {
|
|
1802
|
+
this.getLocalOfferFailed(e);
|
|
1803
|
+
return;
|
|
1804
|
+
} finally {
|
|
1805
|
+
this.makingOffer = false;
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
async gotLocalOffer() {
|
|
1809
|
+
logger.debug(`Call ${this.callId} gotLocalOffer() running`);
|
|
1810
|
+
if (this.callHasEnded()) {
|
|
1811
|
+
logger.debug(`Call ${this.callId} gotLocalOffer() ignoring newly created offer because the call has ended"`);
|
|
1812
|
+
return;
|
|
1813
|
+
}
|
|
1814
|
+
let offer;
|
|
1815
|
+
try {
|
|
1816
|
+
this.getRidOfRTXCodecs();
|
|
1817
|
+
offer = await this.createOffer();
|
|
1818
|
+
} catch (err) {
|
|
1819
|
+
logger.debug(`Call ${this.callId} gotLocalOffer() failed to create offer: `, err);
|
|
1820
|
+
this.terminate(CallParty.Local, CallErrorCode.CreateOffer, true);
|
|
1821
|
+
return;
|
|
1822
|
+
}
|
|
1823
|
+
try {
|
|
1824
|
+
await this.peerConn.setLocalDescription(offer);
|
|
1825
|
+
} catch (err) {
|
|
1826
|
+
logger.debug(`Call ${this.callId} gotLocalOffer() error setting local description!`, err);
|
|
1827
|
+
this.terminate(CallParty.Local, CallErrorCode.SetLocalDescription, true);
|
|
1828
|
+
return;
|
|
1829
|
+
}
|
|
1830
|
+
if (this.peerConn.iceGatheringState === "gathering") {
|
|
1831
|
+
// Allow a short time for initial candidates to be gathered
|
|
1832
|
+
await new Promise(resolve => {
|
|
1833
|
+
setTimeout(resolve, 200);
|
|
1834
|
+
});
|
|
1835
|
+
}
|
|
1836
|
+
if (this.callHasEnded()) return;
|
|
1837
|
+
const eventType = this.state === CallState.CreateOffer ? EventType.CallInvite : EventType.CallNegotiate;
|
|
1838
|
+
const content = {
|
|
1839
|
+
lifetime: CALL_TIMEOUT_MS
|
|
1840
|
+
};
|
|
1841
|
+
if (eventType === EventType.CallInvite && this.invitee) {
|
|
1842
|
+
content.invitee = this.invitee;
|
|
1843
|
+
}
|
|
1946
1844
|
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1845
|
+
// clunky because TypeScript can't follow the types through if we use an expression as the key
|
|
1846
|
+
if (this.state === CallState.CreateOffer) {
|
|
1847
|
+
content.offer = this.peerConn.localDescription?.toJSON();
|
|
1848
|
+
} else {
|
|
1849
|
+
content.description = this.peerConn.localDescription?.toJSON();
|
|
1850
|
+
}
|
|
1851
|
+
content.capabilities = {
|
|
1852
|
+
"m.call.transferee": this.client.supportsCallTransfer,
|
|
1853
|
+
"m.call.dtmf": false
|
|
1854
|
+
};
|
|
1855
|
+
content[SDPStreamMetadataKey.name] = this.getLocalSDPStreamMetadata(true);
|
|
1856
|
+
|
|
1857
|
+
// Get rid of any candidates waiting to be sent: they'll be included in the local
|
|
1858
|
+
// description we just got and will send in the offer.
|
|
1859
|
+
const discardCount = this.discardDuplicateCandidates();
|
|
1860
|
+
logger.info(`Call ${this.callId} gotLocalOffer() discarding ${discardCount} candidates that will be sent in offer`);
|
|
1861
|
+
try {
|
|
1862
|
+
await this.sendVoipEvent(eventType, content);
|
|
1863
|
+
} catch (error) {
|
|
1864
|
+
logger.error(`Call ${this.callId} gotLocalOffer() failed to send invite`, error);
|
|
1865
|
+
if (error instanceof MatrixError && error.event) this.client.cancelPendingEvent(error.event);
|
|
1866
|
+
let code = CallErrorCode.SignallingFailed;
|
|
1867
|
+
let message = "Signalling failed";
|
|
1868
|
+
if (this.state === CallState.CreateOffer) {
|
|
1869
|
+
code = CallErrorCode.SendInvite;
|
|
1870
|
+
message = "Failed to send invite";
|
|
1871
|
+
}
|
|
1872
|
+
if (error.name == "UnknownDeviceError") {
|
|
1873
|
+
code = CallErrorCode.UnknownDevices;
|
|
1874
|
+
message = "Unknown devices present in the room";
|
|
1875
|
+
}
|
|
1876
|
+
this.emit(CallEvent.Error, new CallError(code, message, error), this);
|
|
1877
|
+
this.terminate(CallParty.Local, code, false);
|
|
1878
|
+
|
|
1879
|
+
// no need to carry on & send the candidate queue, but we also
|
|
1880
|
+
// don't want to rethrow the error
|
|
1881
|
+
return;
|
|
1882
|
+
}
|
|
1883
|
+
this.sendCandidateQueue();
|
|
1884
|
+
if (this.state === CallState.CreateOffer) {
|
|
1885
|
+
this.inviteOrAnswerSent = true;
|
|
1886
|
+
this.state = CallState.InviteSent;
|
|
1887
|
+
this.inviteTimeout = setTimeout(() => {
|
|
1888
|
+
this.inviteTimeout = undefined;
|
|
1889
|
+
if (this.state === CallState.InviteSent) {
|
|
1890
|
+
this.hangup(CallErrorCode.InviteTimeout, false);
|
|
1965
1891
|
}
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
// no need to carry on & send the candidate queue, but we also
|
|
1970
|
-
// don't want to rethrow the error
|
|
1971
|
-
return;
|
|
1972
|
-
}
|
|
1973
|
-
_this25.sendCandidateQueue();
|
|
1974
|
-
if (_this25.state === CallState.CreateOffer) {
|
|
1975
|
-
_this25.inviteOrAnswerSent = true;
|
|
1976
|
-
_this25.state = CallState.InviteSent;
|
|
1977
|
-
_this25.inviteTimeout = setTimeout(() => {
|
|
1978
|
-
_this25.inviteTimeout = undefined;
|
|
1979
|
-
if (_this25.state === CallState.InviteSent) {
|
|
1980
|
-
_this25.hangup(CallErrorCode.InviteTimeout, false);
|
|
1981
|
-
}
|
|
1982
|
-
}, CALL_TIMEOUT_MS);
|
|
1983
|
-
}
|
|
1984
|
-
})();
|
|
1892
|
+
}, CALL_TIMEOUT_MS);
|
|
1893
|
+
}
|
|
1985
1894
|
}
|
|
1986
1895
|
/**
|
|
1987
1896
|
* This method removes all video/rtx codecs from screensharing video
|
|
@@ -1999,14 +1908,14 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
1999
1908
|
getRidOfRTXCodecs() {
|
|
2000
1909
|
// RTCRtpReceiver.getCapabilities and RTCRtpSender.getCapabilities don't seem to be supported on FF before v113
|
|
2001
1910
|
if (!RTCRtpReceiver.getCapabilities || !RTCRtpSender.getCapabilities) return;
|
|
2002
|
-
|
|
1911
|
+
const screenshareVideoTransceiver = this.transceivers.get(getTransceiverKey(SDPStreamMetadataPurpose.Screenshare, "video"));
|
|
2003
1912
|
|
|
2004
1913
|
// setCodecPreferences isn't supported on FF (as of v113)
|
|
2005
1914
|
if (!screenshareVideoTransceiver || !screenshareVideoTransceiver.setCodecPreferences) return;
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
for (
|
|
1915
|
+
const recvCodecs = RTCRtpReceiver.getCapabilities("video").codecs;
|
|
1916
|
+
const sendCodecs = RTCRtpSender.getCapabilities("video").codecs;
|
|
1917
|
+
const codecs = [];
|
|
1918
|
+
for (const codec of [...recvCodecs, ...sendCodecs]) {
|
|
2010
1919
|
if (codec.mimeType !== "video/rtx") {
|
|
2011
1920
|
codecs.push(codec);
|
|
2012
1921
|
try {
|
|
@@ -2029,57 +1938,52 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
2029
1938
|
/**
|
|
2030
1939
|
* @internal
|
|
2031
1940
|
*/
|
|
2032
|
-
sendVoipEvent(eventType, content) {
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
1941
|
+
async sendVoipEvent(eventType, content) {
|
|
1942
|
+
const realContent = _objectSpread(_objectSpread({}, content), {}, {
|
|
1943
|
+
version: VOIP_PROTO_VERSION,
|
|
1944
|
+
call_id: this.callId,
|
|
1945
|
+
party_id: this.ourPartyId,
|
|
1946
|
+
conf_id: this.groupCallId
|
|
1947
|
+
});
|
|
1948
|
+
if (this.opponentDeviceId) {
|
|
1949
|
+
const toDeviceSeq = this.toDeviceSeq++;
|
|
1950
|
+
const content = _objectSpread(_objectSpread({}, realContent), {}, {
|
|
1951
|
+
device_id: this.client.deviceId,
|
|
1952
|
+
sender_session_id: this.client.getSessionId(),
|
|
1953
|
+
dest_session_id: this.opponentSessionId,
|
|
1954
|
+
seq: toDeviceSeq,
|
|
1955
|
+
[ToDeviceMessageId]: globalThis.crypto.randomUUID()
|
|
2040
1956
|
});
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
eventType,
|
|
2054
|
-
userId: _this26.invitee || ((_this26$getOpponentMe = _this26.getOpponentMember()) === null || _this26$getOpponentMe === void 0 ? void 0 : _this26$getOpponentMe.userId),
|
|
2055
|
-
opponentDeviceId: _this26.opponentDeviceId,
|
|
2056
|
-
content: _content
|
|
2057
|
-
}, _this26);
|
|
2058
|
-
var userId = _this26.invitee || _this26.getOpponentMember().userId;
|
|
2059
|
-
if (_this26.client.getUseE2eForGroupCall()) {
|
|
2060
|
-
if (!_this26.hasOpponentDeviceInfo) {
|
|
2061
|
-
logger.warn("Call ".concat(_this26.callId, " sendVoipEvent() failed: we do not have opponentDeviceInfo"));
|
|
2062
|
-
return;
|
|
2063
|
-
}
|
|
2064
|
-
|
|
2065
|
-
// TODO: Here we were sending the event to the opponent's device as a to-device message with MatrixClient.encryptAndSendToDevice.
|
|
2066
|
-
// However due to the switch to Rust cryptography we need to migrate to the new encryptToDeviceMessages API.
|
|
2067
|
-
throw new Error("Unimplemented");
|
|
2068
|
-
} else {
|
|
2069
|
-
yield _this26.client.sendToDevice(eventType, new Map([[userId, new Map([[_this26.opponentDeviceId, _content]])]]));
|
|
1957
|
+
this.emit(CallEvent.SendVoipEvent, {
|
|
1958
|
+
type: "toDevice",
|
|
1959
|
+
eventType,
|
|
1960
|
+
userId: this.invitee || this.getOpponentMember()?.userId,
|
|
1961
|
+
opponentDeviceId: this.opponentDeviceId,
|
|
1962
|
+
content
|
|
1963
|
+
}, this);
|
|
1964
|
+
const userId = this.invitee || this.getOpponentMember().userId;
|
|
1965
|
+
if (this.client.getUseE2eForGroupCall()) {
|
|
1966
|
+
if (!this.hasOpponentDeviceInfo) {
|
|
1967
|
+
logger.warn(`Call ${this.callId} sendVoipEvent() failed: we do not have opponentDeviceInfo`);
|
|
1968
|
+
return;
|
|
2070
1969
|
}
|
|
1970
|
+
|
|
1971
|
+
// TODO: Here we were sending the event to the opponent's device as a to-device message with MatrixClient.encryptAndSendToDevice.
|
|
1972
|
+
// However due to the switch to Rust cryptography we need to migrate to the new encryptToDeviceMessages API.
|
|
1973
|
+
throw new Error("Unimplemented");
|
|
2071
1974
|
} else {
|
|
2072
|
-
|
|
2073
|
-
_this26.emit(CallEvent.SendVoipEvent, {
|
|
2074
|
-
type: "sendEvent",
|
|
2075
|
-
eventType,
|
|
2076
|
-
roomId: _this26.roomId,
|
|
2077
|
-
content: realContent,
|
|
2078
|
-
userId: _this26.invitee || ((_this26$getOpponentMe2 = _this26.getOpponentMember()) === null || _this26$getOpponentMe2 === void 0 ? void 0 : _this26$getOpponentMe2.userId)
|
|
2079
|
-
}, _this26);
|
|
2080
|
-
yield _this26.client.sendEvent(_this26.roomId, eventType, realContent);
|
|
1975
|
+
await this.client.sendToDevice(eventType, new Map([[userId, new Map([[this.opponentDeviceId, content]])]]));
|
|
2081
1976
|
}
|
|
2082
|
-
}
|
|
1977
|
+
} else {
|
|
1978
|
+
this.emit(CallEvent.SendVoipEvent, {
|
|
1979
|
+
type: "sendEvent",
|
|
1980
|
+
eventType,
|
|
1981
|
+
roomId: this.roomId,
|
|
1982
|
+
content: realContent,
|
|
1983
|
+
userId: this.invitee || this.getOpponentMember()?.userId
|
|
1984
|
+
}, this);
|
|
1985
|
+
await this.client.sendEvent(this.roomId, eventType, realContent);
|
|
1986
|
+
}
|
|
2083
1987
|
}
|
|
2084
1988
|
|
|
2085
1989
|
/**
|
|
@@ -2113,7 +2017,7 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
2113
2017
|
|
|
2114
2018
|
// MSC2746 recommends these values (can be quite long when calling because the
|
|
2115
2019
|
// callee will need a while to answer the call)
|
|
2116
|
-
|
|
2020
|
+
const delay = this.direction === CallDirection.Inbound ? 500 : 2000;
|
|
2117
2021
|
if (this.candidateSendTries === 0) {
|
|
2118
2022
|
setTimeout(() => {
|
|
2119
2023
|
this.sendCandidateQueue();
|
|
@@ -2125,10 +2029,10 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
2125
2029
|
// Return the number of candidate messages that were discarded.
|
|
2126
2030
|
// Call this method before sending an invite or answer message
|
|
2127
2031
|
discardDuplicateCandidates() {
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
for (
|
|
2131
|
-
|
|
2032
|
+
let discardCount = 0;
|
|
2033
|
+
const newQueue = [];
|
|
2034
|
+
for (let i = 0; i < this.candidateSendQueue.length; i++) {
|
|
2035
|
+
const candidate = this.candidateSendQueue[i];
|
|
2132
2036
|
if (candidate.candidate === "") {
|
|
2133
2037
|
newQueue.push(candidate);
|
|
2134
2038
|
} else {
|
|
@@ -2142,115 +2046,101 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
2142
2046
|
/*
|
|
2143
2047
|
* Transfers this call to another user
|
|
2144
2048
|
*/
|
|
2145
|
-
transfer(targetUserId) {
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
yield _this27.sendVoipEvent(EventType.CallReplaces, body);
|
|
2162
|
-
yield _this27.terminate(CallParty.Local, CallErrorCode.Transferred, true);
|
|
2163
|
-
})();
|
|
2049
|
+
async transfer(targetUserId) {
|
|
2050
|
+
// Fetch the target user's global profile info: their room avatar / displayname
|
|
2051
|
+
// could be different in whatever room we share with them.
|
|
2052
|
+
const profileInfo = await this.client.getProfileInfo(targetUserId);
|
|
2053
|
+
const replacementId = genCallID();
|
|
2054
|
+
const body = {
|
|
2055
|
+
replacement_id: genCallID(),
|
|
2056
|
+
target_user: {
|
|
2057
|
+
id: targetUserId,
|
|
2058
|
+
display_name: profileInfo.displayname,
|
|
2059
|
+
avatar_url: profileInfo.avatar_url
|
|
2060
|
+
},
|
|
2061
|
+
create_call: replacementId
|
|
2062
|
+
};
|
|
2063
|
+
await this.sendVoipEvent(EventType.CallReplaces, body);
|
|
2064
|
+
await this.terminate(CallParty.Local, CallErrorCode.Transferred, true);
|
|
2164
2065
|
}
|
|
2165
2066
|
|
|
2166
2067
|
/*
|
|
2167
2068
|
* Transfers this call to the target call, effectively 'joining' the
|
|
2168
2069
|
* two calls (so the remote parties on each call are connected together).
|
|
2169
2070
|
*/
|
|
2170
|
-
transferToCall(transferTargetCall) {
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
_this29.stopAllMedia();
|
|
2240
|
-
_this29.deleteAllFeeds();
|
|
2241
|
-
if (_this29.peerConn && _this29.peerConn.signalingState !== "closed") {
|
|
2242
|
-
_this29.peerConn.close();
|
|
2243
|
-
}
|
|
2244
|
-
(_this29$stats = _this29.stats) === null || _this29$stats === void 0 || _this29$stats.removeStatsReportGatherer(_this29.callId);
|
|
2245
|
-
if (shouldEmit) {
|
|
2246
|
-
_this29.emit(CallEvent.Hangup, _this29);
|
|
2247
|
-
}
|
|
2248
|
-
_this29.client.callEventHandler.calls.delete(_this29.callId);
|
|
2249
|
-
})();
|
|
2071
|
+
async transferToCall(transferTargetCall) {
|
|
2072
|
+
const targetUserId = transferTargetCall.getOpponentMember()?.userId;
|
|
2073
|
+
const targetProfileInfo = targetUserId ? await this.client.getProfileInfo(targetUserId) : undefined;
|
|
2074
|
+
const opponentUserId = this.getOpponentMember()?.userId;
|
|
2075
|
+
const transfereeProfileInfo = opponentUserId ? await this.client.getProfileInfo(opponentUserId) : undefined;
|
|
2076
|
+
const newCallId = genCallID();
|
|
2077
|
+
const bodyToTransferTarget = {
|
|
2078
|
+
// the replacements on each side have their own ID, and it's distinct from the
|
|
2079
|
+
// ID of the new call (but we can use the same function to generate it)
|
|
2080
|
+
replacement_id: genCallID(),
|
|
2081
|
+
target_user: {
|
|
2082
|
+
id: opponentUserId,
|
|
2083
|
+
display_name: transfereeProfileInfo?.displayname,
|
|
2084
|
+
avatar_url: transfereeProfileInfo?.avatar_url
|
|
2085
|
+
},
|
|
2086
|
+
await_call: newCallId
|
|
2087
|
+
};
|
|
2088
|
+
await transferTargetCall.sendVoipEvent(EventType.CallReplaces, bodyToTransferTarget);
|
|
2089
|
+
const bodyToTransferee = {
|
|
2090
|
+
replacement_id: genCallID(),
|
|
2091
|
+
target_user: {
|
|
2092
|
+
id: targetUserId,
|
|
2093
|
+
display_name: targetProfileInfo?.displayname,
|
|
2094
|
+
avatar_url: targetProfileInfo?.avatar_url
|
|
2095
|
+
},
|
|
2096
|
+
create_call: newCallId
|
|
2097
|
+
};
|
|
2098
|
+
await this.sendVoipEvent(EventType.CallReplaces, bodyToTransferee);
|
|
2099
|
+
await this.terminate(CallParty.Local, CallErrorCode.Transferred, true);
|
|
2100
|
+
await transferTargetCall.terminate(CallParty.Local, CallErrorCode.Transferred, true);
|
|
2101
|
+
}
|
|
2102
|
+
async terminate(hangupParty, hangupReason, shouldEmit) {
|
|
2103
|
+
if (this.callHasEnded()) return;
|
|
2104
|
+
this.hangupParty = hangupParty;
|
|
2105
|
+
this.hangupReason = hangupReason;
|
|
2106
|
+
this.state = CallState.Ended;
|
|
2107
|
+
if (this.inviteTimeout) {
|
|
2108
|
+
clearTimeout(this.inviteTimeout);
|
|
2109
|
+
this.inviteTimeout = undefined;
|
|
2110
|
+
}
|
|
2111
|
+
if (this.iceDisconnectedTimeout !== undefined) {
|
|
2112
|
+
clearTimeout(this.iceDisconnectedTimeout);
|
|
2113
|
+
this.iceDisconnectedTimeout = undefined;
|
|
2114
|
+
}
|
|
2115
|
+
if (this.callLengthInterval) {
|
|
2116
|
+
clearInterval(this.callLengthInterval);
|
|
2117
|
+
this.callLengthInterval = undefined;
|
|
2118
|
+
}
|
|
2119
|
+
if (this.stopVideoTrackTimer !== undefined) {
|
|
2120
|
+
clearTimeout(this.stopVideoTrackTimer);
|
|
2121
|
+
this.stopVideoTrackTimer = undefined;
|
|
2122
|
+
}
|
|
2123
|
+
for (const [stream, listener] of this.removeTrackListeners) {
|
|
2124
|
+
stream.removeEventListener("removetrack", listener);
|
|
2125
|
+
}
|
|
2126
|
+
this.removeTrackListeners.clear();
|
|
2127
|
+
this.callStatsAtEnd = await this.collectCallStats();
|
|
2128
|
+
|
|
2129
|
+
// Order is important here: first we stopAllMedia() and only then we can deleteAllFeeds()
|
|
2130
|
+
this.stopAllMedia();
|
|
2131
|
+
this.deleteAllFeeds();
|
|
2132
|
+
if (this.peerConn && this.peerConn.signalingState !== "closed") {
|
|
2133
|
+
this.peerConn.close();
|
|
2134
|
+
}
|
|
2135
|
+
this.stats?.removeStatsReportGatherer(this.callId);
|
|
2136
|
+
if (shouldEmit) {
|
|
2137
|
+
this.emit(CallEvent.Hangup, this);
|
|
2138
|
+
}
|
|
2139
|
+
this.client.callEventHandler.calls.delete(this.callId);
|
|
2250
2140
|
}
|
|
2251
2141
|
stopAllMedia() {
|
|
2252
|
-
logger.debug(
|
|
2253
|
-
for (
|
|
2142
|
+
logger.debug(`Call ${this.callId} stopAllMedia() running`);
|
|
2143
|
+
for (const feed of this.feeds) {
|
|
2254
2144
|
// Slightly awkward as local feed need to go via the correct method on
|
|
2255
2145
|
// the MediaHandler so they get removed from MediaHandler (remote tracks
|
|
2256
2146
|
// don't)
|
|
@@ -2262,8 +2152,8 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
2262
2152
|
} else if (feed.isLocal() && feed.purpose === SDPStreamMetadataPurpose.Screenshare) {
|
|
2263
2153
|
this.client.getMediaHandler().stopScreensharingStream(feed.stream);
|
|
2264
2154
|
} else if (!feed.isLocal()) {
|
|
2265
|
-
logger.debug(
|
|
2266
|
-
for (
|
|
2155
|
+
logger.debug(`Call ${this.callId} stopAllMedia() stopping stream (streamId=${feed.stream.id})`);
|
|
2156
|
+
for (const track of feed.stream.getTracks()) {
|
|
2267
2157
|
track.stop();
|
|
2268
2158
|
}
|
|
2269
2159
|
}
|
|
@@ -2274,56 +2164,53 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
2274
2164
|
throw new Error("You MUST attach an error listener using call.on('error', function() {})");
|
|
2275
2165
|
}
|
|
2276
2166
|
}
|
|
2277
|
-
sendCandidateQueue() {
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2167
|
+
async sendCandidateQueue() {
|
|
2168
|
+
if (this.candidateSendQueue.length === 0 || this.callHasEnded()) {
|
|
2169
|
+
return;
|
|
2170
|
+
}
|
|
2171
|
+
const candidates = this.candidateSendQueue;
|
|
2172
|
+
this.candidateSendQueue = [];
|
|
2173
|
+
++this.candidateSendTries;
|
|
2174
|
+
const content = {
|
|
2175
|
+
candidates: candidates.map(candidate => candidate.toJSON())
|
|
2176
|
+
};
|
|
2177
|
+
if (this.candidatesEnded) {
|
|
2178
|
+
// If there are no more candidates, signal this by adding an empty string candidate
|
|
2179
|
+
content.candidates.push({
|
|
2180
|
+
candidate: ""
|
|
2181
|
+
});
|
|
2182
|
+
}
|
|
2183
|
+
logger.debug(`Call ${this.callId} sendCandidateQueue() attempting to send ${candidates.length} candidates`);
|
|
2184
|
+
try {
|
|
2185
|
+
await this.sendVoipEvent(EventType.CallCandidates, content);
|
|
2186
|
+
// reset our retry count if we have successfully sent our candidates
|
|
2187
|
+
// otherwise queueCandidate() will refuse to try to flush the queue
|
|
2188
|
+
this.candidateSendTries = 0;
|
|
2189
|
+
|
|
2190
|
+
// Try to send candidates again just in case we received more candidates while sending.
|
|
2191
|
+
this.sendCandidateQueue();
|
|
2192
|
+
} catch (error) {
|
|
2193
|
+
// don't retry this event: we'll send another one later as we might
|
|
2194
|
+
// have more candidates by then.
|
|
2195
|
+
if (error instanceof MatrixError && error.event) this.client.cancelPendingEvent(error.event);
|
|
2196
|
+
|
|
2197
|
+
// put all the candidates we failed to send back in the queue
|
|
2198
|
+
this.candidateSendQueue.push(...candidates);
|
|
2199
|
+
if (this.candidateSendTries > 5) {
|
|
2200
|
+
logger.debug(`Call ${this.callId} sendCandidateQueue() failed to send candidates on attempt ${this.candidateSendTries}. Giving up on this call.`, error);
|
|
2201
|
+
const code = CallErrorCode.SignallingFailed;
|
|
2202
|
+
const message = "Signalling failed";
|
|
2203
|
+
this.emit(CallEvent.Error, new CallError(code, message, error), this);
|
|
2204
|
+
this.hangup(code, false);
|
|
2281
2205
|
return;
|
|
2282
2206
|
}
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
};
|
|
2289
|
-
|
|
2290
|
-
// If there are no more candidates, signal this by adding an empty string candidate
|
|
2291
|
-
content.candidates.push({
|
|
2292
|
-
candidate: ""
|
|
2293
|
-
});
|
|
2294
|
-
}
|
|
2295
|
-
logger.debug("Call ".concat(_this30.callId, " sendCandidateQueue() attempting to send ").concat(candidates.length, " candidates"));
|
|
2296
|
-
try {
|
|
2297
|
-
yield _this30.sendVoipEvent(EventType.CallCandidates, content);
|
|
2298
|
-
// reset our retry count if we have successfully sent our candidates
|
|
2299
|
-
// otherwise queueCandidate() will refuse to try to flush the queue
|
|
2300
|
-
_this30.candidateSendTries = 0;
|
|
2301
|
-
|
|
2302
|
-
// Try to send candidates again just in case we received more candidates while sending.
|
|
2303
|
-
_this30.sendCandidateQueue();
|
|
2304
|
-
} catch (error) {
|
|
2305
|
-
// don't retry this event: we'll send another one later as we might
|
|
2306
|
-
// have more candidates by then.
|
|
2307
|
-
if (error instanceof MatrixError && error.event) _this30.client.cancelPendingEvent(error.event);
|
|
2308
|
-
|
|
2309
|
-
// put all the candidates we failed to send back in the queue
|
|
2310
|
-
_this30.candidateSendQueue.push(...candidates);
|
|
2311
|
-
if (_this30.candidateSendTries > 5) {
|
|
2312
|
-
logger.debug("Call ".concat(_this30.callId, " sendCandidateQueue() failed to send candidates on attempt ").concat(_this30.candidateSendTries, ". Giving up on this call."), error);
|
|
2313
|
-
var code = CallErrorCode.SignallingFailed;
|
|
2314
|
-
var message = "Signalling failed";
|
|
2315
|
-
_this30.emit(CallEvent.Error, new CallError(code, message, error), _this30);
|
|
2316
|
-
_this30.hangup(code, false);
|
|
2317
|
-
return;
|
|
2318
|
-
}
|
|
2319
|
-
var delayMs = 500 * Math.pow(2, _this30.candidateSendTries);
|
|
2320
|
-
++_this30.candidateSendTries;
|
|
2321
|
-
logger.debug("Call ".concat(_this30.callId, " sendCandidateQueue() failed to send candidates. Retrying in ").concat(delayMs, "ms"), error);
|
|
2322
|
-
setTimeout(() => {
|
|
2323
|
-
_this30.sendCandidateQueue();
|
|
2324
|
-
}, delayMs);
|
|
2325
|
-
}
|
|
2326
|
-
})();
|
|
2207
|
+
const delayMs = 500 * Math.pow(2, this.candidateSendTries);
|
|
2208
|
+
++this.candidateSendTries;
|
|
2209
|
+
logger.debug(`Call ${this.callId} sendCandidateQueue() failed to send candidates. Retrying in ${delayMs}ms`, error);
|
|
2210
|
+
setTimeout(() => {
|
|
2211
|
+
this.sendCandidateQueue();
|
|
2212
|
+
}, delayMs);
|
|
2213
|
+
}
|
|
2327
2214
|
}
|
|
2328
2215
|
|
|
2329
2216
|
/**
|
|
@@ -2331,43 +2218,39 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
2331
2218
|
* @throws if you have not specified a listener for 'error' events.
|
|
2332
2219
|
* @throws if have passed audio=false.
|
|
2333
2220
|
*/
|
|
2334
|
-
placeCall(audio, video) {
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
_this31.placeCallFailed(e);
|
|
2368
|
-
return;
|
|
2369
|
-
}
|
|
2370
|
-
})();
|
|
2221
|
+
async placeCall(audio, video) {
|
|
2222
|
+
if (!audio) {
|
|
2223
|
+
throw new Error("You CANNOT start a call without audio");
|
|
2224
|
+
}
|
|
2225
|
+
this.state = CallState.WaitLocalMedia;
|
|
2226
|
+
let callFeed;
|
|
2227
|
+
try {
|
|
2228
|
+
const stream = await this.client.getMediaHandler().getUserMediaStream(audio, video);
|
|
2229
|
+
|
|
2230
|
+
// make sure all the tracks are enabled (same as pushNewLocalFeed -
|
|
2231
|
+
// we probably ought to just have one code path for adding streams)
|
|
2232
|
+
setTracksEnabled(stream.getAudioTracks(), true);
|
|
2233
|
+
setTracksEnabled(stream.getVideoTracks(), true);
|
|
2234
|
+
callFeed = new CallFeed({
|
|
2235
|
+
client: this.client,
|
|
2236
|
+
roomId: this.roomId,
|
|
2237
|
+
userId: this.client.getUserId(),
|
|
2238
|
+
deviceId: this.client.getDeviceId() ?? undefined,
|
|
2239
|
+
stream,
|
|
2240
|
+
purpose: SDPStreamMetadataPurpose.Usermedia,
|
|
2241
|
+
audioMuted: false,
|
|
2242
|
+
videoMuted: false
|
|
2243
|
+
});
|
|
2244
|
+
} catch (e) {
|
|
2245
|
+
this.getUserMediaFailed(e);
|
|
2246
|
+
return;
|
|
2247
|
+
}
|
|
2248
|
+
try {
|
|
2249
|
+
await this.placeCallWithCallFeeds([callFeed]);
|
|
2250
|
+
} catch (e) {
|
|
2251
|
+
this.placeCallFailed(e);
|
|
2252
|
+
return;
|
|
2253
|
+
}
|
|
2371
2254
|
}
|
|
2372
2255
|
|
|
2373
2256
|
/**
|
|
@@ -2376,35 +2259,29 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
2376
2259
|
* @throws if you have not specified a listener for 'error' events.
|
|
2377
2260
|
* @throws if have passed audio=false.
|
|
2378
2261
|
*/
|
|
2379
|
-
placeCallWithCallFeeds(callFeeds) {
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
var haveTurnCreds = yield _this32.client.checkTurnServers();
|
|
2394
|
-
if (!haveTurnCreds) {
|
|
2395
|
-
logger.warn("Call ".concat(_this32.callId, " placeCallWithCallFeeds() failed to get TURN credentials! Proceeding with call anyway..."));
|
|
2396
|
-
}
|
|
2262
|
+
async placeCallWithCallFeeds(callFeeds, requestScreenshareFeed = false) {
|
|
2263
|
+
this.checkForErrorListener();
|
|
2264
|
+
this.direction = CallDirection.Outbound;
|
|
2265
|
+
await this.initOpponentCrypto();
|
|
2266
|
+
|
|
2267
|
+
// XXX Find a better way to do this
|
|
2268
|
+
this.client.callEventHandler.calls.set(this.callId, this);
|
|
2269
|
+
|
|
2270
|
+
// make sure we have valid turn creds. Unless something's gone wrong, it should
|
|
2271
|
+
// poll and keep the credentials valid so this should be instant.
|
|
2272
|
+
const haveTurnCreds = await this.client.checkTurnServers();
|
|
2273
|
+
if (!haveTurnCreds) {
|
|
2274
|
+
logger.warn(`Call ${this.callId} placeCallWithCallFeeds() failed to get TURN credentials! Proceeding with call anyway...`);
|
|
2275
|
+
}
|
|
2397
2276
|
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
})();
|
|
2277
|
+
// create the peer connection now so it can be gathering candidates while we get user
|
|
2278
|
+
// media (assuming a candidate pool size is configured)
|
|
2279
|
+
this.peerConn = this.createPeerConnection();
|
|
2280
|
+
this.emit(CallEvent.PeerConnectionCreated, this.peerConn, this);
|
|
2281
|
+
this.gotCallFeedsForInvite(callFeeds, requestScreenshareFeed);
|
|
2404
2282
|
}
|
|
2405
2283
|
createPeerConnection() {
|
|
2406
|
-
|
|
2407
|
-
var pc = new window.RTCPeerConnection({
|
|
2284
|
+
const pc = new window.RTCPeerConnection({
|
|
2408
2285
|
iceTransportPolicy: this.forceTURN ? "relay" : undefined,
|
|
2409
2286
|
iceServers: this.turnServers.length ? this.turnServers : undefined,
|
|
2410
2287
|
iceCandidatePoolSize: this.client.iceCandidatePoolSize,
|
|
@@ -2419,9 +2296,9 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
2419
2296
|
pc.addEventListener("track", this.onTrack);
|
|
2420
2297
|
pc.addEventListener("negotiationneeded", this.onNegotiationNeeded);
|
|
2421
2298
|
pc.addEventListener("datachannel", this.onDataChannel);
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2299
|
+
const opponentMember = this.getOpponentMember();
|
|
2300
|
+
const opponentMemberId = opponentMember ? opponentMember.userId : "unknown";
|
|
2301
|
+
this.stats?.addStatsReportGatherer(this.callId, opponentMemberId, pc);
|
|
2425
2302
|
return pc;
|
|
2426
2303
|
}
|
|
2427
2304
|
partyIdMatches(msg) {
|
|
@@ -2429,17 +2306,16 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
2429
2306
|
// Also we ignore party IDs on the invite/offer if the version is 0, so we must do the same
|
|
2430
2307
|
// here and use null if the version is 0 (woe betide any opponent sending messages in the
|
|
2431
2308
|
// same call with different versions)
|
|
2432
|
-
|
|
2309
|
+
const msgPartyId = msg.version === 0 ? null : msg.party_id || null;
|
|
2433
2310
|
return msgPartyId === this.opponentPartyId;
|
|
2434
2311
|
}
|
|
2435
2312
|
|
|
2436
2313
|
// Commits to an opponent for the call
|
|
2437
2314
|
// ev: An invite or answer event
|
|
2438
2315
|
chooseOpponent(ev) {
|
|
2439
|
-
var _getMember;
|
|
2440
2316
|
// I choo-choo-choose you
|
|
2441
|
-
|
|
2442
|
-
logger.debug(
|
|
2317
|
+
const msg = ev.getContent();
|
|
2318
|
+
logger.debug(`Call ${this.callId} chooseOpponent() running (partyId=${msg.party_id})`);
|
|
2443
2319
|
this.opponentVersion = msg.version;
|
|
2444
2320
|
if (this.opponentVersion === 0) {
|
|
2445
2321
|
// set to null to indicate that we've chosen an opponent, but because
|
|
@@ -2452,55 +2328,47 @@ export class MatrixCall extends TypedEventEmitter {
|
|
|
2452
2328
|
this.opponentPartyId = msg.party_id || null;
|
|
2453
2329
|
}
|
|
2454
2330
|
this.opponentCaps = msg.capabilities || {};
|
|
2455
|
-
this.opponentMember =
|
|
2331
|
+
this.opponentMember = this.client.getRoom(this.roomId).getMember(ev.getSender()) ?? undefined;
|
|
2456
2332
|
if (this.opponentMember) {
|
|
2457
|
-
|
|
2458
|
-
(_this$stats2 = this.stats) === null || _this$stats2 === void 0 || _this$stats2.updateOpponentMember(this.callId, this.opponentMember.userId);
|
|
2333
|
+
this.stats?.updateOpponentMember(this.callId, this.opponentMember.userId);
|
|
2459
2334
|
}
|
|
2460
2335
|
}
|
|
2461
|
-
addBufferedIceCandidates() {
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2336
|
+
async addBufferedIceCandidates() {
|
|
2337
|
+
const bufferedCandidates = this.remoteCandidateBuffer.get(this.opponentPartyId);
|
|
2338
|
+
if (bufferedCandidates) {
|
|
2339
|
+
logger.info(`Call ${this.callId} addBufferedIceCandidates() adding ${bufferedCandidates.length} buffered candidates for opponent ${this.opponentPartyId}`);
|
|
2340
|
+
await this.addIceCandidates(bufferedCandidates);
|
|
2341
|
+
}
|
|
2342
|
+
this.remoteCandidateBuffer.clear();
|
|
2343
|
+
}
|
|
2344
|
+
async addIceCandidates(candidates) {
|
|
2345
|
+
for (const candidate of candidates) {
|
|
2346
|
+
if ((candidate.sdpMid === null || candidate.sdpMid === undefined) && (candidate.sdpMLineIndex === null || candidate.sdpMLineIndex === undefined)) {
|
|
2347
|
+
logger.debug(`Call ${this.callId} addIceCandidates() got remote ICE end-of-candidates`);
|
|
2348
|
+
} else {
|
|
2349
|
+
logger.debug(`Call ${this.callId} addIceCandidates() got remote ICE candidate (sdpMid=${candidate.sdpMid}, candidate=${candidate.candidate})`);
|
|
2468
2350
|
}
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
return _asyncToGenerator(function* () {
|
|
2475
|
-
for (var candidate of candidates) {
|
|
2476
|
-
if ((candidate.sdpMid === null || candidate.sdpMid === undefined) && (candidate.sdpMLineIndex === null || candidate.sdpMLineIndex === undefined)) {
|
|
2477
|
-
logger.debug("Call ".concat(_this34.callId, " addIceCandidates() got remote ICE end-of-candidates"));
|
|
2351
|
+
try {
|
|
2352
|
+
await this.peerConn.addIceCandidate(candidate);
|
|
2353
|
+
} catch (err) {
|
|
2354
|
+
if (!this.ignoreOffer) {
|
|
2355
|
+
logger.info(`Call ${this.callId} addIceCandidates() failed to add remote ICE candidate`, err);
|
|
2478
2356
|
} else {
|
|
2479
|
-
logger.debug(
|
|
2480
|
-
}
|
|
2481
|
-
try {
|
|
2482
|
-
yield _this34.peerConn.addIceCandidate(candidate);
|
|
2483
|
-
} catch (err) {
|
|
2484
|
-
if (!_this34.ignoreOffer) {
|
|
2485
|
-
logger.info("Call ".concat(_this34.callId, " addIceCandidates() failed to add remote ICE candidate"), err);
|
|
2486
|
-
} else {
|
|
2487
|
-
logger.debug("Call ".concat(_this34.callId, " addIceCandidates() failed to add remote ICE candidate because ignoring offer"), err);
|
|
2488
|
-
}
|
|
2357
|
+
logger.debug(`Call ${this.callId} addIceCandidates() failed to add remote ICE candidate because ignoring offer`, err);
|
|
2489
2358
|
}
|
|
2490
2359
|
}
|
|
2491
|
-
}
|
|
2360
|
+
}
|
|
2492
2361
|
}
|
|
2493
2362
|
get hasPeerConnection() {
|
|
2494
2363
|
return Boolean(this.peerConn);
|
|
2495
2364
|
}
|
|
2496
|
-
initStats(stats) {
|
|
2497
|
-
var peerId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "unknown";
|
|
2365
|
+
initStats(stats, peerId = "unknown") {
|
|
2498
2366
|
this.stats = stats;
|
|
2499
2367
|
this.stats.start();
|
|
2500
2368
|
}
|
|
2501
2369
|
}
|
|
2502
2370
|
export function setTracksEnabled(tracks, enabled) {
|
|
2503
|
-
for (
|
|
2371
|
+
for (const track of tracks) {
|
|
2504
2372
|
track.enabled = enabled;
|
|
2505
2373
|
}
|
|
2506
2374
|
}
|
|
@@ -2516,8 +2384,7 @@ export function supportsMatrixCall() {
|
|
|
2516
2384
|
// There's some information at https://bugzilla.mozilla.org/show_bug.cgi?id=1542616 though the concern
|
|
2517
2385
|
// is that the browser throwing a SecurityError will brick the client creation process.
|
|
2518
2386
|
try {
|
|
2519
|
-
|
|
2520
|
-
var supported = Boolean((_ref5 = (_ref6 = (_window$RTCPeerConnec = window.RTCPeerConnection) !== null && _window$RTCPeerConnec !== void 0 ? _window$RTCPeerConnec : window.RTCSessionDescription) !== null && _ref6 !== void 0 ? _ref6 : window.RTCIceCandidate) !== null && _ref5 !== void 0 ? _ref5 : navigator.mediaDevices);
|
|
2387
|
+
const supported = Boolean(window.RTCPeerConnection ?? window.RTCSessionDescription ?? window.RTCIceCandidate ?? navigator.mediaDevices);
|
|
2521
2388
|
if (!supported) {
|
|
2522
2389
|
/* istanbul ignore if */ // Adds a lot of noise to test runs, so disable logging there.
|
|
2523
2390
|
if (process.env.NODE_ENV !== "test") {
|
|
@@ -2544,19 +2411,19 @@ export function supportsMatrixCall() {
|
|
|
2544
2411
|
*/
|
|
2545
2412
|
export function createNewMatrixCall(client, roomId, options) {
|
|
2546
2413
|
if (!supportsMatrixCall()) return null;
|
|
2547
|
-
|
|
2548
|
-
|
|
2414
|
+
const optionsForceTURN = options ? options.forceTURN : false;
|
|
2415
|
+
const opts = {
|
|
2549
2416
|
client: client,
|
|
2550
2417
|
roomId: roomId,
|
|
2551
|
-
invitee: options
|
|
2418
|
+
invitee: options?.invitee,
|
|
2552
2419
|
turnServers: client.getTurnServers(),
|
|
2553
2420
|
// call level options
|
|
2554
2421
|
forceTURN: client.forceTURN || optionsForceTURN,
|
|
2555
|
-
opponentDeviceId: options
|
|
2556
|
-
opponentSessionId: options
|
|
2557
|
-
groupCallId: options
|
|
2422
|
+
opponentDeviceId: options?.opponentDeviceId,
|
|
2423
|
+
opponentSessionId: options?.opponentSessionId,
|
|
2424
|
+
groupCallId: options?.groupCallId
|
|
2558
2425
|
};
|
|
2559
|
-
|
|
2426
|
+
const call = new MatrixCall(opts);
|
|
2560
2427
|
client.reEmitter.reEmit(call, Object.values(CallEvent));
|
|
2561
2428
|
return call;
|
|
2562
2429
|
}
|