Coder Social home page Coder Social logo

agorawebsdk-ng's Introduction

AgoraWebSDK NG

AS Web NG SDK have been offically released from here. This Demo Project has been deprecated and archived. We will stop maintain it. Please look at https://github.com/AgoraIO/API-Examples-Web for latest Agora Web SDK Samples.

English | 简体中文

The Agora Web SDK NG is the next-generation SDK of the current Agora Web SDK, enabling audio and video real-time communications based on Agora SD-RTN™ and implementing scenarios such as voice-only calls, video call, voice-only interactive broadcast, and video interactive broadcast. The Agora Web SDK NG makes full-scale refactoring to the internal architecture of the Agora Web SDK and improves usability of APIs.

npm install agora-rtc-sdk-ng --save

Documentation Website

We provide some basic demos. For the online website, check out here. For the source code, check out here.

If you have some problems when using the Agora Web SDK NG, or have any suggestions, you can post new issue in this repo and we will reply as soon as possoble.

Overview

For detailed introduction and documentation, please go to Documentation Website. Here we briefly introduce the features of the Agora Web SDK NG:

  • Support Typescript
  • Using ES6 Promise
  • Track-based media objects

Here is the sample code to join the channel and publish local media automatically

import AgoraRTC from "agora-rtc-sdk-ng"

const client = AgoraRTC.createClient()

async function startCall() {
  await client.join("APPID", "CHANNEL", "TOKEN");
  const audioTrack = await AgoraRTC.createMicrophoneAudioTrack();
  const videoTrack = await AgoraRTC.createCameraVideoTrack();

  await client.publish([audioTrack, videoTrack]);
}

startCall().then(/** ... **/).catch(console.error);

agorawebsdk-ng's People

Contributors

disoul avatar ericsyh avatar hahaha44 avatar jinyeqing avatar miclle avatar plutoless avatar smartnav 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

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

agorawebsdk-ng's Issues

RTCPeerConnection.removeTrack does not implement interface RTCRTPSender

Describe the bug

Encountering a certain error while doing setEnabled of localtrack

SDK Logs

You should call enableLogUpload to enable log upload to Agora's Log Server.

Channel: C655-L5fe1

UID: 101

Platform and Browser: Web, Chrome

SDK Version: Agora SDK NG

To Reproduce

Steps to reproduce the behavior:

Trigger setEnabled(true/false) on a published video/audio track
WhatsApp Image 2020-08-06 at 01 01 45

enableDualStream and publish video throws an error on firefox

Hello,

I am trying to publish video & audio stream on firefox with enableDualStream. It throws the below error:

TypeError: l.requestFrame is not a function

I've created this fiddle, which if you open on firefox will show you the same error on console.
Could you please let me know if this is a bug or if I have to do something differently to get the publish working on firefox.

Please note that this happens only if enableDualStream is set and works fine otherwise.

Thanks!

Some feedback

I'm using Agora inside a browser-based game for in-game voice chat. Overall, I really like Agora and Agora Web SDK NG is an easier API than Agora Web SDK – good job!

I have a few points of feedback that I hope is helpful to you.

Bundle size

The minified source is 547 KB, which is large for any library.

I think there are a number of opportunities to reduce bundle size. From looking at the code, you could release 2-3 bundles instead:

  • UMD build
  • CommonJS build
  • ESM build

If you provided a CommonJS or ESM build and then used export & import in your source code to import files, this would make it more eligible for tree shaking. Additionally, for any libraries you use, you'd require them and add them as a dependency in your package.json, rather than inline them into the source.

Different companies use Agora differently – some might use the DOM-related functionality (showing a video stream, adding an <audio /> tag, etc) and some might not. Tree shaking would allow integrators to only import the parts of Agora's SDK that are relevant to their application. This should significantly reduce bundle size for most integrators.

Performance

Agora makes many requests, seemingly for analytics rather than VOIP. There is a meaningful performance cost to sending lots of requests, and browsers have connection limits for how many requests they send at a time per tab.

