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

react-native-media3-player

v3.0.0

Published

React Native Media3 Player component for Android (ExoPlayer 3 integration).

Readme

📽️ Media3Player

A lightweight, high-performance React Native video player powered by Android Media3 (ExoPlayer). Fully customizable with support for autoplay, mute, event handling, automatic stream type detection (DASH, HLS, MP4), and client-side ad insertion (CSAI) via Google IMA. This is an Android only package.


Table of Contents


Installation

Install via npm:

npm install react-native-media3-player

Or yarn:

yarn add react-native-media3-player

Requires React Native >= 0.70


Note: To use a specific Media3 version, add or update the following in your android/build.gradle (Project-level) file:

buildscript {
    ext {
        media3Version = "1.4.1" // Set your desired Media3 version
    }
}

Be sure to sync your project after making this change.


Usage

Basic (non-DRM):

import React from 'react';
import {View} from 'react-native';
import Media3Player from 'react-native-media3-player';

export default function App() {
  return (
    <View style={{flex: 1}}>
      <Media3Player
        style={{width: '100%', height: 250}}
        source={{uri: 'https://example.com/video.mp4'}}
        autoplay={true}
        play={true}
        mute={false}
        onReady={() => console.log('Player is ready')}
        onEnd={() => console.log('Video ended')}
        onError={error => console.log('Player error:', error.message)}
      />
    </View>
  );
}

DRM-protected content (Widevine):

import React from 'react';
import {View} from 'react-native';
import Media3Player from 'react-native-media3-player';

export default function App() {
  return (
    <View style={{flex: 1}}>
      <Media3Player
        style={{width: '100%', height: 250}}
        source={{
          uri: 'https://storage.googleapis.com/shaka-demo-assets/angel-one-widevine/dash.mpd',
          type: 'dash',
          drm: {
            licenseUrl: 'https://cwip-shaka-proxy.appspot.com/no_auth',
          },
        }}
        autoplay={true}
        play={true}
        onReady={() => console.log('Player is ready')}
        onEnd={() => console.log('Video ended')}
        onError={error => console.log('Player error:', error.message)}
      />
    </View>
  );
}

With IMA Ads (Client-Side Ad Insertion):

import React from 'react';
import {View} from 'react-native';
import Media3Player from 'react-native-media3-player';

export default function App() {
  return (
    <View style={{flex: 1}}>
      <Media3Player
        style={{width: '100%', height: 250}}
        source={{
          uri: 'https://storage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
          ads: {
            adTagUrl:
              'https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/vmap_ad_samples&sz=640x480&cust_params=sample_ar%3Dpreonly&ciu_szs=300x250%2C728x90&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&env=vp&correlator=',
          },
        }}
        autoplay={true}
        play={true}
        onReady={() => console.log('Player is ready')}
        onEnd={() => console.log('Video ended')}
        onError={error => console.log('Player error:', error.message)}
      />
    </View>
  );
}

Props

| Prop | Type | Default | Description | | ---------- | ---------------------------- | -------------------------------- | ------------------------------------------------------------------------ | | source | Source | required | Video source object. Must include a valid uri. Supports optional drm and ads config. | | autoplay | boolean | false | Automatically start playback when the video is ready. | | play | boolean | false | Controls whether the player is playing. Overrides autoplay. | | mute | boolean | false | Mutes or unmutes the video. | | style | ViewStyle or ViewStyle[] | { width: '100%', height: 250 } | Styling for the player container. |

Source Object

| Property | Type | Required | Description | | -------- | ---------------------------- | -------- | ------------------------------------------------------------------------------------------------------------ | | uri | string | Yes | The URI of the media to play (MP4, DASH, HLS, etc.). | | type | 'dash' \| 'hls' \| 'mp4' | No | Explicitly set the stream type. Defaults to 'mp4'. If omitted, the player auto-detects the type from the URI. | | drm | DRMConfig | No | DRM configuration for protected content. | | ads | AdsConfig | No | IMA ads configuration for client-side ad insertion. |

DRMConfig Object

| Property | Type | Required | Description | | ------------ | --------------------------------- | -------- | ----------------------------------------------------- | | licenseUrl | string | Yes | The Widevine license server URL. | | headers | Array<{ key: string, value: string }> | No | Custom headers to include in the DRM license request. |

AdsConfig Object

| Property | Type | Required | Description | | ---------- | -------- | -------- | ----------------------------------------------------------------- | | adTagUrl | string | Yes | The VAST/VMAP ad tag URL for client-side ad insertion via IMA SDK. |


Stream Type Detection

The player supports automatic stream type detection based on the media URI. It inspects the file extension and known manifest patterns (.mpd for DASH, .m3u8 for HLS) to choose the correct media source.

You can also explicitly set the stream type using the type property in the source prop. This is useful when the URI does not contain a recognizable extension (e.g., signed URLs or token-based endpoints).

Supported Stream Types

| type Value | Format | Description | | ------------ | ------------------- | ------------------------------------- | | 'dash' | DASH (.mpd) | Dynamic Adaptive Streaming over HTTP | | 'hls' | HLS (.m3u8) | HTTP Live Streaming | | 'mp4' | Progressive (.mp4)| Standard progressive HTTP download |

Auto-Detection (Recommended)

If the URI contains a known extension, you can omit type entirely:

<Media3Player
  source={{uri: 'https://example.com/stream/manifest.mpd'}}
  autoplay
  play
/>

The player will automatically detect this as a DASH stream.

Explicit Type Override

Use type when the URI does not have a recognizable extension:

<Media3Player
  source={{
    uri: 'https://cdn.example.com/stream?token=abc123',
    type: 'hls',
  }}
  autoplay
  play
/>

DRM Support (Widevine)

This library supports Widevine DRM for playing protected DASH streams on Android. To enable DRM, pass a drm object inside the source prop.

Basic DRM Playback

<Media3Player
  source={{
    uri: 'https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd',
    drm: {
      licenseUrl: 'https://proxy.uat.widevine.com/proxy?provider=widevine_test',
    },
  }}
  autoplay
  play
/>

DRM with Custom License Headers

Some license servers require authentication tokens or custom headers. Pass them as an array of { key, value } objects:

<Media3Player
  source={{
    uri: 'https://example.com/protected-stream/manifest.mpd',
    drm: {
      licenseUrl: 'https://license.example.com/widevine',
      headers: [
        {key: 'Authorization', value: 'Bearer <your-token>'},
        {key: 'X-Custom-Header', value: 'custom-value'},
      ],
    },
  }}
  autoplay
  play
  onError={e => console.error('DRM error:', e.message)}
/>

Notes

  • DRM is currently supported on Android only (Widevine L1/L3 depending on device).
  • The source.uri should point to a DASH (.mpd) stream encrypted with Widevine.
  • Multi-session DRM is enabled by default for streams that require it.
  • If the license request fails, the onError callback will fire with the error details.

IMA Ads Support (CSAI)

This library supports Client-Side Ad Insertion (CSAI) using the Google IMA SDK integrated via Media3's IMA extension. To enable ads, pass an ads object inside the source prop with a VAST or VMAP ad tag URL.

Basic Ad Playback

<Media3Player
  source={{
    uri: 'https://storage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
    ads: {
      adTagUrl:
        'https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/vmap_ad_samples&sz=640x480&cust_params=sample_ar%3Dpreonly&ciu_szs=300x250%2C728x90&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&env=vp&correlator=',
    },
  }}
  autoplay
  play
/>

Ads with DRM Content

You can combine ads with DRM-protected streams:

<Media3Player
  source={{
    uri: 'https://storage.googleapis.com/shaka-demo-assets/angel-one-widevine/dash.mpd',
    type: 'dash',
    drm: {
      licenseUrl: 'https://cwip-shaka-proxy.appspot.com/no_auth',
    },
    ads: {
      adTagUrl: 'https://your-ad-server.com/vmap-tag',
    },
  }}
  autoplay
  play
  onError={e => console.error('Error:', e.message)}
/>

Notes

  • Ads are supported on Android only.
  • The adTagUrl should point to a valid VAST or VMAP XML endpoint.
  • Both pre-roll and mid-roll ad configurations are supported via VMAP.
  • The IMA ads loader is automatically initialized and released as needed when the ad tag URL changes.
  • Ads play inline within the same PlayerView used for content playback.

Events

