Coder Social home page Coder Social logo

agora-rtc-react's Introduction

Agora RTC SDK React Wrapper (Archive)

Agora now offers an official React SDK!

The React SDK (2.x) repo is available here.
It's released as v2.x under the same npm package.

Links for 2.x


1.x (this repo)

A react (react.js) wrapper for Agora RTC NG SDK.

This wrapper supports React >= v16.8

Install

npm install agora-rtc-react

Usage

import React from "react";
import { AgoraVideoPlayer, createClient, createMicrophoneAndCameraTracks } from "agora-rtc-react";

const config = {mode: "rtc", codec: "vp8"}

const useClient = createClient(config);
const useMicrophoneAndCameraTracks = createMicrophoneAndCameraTracks();

const App = () => {
  const client = useClient();
  const { ready, tracks } = useMicrophoneAndCameraTracks();

  return (
    ready && <AgoraVideoPlayer videoTrack={tracks[1]} style={{height: '100%', width: '100%'}} />
  )
}

Example

A full videocall example using the wrapper can be found here.

Reference

You can view the methods in the wrapper here.

agora-rtc-react's People

Contributors

ekaansharora avatar kahirokunn avatar ncaq avatar pcardune avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

agora-rtc-react's Issues

Enable and disable speaker

When I use the web application in my mobile device, I want to switch between mobile speaker to earpiece to listen the remote audio. By default it is playing on speaker. How to do that ?

Blocked by CORS policy

Hi, I followed the tutorial from here. Except, according to this SO question, token based authentication is mandatory now. I enabled that by generating a token and giving the value(instead of null), but I still get the error:

Access to XMLHttpRequest at 'https://cds-ap-web-3.agora.io/api/v1?action=config' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

Am I missing something. TIA.

Publish to npm

It would be preferable if the package would be deployed to npm instead of installed through git.

run-s command

i start using the package, and honestly, i found it great and very helpful, but the thing is you are using npm-run-all and with shortcut of run-s in package-json, and this is make it very difficult to install the package in cloud server such as heroku, so when i run the deployement process in Heroku, i got this error

 npm ERR! > [email protected] prepare
remote:        npm ERR! > run-s build
remote:        npm ERR! sh: 1: run-s: not found

so please can you make the package build simply by npm due there is no need to use npm-run-all for the moment as i see the implementation,

Video track accessed by multiple <AgoraVideoPlayer /> components: ` track.stop()` / `track.close()` does not turn off camera light

For my company's web app, we need to have the local camera's video accessible by both our main video chat interface and our video chat settings popup modal (see screenshot below).

image (19)

To try to accomplish this, we create tracks in our parent component using

const useMicrophoneAndCameraTracks = createMicrophoneAndCameraTracks(
  { AEC: true, ANS: true },
  { optimizationMode: "motion" }
);

and

const { ready, tracks } = useMicrophoneAndCameraTracks();

From this, our video track is tracks[1], which is used in both our main video chat interface's component and our video chat settings popup modal's <AgoraVideoPlayer /> component (passed in as props).

