-
Notifications
You must be signed in to change notification settings - Fork 412
MSC3888: Voice Broadcast #3888
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
weeman1337
wants to merge
8
commits into
main
Choose a base branch
from
weeman1337/voice-broadcast
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
MSC3888: Voice Broadcast #3888
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
278fd42
Add MSC3888: Voice Broadcast
weeman1337 49c5aa9
Update proposals/3888-voice-broadcast.md
weeman1337 d29ef9a
Mark MSC as on hold
weeman1337 65dc824
Update ToDo state
weeman1337 b94ae5f
Copy spec from discussion
weeman1337 2e69c06
Fix broken link
weeman1337 42e7158
Update 3888-voice-broadcast.md
ara4n 4930208
Update 3888-voice-broadcast.md
ara4n File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,201 @@ | ||
| # MSC3888: Voice Broadcast | ||
|
|
||
| **Is your feature request related to a problem? Please describe.** | ||
|
|
||
| As a user I want to be able to send a voice broadcast to all users of a room, so that I can easily provide information by just talking. Compared to already existing voice messages it should be possible to listen to voice broadcast at the time they are being recorded. Think of this being a live-podcast over Matrix. | ||
|
|
||
| Some use-case scenarios for this feature can be to verbally provide updates, trainings, or talk to a large number of people. | ||
|
|
||
| **Describe the solution you'd like** | ||
|
|
||
| This issue proposes using a series of voice messages to implement the Voice Broadcast feature. | ||
|
|
||
| A new state event `m.voice_broadcast_info` will be introduced. This state event identifies a broadcast and provides its state, such as `started` or `paused`. In addition to that this proposal introduces new event type `m.voice_broadcast_chunk` with a relation to the state event to mark them as belonging to a specific voice broadcast. | ||
|
|
||
| The following diagram shows a typical event flow for a voice broadcast: | ||
|
|
||
| ```mermaid | ||
| stateDiagram-v2 | ||
| started: m.voice_broadcast_info started | ||
| paused: m.voice_broadcast_info paused | ||
| resumed: m.voice_broadcast_info resumed | ||
| stopped: m.voice_broadcast_info stopped | ||
| chunks1: m.broadcast_chunk … | ||
| chunks2: m.broadcast_chunk … | ||
| [*] --> started | ||
| started --> chunks1 | ||
| chunks1 --> paused | ||
| paused --> resumed | ||
| resumed --> chunks2 | ||
| chunks2 --> stopped | ||
| stopped --> [*] | ||
| ``` | ||
|
|
||
| `m.voice_broadcast_info` event example: | ||
|
|
||
| ```json | ||
| { | ||
| "type": "m.voice_broadcast_info", | ||
| "state_key": "@martin:example.com", | ||
| "content": { | ||
| "device_id": "ABCDEFG", | ||
| "state": "started" | ||
| }, | ||
| "…": "other state event fields" | ||
| } | ||
| ``` | ||
|
|
||
| `m.voice_broadcast_info` properties: | ||
|
|
||
| | Name | Required | Description | | ||
| | --- | --- | --- | | ||
| | `type` | yes | Must be `m.voice_broadcast_info` | | ||
| | `state_key` | yes | Must contain the broadcaster's MXID | | ||
| | `state` | yes | Must contain the broadcast state: <ul><li>`started` a new voice broadcast has been started and is currently being live</li><li>`paused` stands for a paused broadcast that may be resumed</li><li>`resumed` flags a voice broadcast previously paused as resumed</li><li>`stopped` marks a broadcast as finished</li></ul> | | ||
| | `device_id` | Only if `state` is `started` | Must contain the ID of device from which the broadcast has been started | | ||
| | `m.relates_to` | Only if `state` is not `started` | [MSC3267][MSC3267] `m.reference` relation to the `started` `m.voice_broadcast_info` state event | | ||
| | `last_chunk_sequence` | Only if `state` is `paused` or `stopped` | Must be the sequence of the last sent chunk | | ||
|
|
||
| Every following `m.voice_broadcast_info` should have an [MSC3267][MSC3267] `m.reference` relation to the `started` state event: | ||
|
|
||
| ```json | ||
| { | ||
| "type": "m.voice_broadcast_info", | ||
| "state_key": "@martin:example.com", | ||
| "content": { | ||
| "device_id": "ABCDEFG", | ||
| "state": "paused", | ||
| "last_chunk_sequence": 5, | ||
| "m.relates_to": { | ||
| "rel_type": "m.reference", | ||
| "event_id": "$voice_broadcast_info_started_event_id" | ||
| } | ||
| }, | ||
| "…": "other state event fields" | ||
| } | ||
| ``` | ||
|
|
||
| This diagram shows the possible `state` transitions: | ||
|
|
||
| ```mermaid | ||
| stateDiagram-v2 | ||
| [*] --> started | ||
| started --> paused | ||
| paused --> resumed | ||
| resumed --> paused | ||
| resumed --> stopped | ||
| paused --> stopped | ||
| started --> stopped | ||
| stopped --> [*] | ||
| ``` | ||
|
|
||
| :information_source: This proposal does not suggest to implement any server-side support to enforce the correct event order. Clients should be robust enough to handle any `state` transition and receive broadcast chunks in any state. | ||
|
|
||
| The message type of a voice broadcast chunk is `m.voice_broadcast_chunk`. The message content uses the `info`, `file` and `url` properties from [`m.audio` `m.room.message` events][m_audio]. | ||
|
|
||
| `m.voice_broadcast_chunk` messages that belong to the broadcast will have an [MSC3267][MSC3267] `m.reference` | ||
| relation to the `started` `m.voice_broadcast_info` state event. | ||
|
|
||
| To inform clients without voice broadcast support that a broadcast will take place, the first chunk message should contain an [MSC1767][MSC1767] extensible event `m.text` block. | ||
|
|
||
| Example of a first broadcast chunk: | ||
|
|
||
| ```json | ||
| { | ||
| "type": "m.voice_broadcast_chunk", | ||
| "content": { | ||
| "m.text": [ | ||
| { | ||
| "body": "Alice has started a voice broadcast. Unfortunately, your client does not seem to support playback of it." | ||
| } | ||
| ], | ||
| "m.relates_to": { | ||
| "rel_type": "m.reference", | ||
| "event_id": "$voice_broadcast_info_started_event_id", | ||
| }, | ||
| "info": { | ||
| "duration": 2140786, | ||
| "mimetype": "audio/mpeg", | ||
| "size": 1563685 | ||
| }, | ||
| "url": "mxc://example.org/ffed755USFFxlgbQYZGtryd", | ||
| "sequence": 1 | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| Example of a subsequent broadcast chunk: | ||
|
|
||
| ```json | ||
| { | ||
| "type": "m.voice_broadcast_chunk", | ||
| "content": { | ||
| "m.relates_to": { | ||
| "rel_type": "m.reference", | ||
| "event_id": "$voice_broadcast_info_started_event_id", | ||
| }, | ||
| "info": { | ||
| "duration": 2140786, | ||
| "mimetype": "audio/mpeg", | ||
| "size": 1563685 | ||
| }, | ||
| "url": "mxc://example.org/ffed755USFFxlgbQYZGtryd", | ||
| "sequence": 23 | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| `m.voice_broadcast_chunk` properties: | ||
|
|
||
| | Name | Required | Description | | ||
| | --- | --- | --- | | ||
| | `m.relates_to` | yes | [MSC3267][MSC3267] `m.reference` relation to the `started` `m.voice_broadcast_info` state event | | ||
| | `info` | yes | [See `m.audio` ][m_audio] | | ||
| | `url`/`file` | yes | [See `m.audio` ][m_audio] | | ||
| | `sequence` | yes | The sequence number to determine the correct order of the chunks starting at `1` | | ||
|
|
||
| --- | ||
|
|
||
| **Describe alternatives you've considered** | ||
|
|
||
| _Implementation based on [MSC3401: Native Group VoIP Signalling][MSC3401]_ | ||
|
|
||
| - VoIP can’t do mix down while preserving E2EE without a high effort | ||
| - It would rely on a media-server SFU which doesn’t exist at the time writing this MSC | ||
|
|
||
| _Implementation based on [MSC4016: Streaming E2EE file transfers with random access][MSC4016]_ | ||
|
|
||
| Streaming file transfer could be relatively easy on the server-side, given Glow exists and works (other than the operational unpleasantness of introducing an entirely new server), but client-side it requires major changes on all three platforms: | ||
|
|
||
| - Switch the whole file-upload/download pipeline to be streamed rather than in-memory blobs (desirable anyway for memory usage of clients, and ability to send > ~1.5GB files) | ||
| - Switch crypto to AES-GCM to solve hashing causality | ||
| - Switch to use async file uploads [MSC2246](https://github.com/matrix-org/matrix-spec-proposals/pull/2246) so you can send the event to reference the URL before finishing uploading the media | ||
| - Switch the whole voice message UI to calculate waveforms locally as the file is received (rescaling the waveform as more message is received!?), and to allow scrubbing within a file whose length is changing from under you | ||
| - Optional: random access to the download, letting the receiver jump to the end of the voice message without having to download the rest of the file first. (a 2 hour voice message is roughly 20MB, so it might not be a disaster to have to download the whole VM first rather than doing random access). This would mean: | ||
| - Change crypto to send in self-contained AES-GCM blocks (of 16KB or so), to support random access | ||
| - Support scrubbing into chunks of the file which haven’t been downloaded yet | ||
|
|
||
| **Unstable prefixes** | ||
|
|
||
| While this MSC is unstable, these event types should be used: | ||
|
|
||
| | Stable value | Unstable value | | ||
| | --- | --- | | ||
| | `m.voice_broadcast_info` | `org.matrix.msc3888.voice_broadcast_info` | | ||
| | `m.voice_broadcast_chunk` | `org.matrix.msc3888.voice_broadcast_chunk` | | ||
|
|
||
| **Additional context** | ||
|
|
||
| Clients could use [MSC3912: Relation-based redactions][MSC3912] to redact a voice broadcast and all related events. | ||
|
|
||
| :information_source: This discussion describes an intermediate solution to implement voice broadcasts. The final solution will be described in [MSC3888][MSC3888]. | ||
|
|
||
| [m_audio]: https://spec.matrix.org/v1.6/client-server-api/#maudio | ||
| [MSC1767]: https://github.com/matrix-org/matrix-spec-proposals/pull/1767 | ||
| [MSC3245]: https://github.com/matrix-org/matrix-spec-proposals/blob/travis/msc/voice-messages/proposals/3245-voice-messages.md | ||
| [MSC3267]: https://github.com/matrix-org/matrix-spec-proposals/blob/aggregations-references/proposals/3267-reference-relations.md | ||
| [MSC3401]: https://github.com/matrix-org/matrix-spec-proposals/pull/3401 | ||
| [MSC3489]: https://github.com/matrix-org/matrix-spec-proposals/blob/matthew/location-streaming/proposals/3489-location-streaming.md | ||
| [MSC3888]: https://github.com/matrix-org/matrix-spec-proposals/pull/3888 | ||
| [MSC3912]: https://github.com/matrix-org/matrix-spec-proposals/pull/3912 | ||
| [MSC4016]: https://github.com/matrix-org/matrix-spec-proposals/pull/4016 | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.