mpegts-vue3 0.3.2 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,252 @@
1
+ # mpegts-vue3 / mpegts-react
2
+
3
+ [![npm version](https://img.shields.io/npm/v/mpegts-vue3.svg)](https://www.npmjs.com/package/mpegts-vue3)
4
+ [![npm downloads](https://img.shields.io/npm/dm/mpegts-vue3.svg)](https://www.npmjs.com/package/mpegts-vue3)
5
+ [![npm version](https://img.shields.io/npm/v/mpegts-react.svg)](https://www.npmjs.com/package/mpegts-react)
6
+ [![npm downloads](https://img.shields.io/npm/dm/mpegts-react.svg)](https://www.npmjs.com/package/mpegts-react)
7
+ [![license](https://img.shields.io/npm/l/mpegts-vue3.svg)](./LICENSE)
8
+
9
+ Vue 3 and React components for [mpegts.js](https://github.com/xqq/mpegts.js) video streaming player. Supports FLV live streams over HTTP/WebSocket with low-latency playback.
10
+
11
+ This monorepo contains two packages:
12
+
13
+ - **`mpegts-vue3`** — Vue 3 component (self-contained inline styles, zero CSS deps)
14
+ - **`mpegts-react`** — React 17+ component (inline styles, zero CSS dependency)
15
+
16
+ ## Features
17
+
18
+ **Performance**
19
+ - Web Worker transmuxing on by default (`enableWorker`) — FLV remuxing off the main thread; the biggest lever for multi-view dashboards
20
+ - Low-latency live tuning out of the box (`enableStashBuffer: false`, `liveSyncTargetLatency: 0.5`) for sub-second latency
21
+ - Optional MSE-in-worker on Chrome (`enableWorkerForMSE`) — moves the entire MediaSource pipeline into a worker
22
+ - CDN redirect reuse (`reuseRedirectedURL`) — reuses 301/302 across seek/reconnect, pure upside for HTTP live-FLV
23
+
24
+ **Resilience**
25
+ - Live auto-reconnect with exponential backoff — mpegts.js only auto-reconnects VOD; this wrapper owns live reconnect (emits `reconnecting`, skips permanent HTTP errors)
26
+ - VOD early-EOF self-heal, surfaced via `onRecovered`
27
+
28
+ **Observability**
29
+ - Real-time telemetry: `onStatistics` (speed, dropped frames, fps ~every 600 ms) and `onMediaInfo` (resolution, codec, bitrate)
30
+
31
+ **Control**
32
+ - Imperative ref API — `play` / `pause` / `reload` / `seek` / volume / `getCurrentTime` / `getBufferedRanges` / `getStatistics`
33
+ - mpegts.js escape hatch — `getPlayer()` for the raw instance, plus a re-exported `Mpegts` namespace (`getFeatureList`, `isSupported`, `Events`)
34
+
35
+ **DX**
36
+ - Full TypeScript, dual ESM/CJS with type declarations, zero CSS dependencies (inline styles), transparent `config` passthrough
37
+
38
+ ---
39
+
40
+ ## Vue 3 (`mpegts-vue3`)
41
+
42
+ ### Install
43
+
44
+ ```bash
45
+ pnpm add mpegts-vue3 mpegts.js
46
+ ```
47
+
48
+ `mpegts.js` and `vue` are peer dependencies and must be installed separately.
49
+
50
+ ### Usage
51
+
52
+ ```vue
53
+ <script setup lang="ts">
54
+ import { ref } from 'vue'
55
+ import { MpegtsPlayer } from 'mpegts-vue3'
56
+ import type { PlayerStatus } from 'mpegts-vue3'
57
+
58
+ const playerRef = ref()
59
+ </script>
60
+
61
+ <template>
62
+ <MpegtsPlayer
63
+ ref="playerRef"
64
+ url="ws://host:port/live/stream.flv"
65
+ :autoplay="true"
66
+ :is-live="true"
67
+ :muted="true"
68
+ object-fit="fill"
69
+ @status="(s: PlayerStatus) => console.log(s)"
70
+ @error="(type, detail, info) => console.error(type, detail)"
71
+ @statistics="(s) => console.log('speed KB/s:', s.speed)"
72
+ />
73
+ </template>
74
+ ```
75
+
76
+ ### Styling
77
+
78
+ 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.
79
+
80
+ ---
81
+
82
+ ## React (`mpegts-react`)
83
+
84
+ ### Install
85
+
86
+ ```bash
87
+ pnpm add mpegts-react mpegts.js
88
+ ```
89
+
90
+ `mpegts.js` and `react` are peer dependencies and must be installed separately.
91
+
92
+ ### Usage
93
+
94
+ ```tsx
95
+ import { useRef } from 'react'
96
+ import { MpegtsPlayer } from 'mpegts-react'
97
+ import type { MpegtsPlayerRef, PlayerStatus } from 'mpegts-react'
98
+
99
+ function App() {
100
+ const ref = useRef<MpegtsPlayerRef>(null)
101
+
102
+ return (
103
+ <MpegtsPlayer
104
+ ref={ref}
105
+ url="ws://host:port/live/stream.flv"
106
+ autoplay={true}
107
+ isLive={true}
108
+ muted={true}
109
+ objectFit="fill"
110
+ onStatus={(s: PlayerStatus) => console.log(s)}
111
+ onError={(type, detail, info) => console.error(type, detail)}
112
+ onStatistics={(s) => console.log('speed KB/s:', s.speed)}
113
+ />
114
+ )
115
+ }
116
+ ```
117
+
118
+ ### Styling
119
+
120
+ The React component uses inline styles — zero CSS dependency, works in any project.
121
+
122
+ ---
123
+
124
+ ## Shared Props API
125
+
126
+ Both Vue 3 and React components share the same props interface:
127
+
128
+ | Prop | Type | Default | Description |
129
+ |------|------|---------|-------------|
130
+ | `url` | `string` | — | Stream URL (required, same as mpegts.js `MediaDataSource.url`) |
131
+ | `autoplay` | `boolean` | `true` | Auto-play on mount. Create-time only — toggling after mount has no effect. |
132
+ | `isLive` | `boolean` | `true` | Live stream mode |
133
+ | `muted` | `boolean` | `true` | Muted playback |
134
+ | `objectFit` | `'fill' \| 'contain' \| 'cover' \| 'none' \| 'scale-down'` | `'fill'` | Video element `object-fit` style |
135
+ | `type` | `string` | `'mse'` | Media type: `'mse'`, `'mpegts'`, `'m2ts'`, `'flv'`, `'mp4'` |
136
+ | `cors` | `boolean` | — | Enable CORS for HTTP fetching |
137
+ | `withCredentials` | `boolean` | — | HTTP fetching with cookies |
138
+ | `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 |
139
+ | `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. |
140
+ | `duration` | `number` | — | Total media duration in milliseconds |
141
+ | `filesize` | `number` | — | Total file size in bytes |
142
+ | `showLoading` | `boolean` | `true` | Show the "Connecting..." loading overlay (spinner + text) while connecting to the stream |
143
+ | `config` | `Partial<MpegtsConfig>` | `{}` | mpegts.js player config. See [mpegts.js API](https://github.com/xqq/mpegts.js/blob/master/docs/api.md) |
144
+ | `autoReconnect` | `boolean` | `true` | Auto-reconnect on transient live network errors (mpegts.js only auto-reconnects VOD). Exponential backoff up to `reconnect.retries`. |
145
+ | `reconnect` | `{ retries?, minDelay?, maxDelay? }` | `{ retries: 5, minDelay: 1000, maxDelay: 16000 }` | Reconnect backoff tuning (ms). delay = `min(maxDelay, minDelay * 2^attempt)`. |
146
+
147
+ ### Config merge
148
+
149
+ `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).
150
+
151
+ ### Notes
152
+
153
+ - **Latency**: defaults (`enableStashBuffer: false`, `liveSyncTargetLatency: 0.5`, `liveBufferLatencyChasing: true`) target sub-second live latency. On lossy networks this can cause stalls — raise `liveSyncTargetLatency` / enable `enableStashBuffer` via `config` if you need stability over latency.
154
+ - **Auto-reconnect**: on transient live network errors (`ConnectingTimeout`, `UnrecoverableEarlyEof`, `Exception`) the player retries with exponential backoff (default 5 tries, 1s→16s), emitting a `reconnecting` status. HTTP status errors (4xx/5xx) are **not** retried (permanent). Disable with `autoReconnect={false}`.
155
+ - **Performance tuning**: `enableWorker: true` is on by default (transmuxing in a Web Worker). For maximum offloading on Chrome, set `config: { 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 every `statisticsInfoReportInterval` (default 600 ms) — raise it under heavy multi-view to cut reactivity load, or use the `getStatistics()` ref method to pull on demand.
156
+ - **`type` and MSE**: types `mse` / `mpegts` / `m2ts` / `flv` route through mpegts.js's MSE path and require `MediaSource Extensions`. Any other `type` (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.
157
+ - **SSR / client-only**: the component imports `mpegts.js`, which touches `window` at module load, so it is **client-only**. In Nuxt wrap with `<ClientOnly>`; in Next.js use `next/dynamic(() => import(...), { ssr: false })`.
158
+
159
+ ### Events / Callbacks
160
+
161
+ | Event | Payload | Description |
162
+ |-------|---------|-------------|
163
+ | `onStatus` / `@status` | `(status: PlayerStatus)` | Status change |
164
+ | `onError` / `@error` | `(errorType, errorDetail, errorInfo)` | Playback error |
165
+ | `onStatistics` / `@statistics` | `(info: StatisticsInfo)` | mpegts.js telemetry (speed KB/s, decoded/dropped frames, segment counts) every ~600 ms |
166
+ | `onMediaInfo` / `@mediaInfo` | `(info: MediaInfo)` | Resolved media info (resolution, fps, codecs, bitrate) — fires once when known |
167
+ | `onRecovered` / `@recovered` | `()` | Stream self-healed after an early-EOF (mpegts.js internal VOD reconnect) |
168
+ | `onEnded` / `@ended` | `()` | VOD playback reached end-of-stream (`LOADING_COMPLETE`) |
169
+
170
+ ### Ref Methods
171
+
172
+ | Method | Description |
173
+ |--------|-------------|
174
+ | `play()` | Resume playback |
175
+ | `pause()` | Pause playback |
176
+ | `reload()` | Destroy and recreate the player — reconnects to the current `url`/`config`. Use to recover from stalls. |
177
+ | `setMuted(muted: boolean)` | Imperatively mute/unmute the underlying `<video>` element without re-rendering. |
178
+ | `getPlayer()` | Returns the underlying `mpegts.js` `Player` instance (or `null`) as an escape hatch for advanced APIs (statistics, buffered ranges, custom events). |
179
+ | `getVolume()` / `setVolume(v)` | Get/set the underlying `<video>` volume (`0`–`1`) imperatively, without re-rendering. |
180
+ | `seek(seconds)` | Seek — routes through mpegts.js so it range-loads the right segment (don't assign `<video>.currentTime` directly for VOD). |
181
+ | `getCurrentTime()` | Current playback position in seconds. |
182
+ | `getBufferedRanges()` | The `<video>` `TimeRanges` that have been downloaded/buffered. |
183
+ | `getStatistics()` | Pull mpegts.js telemetry on demand (same shape as `onStatistics`) — for overlays that only show stats when visible. |
184
+
185
+ ### PlayerStatus Type
186
+
187
+ ```ts
188
+ type PlayerStatus =
189
+ | 'connecting' // Connecting to stream
190
+ | 'reconnecting' // Auto-reconnecting after a transient network error
191
+ | 'error' // Playback error (terminal: retries exhausted or non-recoverable)
192
+ | 'nosignal' // No signal / no url
193
+ | 'playing' // Playing
194
+ | 'stopped' // Paused / stopped
195
+ ```
196
+
197
+ ## Demo
198
+
199
+ To run locally:
200
+
201
+ ```bash
202
+ pnpm install
203
+
204
+ # Vue 3 demo
205
+ pnpm dev
206
+
207
+ # React 17 demo
208
+ pnpm dev:react
209
+ ```
210
+
211
+ ## Development
212
+
213
+ ```bash
214
+ pnpm install
215
+
216
+ # Build all packages
217
+ pnpm build
218
+
219
+ # Build Vue 3 package only
220
+ pnpm -C packages/player build
221
+
222
+ # Build React package only
223
+ pnpm -C packages/react-player build
224
+ ```
225
+
226
+ ## Publishing
227
+
228
+ Releases are managed via [release-it](https://github.com/release-it/release-it) with auto-generated CHANGELOG from conventional commits:
229
+
230
+ ```bash
231
+ pnpm release
232
+ ```
233
+
234
+ This will:
235
+
236
+ 1. Prompt to select version (patch / minor / major)
237
+ 2. Auto-generate `CHANGELOG.md` from git log
238
+ 3. Update version in all `package.json` files
239
+ 4. Commit, tag (`v${version}`), and push
240
+
241
+ GitHub Actions will then detect the tag and publish to npm automatically.
242
+
243
+ ## Tech Stack
244
+
245
+ - [Vue 3](https://vuejs.org/) + [React](https://react.dev/) + [TypeScript](https://www.typescriptlang.org/)
246
+ - [mpegts.js](https://github.com/xqq/mpegts.js) — FLV over HTTP/WebSocket playback
247
+ - [tsdown](https://tsdown.dev/) — Library bundler powered by Rolldown
248
+ - [release-it](https://github.com/release-it/release-it) — Automated versioning and changelog
249
+
250
+ ## License
251
+
252
+ MIT