Skip to content

chore: add audio level and access to call stats on media-signaling lib#37160

Merged
kodiakhq[bot] merged 5 commits into
developfrom
chore/media-call-audio-level
Oct 8, 2025
Merged

chore: add audio level and access to call stats on media-signaling lib#37160
kodiakhq[bot] merged 5 commits into
developfrom
chore/media-call-audio-level

Conversation

@pierre-lehnen-rc

@pierre-lehnen-rc pierre-lehnen-rc commented Oct 7, 2025

Copy link
Copy Markdown
Contributor

Proposed changes (including videos or screenshots)

Issue(s)

VGA-30

Steps to test or reproduce

Further comments

Summary by CodeRabbit

  • New Features
    • Exposes real-time audio level readings for both local and remote audio during calls, enabling UI meters or indicators.
    • Provides a call statistics API to retrieve WebRTC metrics on demand, with an optional track selector for focused insights.
    • Audio levels and stats are available from active calls and return safe defaults when unavailable.

@dionisio-bot

dionisio-bot Bot commented Oct 7, 2025

Copy link
Copy Markdown
Contributor

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is targeting the wrong base branch. It should target 7.12.0, but it targets 7.11.0

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@changeset-bot

changeset-bot Bot commented Oct 7, 2025

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 4fbc2b1

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pierre-lehnen-rc pierre-lehnen-rc marked this pull request as ready for review October 7, 2025 19:43
@coderabbitai

coderabbitai Bot commented Oct 7, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Adds audio level tracking and stats retrieval to media calls. Extends interfaces with audioLevel, localAudioLevel, and getStats(selector?). ClientMediaCall exposes getters and getStats delegating to the WebRTC processor. Processor implements periodic getStats polling to update audio levels and manages lifecycle registration/unregistration.

Changes

Cohort / File(s) Summary
Public API: Call and WebRTC interfaces
packages/media-signaling/src/definition/call/IClientMediaCall.ts, packages/media-signaling/src/definition/services/webrtc/IWebRTCProcessor.ts
Added properties audioLevel: number, localAudioLevel: number, and method getStats(selector?: MediaStreamTrack | null): Promise<RTCStatsReport | null> to both interfaces.
Client surface: ClientMediaCall
packages/media-signaling/src/lib/Call.ts
Added getters audioLevel, localAudioLevel (default 0 when absent) and method getStats(selector?) delegating to the processor or returning null.
WebRTC processor implementation
packages/media-signaling/src/lib/services/webrtc/Processor.ts
Implemented audio level tracking via periodic getStats polling; added getters for levels, lifecycle methods to register/unregister tracker, and getStats(selector?) that queries the RTCPeerConnection and guards for stopped state.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor App
  participant ClientMediaCall
  participant WebRTCProcessor
  participant RTCPeerConnection as RTCPeerConnection

  Note over WebRTCProcessor: Initialization
  WebRTCProcessor->>WebRTCProcessor: registerAudioLevelTracker()
  loop interval tick
    WebRTCProcessor->>RTCPeerConnection: getStats(selector?)
    RTCPeerConnection-->>WebRTCProcessor: RTCStatsReport \| null
    WebRTCProcessor->>WebRTCProcessor: parse audio reports<br/>update audioLevel/localAudioLevel (or 0 on error)
  end

  App->>ClientMediaCall: getStats(selector?)
  ClientMediaCall->>WebRTCProcessor: getStats(selector?)
  WebRTCProcessor-->>ClientMediaCall: RTCStatsReport \| null
  ClientMediaCall-->>App: RTCStatsReport \| null

  App->>ClientMediaCall: read audioLevel/localAudioLevel
  ClientMediaCall->>WebRTCProcessor: audioLevel/localAudioLevel
  WebRTCProcessor-->>ClientMediaCall: numbers

  Note over WebRTCProcessor: Stop
  App->>WebRTCProcessor: stop()
  WebRTCProcessor->>WebRTCProcessor: unregisterAudioLevelTracker()<br/>reset levels
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • tassoevan
  • ggazzo

Poem

Thump-thump—my ears catch levels’ glow,
Stats hop in, like carrots in a row. 🥕
Tracks hum soft, remote and near,
I nibble numbers, crisp and clear.
When the call says “stop,” I rest—
Burrowed logs, a tidy nest. 🐇📊

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly describes the primary changes to the media-signaling library by highlighting the addition of audio level monitoring and call stats access, and it clearly indicates the scope without unnecessary detail.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/media-call-audio-level

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
packages/media-signaling/src/lib/services/webrtc/Processor.ts (3)

237-244: Consider using selector to reduce getStats load

When available, pass the specific audio track to limit report size; this reduces overhead versus full-graph stats.


334-366: Fix stats parsing and reduce polling overhead; current filter likely misses inbound audio

  • Correctness: Many browsers expose audio level on 'media-source' and/or 'track'; inbound-rtp may not have kind, and may use mediaType. The current report.kind !== 'audio' filter will skip valid inbound reports, keeping audioLevel at 0.
  • Performance: Polling the full stats graph every 50ms per call is heavy.

