Skip to content

fix(recorder): support for "ready to record" signal#2169

Open
oliverlaz wants to merge 3 commits intomainfrom
recording-readiness
Open

fix(recorder): support for "ready to record" signal#2169
oliverlaz wants to merge 3 commits intomainfrom
recording-readiness

Conversation

@oliverlaz
Copy link
Member

@oliverlaz oliverlaz commented Mar 20, 2026

💡 Overview

Ensure Skool's layout can signal recording readiness.
Ref: https://github.com/skooldev/skool-stream-layout/pull/4

🎫 Ticket: https://linear.app/stream/issue/REACT-907/fix-missed-egress-ready-play-event-in-custom-layouts

Summary by CodeRabbit

  • Bug Fixes
    • Improved egress readiness detection for participants with video tracks by checking current playback state and notifying readiness immediately if playback is already active.
    • Layouts now surface readiness notifications to the egress notifier so readiness is reported earlier.
    • Reduced duplicate readiness logs by only logging when readiness state actually changes.

@oliverlaz oliverlaz requested a review from jdimovska March 20, 2026 12:30
@changeset-bot
Copy link

changeset-bot bot commented Mar 20, 2026

⚠️ No Changeset found

Latest commit: 67bcacf

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@oliverlaz oliverlaz changed the title fix: support for "ready to record" signal fix(recorder): support for "ready to record" signal Mar 20, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 20, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 345807ff-4dd0-41df-adfe-0f499e3231e9

📥 Commits

Reviewing files that changed from the base of the PR and between d4df67a and 10931a3.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (1)
  • sample-apps/react/egress-composite/package.json
✅ Files skipped from review due to trivial changes (1)
  • sample-apps/react/egress-composite/package.json

📝 Walkthrough

Walkthrough

Enhanced egress readiness detection by checking video playback state immediately (before the play event), integrated the notify hook into the layout to pass a notifyReady callback, and adjusted hook state updates and conditional logging; package dependency bumped from 1.0.12 to 1.0.13.

Changes

Cohort / File(s) Summary
Layouts (egress readiness)
sample-apps/react/egress-composite/src/components/layouts/egressReady.ts
Updated import path for useNotifyEgressReady; effect now pre-checks <video> element playback state (currentTime > 0, not paused, not ended) and calls notifyEgressReady(true) immediately when appropriate, while preserving existing play listener logic.
Layout integration
sample-apps/react/egress-composite/src/components/layouts/index.tsx
Imported and invoked useNotifyEgressReady in CustomSkoolStreamLayout, passing the returned notifyReady callback into SkoolStreamLayout via a new notifyReady prop.
Hook: state & logging
sample-apps/react/egress-composite/src/hooks/useNotifyEgress.tsx
Changed spyIsReady to use functional state updates (setIsReady(current => ...)) and made console logging conditional to only log when the readiness value actually changes.
Package
sample-apps/react/egress-composite/package.json
Bumped @skooldev/skool-stream-layout dependency from 1.0.12 to 1.0.13.

Sequence Diagram(s)

sequenceDiagram
    participant Layout as CustomSkoolStreamLayout
    participant Hook as useNotifyEgressReady
    participant Video as VideoElement
    participant Egress as EgressNotifier

    Layout->>Hook: invoke hook / register spy
    Hook->>Video: query playback state (currentTime, paused, ended)
    alt Video already playing
        Video-->>Hook: returns playing
        Hook->>Egress: notifyReady(true)
    else Not yet playing
        Hook->>Video: attach 'play' listener
        Video-->>Hook: 'play' event fires
        Hook->>Egress: notifyReady(true)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰
A rabbit peeks at screens that play,
If videos run, I shout hooray!
State updated, logs kept neat,
A gentle hop—egress: complete. 🎥✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding support for a 'ready to record' signal in the recorder functionality, which aligns with the PR's objective of enabling Skool's layout to signal recording readiness.
Description check ✅ Passed The description includes the Overview and Ticket sections as required by the template, providing context about the change and linking to relevant resources. The 'Implementation notes' section is missing but not critical.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch recording-readiness

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
sample-apps/react/egress-composite/src/components/layouts/egressReady.ts (1)

21-30: Good fix for the missed play event scenario.

The immediate playback check correctly handles the case where the video is already playing when the effect runs. The conditions currentTime > 0 && !paused && !ended are appropriate for detecting active playback.

