mpegts-vue3 0.3.0 → 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 +252 -0
- package/dist/index.cjs +300 -58
- package/dist/index.d.cts +46 -6
- package/dist/index.d.ts +46 -6
- package/dist/index.js +298 -63
- package/package.json +8 -4
package/README.md
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# mpegts-vue3 / mpegts-react
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/mpegts-vue3)
|
|
4
|
+
[](https://www.npmjs.com/package/mpegts-vue3)
|
|
5
|
+
[](https://www.npmjs.com/package/mpegts-react)
|
|
6
|
+
[](https://www.npmjs.com/package/mpegts-react)
|
|
7
|
+
[](./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
|