Skip to content

Commit 103d776

Browse files
author
Tyler
committed
Merge remote-tracking branch 'upstream/main'
2 parents bf369d8 + 8dfaf67 commit 103d776

24 files changed

Lines changed: 451 additions & 154 deletions

.changes/audio-renderer-api

Lines changed: 0 additions & 1 deletion
This file was deleted.

.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.6.5
1+
2.7.0

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# CHANGELOG
22

3+
## 2.7.0
4+
5+
* Added: Add setVideoDimensions for remote track publications
6+
* Added: Add audio renderer API for receiving raw audio frames
7+
* Changed: Bump flutter-webrtc to 1.4.0 and upgrade to libwebrtc m144
8+
* Fixed: Add signal RTT tracking via pingReq/pongResp
9+
* Fixed: Add jitter to reconnect retry delays
10+
* Fixed: Fix missing params in CameraCaptureOptions.copyWith
11+
* Fixed: Fix missing RoomReconnectedEvent and incorrect SyncState timing during signal-only reconnection
12+
* Fixed: Fix VP9/SVC dynacast layer handling
13+
* Fixed: Stop processor on track end
14+
* Fixed: Include last server offer in SyncState during reconnection
15+
316
## 2.6.5
417

518
* Added: Send reconnect reason to server during WebSocket reconnection

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Include this package to your `pubspec.yaml`
4646
```yaml
4747
---
4848
dependencies:
49-
livekit_client: ^2.6.5
49+
livekit_client: ^2.7.0
5050
```
5151
5252
### iOS

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ android {
5252
dependencies {
5353
testImplementation("org.jetbrains.kotlin:kotlin-test")
5454
testImplementation("org.mockito:mockito-core:5.0.0")
55-
implementation 'io.github.webrtc-sdk:android:137.7151.04'
55+
implementation 'io.github.webrtc-sdk:android:144.7559.01'
5656
implementation 'io.livekit:noise:2.0.0'
5757
}
5858

example/ios/Flutter/AppFrameworkInfo.plist

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,5 @@
2020
<string>????</string>
2121
<key>CFBundleVersion</key>
2222
<string>1.0</string>
23-
<key>MinimumOSVersion</key>
24-
<string>13.0</string>
2523
</dict>
2624
</plist>

ios/livekit_client.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'livekit_client'
3-
s.version = '2.6.5'
3+
s.version = '2.7.0'
44
s.summary = 'Open source platform for real-time audio and video.'
55
s.description = 'Open source platform for real-time audio and video.'
66
s.homepage = 'https://livekit.io/'
@@ -16,6 +16,6 @@ Pod::Spec.new do |s|
1616
s.static_framework = true
1717

1818
s.dependency 'Flutter'
19-
s.dependency 'WebRTC-SDK', '137.7151.04'
19+
s.dependency 'WebRTC-SDK', '144.7559.01'
2020
s.dependency 'flutter_webrtc'
2121
end

lib/src/core/engine.dart

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
// ignore_for_file: deprecated_member_use_from_same_package
1616

1717
import 'dart:async';
18+
import 'dart:math' as math;
1819
import 'dart:typed_data' show Uint8List;
1920

2021
import 'package:flutter/foundation.dart' show kDebugMode, kIsWeb;
@@ -1018,7 +1019,11 @@ class Engine extends Disposable with EventsEmittable<EngineEvent> {
10181019
return;
10191020
}
10201021

1021-
final delay = defaultRetryDelaysInMs[reconnectAttempts!];
1022+
var delay = defaultRetryDelaysInMs[reconnectAttempts!];
1023+
// Add random jitter to prevent thundering herd on reconnect
1024+
if (reconnectAttempts! > 1) {
1025+
delay += math.Random().nextInt(1000);
1026+
}
10221027

10231028
events.emit(EngineAttemptReconnectEvent(
10241029
attempt: reconnectAttempts! + 1,
@@ -1236,6 +1241,7 @@ class Engine extends Disposable with EventsEmittable<EngineEvent> {
12361241
required List<String> trackSidsDisabled,
12371242
}) async {
12381243
final previousAnswer = (await subscriber?.pc.getLocalDescription())?.toPBType();
1244+
final previousOffer = (await subscriber?.pc.getRemoteDescription())?.toPBType();
12391245

12401246
// Build data channel receive states for reliability
12411247
final dataChannelReceiveStates = <lk_rtc.DataChannelReceiveState>[];
@@ -1250,6 +1256,7 @@ class Engine extends Disposable with EventsEmittable<EngineEvent> {
12501256
}
12511257
signalClient.sendSyncState(
12521258
answer: previousAnswer,
1259+
offer: previousOffer,
12531260
subscription: subscription,
12541261
publishTracks: publishTracks,
12551262
dataChannelInfo: dataChannelInfo(),

lib/src/core/room.dart

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ import '../types/data_stream.dart';
5151
import '../types/other.dart';
5252
import '../types/rpc.dart';
5353
import '../types/transcription_segment.dart';
54-
import '../utils.dart' show unpackStreamId;
54+
import '../utils.dart' show isSVCCodec, unpackStreamId;
5555
import 'engine.dart';
5656
import 'participant_collection.dart';
5757
import 'pending_track_queue.dart';
@@ -363,7 +363,8 @@ class Room extends DisposableChangeNotifier with EventsEmittable<RoomEvent> {
363363
}
364364
} else if (event.subscribedQualities.isNotEmpty) {
365365
final videoTrack = publication.track as LocalVideoTrack;
366-
await videoTrack.updatePublishingLayers(videoTrack, event.subscribedQualities);
366+
await videoTrack.setPublishingLayers(videoTrack, event.subscribedQualities,
367+
isSVC: isSVCCodec(videoTrack.codec ?? ''));
367368
}
368369
})
369370
..on<SignalSubscriptionPermissionUpdateEvent>((event) async {
@@ -499,6 +500,7 @@ class Room extends DisposableChangeNotifier with EventsEmittable<RoomEvent> {
499500
..on<EngineResumedEvent>((event) async {
500501
// re-send tracks permissions
501502
localParticipant?.sendTrackSubscriptionPermissions();
503+
events.emit(const RoomReconnectedEvent());
502504
notifyListeners();
503505
})
504506
..on<EngineFullRestartingEvent>((event) async {
@@ -536,9 +538,12 @@ class Room extends DisposableChangeNotifier with EventsEmittable<RoomEvent> {
536538
notifyListeners();
537539
})
538540
..on<EngineResumingEvent>((event) async {
539-
await _sendSyncState();
541+
events.emit(const RoomResumingEvent());
540542
notifyListeners();
541543
})
544+
..on<SignalReconnectedEvent>((event) async {
545+
await _sendSyncState();
546+
})
542547
..on<EngineAttemptReconnectEvent>((event) async {
543548
events.emit(RoomAttemptReconnectEvent(
544549
attempt: event.attempt,

lib/src/core/signal_client.dart

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,11 @@ class SignalClient extends Disposable with EventsEmittable<SignalEvent> {
5353
Timer? _pingIntervalTimer;
5454

5555
int get pingCount => _pingCount;
56-
5756
int _pingCount = 0;
57+
58+
/// Signal round-trip time in milliseconds, calculated from pingReq/pongResp.
59+
int get rtt => _rtt;
60+
int _rtt = 0;
5861
String? participantSid;
5962

6063
int _requestId = 0;
@@ -345,6 +348,11 @@ class SignalClient extends Disposable with EventsEmittable<SignalEvent> {
345348
_pingCount++;
346349
_resetPingTimeout();
347350
break;
351+
case lk_rtc.SignalResponse_Message.pongResp:
352+
_rtt = DateTime.timestamp().millisecondsSinceEpoch - msg.pongResp.lastPingTimestamp.toInt();
353+
_pingCount++;
354+
_resetPingTimeout();
355+
break;
348356
case lk_rtc.SignalResponse_Message.reconnect:
349357
events.emit(SignalReconnectResponseEvent(response: msg.reconnect));
350358
break;
@@ -379,7 +387,14 @@ class SignalClient extends Disposable with EventsEmittable<SignalEvent> {
379387
}
380388

381389
void _sendPing() {
382-
_sendRequest(lk_rtc.SignalRequest()..ping = Int64(DateTime.timestamp().millisecondsSinceEpoch));
390+
final now = DateTime.timestamp().millisecondsSinceEpoch;
391+
// Send both ping and pingReq for compatibility with old and new servers
392+
_sendRequest(lk_rtc.SignalRequest()..ping = Int64(now));
393+
_sendRequest(lk_rtc.SignalRequest()
394+
..pingReq = lk_rtc.Ping(
395+
timestamp: Int64(now),
396+
rtt: Int64(_rtt),
397+
));
383398
}
384399

385400
void _startPingInterval() {
@@ -485,6 +500,7 @@ extension SignalClientRequests on SignalClient {
485500
@internal
486501
void sendSyncState({
487502
required lk_rtc.SessionDescription? answer,
503+
required lk_rtc.SessionDescription? offer,
488504
required lk_rtc.UpdateSubscription subscription,
489505
required Iterable<lk_rtc.TrackPublishedResponse>? publishTracks,
490506
required Iterable<lk_rtc.DataChannelInfo>? dataChannelInfo,
@@ -494,6 +510,7 @@ extension SignalClientRequests on SignalClient {
494510
_sendRequest(lk_rtc.SignalRequest(
495511
syncState: lk_rtc.SyncState(
496512
answer: answer,
513+
offer: offer,
497514
subscription: subscription,
498515
publishTracks: publishTracks,
499516
dataChannels: dataChannelInfo,

0 commit comments

Comments
 (0)