# Resenha - Add Discord-style Video and Voice Rooms and Calls to Your Community 🎙

**URL:** https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056
**Category:** Plugin
**Created:** [19 בנובמבר,‏ 2025,‏ 4:34pm UTC](https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056 "2025-11-19T16:34:26Z")
**Posts on this page:** 20
**Page:** 4

<div class="post-metadata">

### Author: ![bird](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/bird/32/552706_2.png) [@bird](https://meta.discourse.org/u/bird)
#### Post date: [7 ביולי,‏ 2026,‏ 6:11pm UTC](https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056/63 "2026-07-07T18:11:50Z")

</div>

It seems that on the mobile app, you can only create rooms but cannot directly enter already created rooms by clicking on them. However, if you directly access `/resenha/r/topic`, it works. Is this a bug?

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [7 ביולי,‏ 2026,‏ 6:27pm UTC](https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056/64 "2026-07-07T18:27:28Z")

</div>

Works just fine for me on my phone, have you updated your Discourse instance this week?

Experimental plugins require frequent updates

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [16 ביולי,‏ 2026,‏ 9:34pm UTC](https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056/66 "2026-07-16T21:34:22Z")

</div>

Lots of updates this month, but the main one is optional and per-room support for SFU via LiveKit.

Full P2P WebRTC is still the main and default supported transport, but SFU is now also supported for people who need to support hundreds of participants in a single room.

We’ve also made lots of improvements, like Audio and Video device pickers on room and widget controls, made Resenha rooms mentionable via `#` auto complete on chat and posts, room layout options, and more.

---

<div class="post-metadata">

### Author: ![nicolsdennis](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nicolsdennis/32/545883_2.png) [@nicolsdennis](https://meta.discourse.org/u/nicolsdennis)
#### Post date: [18 ביולי,‏ 2026,‏ 10:54am UTC](https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056/68 "2026-07-18T10:54:39Z")

</div>

Thanks for this, the SFU was the real missing piece. It’s what originally pushed me into maintaining a separate fork; with it supported upstream I can retire the fork and track resenha directly.

I’d held off asking about LiveKit because I didn’t know if you wanted to go that direction. Now that you have: are you open to PRs for features and small improvements?

---

<div class="post-metadata">

### Author: ![nicolsdennis](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nicolsdennis/32/545883_2.png) [@nicolsdennis](https://meta.discourse.org/u/nicolsdennis)
#### Post date: [20 ביולי,‏ 2026,‏ 2:15pm UTC](https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056/69 "2026-07-20T14:15:36Z")

</div>

@Falco Hey I’ve hit a few reproducible issues while testing the updated resenha. Sharing findings + the patches I’m running locally, in case they’re useful upstream.

**1. Admin UI silently discards `room_type` stage rooms can never stick**  
`app/controllers/resenha/admin_rooms_controller.rb:65` (`room_params`) omits `:room_type` from the permit list, and `admin_room_serializer.rb` never serializes it.

Every stage assignment made through the admin UI is dropped, rooms create as open and “revert” to open on any later admin edit. Confirmed via production logs; the user-facing controller permits it, only the admin path lost it.

```plaintext
# admin_rooms_controller.rb — add :room_type to the permit list, then:
if permitted.key?(:room_type)
  value = Resenha::Room::ROOM_TYPES[permitted[:room_type].to_s]
  raise Discourse::InvalidParameters.new(:room_type) if value.nil?
  permitted[:room_type] = value
end
# admin_room_serializer.rb — serialize room_type so the form initializes correctly

```

**2. Invalid `room_type` silently falls back to open**  
`app/controllers/resenha/rooms_controller.rb:575` — `ROOM_TYPES[...] || ROOM_TYPE_OPEN`.

Any malformed/stale `room_type` in an otherwise-valid room edit quietly flips a stage room to open. A 400 makes the misbehaving caller visible instead of corrupting the room.

```plaintext
value = Resenha::Room::ROOM_TYPES[permitted[:room_type].to_s]
raise Discourse::InvalidParameters.new(:room_type) if value.nil?
permitted[:room_type] = value

```

**3. Heartbeat resurrects a user who just left (ghost presence)**  
`rooms_controller.rb:234` (`heartbeat`) unconditionally re-adds presence, so a heartbeat in flight when `leave` (`:220`) processes lands second and re-creates the departed user.  
The ghost persists until the TTL reap, which doesn’t broadcast — clients show them “in the room” for up to a minute.

