diff --git a/example/lib/widgets/participant.dart b/example/lib/widgets/participant.dart index 070f6e5..e26b3f2 100644 --- a/example/lib/widgets/participant.dart +++ b/example/lib/widgets/participant.dart @@ -199,17 +199,22 @@ class _RemoteParticipantWidgetState mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.end, children: [ + // Menu for RemoteTrackPublication + if (firstAudioPublication != null && !isScreenShare) + RemoteTrackPublicationMenuWidget( + pub: firstAudioPublication!, + icon: EvaIcons.volumeUp, + ), // Menu for RemoteTrackPublication if (videoPublication != null) RemoteTrackPublicationMenuWidget( pub: videoPublication!, icon: isScreenShare ? EvaIcons.monitor : EvaIcons.video, ), - // Menu for RemoteTrackPublication - if (firstAudioPublication != null && !isScreenShare) - RemoteTrackPublicationMenuWidget( - pub: firstAudioPublication!, - icon: EvaIcons.volumeUp, + if (videoPublication != null) + RemoteTrackFPSMenuWidget( + pub: videoPublication!, + icon: EvaIcons.options2, ), ], ), @@ -253,3 +258,37 @@ class RemoteTrackPublicationMenuWidget extends StatelessWidget { ), ); } + +class RemoteTrackFPSMenuWidget extends StatelessWidget { + final IconData icon; + final RemoteTrackPublication pub; + const RemoteTrackFPSMenuWidget({ + required this.pub, + required this.icon, + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) => Material( + color: Colors.black.withOpacity(0.3), + child: PopupMenuButton( + tooltip: 'PreferredFPS', + icon: Icon(icon, color: Colors.white), + onSelected: (value) => value(), + itemBuilder: (BuildContext context) => >[ + PopupMenuItem( + child: const Text('30'), + value: () => pub.setVideoFPS(30), + ), + PopupMenuItem( + child: const Text('15'), + value: () => pub.setVideoFPS(15), + ), + PopupMenuItem( + child: const Text('8'), + value: () => pub.setVideoFPS(8), + ), + ], + ), + ); +} diff --git a/lib/src/publication/remote.dart b/lib/src/publication/remote.dart index 3c8f2de..a135b50 100644 --- a/lib/src/publication/remote.dart +++ b/lib/src/publication/remote.dart @@ -31,6 +31,10 @@ class RemoteTrackPublication bool get enabled => _enabled; bool _enabled = true; + /// The current desired FPS of the track. This is only available for video tracks that support SVC. + int? _fps; + int get fps => _fps ?? 0; + lk_models.VideoQuality _videoQuality = lk_models.VideoQuality.HIGH; lk_models.VideoQuality get videoQuality => _videoQuality; @@ -227,6 +231,14 @@ class RemoteTrackPublication sendUpdateTrackSettings(); } + /// Set desired FPS, server will do its best to return FPS close to this. + /// It's only supported for video codecs that support SVC currently. + Future setVideoFPS(int newValue) async { + if (newValue == _fps) return; + _fps = newValue; + sendUpdateTrackSettings(); + } + Future enable() async { if (_enabled) return; _enabled = true; @@ -289,6 +301,7 @@ class RemoteTrackPublication ); if (kind == lk_models.TrackType.VIDEO) { settings.quality = _videoQuality; + if (_fps != null) settings.fps = _fps!; } participant.room.engine.signalClient.sendUpdateTrackSettings(settings); }