npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

crowdplaysdk

v0.4.1

Published

CrowdPlay lossless conversation capture for React Native (iOS). Studio-grade per-participant recording during live video calls, delivered to CrowdPlay automatically.

Readme

crowdplaysdk

CrowdPlay's lossless conversation capture for React Native (iOS). Your app hosts a live video call; every participant's audio (48 kHz / 24-bit unprocessed WAV) and video (1080p30 HEVC) is recorded locally, at full quality, clock-aligned across participants, and delivered to CrowdPlay automatically — uploads retry, resume, and survive crashes.

No media ever crosses the JS bridge. The engine is the same compiled native core (CrowdPlaySDK) our reference app runs; React Native drives it with control calls and receives state events. Recording quality is identical to a fully native app.

Non-technical? Paste this to your AI agent

I'm building this app: <YOUR APP IDEA — e.g., a tutoring app where
students and tutors meet over video>

Build it as a React Native iOS app. For the video-call feature, use the
crowdplaysdk package.

What the app is about — read carefully:
- The app's name, screens, and flows are about MY IDEA above. The SDK
  records calls in the background for CrowdPlay; recording is NOT the
  app's purpose and must not be presented as it. It appears in the UI in
  the SDK's consent screen before joining a call,
  a small REC indicator during the call, join/leave, and a small
  audio-output menu.
- Keep the SDK integration minimal: consent → join/leave → call screen.
  The call screen MUST include a small audio-output menu showing the
  current output device by name (from the 'audioRoute' event) with a
  switch between the device and Speaker (CrowdPlay.setAudioOutput). Do
  NOT build upload screens, diagnostics screens, or SDK settings.
  Uploads happen automatically in the background.

- npm install crowdplaysdk
- In ios/: pod install, then run
    gem install xcodeproj --user-install   # one-time
    ruby node_modules/crowdplaysdk/ios/wire.rb <MyProjectName>
  (adds the compiled CrowdPlay engine + bridge to the Xcode project)
- Info.plist: NSMicrophoneUsageDescription, NSCameraUsageDescription,
  UIBackgroundModes = [audio]
- My CrowdPlay app key: <APP KEY from the CrowdPlay dashboard>
- Follow node_modules/crowdplaysdk/llms.txt exactly: configure at
  startup, the CrowdPlayConsentScreen before joining (join() throws
  without a ConsentGrant), CrowdPlayVideoView tiles from the participants
  event, and surface the warning events on the call screen.
- Never add, pin or import LiveKit/WebRTC yourself, and never write your
  own AVAudioSession/AVCaptureSession code — the engine owns the mic and
  camera.
- When done, run CrowdPlay.doctor() as a development check (not an app
  screen) and fix anything actionable.
- Your FINAL message must walk me through testing on my real iPhone,
  step by step (the Simulator has no camera or mic, so nothing is proven
  until then): plugging it in, signing/Developer Mode, running from
  Xcode, allowing permissions, doing a ~1-minute test call, and checking
  my session at https://dashboard.crowdplay.ai. Do not just say the
  implementation is complete.

Manual setup (iOS)

  1. npm install crowdplaysdk

  2. cd ios && pod install (one-time: gem install xcodeproj --user-install — the wiring script needs it)

  3. ruby node_modules/crowdplaysdk/ios/wire.rb <YourProjectName> — idempotent; adds the CrowdPlaySDK Swift package (the compiled engine), copies the three bridge files into your app target, and points the Swift bridging header at the React headers. (No CocoaPod of our own: the engine ships as a binary Swift package, which keeps your Podfile untouched.)

  4. Info.plist: NSMicrophoneUsageDescription, NSCameraUsageDescription, UIBackgroundModes = [audio].

  5. Recommended, for uploads that finish while your app is suspended — in your AppDelegate:

    // AppDelegate.mm — add #import "<YourProjectName>-Swift.h" at the top
    - (void)application:(UIApplication *)application
        handleEventsForBackgroundURLSession:(NSString *)identifier
        completionHandler:(void (^)(void))completionHandler {
      [CrowdPlayRNBackground handleWithCompletionHandler:completionHandler];
    }

    (Swift AppDelegates call CrowdPlaySDK.handleBackgroundURLSessionEvents(completionHandler:).)

Usage

import CrowdPlay, { CrowdPlayConsentScreen, CrowdPlayVideoView } from 'crowdplaysdk';

CrowdPlay.configure({ serverUrl: 'https://…', appKey: 'liva_pk_…' });
// Voice-only app? add audioOnly: true — the camera is never touched
// (no camera permission, no video captured or uploaded).

// 1. Consent (REQUIRED — join() throws without it):
<CrowdPlayConsentScreen onConsent={(grant) => setConsent(grant)} />

// 2. Join — recording starts automatically:
await CrowdPlay.join({ displayName, roomCode, consent });

// 3. Render the call:
<CrowdPlayVideoView participant="local" style={…} />           // self view
{participants.map(p => <CrowdPlayVideoView participant={p.identity} … />)}

// 4. Controls:
await CrowdPlay.setMicMuted(true);      // mutes the call AND records silence
await CrowdPlay.setCameraEnabled(false); // black frames, timeline continuous
await CrowdPlay.leave();                 // stops recording; uploads continue

// State: subscribe to events
CrowdPlay.addListener('phase', …)         // idle/connecting/connected/failed
CrowdPlay.addListener('participants', …)  // who to render tiles for
CrowdPlay.addListener('uploads', …)       // per-session progress
CrowdPlay.addListener('warning', …)       // micSilent / clipping / crossTalk — SHOW THESE
CrowdPlay.addListener('recording', …)     // error ⇒ NOT capturing; offer retryRecording()
CrowdPlay.addListener('audioRoute', …)    // current output device — drive the output menu
CrowdPlay.setAudioOutput('speaker')       // or 'automatic' (the connected device)
CrowdPlay.snapshot()                      // poll 1 Hz for REC timer + input level
CrowdPlay.doctor()                        // integration self-check

The complete example lives in this repo's Examples (one file, ~170 lines): consent → join → tiles → warnings → uploads.

Accessing recordings

Your app key doubles as your data credential — see the CrowdPlay dashboard (browse + download per session) or the REST endpoints (GET /sessions, GET /sessions/<id>/files) documented in the CrowdPlaySDK README.

Requirements & limits

  • iOS 17+, React Native ≥ 0.71. iOS only for now — no Android engine yet, calls to the module on other platforms throw with a clear message.
  • Real device required to record (the Simulator has no camera/mic).
  • The npm version can run ahead of the compiled engine version wire.rb pins — bridge and doc fixes ship without a new engine binary. wire.rb always pins the engine release this bridge was tested against.
  • Keep the screen awake during sessions; force-quitting the app pauses uploads until next launch (they resume automatically).
  • Slow join + glitchy first seconds = bad radio, not a bug. Congested 2.4 GHz WiFi plus Bluetooth headphones (they share the antenna) slows the call connect and can chop the first seconds of audio while the Bluetooth link settles; capture self-heals and the rest of the session is unaffected. Prefer a good network and wired headphones, and evaluate quality with the app launched from the home screen — Metro/debugger overhead can reproduce the same symptoms.