Reproduced on device; kick has the identical exposure.

```plaintext
# ParticipantTracker: 15s tombstone
def mark_left(room_id, user_id) = redis.setex(left_key(room_id, user_id), 15, "1")
def recently_left?(room_id, user_id) = redis.exists?(left_key(room_id, user_id))
# leave/kick → mark_left; join/livekit_token → clear_left; heartbeat:
return head :no_content if Resenha::ParticipantTracker.recently_left?(@room.id, current_user.id)

```

**4. Stale `participant_left` webhook phantom-kicks a fresh session**  
`livekit_webhooks_controller.rb:37/57` — departures are matched by user identity alone.  
On a quick disconnect/rejoin, the superseded session’s `participant_left` arrives late and expires the _new_ session’s presence (user “kicked” ~3s after rejoining, back ~15s later).  
Reproduced on device; the `gone_at` heuristic can’t distinguish the sessions when the rejoin predates the old session’s disconnect.

```plaintext
# participant_joined → record the live SID
Resenha::ParticipantTracker.set_livekit_sid(room.id, user_id, event.dig("participant", "sid"))
# expire_participant → skip a superseded session's departure
known = Resenha::ParticipantTracker.livekit_sid(room.id, user_id)
return if sid.present? && known.present? && sid != known

```

**5. `DeleteRoom` 404 after the last leave floods the logs**  
`lib/resenha/livekit/room_service_client.rb:84` warns on any non-200.  
The SFU auto-closes a room the moment it empties, so the last leave’s DeleteRoom routinely races it — “requested room does not exist” is the desired end state, not a fault.  
It lands in Logster on every last-leave.

```plaintext
elsif method == "DeleteRoom" && response.status == 404
  Rails.logger.debug("[resenha-livekit] DeleteRoom no-op for room #{room.id}: already gone")
  true

```

I can send a pull request if you wish.