If the only thing happening on the page is VOIP, then its probably fine. But, if there's lots of other stuff too (e.g. rendering a 3D game), it can cause performance problems.

It would be great if integrators could disable analytics and voice quality-related data collection.

Additionally, allocating new objects or pushing onto arrays inside of setInterval (or any timer) is an easy way to trigger Garbage Collection and briefly freeze the webpage. If you reuse objects (where possible) inside of timers, it will improve performance.

CORP & COEP

Currently, this SDK does not work when using Cross-Origin-Resource-Policy & Cross-Origin-Embedder-Policy together. Requests to Agora's servers are blocked by the browser.

These headers enable SharedArrayBuffer in Firefox 79 and soon will be required by Chrome to use SharedArrayBuffer too.

These standards are pretty new, so it makes sense why this wouldn't be supported yet. I'm honestly not sure of a solution to this, unless it involves proxying.

Audio Context

Web browsers cannot create many AudioContext objects per page without stuff breaking. It would be great if the SDK allowed a developer to pass in their own AudioContext object, instead of creating one during initialization.

How to handle multiple tracks

Hey,

I have a use case where I need to play an audio track created from createMicrophoneAudioTrack and also would like to have another track playing simultaneously created with createBufferSourceAudioTrack is this possible to have those two audio tracks to publish and play simultaneously? If not what would you suggest for implementing such a use case?

Thanks in advance

Webapp Integration

hey, I am trying to integrate agora into my web app. I want it to be one to one. I am not being able to do it. Third-person can still join in and then the quality drops drastically. Can anyone help me fix it

How to know that the local video/audio track is not enabled?

Hi, so in our web app there an option to toggle on and off the local video.

Could you tell me how to get the current state of the local track (I need that for display placeholder/user avatar)
I tried out the localTrack.isPlaying but it doesn't seem work.

Thank you

Q: Cloud-recording layout

Hi, 👋 We are trying to record the channel using cloud-recording. We plan to record the channel using a custom layout that places the active-speaker center of the canvas, custom thumbnail size, watermark, etc. Other layout types do not fit with we want.

We have read the entire documentation including RTMP-Converter, Cloud-recording, On-premise recording. We want to know who is joined the channel, who is speaking, who has disabled the camera etc. on the backend side since giving this responsibility to the client (WEB) is not reliable because of the connection issues, bad network connection, etc. When we try to give this privilege to someone on the channel and when this client disconnects, our layout will not be updated (still recording) or we have to assign this role, someone, on the channel again. This is not meaningful IMHO.

We've found something on the on-premise recording . If we use on-premise recording we can get the client events on the backend-side (node).

Here is the question; How can we listen to the channel events that we want to record on BE side? Is there a webhook or SDK for it without using the on-premise recording product?

I think this issue should not be here but I don't know where I should post it.

Interoperability issue with native sdk

Hey,

Trying to integrate agora-rtc-sdk-ng 0.1.9 and have issues with AgoraRtcEngine_iOS 3.0.1 for ios, while video from web appears on ios device as and sound, web sdk cannot subscribe to video from ios device, therefore no video from ios on the web and no sound from the web, for native rtc engine this is enabled agoraKit?.enableWebSdkInteroperability(true)
video sharing works between ios devices but seems to have issues between native and web.

Was testing it on chrome Version 83.0.4103.61 (Official Build) (64-bit) macos
Iphone X 13.3.1

Could you please give a tip what could be wrong,
Thanks in advance!

createCustomVideoTrack with audio

Calling createCustomVideoTrack with true for withAudio returns a list with two tracks (audio and video) if the user selects to share a browser tab and ticks Share Audio, otherwise fails.

It would be helpful if, instead, createCustomVideoTrack with true for withAudio returned a list containing only the video track rather than an error if user does not tick Share Audio. Then the app could decide if it would like to request audio, but can gracefully fall back to video only for screen share if user does not agree to share audio.

Issue joining a channel when using string uid

Hello!

Thanks for writing this library. I am trying to migrate from the Agora web sdk to this library and am unable to join a channel when using a string uid. Below is a snippet of the code that I am using to join the channel:

