/
DailyAudioTrack.tsx
75 lines (68 loc) · 2.21 KB
/
DailyAudioTrack.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import React, { forwardRef, memo, useEffect, useRef } from 'react';
import { useMediaTrack } from '../hooks/useMediaTrack';
import useMergedRef from '../hooks/useMergedRef';
export interface DailyAudioPlayException {
name?: string;
message?: string;
sessionId: string;
target: HTMLAudioElement;
type: string;
}
interface Props extends React.AudioHTMLAttributes<HTMLAudioElement> {
/**
* Callback to handle failed attempt to play audio.
*/
onPlayFailed?(e: DailyAudioPlayException): void;
sessionId: string;
type?: 'audio' | 'screenAudio' | 'rmpAudio';
}
export const DailyAudioTrack = memo(
forwardRef<HTMLAudioElement, Props>(
({ onPlayFailed, sessionId, type = 'audio', ...props }, ref) => {
const audioEl = useRef<HTMLAudioElement>(null);
const audio = useMediaTrack(sessionId, type);
const audioRef = useMergedRef<HTMLAudioElement>(audioEl, ref);
const subscribedState = audio?.subscribed;
/**
* Setup audio tag.
*/
useEffect(() => {
const audioTag = audioEl.current;
if (!audioTag || !audio?.persistentTrack) return;
let playTimeout: ReturnType<typeof setTimeout>;
const handleCanPlay = () => {
audioTag.play().catch((e) => {
onPlayFailed?.({
sessionId,
target: audioTag,
type,
message: e.message,
name: e.name,
});
});
};
const handlePlay = () => {
clearTimeout(playTimeout);
};
audioTag.addEventListener('canplay', handleCanPlay);
audioTag.addEventListener('play', handlePlay);
audioTag.srcObject = new MediaStream([audio?.persistentTrack]);
return () => {
audioTag?.removeEventListener('canplay', handleCanPlay);
audioTag?.removeEventListener('play', handlePlay);
};
}, [audio?.persistentTrack, onPlayFailed, sessionId, type]);
return (
<audio
autoPlay
ref={audioRef}
{...props}
data-session-id={sessionId}
data-audio-type={type}
data-subscribed={subscribedState}
/>
);
}
)
);
DailyAudioTrack.displayName = 'DailyAudioTrack';