livekit / components-js

Official open source React components and examples for building with LiveKit.
https://livekit.io
Apache License 2.0
157 stars 72 forks source link

Prevent screen blanking/screensaver #777

Open dmke opened 7 months ago

dmke commented 7 months ago

Describe the problem

On my machine, the screen blanks (and actually locks) after 5min of inactivity (i.e. no mouse or keyboard input). For company policy reasons, I cannot disable that behaviour.

It is a bit of an annoyance, when my monitor goes into sleep mode in the middle of a sentence, as it takes a moment to recover from that...

Describe the proposed solution

Browsers usually prevent screensavers from activating, when they play media (and NoSleep.js promises to provide such a functionality).

I'm not sure why the video/audio tracks of LiveKit itself don't count towards this behaviour.

Speculation I presume this is because the tracks don't actually originate from a user input event, such as a button click? For example, the local video track already exists in the `` prefab, even before I click on the "Join" button. And remote tracks of course are added without user interaction at all.

There's also the Screen Wake Lock API, but Firefox support is missing:

image

Alternatives considered

No response

Importance

nice to have

Additional Information

No response

lukasIO commented 7 months ago

I think whether or not this is desired behaviour would greatly depend on the use case. I'm not sure whether the library (components) is the right place for this. I guess adding a wakelock to github.com/livekit-examples/meet might make sense

dmke commented 7 months ago

That's fine with me :)

I'll try to hook into <PreJoin onSubmit/> and report back.

dmke commented 7 months ago

I've added use-stay-awake[^1] and called preventSleeping in the <PreJoin onSubmit/> callback, and allowSleeping to <LiveKitRoom onDisconnect/>:

export function JoinRoom(props: { token: string, url: string }) {
  const screen = useStayAwake()

  function onJoin(choices: LocalUserChoices) {
    screen.preventSleeping()
  }

  function onLeave() {
    screen.allowSleeping()
  }

  if (preJoinChoices === null) {
    return <PreJoin onSubmit={onJoin} />
  }
  return <LiveKitRoom onDisconnected={onLeave}>
    <VideoConference chatMessageFormatter={formatChatMessageLinks} />
  </LiveKitRoom>
}

AFAICT, this seems to work.

(Here, I've omitted handling of LocalUserOptions and transforming it into RoomOptions and a new Room instance, before passing it to the <LiveKitRoom/>.)

[^1]: The NPM package depends on React v16, but the source code can easily be vendored.

dmke commented 7 months ago

I'll withdraw my previous comment: While the background media inserted by use-stay-awake does indeed play, it doesn't prevent the screen from blanking. I suspect the <PreJoin onSubmit /> callback isn't detected properly as a user-initiated action - maybe this needs to be implemented closer to the click handler of the "Join" button? :thinking:

With Firefox 124 (scheduled for release mid-March) to enable the Screen Wake Lock API by default, would you accept a PR which adds that to the <PreJoin /> component directly (maybe even behind an off-by-default switch)?

lukasIO commented 7 months ago

Have you confirmed that it's working in isolation?

If we were to add screen lock wake, then the livekit/client-sdk-js repo would be the best place for it. However, I'm not sure if this is the right approach. It's unexpected that your screen blanks in the first place while video is being played back.

dmke commented 7 months ago

I don't have hard evidence, just some observations when screen blanking does not occur on my machine:

I do however have quite an old installation of Debian 11/Gnome 3.38.5 which might play into this (upgrading is a problem of finding a bit of time to do so :)).