| Event | Callback Signature | Description | | --------- | -------------------------------------- | -------------------------------------------------------------------------------------- | | onReady | () => void | Fired when the player is ready to play. | | onEnd | () => void | Fired when the video reaches the end. | | onError | (error: { message: string }) => void | Fired when the player encounters an error. Error object includes a message property. |


TypeScript Support

This library includes TypeScript definitions. Example:

import React from 'react';
import {ViewStyle} from 'react-native';
import Media3Player, {Media3PlayerProps} from 'react-native-media3-player';

const props: Media3PlayerProps = {
  source: {uri: 'https://example.com/video.mp4'},
  autoplay: true,
  play: true,
  mute: false,
  style: {width: '100%', height: 250},
  onReady: () => console.log('Ready'),
  onEnd: () => console.log('End'),
  onError: err => console.log(err.message),
};

With DRM and explicit stream type:

const drmProps: Media3PlayerProps = {
  source: {
    uri: 'https://storage.googleapis.com/shaka-demo-assets/angel-one-widevine/dash.mpd',
    type: 'dash',
    drm: {
      licenseUrl: 'https://cwip-shaka-proxy.appspot.com/no_auth',
      headers: [
        {key: 'Authorization', value: 'Bearer my-token'},
      ],
    },
  },
  autoplay: true,
  play: true,
  style: {width: '100%', height: 250},
  onError: err => console.log('DRM Error:', err.message),
};

With IMA Ads:

const adsProps: Media3PlayerProps = {
  source: {
    uri: 'https://storage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
    ads: {
      adTagUrl: 'https://pubads.g.doubleclick.net/gampad/ads?...',
    },
  },
  autoplay: true,
  play: true,
  style: {width: '100%', height: 250},
  onError: err => console.log('Ad Error:', err.message),
};

Examples

Basic Player:

<Media3Player source={{uri: 'https://example.com/video.mp4'}} />

Autoplay & Mute:

<Media3Player source={{uri: 'https://example.com/video.mp4'}} autoplay mute />

Event Handling:

<Media3Player
  source={{uri: 'https://example.com/video.mp4'}}
  onReady={() => console.log('Ready')}
  onEnd={() => console.log('End')}
  onError={err => console.error(err.message)}
/>

HLS Stream:

<Media3Player
  source={{
    uri: 'https://example.com/live/stream.m3u8',
    type: 'hls',
  }}
  autoplay
  play
/>

DASH Stream (auto-detected):

<Media3Player
  source={{uri: 'https://example.com/video/manifest.mpd'}}
  autoplay
  play
/>

Widevine DRM Stream:

<Media3Player
  source={{
    uri: 'https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd',
    type: 'dash',
    drm: {
      licenseUrl: 'https://proxy.uat.widevine.com/proxy?provider=widevine_test',
    },
  }}
  autoplay
  play
/>

DRM with License Headers:

<Media3Player
  source={{
    uri: 'https://example.com/protected/manifest.mpd',
    type: 'dash',
    drm: {
      licenseUrl: 'https://license.example.com/widevine',
      headers: [
        {key: 'Authorization', value: 'Bearer my-token'},
      ],
    },
  }}
  autoplay
  play
  onError={err => console.error('DRM Error:', err.message)}
/>

With IMA Ads (VMAP):

<Media3Player
  source={{
    uri: 'https://example.com/video.mp4',
    ads: {
      adTagUrl: 'https://pubads.g.doubleclick.net/gampad/ads?...',
    },
  }}
  autoplay
  play
/>

Ads with DRM Stream:

<Media3Player
  source={{
    uri: 'https://example.com/protected/manifest.mpd',
    type: 'dash',
    drm: {
      licenseUrl: 'https://license.example.com/widevine',
    },
    ads: {
      adTagUrl: 'https://pubads.g.doubleclick.net/gampad/ads?...',
    },
  }}
  autoplay
  play
  onError={err => console.error('Error:', err.message)}
/>

Contributing

We welcome contributions!

  1. Fork the repo
  2. Create a branch (git checkout -b feature/new-feature)
  3. Commit your changes (git commit -m 'Add feature')
  4. Push to the branch (git push origin feature/new-feature)
  5. Open a Pull Request

Please follow Semantic Versioning for commits.


License

MIT © Mohammad Rehan