As I said in previous I don’t know your direction in full, but you can have a look at mines as I’ve made a post here → [https://meta.discourse.org/t/discourse-desktop-mac-app/406912/10?u=nicolsdennis](https://meta.discourse.org/t/discourse-desktop-mac-app/406912/10)

---

<div class="post-metadata">

### Author: ![nathank](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nathank/32/290039_2.png) [@nathank](https://meta.discourse.org/u/nathank)
#### Post date: [23 ביולי,‏ 2026,‏ 2:24am UTC](https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056/70 "2026-07-23T02:24:29Z")

</div>

> [@Falco](#):
>
> That may be on the cards in the future, but we don’t have anything like that planned at the moment. Maybe it could be something when an event has a Resenha room in its location URL. Five minutes before the event, we trigger an in-app notification, push notifications, and emails that, when clicked, direct the user to the `/resenha/r/#{room.slug}` so they land straight into the event room.

This would be absolutely brilliant - it would make sense to make it hook into the Livestream mechanism, which would provide the associated chat channel as part of a beautiful integrated experience

---

<div class="post-metadata">

### Author: ![Johnny\_McIvor](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/johnny_mcivor/32/218747_2.png) [@Johnny\_McIvor](https://meta.discourse.org/u/Johnny_McIvor)
#### Post date: [23 ביולי,‏ 2026,‏ 5:13pm UTC](https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056/71 "2026-07-23T17:13:42Z")

</div>

Hi, when changing the name of the room, it doesn’t update the slug. Also, it doesn’t let me delete rooms – I get server error.

It would also be nice to be able to visually change the order of the rooms and how they appear.

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [30 ביולי,‏ 2026,‏ 7:09pm UTC](https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056/72 "2026-07-30T19:09:37Z")

</div>

Thanks for the detailed report, just a merged a PR for those:

> <https://github.com/discourse/resenha/pull/72>
>
> This addresses five user-reported bugs around presence tracking, room types, and… LiveKit reconciliation. One commit per fix.
> 
> \## 1. Racing heartbeats resurrected departed users (ghost presence)
> 
> A heartbeat already in flight when a \`leave\` or \`kick\` was processed landed second and unconditionally re-added the departed user's presence. Because the TTL reap never broadcasts, the ghost stayed visible to other clients until the next republish sweep — up to a minute.
> 
> Leave and kick now write a short-lived Redis tombstone (15s — one heartbeat interval plus latency) that \`heartbeat\` checks before re-adding presence. \`join\` and the reconnect ladder's \`livekit\_token\` endpoint clear it, since both are explicit statements that the user is (re-)entering the call.
> 
> \## 2. \`room\_type\` could not be set through the admin UI, and unknown values silently became "open"
> 
> The admin controller never permitted \`room\_type\` and the admin serializer never returned it, so the admin form always displayed (and submitted) "open" — stage assignments made there were silently dropped. Both halves land together deliberately: permitting the param while the form still prefills "open" from the missing serializer field would flip existing stage rooms back to open on any admin edit.
> 
> The user-facing controller also mapped unknown \`room\_type\` values to open as a silent fallback. Both controllers now share a strict model-level lookup that rejects unknown names with a 400 — the column is an integer, so an unmapped name would otherwise cast to \`0\` (open) and corrupt the room.
> 
> \## 3. A superseded LiveKit session's late departure webhook dropped a fresh session
> 
> Departure webhooks were matched by user identity alone. On a quick disconnect/rejoin, the old session's \`participant\_left\` routinely arrives after the new session is connected, and the \`gone\_at\` heuristic can't tell them apart (the rejoin's presence timestamp predates the old session's disconnect), so the new session's presence was expired and the user vanished from the roster until their next heartbeat.
> 
> \`participant\_joined\` events now record the session SID per user, and a departure whose SID differs from the recorded one is skipped as superseded. Departures without SID context on either side still expire presence, keeping the webhook's reconcile-only backstop role intact. Webhook delivery is unordered, so this narrows the race window rather than sealing it — the next heartbeat still recovers the residual case.
> 
> \## 4. The last leave's \`DeleteRoom\` race logged as a failure
> 
> The SFU tears an emptied room down on its own, so the \`DeleteRoom\` issued by the last participant's leave routinely finds the room already gone and 404s. That's the desired end state, not a fault, yet it landed in Logster on every last-leave (and again from the emptied-room sweep). \`DeleteRoom\` now treats 404 as success at debug level; every other call and status keeps warning.

---

<div class="post-metadata">

### Author: ![nathank](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nathank/32/290039_2.png) [@nathank](https://meta.discourse.org/u/nathank)
#### Post date: [30 ביולי,‏ 2026,‏ 11:28pm UTC](https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056/73 "2026-07-30T23:28:48Z")

</div>

I’ve got a couple of minor UI/UX things related to private voice rooms:

#### 1. The private / lock micro-icon is too small.

Great that we have an icon indicating the privacy status of a room; unfortunately it  
is too small, and overlaps the icon a lot. And is inconsitent with the rest of the sidebar:

![image](https://global.discourse-cdn.com/meta/original/4X/3/0/6/30607981d1a3255d235afc677b02298264886404.png) &nbsp;&nbsp; ![image](https://global.discourse-cdn.com/meta/original/4X/0/9/1/0910651ebfeabaaeef70ce7ce85340406be7adfe.png)

#### 2. The participant list is hard to find

You can only get to the participant list in a private voiceroom from within the call itself.

This isn’t super-intuitive. I expect to be able to modify the participants / invitees from the settings available when the voiceroom is inactive as well. There _are_ plently of settings available when it is inactive (including public vs private, max participants, etc), just not the actual participant list.

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [31 ביולי,‏ 2026,‏ 5:51pm UTC](https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056/74 "2026-07-31T17:51:26Z")

</div>

I have made fixes for both of those, thanks for the report @nathank!

---

<div class="post-metadata">

### Author: ![satonotdead](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/satonotdead/32/447830_2.png) [@satonotdead](https://meta.discourse.org/u/satonotdead)
#### Post date: [31 ביולי,‏ 2026,‏ 5:51pm UTC](https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056/75 "2026-07-31T17:51:57Z")

</div>

I wonder if it is possible to link a specific room from href links? Want to add a shortcut to a single test room to simplify our UX.

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [31 ביולי,‏ 2026,‏ 5:56pm UTC](https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056/76 "2026-07-31T17:56:43Z")

</div>

Yeah, it is now possible in this format

[https://discourse-on-a-pi5.falco.dev/resenha/r/watercooler](https://discourse-on-a-pi5.falco.dev/resenha/r/watercooler)

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [31 ביולי,‏ 2026,‏ 8:44pm UTC](https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056/77 "2026-07-31T20:44:17Z")

</div>

Also worth highlighting recent improvements:

### Support for private STUN/TURN via coturn auth

This allows you to keep your coturn instance restricted to you, and it’s very easy to configure with a shared secret between Discourse and Coturn.

### Support for session recording when using LiveKit

All via the call UI, single click to start recording, single click to stop.

### Flag support for call participants

While the flag will lack context, users can provide it via the text area

### Right click menu on the video tiles

Easy to adjust volume of a peer, or kick, etc.

### Opt-in higher quality for voice, video and screen sharing

My favorite feature of the week, this allows users to opt into much higher bitrate limits, and get much better audio / video.

---

<div class="post-metadata">

### Author: ![nathank](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nathank/32/290039_2.png) [@nathank](https://meta.discourse.org/u/nathank)
#### Post date: [31 ביולי,‏ 2026,‏ 9:29pm UTC](https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056/78 "2026-07-31T21:29:25Z")

</div>

> [@Falco](#):
>
> I have made fixes for both of those, thanks for the report @nathank!

Much better!!! Thank you for listening (and acting)!!

 ![image](https://global.discourse-cdn.com/meta/original/4X/6/4/1/6410a8c3b55d824a5d1dcc621e3eb932138610a5.png)

![image](https://global.discourse-cdn.com/meta/original/4X/9/8/6/986134e45025bea49ed1c0a5701e9d10be0fc87c.png)

---

<div class="post-metadata">

### Author: ![satonotdead](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/satonotdead/32/447830_2.png) [@satonotdead](https://meta.discourse.org/u/satonotdead)
#### Post date: [3 באוגוסט,‏ 2026,‏ 4:03pm UTC](https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056/79 "2026-08-03T16:03:26Z")

</div>

Is it my instance or probably something to look into? I’m recieving error 500 when trying to remove voice rooms from admin panel:

```plaintext
ActiveRecord::InvalidForeignKey (PG::ForeignKeyViolation: ERROR: update or delete on table "resenha_rooms" violates foreign key constraint "fk_rails_ID" on table "resenha_sessions" DETAIL: Key (id)=(1) is still referenced from table "resenha_sessions".

```

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [3 באוגוסט,‏ 2026,‏ 5:47pm UTC](https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056/80 "2026-08-03T17:47:24Z")

</div>

Thanks for the report, fix is merged

> <https://github.com/discourse/resenha/pull/75>
>
> Previously, deleting a room with any session history raised \`PG::ForeignKeyViola…tion\` (500 in the admin panel), and deleting a user either failed the same way or silently destroyed every room they created through \`dependent: :destroy\`.
> 
> This change drops the sessions/memberships/co-presences/creator foreign keys (post-deploy, matching core's no-FK convention) and moves integrity to application logic: a deleted user's rooms are reassigned to the system user, their memberships and co-presences are removed, and sessions are kept as analytics history — with the admin dashboard rendering \`(deleted room)\` / \`(deleted user)\` for dangling references. Also guards the default room seeder against running before pending migrations, which previously made \`rake db:migrate\` itself crash on a database that was behind.

---

<div class="post-metadata">

### Author: ![satonotdead](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/satonotdead/32/447830_2.png) [@satonotdead](https://meta.discourse.org/u/satonotdead)
#### Post date: [3 באוגוסט,‏ 2026,‏ 9:50pm UTC](https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056/81 "2026-08-03T21:50:15Z")

</div>

Thanks for this ultra-fast fix; it worked as expected.

Just a little note, following up: changing the default room name did not update the path `/resenha/r/watercooler`, but I was now able to remove the previous default room and add a fresh one.

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [4 באוגוסט,‏ 2026,‏ 8:25pm UTC](https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056/82 "2026-08-04T20:25:44Z")

</div>

I have made the slug explicitly editable now, so it works like categories

> <https://github.com/discourse/resenha/pull/77>
>
> Previously, a room's slug was generated from its name on creation and could neve…r be changed, so renamed rooms kept their stale slug with no way to fix it.
> 
> This change adds an optional slug field to the room form (create, edit, and admin): a provided slug is normalized like category slugs, a blank one is still auto-generated from the name, and clearing it regenerates it after a rename.

---

<div class="post-metadata">

### Author: ![gabriel](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gabriel/32/367911_2.png) [@gabriel](https://meta.discourse.org/u/gabriel)
#### Post date: [6 באוגוסט,‏ 2026,‏ 11:38pm UTC](https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056/83 "2026-08-06T23:38:30Z")

</div>

You can also add some URL params to open in a specific way:

`https://discourse-on-a-pi5.falco.dev/resenha/r/watercooler?join`, just enters the room, no click to join button

`https://discourse-on-a-pi5.falco.dev/resenha/r/watercooler?join&widget` (added earlier this week), opens and turns into widget mode

`https://discourse-on-a-pi5.falco.dev/resenha/r/watercooler?join&chat` opens in chat mode

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [21 באוגוסט,‏ 2026,‏ 8:57pm UTC](https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056/84 "2026-08-21T20:57:35Z")

</div>

We have been using this plugin internally for meetings, which has been great for gathering feedback and evolving it based on real use cases. In the last two weeks, the highlights are:

### AI Noise Suppression

 ![image](https://global.discourse-cdn.com/meta/original/4X/0/6/e/06e5c8df34b757911fb45b75b68aafe77b7194d4.png)

Noise suppression was completely re-done, with several changes. We now offer controls to handle the standard WebRTC features:

- Noise Suppression
- Auto Gain Control
- Echo Cancellation

 ![image](https://global.discourse-cdn.com/meta/original/4X/7/7/b/77bf8760b6621ec41a66558937eb18d1564288e3.png)

Furthermore, the plugin now ships three different AI models for those who need better noise suppression, from low to high respectively:

- RNNoise
- DTLN
- DeepFilter3

### Direct calls

 ![image](https://global.discourse-cdn.com/meta/original/4X/6/0/7/6073648ca49272e9ed6e635b84cdafa835103dd7.png)  
 ![image](https://global.discourse-cdn.com/meta/original/4X/1/2/6/1268a8dd4220b4a07ae88eeccc86a061a8391250.png)  
 ![image](https://global.discourse-cdn.com/meta/original/4X/9/3/9/939f4d50be7ccd2d4f46eb81fd7e013e6c1f1fdc.png)

Users can now initiate 1-to-1 or 1-to-many direct calls via a button on the user card. This uses ephemeral rooms infrastructure we built, which will also be used to handle integrations in the future, like with the events plugin.

### Invites

 ![image](https://global.discourse-cdn.com/meta/original/4X/c/a/b/cabc2138ce9bf8c8218ea03528a9c07e24775cc3.png)

Right-clicking a room allows you to generate invites, and it uses your conversation history in that room to suggest users.

### Sound packs

Resenha sounds now follow your preferred sound pack from [New chat notification sound packs](https://meta.discourse.org/t/new-chat-notification-sound-packs/410644).

### Room UX

 ![image](https://global.discourse-cdn.com/meta/original/4X/a/b/e/abe028830bf30dac8581cd0176ef97821138604d.jpeg)

Right-click to copy link to room, widget tiles auto-sizing and collapse, widget positioning above the site header, shift+click room support, accuracy and better performance on the voice activity indicator.

### Android Camera Switching

 ![image](https://global.discourse-cdn.com/meta/original/4X/d/c/6/dc6210d280bdcfe7a8ec5de61d1ffb68376a2ef4.jpeg)

You can now switch between your Android phone front and back cameras seamlessly mid-call.

### Mesh connectivity warning

 ![image](https://global.discourse-cdn.com/meta/original/4X/1/9/b/19b8bacf8fb4e1d9517527e7c5b52e2033e63930.png)

The first time a user tries to connect to a room that uses WebRTC mesh, we present a warning that explains potential IP exposure.

And last but not least, two experimental features 🧑‍🔬

### Live Subtitles

 ![image](https://global.discourse-cdn.com/meta/original/4X/3/7/a/37a3c7f25d37f72147f0eff0b9a64e2bf04eb2ec.png)

We added opt-in live subtitles, powered by state-of-the-art AI models running on device.

When enabled, we download a 2.5GB AI model that is run using WebGPU, so compatibility is restricted to fast and modern devices.

There is a lot to polish and fine-tune on this feature, so let me know how it goes.

### Transcription

 ![image](https://global.discourse-cdn.com/meta/original/4X/7/c/1/7c161b10486e879daedb54c4210dd5653cb79b50.png)

Users with live subtitles enabled can now start transcriptions from those, which are backed to a new topic draft. After finishing the recording, you get a composer with all the saved transcriptions using the same format chat quotes use.

[Previous page](https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056.md?page=3)

[Next page](https://meta.discourse.org/t/resenha-add-discord-style-video-and-voice-rooms-and-calls-to-your-community/389056.md?page=5)
