mirror of
https://github.com/jech/galene.git
synced 2024-11-10 02:35:58 +01:00
Improve README.FRONTEND.
This commit is contained in:
parent
33bfb433f1
commit
e0c10acdf0
1 changed files with 72 additions and 40 deletions
|
@ -1,57 +1,72 @@
|
||||||
# Writing a new frontend
|
# Writing a new frontend
|
||||||
|
|
||||||
The frontend is split into two javascript files:
|
The frontend is written in JavaScript and is split into two files:
|
||||||
|
|
||||||
- `protocol.js` contains the low-level functions that interact with the server;
|
- `protocol.js` contains the low-level functions that interact with the
|
||||||
|
server;
|
||||||
- `sfu.js` contains the user interface.
|
- `sfu.js` contains the user interface.
|
||||||
|
|
||||||
If you wish to develop your own frontend, I recommend using `protocol.js`,
|
If you wish to develop your own frontend, I recommend using `protocol.js`,
|
||||||
which is likely to remain reasonably stable as the protocol evolves. This
|
which is likely to remain reasonably stable as the protocol evolves. This
|
||||||
file can be processed with JSDoc or Typescript (a sample `tsconfig.json`
|
file can be processed with JSDoc or Typescript (a sample `tsconfig.json`
|
||||||
is provided).
|
is provided), but is otherwise plain Javascript (ES6).
|
||||||
|
|
||||||
## Data structures
|
## Data structures
|
||||||
|
|
||||||
The class `ServerConnection` encapsulates a connection to the server as
|
The class `ServerConnection` encapsulates a connection to the server as
|
||||||
well as all the associated streams.
|
well as all the associated streams.
|
||||||
|
|
||||||
The class `Stream` encapsulates a set of associated audio and video
|
The class `Stream` encapsulates a set of related audio and video tracks;
|
||||||
tracks; your frontend will probably associate each stream with a video
|
your frontend will probably associate each stream with a `video` or
|
||||||
component.
|
`audio` component.
|
||||||
|
|
||||||
## Connecting to the server
|
## Connecting to the server
|
||||||
|
|
||||||
First, create a `ServerConnection` and set up all the callbacks:
|
First, create a `ServerConnection` and set up all the callbacks:
|
||||||
|
|
||||||
```
|
```javascript
|
||||||
let sc = new ServerConnection()
|
let sc = new ServerConnection()
|
||||||
serverConnection.onconnected = ...;
|
serverConnection.onconnected = ...;
|
||||||
serverConnection.onclose = ...;
|
serverConnection.onclose = ...;
|
||||||
serverConnection.ondownstream = ...;
|
serverConnection.onusermessage = ...;
|
||||||
serverConnection.onuser = ...;
|
|
||||||
serverConnection.onpermissions = ...;
|
serverConnection.onpermissions = ...;
|
||||||
|
serverConnection.onuser = ...;
|
||||||
serverConnection.onchat = ...;
|
serverConnection.onchat = ...;
|
||||||
serverConnection.onclearchat = ...;
|
serverConnection.onclearchat = ...;
|
||||||
serverConnection.onusermessage = ...;
|
serverConnection.ondownstream = ...;
|
||||||
```
|
```
|
||||||
|
|
||||||
You may now connect to the server:
|
The `onconnected` callback is called when we connect to the server;
|
||||||
```
|
`onclose` is the opposite of `onconnected`. `onusermessage` indicates
|
||||||
|
a message from the server that should be displayed to the user.
|
||||||
|
|
||||||
|
The other callbacks will only be called after you join a group. `onuser`
|
||||||
|
is used to indicate that a user has joined or left the current group.
|
||||||
|
`onchat` indicates that a chat message has been posted to the group, and
|
||||||
|
`onclearchat` indicates that the chat history has been cleared. Finally,
|
||||||
|
`ondownstream` is called when the server pushes a stream to the client;
|
||||||
|
see the section below about streams.
|
||||||
|
|
||||||
|
You may now connect to the server.
|
||||||
|
|
||||||
|
```javascript
|
||||||
serverConnection.connect(`wss://${location.host}/ws`);
|
serverConnection.connect(`wss://${location.host}/ws`);
|
||||||
```
|
```
|
||||||
You log-in, join a group and request media in the `onconnected` callback:
|
|
||||||
```
|
You log-in, join a group and request media in the `onconnected` callback.
|
||||||
|
|
||||||
|
```javascript
|
||||||
serverConnection.onconnected = function() {
|
serverConnection.onconnected = function() {
|
||||||
this.login(username, password);
|
this.login(username, password);
|
||||||
this.join(group);
|
this.join(group);
|
||||||
this.request('everything');
|
this.request('everything');
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
The `onpermissions` callback will trigger when the server informs us about
|
|
||||||
the permissions that were granted; you should probably reflect the
|
|
||||||
permissions in the user interface.
|
|
||||||
|
|
||||||
## Managing groups and clients
|
You should not attempt to push a stream to the server until it has granted
|
||||||
|
you the `present` permission through the `onpermissions` callback.
|
||||||
|
|
||||||
|
## Managing groups and users
|
||||||
|
|
||||||
The `groupaction` and `useraction` methods perform actions such as kicking
|
The `groupaction` and `useraction` methods perform actions such as kicking
|
||||||
users or locking groups. Most actions require either the `Op` or the
|
users or locking groups. Most actions require either the `Op` or the
|
||||||
|
@ -59,10 +74,13 @@ users or locking groups. Most actions require either the `Op` or the
|
||||||
|
|
||||||
## Sending and receiving chat messages
|
## Sending and receiving chat messages
|
||||||
|
|
||||||
You send a chat message with the `chat` method:
|
Once you have joined a group, you send chat messages with the `chat`
|
||||||
```
|
method. No permission is needed to do that.
|
||||||
|
|
||||||
|
```javascript
|
||||||
serverConnection.chat(username, '', 'Hi!');
|
serverConnection.chat(username, '', 'Hi!');
|
||||||
```
|
```
|
||||||
|
|
||||||
You receive chat messages in the `onchat` callback. The server may
|
You receive chat messages in the `onchat` callback. The server may
|
||||||
request that you clear your chat window, in that case the `onclearchat`
|
request that you clear your chat window, in that case the `onclearchat`
|
||||||
callback will trigger.
|
callback will trigger.
|
||||||
|
@ -70,9 +88,8 @@ callback will trigger.
|
||||||
## Accepting incoming video streams
|
## Accepting incoming video streams
|
||||||
|
|
||||||
When the server pushes a stream to the client, the `ondownstream` callback
|
When the server pushes a stream to the client, the `ondownstream` callback
|
||||||
will trigger; you should set up the stream callbacks here. It is
|
will trigger; you should set up the stream's callbacks here.
|
||||||
premature to set up a video component --- do that in `ondowntrack`.
|
```javascript
|
||||||
```
|
|
||||||
serverConnection.ondownstream = function(stream) {
|
serverConnection.ondownstream = function(stream) {
|
||||||
stream.onclose = ...;
|
stream.onclose = ...;
|
||||||
stream.onerror = ...;
|
stream.onerror = ...;
|
||||||
|
@ -81,6 +98,16 @@ premature to set up a video component --- do that in `ondowntrack`.
|
||||||
stream.onstatus = ...;
|
stream.onstatus = ...;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The `stream.labels` dictionary maps each track's id to one of `audio`,
|
||||||
|
`video` or `screenshare`. Since `stream.labels` is already available at
|
||||||
|
this point, you may set up an `audio` or `video` component straight away,
|
||||||
|
or you may choose to wait until the `ondowntrack` callback is called.
|
||||||
|
|
||||||
|
The server will usually invoke the `onlabel` callback in order to set
|
||||||
|
a user-readable label on the stream; this is currently just the
|
||||||
|
originating client's username.
|
||||||
|
|
||||||
After a new stream is created, `ondowntrack` will be called whenever
|
After a new stream is created, `ondowntrack` will be called whenever
|
||||||
a track is added. If the `MediaStream` passed to `ondowntrack` differs
|
a track is added. If the `MediaStream` passed to `ondowntrack` differs
|
||||||
from the one previously received, then the stream has been torn down and
|
from the one previously received, then the stream has been torn down and
|
||||||
|
@ -88,14 +115,22 @@ recreated, and you must drop all previously received tracks; in practice,
|
||||||
it is enough to set the `srcObject` property of the video component to the
|
it is enough to set the `srcObject` property of the video component to the
|
||||||
new stream.
|
new stream.
|
||||||
|
|
||||||
|
The `onstatus` callback is invoked whenever the client library detects
|
||||||
|
a change in the status of the stream; states `connected` and `complete`
|
||||||
|
indicate a functioning stream; other states indicate that the stream is
|
||||||
|
not working right now but might recover in the future.
|
||||||
|
|
||||||
|
The `onclose` callback is called when the stream is destroyed by the
|
||||||
|
server.
|
||||||
|
|
||||||
## Pushing outgoing video streams
|
## Pushing outgoing video streams
|
||||||
|
|
||||||
If you have the `present` permission, you may use the `newUpStream` method
|
If you have the `present` permission, you may use the `newUpStream` method
|
||||||
to push a stream to the server. Given a local stream `localStream`, do
|
to push a stream to the server. Given a `MediaStream` called `localStream`
|
||||||
something like the following:
|
(as obtained from `getUserMedia` or `getDisplayMedia`).
|
||||||
```
|
|
||||||
let stream = serverConnection.newUpStream;
|
```javascript
|
||||||
stream.kind = 'local';
|
let stream = serverConnection.newUpStream();
|
||||||
stream.onerror = ...;
|
stream.onerror = ...;
|
||||||
stream.onabort = ...;
|
stream.onabort = ...;
|
||||||
stream.onstatus = ...;
|
stream.onstatus = ...;
|
||||||
|
@ -104,13 +139,10 @@ localStream.getTracks().forEach(t => {
|
||||||
c.pc.addTrack(t, c.stream);
|
c.pc.addTrack(t, c.stream);
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
You should set `c.labels[t.id]` to one of `audio`, `video` or `screenshare`.
|
|
||||||
|
|
||||||
## Stream status and statistics
|
See above for information about setting up the `labels` dictionary.
|
||||||
|
|
||||||
The `onstatus` callback can be used to give users feedback about whether
|
## Stream statistics
|
||||||
a stream is working. You should probably treat states `connected` and
|
|
||||||
`completed` as good, and all other states as bad.
|
|
||||||
|
|
||||||
For outgoing streams only, the `setStatsInterval` and `onstats` callback
|
For outgoing streams only, the `setStatsInterval` and `onstats` callback
|
||||||
can be used to determine the data rate in real time. This is currently
|
can be used to determine the data rate in real time. This is currently
|
||||||
|
|
Loading…
Reference in a new issue