* fix(recording): allow samesite iframe embeds to work with local recording
Skip capture handle validation when inside an iframe to ensure local
recording works. This only applies if the iframe is served from the
same domain.
* fix(recording): add missing line breaks for better readability in LocalRecordingManager
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.
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.
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.
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.
The previous version of getToolbarButtons function was actually adding the custom buttons on every call to the config toolbarButtons array, effectively creating dublicates of every custom button. The PR fixes this issue.
Also now we will be running the getToolbarButtons calculation only when needed.