fix: Release the microphone to the browser when a call ends (#2685)

The microphone is connected when a call needs it and released the moment
that
call ends, so the browser stops reporting it as in use at hangup rather
than
`disconnect_seconds` later.

Existing configurations are migrated automatically by the visual editor.

 - Closes: #2681 

BREAKING CHANGE: `live.microphone.disconnect_seconds` is removed. The
microphone is released when a call ends, so there is no idle countdown
to
configure. Use `live.microphone.always_connected` to hold it open
instead.

BREAKING CHANGE: The `microphone_connect` and `microphone_disconnect`
actions
are removed. The card owns the microphone lifecycle; `microphone_mute`
and
`microphone_unmute` remain.

BREAKING CHANGE: `call` is removed from `live.microphone.auto_mute`,
whose
default is now `[]`. The microphone is muted when a call ends regardless
of
this option.

BREAKING CHANGE: `microphone_unmute` has no effect outside a call.
Nothing
carries the audio at any other time, so the request is ignored rather
than
opening the microphone.
This commit is contained in:
Dermot Duffy
2026-08-14 16:17:31 -07:00
committed by GitHub
parent 65bc52d18e
commit 85d6811761
33 changed files with 1480 additions and 572 deletions
+10 -4
View File
@@ -69,16 +69,22 @@ enabled by default and appears in the `live` view whenever the selected camera
[`always_connected`](../configuration/live.md?id=microphone) microphone option
is set to `true`. On the first call there may be a brief `webrtc` connection
reset to include 2-way audio.
- The browser asks for microphone permission when a call needs it. How often it
asks depends on the browser: Chrome remembers the choice for the site, Safari
asks once per page load, and Firefox asks for every call unless _Remember this
decision_ is ticked. Set
[`always_connected`](../configuration/live.md?id=microphone) to `true` to be
asked once at card load instead.
- While a call is in progress the card locks disruptive actions (camera and
substream changes, casting, reload, etc.) so an accidental tap, swipe, or
button press doesn't cut the call off. Set
[`live.controls.call.lock`](../configuration/live.md?id=call) to `false` to
disable this.
- End the call with the overlay's end-call button. When the call ends the
microphone and inbound audio are muted again.
- The video automatically resets to remove the microphone after the number of
seconds specified by [`disconnect_seconds`](../configuration/live.md?id=microphone)
have elapsed since the call ended.
microphone and inbound audio are muted again, and the microphone is
disconnected. The exception is
[`always_connected`](../configuration/live.md?id=microphone), which holds the
microphone connected for as long as the card is running.
Calls can also be controlled programmatically with the
[`call_start`](../configuration/actions/custom/README.md?id=call_start),
+33 -33
View File
@@ -51,39 +51,39 @@ To send an action to a specific named Advanced Camera Card:
Only a subset of all [actions](../configuration/actions/README.md) are supported in URL form.
| Action | Supported in URL | Explanation |
| ------------------------------------------------------------------------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| `camera_select` | :white_check_mark: | |
| `camera_ui` | :white_check_mark: | |
| `clip` | :white_check_mark: | |
| `clips` | :white_check_mark: | |
| `default` | :white_check_mark: | |
| `diagnostics` | :white_check_mark: | |
| `download` | :heavy_multiplication_x: | Latest media information is not available on initial render. |
| `expand` | :white_check_mark: | |
| `folder` | :white_check_mark: | |
| `folders` | :white_check_mark: | |
| `fullscreen` | :heavy_multiplication_x: | Javascript does not support activating fullscreen without direct human interaction. Use `expand` as an alternative. |
| `gallery` | :white_check_mark: | |
| `image` | :white_check_mark: | |
| `live` | :white_check_mark: | |
| `media` | :white_check_mark: | |
| `media_player` | :heavy_multiplication_x: | Please [request](https://github.com/dermotduffy/advanced-camera-card/issues) if you need this. |
| `menu_toggle` | :white_check_mark: | |
| `microphone_connect`, `microphone_disconnect`, `microphone_mute`, `microphone_unmute` | :heavy_multiplication_x: | |
| `mute`, `unmute` | :heavy_multiplication_x: | |
| `play`, `pause` | :heavy_multiplication_x: | |
| `ptz` | :heavy_multiplication_x: | Please [request](https://github.com/dermotduffy/advanced-camera-card/issues) if you need this. |
| `recording` | :white_check_mark: | |
| `recordings` | :white_check_mark: | |
| `review` | :white_check_mark: | |
| `reviews` | :white_check_mark: | |
| `screenshot` | :heavy_multiplication_x: | Latest media information is not available on initial render. |
| `ptz_controls` | :heavy_multiplication_x: | Please [request](https://github.com/dermotduffy/advanced-camera-card/issues) if you need this. |
| `snapshot` | :white_check_mark: | |
| `snapshots` | :white_check_mark: | |
| `substream_off` | :white_check_mark: | The `camera` field is not exposed via URL; the selected camera is used. Use the action config directly to target another camera. |
| `substream_on` | :white_check_mark: | Pass the substream camera ID as the URL value to engage it directly; omit the value to cycle. |
| Action | Supported in URL | Explanation |
| -------------------------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| `camera_select` | :white_check_mark: | |
| `camera_ui` | :white_check_mark: | |
| `clip` | :white_check_mark: | |
| `clips` | :white_check_mark: | |
| `default` | :white_check_mark: | |
| `diagnostics` | :white_check_mark: | |
| `download` | :heavy_multiplication_x: | Latest media information is not available on initial render. |
| `expand` | :white_check_mark: | |
| `folder` | :white_check_mark: | |
| `folders` | :white_check_mark: | |
| `fullscreen` | :heavy_multiplication_x: | Javascript does not support activating fullscreen without direct human interaction. Use `expand` as an alternative. |
| `gallery` | :white_check_mark: | |
| `image` | :white_check_mark: | |
| `live` | :white_check_mark: | |
| `media` | :white_check_mark: | |
| `media_player` | :heavy_multiplication_x: | Please [request](https://github.com/dermotduffy/advanced-camera-card/issues) if you need this. |
| `menu_toggle` | :white_check_mark: | |
| `microphone_mute`, `microphone_unmute` | :heavy_multiplication_x: | |
| `mute`, `unmute` | :heavy_multiplication_x: | |
| `play`, `pause` | :heavy_multiplication_x: | |
| `ptz` | :heavy_multiplication_x: | Please [request](https://github.com/dermotduffy/advanced-camera-card/issues) if you need this. |
| `recording` | :white_check_mark: | |
| `recordings` | :white_check_mark: | |
| `review` | :white_check_mark: | |
| `reviews` | :white_check_mark: | |
| `screenshot` | :heavy_multiplication_x: | Latest media information is not available on initial render. |
| `ptz_controls` | :heavy_multiplication_x: | Please [request](https://github.com/dermotduffy/advanced-camera-card/issues) if you need this. |
| `snapshot` | :white_check_mark: | |
| `snapshots` | :white_check_mark: | |
| `substream_off` | :white_check_mark: | The `camera` field is not exposed via URL; the selected camera is used. Use the action config directly to target another camera. |
| `substream_on` | :white_check_mark: | Pass the substream camera ID as the URL value to engage it directly; omit the value to cycle. |
## Examples