await videoClient.join(agora_app_id, channel_id, token_obtained_from_the_server, STRING_USER_ID)

The token_obtained_from_server is being generated by my rails application for the string user_id.

Am getting the following error when trying to join the channel:
code: "CAN_NOT_GET_GATEWAY_SERVER"
message: "AgoraRTCError CAN_NOT_GET_GATEWAY_SERVER: invalid token, authorized failed"

When I analyzed the xhr requests between using agora sdk and this library, the one difference that I see is, the agora sdk passes the key detail: {6: STRING_USER_ID} in the request body for the /api/v1?action=wrtc_gateway , whereas this library does not. Not sure if this is what is causing the issue.

Could you please let me know if this library supports string uid and/or if I have to do anything else to get the client.join working?

Thanks!

The play request was interrupted by a call to pause

Describe the bug

Unable to stream a remote user's track.

SDK Logs

You should call enableLogUpload to enable log upload to Agora's Log Server.

Channel: C662-La1f7

UID: 1140

Platform and Browser: Agora Web SDK NG, Chrome

SDK Version:

To Reproduce

Scenario - 4 people were hosts in live mode.
One person refreshed his screen and joined back.
He was only able to play one stream and the other streams threw an error saying The play request was interrupted by a call to pause

WhatsApp Image 2020-08-02 at 15 49 48

Release 4.0.1 is broken

Hi,
I tried the basicLive demo and this used to work in the previous release across mobile browser and my desktop test environment.

I'm testing between a Chrome browser on iPhone XS and MAC Safari Browser 13.1.1. Two problems:

  1. Join as host on the desktop Safari and join as audience on mobile browser. No audio stream can be received on the mobile browser.

  2. Join as audience on desktop Safari and join as host on mobile Chrome browser. Mobile browser shows error: AgoraRTCError: NOT_UPPORT: cannot find getUserMedia.

Production Ready?

I just wanted to double check that this library is production ready. We have an event on Monday with 500 people where we will be using our app migrated to this new ng library

Custom Video Source not working for canvas.captureStream()

I'm trying to create a MediaStreamTrack from a Canvas element then publish it to a video call. local video track is playing correctly, but other users could not receive the video track. captureStream() from video element works fine though.

Code:

    // ... file from <input type="file"/> 
    var url = URL.createObjectURL(file);
    var img = new Image;
    img.src = url;

    img.onload = () => {
        const canvas = document.createElement('canvas');
        canvas.width = 1280;
        canvas.height = 720;
        const ctx = canvas.getContext('2d');
        ctx.drawImage(img, 0, 0);
        var stream = canvas.captureStream();
        var customStream = stream.getVideoTracks()[0];

        // ...createClient
        // ...client.join
        // ...createAudioTrack
        this.localVideoTrack = AgoraRTC.createCustomVideoTrack({
            mediaStreamTrack: customStream,
        });

        this.client.publish([this.localVideoTrack, this.localAudioTrack]);
    }

Massive echo in the audio just throughout the call

Describe the bug

As soon as I join the channel and create createMicrophoneAudioTrack, there is a massive echo issue and that makes it impossible to continue the call. This is happening consistently on Mac + Chrome with just one user in the channel. No other video calling website or software is open at the same time.

Channel: C88-L5af1

UID: 101

Platform and Browser: Macbook + Google Chrome 84.0.4147.89 (Official Build)

SDK Version: Agora NG 4.0.1

Cannot using SDK with Next.js for `window is not defined`

Reproduce Repo: https://github.com/matamatanot/agoraTest Deleted
I used the official template and simply added 2 lines in index.js.

import AgoraRTC from "agora-rtc-sdk-ng";
console.log(AgoraRTC);
ReferenceError: window is not defined

This error happened while generating the page. Any console logs will be displayed in the terminal window.

If you can, please consider adding example code snippet to the official Next.js example folder.
There are many examples that use external js libraries.

Chrome Version 85 beta issue

Hi,

