diff --git a/dailyjs/pagination/README.md b/dailyjs/pagination/README.md index 733e3b7..89272f3 100644 --- a/dailyjs/pagination/README.md +++ b/dailyjs/pagination/README.md @@ -29,7 +29,7 @@ Note: this example uses an additional env `MANUAL_TRACK_SUBS=1` that will disabl ## How does this example work? -When call sizes exceed a certain volume (~12 or more particpants) it's important to start optimising for both bandwidth and CPU. Using manual track subscriptions allows each client to specify which participants they want to receive video and/or audio from, reducing how much data needs to be downloaded as well as the number of connections our servers maintain (subsequently supporting increased participant counts.) +When call sizes exceed a certain volume (~12 or more participants) it's important to start optimising for both bandwidth and CPU. Using manual track subscriptions allows each client to specify which participants they want to receive video and/or audio from, reducing how much data needs to be downloaded as well as the number of connections our servers maintain (subsequently supporting increased participant counts.) This demo introduces a new paginated grid component that subscribes to any tiles that are in view. Our subscription API allows for the subscribing, pausing, resuming and unsubscribing of tracks. The grid component will: diff --git a/dailyjs/pagination/components/PaginatedVideoGrid/PaginatedVideoGrid.js b/dailyjs/pagination/components/PaginatedVideoGrid/PaginatedVideoGrid.js index 72ea368..4d3661e 100644 --- a/dailyjs/pagination/components/PaginatedVideoGrid/PaginatedVideoGrid.js +++ b/dailyjs/pagination/components/PaginatedVideoGrid/PaginatedVideoGrid.js @@ -1,13 +1,16 @@ import React, { + useRef, useCallback, useMemo, useEffect, - useRef, useState, } from 'react'; import { Button } from '@dailyjs/shared/components/Button'; import Tile from '@dailyjs/shared/components/Tile'; -import { DEFAULT_ASPECT_RATIO } from '@dailyjs/shared/constants'; +import { + DEFAULT_ASPECT_RATIO, + MEETING_STATE_JOINED, +} from '@dailyjs/shared/constants'; import { useCallState } from '@dailyjs/shared/contexts/CallProvider'; import { useParticipants } from '@dailyjs/shared/contexts/ParticipantsProvider'; import { isLocalId } from '@dailyjs/shared/contexts/participantsState'; @@ -15,13 +18,17 @@ import { useActiveSpeaker } from '@dailyjs/shared/hooks/useActiveSpeaker'; import { useCamSubscriptions } from '@dailyjs/shared/hooks/useCamSubscriptions'; import { ReactComponent as IconArrow } from '@dailyjs/shared/icons/raquo-md.svg'; import sortByKey from '@dailyjs/shared/lib/sortByKey'; +import PropTypes from 'prop-types'; import { useDeepCompareMemo } from 'use-deep-compare'; // --- Constants + const MIN_TILE_WIDTH = 280; const MAX_TILES_PER_PAGE = 12; -export const PaginatedVideoGrid = () => { +export const PaginatedVideoGrid = ({ + maxTilesPerPage = MAX_TILES_PER_PAGE, +}) => { const { callObject } = useCallState(); const { activeParticipant, @@ -44,7 +51,6 @@ export const PaginatedVideoGrid = () => { }); const [page, setPage] = useState(1); const [pages, setPages] = useState(1); - const [maxTilesPerPage] = useState(MAX_TILES_PER_PAGE); const gridRef = useRef(null); @@ -58,10 +64,7 @@ export const PaginatedVideoGrid = () => { frame = requestAnimationFrame(() => { const width = gridRef.current?.clientWidth; const height = gridRef.current?.clientHeight; - setDimensions({ - width, - height, - }); + setDimensions({ width, height }); }); }; handleResize(); @@ -126,6 +129,8 @@ export const PaginatedVideoGrid = () => { ); }, [dimensions, pageSize, displayableParticipantCount]); + // -- Track subscriptions + // Memoized array of participants on the current page (those we can see) const visibleParticipants = useMemo( () => @@ -135,8 +140,6 @@ export const PaginatedVideoGrid = () => { [page, pageSize, participants] ); - // -- Track subscriptions - /** * Play / pause tracks based on pagination * Note: we pause adjacent page tracks and unsubscribe from everything else @@ -174,7 +177,7 @@ export const PaginatedVideoGrid = () => { const stagedIds = []; // Decide whether to subscribe to or stage participants' - // track based on isibility + // track based on visibility renderedOrBufferedIds.forEach((id) => { if (id !== isLocalId()) { if (visibleParticipants.some((vp) => vp.id === id)) { @@ -200,7 +203,8 @@ export const PaginatedVideoGrid = () => { * Set bandwidth layer based on amount of visible participants */ useEffect(() => { - if (!(callObject && callObject.meetingState() === 'joined-meeting')) return; + if (!(callObject && callObject.meetingState() === MEETING_STATE_JOINED)) + return; const count = visibleParticipants.length; let layer; @@ -356,4 +360,8 @@ export const PaginatedVideoGrid = () => { ); }; +PaginatedVideoGrid.propTypes = { + maxTilesPerPage: PropTypes.number, +}; + export default PaginatedVideoGrid; diff --git a/dailyjs/shared/components/GlobalHead/GlobalHead.js b/dailyjs/shared/components/GlobalHead/GlobalHead.js index ac9b7a1..dc4660a 100644 --- a/dailyjs/shared/components/GlobalHead/GlobalHead.js +++ b/dailyjs/shared/components/GlobalHead/GlobalHead.js @@ -5,7 +5,7 @@ export const GlobalHead = () => (
diff --git a/dailyjs/shared/components/ParticipantBar/ParticipantBar.js b/dailyjs/shared/components/ParticipantBar/ParticipantBar.js index e0d3665..416c27f 100644 --- a/dailyjs/shared/components/ParticipantBar/ParticipantBar.js +++ b/dailyjs/shared/components/ParticipantBar/ParticipantBar.js @@ -192,7 +192,7 @@ export const ParticipantBar = ({ useResize(() => { const scrollEl = scrollRef.current; - if (!showParticipantsBar || !scrollEl) return; + if (!scrollEl) return; setIsSidebarScrollable(scrollEl?.scrollHeight > scrollEl?.clientHeight); const r = updateVisibleRange(scrollEl.scrollTop); updateCamSubscriptions(r); diff --git a/dailyjs/shared/contexts/CallProvider.js b/dailyjs/shared/contexts/CallProvider.js index 48dbf78..eb133c8 100644 --- a/dailyjs/shared/contexts/CallProvider.js +++ b/dailyjs/shared/contexts/CallProvider.js @@ -112,16 +112,14 @@ export const CallProvider = ({ networkState, showLocalVideo, roomExp, - videoQuality, enableRecording, + videoQuality, setVideoQuality, setBandwidth, setRedirectOnLeave, setShowLocalVideo, - setVideoQuality, startCloudRecording, subscribeToTracksAutomatically, - videoQuality, }} > {children} diff --git a/dailyjs/shared/contexts/ParticipantsProvider.js b/dailyjs/shared/contexts/ParticipantsProvider.js index 56f873c..81b6a94 100644 --- a/dailyjs/shared/contexts/ParticipantsProvider.js +++ b/dailyjs/shared/contexts/ParticipantsProvider.js @@ -1,5 +1,3 @@ -/* global rtcpeers */ - import React, { createContext, useCallback, diff --git a/dailyjs/shared/contexts/TracksProvider.js b/dailyjs/shared/contexts/TracksProvider.js index 94e2615..4021d43 100644 --- a/dailyjs/shared/contexts/TracksProvider.js +++ b/dailyjs/shared/contexts/TracksProvider.js @@ -124,6 +124,7 @@ export const TracksProvider = ({ children }) => { }; }, {}); + if (Object.keys(updates).length === 0) return; callObject.updateParticipants(updates); }, [callObject, remoteParticipantIds, recentSpeakerIds] @@ -202,7 +203,7 @@ export const TracksProvider = ({ children }) => { return { [id]: result }; }, {}); - if (!subscribeToTracksAutomatically) { + if (!subscribeToTracksAutomatically && Object.keys(updates).length0) { callObject.updateParticipants(updates); } }, 100); diff --git a/dailyjs/shared/package.json b/dailyjs/shared/package.json index 8653931..0c0a123 100644 --- a/dailyjs/shared/package.json +++ b/dailyjs/shared/package.json @@ -4,7 +4,7 @@ "private": true, "main": "index.js", "dependencies": { - "@daily-co/daily-js": "^0.16.0", + "@daily-co/daily-js": "^0.18.0", "bowser": "^2.11.0", "classnames": "^2.3.1", "debounce": "^1.2.1", diff --git a/yarn.lock b/yarn.lock index 47b4aba..073555d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -160,10 +160,10 @@ "@babel/helper-validator-identifier" "^7.12.11" to-fast-properties "^2.0.0" -"@daily-co/daily-js@^0.16.0": - version "0.16.0" - resolved "https://registry.yarnpkg.com/@daily-co/daily-js/-/daily-js-0.16.0.tgz#9020104bb88de62dcc1966e713da65844243b9ab" - integrity sha512-DBWzbZs2IR7uYqfbABva1Ms3f/oX85dnQnCpVbGbexTN63LPIGknFSQp31ZYED88qcG+YJNydywBTb+ApNiNXA== +"@daily-co/daily-js@^0.18.0": + version "0.18.0" + resolved "https://registry.yarnpkg.com/@daily-co/daily-js/-/daily-js-0.18.0.tgz#b8341c2ac12b6e27fec2ab187be6cca699e60dce" + integrity sha512-MXY6mpC0bJ1RCbVLlNioOfoNFhMX8lwoI/G9t3d/CAQqO9brxnp73t2Ltyaf2SXMIR+S88flgtfMcRtEBnFsjQ== dependencies: "@babel/runtime" "^7.12.5" bowser "^2.8.1"