-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
112 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
.agora-rtc-remote-user { | ||
width: 288px; | ||
height: 216px; | ||
position: relative; | ||
overflow: hidden; | ||
} | ||
|
||
.agora-rtc-remote-user-video { | ||
width: 100%; | ||
height: 100%; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import "./RemoteUser.css"; | ||
|
||
import type { IAgoraRTCClient, IAgoraRTCRemoteUser } from "agora-rtc-sdk-ng"; | ||
import type { HTMLProps, PropsWithChildren } from "react"; | ||
import { useEffect } from "react"; | ||
|
||
import { forwardRef, useRef } from "react"; | ||
import { RemoteAudioTrack } from "./RemoteAudioTrack"; | ||
import { RemoteVideoTrack } from "./RemoteVideoTrack"; | ||
import { useRTCClient } from "../hooks"; | ||
import { useForceUpdate } from "../hooks/tools"; | ||
import { useSafePromise } from "../utils"; | ||
|
||
export interface RemoteUserProps extends HTMLProps<HTMLDivElement> { | ||
readonly client?: IAgoraRTCClient; | ||
/** | ||
* A remote user | ||
*/ | ||
readonly user?: IAgoraRTCRemoteUser; | ||
/** | ||
* Whether to play the remote user's video track. | ||
*/ | ||
readonly videoOn?: boolean; | ||
/** | ||
* Whether to play the remote user's audio track. | ||
*/ | ||
readonly audioOn?: boolean; | ||
/** | ||
* Device ID, which can be retrieved by calling `getPlaybackDevices`. | ||
* | ||
* Changes of the ID will invoke `setPlaybackDevice` which sets the audio playback device, for example, the speaker. | ||
* | ||
* > `setPlaybackDevice` supports Chrome on desktop devices only. Other browsers throw a `NOT_SUPPORTED` error when calling the method. | ||
*/ | ||
readonly playbackDeviceId?: string; | ||
/** | ||
* The volume. The value ranges from 0 (mute) to 100 (maximum). A value of 100 is the current volume. | ||
*/ | ||
readonly volume?: number; | ||
} | ||
|
||
export const RemoteUser = /* @__PURE__ */ forwardRef< | ||
HTMLDivElement, | ||
PropsWithChildren<RemoteUserProps> | ||
>(function RemoteUser( | ||
{ user, videoOn, audioOn, playbackDeviceId, volume, children, className, ...props }, | ||
ref, | ||
) { | ||
const client = useRTCClient(); | ||
const subscribedRef = useRef(0b00); // 0b01: audio, 0b10: video, 0b11: both, 0: none | ||
const forceUpdate = useForceUpdate(); | ||
const sp = useSafePromise(); | ||
|
||
useEffect(() => { | ||
if (user && videoOn && !(subscribedRef.current & 0b10)) { | ||
subscribedRef.current |= 0b10; | ||
sp(client.subscribe(user, "video")).then(forceUpdate).catch(console.error); | ||
} | ||
}, [client, user, videoOn, sp, forceUpdate]); | ||
|
||
useEffect(() => { | ||
if (user && audioOn && !(subscribedRef.current & 0b01)) { | ||
subscribedRef.current |= 0b01; | ||
sp(client.subscribe(user, "audio")).then(forceUpdate).catch(console.error); | ||
} | ||
}, [client, user, audioOn, sp, forceUpdate]); | ||
|
||
useEffect( | ||
() => () => { | ||
if (user && subscribedRef.current) { | ||
subscribedRef.current = 0b00; | ||
client.unsubscribe(user).catch(console.error); | ||
} | ||
}, | ||
[user, client], | ||
); | ||
|
||
return ( | ||
<div className={`agora-rtc-remote-user ${className ?? ""}`} {...props} ref={ref}> | ||
<RemoteVideoTrack | ||
className="agora-rtc-remote-user-video" | ||
track={user?.videoTrack} | ||
play={videoOn} | ||
/> | ||
<RemoteAudioTrack | ||
playbackDeviceId={playbackDeviceId} | ||
volume={volume} | ||
track={user?.audioTrack} | ||
play={audioOn} | ||
/> | ||
{children} | ||
</div> | ||
); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { useCallback, useState } from "react"; | ||
|
||
export function useForceUpdate() { | ||
const [_, forceUpdate] = useState(0); | ||
return useCallback(() => forceUpdate(n => (n + 1) | 0), []); | ||
} |