react-mse-player 1.0.6 → 1.1.0

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 CHANGED
@@ -2,16 +2,18 @@
2
2
 
3
3
  [![CI](https://github.com/Mkhgkk/react-mse-player/actions/workflows/ci.yml/badge.svg)](https://github.com/Mkhgkk/react-mse-player/actions/workflows/ci.yml) [![NPM Version](https://img.shields.io/npm/v/react-mse-player)](https://www.npmjs.com/package/react-mse-player) [![NPM Downloads](https://img.shields.io/npm/dm/react-mse-player)](https://www.npmjs.com/package/react-mse-player) [![License](https://img.shields.io/npm/l/react-mse-player)](https://github.com/Mkhgkk/react-mse-player)
4
4
 
5
- A strict, type-safe React component for streaming low-latency video using Media Source Extensions (MSE). Designed for seamless integration with [go2rtc](https://github.com/AlexxIT/go2rtc).
5
+ React components for low-latency video streaming via **MSE** and **WebRTC**. Designed for [go2rtc](https://github.com/AlexxIT/go2rtc).
6
6
 
7
7
  ## Features
8
8
 
9
- - **Media Source Extensions (MSE)**: Low-latency streaming directly in the browser.
10
- - **Robust Connection Management**: Automatic reconnection handling with exponential backoff and stall detection.
11
- - **Type-Safe**: Full TypeScript support with comprehensive type definitions.
12
- - **Smart Buffering**: Internal buffer queueing and automatic memory trimming to prevent quota errors.
13
- - **Broad Codec Support**: automatic negotiation for H.264, H.265 (HEVC), AAC, FLAC, and Opus.
14
- - **ManagedMediaSource**: Support for iOS 17+ via ManagedMediaSource API.
9
+ - **MSEVideoStream** low-latency streaming over WebSocket using Media Source Extensions.
10
+ - **WebRTCVideoStream** ultra-low-latency streaming via WebRTC with WebSocket signalling.
11
+ - **Automatic reconnection** with stall detection and smart backoff.
12
+ - **Full TypeScript support** with comprehensive type definitions.
13
+ - **Smart buffering** internal queue and automatic memory trimming to prevent quota errors (MSE).
14
+ - **Broad codec support** H.264, H.265 (HEVC), AAC, FLAC, Opus negotiated automatically.
15
+ - **ManagedMediaSource** — iOS 17+ support (MSE).
16
+ - **TCP-only ICE** — optional restriction for WebRTC in firewall-heavy environments.
15
17
 
16
18
  ## Installation
17
19
 
@@ -23,75 +25,119 @@ yarn add react-mse-player
23
25
 
24
26
  ## Usage
25
27
 
26
- ### Basic Usage
28
+ ### MSE
27
29
 
28
30
  ```tsx
29
- import React from 'react';
30
31
  import { MSEVideoStream } from 'react-mse-player';
31
32
 
32
- const Player = () => {
33
- return (
34
- <div style={{ width: '640px', aspectRatio: '16/9' }}>
35
- <MSEVideoStream
36
- src="ws://localhost:1984/api/ws?src=camera1"
37
- />
38
- </div>
39
- );
40
- };
33
+ <MSEVideoStream src="ws://localhost:1984/api/ws?src=camera1" />
41
34
  ```
42
35
 
43
- ### Advanced Usage with TypeScript
36
+ ### WebRTC
44
37
 
45
38
  ```tsx
46
- import React, { useCallback } from 'react';
47
- import { MSEVideoStream } from 'react-mse-player';
39
+ import { WebRTCVideoStream } from 'react-mse-player';
40
+
41
+ <WebRTCVideoStream src="ws://localhost:1984/api/ws?src=camera1" />
42
+ ```
43
+
44
+ > Both components accept a `ws://` or `wss://` URL. HTTP/HTTPS URLs are converted automatically. Relative paths (`/api/ws?src=...`) are also supported.
45
+
46
+ ### Choosing between MSE and WebRTC
47
+
48
+ | | MSE | WebRTC |
49
+ | --- | --- | --- |
50
+ | Latency | ~1–3 s | < 500 ms |
51
+ | Safari iOS | 17+ only | 11+ |
52
+ | Firewall-friendly | Yes (WS) | Needs STUN/TURN |
53
+ | Audio/Video sync | Good | Excellent |
54
+
55
+ Use **WebRTC** when latency matters most. Use **MSE** as a fallback for broader compatibility.
56
+
57
+ ### Advanced example
48
58
 
49
- const AdvancedPlayer = () => {
50
- const handleStatus = useCallback((status: string) => {
51
- // status: 'connecting' | 'open' | 'streaming' | 'closed' | 'error' | 'stalled' | 'reconnecting'
52
- console.log('[Player Status]', status);
53
- }, []);
54
-
55
- const handleError = useCallback((error: any) => {
56
- console.error('[Player Error]', error);
57
- }, []);
58
-
59
- return (
60
- <MSEVideoStream
61
- src="ws://localhost:1984/api/ws?src=camera1"
62
- autoPlay={true}
63
- controls={false}
64
- media="video,audio"
65
- onStatus={handleStatus}
66
- onError={handleError}
67
- className="custom-player-class"
68
- style={{ width: '100%', height: '100%' }}
69
- />
70
- );
71
- };
59
+ ```tsx
60
+ import { WebRTCVideoStream, MSEVideoStream } from 'react-mse-player';
61
+
62
+ // WebRTC with custom ICE servers and TCP-only mode
63
+ <WebRTCVideoStream
64
+ src="ws://localhost:1984/api/ws?src=camera1"
65
+ mode="webrtc/tcp"
66
+ pcConfig={{
67
+ iceServers: [{ urls: 'turn:my-turn-server.com', username: 'user', credential: 'pass' }],
68
+ }}
69
+ media="video,audio"
70
+ onStatus={(s) => console.log(s)}
71
+ onError={(e) => console.error(e)}
72
+ debug
73
+ />
74
+
75
+ // MSE with stall detection timeout
76
+ <MSEVideoStream
77
+ src="ws://localhost:1984/api/ws?src=camera1"
78
+ dataTimeout={5000}
79
+ media="video,audio"
80
+ onStatus={(s) => console.log(s)}
81
+ onError={(e) => console.error(e)}
82
+ debug
83
+ />
72
84
  ```
73
85
 
74
86
  ## Props
75
87
 
88
+ ### Shared props (both components)
89
+
76
90
  | Prop | Type | Default | Description |
77
- |------|------|---------|-------------|
78
- | `src` | `string` | **Required** | WebSocket URL for the stream (e.g., `ws://...` or `/api/ws...`). |
79
- | `width` | `string \| number` | `'100%'` | Width of the container. |
80
- | `height` | `string \| number` | `'100%'` | Height of the container. |
81
- | `autoPlay` | `boolean` | `true` | Whether to start playback automatically. |
91
+ | --- | --- | --- | --- |
92
+ | `src` | `string` | **Required** | WebSocket URL (`ws://`, `wss://`, relative `/` path, or `http(s)://` auto-converted). |
93
+ | `width` | `string \| number` | `'100%'` | Container width. |
94
+ | `height` | `string \| number` | `'100%'` | Container height. |
95
+ | `autoPlay` | `boolean` | `true` | Start playback automatically. |
82
96
  | `controls` | `boolean` | `false` | Show native video controls. |
83
- | `media` | `string` | `'video,audio'` | Media types to negotiate (`'video'`, `'audio'`, or `'video,audio'`). |
84
- | `onStatus` | `(status: string) => void` | `undefined` | Callback for connection status updates. |
85
- | `onError` | `(error: any) => void` | `undefined` | Callback for errors. |
97
+ | `media` | `string` | `'video,audio'` | Requested tracks: `'video'`, `'audio'`, or `'video,audio'`. |
98
+ | `objectFit` | `string` | `'contain'` | CSS `object-fit` for the video element. |
99
+ | `onStatus` | `(status: string) => void` | | Status change callback. |
100
+ | `onError` | `(error: any) => void` | — | Error callback. |
86
101
  | `className` | `string` | `''` | CSS class for the container. |
87
- | `style` | `React.CSSProperties` | `{}` | Inline styles for the container. |
102
+ | `style` | `CSSProperties` | `{}` | Inline styles for the container. |
103
+ | `debug` | `boolean` | `false` | Log connection events to the console. |
104
+
105
+ ### MSEVideoStream-only props
106
+
107
+ | Prop | Type | Default | Description |
108
+ | --- | --- | --- | --- |
109
+ | `dataTimeout` | `number` | `10000` | Milliseconds without data before triggering a reconnect. |
110
+
111
+ ### WebRTCVideoStream-only props
112
+
113
+ | Prop | Type | Default | Description |
114
+ | --- | --- | --- | --- |
115
+ | `mode` | `'webrtc' \| 'webrtc/tcp'` | `'webrtc'` | Use `'webrtc/tcp'` to restrict ICE candidates to TCP only. |
116
+ | `pcConfig` | `RTCConfiguration` | Cloudflare + Google STUN | Override ICE servers or bundle policy. |
117
+
118
+ ### Status values
119
+
120
+ | Status | Description |
121
+ | --- | --- |
122
+ | `connecting` | Opening the WebSocket connection. |
123
+ | `open` | WebSocket connected, negotiating stream. |
124
+ | `streaming` | *(MSE)* Data flowing, buffer active. |
125
+ | `connected` | *(WebRTC)* Peer connection established. |
126
+ | `reconnecting` | Connection lost, waiting to retry. |
127
+ | `closed` | Connection closed. |
128
+ | `error` | Unrecoverable error. |
88
129
 
89
130
  ## Browser Support
90
131
 
91
- - **Chromium-based** (Chrome, Edge, Brave): Full support.
92
- - **Firefox**: Full support.
93
- - **Safari**: Supported on version 17+ via `ManagedMediaSource`.
94
- - **Mobile**: Supported on Android (Chrome/Firefox) and iOS 17.1+ (Safari).
132
+ | Browser | MSE | WebRTC |
133
+ | --- | --- | --- |
134
+ | Chrome / Edge / Brave | ✅ | ✅ |
135
+ | Firefox | | |
136
+ | Safari 17+ | ✅ (ManagedMediaSource) | ✅ |
137
+ | Safari < 17 | ❌ | ✅ (11+) |
138
+ | Android (Chrome) | ✅ | ✅ |
139
+ | iOS Safari 17.1+ | ✅ | ✅ |
140
+ | iOS Safari < 17 | ❌ | ✅ |
95
141
 
96
142
  ## License
97
143
 
@@ -0,0 +1,16 @@
1
+ import React, { CSSProperties } from "react";
2
+ export interface VideoShellProps {
3
+ videoRef: React.RefObject<HTMLVideoElement>;
4
+ width?: string | number;
5
+ height?: string | number;
6
+ controls?: boolean;
7
+ autoPlay?: boolean;
8
+ objectFit?: "fill" | "contain" | "cover" | "none" | "scale-down";
9
+ className?: string;
10
+ style?: CSSProperties;
11
+ isLoading: boolean;
12
+ status: string;
13
+ error: any;
14
+ }
15
+ declare const VideoShell: React.FC<VideoShellProps>;
16
+ export default VideoShell;
@@ -0,0 +1,29 @@
1
+ import React, { CSSProperties } from "react";
2
+ export interface WebRTCVideoStreamProps {
3
+ src: string;
4
+ width?: string | number;
5
+ height?: string | number;
6
+ controls?: boolean;
7
+ autoPlay?: boolean;
8
+ /**
9
+ * Requested media tracks. Supports "video", "audio", "microphone".
10
+ * e.g. "video,audio" or "video,audio,microphone"
11
+ */
12
+ media?: string;
13
+ /**
14
+ * WebRTC mode. Use "webrtc/tcp" to restrict ICE candidates to TCP only.
15
+ */
16
+ mode?: "webrtc" | "webrtc/tcp";
17
+ /**
18
+ * RTCPeerConnection configuration. ICE servers can be overridden here.
19
+ */
20
+ pcConfig?: RTCConfiguration;
21
+ onStatus?: (status: string) => void;
22
+ onError?: (error: any) => void;
23
+ className?: string;
24
+ style?: CSSProperties;
25
+ objectFit?: "fill" | "contain" | "cover" | "none" | "scale-down";
26
+ debug?: boolean;
27
+ }
28
+ declare const WebRTCVideoStream: React.FC<WebRTCVideoStreamProps>;
29
+ export default WebRTCVideoStream;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  export { default as MSEVideoStream } from './MSEVideoStream';
2
2
  export type { MSEVideoStreamProps } from './MSEVideoStream';
3
+ export { default as WebRTCVideoStream } from './WebRTCVideoStream';
4
+ export type { WebRTCVideoStreamProps } from './WebRTCVideoStream';
3
5
  export { default } from './MSEVideoStream';