diff --git a/dailyjs/shared/components/Audio/Audio.js b/dailyjs/shared/components/Audio/Audio.js index 07271c5..931ee56 100644 --- a/dailyjs/shared/components/Audio/Audio.js +++ b/dailyjs/shared/components/Audio/Audio.js @@ -1,5 +1,11 @@ /** * Audio + * --- + * When working with audio elements it's very important to avoid mutating + * the DOM elements as much as possible to avoid audio pops and crackles. + * This component addresses to known browser quirks; Safari autoplay + * and Chrome's maximum media elements. On Chrome we add all audio tracks + * into into a single audio node using the CombinedAudioTrack component */ import React, { useEffect, useMemo } from 'react'; import { useTracks } from '@dailyjs/shared/contexts/TracksProvider'; diff --git a/dailyjs/shared/components/Tile/Tile.js b/dailyjs/shared/components/Tile/Tile.js index 53afe11..efaeb3c 100644 --- a/dailyjs/shared/components/Tile/Tile.js +++ b/dailyjs/shared/components/Tile/Tile.js @@ -1,4 +1,4 @@ -import React, { useRef } from 'react'; +import React, { useEffect, useRef } from 'react'; import useVideoTrack from '@dailyjs/shared/hooks/useVideoTrack'; import { ReactComponent as IconMicMute } from '@dailyjs/shared/icons/mic-off-sm.svg'; import classNames from 'classnames'; @@ -14,11 +14,36 @@ export const Tile = React.memo( showName = true, showAvatar = true, aspectRatio = DEFAULT_ASPECT_RATIO, + onVideoResize, ...props }) => { const videoTrack = useVideoTrack(participant); const videoEl = useRef(null); + /** + * Add optional event listener for resize event so the parent component + * can know the video's native aspect ratio. + */ + useEffect(() => { + const video = videoEl.current; + if (!onVideoResize || !video) return false; + + const handleResize = () => { + if (!video) return; + const width = video?.videoWidth; + const height = video?.videoHeight; + if (width && height) { + // Return the video's aspect ratio to the parent's handler + onVideoResize(width / height); + } + }; + + handleResize(); + video?.addEventListener('resize', handleResize); + + return () => video?.removeEventListener('resize', handleResize); + }, [onVideoResize, videoEl, participant]); + const cx = classNames('tile', { mirrored, avatar: showAvatar && !videoTrack, @@ -35,7 +60,11 @@ export const Tile = React.memo( )} {videoTrack ? ( -