Suggested improvements:

  • Parse per type and check mediaType for inbound-rtp; include 'track' fallback with 'audioLevel'.
  • Add minimal casting to satisfy TS DOM typings.
  • Gate updates by connected state.
  • Reduce interval (e.g., 200ms). Optionally pass a selector track to getStats to narrow results.
-		this._audioLevelTracker = setInterval(() => {
-			this.getStats()
+		this._audioLevelTracker = setInterval(() => {
+			// Avoid noisy polling when not connected
+			if (this.peer.connectionState !== 'connected') {
+				this._audioLevel = 0;
+				this._localAudioLevel = 0;
+				return;
+			}
+
+			this.getStats()
 				.then((stats) => {
 					if (!stats) {
 						return;
 					}
 
-					stats.forEach((report) => {
-						if (report.kind !== 'audio') {
-							return;
-						}
-
-						switch (report.type) {
-							case 'inbound-rtp':
-								this._audioLevel = report.audioLevel ?? 0;
-								break;
-							case 'media-source':
-								this._localAudioLevel = report.audioLevel ?? 0;
-								break;
-						}
-					});
+					(stats as any).forEach((report: any) => {
+						switch (report.type) {
+							case 'inbound-rtp': {
+								// Chrome/Safari: mediaType; some don't expose `kind` here
+								if (report.kind === 'audio' || report.mediaType === 'audio') {
+									this._audioLevel = report.audioLevel ?? 0;
+								}
+								break;
+							}
+							case 'media-source': {
+								// Local mic level
+								if (report.kind === 'audio') {
+									this._localAudioLevel = report.audioLevel ?? 0;
+								}
+								break;
+							}
+							case 'track': {
+								// Fallback: some browsers report audioLevel on track stats
+								if (report.kind === 'audio' && 'audioLevel' in report) {
+									if (report.remoteSource) {
+										this._audioLevel = report.audioLevel ?? this._audioLevel;
+									} else {
+										this._localAudioLevel = report.audioLevel ?? this._localAudioLevel;
+									}
+								}
+								break;
+							}
+						}
+					});
 				})
 				.catch(() => {
 					this._audioLevel = 0;
 					this._localAudioLevel = 0;
 				});
-		}, 50);
+		}, 200);

Optionally, you can call getStats(this.remoteMediaStream.getAudioTracks()[0] ?? undefined as any) and a second pass for the local track to further shrink the report size.


368-377: Good cleanup on stop; consider also resetting when connection fails

Unregistering the tracker and zeroing levels on stop is good. Also consider zeroing when the connection transitions to failed/closed.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between fd4f9b2 and 42619ad.

📒 Files selected for processing (4)
  • packages/media-signaling/src/definition/call/IClientMediaCall.ts (2 hunks)
  • packages/media-signaling/src/definition/services/webrtc/IWebRTCProcessor.ts (1 hunks)
  • packages/media-signaling/src/lib/Call.ts (2 hunks)
  • packages/media-signaling/src/lib/services/webrtc/Processor.ts (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/media-signaling/src/lib/services/webrtc/Processor.ts (1)
packages/media-signaling/src/definition/services/webrtc/IWebRTCProcessor.ts (1)
  • WebRTCProcessorConfig (40-46)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build
🔇 Additional comments (4)
packages/media-signaling/src/definition/call/IClientMediaCall.ts (1)

96-96: LGTM on getStats surface

Signature matches processor; nullable return is a pragmatic choice.

packages/media-signaling/src/lib/Call.ts (2)

160-166: LGTM: safe getters

Cleanly expose processor levels with 0 fallback when unavailable.


652-654: LGTM: getStats delegation

Null on missing/stopped processor is reasonable.

packages/media-signaling/src/lib/services/webrtc/Processor.ts (1)

52-65: LGTM: audio level fields and accessors

Initialization and public getters look good.

Also applies to: 71-74

Comment thread packages/media-signaling/src/definition/call/IClientMediaCall.ts
@codecov

codecov Bot commented Oct 7, 2025

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 67.39%. Comparing base (1b85a9e) to head (4fbc2b1).
⚠️ Report is 1 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #37160      +/-   ##
===========================================
+ Coverage    67.35%   67.39%   +0.03%     
===========================================
  Files         3286     3286              
  Lines       111584   111584              
  Branches     20366    20377      +11     
===========================================
+ Hits         75158    75200      +42     
+ Misses       33740    33702      -38     
+ Partials      2686     2682       -4     
Flag Coverage Δ
e2e 57.29% <ø> (+0.01%) ⬆️
unit 71.42% <ø> (+0.05%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@pierre-lehnen-rc pierre-lehnen-rc added the stat: QA assured Means it has been tested and approved by a company insider label Oct 8, 2025
@pierre-lehnen-rc pierre-lehnen-rc added this to the 7.12.0 milestone Oct 8, 2025
@dionisio-bot dionisio-bot Bot added the stat: ready to merge PR tested and approved waiting for merge label Oct 8, 2025
@kodiakhq kodiakhq Bot merged commit e64c9a8 into develop Oct 8, 2025
49 checks passed
@kodiakhq kodiakhq Bot deleted the chore/media-call-audio-level branch October 8, 2025 20:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stat: QA assured Means it has been tested and approved by a company insider stat: ready to merge PR tested and approved waiting for merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants