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-all-video-player

v0.1.11

Published

One video player for React Native: pass any URL — YouTube links, mp4/mov/webm files, HLS (m3u8) and DASH (mpd) streams — and get the same custom controls and built-in landscape fullscreen. Native playback (ExoPlayer / AVPlayer), nothing else to install (N

Readme

react-native-all-video-player

One video player for React Native. Pass any video URL: YouTube links, mp4/mov/webm files, HLS (.m3u8) and DASH (.mpd) streams, signed stream links and S3/CDN files. Every source gets the same custom controls, settings menu and fullscreen.

| Controls | Settings | |---|---| | Player controls with previous/next, seek bar, settings and fullscreen | Playback speed list |

Fullscreen with the settings menu: playback speed and Autoplay next

Features

  • Any source: YouTube and video files or streams, through one component. Video files and streams play natively: ExoPlayer (Media3) on Android, AVPlayer on iOS.
  • Custom controls: play/pause, double-tap left/right to seek, draggable seek bar and time. Swipe up for fullscreen and down to leave it.
  • Settings menu: playback speed (0.25x to 2x) and, for playlists, an "Autoplay next" switch.
  • Playlists: pass playlist with any mix of YouTube links and video files to get previous/next buttons and autoplay of the next video. Give the items titles to list them under the player, as on YouTube.
  • Thumbnails: your own image, or a frame grabbed from the video, shown before the first play and at the end (and optionally while paused).
  • Built-in fullscreen: rotates to landscape, hides the status bar, handles Android's back button, and restores everything on exit.
  • Picture in picture: supported too.
  • Mini player: swipe down on a video to shrink it into a floating player that stays over every screen while the viewer browses.
  • Headphone controls: wired, Bluetooth and AirPods buttons play/pause and skip, and unplugging pauses. On iOS the lock screen and Control Center work too.
  • One install: nothing else to add, no AppDelegate/MainActivity changes.

Installation

npm install react-native-all-video-player
cd ios && pod install

Rebuild the app afterwards (npx react-native run-android / run-ios). Requires the New Architecture and React Native 0.81+. Expo works with a development build (npx expo prebuild), not Expo Go.

On Android the player uses Media3 1.11.1. To use another version, set media3Version in your app's android/build.gradle:

buildscript {
  ext {
    media3Version = "1.11.1"
  }
}

Usage

import { VideoPlayer } from 'react-native-all-video-player';

<VideoPlayer url="https://youtu.be/dQw4w9WgXcQ" style={{ width: '100%', aspectRatio: 16 / 9 }} />;
<VideoPlayer url="https://cdn.example.com/lessons/intro.mp4" style={{ width: '100%', aspectRatio: 16 / 9 }} />;
<VideoPlayer url="https://cdn.example.com/live/index.m3u8" style={{ width: '100%', aspectRatio: 16 / 9 }} />;

Without a style the player is full width at 16:9; pass one to size it yourself. Pass url or playlist; TypeScript reports an error if both are missing.

Playlists

<VideoPlayer
  playlist={[
    'https://youtu.be/dQw4w9WgXcQ',
    'https://cdn.example.com/lessons/intro.mp4',
    'https://cdn.example.com/lessons/part-2.m3u8',
  ]}
  playlistStartIndex={1}
  onVideoChange={(index, url) => console.log('now playing', index, url)}
  style={{ width: '100%', aspectRatio: 16 / 9 }}
/>;
  • Previous/next buttons appear beside play/pause; each is dimmed at the start or end of the list. Pressing one starts that video.
  • With "Autoplay next" on (the default), the next video starts when one ends, inline or in fullscreen.
  • The "Autoplay next" and "Captions" choices from the settings menu are kept for the rest of the app session, for every player.
  • A playlist with one video behaves like a plain url.

With titles: the playlist under the player

Pass items instead of urls to list the playlist under the video, as on YouTube: each row shows a thumbnail (YouTube videos get theirs automatically), the title and the subtitle; the playing one is highlighted, and tapping a row plays it.

<View style={{ flex: 1 }}>
  <VideoPlayer
    playlist={[
      { url: 'https://youtu.be/dQw4w9WgXcQ', title: 'Introduction', subTitle: 'Lesson 1 · 3 min' },
      { url: 'https://cdn.example.com/lessons/part-2.mp4', title: 'Setting up', subTitle: 'Lesson 2', thumbnail: 'https://cdn.example.com/lessons/part-2.jpg' },
    ]}
    style={{ width: '100%', aspectRatio: 16 / 9 }}
  />
</View>

The player then fills the space it's given: the video, sized by style, on top and the list below it, so put it in a container that has room (e.g. flex: 1). The list follows the system light/dark appearance and uses accentColor for the playing row.

Mini player

Swiping down on a player shrinks it into a mini player that floats over every screen, continuing from the same moment (playlists included), with no setup. It works like YouTube's:

  • Drag it anywhere; it snaps to the nearer side. Fling it off a side to close it.
  • Pinch to resize it.
  • Its buttons play/pause and close it. Tapping anywhere else hands the video back to its original player, reopening its screen if that has closed (see below). Without a way to reopen it, the mini player grows into a full-window player (swipe down or press back to shrink it again).
  • Starting another video closes the mini player.

With React Navigation, the player's screen closes when its video moves into the mini player, and tapping the mini player reopens it; the player there carries on from the same moment. Nothing to set up.

Thumbnails

<VideoPlayer url="https://cdn.example.com/a.mp4" thumbnail="https://cdn.example.com/a.jpg" thumbnailOnPause />;

The thumbnail covers the video before the first play and at the end, and while paused if thumbnailOnPause is set. Without thumbnail, video files (mp4, mov, webm, …) use a frame grabbed from the video, skipping blank frames; HLS/DASH streams get none.

Supported sources

| Source | Android | iOS | |---|---|---| | YouTube id or link (watch, youtu.be, shorts, embed, live) | ✓ | ✓ | | MP4 / MOV | ✓ | ✓ | | WebM / MKV | ✓ | — | | HLS (.m3u8) | ✓ | ✓ | | DASH (.mpd) | ✓ | — |

  • On Android, streams are recognised by their .m3u8 / .mpd extension; links without one play as regular files. iOS also detects HLS from the server's response.
  • Seeking needs a server that supports HTTP range requests.
  • Plain http:// URLs need cleartext traffic allowed on Android and an App Transport Security exception on iOS.
  • Playback pauses when the app goes to the background, unless picture in picture takes over.
  • On iOS, playing a video file sets the app's audio session to playback, so sound plays even with the silent switch on.

Controlling it from code

const player = useRef<VideoPlayerRef>(null);

<VideoPlayer ref={player} url="https://cdn.example.com/a.mp4" onEnd={() => console.log('done')} />;

player.current?.seekTo(90);
player.current?.play();

Fullscreen

The fullscreen button (or ref.setFullscreen(true)) opens the player in a full-screen Modal, rotated to landscape, continuing from the same position. Back, or the button again, returns to the inline player. The screen goes back to its previous orientation, so a portrait-only app stays portrait-only. Entering fullscreen starts a second player, so a spinner shows briefly.

See example/App.tsx for a runnable screen.

Props

| Prop | Type | Default | | |---|---|---|---| | url | string | — | Any video URL, or a YouTube id/link. Required unless playlist is given. | | playlistStartIndex | number | 0 | Playlists: the video to start with. | | playlist | string[] or { url, title, subTitle?, thumbnail? }[] | — | Videos to play in order, YouTube and files mixed; used instead of url. Adds previous/next buttons and "Autoplay next" in settings. Items with titles are also listed under the player. | | onVideoChange | (index: number, url: string) => void | — | Playlists: the player moved to another video (previous/next or autoplay). | | autoPlay | boolean | false | Play as soon as the player is ready. | | startSeconds | number | 0 | Start position. | | thumbnail | string | — | Image URL shown before the first play and at the end, for any source. See Thumbnails. | | thumbnailOnPause | boolean | false | Also show the thumbnail while paused mid-video. | | hideYouTubeBranding | boolean | false | YouTube only: hide YouTube's title bar, logo, watermark, "More videos" and end screen. | | showControls | boolean | true | false gives a bare player you drive through the ref. | | playbackRates | number[] | [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2] | Speeds under Settings → Playback speed; [] removes that row (and the settings button, unless it's a playlist). | | seekStepSeconds | number | 10 | Seconds each double-tap seeks; 0 turns double-tap seeking off. | | doubleTapToSeek | boolean | true | Double-tap left or right of the center controls to seek back / forward. The areas start just past the previous/next buttons in a playlist, otherwise just past play/pause. | | accentColor | string | #EF4444 | Seek bar, selected speed and switch color. | | allowFullscreen | boolean | true | Show the fullscreen button. | | onFullscreenChange | (fullscreen: boolean) => void | — | | | style | ViewStyle | full width, 16:9, black | Size and position of the video; replaces the default. | | renderLoading | () => ReactNode | spinner | Shown while loading/buffering. | | renderBackButton | ({ exitFullscreen }) => ReactNode | arrow in a circle | Replaces the fullscreen back button (shown with the controls). Position it yourself; return null to hide it. | | renderError | ({ error, retry }) => ReactNode | message + Retry | Shown over the player when the video can't play, or url is missing or not a video link (then retry is undefined). Return null to show nothing. | | onReady | ({ duration }) => void | — | duration is 0 for live streams. | | onStateChange | (state: PlayerState) => void | — | Unstarted / Ended / Playing / Paused / Buffering / Cued. | | onProgress | ({ currentTime, duration }) => void | — | About twice a second. | | onEnd | () => void | — | | | onError | ({ code?, message }) => void | — | See Errors. |