Minor optimization: when isAlreadyPlaying is true, the play event listener on lines 28-29 becomes redundant since readiness is already signaled. Consider returning early to avoid unnecessary listener setup.

♻️ Optional: Skip listener when already playing
     if (isPublishingVideoTrack && videoElement) {
       // video element for participants with video
       const isAlreadyPlaying =
         videoElement.currentTime > 0 &&
         !videoElement.paused &&
         !videoElement.ended;
-      if (isAlreadyPlaying) notifyEgressReady(true);
+      if (isAlreadyPlaying) {
+        notifyEgressReady(true);
+        return; // No need to listen for 'play' event
+      }
       const onPlay = () => notifyEgressReady(true);
       videoElement.addEventListener('play', onPlay, { once: true });
       return () => videoElement.removeEventListener('play', onPlay);
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sample-apps/react/egress-composite/src/components/layouts/egressReady.ts`
around lines 21 - 30, When the immediate playback check in the effect detects
that the video is already playing (using isPublishingVideoTrack, videoElement
and the isAlreadyPlaying condition), return early after calling
notifyEgressReady(true) so you don't add the redundant 'play' event listener
(onPlay) or set up unnecessary cleanup; modify the block around isAlreadyPlaying
to call notifyEgressReady(true) and then return before the
videoElement.addEventListener(...) line to skip listener registration.
sample-apps/react/egress-composite/src/hooks/useNotifyEgress.tsx (1)

33-38: Good use of functional state update pattern.

The functional update setIsReady((current) => ...) correctly avoids stale closure issues and the conditional logging prevents duplicate messages when notifyEgressReady(true) is called multiple times (e.g., from both the immediate check and the play event).

One consideration: the console.log on line 35 will execute in production builds. As per coding guidelines, production logging should be gated behind environment flags.

🔧 Optional: Gate logging behind an environment check
 const spyIsReady = useCallback((value: boolean) => {
   setIsReady((current) => {
-    if (current !== value) console.log('Egress is ready', value);
+    if (current !== value && process.env.NODE_ENV !== 'production') {
+      console.log('Egress is ready', value);
+    }
     return value;
   });
 }, []);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sample-apps/react/egress-composite/src/hooks/useNotifyEgress.tsx` around
lines 33 - 38, The console.log in spyIsReady should be gated so it doesn't run
in production; update the spyIsReady callback (which calls setIsReady) to only
log when a dev/debug flag is enabled (e.g., process.env.NODE_ENV !==
'production' or a dedicated DEBUG/LOGGING feature flag) before calling
console.log('Egress is ready', value); keep the functional state update and
conditional compare but wrap the log behind that environment/flag check so
notifyEgressReady/play-triggered calls no longer emit production logs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@sample-apps/react/egress-composite/src/components/layouts/egressReady.ts`:
- Around line 21-30: When the immediate playback check in the effect detects
that the video is already playing (using isPublishingVideoTrack, videoElement
and the isAlreadyPlaying condition), return early after calling
notifyEgressReady(true) so you don't add the redundant 'play' event listener
(onPlay) or set up unnecessary cleanup; modify the block around isAlreadyPlaying
to call notifyEgressReady(true) and then return before the
videoElement.addEventListener(...) line to skip listener registration.

In `@sample-apps/react/egress-composite/src/hooks/useNotifyEgress.tsx`:
- Around line 33-38: The console.log in spyIsReady should be gated so it doesn't
run in production; update the spyIsReady callback (which calls setIsReady) to
only log when a dev/debug flag is enabled (e.g., process.env.NODE_ENV !==
'production' or a dedicated DEBUG/LOGGING feature flag) before calling
console.log('Egress is ready', value); keep the functional state update and
conditional compare but wrap the log behind that environment/flag check so
notifyEgressReady/play-triggered calls no longer emit production logs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 42d143df-d71a-457c-a4eb-8d382c2e43b1

📥 Commits

Reviewing files that changed from the base of the PR and between af6d0e5 and d4df67a.

📒 Files selected for processing (3)
  • sample-apps/react/egress-composite/src/components/layouts/egressReady.ts
  • sample-apps/react/egress-composite/src/components/layouts/index.tsx
  • sample-apps/react/egress-composite/src/hooks/useNotifyEgress.tsx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant