React Native Player (iOS + Android)

React Native Video is a popular player for video in React Native apps. Gumlet Insights v2 wraps it with a higher-order component (withGumletInsights) and sends the same playback analytics as the web SDK via @gumlet/insights-js-core.

Sample app

Prefer a working project? Clone gumlet/react-native-video-insights-sample — a React Native app that integrates react-native-video with Gumlet Insights. Set your workspace_id and stream URL, then run on iOS or Android.

Requirements

  • @gumlet/insights-react-native 2.x
  • @gumlet/insights-js-core 4.0.1+
  • React ≥ 17, React Native ≥ 0.68
  • react-native-video ≥ 5.2 (v6 recommended)

Step 1: Install packages

Install the Gumlet SDKs and peer dependencies (npm does not install peers automatically):

npm install @gumlet/insights-react-native @gumlet/insights-js-core
npm install react-native-video @react-native-async-storage/async-storage react-native-device-info react-native-uuid
cd ios && pod install && cd ..
Package Why your app needs it
react-native-video Player wrapped by the SDK; callbacks drive play, pause, seek, rebuffer, and error events
@react-native-async-storage/async-storage Persists session and user ids across launches
react-native-device-info Device/OS metadata and durable user id
react-native-uuid Generates new session ids when storage is empty

react-native-url-polyfill is bundled inside @gumlet/insights-react-native (ingest fetch). react-native-crypto is not required in v2.

React Native 0.73+ (optional Babel)

If Metro reports “Static class blocks are not enabled” when bundling core, add:

// babel.config.js
module.exports = {
  presets: ['module:@react-native/babel-preset'],
  plugins: ['@babel/plugin-transform-class-static-block'],
};

Step 2: Import and wrap the player

Import withGumletInsights and your react-native-video component, then create a tracked player once (outside your screen component or in module scope):

import Video from 'react-native-video';
import withGumletInsights from '@gumlet/insights-react-native';

const TrackedVideo = withGumletInsights(Video);

You do not need a ref on the video for analytics in v2.

Step 3: Create the config object

All data is associated with a workspace ID from the Workspaces section. Pass it as workspace_id — this is the only required field. It gates the GET /license call; without a valid id, no events are sent.

Optional fields include screen name, custom user/video metadata, and debug logging. See custom data options for the full list (same shape as the web SDK).

const insightsConfig = {
  workspace_id: 'YOUR_WORKSPACE_ID', // required
  screen_name: 'Home',
  screen_type: 'feed',
  debug: __DEV__, // optional — verbose license/beacon logs in Metro
};

Do not set player_name — the SDK reports player_software: react-native-video and the installed player version automatically.

Step 4: Render the tracked player

Pass config, source, and paused from React state so PLAY/PAUSE beacons match real playback:

import React, { useMemo, useState } from 'react';
import { View } from 'react-native';
import Video from 'react-native-video';
import withGumletInsights from '@gumlet/insights-react-native';

const TrackedVideo = withGumletInsights(Video);

export function PlayerScreen() {
  const [paused, setPaused] = useState(true);

  const config = useMemo(
    () => ({
      workspace_id: 'YOUR_WORKSPACE_ID',
      screen_name: 'Home',
      screen_type: 'feed',
    }),
    [],
  );

  return (
    <View>
      <TrackedVideo
        config={config}
        source={{
          uri: 'https://example.com/stream.m3u8',
        }}
        paused={paused}
        muted={false}
        resizeMode="contain"
        style={{ width: '100%', aspectRatio: 16 / 9 }}
      />
    </View>
  );
}

Integration tips

  • The player renders immediately — session and user ids resolve in the background (no blank placeholder).
  • Avoid key={source.uri} on the tracked player for every load; that remounts analytics. Update source via props instead.
  • Do not remount the whole screen with a new HOC instance on each navigation if you can keep one player tree alive.

Once integrated, verify GET /license?workspace_id=… in your network inspector, then press Play. Data should appear on your real-time dashboard.

Session vs playback events

When What is sent
First install (no stored session) Session beacon once (event_family=session on v2 ingest)
App reopen within ~30 minutes Same session id — no new session HTTP
Each video load / play event_player_ready, event_playback_ready, play, pause, seek, rebuffer, etc.

player_ready and player_init on load are not the same as session creation.

How to?

Add custom data

Pass first-party user, video, and player fields on the same config object. Full parameter list: custom data options.

const insightsConfig = {
  workspace_id: 'YOUR_WORKSPACE_ID',
  screen_name: 'Episode',
  screen_type: 'detail',
  userId: '123',
  userName: 'Océane Bourgeois',
  userEMail: 'oceane.bourgeois@example.com',
  userPhone: '(840)-295-4133',
  customVideoTitle: 'Pilot',
  customVideoSeries: 'Season 1',
  customVideoId: 'episode-1',
  customData1: 'campaign-a',
  customData2: 'variant-b',
};

You can also spread the core QA helper (every optional field prefilled):

import { fullCustomAnalyticsConfig } from '@gumlet/insights-js-core';

const insightsConfig = {
  ...fullCustomAnalyticsConfig,
  workspace_id: 'YOUR_WORKSPACE_ID',
};

Enable debug logging

Set debug: true in config (or debug: __DEV__ in development). Logs appear in Metro via console.warn.

Reset session in development

import { clearIdentityForTests } from '@gumlet/insights-react-native';

await clearIdentityForTests(); // call before the tracked player mounts

Migrating from SDK 1.x

1.x 2.x
import gumletReactNativeVideo from '…' import withGumletInsights from '…'
gumletReactNativeVideo(Video) withGumletInsights(Video)
Config without workspace_id workspace_id required
react-native-crypto peer Removed — not needed
Blank UI until ids resolved Player always visible
player_name in config Omit — use automatic player_software

Upgrade both packages together:

npm install @gumlet/insights-react-native@2 @gumlet/insights-js-core@^4.0.1

After upgrading, restart Metro with a clean cache:

npx react-native start --reset-cache

Troubleshooting

Symptom What to check
No beacons Valid workspace_id; Metro for [GumletInsights] Analytics disabled
Session on every app open Old SDK, or player remounted with key={…} on every load
Play events while paused Pass paused from state; upgrade to v2 (PLAY from onPlaybackStateChanged)
False rebuffer on load Upgrade to v2 (rebuffer from onBuffer, not progress stall timer)
Android emulator HLS errors Use MP4 on emulators or test HLS on a physical device