Ref

| Method | | |---|---| | play() / pause() | | | seekTo(seconds) | Clamped to the video length. | | setPlaybackRate(rate) | | | mute() / unMute() | | | getCurrentTime() / getDuration() | Last reported values, in seconds. | | setFullscreen(on) | Enter or leave fullscreen. |

Types

import {
  PlayerState,
  type PlayerError,
  type ProgressEvent,
  type VideoPlayerProps,
  type VideoPlayerOptions,
  type VideoSource,
  type VideoPlayerRef,
} from 'react-native-all-video-player';

VideoPlayerProps is VideoSource (url or playlist) plus VideoPlayerOptions (everything else).

PlayerState has the values Unstarted (-1), Ended (0), Playing (1), Paused (2), Buffering (3) and Cued (5). They're the same for every source.

Helpers

import { resolveSource, youtubeId, isValidVideoId, formatTime } from 'react-native-all-video-player';

resolveSource('https://youtu.be/dQw4w9WgXcQ');  // { kind: 'youtube', videoId: 'dQw4w9WgXcQ' }
resolveSource('https://cdn.example.com/a.mp4'); // { kind: 'video', url: 'https://cdn.example.com/a.mp4' }
resolveSource('not a url');                     // null
formatTime(3725);                               // '1:02:05'

Errors

Video files and streams report a message and no code. On Android the message is one of "A network error stopped the video from loading", "The video link is invalid or has expired" or "The video format is not supported", falling back to the player's own message. On iOS it is the system's error description. A url that is neither a YouTube video nor an http(s) URL reports "Not a supported video link", and a missing or empty one "No video URL". Messages never name YouTube, so they are safe to show to users. The player also shows its own message over the video (see renderError).

YouTube videos report a code:

| code | Meaning | |---|---| | 2 | Invalid video id. | | 5 | Can't be played in an HTML5 player. | | 100 | Not found, removed, or private. | | 101, 150, 152 | The owner disabled embedding. | | 153 | YouTube rejected the player configuration. | | none | The player failed to load (e.g. offline). |

Development

npm install
npm test
npm run typecheck
npm run build

License

MIT