Fix/track not stop stats monitor correctly (#306)
* feat: add preferCurrentTab support for flutter web. * fix: Stop Stats monitor correctly when Track.onDispose.
This commit is contained in:
@@ -33,10 +33,10 @@ class LocalAudioTrack extends LocalTrack
|
|||||||
AudioSenderStats? prevStats;
|
AudioSenderStats? prevStats;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> monitorSender() async {
|
Future<bool> monitorStats() async {
|
||||||
if (sender == null) {
|
if (sender == null || events.isDisposed) {
|
||||||
_currentBitrate = 0;
|
_currentBitrate = 0;
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
final stats = await getSenderStats();
|
final stats = await getSenderStats();
|
||||||
|
|
||||||
@@ -47,6 +47,7 @@ class LocalAudioTrack extends LocalTrack
|
|||||||
}
|
}
|
||||||
|
|
||||||
prevStats = stats;
|
prevStats = stats;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<AudioSenderStats?> getSenderStats() async {
|
Future<AudioSenderStats?> getSenderStats() async {
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import '../../types/other.dart';
|
|||||||
import '../options.dart';
|
import '../options.dart';
|
||||||
import '../remote/audio.dart';
|
import '../remote/audio.dart';
|
||||||
import '../remote/video.dart';
|
import '../remote/video.dart';
|
||||||
import '../stats.dart';
|
|
||||||
import '../track.dart';
|
import '../track.dart';
|
||||||
import 'audio.dart';
|
import 'audio.dart';
|
||||||
import 'video.dart';
|
import 'video.dart';
|
||||||
@@ -196,7 +195,6 @@ abstract class LocalTrack extends Track {
|
|||||||
}
|
}
|
||||||
|
|
||||||
logger.fine('$objectId.publish()');
|
logger.fine('$objectId.publish()');
|
||||||
startMonitor();
|
|
||||||
_published = true;
|
_published = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -210,26 +208,7 @@ abstract class LocalTrack extends Track {
|
|||||||
}
|
}
|
||||||
|
|
||||||
logger.fine('$objectId.unpublish()');
|
logger.fine('$objectId.unpublish()');
|
||||||
stopMonitor();
|
|
||||||
_published = false;
|
_published = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer? _monitorTimer;
|
|
||||||
|
|
||||||
Future<void> monitorSender();
|
|
||||||
|
|
||||||
@internal
|
|
||||||
void startMonitor() {
|
|
||||||
_monitorTimer ??=
|
|
||||||
Timer.periodic(const Duration(milliseconds: monitorFrequency), (_) {
|
|
||||||
monitorSender();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@internal
|
|
||||||
void stopMonitor() {
|
|
||||||
_monitorTimer?.cancel();
|
|
||||||
_monitorTimer = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,17 +23,17 @@ class LocalVideoTrack extends LocalTrack with VideoTrack {
|
|||||||
final Map<String, num> _bitrateFoLayers = {};
|
final Map<String, num> _bitrateFoLayers = {};
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> monitorSender() async {
|
Future<bool> monitorStats() async {
|
||||||
if (sender == null) {
|
if (sender == null || events.isDisposed) {
|
||||||
_currentBitrate = 0;
|
_currentBitrate = 0;
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
List<VideoSenderStats> stats = [];
|
List<VideoSenderStats> stats = [];
|
||||||
try {
|
try {
|
||||||
stats = await getSenderStats();
|
stats = await getSenderStats();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.warning('Failed to get sender stats: $e');
|
logger.warning('Failed to get sender stats: $e');
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
Map<String, VideoSenderStats> statsMap = {};
|
Map<String, VideoSenderStats> statsMap = {};
|
||||||
|
|
||||||
@@ -58,6 +58,7 @@ class LocalVideoTrack extends LocalTrack with VideoTrack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
prevStats = statsMap;
|
prevStats = statsMap;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<VideoSenderStats>> getSenderStats() async {
|
Future<List<VideoSenderStats>> getSenderStats() async {
|
||||||
|
|||||||
@@ -66,10 +66,10 @@ class RemoteAudioTrack extends RemoteTrack
|
|||||||
get currentBitrate => _currentBitrate;
|
get currentBitrate => _currentBitrate;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> monitorReceiver() async {
|
Future<bool> monitorStats() async {
|
||||||
if (receiver == null) {
|
if (receiver == null && events.isDisposed) {
|
||||||
_currentBitrate = 0;
|
_currentBitrate = 0;
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
final stats = await getReceiverStats();
|
final stats = await getReceiverStats();
|
||||||
|
|
||||||
@@ -80,6 +80,7 @@ class RemoteAudioTrack extends RemoteTrack
|
|||||||
}
|
}
|
||||||
|
|
||||||
prevStats = stats;
|
prevStats = stats;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<AudioReceiverStats?> getReceiverStats() async {
|
Future<AudioReceiverStats?> getReceiverStats() async {
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
|
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
|
|
||||||
import '../../proto/livekit_models.pb.dart' as lk_models;
|
import '../../proto/livekit_models.pb.dart' as lk_models;
|
||||||
import '../../types/other.dart';
|
import '../../types/other.dart';
|
||||||
import '../stats.dart';
|
|
||||||
import '../track.dart';
|
import '../track.dart';
|
||||||
|
|
||||||
abstract class RemoteTrack extends Track {
|
abstract class RemoteTrack extends Track {
|
||||||
@@ -25,7 +23,6 @@ abstract class RemoteTrack extends Track {
|
|||||||
final didStart = await super.start();
|
final didStart = await super.start();
|
||||||
if (didStart) {
|
if (didStart) {
|
||||||
await enable();
|
await enable();
|
||||||
startMonitor();
|
|
||||||
}
|
}
|
||||||
return didStart;
|
return didStart;
|
||||||
}
|
}
|
||||||
@@ -36,25 +33,6 @@ abstract class RemoteTrack extends Track {
|
|||||||
if (didStop) {
|
if (didStop) {
|
||||||
await disable();
|
await disable();
|
||||||
}
|
}
|
||||||
stopMonitor();
|
|
||||||
return didStop;
|
return didStop;
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer? _monitorTimer;
|
|
||||||
|
|
||||||
Future<void> monitorReceiver();
|
|
||||||
|
|
||||||
@internal
|
|
||||||
void startMonitor() {
|
|
||||||
_monitorTimer ??=
|
|
||||||
Timer.periodic(const Duration(milliseconds: monitorFrequency), (_) {
|
|
||||||
monitorReceiver();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@internal
|
|
||||||
void stopMonitor() {
|
|
||||||
_monitorTimer?.cancel();
|
|
||||||
_monitorTimer = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ class RemoteVideoTrack extends RemoteTrack with VideoTrack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> monitorReceiver() async {
|
Future<bool> monitorStats() async {
|
||||||
if (receiver == null) {
|
if (receiver == null && events.isDisposed) {
|
||||||
_currentBitrate = 0;
|
_currentBitrate = 0;
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
final stats = await getReceiverStats();
|
final stats = await getReceiverStats();
|
||||||
|
|
||||||
@@ -45,6 +45,7 @@ class RemoteVideoTrack extends RemoteTrack with VideoTrack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
prevStats = stats;
|
prevStats = stats;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<VideoReceiverStats?> getReceiverStats() async {
|
Future<VideoReceiverStats?> getReceiverStats() async {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
|
import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
@@ -10,6 +12,7 @@ import '../managers/event.dart';
|
|||||||
import '../proto/livekit_models.pb.dart' as lk_models;
|
import '../proto/livekit_models.pb.dart' as lk_models;
|
||||||
import '../support/disposable.dart';
|
import '../support/disposable.dart';
|
||||||
import '../types/other.dart';
|
import '../types/other.dart';
|
||||||
|
import 'stats.dart';
|
||||||
|
|
||||||
/// Wrapper around a MediaStreamTrack with additional metadata.
|
/// Wrapper around a MediaStreamTrack with additional metadata.
|
||||||
/// Base for [AudioTrack] and [VideoTrack],
|
/// Base for [AudioTrack] and [VideoTrack],
|
||||||
@@ -55,6 +58,7 @@ abstract class Track extends DisposableChangeNotifier
|
|||||||
|
|
||||||
onDispose(() async {
|
onDispose(() async {
|
||||||
logger.fine('${objectId} onDispose()');
|
logger.fine('${objectId} onDispose()');
|
||||||
|
await stop();
|
||||||
// dispose events
|
// dispose events
|
||||||
await events.dispose();
|
await events.dispose();
|
||||||
});
|
});
|
||||||
@@ -93,6 +97,8 @@ abstract class Track extends DisposableChangeNotifier
|
|||||||
|
|
||||||
logger.fine('$objectId.start()');
|
logger.fine('$objectId.start()');
|
||||||
|
|
||||||
|
startMonitor();
|
||||||
|
|
||||||
_active = true;
|
_active = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -106,6 +112,8 @@ abstract class Track extends DisposableChangeNotifier
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stopMonitor();
|
||||||
|
|
||||||
logger.fine('$objectId.stop()');
|
logger.fine('$objectId.stop()');
|
||||||
|
|
||||||
_active = false;
|
_active = false;
|
||||||
@@ -137,6 +145,26 @@ abstract class Track extends DisposableChangeNotifier
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Timer? _monitorTimer;
|
||||||
|
|
||||||
|
Future<bool> monitorStats();
|
||||||
|
|
||||||
|
@internal
|
||||||
|
void startMonitor() {
|
||||||
|
_monitorTimer ??= Timer.periodic(
|
||||||
|
const Duration(milliseconds: monitorFrequency), (_) async {
|
||||||
|
if (!await monitorStats()) {
|
||||||
|
stopMonitor();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@internal
|
||||||
|
void stopMonitor() {
|
||||||
|
_monitorTimer?.cancel();
|
||||||
|
_monitorTimer = null;
|
||||||
|
}
|
||||||
|
|
||||||
@internal
|
@internal
|
||||||
void updateMuted(
|
void updateMuted(
|
||||||
bool muted, {
|
bool muted, {
|
||||||
|
|||||||
Reference in New Issue
Block a user