bigbluebutton-Github/bigbluebutton-html5/imports/utils/media-stream-utils.js
prlanzarin d6c7f23a0e feat(audio): local echo test and audio energy meter
New features:
  - A simplified echo test mode that only does a local loopback (instead of
  going to FS and back)
  - A volume meter for microphone streams to the AudioSettings view

Those two features are experimental and disabled by default; see
public.app.media.simplifiedEchoTest and public.app.media.showVolumeMeter configs

Collateral changes:
  - fix: localize fallback device strings in AudioSettings/DeviceSelector
  - Refactor on some media stream utils to be re-usable across components
  - Refactor in AudioSettings to keep gUM #uses stable.
    * TODO: need to pass streams through AudioManager to avoid the surplus gUM.
  - fix(audio): drop ScriptProcessorNode usage (deprecated)
    * Used in volume meter for tracking - use hark instead
2022-04-11 19:21:56 +00:00

73 lines
1.8 KiB
JavaScript
Executable File

const stopMediaStreamTracks = (stream) => {
if (stream && typeof stream.getTracks === 'function') {
stream.getTracks().forEach((track) => {
if (typeof track.stop === 'function' && track.readyState !== 'ended') {
track.stop();
// Manually emit the event as a safeguard; Firefox doesn't fire it when it
// should with live MediaStreamTracks...
const trackStoppedEvt = new MediaStreamTrackEvent('ended', { track });
track.dispatchEvent(trackStoppedEvt);
}
});
}
};
const getAudioTracks = (stream) => {
if (stream) {
if (typeof stream.getAudioTracks === 'function') {
return stream.getAudioTracks();
}
if (typeof stream.getTracks === 'function') {
return stream.getTracks().filter((track) => track.kind === 'audio');
}
}
return [];
};
const getVideoTracks = (stream) => {
if (stream) {
if (typeof stream.getVideoTracks === 'function') {
return stream.getVideoTracks();
}
if (typeof stream.getTracks === 'function') {
return stream.getTracks().filter((track) => track.kind === 'video');
}
}
return [];
};
const getDeviceIdFromTrack = (track) => {
if (track && typeof track.getSettings === 'function') {
const { deviceId } = track.getSettings();
return deviceId;
}
return '';
};
const extractDeviceIdFromStream = (stream, kind) => {
// An empty string is the browser's default...
let tracks = [];
switch (kind) {
case 'audio':
tracks = getAudioTracks(stream);
return getDeviceIdFromTrack(tracks[0]);
case 'video':
tracks = getVideoTracks(stream);
return getDeviceIdFromTrack(tracks[0]);
default: {
return '';
}
}
};
export default {
stopMediaStreamTracks,
getVideoTracks,
extractDeviceIdFromStream,
};