Agora screen sharing in electron with react, Gives permission denied

All we need is an easy explanation of the problem, so here it is.

I am building an electron-react app with Agora for calls. I am trying to implement the screen sharing feature.

As described in the following documentation I tried requesting screen sharing.
https://docs.agora.io/en/video/screensharing_web_ng?platform=Web#screen-sharing-on-electron

But I am getting the following error

AgoraRTCError PERMISSION_DENIED: NotAllowedError: Permission denied

I tried invoking the same function AgoraRTC.createScreenVideoTrack in react and electron but the result was the same.

How do I get permission to share the screen in electron with agora?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

After some research, I found the electron way of doing it.

  • First I request to share the screen.
const turnScreenSharingOn = async () => {
  const sources = await window.electron.media.getDesktopSources();
    setScreenSources(sources);
    setScreenSharePopupVisible(true);
  };
  • window.electron.media.getDesktopSources() is a electron preload function that fetches the screen sources.
    getDesktopSources: async () =>
      await desktopCapturer
        .getSources({
          types: ['window', 'screen'],
        })
        .then((sources) =>
          sources.map((source) => ({
            id: source.id,
            name: source.name,
            appIconUrl: source?.appIcon?.toDataURL(),
            thumbnailUrl: source?.thumbnail
              ?.resize({ height: 160 })
              .toDataURL(),
          }))
        )
  • Once I have the sources I show the popup from which I choose the source and pass the source id to the next function.
  const onScreenChoose = async (sourceId: string, cb?: () => void) => {
    const stream = await navigator.mediaDevices.getUserMedia({
      audio: false,
      video: {
        mandatory: {
          chromeMediaSource: 'desktop',
          chromeMediaSourceId: sourceId,
        },
      } as MediaTrackConstraints,
    });
    const track = stream.getVideoTracks()[0];
    const screenTrack = AgoraRTC.createCustomVideoTrack({
      mediaStreamTrack: track,
    });
    window.agora.screenTrack?.setEnabled(false);
    window.agora.screenTrack = screenTrack;

    setScreenTrack(screenTrack);
    await screenShareClient.publish(screenTrack);
    setScreenSharePopupVisible(false);
    cb?.();
  };

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

Leave a Reply