@stream-io/video-client 1.11.7 → 1.11.9
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 +14 -0
- package/dist/index.browser.es.js +45 -27
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +45 -27
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +45 -27
- package/dist/index.es.js.map +1 -1
- package/dist/src/rtc/codecs.d.ts +1 -1
- package/package.json +1 -1
- package/src/devices/InputMediaDeviceManager.ts +1 -0
- package/src/devices/devices.ts +16 -22
- package/src/helpers/__tests__/sdp-munging.test.ts +92 -0
- package/src/helpers/sdp-munging.ts +10 -6
- package/src/rtc/Publisher.ts +10 -3
- package/src/rtc/__tests__/codecs.test.ts +6 -6
- package/src/rtc/codecs.ts +20 -9
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
## [1.11.9](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.11.8...@stream-io/video-client-1.11.9) (2024-11-27)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* cover some device selection edge cases ([#1604](https://github.com/GetStream/stream-video-js/issues/1604)) ([a8fc0ea](https://github.com/GetStream/stream-video-js/commit/a8fc0eaf1ed6c79ce24f77f52351a1e90701bd02))
|
|
11
|
+
|
|
12
|
+
## [1.11.8](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.11.7...@stream-io/video-client-1.11.8) (2024-11-27)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* **ios:** use vp8 when h264 constrainted baseline isn't available ([#1597](https://github.com/GetStream/stream-video-js/issues/1597)) ([6281216](https://github.com/GetStream/stream-video-js/commit/62812161cef5e9917c504dbc4cd9257709ea5fa1))
|
|
18
|
+
|
|
5
19
|
## [1.11.7](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.11.6...@stream-io/video-client-1.11.7) (2024-11-26)
|
|
6
20
|
|
|
7
21
|
|
package/dist/index.browser.es.js
CHANGED
|
@@ -3297,7 +3297,7 @@ const retryable = async (rpc, signal) => {
|
|
|
3297
3297
|
return result;
|
|
3298
3298
|
};
|
|
3299
3299
|
|
|
3300
|
-
const version = "1.11.
|
|
3300
|
+
const version = "1.11.9";
|
|
3301
3301
|
const [major, minor, patch] = version.split('.');
|
|
3302
3302
|
let sdkInfo = {
|
|
3303
3303
|
type: SdkType.PLAIN_JAVASCRIPT,
|
|
@@ -3403,7 +3403,7 @@ var browsers = /*#__PURE__*/Object.freeze({
|
|
|
3403
3403
|
* @param codecToRemove the codec to exclude from the list.
|
|
3404
3404
|
* @param codecPreferencesSource the source of the codec preferences.
|
|
3405
3405
|
*/
|
|
3406
|
-
const getPreferredCodecs = (kind, preferredCodec, codecToRemove, codecPreferencesSource
|
|
3406
|
+
const getPreferredCodecs = (kind, preferredCodec, codecToRemove, codecPreferencesSource) => {
|
|
3407
3407
|
const source = codecPreferencesSource === 'receiver' ? RTCRtpReceiver : RTCRtpSender;
|
|
3408
3408
|
if (!('getCapabilities' in source))
|
|
3409
3409
|
return;
|
|
@@ -3439,10 +3439,7 @@ const getPreferredCodecs = (kind, preferredCodec, codecToRemove, codecPreference
|
|
|
3439
3439
|
partiallyPreferred.push(codec);
|
|
3440
3440
|
continue;
|
|
3441
3441
|
}
|
|
3442
|
-
|
|
3443
|
-
// https://datatracker.ietf.org/doc/html/rfc6184#section-6.2
|
|
3444
|
-
if (sdpFmtpLine.includes('packetization-mode=0') ||
|
|
3445
|
-
!sdpFmtpLine.includes('packetization-mode')) {
|
|
3442
|
+
if (sdpFmtpLine.includes('packetization-mode=1')) {
|
|
3446
3443
|
preferred.unshift(codec);
|
|
3447
3444
|
}
|
|
3448
3445
|
else {
|
|
@@ -3479,8 +3476,9 @@ const getOptimalVideoCodec = (preferredCodec) => {
|
|
|
3479
3476
|
const os = getOSInfo()?.name.toLowerCase();
|
|
3480
3477
|
if (os === 'android')
|
|
3481
3478
|
return preferredOr(preferredCodec, 'vp8');
|
|
3482
|
-
if (os === 'ios' || os === 'ipados')
|
|
3483
|
-
return 'h264';
|
|
3479
|
+
if (os === 'ios' || os === 'ipados') {
|
|
3480
|
+
return supportsH264Baseline() ? 'h264' : 'vp8';
|
|
3481
|
+
}
|
|
3484
3482
|
return preferredOr(preferredCodec, 'h264');
|
|
3485
3483
|
}
|
|
3486
3484
|
if (isSafari())
|
|
@@ -3511,6 +3509,18 @@ const preferredOr = (codec, fallback) => {
|
|
|
3511
3509
|
? codec
|
|
3512
3510
|
: fallback;
|
|
3513
3511
|
};
|
|
3512
|
+
/**
|
|
3513
|
+
* Returns whether the platform supports the H264 baseline codec.
|
|
3514
|
+
*/
|
|
3515
|
+
const supportsH264Baseline = () => {
|
|
3516
|
+
if (!('getCapabilities' in RTCRtpSender))
|
|
3517
|
+
return false;
|
|
3518
|
+
const capabilities = RTCRtpSender.getCapabilities('video');
|
|
3519
|
+
if (!capabilities)
|
|
3520
|
+
return false;
|
|
3521
|
+
return capabilities.codecs.some((c) => c.mimeType.toLowerCase() === 'video/h264' &&
|
|
3522
|
+
c.sdpFmtpLine?.includes('profile-level-id=42e01f'));
|
|
3523
|
+
};
|
|
3514
3524
|
/**
|
|
3515
3525
|
* Returns whether the codec is an SVC codec.
|
|
3516
3526
|
*
|
|
@@ -5483,8 +5493,14 @@ const preserveCodec = (sdp, mid, codec) => {
|
|
|
5483
5493
|
// find the payload id of the desired codec
|
|
5484
5494
|
const payloads = new Set();
|
|
5485
5495
|
for (const rtp of media.rtp) {
|
|
5486
|
-
if (rtp.codec.toLowerCase()
|
|
5487
|
-
|
|
5496
|
+
if (rtp.codec.toLowerCase() !== codecName)
|
|
5497
|
+
continue;
|
|
5498
|
+
const match =
|
|
5499
|
+
// vp8 doesn't have any fmtp, we preserve it without any additional checks
|
|
5500
|
+
codecName === 'vp8'
|
|
5501
|
+
? true
|
|
5502
|
+
: media.fmtp.some((f) => f.payload === rtp.payload && equal(toSet(f.config), codecFmtp));
|
|
5503
|
+
if (match) {
|
|
5488
5504
|
payloads.add(rtp.payload);
|
|
5489
5505
|
}
|
|
5490
5506
|
}
|
|
@@ -5686,7 +5702,7 @@ class Publisher {
|
|
|
5686
5702
|
// handle codec preferences
|
|
5687
5703
|
if (!('setCodecPreferences' in transceiver))
|
|
5688
5704
|
return;
|
|
5689
|
-
const codecPreferences = this.getCodecPreferences(trackType, trackType === TrackType.VIDEO ? codecInUse : undefined);
|
|
5705
|
+
const codecPreferences = this.getCodecPreferences(trackType, trackType === TrackType.VIDEO ? codecInUse : undefined, 'receiver');
|
|
5690
5706
|
if (!codecPreferences)
|
|
5691
5707
|
return;
|
|
5692
5708
|
try {
|
|
@@ -5847,12 +5863,12 @@ class Publisher {
|
|
|
5847
5863
|
};
|
|
5848
5864
|
this.getCodecPreferences = (trackType, preferredCodec, codecPreferencesSource) => {
|
|
5849
5865
|
if (trackType === TrackType.VIDEO) {
|
|
5850
|
-
return getPreferredCodecs('video', preferredCodec || 'vp8', codecPreferencesSource);
|
|
5866
|
+
return getPreferredCodecs('video', preferredCodec || 'vp8', undefined, codecPreferencesSource);
|
|
5851
5867
|
}
|
|
5852
5868
|
if (trackType === TrackType.AUDIO) {
|
|
5853
5869
|
const defaultAudioCodec = this.isRedEnabled ? 'red' : 'opus';
|
|
5854
5870
|
const codecToRemove = !this.isRedEnabled ? 'red' : undefined;
|
|
5855
|
-
return getPreferredCodecs('audio', preferredCodec ?? defaultAudioCodec, codecToRemove);
|
|
5871
|
+
return getPreferredCodecs('audio', preferredCodec ?? defaultAudioCodec, codecToRemove, codecPreferencesSource);
|
|
5856
5872
|
}
|
|
5857
5873
|
};
|
|
5858
5874
|
this.onIceCandidate = (e) => {
|
|
@@ -6077,7 +6093,8 @@ class Publisher {
|
|
|
6077
6093
|
}
|
|
6078
6094
|
removeUnpreferredCodecs(sdp, trackType) {
|
|
6079
6095
|
const opts = this.publishOptsForTrack.get(trackType);
|
|
6080
|
-
|
|
6096
|
+
const forceSingleCodec = !!opts?.forceSingleCodec || isReactNative() || isFirefox();
|
|
6097
|
+
if (!opts || !forceSingleCodec)
|
|
6081
6098
|
return sdp;
|
|
6082
6099
|
const codec = opts.forceCodec || getOptimalVideoCodec(opts.preferredCodec);
|
|
6083
6100
|
const orderedCodecs = this.getCodecPreferences(trackType, codec, 'sender');
|
|
@@ -8327,7 +8344,7 @@ const getAudioStream = async (trackConstraints) => {
|
|
|
8327
8344
|
const constraints = {
|
|
8328
8345
|
audio: {
|
|
8329
8346
|
...audioDeviceConstraints.audio,
|
|
8330
|
-
...trackConstraints,
|
|
8347
|
+
...normalizeContraints(trackConstraints),
|
|
8331
8348
|
},
|
|
8332
8349
|
};
|
|
8333
8350
|
try {
|
|
@@ -8338,11 +8355,6 @@ const getAudioStream = async (trackConstraints) => {
|
|
|
8338
8355
|
return await getStream(constraints);
|
|
8339
8356
|
}
|
|
8340
8357
|
catch (error) {
|
|
8341
|
-
if (error instanceof OverconstrainedError && trackConstraints?.deviceId) {
|
|
8342
|
-
const { deviceId, ...relaxedContraints } = trackConstraints;
|
|
8343
|
-
getLogger(['devices'])('warn', 'Failed to get audio stream, will try again with relaxed contraints', { error, constraints, relaxedContraints });
|
|
8344
|
-
return getAudioStream(relaxedContraints);
|
|
8345
|
-
}
|
|
8346
8358
|
getLogger(['devices'])('error', 'Failed to get audio stream', {
|
|
8347
8359
|
error,
|
|
8348
8360
|
constraints,
|
|
@@ -8362,7 +8374,7 @@ const getVideoStream = async (trackConstraints) => {
|
|
|
8362
8374
|
const constraints = {
|
|
8363
8375
|
video: {
|
|
8364
8376
|
...videoDeviceConstraints.video,
|
|
8365
|
-
...trackConstraints,
|
|
8377
|
+
...normalizeContraints(trackConstraints),
|
|
8366
8378
|
},
|
|
8367
8379
|
};
|
|
8368
8380
|
try {
|
|
@@ -8373,11 +8385,6 @@ const getVideoStream = async (trackConstraints) => {
|
|
|
8373
8385
|
return await getStream(constraints);
|
|
8374
8386
|
}
|
|
8375
8387
|
catch (error) {
|
|
8376
|
-
if (error instanceof OverconstrainedError && trackConstraints?.deviceId) {
|
|
8377
|
-
const { deviceId, ...relaxedContraints } = trackConstraints;
|
|
8378
|
-
getLogger(['devices'])('warn', 'Failed to get video stream, will try again with relaxed contraints', { error, constraints, relaxedContraints });
|
|
8379
|
-
return getVideoStream(relaxedContraints);
|
|
8380
|
-
}
|
|
8381
8388
|
getLogger(['devices'])('error', 'Failed to get video stream', {
|
|
8382
8389
|
error,
|
|
8383
8390
|
constraints,
|
|
@@ -8385,6 +8392,16 @@ const getVideoStream = async (trackConstraints) => {
|
|
|
8385
8392
|
throw error;
|
|
8386
8393
|
}
|
|
8387
8394
|
};
|
|
8395
|
+
function normalizeContraints(constraints) {
|
|
8396
|
+
if (constraints?.deviceId === 'default' ||
|
|
8397
|
+
(typeof constraints?.deviceId === 'object' &&
|
|
8398
|
+
'exact' in constraints.deviceId &&
|
|
8399
|
+
constraints.deviceId.exact === 'default')) {
|
|
8400
|
+
const { deviceId, ...contraintsWithoutDeviceId } = constraints;
|
|
8401
|
+
return contraintsWithoutDeviceId;
|
|
8402
|
+
}
|
|
8403
|
+
return constraints;
|
|
8404
|
+
}
|
|
8388
8405
|
/**
|
|
8389
8406
|
* Prompts the user for a permission to share a screen.
|
|
8390
8407
|
* If the user grants the permission, a screen sharing stream is returned. Throws otherwise.
|
|
@@ -8611,6 +8628,7 @@ class InputMediaDeviceManager {
|
|
|
8611
8628
|
}
|
|
8612
8629
|
catch (error) {
|
|
8613
8630
|
this.state.setDevice(prevDeviceId);
|
|
8631
|
+
await this.applySettingsToStream();
|
|
8614
8632
|
throw error;
|
|
8615
8633
|
}
|
|
8616
8634
|
}
|
|
@@ -12596,7 +12614,7 @@ class StreamClient {
|
|
|
12596
12614
|
return await this.wsConnection.connect(this.defaultWSTimeout);
|
|
12597
12615
|
};
|
|
12598
12616
|
this.getUserAgent = () => {
|
|
12599
|
-
const version = "1.11.
|
|
12617
|
+
const version = "1.11.9";
|
|
12600
12618
|
return (this.userAgent ||
|
|
12601
12619
|
`stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${version}`);
|
|
12602
12620
|
};
|