Skip to content

Add jamulusserver/getSilenceStatus RPC endpoint#3724

Closed
mcfnord wants to merge 1 commit into
jamulussoftware:mainfrom
mcfnord:feature/silence-status-rpc
Closed

Add jamulusserver/getSilenceStatus RPC endpoint#3724
mcfnord wants to merge 1 commit into
jamulussoftware:mainfrom
mcfnord:feature/silence-status-rpc

Conversation

@mcfnord
Copy link
Copy Markdown
Contributor

@mcfnord mcfnord commented Jun 4, 2026

Summary

  • Tracks whether the server audio mix has been silent for ≥2 seconds by scanning decoded PCM frames in OnTimer().
  • Adds GetIsSilent() to CServer and two private members (m_bIsSilent, m_iLastAudioActivityMs).
  • Adds jamulusserver/getSilenceStatus RPC method returning {"silent": bool}.

When no clients are connected the flag resets to false.

Test plan

  • Connect clients playing audio → getSilenceStatus returns {"silent": false}
  • All clients mute / go quiet for >2 s → returns {"silent": true}
  • All clients disconnect → returns {"silent": false}
  • Server with no RPC port configured is unaffected (no new required flags)

🤖 Generated with Claude Code

Tracks whether the server audio mix has been below threshold for ≥2 seconds.
In OnTimer(), scan the decoded PCM frames; if any sample exceeds ±100 (out of
32767), update m_iLastAudioActivityMs.  m_bIsSilent is true when no such
activity has occurred for more than 2 s.  When no clients are connected the
flag is reset to false.

The new RPC method jamulusserver/getSilenceStatus returns {"silent": bool}.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@mcfnord
Copy link
Copy Markdown
Contributor Author

mcfnord commented Jun 4, 2026

Would you consider a "public API" where some read-only endpoints can be called without any authentication? I'd like to reveal when a server is quiet, because it's an indication of activity level (obviously).

Comment thread src/serverrpc.cpp
/// @rpc_method jamulusserver/getSilenceStatus
/// @brief Returns whether the server mix is currently silent.
/// @param {object} params - No parameters (empty object).
/// @result {boolean} result.silent - True if all connected clients have been below the audio threshold for ≥2 seconds. False if no clients are connected or audio is active.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

If no clients are connected, I guess that sounds like true (silent) to me!

@softins
Copy link
Copy Markdown
Member

softins commented Jun 4, 2026

Would you consider a "public API" where some read-only endpoints can be called without any authentication? I'd like to reveal when a server is quiet, because it's an indication of activity level (obviously).

Even if we did, you would probably have an uphill battle getting server operators to enable and expose it.

@mcfnord
Copy link
Copy Markdown
Contributor Author

mcfnord commented Jun 4, 2026

Even if we did, you would probably have an uphill battle getting server operators to enable and expose it.

Perhaps, but I'm not so sure.

The technical hurdle would be opening the port. This is trickier than it may seem at first glance, because ideally, the port should be well-known. If I have to somehow broadcast which port is the public API, that's not ideal. So I thought maybe the TCP port could always be 22224. Then some operators (not all) would need to open the port based on their default firewall behavior, but at least we'd know where to look. (I personally suspect silence status ought to be visible by default, but I'm sure someone will find that view deplorable.)

There's also a social hurdle: Would anyone want to open the server up to reveal this information? Well, why not? Quiet is quiet. Sound is sound. In my view, it's quite a steep notion of privacy that the operator of a server listed on a public directory would treasure and protect their current silence status. It seems bit extreme, even if it's a view some hold.

I think there's a continuum between those who prioritize every vestige of privacy, and those who celebrate the beneficial facets of being in public. My fork's jamfan branch adds features that enhance the public experience. Perhaps these don't interest those who prioritize privacy. You might prefer to withhold silence information, but a lot of Thailand and my dozen servers reveal it today, and I haven't heard a complaint (yet).

So I am not focused on persuading people who prioritize a stronger privacy preference to become people who prioritize a richer public experience, because I don't think there's any persuasion necessary. I'm just going to serve the people who prioritize a (thoughtful) public experience, which I think is the norm.

@ann0see
Copy link
Copy Markdown
Member

ann0see commented Jun 4, 2026

I doubt we'd want to expose JSON-RPC as API. I certainly wouldn't as there's no encryption/authentication.

@mcfnord
Copy link
Copy Markdown
Contributor Author

mcfnord commented Jun 4, 2026

I doubt we'd want to expose JSON-RPC as API. I certainly wouldn't as there's no encryption/authentication.

Why not? Tell me about a worst-case scenario. Perhaps a UDP response could include silence status. Unfortunately that protocol of ours appears to be binary. So I'm considering a new UDP message.

@pljones
Copy link
Copy Markdown
Collaborator

pljones commented Jun 4, 2026

Any server operator wanting to expose JSONRPC - even specific requests - can already do so with virtually no coding. Just ask Google or Claude or ... etc. If they're not doing it, they'd probably rather it was kept that way.

JSONRPC exists to show and change the state of the Jamulus client or server. Not to perform monitoring that isn't already there.

For this, just attach a client and monitor the audio. Run without the UI, connect the audio outs to your monitoring tool.

@ann0see
Copy link
Copy Markdown
Member

ann0see commented Jun 4, 2026

Why not? Tell me about a worst-case scenario.

JSON-RPC is not designed for this usecase. It would open another potential security hole.

Comment thread src/server.cpp

{
bool bAnyActivity = false;
for ( int j = 0; j < iNumClients && !bAnyActivity; j++ )
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't think this is appropriate. Worst case is N clients and only channel n=N-1 is sending audio.
The code would iterate over (N - 1) * vecvecsData[n].Size() + 1 single samples before leaving the loop on every server tick.
Even if this would be accepted this wouldn't be the way to implement it. A server should rather be queried for activity and only then a calculation should be taking place for a given amount of time and not on every tick and not for every single sample.

Copy link
Copy Markdown
Contributor Author

@mcfnord mcfnord Jun 4, 2026

Choose a reason for hiding this comment

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

Good feedback.

My new design will use a custom UDP message and get back the # of seconds since last audio, and a bit mask of all audible channels at the most recent sample.

Using UDP solves the firewall problem, and using a custom message rather than an existing message solves the binary protocol problem.

Not sure, but I think sampling only on second-tick changes should be adequate.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think I can use the existing levels! So i'll close this now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature request Feature request JSON-RPC Related to the JSON-RPC API

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants