mpegts-react
v0.4.1
Published
React component for mpegts.js video streaming player
Maintainers
Readme
mpegts-vue3 / mpegts-react
Vue 3 and React components for mpegts.js video streaming player. Supports FLV live streams over HTTP/WebSocket with low-latency playback.
This monorepo contains two packages:
mpegts-vue3— Vue 3 component (self-contained inline styles, zero CSS deps)mpegts-react— React 17+ component (inline styles, zero CSS dependency)
Features
Performance
- Web Worker transmuxing on by default (
enableWorker) — FLV remuxing off the main thread; the biggest lever for multi-view dashboards - Low-latency live tuning out of the box (
enableStashBuffer: false,liveSyncTargetLatency: 0.5) for sub-second latency - Optional MSE-in-worker on Chrome (
enableWorkerForMSE) — moves the entire MediaSource pipeline into a worker - CDN redirect reuse (
reuseRedirectedURL) — reuses 301/302 across seek/reconnect, pure upside for HTTP live-FLV
Resilience
- Live auto-reconnect with exponential backoff — mpegts.js only auto-reconnects VOD; this wrapper owns live reconnect (emits
reconnecting, skips permanent HTTP errors) - VOD early-EOF self-heal, surfaced via
onRecovered
Observability
- Real-time telemetry:
onStatistics(speed, dropped frames, fps ~every 600 ms) andonMediaInfo(resolution, codec, bitrate)
Control
- Imperative ref API —
play/pause/reload/seek/ volume /getCurrentTime/getBufferedRanges/getStatistics - mpegts.js escape hatch —
getPlayer()for the raw instance, plus a re-exportedMpegtsnamespace (getFeatureList,isSupported,Events)
DX
- Full TypeScript, dual ESM/CJS with type declarations, zero CSS dependencies (inline styles), transparent
configpassthrough
Vue 3 (mpegts-vue3)
Install
pnpm add mpegts-vue3 mpegts.jsmpegts.js and vue are peer dependencies and must be installed separately.
Usage
<script setup lang="ts">
import { ref } from 'vue'
import { MpegtsPlayer } from 'mpegts-vue3'
import type { PlayerStatus } from 'mpegts-vue3'
const playerRef = ref()
</script>
<template>
<MpegtsPlayer
ref="playerRef"
url="ws://host:port/live/stream.flv"
:autoplay="true"
:is-live="true"
:muted="true"
object-fit="fill"
@status="(s: PlayerStatus) => console.log(s)"
@error="(type, detail, info) => console.error(type, detail)"
@statistics="(s) => console.log('speed KB/s:', s.speed)"
/>
</template>Styling
The Vue 3 component ships with self-contained inline styles (the spinner keyframe is injected once at runtime) — zero Tailwind or CSS setup required. Status overlays (connecting, reconnecting, playing, error, no-signal) render correctly in any project out of the box.
React (mpegts-react)
Install
pnpm add mpegts-react mpegts.jsmpegts.js and react are peer dependencies and must be installed separately.
Usage
import { useRef } from 'react'
import { MpegtsPlayer } from 'mpegts-react'
import type { MpegtsPlayerRef, PlayerStatus } from 'mpegts-react'
function App() {
const ref = useRef<MpegtsPlayerRef>(null)
return (
<MpegtsPlayer
ref={ref}
url="ws://host:port/live/stream.flv"
autoplay={true}
isLive={true}
muted={true}
objectFit="fill"
onStatus={(s: PlayerStatus) => console.log(s)}
onError={(type, detail, info) => console.error(type, detail)}
onStatistics={(s) => console.log('speed KB/s:', s.speed)}
/>
)
}Styling
The React component uses inline styles — zero CSS dependency, works in any project.
Shared Props API
Both Vue 3 and React components share the same props interface:
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| url | string | — | Stream URL (required, same as mpegts.js MediaDataSource.url) |
| autoplay | boolean | true | Auto-play on mount. Create-time only — toggling after mount has no effect. |
| isLive | boolean | true | Live stream mode |
| muted | boolean | true | Muted playback |
| objectFit | 'fill' \| 'contain' \| 'cover' \| 'none' \| 'scale-down' | 'fill' | Video element object-fit style |
| type | string | 'mse' | Media type: 'mse', 'mpegts', 'm2ts', 'flv', 'mp4' |
| cors | boolean | — | Enable CORS for HTTP fetching |
| withCredentials | boolean | — | HTTP fetching with cookies |
| hasAudio | boolean | true | Whether stream has audio track. Defaults to true to avoid audio packets being dropped for FLV streams (e.g. ZLMediaKit) whose header flag doesn't mark audio |
| hasVideo | boolean | true | Whether stream has video track. Defaults to true to avoid video packets being dropped for FLV streams (e.g. ZLMediaKit) whose header flag doesn't mark video — same rationale as hasAudio. Set false for audio-only streams. |
| duration | number | — | Total media duration in milliseconds |
| filesize | number | — | Total file size in bytes |
| showLoading | boolean | true | Show the "Connecting..." loading overlay (spinner + text) while connecting to the stream |
| config | Partial<MpegtsConfig> | {} | mpegts.js player config. See mpegts.js API |
| autoReconnect | boolean | true | Auto-reconnect on transient live network errors (mpegts.js only auto-reconnects VOD). Exponential backoff up to reconnect.retries. |
| reconnect | { retries?, minDelay?, maxDelay? } | { retries: 5, minDelay: 1000, maxDelay: 16000 } | Reconnect backoff tuning (ms). delay = min(maxDelay, minDelay * 2^attempt). |
Config merge
config is shallow-merged with the package's low-latency live defaults: { ...DEFAULT_CONFIG, ...config }. Your config overrides matching top-level keys; keys you don't set keep their defaults. There is no way to "unset" a default by passing undefined — omit the key to keep the default, or pass an explicit value to override. config is treated as create-time: changing it after mount debounces a player rebuild (~300 ms). Notable defaults: enableWorker: true (transmuxing off the main thread — the biggest perf lever for multi-view; pass false under CSP/no-Worker constraints), enableStashBuffer: false, liveSyncTargetLatency: 0.5, reuseRedirectedURL: true (reuse CDN 301/302 redirects across seek/reconnect — pure upside for HTTP live-FLV).
Notes
- Latency: defaults (
enableStashBuffer: false,liveSyncTargetLatency: 0.5,liveBufferLatencyChasing: true) target sub-second live latency. On lossy networks this can cause stalls — raiseliveSyncTargetLatency/ enableenableStashBufferviaconfigif you need stability over latency. - Auto-reconnect: on transient live network errors (
ConnectingTimeout,UnrecoverableEarlyEof,Exception) the player retries with exponential backoff (default 5 tries, 1s→16s), emitting areconnectingstatus. HTTP status errors (4xx/5xx) are not retried (permanent). Disable withautoReconnect={false}. - Performance tuning:
enableWorker: trueis on by default (transmuxing in a Web Worker). For maximum offloading on Chrome, setconfig: { enableWorkerForMSE: true }to move the entire MSE pipeline (incl.MediaSource/SourceBuffer) into a worker — capability is auto-detected and falls back gracefully on unsupported browsers. Statistics fire everystatisticsInfoReportInterval(default 600 ms) — raise it under heavy multi-view to cut reactivity load, or use thegetStatistics()ref method to pull on demand. typeand MSE: typesmse/mpegts/m2ts/flvroute through mpegts.js's MSE path and requireMediaSource Extensions. Any othertype(e.g.mp4) uses native<video>playback and works on browsers without MSE (e.g. iOS Safari). FLV cannot play on MSE-less browsers — there is no software-decode fallback.- SSR / client-only: the component imports
mpegts.js, which toucheswindowat module load, so it is client-only. In Nuxt wrap with<ClientOnly>; in Next.js usenext/dynamic(() => import(...), { ssr: false }).
Events / Callbacks
| Event | Payload | Description |
|-------|---------|-------------|
| onStatus / @status | (status: PlayerStatus) | Status change |
| onError / @error | (errorType, errorDetail, errorInfo) | Playback error |
| onStatistics / @statistics | (info: StatisticsInfo) | mpegts.js telemetry (speed KB/s, decoded/dropped frames, segment counts) every ~600 ms |
| onMediaInfo / @mediaInfo | (info: MediaInfo) | Resolved media info (resolution, fps, codecs, bitrate) — fires once when known |
| onRecovered / @recovered | () | Stream self-healed after an early-EOF (mpegts.js internal VOD reconnect) |
| onEnded / @ended | () | VOD playback reached end-of-stream (LOADING_COMPLETE) |
Ref Methods
| Method | Description |
|--------|-------------|
| play() | Resume playback |
| pause() | Pause playback |
| reload() | Destroy and recreate the player — reconnects to the current url/config. Use to recover from stalls. |
| setMuted(muted: boolean) | Imperatively mute/unmute the underlying <video> element without re-rendering. |
| getPlayer() | Returns the underlying mpegts.js Player instance (or null) as an escape hatch for advanced APIs (statistics, buffered ranges, custom events). |
| getVolume() / setVolume(v) | Get/set the underlying <video> volume (0–1) imperatively, without re-rendering. |
| seek(seconds) | Seek — routes through mpegts.js so it range-loads the right segment (don't assign <video>.currentTime directly for VOD). |
| getCurrentTime() | Current playback position in seconds. |
| getBufferedRanges() | The <video> TimeRanges that have been downloaded/buffered. |
| getStatistics() | Pull mpegts.js telemetry on demand (same shape as onStatistics) — for overlays that only show stats when visible. |
PlayerStatus Type
type PlayerStatus =
| 'connecting' // Connecting to stream
| 'reconnecting' // Auto-reconnecting after a transient network error
| 'error' // Playback error (terminal: retries exhausted or non-recoverable)
| 'nosignal' // No signal / no url
| 'playing' // Playing
| 'stopped' // Paused / stoppedDemo
To run locally:
pnpm install
# Vue 3 demo
pnpm dev
# React 17 demo
pnpm dev:reactDevelopment
pnpm install
# Build all packages
pnpm build
# Build Vue 3 package only
pnpm -C packages/player build
# Build React package only
pnpm -C packages/react-player buildPublishing
Releases are managed via release-it with auto-generated CHANGELOG from conventional commits:
pnpm releaseThis will:
- Prompt to select version (patch / minor / major)
- Auto-generate
CHANGELOG.mdfrom git log - Update version in all
package.jsonfiles - Commit, tag (
v${version}), and push
GitHub Actions will then detect the tag and publish to npm automatically.
Tech Stack
- Vue 3 + React + TypeScript
- mpegts.js — FLV over HTTP/WebSocket playback
- tsdown — Library bundler powered by Rolldown
- release-it — Automated versioning and changelog
License
MIT