Its not really a bug yet, but it may well be soon if not monitored. We are using Chrome Version 85.0.4183.48 (Official Build) beta (64-bit) to be future proof and make sure our apps are working on coming browser releases from day one.
In this Chrome Version 85 the WebSDK NG (and also previous SDK) creates multiple connections, which leads to Firewall blocking all network traffic with error Maximum sessions per host (1000) was exceeded after about 20 seconds. It also makes API reconnects all the time during a call and leads to many records in Agora Analysts for one call.

It works fine on Official Build Version 84.0.4147.105 (Official Build) (64-bit).

Thanks.

AbortError: The play() request was interrupted by a new load request. https://goo.gl/LdLk22

Getting following error:

AbortError: The play() request was interrupted by a new load request. https://goo.gl/LdLk22

It leads to getting audio but doesn't create a video player. The error itself is quite intermittent but has occurred quite a few times now.

From the link: https://goo.gl/LdLk22, mentioned with error, I can see that play method can be a promise and we can do something like:

 var playPromise = video.play();

  if (playPromise !== undefined) {
    playPromise.then(_ => {
      // Automatic playback started!
      // Show playing UI.
    })
    .catch(error => {
      // Auto-play was prevented
      // Show paused UI.
    });
  }

Client.join timeout on Microsoft Edge 44.19041.1.0

Hi,

I am trying to use NG SDK and facing issue on Microsoft Edge.

I am not able to connect and connection always fails with a timeout. I can see the same issue with the NG SDK Demo located at https://agoraio-community.github.io/AgoraWebSDK-NG/demo/basicVideoCall/index.html

Is Edge supported in new SDK and future plans or is there a workaround available to fix this?

I am using AgoraRTC.checkSystemRequirements() to find out compatibility and I am getting "true" from this method on the Edge browser.

Below is the console log from https://agoraio-community.github.io/AgoraWebSDK-NG/demo/basicVideoCall/index.html
------------------------------------------------------------------------------------
HTML1300: Navigation occurred.
index.html (1,1)

00:00:56:676 Agora-SDK [INFO]: browser compatibility [object Object] [object Object]

00:01:24:586 Agora-SDK [INFO]: [c5f53] Initializing AgoraRTC client v0.1.9, mode: rtc, codec: h264
AgoraRTC_N.js (5,143243)

00:01:24:586 Agora-SDK [DEBUG]: [c5f53] connection state change: DISCONNECTED -> CONNECTING
AgoraRTC_N.js (5,143243)

00:01:24:587 Agora-SDK [DEBUG]: Flush cached event reporting: 1
AgoraRTC_N.js (5,143243)

00:01:24:588 Agora-SDK [DEBUG]: [c5f53] Connect to choose_server: https://webrtc2-ap-web-1.agora.io/api/v1
AgoraRTC_N.js (5,143243)

00:01:24:589 Agora-SDK [DEBUG]: [c5f53] Connect to choose_server: https://webrtc2-ap-web-2.agoraio.cn/api/v1
AgoraRTC_N.js (5,143243)

00:01:24:590 Agora-SDK [DEBUG]: GetUserMedia {"audio":{}}
AgoraRTC_N.js (5,143243)

00:01:24:592 Agora-SDK [DEBUG]: GetUserMedia {"video":{}}
AgoraRTC_N.js (5,143243)

WEBAUDIO17060: The given destination is not connected.
AgoraRTC_N.js (5,189655)

00:01:26:303 Agora-SDK [DEBUG]: start check mediaStreamTrack resolution [object MediaStreamTrack]

00:01:26:350 Agora-SDK [DEBUG]: [c5f53] Connect to choose_server: https://webrtc2-ap-web-3.agora.io/api/v1
AgoraRTC_N.js (5,143243)

00:01:26:350 Agora-SDK [DEBUG]: [c5f53] Connect to choose_server: https://webrtc2-ap-web-4.agoraio.cn/api/v1
AgoraRTC_N.js (5,143243)

00:01:26:524 Agora-SDK [DEBUG]: get track resolution: 640 x 360 [object MediaStreamTrack]

00:02:24:598 Agora-SDK [DEBUG]: Client.join timeout

