Replaces hard-coded pixel values with relative rem units across UI components to improve typography responsiveness and maintainability.
Co-authored-by: Hristo Terezov <hristo@jitsi.org>
We have observed some failed recordings which are lacking the EBML
header. The only way in which that seems plausible is if the
dataavailable event is received while processing the stop event. This is
allegedly not possible, but it's the only plausible explanation, so
let's defend against that.
Extend the timeslice back to 5s too.
After a lot of back and forth, WebM seems to be the only option we
really have. In terms of containers and codecs, here is the rundown:
- WebM, any codec: the resulting file is not seekable
- MKV, any codec: the resulting file is not seekable
- MP4, vp9 + opus: video artifacts and audio clipping, file is seekable
- MP4, av1 + AAC: all good, but not supported on Linux :-/
MP4 looked very promising but there is no combination that leads to
something that works reliably everywhere, oh well. In addition, MP4
files can be opened with QuickTime on macOS, but not with the codec
combination we'd use, so that is somewhat a disadvantage.
So, we are back to where we started: WebM with VP8 and opus. But we need
to fix the duration in a potentially long file... the trick is to _only_
fix the duration. We can do that by inserting the right segment in the
metadata section. Something we cannot do without reading the whole file
is create cue points, but players like VLC seem to work well without
them.
Setting the UA string in Electron doesn't propagate the change to the
iframe where the meeting is loaded (🤦).
Thus make it more resilient by trying different things:
- A freshly introduced "iAmSpot" config option, similar to Jibri
- The app ID is present in the UA string, so we can test for that
- As a last-ditch effort, check if the display name is the default
"Meeting Room"
In the 1st incarnation of local recordings we used to use VP8 as the
video encoder. Upon switching to MP4 that combiantion is not supported
for some reason, so I used VP9 instead.
Some anecdotal evidence suggests VP9 is behqaving more erratically, with
rendering errors and fixes.
Turns out Chrome also supports the Matroska container! And VP8 inside it
at that! The bonus we get from using it is that QuickTime on macOS won't
try to open it, thus avoiding some confusion with MP4 files, which it
recognizes, but cannot open due to the video codec.
When turned on, the consent dialog won't be displayed for the users who
are already in the meeting, it will only be displayed to those who join
after the recording was started.
Flush the file after the 'stop' event is emitted, which happens _after_
the last 'dataavailable' has been emitted, and thus when the
MediaRecorder is really done.
In addition, lower the time slice as added precaution against crashes.
It's OK if we don't have any local audio track, we'll add it to the
mixer later.
The original bug / limitation that prompted the previous code no longer
applies since we always have a MediaStream (with audio tracks) which
we are recording.
Capture the tab audio, which will include all participants and sound
effects, YouTube videos, anything playing in the tab.
This requires the `suppressLocalAudioPlayback` constraint since
otherwise the shared tab won't keep playing audio.
Local audio still needs to be injected seprarately, since it's not
played back to the local user.
A given recording should only trigger a single consent request.
The mechanism to notify about recording status updates may fire multiple
times since it's tied to XMPP presence and may send updates such as when
the live stream view URL is set.
Rather than trying to handle all possible corner cases to make sure we
only show the consent dialog once, keep track of the recording session
IDs for which we _have_ asked for consent and skip the dialog in case we
have done it already.
Use the `showSaveFilePicker` File System Access API to pre-select the
file for download and stream the contents there. The browser uses a
temporary file as the buffer, thus not requiring us to buffer the
contents in memory.
Also change the container to MP4, since we have no way to fix the
seeking problem since we don't have the file in memory. Good news is
that it's supported since Chrome 126 and we can feature detect it!
Finally, add a helper `isSupprted` method which feature-detects
everything we need to make this work.
Ref: https://developer.mozilla.org/en-US/docs/Web/API/Window/showSaveFilePicker
Ref: https://groups.google.com/a/chromium.org/g/blink-dev/c/p1OMVj1FrMI/m/6FdLk7rZAQAJ
When any of the backend is used 'anonymous', 'jitsi-anonymous', 'internal_hashed', 'internal_plain', 'cyrus' and a participant becomes a moderator, because of external module or because set from jicofo we send to client with the self-presence about becoming moderator a default set of permissions which can be controlled via prosody config.
If using 'token' authentication the above applies only if there is a token and the token does not contain context.features.
* fix(transcriptions): Uses dial command to invite transcriber.
* fix(transcriptions,recording): Allows non moderators with features to dial, record or transcribe.
* sqaush: Make sure filtering works when only is a moderator.
It works now and without a token and no features, but being moderator.
* squash: Rename constant.
* squash: Checks features first before defaulting to moderator when filtering metadata service.
* squash: Checks features first before defaulting to moderator in UI.
* squash: Fixes lint and one other check.
* squash: Moves more logic to is_feature_allowed.
* squash: Drops unnecessary check.
* squash: Uses constant coming from ljm.
* squash: Toggles back captions button on error.
* squash: Fix comment.
* squash: Reverting back isLiveStreamingButtonVisible.
* squash: Fix imports.
Some middleware functions are declared as async. This wraps next(action) in Promise which will delay the execution of actions and also dispatch will return the its result always as a Promise.