Skip to content

2.32.1 customisations#2

Open
nick-vasic wants to merge 7 commits into
2.32.1from
2.32.1-customisations
Open

2.32.1 customisations#2
nick-vasic wants to merge 7 commits into
2.32.1from
2.32.1-customisations

Conversation

@nick-vasic

Copy link
Copy Markdown
Owner

Key differences from release/0.21.1 port:

Android

Legacy added a duplicate OTScreenCapturerMediaProjection; current port folds that behaviour into existing OTScreenCapturer.java.
Reason: current branch already wires OTScreenCapturer(this) from Kotlin new-architecture publisher code, so a second capturer class would be unused unless we changed more call sites.

Legacy changed OTSessionManager.java; current branch has no OTSessionManager.java.
Reason: current architecture moved publisher creation into OTRNPublisher.kt, so the equivalent integration point is the existing capturer constructor path.

Legacy app expected Branz to declare activity/service. Current port internalises declarations in both Android manifests and the Expo plugin.
Reason: the library should be self-contained for bare RN and Expo/prebuild consumers.

Legacy service recreated the virtual display on rotation. Current port resizes the existing VirtualDisplay and swaps the ImageReader surface.
Reason: Android 14+ rejects multiple createVirtualDisplay() calls on the same MediaProjection token.

Legacy used startForeground() with a bare NotificationCompat notification. Current port uses ServiceCompat.startForeground() with FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION, plus androidx.core.
Reason: target SDK is now 36, so foreground-service type enforcement matters.

Legacy used a static captureActivity.stopProjection(). Current port stops the service directly.
Reason: static Activity references are fragile/leaky, and stop should not start a new foreground service.

iOS

Legacy converted ReplayKit sample buffers into UIImage/CGImage, stored latestImage, then fed a timer-based frame pipeline. Current port feeds CVImageBufferRef directly to consumeImageBuffer.
Reason: current iOS implementation already uses the newer OpenTok consumeImageBuffer path, so image conversion is unnecessary and wasteful.

Legacy retained the old timer/padding/OTVideoFrame flow. Current port removes it.
Reason: ReplayKit already provides timed CMSampleBuffer video frames with presentation timestamps.

Legacy exposed ReplayKit state in the header (recorder, latestImage, lastCaptureMillis). Current port keeps those private.
Reason: they are implementation details and not part of the public capture API.

Current port adds availability checks, start/stop error logging, and timestamp fallback.
Reason: safer behavior around ReplayKit availability and malformed/missing timestamps.

Net: this is not a literal cherry-pick. It preserves the legacy intent, MediaProjection on Android and ReplayKit on iOS, but adapts it to the current new-architecture codebase and current Android/iOS capture APIs.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 46f0932592

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +305 to +306
if (previousBitmap != null && !previousBitmap.isRecycled()) {
previousBitmap.recycle();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Stop recycling shared frame bitmaps in producer thread

ImageAvailableListener recycles previousBitmap immediately after swapping ScreenCaptureImageActivity.latestBitmap, but OTScreenCapturer.newFrame reads that same shared bitmap on another thread and then calls getPixels(...) without synchronization. If the producer swaps and recycles between the consumer’s isRecycled() check and getPixels, screen sharing can crash with a recycled-bitmap access or emit corrupted frames under normal frame churn.

Useful? React with 👍 / 👎.

Comment on lines +76 to +77
Intent intent = new Intent(context, ScreenCaptureMediaProjectionService.class);
context.stopService(intent);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Clear cached frame when stopping screen capture

stopCapture() only stops the service, but the static ScreenCaptureImageActivity.latestBitmap cache is left intact, and OTScreenCapturer.newFrame will continue to publish whatever bitmap remains in that field whenever capturing is true. After a stop/restart (especially if the next permission prompt is denied), this can publish stale frames from a prior session and keep reporting capture as active without a live projection.

Useful? React with 👍 / 👎.

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.

2 participants