However, the problem is that we then fail to turn off the camera (and camera light) after we dismount the parent component:

  useEffect(() => {
    ...
    return () => {
        for (const track of tracks) {
          track.stop();
          track.close();
        }
    }, []);

We do confirm that the camera and camera light does turn off if we only use the track in only one single <AgoraVideoPlayer />

How can we ensure that the light turns off when the parent component is dismounted? Or if this is not the right approach, what should we do instead?

createCustomVideoTrack difficult to use

Since this needs to be called outside the functional component, and it requires a MediaStreamTrack to already be in place, it does not seem to offer any functionality outside of a hard-coded track.
Perhaps I am missing something, but there seems no way to pass it any sort of dynamically-created track.
Is there a way?

Need an example how to emplement Screen Sharing

I try to use createScreenVideoTrack Hook
But when I call this hook it opene screen sharing automatically when page opened.

I want when i press on button open share screen dialogue and when I chose media for sharng, replace localVideoTrack with screenTrack

Thanks for answering ๐Ÿ™

user-unpublished not caught when using Strict Mode

The problem i encountered is next:

I followed the exact implementation as stated in: React Agora Example
But when Strict Mode is on "user-unpublished" event for meeting participants doesn't get executed. Can't determine whether event is not being sent at all or simply other participants sides don't get according events but when strict mode is on it doesn't work ( All other events work fine ).

When turning Strict mode off everything works fine.

I'm interested whether or not it is a common behaviour? And if turning off Strict Mode for these kinds of purposes is ok.
Thanks in advance

createMicrophoneAndCameraTracks method bug

in your examle, async function createClosure in createMicrophoneAndCameraTracks will be called twice, resulting in different results for tracks.

trackMediaType: 'audio', _ID: 'track-mic-150d1549'

trackMediaType: 'audio', _ID: 'track-mic-150d1549'

How to join a call with only audio, with camera off?

Hello, I have a case where the user can only join with audio with the camera off. In that case, I set the local video track to disable. Then I got an error if I try to join the call I got an error. "can't publish disabled video track." In that case help me, how to join a call with audio only.

client.leave() will not trigger "user-left" on other clients

When leaving a channel the "user-left" event is not triggered on other clients:

const doLeave = useCallback(async () => { console.log("leaving"); await client.leave(); client.removeAllListeners(); tracks[0].close(); tracks[1].close(); }, [client, tracks]);

However, reloading the window on the leaver does trigger "user-left" on other clients

Closing tracks doesn't turn off camera light

I'm testing the sample code you gave but when I leave call and close trackers my camera light still on and brwosers show the icon in tab that says the website is using microphone or camera.

I've also tried first stopping them and then closing each one but it doesn't work.

React 18 - node 16.15.1

const leaveChannel = async () => {
        await client.leave();
        client.removeAllListeners();
        // we close the tracks to perform cleanup
        await tracks[0].stop();
        await tracks[0].close();        
        await tracks[1].stop();
        await tracks[1].close();
        // the camera light should go off
        setStart(false);
        setInCall(false);
        // you can now unmount the component if required
    };

screen sharing not working on safari browser

we are not able to share screen for safari browser.
I was getting an error "AgoraRTCError UNEXPECTED_ERROR: InvalidAccessError: getDisplayMedia must be called from a user gesture handler."

Can you please provide some code snippets for resolving this issue.

Add beauty effect option

Hello,
thank you for this library, I want to add beauty effect in the video tracks
how can I do this I was able to add in react native but there is no documentation to add in react js.

please let me know if it is possible in react js and how can I add.

Draw on AgoraVideoPlayer to find face

hello, i want to know how can i draw on AgoraVideoPlayer , i want to use Agora and face-api.js to find face when i call. pls tell me how to do it

Audio track does not stop in Chrome Icognito

When leaving a channel in an Incognito Window in chrome the audio is still on.

const doLeave = useCallback(async () => { console.log("leaving"); await client.leave(); client.removeAllListeners(); tracks[0].close(); tracks[1].close(); }, [client, tracks]);

How to know who is joined?

Hi. I am new with agora. Please help me.
Suppose 2 users Asit and Sumit is joining the channel via web browser. How Asit will knows who is joined similar way how sumit will knows who is joined in this call? Please tell me how to set the joiner name?

And also one thing i want to know when any user mute his video in the opposite end how to know user is on the call or leave from call. because after video mute videotrack is removed and that's why only one user is showing. Please help me.

Enable setLogLevel

Right now the logLevel defaults to DEBUG which floods the console with messages.
Exporting the setLogLevel function would let us customize determine the level we want when developing.

Disable mic on connect

How can I use example below in order to connect without microphone enabled ? As far as I know, we can't call hooks conditionally

import { AgoraVideoPlayer, createClient, createMicrophoneAndCameraTracks } from "agora-rtc-react";

const config = {mode: "rtc", codec: "vp8"}

const useClient = createClient(config);
const useMicrophone = createMicrophoneAudioTrack();

const App = () => {
  const client = useClient();
  const { ready, tracks } = useMicrophone(); // it should be muted by default and enabled when user click mic icon

  return (
    ready && <Player />
  )
}

Using an archived agora dependency

This repo uses https://github.com/AgoraIO-Community/AgoraWebSDK-NG which is an archived repository, and seems to be unsupported.

Are there any plans to update to a supported dependency?

agora-web-archive seems to be actively maintained, but the contributors are a bit bizarre.

I'm wondering what this repo's community is thinking about the future of the codebase. (I'm starting a new project on agora and selfishly want to make sure I pick dependencies that have bright futures)

Thanks!

Audio is working only on refresh

Lets assume 2 users A and B is joining the channel via web browser User "A" is able to hear and see User "B" where as User "B" is able to see User "A" but unable to hear user "A" ideally only one participant is able hear and see where as the other participant is able to only see and not able to hear if the participant who is unable to hear refresh his browser then everything is working fine.

Checked the audio profile its automatically assigned by agora and we don't have anything to do there and this happens in the AgoraWeb-React

SDK Version 3.6

Error while deploying on vercel

Conflict while building. Next.js with react version @18.2.0.

In the meantime I used a temporary fix npm i agora-rtc-react --legacy-peers-deps. Is this advisable?

16:12:35.133 | npm ERR! code ERESOLVE
16:12:35.136 | npm ERR! ERESOLVE could not resolve
16:12:35.136 | npm ERR!
16:12:35.137 | npm ERR! While resolving: [email protected]
16:12:35.137 | npm ERR! Found: [email protected]
16:12:35.137 | npm ERR! node_modules/react
16:12:35.137 | npm ERR!   react@"^18.2.0" from the root project
16:12:35.137 | npm ERR!   peer react@"^16 \|\| ^17 \|\| ^18" from @headlessui/[email protected]
16:12:35.137 | npm ERR!   node_modules/@headlessui/react
16:12:35.137 | npm ERR!     @headlessui/react@"^1.7.10" from the root project
16:12:35.138 | npm ERR!   10 more (@heroicons/react, @react-oauth/google, next, react-dom, ...)
16:12:35.138 | npm ERR!
16:12:35.138 | npm ERR! Could not resolve dependency:
16:12:35.138 | npm ERR! peer react@"^16.8.0 \|\| ^17" from [email protected]
16:12:35.138 | npm ERR! node_modules/agora-rtc-react
16:12:35.138 | npm ERR!   agora-rtc-react@"github:AgoraIO-Community/agora-rtc-react#v1.0.1" from the root project
16:12:35.138 | npm ERR!
16:12:35.138 | npm ERR! Conflicting peer dependency: [email protected]
16:12:35.138 | npm ERR! node_modules/react
16:12:35.138 | npm ERR!   peer react@"^16.8.0 \|\| ^17" from [email protected]
16:12:35.138 | npm ERR!   node_modules/agora-rtc-react
16:12:35.139 | npm ERR!     agora-rtc-react@"github:AgoraIO-Community/agora-rtc-react#v1.0.1" from the root project

setLogLevel

How can I set the log level using this? Equivalent to:

AgoraRTC.Logger.setLogLevel(AgoraRTC.Logger.INFO);

Option to disable camera and microphone initially

Nice work on the wrapper so far!

Is there a way to disable the camera and microphone tracks on page load?

I want to be able to manually enable them only when the server returns the details for the live stream (I.e. App Id, channel name, etc)

React 18 Support?

I was wondering if it's on the road map to support react 18 with this library.

Vite Build Failing

We recently upgraded our application from CRA to Vite and are running into issues with this library (and the agora-rtc-sdk-ng library) when trying to preview a build. I both scenarios, we get the following console error when trying to preview the build:

it is not a constructor or e is not a constructor with the stack trace originating from the Agora library import. We then tried dynamically importing the library, which allowed the page to load, but then ran into the issue again when we go to initialize the library.

Prior to Vite, we had the library working fine with CRA. And, we've tried configuring Vite with ESNext and ES2015 build targets using terser but none of those options have worked. We also tried to getting the Quick Demo React to work (available here: https://github.com/AgoraIO/agora-rtc-web/tree/main/projects/quick-demo-react) but that runs into an Agora-RTE-Extension--1.2.4.tgz not found 404 error when running pnpm i.

Any ideas on how to get the Vite build working?

How to share the group call directly to Youtube Stream?

I have tried to follow this example. But sadly it is telling nothing about exact instruction for Youtube stream.

I also tried to implement some of this methods on client but getting error. Not working at all.

Can anyone give me any straight forward exmple to pass the group call stream directly to Youtube stream?

React 18

Hello,

I have tested this React 18.2.0 and there is some functionality that is broken. Specifically muting and disabling video. This is fixed when I downgrade my application to React 17.0.2.

Can't get remote user with audio and video muted.

@EkaanshArora
How to know if the user is in channel who has muted both audio and video? Is there any api to get all remote users in a channel in rtc mode.

I got the solution while going through your docs.

client.on("user-joined", (user) => {}) => this will be triggered while joining gives all remote clients .

Video gets cropped

The video gets cropped for different window sizes:

For a wide window:
a

For a narrower window:
b

I have used the same code snippet from the examples.

In this case, the user can see different parts of the stream depending on their window sizes. How do I resolve this?

associating user with video

I'm a student trying with my team to build a video chat app with support for a simple game. We need to divide the users into two teams and sort them on the screen. We can't figure out a way for the callers to identify themself so that we can associate it with our user models. Please help if you can! Any advice would be super appreciated!

How to mute unmute other remote users?

Hey, I am using this wrapper for group video calling in my project, and I want to give an option to users where they can mute and unmute other users. Any idea how can i do that in this wrapper.

TypeScript issue on AgoraVideoPlayer

When publishing a export const useCreateScreenVideoTrack = createScreenVideoTrack(createScreenVideoTrackConfig);

and using

<AgoraVideoPlayer
  style={{ height: "100%", width: "100%" }}
  videoTrack={screenVideoTrack}
/>

I get this error

(property) videoTrack: ICameraVideoTrack | ILocalVideoTrack | IRemoteVideoTrack
Type 'ILocalVideoTrack | [ILocalVideoTrack, ILocalAudioTrack]' is not assignable to type 'ICameraVideoTrack | ILocalVideoTrack | IRemoteVideoTrack'.
  Type '[ILocalVideoTrack, ILocalAudioTrack]' is not assignable to type 'ICameraVideoTrack | ILocalVideoTrack | IRemoteVideoTrack'.ts(2322)
index.d.ts(183, 5): The expected type comes from property 'videoTrack' which is declared here on type 'IntrinsicAttributes & ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement> & { ...; } & { ...; }'

Camera disabling on Component Unmount

I have a case when i need to switch off WebCamera after user leave chat page. Switched on green light is annoying and scares my users.

So i've tried:

// ... somewhere in my Session component
  const useMicrophoneAndCameraTracks = useMemo(
    _ => createMicrophoneAndCameraTracks()
  , [])

  const {
    ready,
    tracks,
    error } = useMicrophoneAndCameraTracks()

// Disable camera on component unmount
useEffect(_ => 
   _ => {
       await client.leave()
       client.removeAllListeners()
       // here i try to disable them
       tracks[0].close()
       tracks[1].close()   
   }
)

But the tracks are also null... because:

Somewhere in index.tsx

      return () => {
        tracks = null
      }

... So what is better to create PR or just to make a local fix. And if creating a PR would it be ok i disable tracks manually in Effect?

Video and/or audio often not working in our web app

Our web app uses this library for a 1-to-1 video chat, and we are very often observing video and/or audio not working in our web app. We have the following requirements:

  • Agora Cloud Proxy in Force TCP mode
  • Initially not publishing audio, and then publishing audio later (when a chat agenda modal is dismissed -- the modal's visibility status is handled in Redux)

Are we missing anything important in the Agora client lifecycle?

import React, { useState, useEffect, useCallback, useRef } from "react";
import AgoraRTC, {
  AgoraVideoPlayer,
  createClient,
  createMicrophoneAndCameraTracks,
  ClientConfig,
  IAgoraRTCRemoteUser,
  IMicrophoneAudioTrack,
  ICameraVideoTrack,
  AREAS,
} from "agora-rtc-react";

import { useDispatch, useSelector } from "react-redux";
import { ActionCreators } from "actions";

...

const config: ClientConfig = {
  mode: "rtc",
  codec: "vp8",
};
const useClient = createClient(config);
const useMicrophoneAndCameraTracks = createMicrophoneAndCameraTracks();

...

export default function Chat() {
  const dispatch = useDispatch();

  const chatAgendaModalVisible = useSelector(
    (state: any) => state.chatAgendaModalVisible
  );
  const [chatStarted, setChatStarted] = useState(false);
  const [chatEnded, setChatEnded] = useState(false);
  const [agoraRemoteUsers, setAgoraRemoteUsers] = useState<
    IAgoraRTCRemoteUser[]
  >([]);

  const agoraClient = useClient();
  const { ready, tracks } = useMicrophoneAndCameraTracks();
  const readyRef = useRef<boolean>();
  readyRef.current = ready;
  const tracksRef = useRef<[IMicrophoneAudioTrack, ICameraVideoTrack] | null>();
  tracksRef.current = tracks;

  const _handleInitAgoraRtcEngine = async () => {
    try {
      AgoraRTC.setArea({ areaCode: [AREAS.NORTH_AMERICA] });
      agoraClient.startProxyServer(5); // Force TCP Cloud Proxy mode
      agoraClient.on("connection-state-change", (state) => {
        console.log("event connection-state-change", state);
        if (state === "CONNECTED") {
          setHasSelfJoinedChannel(true);
        }
      });
      agoraClient.on("user-published", (user, mediaType) => {
        console.log("event user-published", user, mediaType);
        const subscribe = async () => {
          await agoraClient.subscribe(user, mediaType);
          if (mediaType === "video") {
            setAgoraRemoteUsers((prevUsers) => {
              return [...prevUsers, user];
            });
            setHasPartnerJoinedChannel(true);
          }
          if (mediaType === "audio") {
            user.audioTrack?.play();
          }
        };
        subscribe();
      });
      agoraClient.on("user-unpublished", (user, type) => {
        console.log("event user-unpublished", user, type);
        if (type === "video") {
          setAgoraRemoteUsers((prevUsers) => {
            return prevUsers.filter((u) => u.uid !== user.uid);
          });
        }
        if (type === "audio") {
          user.audioTrack?.stop();
        }
      });
      agoraClient.on("user-left", (user) => {
        console.log("event user-left", user);
        setAgoraRemoteUsers((prevUsers) => {
          return prevUsers.filter((u) => u.uid !== user.uid);
        });
      });
      agoraClient.on("is-using-cloud-proxy", () => {
        console.log("is-using-cloud-proxy");
      });
      await agoraClient.join(
        process.env.REACT_APP_AGORA_APP_ID || "",
        matchObject.agoraChannel,
        matchObject.agoraToken,
        userId
      );
    } catch (error) {
      console.log("_handleInitAgoraRtcEngine error", error);
    }
  };

  const _handlePublishTrack = async (type: "audio" | "video") => {
    if (readyRef.current && tracksRef.current) {
      const trackIndex = type === "audio" ? 0 : 1;
      await tracksRef.current[trackIndex].setMuted(false);
      await agoraClient.publish(tracksRef.current[trackIndex]);
    }
  };

  const _handleCloseChat = useCallback(async () => {
    if (!chatEnded) {
      setChatEnded(true);
      await agoraClient.leave();
      agoraClient.removeAllListeners();
      if (tracksRef.current) {
        for (const track of tracksRef.current) {
          track.close();
        }
      }
      agoraClient.stopProxyServer();
    }
  }, [chatEnded, agoraClient, _handleClearAllTimers]);
...
  useEffect(() => {
    const initChat = async () => {
      await _handleInitAgoraRtcEngine();
    };
    initChat();
    return () => {
      _handleCloseChat();
    };
  }, []);

  useEffect(() => {
    // As soon as tracks are available and ready, start publishing video
    if (readyRef.current && tracksRef.current) {
      _handlePublishTrack("video");
    }
  }, [readyRef.current, tracksRef.current]);

  useEffect(() => {
    // Disable initial agenda modal and turn audio on
    if (chatStarted && !chatAgendaModalVisible) {
      const publishAudio = async () => {
        if (readyRef.current && tracksRef.current) {
          await tracksRef.current[0].setMuted(false);
          await agoraClient.publish(tracksRef.current[0]);
        }
      };
      publishAudio();
    }
  }, [
    chatAgendaModalVisible,
    chatStarted,
    readyRef.current,
    tracksRef.current,
  ]);

  ...

  return (

  ...

        {agoraRemoteUsers.length > 0 && agoraRemoteUsers[0]?.videoTrack ? (
          <AgoraVideoPlayer
            videoTrack={agoraRemoteUsers[0].videoTrack}
            style={{ height: "100%", width: "100%" }}
          />
        ) : null}

  ...

        {readyRef.current && tracksRef.current ? (
          <AgoraVideoPlayer
            videoTrack={tracksRef.current[1]}
            style={{ height: "100%", width: "100%" }}
          />
        ) : null}

  ...

  )
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.