exception 2001 fired for too long

Problem:
The exception 2001 AUDIO_INPUT_LEVEL_TOO_LOW is shown for 30 seconds before a newly-joined user could be heard by others in the same channel.

Console log:
image

How to reproduce:

  1. Start a video call using the Web SDK NG.
  2. Ask ten people to join the call one-by-one.
  3. 7 out of 10 people report that they cannot be heard by others during the first 30 seconds since they join.
  4. After 30 seconds, the exception 2001 goes away.

Chrome v74+ screenshare of browser tab with audio should be supported on Mac OS

Mac OS 10.15, Chrome v83, AgoraWebSDK-NG v4.0.1.

Using createScreenVideoTrack with withAudio set to auto does not show the Share Audio checkbox in the Chrome dialog to select a tab.

With withAudio set to enable an error occurs: Agora-SDK [ERROR]: AgoraRTCError NOT_SUPPORT: your browser or platform is not support share-screen with audio

However, on the same Mac OS and Chrome versions, Google Meet web app shows the Share Audio checkbox and is able to share audio stream from selected tab. MDN browser compatibility also indicates Chrome v74+ on Mac OS should be able to share audio from a tab. https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia#Browser_compatibility

screenshare popup failed to open in poor network

  • Device: MacOS 10.15.5
  • Browser: Chrome Version 83.0.4103.106 (Official Build) (64-bit)
  • SDK-NG: 0.1.9
  • Problem:
  1. Start a basic video call
  2. Change Network to poor condition, say, 2G (uplink 10kb/s, downlink 10kb/s, 500 ms latency)
  3. Click "Start Screenshare" button
  4. Expected: a popup window opens to choose which screen to share
    Actual: no popup window
  5. Change Network back to default (wifi)
  6. The popup window immediately appears
  • Console log during step 4:
    image

  • Question: why does the screenshare popup get stuck somewhere and fail to show up when the network is slow?

Publish useAgora package to npm .

Thank for Sharing New React Demo!
That's exactly NG! There are Functional Components and React Hooks.

If possible, Please consider publishing useAgora hooks to npm package.
To establish both operability and reusability.

Echo issue and failed to close media track.

Hi, i‘m having problem with the following issues and wish you can help me and shed some light upon them:

  1. I'm getting loud echos and noises when duplicating pages to test.
    While checking your demo page, I found there is no noice or echo at all, yet I failed figure out the difference between our ways to use audiotrack.

in your demo, you are just using
localTracks.audioTrack = AgoraRTC.createMicrophoneAudioTrack() to create audiotrack.
I'm using the same way to create audio track and have tried using audio config to cancel noise and echo, but that doesn't work.
rtc.localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack({AEC: true, ANS: true, AGC: true});
And after the audio track gets created, I'm only publishing it, and not playing it at local, so the audioTrack.play() only gets called in the user-publish event handler.

  1. I'm having trouble close the track and releasing the device bound to it.
    await rtc.client.unpublish(); rtc.localVideoTrack.stop(); rtc.localAudioTrack.stop(); rtc.localVideoTrack.close(); rtc.localAudioTrack.close();
    Yet the media play stopped while the devices are still in use.

Could you please give me some advice upon these issues? Thank you.

Getting error AgoraRTCError INVALID_PARAMS

Whenever I am trying to subscribe the client then this error is coming, previously this was working perfect. It spoiled my demo.

message: "AgoraRTCError INVALID_PARAMS: mediaType can only be set as ["audio","video"]"

DOM related performance issue

Describe the bug

When you call the setEnabled(true)helper of localVideoTrack the SDK attaches additional video and canvas element to the dom. For example, if you enabled the dualStreamMode and call the setEnabled function more than once you will see the nx2 elements in the document.

Platform and Browser:
-- Browsers that support the dualStreamMode

SDK Version:
4.0.1

To Reproduce

  1. Enable dual-stream mode and Publish a new video track
  2. Toggle the video by calling the setEnabled function more than once
  3. Open the developer console scroll to the bottom
  4. You will see nx2 video/canvas elements

