moved audio tracks component to shared library

This commit is contained in:
Jon 2021-06-17 11:29:18 +01:00
parent 33fcef847c
commit f6229317d8
4 changed files with 80 additions and 45 deletions

View File

@ -1,44 +0,0 @@
import React, { useRef, useEffect } from 'react';
import { useParticipants } from '@dailyjs/shared/contexts/ParticipantsProvider';
import useAudioTrack from '@dailyjs/shared/hooks/useAudioTrack';
import PropTypes from 'prop-types';
const AudioItem = React.memo(({ participant }) => {
const audioRef = useRef(null);
const audioTrack = useAudioTrack(participant);
useEffect(() => {
if (!audioTrack || !audioRef.current) return;
// quick sanity to check to make sure this is an audio track...
if (audioTrack.kind !== 'audio') return;
audioRef.current.srcObject = new MediaStream([audioTrack]);
}, [audioTrack]);
return (
<>
<audio autoPlay playsInline ref={audioRef} id={participant.name}>
<track kind="captions" />
</audio>
</>
);
});
AudioItem.propTypes = {
participant: PropTypes.object,
};
export const Audio = React.memo(() => {
const { allParticipants } = useParticipants();
return (
<>
{allParticipants.map(
(p) => !p.isLocal && <AudioItem participant={p} key={p.id} />
)}
</>
);
});
export default Audio;

View File

@ -1,4 +1,5 @@
import React from 'react';
import { Audio } from '@dailyjs/shared/components/Audio';
import {
WaitingRoomModal,
WaitingRoomNotification,
@ -16,7 +17,6 @@ import { ReactComponent as IconMicOn } from '@dailyjs/shared/icons/mic-on-md.svg
import { ReactComponent as IconSettings } from '@dailyjs/shared/icons/settings-md.svg';
import PropTypes from 'prop-types';
import { Audio } from '../Audio';
import { VideoGrid } from '../VideoGrid';
import { Header } from './Header';
import { Tray, TrayButton } from './Tray';

View File

@ -0,0 +1,79 @@
/**
* Audio
* ---
* Renders audio tags for each audible participant / screen share in the call
* Note: it's very important to minimise DOM mutates for audio components
* as iOS / Safari do a lot of browser 'magic' that may result in muted
* tracks. We heavily memoize this component to avoid unnecassary re-renders.
*/
import React, { useRef, useEffect } from 'react';
import { useParticipants } from '@dailyjs/shared/contexts/ParticipantsProvider';
import useAudioTrack from '@dailyjs/shared/hooks/useAudioTrack';
import PropTypes from 'prop-types';
const AudioItem = React.memo(
({ participant }) => {
const audioRef = useRef(null);
const audioTrack = useAudioTrack(participant);
useEffect(() => {
if (!audioTrack || !audioRef.current) return;
// quick sanity to check to make sure this is an audio track...
if (audioTrack.kind !== 'audio') return;
audioRef.current.srcObject = new MediaStream([audioTrack]);
}, [audioTrack]);
useEffect(() => {
// On iOS safari, when headphones are disconnected, all audio elements are paused.
// This means that when a user disconnects their headphones, that user will not
// be able to hear any other users until they mute/unmute their mics.
// To fix that, we call `play` on each audio track on all devicechange events.
if (audioRef.currenet) {
return false;
}
const startPlayingTrack = () => {
audioRef.current?.play();
};
navigator.mediaDevices.addEventListener(
'devicechange',
startPlayingTrack
);
return () =>
navigator.mediaDevices.removeEventListener(
'devicechange',
startPlayingTrack
);
}, [audioRef]);
return (
<>
<audio autoPlay playsInline ref={audioRef}>
<track kind="captions" />
</audio>
</>
);
},
() => true
);
AudioItem.propTypes = {
participant: PropTypes.object,
};
export const Audio = React.memo(() => {
const { allParticipants } = useParticipants();
return (
<>
{allParticipants.map(
(p) => !p.isLocal && <AudioItem participant={p} key={p.id} />
)}
</>
);
});
export default Audio;