daily-co / daily-react

React hooks and components to get started with Daily
https://docs.daily.co/reference/daily-react
BSD 2-Clause "Simplified" License
53 stars 16 forks source link

callobject is destroyed at some point after startCamera() since 0.17.0 #29

Closed oponder closed 9 months ago

oponder commented 9 months ago

In my custom react app we use createCallObject and manually manage the callObject lifecycle instead of the newly introduced useCallObject hook.

I can confirm that at 0.16.0 our app works, but at 0.17.0 the callObject gets destroyed at some point after startCamera.

I'd be happy to try and isolate some code and create a repeatable example if this is not enough info.

Our code that sets up the callObject looks like this:

import DailyIframe, {
  DailyEventObjectParticipant,
  DailyEventObjectParticipantLeft,
  DailyEventObjectActiveSpeakerChange,
} from "@daily-co/daily-js";
import getToken from "../../lib/requests/getToken";

export const setupCallObject = async (
  hashedInvitationID: string,
  roomName: string,
  clientID: string,
  userName: string,
  onParticipantJoined: (event?: DailyEventObjectParticipant) => void,
  onParticipantLeft: (event?: DailyEventObjectParticipantLeft) => void,
  onActiveSpeakerChange: (event?: DailyEventObjectActiveSpeakerChange) => void
) => {
  console.log("[session-ui]: Setting up call object");
  const dailyTokenResponse = await getToken(hashedInvitationID, clientID);
  const url = `https://xxxxx.daily.co/${roomName}`;

  let callObject = DailyIframe.getCallInstance();

  if (callObject) {
    console.log("[session-ui]: Daily iframe already exists, leaving meeting.");
    await callObject.leave();
  }

  if (!callObject) {
    callObject = DailyIframe.createCallObject({ strictMode: true });
  }

  callObject.on("participant-joined", onParticipantJoined);
  callObject.on("participant-left", onParticipantLeft);
  callObject.on("active-speaker-change", onActiveSpeakerChange);

  callObject.on("call-instance-destroyed", (e) => {
    console.error("callInstanceDestroyed Event", e);
  });

  callObject.on("error", (e) => {
    console.error("callObjectError Event", e);
  });

  await callObject.startCamera({
    token: dailyTokenResponse.token,
    userName: userName.toString() || "",
    url: url,
    dailyConfig: {
      v2CamAndMic: true,
    },
  });

  await callObject.startLocalAudioLevelObserver(100);
  await callObject.startRemoteParticipantsAudioLevelObserver(100);

  return callObject;
};

Another part of our app then calls callObject.join triggered by the button in our prejoin/haircheck component.

We render the app with the DailyProvider, and initially callObject can be undefined. I thought maybe there is something going on where DailyProvider is doing the destroying, so I also tried not having DailyProvider in the component tree until the callObject is ready to be used, but that didn't seem to do anything.

        {callObject && (
          <DailyProvider callObject={callObject}>
            <ThemeProvider theme={getThemeByName("default")}>{children}</ThemeProvider>
          </DailyProvider>
        )}
        {!callObject && <ThemeProvider theme={getThemeByName("default")}>{children}</ThemeProvider>}
Regaddi commented 9 months ago

Hey @oponder,

this sounds like an unintended side-effect of a subtle bug that was introduced with 0.17.0 and the new external (custom call object) vs. internal (useCallObject) handling. There's already a fix in flight for 0.17.1, which we're working on to release asap.

Keep an eye on our releases and once 0.17.1 is available I'd ask you to try and confirm whether your specific issue is fixed.

Best, Christian

Regaddi commented 9 months ago

0.17.1 is now released!

@oponder do you mind giving this a check?

oponder commented 9 months ago

It's working well for us at 0.17.1 :) Thanks @Regaddi for the speedy release.