@stream-io/video-client 0.3.11 → 0.3.12
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/CHANGELOG.md +7 -0
- package/dist/index.browser.es.js +126 -227
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +126 -227
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +126 -227
- package/dist/index.es.js.map +1 -1
- package/dist/src/rtc/codecs.d.ts +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/Call.ts +1 -7
- package/src/rtc/codecs.ts +1 -35
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
### [0.3.12](https://github.com/GetStream/stream-video-js/compare/client0.3.11...client0.3.12) (2023-08-31)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* do not do any codec preferences when sending dummy sdp ([#1028](https://github.com/GetStream/stream-video-js/issues/1028)) ([3910619](https://github.com/GetStream/stream-video-js/commit/391061902ab71571e2910a0ebdfeb02e8bfd390a))
|
|
11
|
+
|
|
5
12
|
### [0.3.11](https://github.com/GetStream/stream-video-js/compare/client0.3.10...client0.3.11) (2023-08-30)
|
|
6
13
|
|
|
7
14
|
|
package/dist/index.browser.es.js
CHANGED
|
@@ -5836,204 +5836,6 @@ const createSignalClient = (options) => {
|
|
|
5836
5836
|
return new SignalServerClient(transport);
|
|
5837
5837
|
};
|
|
5838
5838
|
|
|
5839
|
-
/**
|
|
5840
|
-
* Checks whether we are using React Native
|
|
5841
|
-
*/
|
|
5842
|
-
const isReactNative = () => {
|
|
5843
|
-
var _a;
|
|
5844
|
-
if (typeof navigator === 'undefined')
|
|
5845
|
-
return false;
|
|
5846
|
-
return ((_a = navigator.product) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === 'reactnative';
|
|
5847
|
-
};
|
|
5848
|
-
|
|
5849
|
-
const getRtpMap = (line) => {
|
|
5850
|
-
// Example: a=rtpmap:110 opus/48000/2
|
|
5851
|
-
const rtpRegex = /^a=rtpmap:(\d*) ([\w\-.]*)(?:\s*\/(\d*)(?:\s*\/(\S*))?)?/;
|
|
5852
|
-
// The first captured group is the payload type number, the second captured group is the encoding name, the third captured group is the clock rate, and the fourth captured group is any additional parameters.
|
|
5853
|
-
const rtpMatch = rtpRegex.exec(line);
|
|
5854
|
-
if (rtpMatch) {
|
|
5855
|
-
return {
|
|
5856
|
-
original: rtpMatch[0],
|
|
5857
|
-
payload: rtpMatch[1],
|
|
5858
|
-
codec: rtpMatch[2],
|
|
5859
|
-
};
|
|
5860
|
-
}
|
|
5861
|
-
};
|
|
5862
|
-
const getFmtp = (line) => {
|
|
5863
|
-
// Example: a=fmtp:111 minptime=10; useinbandfec=1
|
|
5864
|
-
const fmtpRegex = /^a=fmtp:(\d*) (.*)/;
|
|
5865
|
-
const fmtpMatch = fmtpRegex.exec(line);
|
|
5866
|
-
// The first captured group is the payload type number, the second captured group is any additional parameters.
|
|
5867
|
-
if (fmtpMatch) {
|
|
5868
|
-
return {
|
|
5869
|
-
original: fmtpMatch[0],
|
|
5870
|
-
payload: fmtpMatch[1],
|
|
5871
|
-
config: fmtpMatch[2],
|
|
5872
|
-
};
|
|
5873
|
-
}
|
|
5874
|
-
};
|
|
5875
|
-
/**
|
|
5876
|
-
* gets the media section for the specified media type.
|
|
5877
|
-
* The media section contains the media type, port, codec, and payload type.
|
|
5878
|
-
* Example: m=video 9 UDP/TLS/RTP/SAVPF 100 101 96 97 35 36 102 125 127
|
|
5879
|
-
*/
|
|
5880
|
-
const getMedia = (line, mediaType) => {
|
|
5881
|
-
const regex = new RegExp(`(m=${mediaType} \\d+ [\\w/]+) ([\\d\\s]+)`);
|
|
5882
|
-
const match = regex.exec(line);
|
|
5883
|
-
if (match) {
|
|
5884
|
-
return {
|
|
5885
|
-
original: match[0],
|
|
5886
|
-
mediaWithPorts: match[1],
|
|
5887
|
-
codecOrder: match[2],
|
|
5888
|
-
};
|
|
5889
|
-
}
|
|
5890
|
-
};
|
|
5891
|
-
const getMediaSection = (sdp, mediaType) => {
|
|
5892
|
-
let media;
|
|
5893
|
-
const rtpMap = [];
|
|
5894
|
-
const fmtp = [];
|
|
5895
|
-
let isTheRequiredMediaSection = false;
|
|
5896
|
-
sdp.split(/(\r\n|\r|\n)/).forEach((line) => {
|
|
5897
|
-
const isValidLine = /^([a-z])=(.*)/.test(line);
|
|
5898
|
-
if (!isValidLine)
|
|
5899
|
-
return;
|
|
5900
|
-
/*
|
|
5901
|
-
NOTE: according to https://www.rfc-editor.org/rfc/rfc8866.pdf
|
|
5902
|
-
Each media description starts with an "m=" line and continues to the next media description or the end of the whole session description, whichever comes first
|
|
5903
|
-
*/
|
|
5904
|
-
const type = line[0];
|
|
5905
|
-
if (type === 'm') {
|
|
5906
|
-
const _media = getMedia(line, mediaType);
|
|
5907
|
-
isTheRequiredMediaSection = !!_media;
|
|
5908
|
-
if (_media) {
|
|
5909
|
-
media = _media;
|
|
5910
|
-
}
|
|
5911
|
-
}
|
|
5912
|
-
else if (isTheRequiredMediaSection && type === 'a') {
|
|
5913
|
-
const rtpMapLine = getRtpMap(line);
|
|
5914
|
-
const fmtpLine = getFmtp(line);
|
|
5915
|
-
if (rtpMapLine) {
|
|
5916
|
-
rtpMap.push(rtpMapLine);
|
|
5917
|
-
}
|
|
5918
|
-
else if (fmtpLine) {
|
|
5919
|
-
fmtp.push(fmtpLine);
|
|
5920
|
-
}
|
|
5921
|
-
}
|
|
5922
|
-
});
|
|
5923
|
-
if (media) {
|
|
5924
|
-
return {
|
|
5925
|
-
media,
|
|
5926
|
-
rtpMap,
|
|
5927
|
-
fmtp,
|
|
5928
|
-
};
|
|
5929
|
-
}
|
|
5930
|
-
};
|
|
5931
|
-
/**
|
|
5932
|
-
* Returns a string of codec IDs with the preferred codec ID in front of the other codec IDs.
|
|
5933
|
-
* It is used to ensure that a preferred codec is used when decoding a media stream.
|
|
5934
|
-
* Example: Suppose we want to prefer VP8 which has id 96
|
|
5935
|
-
* 1. If codec order is 100 101 96 97 35 36 102 125 127
|
|
5936
|
-
* 2. The function returns 96 100 101 97 35 36 102 125 127
|
|
5937
|
-
*/
|
|
5938
|
-
const moveCodecToFront = (codecOrder, preferredCodecId) => {
|
|
5939
|
-
const codecIds = codecOrder.split(' ');
|
|
5940
|
-
const index = codecIds.indexOf(preferredCodecId);
|
|
5941
|
-
if (index > -1) {
|
|
5942
|
-
codecIds.splice(index, 1);
|
|
5943
|
-
codecIds.unshift(preferredCodecId);
|
|
5944
|
-
}
|
|
5945
|
-
return codecIds.join(' ');
|
|
5946
|
-
};
|
|
5947
|
-
/**
|
|
5948
|
-
* Returns a string of codec IDs with the given codec ID removed
|
|
5949
|
-
* It is used to ensure that a codec is disabled when processing a media stream.
|
|
5950
|
-
* Example: Suppose we want to prefer RED which has id 63
|
|
5951
|
-
* 1. If codec order is 111 63 103 104 9 102 0 8 106 105 13 110 112 113 126
|
|
5952
|
-
* 2. The function returns 111 103 104 9 102 0 8 106 105 13 110 112 113 126
|
|
5953
|
-
*/
|
|
5954
|
-
const removeCodecFromOrder = (codecOrder, codecIdToRemove) => {
|
|
5955
|
-
const codecIds = codecOrder.split(' ');
|
|
5956
|
-
return codecIds.filter((codecID) => codecID !== codecIdToRemove).join(' ');
|
|
5957
|
-
};
|
|
5958
|
-
/**
|
|
5959
|
-
* Returns an SDP with the preferred codec in front of the other codecs.
|
|
5960
|
-
* Example: Suppose we want to prefer VP8
|
|
5961
|
-
* 1. find video media specification m=video 9 UDP/TLS/RTP/SAVPF 100 101 96 97 35 36 102 125 127
|
|
5962
|
-
* 2. look for specified codec (VP8) a=rtpmap:96 VP8/90000
|
|
5963
|
-
* 3. extract 96 as an identifier of VP8
|
|
5964
|
-
* 4. move 96 to the front
|
|
5965
|
-
* 5. now media looks like this: m=video 9 UDP/TLS/RTP/SAVPF 96 100 101 97 35 36 102 125 127
|
|
5966
|
-
*/
|
|
5967
|
-
const setPreferredCodec = (sdp, mediaType, preferredCodec) => {
|
|
5968
|
-
const section = getMediaSection(sdp, mediaType);
|
|
5969
|
-
if (!section)
|
|
5970
|
-
return sdp;
|
|
5971
|
-
const rtpMap = section.rtpMap.find((r) => r.codec.toLowerCase() === preferredCodec.toLowerCase());
|
|
5972
|
-
const codecId = rtpMap === null || rtpMap === void 0 ? void 0 : rtpMap.payload;
|
|
5973
|
-
if (!codecId)
|
|
5974
|
-
return sdp;
|
|
5975
|
-
const newCodecOrder = moveCodecToFront(section.media.codecOrder, codecId);
|
|
5976
|
-
return sdp.replace(section.media.original, `${section.media.mediaWithPorts} ${newCodecOrder}`);
|
|
5977
|
-
};
|
|
5978
|
-
/**
|
|
5979
|
-
* Returns an SDP with the specified codec removed.
|
|
5980
|
-
* Example: Suppose we want to remove RED
|
|
5981
|
-
* 1. find audio media specification m=video 9 UDP/TLS/RTP/SAVPF 100 101 96 97 35 36 102 125 127
|
|
5982
|
-
* 2. look for specified codec (RED) a=rtpmap:127 red/90000
|
|
5983
|
-
* 3. extract 127 as an identifier of RED
|
|
5984
|
-
* 4. remove 127 from the codec order
|
|
5985
|
-
* 5. remove a=rtpmap:127 red/90000
|
|
5986
|
-
* 6. remove a=fmtp:127 ...
|
|
5987
|
-
*/
|
|
5988
|
-
const removeCodec = (sdp, mediaType, codecToRemove) => {
|
|
5989
|
-
const section = getMediaSection(sdp, mediaType);
|
|
5990
|
-
const mediaSection = section === null || section === void 0 ? void 0 : section.media;
|
|
5991
|
-
if (!mediaSection) {
|
|
5992
|
-
return sdp;
|
|
5993
|
-
}
|
|
5994
|
-
const rtpMap = section === null || section === void 0 ? void 0 : section.rtpMap.find((r) => r.codec.toLowerCase() === codecToRemove.toLowerCase());
|
|
5995
|
-
const codecId = rtpMap === null || rtpMap === void 0 ? void 0 : rtpMap.payload;
|
|
5996
|
-
if (!codecId) {
|
|
5997
|
-
return sdp;
|
|
5998
|
-
}
|
|
5999
|
-
const newCodecOrder = removeCodecFromOrder(mediaSection.codecOrder, codecId);
|
|
6000
|
-
const fmtp = section === null || section === void 0 ? void 0 : section.fmtp.find((f) => f.payload === codecId);
|
|
6001
|
-
return sdp
|
|
6002
|
-
.replace(mediaSection.original, `${mediaSection.mediaWithPorts} ${newCodecOrder}`)
|
|
6003
|
-
.replace(new RegExp(`${rtpMap.original}[\r\n]+`), '') // remove the corresponding rtpmap line
|
|
6004
|
-
.replace((fmtp === null || fmtp === void 0 ? void 0 : fmtp.original) ? new RegExp(`${fmtp === null || fmtp === void 0 ? void 0 : fmtp.original}[\r\n]+`) : '', ''); // remove the corresponding fmtp line
|
|
6005
|
-
};
|
|
6006
|
-
/**
|
|
6007
|
-
* Gets the fmtp line corresponding to opus
|
|
6008
|
-
*/
|
|
6009
|
-
const getOpusFmtp = (sdp) => {
|
|
6010
|
-
const section = getMediaSection(sdp, 'audio');
|
|
6011
|
-
const rtpMap = section === null || section === void 0 ? void 0 : section.rtpMap.find((r) => r.codec.toLowerCase() === 'opus');
|
|
6012
|
-
const codecId = rtpMap === null || rtpMap === void 0 ? void 0 : rtpMap.payload;
|
|
6013
|
-
if (codecId) {
|
|
6014
|
-
return section === null || section === void 0 ? void 0 : section.fmtp.find((f) => f.payload === codecId);
|
|
6015
|
-
}
|
|
6016
|
-
};
|
|
6017
|
-
/**
|
|
6018
|
-
* Returns an SDP with DTX enabled or disabled.
|
|
6019
|
-
*/
|
|
6020
|
-
const toggleDtx = (sdp, enable) => {
|
|
6021
|
-
const opusFmtp = getOpusFmtp(sdp);
|
|
6022
|
-
if (opusFmtp) {
|
|
6023
|
-
const matchDtx = /usedtx=(\d)/.exec(opusFmtp.config);
|
|
6024
|
-
const requiredDtxConfig = `usedtx=${enable ? '1' : '0'}`;
|
|
6025
|
-
if (matchDtx) {
|
|
6026
|
-
const newFmtp = opusFmtp.original.replace(/usedtx=(\d)/, requiredDtxConfig);
|
|
6027
|
-
return sdp.replace(opusFmtp.original, newFmtp);
|
|
6028
|
-
}
|
|
6029
|
-
else {
|
|
6030
|
-
const newFmtp = `${opusFmtp.original};${requiredDtxConfig}`;
|
|
6031
|
-
return sdp.replace(opusFmtp.original, newFmtp);
|
|
6032
|
-
}
|
|
6033
|
-
}
|
|
6034
|
-
return sdp;
|
|
6035
|
-
};
|
|
6036
|
-
|
|
6037
5839
|
// log levels, sorted by verbosity
|
|
6038
5840
|
const logLevels = Object.freeze({
|
|
6039
5841
|
trace: 0,
|
|
@@ -6125,39 +5927,13 @@ const getPreferredCodecs = (kind, preferredCodec, codecToRemove) => {
|
|
|
6125
5927
|
logger === null || logger === void 0 ? void 0 : logger('info', `Preffered codecs: `, result);
|
|
6126
5928
|
return result;
|
|
6127
5929
|
};
|
|
6128
|
-
const getGenericSdp = (direction
|
|
5930
|
+
const getGenericSdp = (direction) => __awaiter(void 0, void 0, void 0, function* () {
|
|
6129
5931
|
var _a;
|
|
6130
5932
|
const tempPc = new RTCPeerConnection();
|
|
6131
5933
|
tempPc.addTransceiver('video', { direction });
|
|
6132
|
-
// if ('setCodecPreferences' in videoTransceiver) {
|
|
6133
|
-
// const videoCodecPreferences = getPreferredCodecs(
|
|
6134
|
-
// 'audio',
|
|
6135
|
-
// preferredVideoCodec ?? 'vp8',
|
|
6136
|
-
// );
|
|
6137
|
-
// videoTransceiver.setCodecPreferences([...(videoCodecPreferences ?? [])]);
|
|
6138
|
-
// }
|
|
6139
5934
|
tempPc.addTransceiver('audio', { direction });
|
|
6140
|
-
const preferredAudioCodec = isRedEnabled ? 'red' : 'opus';
|
|
6141
|
-
const audioCodecToRemove = !isRedEnabled ? 'red' : undefined;
|
|
6142
|
-
// if ('setCodecPreferences' in audioTransceiver) {
|
|
6143
|
-
// const audioCodecPreferences = getPreferredCodecs(
|
|
6144
|
-
// 'audio',
|
|
6145
|
-
// preferredAudioCodec,
|
|
6146
|
-
// // audioCodecToRemove,
|
|
6147
|
-
// );
|
|
6148
|
-
// audioTransceiver.setCodecPreferences([...(audioCodecPreferences || [])]);
|
|
6149
|
-
// }
|
|
6150
5935
|
const offer = yield tempPc.createOffer();
|
|
6151
5936
|
let sdp = (_a = offer.sdp) !== null && _a !== void 0 ? _a : '';
|
|
6152
|
-
if (isReactNative()) {
|
|
6153
|
-
if (preferredVideoCodec) {
|
|
6154
|
-
sdp = setPreferredCodec(sdp, 'video', preferredVideoCodec);
|
|
6155
|
-
}
|
|
6156
|
-
sdp = setPreferredCodec(sdp, 'audio', preferredAudioCodec);
|
|
6157
|
-
if (audioCodecToRemove) {
|
|
6158
|
-
sdp = removeCodec(sdp, 'audio', audioCodecToRemove);
|
|
6159
|
-
}
|
|
6160
|
-
}
|
|
6161
5937
|
tempPc.getTransceivers().forEach((t) => {
|
|
6162
5938
|
t.stop();
|
|
6163
5939
|
});
|
|
@@ -6266,6 +6042,16 @@ function getIceCandidate(candidate) {
|
|
|
6266
6042
|
}
|
|
6267
6043
|
}
|
|
6268
6044
|
|
|
6045
|
+
/**
|
|
6046
|
+
* Checks whether we are using React Native
|
|
6047
|
+
*/
|
|
6048
|
+
const isReactNative = () => {
|
|
6049
|
+
var _a;
|
|
6050
|
+
if (typeof navigator === 'undefined')
|
|
6051
|
+
return false;
|
|
6052
|
+
return ((_a = navigator.product) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === 'reactnative';
|
|
6053
|
+
};
|
|
6054
|
+
|
|
6269
6055
|
let sdkInfo;
|
|
6270
6056
|
let osInfo;
|
|
6271
6057
|
let deviceInfo;
|
|
@@ -6462,6 +6248,119 @@ const muteTypeToTrackType = (muteType) => {
|
|
|
6462
6248
|
}
|
|
6463
6249
|
};
|
|
6464
6250
|
|
|
6251
|
+
const getRtpMap = (line) => {
|
|
6252
|
+
// Example: a=rtpmap:110 opus/48000/2
|
|
6253
|
+
const rtpRegex = /^a=rtpmap:(\d*) ([\w\-.]*)(?:\s*\/(\d*)(?:\s*\/(\S*))?)?/;
|
|
6254
|
+
// The first captured group is the payload type number, the second captured group is the encoding name, the third captured group is the clock rate, and the fourth captured group is any additional parameters.
|
|
6255
|
+
const rtpMatch = rtpRegex.exec(line);
|
|
6256
|
+
if (rtpMatch) {
|
|
6257
|
+
return {
|
|
6258
|
+
original: rtpMatch[0],
|
|
6259
|
+
payload: rtpMatch[1],
|
|
6260
|
+
codec: rtpMatch[2],
|
|
6261
|
+
};
|
|
6262
|
+
}
|
|
6263
|
+
};
|
|
6264
|
+
const getFmtp = (line) => {
|
|
6265
|
+
// Example: a=fmtp:111 minptime=10; useinbandfec=1
|
|
6266
|
+
const fmtpRegex = /^a=fmtp:(\d*) (.*)/;
|
|
6267
|
+
const fmtpMatch = fmtpRegex.exec(line);
|
|
6268
|
+
// The first captured group is the payload type number, the second captured group is any additional parameters.
|
|
6269
|
+
if (fmtpMatch) {
|
|
6270
|
+
return {
|
|
6271
|
+
original: fmtpMatch[0],
|
|
6272
|
+
payload: fmtpMatch[1],
|
|
6273
|
+
config: fmtpMatch[2],
|
|
6274
|
+
};
|
|
6275
|
+
}
|
|
6276
|
+
};
|
|
6277
|
+
/**
|
|
6278
|
+
* gets the media section for the specified media type.
|
|
6279
|
+
* The media section contains the media type, port, codec, and payload type.
|
|
6280
|
+
* Example: m=video 9 UDP/TLS/RTP/SAVPF 100 101 96 97 35 36 102 125 127
|
|
6281
|
+
*/
|
|
6282
|
+
const getMedia = (line, mediaType) => {
|
|
6283
|
+
const regex = new RegExp(`(m=${mediaType} \\d+ [\\w/]+) ([\\d\\s]+)`);
|
|
6284
|
+
const match = regex.exec(line);
|
|
6285
|
+
if (match) {
|
|
6286
|
+
return {
|
|
6287
|
+
original: match[0],
|
|
6288
|
+
mediaWithPorts: match[1],
|
|
6289
|
+
codecOrder: match[2],
|
|
6290
|
+
};
|
|
6291
|
+
}
|
|
6292
|
+
};
|
|
6293
|
+
const getMediaSection = (sdp, mediaType) => {
|
|
6294
|
+
let media;
|
|
6295
|
+
const rtpMap = [];
|
|
6296
|
+
const fmtp = [];
|
|
6297
|
+
let isTheRequiredMediaSection = false;
|
|
6298
|
+
sdp.split(/(\r\n|\r|\n)/).forEach((line) => {
|
|
6299
|
+
const isValidLine = /^([a-z])=(.*)/.test(line);
|
|
6300
|
+
if (!isValidLine)
|
|
6301
|
+
return;
|
|
6302
|
+
/*
|
|
6303
|
+
NOTE: according to https://www.rfc-editor.org/rfc/rfc8866.pdf
|
|
6304
|
+
Each media description starts with an "m=" line and continues to the next media description or the end of the whole session description, whichever comes first
|
|
6305
|
+
*/
|
|
6306
|
+
const type = line[0];
|
|
6307
|
+
if (type === 'm') {
|
|
6308
|
+
const _media = getMedia(line, mediaType);
|
|
6309
|
+
isTheRequiredMediaSection = !!_media;
|
|
6310
|
+
if (_media) {
|
|
6311
|
+
media = _media;
|
|
6312
|
+
}
|
|
6313
|
+
}
|
|
6314
|
+
else if (isTheRequiredMediaSection && type === 'a') {
|
|
6315
|
+
const rtpMapLine = getRtpMap(line);
|
|
6316
|
+
const fmtpLine = getFmtp(line);
|
|
6317
|
+
if (rtpMapLine) {
|
|
6318
|
+
rtpMap.push(rtpMapLine);
|
|
6319
|
+
}
|
|
6320
|
+
else if (fmtpLine) {
|
|
6321
|
+
fmtp.push(fmtpLine);
|
|
6322
|
+
}
|
|
6323
|
+
}
|
|
6324
|
+
});
|
|
6325
|
+
if (media) {
|
|
6326
|
+
return {
|
|
6327
|
+
media,
|
|
6328
|
+
rtpMap,
|
|
6329
|
+
fmtp,
|
|
6330
|
+
};
|
|
6331
|
+
}
|
|
6332
|
+
};
|
|
6333
|
+
/**
|
|
6334
|
+
* Gets the fmtp line corresponding to opus
|
|
6335
|
+
*/
|
|
6336
|
+
const getOpusFmtp = (sdp) => {
|
|
6337
|
+
const section = getMediaSection(sdp, 'audio');
|
|
6338
|
+
const rtpMap = section === null || section === void 0 ? void 0 : section.rtpMap.find((r) => r.codec.toLowerCase() === 'opus');
|
|
6339
|
+
const codecId = rtpMap === null || rtpMap === void 0 ? void 0 : rtpMap.payload;
|
|
6340
|
+
if (codecId) {
|
|
6341
|
+
return section === null || section === void 0 ? void 0 : section.fmtp.find((f) => f.payload === codecId);
|
|
6342
|
+
}
|
|
6343
|
+
};
|
|
6344
|
+
/**
|
|
6345
|
+
* Returns an SDP with DTX enabled or disabled.
|
|
6346
|
+
*/
|
|
6347
|
+
const toggleDtx = (sdp, enable) => {
|
|
6348
|
+
const opusFmtp = getOpusFmtp(sdp);
|
|
6349
|
+
if (opusFmtp) {
|
|
6350
|
+
const matchDtx = /usedtx=(\d)/.exec(opusFmtp.config);
|
|
6351
|
+
const requiredDtxConfig = `usedtx=${enable ? '1' : '0'}`;
|
|
6352
|
+
if (matchDtx) {
|
|
6353
|
+
const newFmtp = opusFmtp.original.replace(/usedtx=(\d)/, requiredDtxConfig);
|
|
6354
|
+
return sdp.replace(opusFmtp.original, newFmtp);
|
|
6355
|
+
}
|
|
6356
|
+
else {
|
|
6357
|
+
const newFmtp = `${opusFmtp.original};${requiredDtxConfig}`;
|
|
6358
|
+
return sdp.replace(opusFmtp.original, newFmtp);
|
|
6359
|
+
}
|
|
6360
|
+
}
|
|
6361
|
+
return sdp;
|
|
6362
|
+
};
|
|
6363
|
+
|
|
6465
6364
|
const logger$3 = getLogger(['Publisher']);
|
|
6466
6365
|
/**
|
|
6467
6366
|
* The `Publisher` is responsible for publishing/unpublishing media streams to/from the SFU
|
|
@@ -10788,7 +10687,7 @@ class Call {
|
|
|
10788
10687
|
// prepare a generic SDP and send it to the SFU.
|
|
10789
10688
|
// this is a throw-away SDP that the SFU will use to determine
|
|
10790
10689
|
// the capabilities of the client (codec support, etc.)
|
|
10791
|
-
.then(() => getGenericSdp('recvonly'
|
|
10690
|
+
.then(() => getGenericSdp('recvonly'))
|
|
10792
10691
|
.then((sdp) => {
|
|
10793
10692
|
var _a;
|
|
10794
10693
|
const subscriptions = getCurrentValue(this.trackSubscriptionsSubject);
|
|
@@ -12842,7 +12741,7 @@ class WSConnectionFallback {
|
|
|
12842
12741
|
}
|
|
12843
12742
|
}
|
|
12844
12743
|
|
|
12845
|
-
const version = '0.3.
|
|
12744
|
+
const version = '0.3.12';
|
|
12846
12745
|
|
|
12847
12746
|
const logger = getLogger(['location']);
|
|
12848
12747
|
const HINT_URL = `https://hint.stream-io-video.com/`;
|