Additional context

To improve the performance if you have a chance to use the offscreencanvas it might be better than canvas API 👋

Also, Can you have a guide to improve the device CPU and Memory usage?

Safari Crashes on streaming

Describe the bug

When a user joined streaming from safari, the entire browser froze.

SDK Logs

You should call enableLogUpload to enable log upload to Agora's Log Server.

Channel: C671-Lb437

UID: 101 (first participant, chrome), 1404 (joins via safari, crash)

Platform and Browser:

SDK Version: Agora Web SDK NG

To Reproduce

Steps to reproduce the behavior:

  1. Go to chrome and join Channel and start streaming (live mode, role is host)
  2. Go on safari as second user (live mode, role is audience)
  3. Change role of 2nd audience to host and start streaming
  4. Safari freezes, also causes chrome to freeze a bit

Frequent issue of no sound or black video screen

I am using Agora client settings for interactive video broadcasting:

{ mode: "live", codec: "vp8" }

And to reduce bandwidth usage, I am using the following camera encoder profile:

{ encoderConfig: "180p_1" }

My users are frequently complaining of no sound or black video screen.

I am using your demo Agora React hook code.

Is the Agora client so unstable such that sometimes the published user does not get registered on the playback side?
What is the recommended way to ensure that the playback client can always consistently receive both published video and audio?

Known issue about `SEND_AUDIO_BITRATE_TO_LOW`

How to reproduce

If you create and publish your microphone audio track without any user interaction, the remote user may not hear you. In this case, the console will print some logs like SEND_AUDIO_BITRATE_TO_LOW and AUDIO_INPUT_LEVEL_TOO_LOW.

And once you interact with the webpage, the remote user will hear you.

Root cause

Agora Web SDK NG uses the AudioContext API to do some audio pre-processing by default. However, the AudioContext is restricted by the browser's autoplay policy. If user has not interacted with your webpage, the AudioContext will not run. So there is no audio data produced from the SDK's pre-processing module in this case.

How to avoid

We will fix this issue in v4.0.2, and it will be released next month.

For now, we recommend that you should ensure that the user has interacted with the webpage before the audio track is published. For example, the user is required to click the accpet or confirm button to start a call.

Not getting "user-unpublished" event when unpublishing a local video track

Hello there,

I am trying to unpublish the local video track with the below code to mute the video and switch off the camera indicator:

client.unpublish([localVideoTrack])
localVideoTrack.close()
localVideoTrack = null

When I execute the above code, the video stops for the local user as expected but on the remote users end, the video freezes and I am not getting a "user-unpublished" event callback. I've registered for the event on the remote users end with the following code:

client.on('user-unpublished', (user, mediaType) => {
console.log('unpublished', user, mediaType)
})

When I refresh the page on the remote users end, I can see the above console log statement though.
Could you please let me know if I have to do something else to get the callbacks working?

Thanks!

Issue in Re initializing connection after close()

I am currently working on a demo where I can make video and audio mute options.

API already provides mute APIS but it doesn't provide video mute API which also closes Camera light.

From this link, I see it is possible with this SDK but when I try to re-init(publish) video stream after close() method, I don't get any user-publish event callback.
https://docs.agora.io/en/faq/web_camera_light.

I also intermittently get warning "SDK [WARNING]: [e0540] no need to update" where the video bool flag is set to false. THE NG SDK doesn't takes video/audio/screen bools from anywhere in code. As I understand, we could pass these option in agora-sdk

From logs, I can see that video track publishes but there is no effect on the viewer end


On further debugging, I noticed:

await this.client.unpublish([this.video])

neither throws any error nor calls any unPublishCallback for recievers

Usage with React + TypeScript

Hello.

I love this SDK. I can do everything I could do with the older SDK with less than half the same amount of code.

I was wondering if I could show my current solution to using this SDK with React and TypeScript and perhaps get some feedback and your thoughts on whether or not it's a good solution.

First, I create my own IStream interface containing two properties:

interface IStream {
    owner: string | number;
    mediaStream: MediaStream
}

