daily-examples/custom/shared/components/Audio/CombinedAudioTrack.js

68 lines
1.5 KiB
JavaScript

import React, { useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
import { useDeepCompareEffect, useDeepCompareMemo } from 'use-deep-compare';
const CombinedAudioTrack = ({ tracks }) => {
const audioEl = useRef(null);
useEffect(() => {
if (!audioEl) return;
audioEl.current.srcObject = new MediaStream();
}, []);
const trackIds = useDeepCompareMemo(
() => Object.values(tracks).map((t) => t?.persistentTrack?.id),
[tracks]
);
useDeepCompareEffect(() => {
const audio = audioEl.current;
if (!audio || !audio.srcObject) return;
const stream = audio.srcObject;
const allTracks = Object.values(tracks);
allTracks.forEach((track) => {
const persistentTrack = track?.persistentTrack;
if (persistentTrack) {
persistentTrack.addEventListener(
'ended',
(ev) => stream.removeTrack(ev.target),
{ once: true }
);
stream.addTrack(persistentTrack);
}
});
const playAudio = async () => {
try {
if (
stream
.getAudioTracks()
.some((t) => t.enabled && t.readyState === 'live') &&
audio.paused
) {
await audio.play();
}
} catch {
// ...
}
};
audio.load();
playAudio();
}, [tracks, trackIds]);
return (
<audio autoPlay playsInline ref={audioEl}>
<track kind="captions" />
</audio>
);
};
CombinedAudioTrack.propTypes = {
tracks: PropTypes.object,
};
export default CombinedAudioTrack;