Skip to content

Commit 61dfe11

Browse files
committed
Implement handling audio levels SFU event + add participant AudioLevelChanged and IsSpeakingChanged events
1 parent 6647e0c commit 61dfe11

File tree

5 files changed

+75
-4
lines changed

5 files changed

+75
-4
lines changed

Packages/StreamVideo/Runtime/Core/LowLevelClient/RtcSession.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,8 +1421,8 @@ private void OnSfuConnectionQualityChanged(ConnectionQualityChanged connectionQu
14211421

14221422
private void OnSfuAudioLevelChanged(AudioLevelChanged audioLevelChanged)
14231423
{
1424-
1425-
// StreamTODO: Implement OnSfuAudioLevelChanged
1424+
// Ignore tracing AudioLevelChanged -> not much debug value + creates too much noise in data
1425+
ActiveCall?.UpdateFromSfu(audioLevelChanged);
14261426
}
14271427

14281428
private void OnSfuPublisherAnswer(PublisherAnswer publisherAnswer)

Packages/StreamVideo/Runtime/Core/Models/CallSession.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,5 +232,19 @@ private void UpdateParticipantCountFromSessionInternal(int anonymousParticipantC
232232
((IStateLoadableFrom<SfuParticipantCount, ParticipantCount>)ParticipantCount)
233233
.LoadFromDto(dto, null);
234234
}
235+
236+
internal void UpdateFromSfu(AudioLevelChanged audioLevelChanged)
237+
{
238+
foreach (var entry in audioLevelChanged.AudioLevels)
239+
{
240+
for (int i = 0; i < _participants.Count; i++)
241+
{
242+
if (_participants[i].SessionId == entry.SessionId)
243+
{
244+
_participants[i].UpdateFromSfu(entry);
245+
}
246+
}
247+
}
248+
}
235249
}
236250
}

Packages/StreamVideo/Runtime/Core/StatefulModels/IStreamVideoCallParticipant.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@ public interface IStreamVideoCallParticipant : IStreamStatefulModel, IHasCustomD
2222
/// </summary>
2323
event ParticipantTrackChangedHandler TrackIsEnabledChanged;
2424

25+
/// <summary>
26+
/// Event notifying that the value of <see cref="AudioLevel"/> changed for this participant. The event callback contains the current value of <see cref="AudioLevel"/>
27+
/// </summary>
28+
event Action<float> AudioLevelChanged;
29+
30+
/// <summary>
31+
/// Event notifying that the value of <see cref="IsSpeaking"/> changed for this participant. The event callback contains the current value of <see cref="IsSpeaking"/>
32+
/// </summary>
33+
event Action<bool> IsSpeakingChanged;
34+
2535
/// <summary>
2636
/// Is this participant "pinned" in the call meaning it will have precedence in <see cref="IStreamCall.SortedParticipants"/> list
2737
/// </summary>

Packages/StreamVideo/Runtime/Core/StatefulModels/StreamCall.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,11 @@ internal void UpdateFromSfu(HealthCheckResponse healthCheckResponse, ICache cach
720720
{
721721
Session?.UpdateFromSfu(healthCheckResponse, cache);
722722
}
723+
724+
internal void UpdateFromSfu(AudioLevelChanged audioLevelChanged)
725+
{
726+
Session?.UpdateFromSfu(audioLevelChanged);
727+
}
723728

724729
internal void UpdateFromCoordinator(CallSessionParticipantCountsUpdatedEventInternalDTO eventData)
725730
{

Packages/StreamVideo/Runtime/Core/StatefulModels/StreamVideoCallParticipant.cs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using StreamVideo.Core.StatefulModels.Tracks;
1010
using StreamVideo.Core.Utils;
1111
using StreamVideo.Libs.Serialization;
12+
using StreamVideo.v1.Sfu.Events;
1213
using Unity.WebRTC;
1314
using UnityEngine;
1415
using Participant = StreamVideo.v1.Sfu.Models.Participant;
@@ -22,6 +23,9 @@ internal sealed class StreamVideoCallParticipant : StreamStatefulModelBase<Strea
2223
{
2324
public event ParticipantTrackChangedHandler TrackAdded;
2425
public event ParticipantTrackChangedHandler TrackIsEnabledChanged;
26+
27+
public event Action<float> AudioLevelChanged;
28+
public event Action<bool> IsSpeakingChanged;
2529

2630
public bool IsLocalParticipant => SessionId == Client.InternalLowLevelClient.RtcSession.SessionId;
2731

@@ -60,9 +64,39 @@ internal sealed class StreamVideoCallParticipant : StreamStatefulModelBase<Strea
6064

6165
public string TrackLookupPrefix { get; private set; }
6266
public ConnectionQuality ConnectionQuality { get; private set; }
63-
public bool IsSpeaking { get; private set; }
67+
68+
public bool IsSpeaking
69+
{
70+
get => _isSpeaking;
71+
private set
72+
{
73+
if (_isSpeaking == value)
74+
{
75+
return;
76+
}
77+
78+
_isSpeaking = value;
79+
IsSpeakingChanged?.Invoke(value);
80+
}
81+
}
82+
6483
public bool IsDominantSpeaker { get; private set; }
65-
public float AudioLevel { get; private set; }
84+
85+
public float AudioLevel
86+
{
87+
get => _audioLevel;
88+
private set
89+
{
90+
if (Math.Abs(_audioLevel - value) < Mathf.Epsilon)
91+
{
92+
return;
93+
}
94+
95+
_audioLevel = value;
96+
AudioLevelChanged?.Invoke(value);
97+
}
98+
}
99+
66100
public string Name { get; private set; }
67101
public string Image { get; private set; }
68102
public IEnumerable<string> Roles => _roles;
@@ -176,6 +210,12 @@ internal void UpdateFromSfu(Participant dto)
176210
{
177211
((IUpdateableFrom<Participant, StreamVideoCallParticipant>)this).UpdateFromDto(dto, Cache);
178212
}
213+
214+
internal void UpdateFromSfu(AudioLevel audioLevel)
215+
{
216+
IsSpeaking = audioLevel.IsSpeaking;
217+
AudioLevel = audioLevel.Level;
218+
}
179219

180220
internal void Update()
181221
{
@@ -280,6 +320,8 @@ protected override Task UploadCustomDataAsync()
280320

281321
private readonly List<TrackType> _publishedTracks = new List<TrackType>();
282322
private readonly List<string> _roles = new List<string>();
323+
private float _audioLevel;
324+
private bool _isSpeaking;
283325

284326
#endregion
285327

0 commit comments

Comments
 (0)