I set my component's state to be an array of that interface:

const [streams, setStreams] = useState<IStream[]>([]);

Inside the callback/handler to user-published, where I have access to user and mediaType, I map over the provided tracks and add them to my IStream state:

const potentialAgoraTracks: (IRemoteTrack | undefined)[] = [user.audioTrack, user.videoTrack];

const mediaStreamTracks: MediaStreamTrack[] = potentialAgoraTracks
    .filter(track => track !== undefined)
    .map(track => track!.getMediaStreamTrack());

const owner = user.uid;
const mediaStream = new MediaStream(mediaStreamTracks);

setStreams(currentStreams => [...currentStreams, { owner, mediaStream }]);

That then makes it really easy to remove streams in user-unpublished:

setStreams(
    currentStreams => currentStreams.filter(currentStream => currentStream.owner !== user.uid)
);

The full code for my component is thus:

interface IRTC {
    client: IAgoraRTCClient | null;
}

interface IOptions {
    appID: string;
    channel: string;
    token: string;
}

interface IStream {
    owner: string | number;
    mediaStream: MediaStream;
}

type MediaType = 'audio' | 'video' | 'all';

const AgoraRoomNG: React.FC = (props) => {
    const [streams, setStreams] = useState<IStream[]>([]);

    const rtc: IRTC = {
        client: null
    };

    const options: IOptions = {
        appID: '',
        channel: 'test',
        token: ''
    };

    useEffect(() => {
        rtc.client = AgoraRTC.createClient({ mode: 'live', codec: 'vp8' });

        const onUserPublished = async (user: IAgoraRTCRemoteUser, mediaType: MediaType) => {
            if (!rtc.client)
                throw new TypeError('Client not defined.');

            await rtc.client.subscribe(user);

            const potentialAgoraTracks: (IRemoteTrack | undefined)[] = [user.audioTrack, user.videoTrack];

            const mediaStreamTracks: MediaStreamTrack[] = potentialAgoraTracks
                .filter(track => track !== undefined)
                .map(track => track!.getMediaStreamTrack());

            const owner = user.uid;
            const mediaStream = new MediaStream(mediaStreamTracks);

            setStreams(currentStreams => [...currentStreams, { owner, mediaStream }]);
        };

        const onUserUnpublished = async (user: IAgoraRTCRemoteUser, mediaType: MediaType) => {
            setStreams(currentStreams => currentStreams.filter(currentStream => currentStream.owner !== user.uid));
        };

        rtc.client.on('user-published', onUserPublished);
        rtc.client.on('user-unpublished', onUserUnpublished);

        return () => {
            rtc.client?.off('user-published', onUserPublished);
            rtc.client?.off('user-unpublished', onUserUnpublished);
        };
    }, [rtc.client]);

    const onJoinClick = async (role: 'host' | 'audience') => {
        if (!rtc.client)
            throw new TypeError('Client not defined');

        rtc.client.setClientRole(role);

        const uid = await rtc.client.join(options.appID, options.channel, options.token, null);

        if (role === 'host') {
            const videoTrack = await AgoraRTC.createScreenVideoTrack({}, false);

            setStreams(currentStreams => [...currentStreams, { 
                owner: uid, 
                mediaStream: new MediaStream([videoTrack.getMediaStreamTrack()])
            }]);

            await rtc.client.publish([videoTrack]);
        }
    };

    return (
        <div>
            <Header/>
            <div className="room-container">
                <StreamContainer
                    mediaStreams={streams.map(stream => stream.mediaStream)}
                    containSourceOnly={true}
                />
            </div>
            <Footer joinCall={onJoinClick} leaveCall={() => null}/>
        </div>
    );
};

export default AgoraRoomNG;

The StreamContainer component just accepts an array of MediaStreams and creates an individual video element for each.

Thanks for your time.

Audio+Video Lag

We switched our production app from the old sdk to the ng sdk. We never noticed a mismatch in audio and video tracks with the old sdk, but now we see that pretty often. Is there something we can do to better handle that?

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.