@streamslice/widget 1.0.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 +234 -0
- package/dist/StreamSlice.d.ts +104 -0
- package/dist/api/client.d.ts +12 -0
- package/dist/index.d.ts +9 -0
- package/dist/player/IVSPlayer.d.ts +58 -0
- package/dist/streamslice.esm.js +1655 -0
- package/dist/streamslice.esm.js.map +1 -0
- package/dist/streamslice.esm.min.js +7 -0
- package/dist/streamslice.esm.min.js.map +1 -0
- package/dist/streamslice.js +1666 -0
- package/dist/streamslice.js.map +1 -0
- package/dist/streamslice.min.js +7 -0
- package/dist/streamslice.min.js.map +1 -0
- package/dist/styles/index.d.ts +6 -0
- package/dist/types/index.d.ts +76 -0
- package/dist/ui/FloatingWindow.d.ts +55 -0
- package/dist/ui/PlayerControls.d.ts +32 -0
- package/dist/ui/icons.d.ts +20 -0
- package/package.json +68 -0
package/README.md
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# Widget
|
|
2
|
+
|
|
3
|
+
A floating video player library with Amazon IVS support for embedding live streams on any website.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Draggable and resizable floating window
|
|
8
|
+
- Amazon IVS Player integration for HLS streams
|
|
9
|
+
- Automatic playlist fetching by page URL
|
|
10
|
+
- Playback controls (play/pause, volume, quality, fullscreen)
|
|
11
|
+
- Dark and light themes
|
|
12
|
+
- TypeScript support
|
|
13
|
+
- Lightweight with no external dependencies (except IVS SDK)
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
### NPM
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @streamslice/widget
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### CDN
|
|
24
|
+
|
|
25
|
+
```html
|
|
26
|
+
<!-- Minified (recommended for production) -->
|
|
27
|
+
<script src="https://unpkg.com/@streamslice/widget"></script>
|
|
28
|
+
|
|
29
|
+
<!-- Or via jsDelivr -->
|
|
30
|
+
<script src="https://cdn.jsdelivr.net/npm/@streamslice/widget"></script>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
### ES Modules
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { StreamSlice } from '@streamslice/widget';
|
|
39
|
+
|
|
40
|
+
const widget = new StreamSlice({
|
|
41
|
+
apiUrl: 'https://api.your-backend.com',
|
|
42
|
+
autoPlay: true,
|
|
43
|
+
muted: false,
|
|
44
|
+
theme: 'dark',
|
|
45
|
+
onReady: () => console.log('Widget ready'),
|
|
46
|
+
onError: (error) => console.error('Error:', error),
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Initialize widget
|
|
50
|
+
widget.init();
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### UMD (Browser)
|
|
54
|
+
|
|
55
|
+
```html
|
|
56
|
+
<script src="https://unpkg.com/streamslice-widget"></script>
|
|
57
|
+
<script>
|
|
58
|
+
const widget = new StreamSlice.StreamSlice({
|
|
59
|
+
apiUrl: 'https://api.your-backend.com',
|
|
60
|
+
autoPlay: true,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
widget.init();
|
|
64
|
+
</script>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Configuration
|
|
68
|
+
|
|
69
|
+
| Parameter | Type | Default | Description |
|
|
70
|
+
|-----------|------|---------|-------------|
|
|
71
|
+
| `apiUrl` | `string` | **required** | API server URL |
|
|
72
|
+
| `position` | `{ x: number, y: number }` | `{ x: 20, y: 20 }` | Initial window position |
|
|
73
|
+
| `size` | `{ width: number, height: number }` | `{ width: 400, height: 280 }` | Initial window size |
|
|
74
|
+
| `minSize` | `{ width: number, height: number }` | `{ width: 320, height: 220 }` | Minimum window size |
|
|
75
|
+
| `maxSize` | `{ width: number, height: number }` | `{ width: 800, height: 600 }` | Maximum window size |
|
|
76
|
+
| `autoPlay` | `boolean` | `true` | Auto-play when stream loads |
|
|
77
|
+
| `muted` | `boolean` | `false` | Start muted |
|
|
78
|
+
| `volume` | `number` | `1` | Initial volume (0-1) |
|
|
79
|
+
| `showControls` | `boolean` | `true` | Show player controls |
|
|
80
|
+
| `zIndex` | `number` | `999999` | Window z-index |
|
|
81
|
+
| `theme` | `'dark' \| 'light'` | `'dark'` | Color theme |
|
|
82
|
+
| `className` | `string` | - | Additional CSS class |
|
|
83
|
+
|
|
84
|
+
### Callbacks
|
|
85
|
+
|
|
86
|
+
| Callback | Parameters | Description |
|
|
87
|
+
|----------|-----------|-------------|
|
|
88
|
+
| `onReady` | - | Called when widget is ready for playback |
|
|
89
|
+
| `onPlay` | - | Called when playback starts |
|
|
90
|
+
| `onPause` | - | Called when playback pauses |
|
|
91
|
+
| `onError` | `{ code: string, message: string }` | Called on error |
|
|
92
|
+
| `onClose` | - | Called when widget is closed |
|
|
93
|
+
| `onResize` | `{ width: number, height: number }` | Called when window is resized |
|
|
94
|
+
| `onMove` | `{ x: number, y: number }` | Called when window is moved |
|
|
95
|
+
|
|
96
|
+
## API
|
|
97
|
+
|
|
98
|
+
### Methods
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
// Playback control
|
|
102
|
+
widget.play();
|
|
103
|
+
widget.pause();
|
|
104
|
+
widget.togglePlayPause();
|
|
105
|
+
|
|
106
|
+
// Volume
|
|
107
|
+
widget.setVolume(0.5); // 0-1
|
|
108
|
+
widget.getVolume();
|
|
109
|
+
widget.mute();
|
|
110
|
+
widget.unmute();
|
|
111
|
+
widget.toggleMute();
|
|
112
|
+
|
|
113
|
+
// Quality
|
|
114
|
+
widget.setQuality('720p');
|
|
115
|
+
widget.getQualities(); // ['Auto', '1080p', '720p', '480p', ...]
|
|
116
|
+
|
|
117
|
+
// Fullscreen
|
|
118
|
+
widget.toggleFullscreen();
|
|
119
|
+
|
|
120
|
+
// Window position and size
|
|
121
|
+
widget.setPosition({ x: 100, y: 100 });
|
|
122
|
+
widget.setSize({ width: 500, height: 350 });
|
|
123
|
+
|
|
124
|
+
// Visibility
|
|
125
|
+
widget.show();
|
|
126
|
+
widget.hide();
|
|
127
|
+
widget.close();
|
|
128
|
+
|
|
129
|
+
// State
|
|
130
|
+
widget.isReady(); // boolean
|
|
131
|
+
widget.getState(); // PlayerState
|
|
132
|
+
|
|
133
|
+
// Cleanup
|
|
134
|
+
widget.destroy();
|
|
135
|
+
|
|
136
|
+
// Static method to remove injected styles
|
|
137
|
+
StreamSlice.removeStyles();
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### PlayerState
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
interface PlayerState {
|
|
144
|
+
isPlaying: boolean;
|
|
145
|
+
isMuted: boolean;
|
|
146
|
+
volume: number;
|
|
147
|
+
isFullscreen: boolean;
|
|
148
|
+
isLoading: boolean;
|
|
149
|
+
duration: number;
|
|
150
|
+
currentTime: number;
|
|
151
|
+
isLive: boolean;
|
|
152
|
+
quality: string;
|
|
153
|
+
availableQualities: string[];
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Backend API
|
|
158
|
+
|
|
159
|
+
The library expects the following API endpoint:
|
|
160
|
+
|
|
161
|
+
### GET /api/event/getPlaylist
|
|
162
|
+
|
|
163
|
+
**Query Parameters:**
|
|
164
|
+
- `link` (string, required) - Page URL
|
|
165
|
+
|
|
166
|
+
**Response:**
|
|
167
|
+
```json
|
|
168
|
+
{
|
|
169
|
+
"data": {
|
|
170
|
+
"link": "https://ivs.stream.url/playlist.m3u8"
|
|
171
|
+
},
|
|
172
|
+
"error": null
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**Error Response:**
|
|
177
|
+
```json
|
|
178
|
+
{
|
|
179
|
+
"data": null,
|
|
180
|
+
"error": {
|
|
181
|
+
"code": "ERROR_CODE",
|
|
182
|
+
"error_message_message": "Error description"
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Build
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# Install dependencies
|
|
191
|
+
npm install
|
|
192
|
+
|
|
193
|
+
# Build
|
|
194
|
+
npm run build
|
|
195
|
+
|
|
196
|
+
# Build with watch mode
|
|
197
|
+
npm run dev
|
|
198
|
+
|
|
199
|
+
# Run example server
|
|
200
|
+
npm run serve
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Output Files
|
|
204
|
+
|
|
205
|
+
| File | Size | Description |
|
|
206
|
+
|------|------|-------------|
|
|
207
|
+
| `streamslice.js` | ~55 KB | UMD, development |
|
|
208
|
+
| `streamslice.min.js` | ~33 KB | UMD, minified (production) |
|
|
209
|
+
| `streamslice.esm.js` | ~50 KB | ES Modules |
|
|
210
|
+
| `streamslice.esm.min.js` | ~33 KB | ES Modules, minified |
|
|
211
|
+
|
|
212
|
+
## Project Structure
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
src/
|
|
216
|
+
├── index.ts # Entry point
|
|
217
|
+
├── StreamSlice.ts # Main class
|
|
218
|
+
├── api/
|
|
219
|
+
│ └── client.ts # API client
|
|
220
|
+
├── player/
|
|
221
|
+
│ └── IVSPlayer.ts # Amazon IVS Player wrapper
|
|
222
|
+
├── ui/
|
|
223
|
+
│ ├── FloatingWindow.ts # Floating window
|
|
224
|
+
│ ├── PlayerControls.ts # Player controls
|
|
225
|
+
│ └── icons.ts # SVG icons
|
|
226
|
+
├── styles/
|
|
227
|
+
│ └── index.ts # CSS styles
|
|
228
|
+
└── types/
|
|
229
|
+
└── index.ts # TypeScript types
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## License
|
|
233
|
+
|
|
234
|
+
MIT
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StreamSlice - Main Widget Class
|
|
3
|
+
*/
|
|
4
|
+
import type { StreamSliceConfig, WindowPosition, WindowSize, PlayerState } from './types';
|
|
5
|
+
export declare class StreamSlice {
|
|
6
|
+
private config;
|
|
7
|
+
private apiClient;
|
|
8
|
+
private floatingWindow;
|
|
9
|
+
private playerControls;
|
|
10
|
+
private player;
|
|
11
|
+
private isInitialized;
|
|
12
|
+
private playlistUrl;
|
|
13
|
+
private playerState;
|
|
14
|
+
constructor(config: StreamSliceConfig);
|
|
15
|
+
/**
|
|
16
|
+
* Initialize and show the widget
|
|
17
|
+
*/
|
|
18
|
+
init(): Promise<void>;
|
|
19
|
+
private createWidget;
|
|
20
|
+
private loadStream;
|
|
21
|
+
private showNoStreamState;
|
|
22
|
+
private handlePlayerStateChange;
|
|
23
|
+
private handleClose;
|
|
24
|
+
/**
|
|
25
|
+
* Play the stream
|
|
26
|
+
*/
|
|
27
|
+
play(): void;
|
|
28
|
+
/**
|
|
29
|
+
* Pause the stream
|
|
30
|
+
*/
|
|
31
|
+
pause(): void;
|
|
32
|
+
/**
|
|
33
|
+
* Toggle play/pause
|
|
34
|
+
*/
|
|
35
|
+
togglePlayPause(): void;
|
|
36
|
+
/**
|
|
37
|
+
* Set volume (0-1)
|
|
38
|
+
*/
|
|
39
|
+
setVolume(volume: number): void;
|
|
40
|
+
/**
|
|
41
|
+
* Get current volume
|
|
42
|
+
*/
|
|
43
|
+
getVolume(): number;
|
|
44
|
+
/**
|
|
45
|
+
* Mute the player
|
|
46
|
+
*/
|
|
47
|
+
mute(): void;
|
|
48
|
+
/**
|
|
49
|
+
* Unmute the player
|
|
50
|
+
*/
|
|
51
|
+
unmute(): void;
|
|
52
|
+
/**
|
|
53
|
+
* Toggle mute
|
|
54
|
+
*/
|
|
55
|
+
toggleMute(): void;
|
|
56
|
+
/**
|
|
57
|
+
* Set quality
|
|
58
|
+
*/
|
|
59
|
+
setQuality(quality: string): void;
|
|
60
|
+
/**
|
|
61
|
+
* Get available qualities
|
|
62
|
+
*/
|
|
63
|
+
getQualities(): string[];
|
|
64
|
+
/**
|
|
65
|
+
* Toggle fullscreen
|
|
66
|
+
*/
|
|
67
|
+
toggleFullscreen(): void;
|
|
68
|
+
/**
|
|
69
|
+
* Set window position
|
|
70
|
+
*/
|
|
71
|
+
setPosition(position: WindowPosition): void;
|
|
72
|
+
/**
|
|
73
|
+
* Set window size
|
|
74
|
+
*/
|
|
75
|
+
setSize(size: WindowSize): void;
|
|
76
|
+
/**
|
|
77
|
+
* Check if widget is initialized
|
|
78
|
+
*/
|
|
79
|
+
isReady(): boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Get current player state
|
|
82
|
+
*/
|
|
83
|
+
getState(): PlayerState;
|
|
84
|
+
/**
|
|
85
|
+
* Show the widget
|
|
86
|
+
*/
|
|
87
|
+
show(): void;
|
|
88
|
+
/**
|
|
89
|
+
* Hide the widget
|
|
90
|
+
*/
|
|
91
|
+
hide(): void;
|
|
92
|
+
/**
|
|
93
|
+
* Close and destroy the widget
|
|
94
|
+
*/
|
|
95
|
+
close(): void;
|
|
96
|
+
/**
|
|
97
|
+
* Destroy the widget and clean up resources
|
|
98
|
+
*/
|
|
99
|
+
destroy(): void;
|
|
100
|
+
/**
|
|
101
|
+
* Static method to remove all injected styles
|
|
102
|
+
*/
|
|
103
|
+
static removeStyles(): void;
|
|
104
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StreamSlice API Client
|
|
3
|
+
*/
|
|
4
|
+
import type { PlaylistResponse } from '../types';
|
|
5
|
+
export declare class ApiClient {
|
|
6
|
+
private baseUrl;
|
|
7
|
+
constructor(baseUrl: string);
|
|
8
|
+
/**
|
|
9
|
+
* Get playlist URL for a page link
|
|
10
|
+
*/
|
|
11
|
+
getPlaylist(pageLink: string): Promise<PlaylistResponse>;
|
|
12
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StreamSlice Widget Library
|
|
3
|
+
*
|
|
4
|
+
* A floating video player widget with Amazon IVS support
|
|
5
|
+
*/
|
|
6
|
+
export { StreamSlice } from './StreamSlice';
|
|
7
|
+
export type { StreamSliceConfig, StreamSliceError, WindowPosition, WindowSize, PlayerState, PlaylistResponse, } from './types';
|
|
8
|
+
import { StreamSlice } from './StreamSlice';
|
|
9
|
+
export default StreamSlice;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Amazon IVS Player Wrapper
|
|
3
|
+
*/
|
|
4
|
+
import type { PlayerState } from '../types';
|
|
5
|
+
declare global {
|
|
6
|
+
interface Window {
|
|
7
|
+
IVSPlayer?: any;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export interface IVSPlayerOptions {
|
|
11
|
+
container: HTMLElement;
|
|
12
|
+
autoPlay?: boolean;
|
|
13
|
+
muted?: boolean;
|
|
14
|
+
volume?: number;
|
|
15
|
+
onStateChange?: (state: Partial<PlayerState>) => void;
|
|
16
|
+
onError?: (error: {
|
|
17
|
+
code: string;
|
|
18
|
+
message: string;
|
|
19
|
+
}) => void;
|
|
20
|
+
onReady?: () => void;
|
|
21
|
+
}
|
|
22
|
+
export declare class IVSPlayerWrapper {
|
|
23
|
+
private container;
|
|
24
|
+
private videoElement;
|
|
25
|
+
private player;
|
|
26
|
+
private options;
|
|
27
|
+
private isPlayerReady;
|
|
28
|
+
private loadingOverlay;
|
|
29
|
+
private errorOverlay;
|
|
30
|
+
private currentPlaybackUrl;
|
|
31
|
+
constructor(options: IVSPlayerOptions);
|
|
32
|
+
private init;
|
|
33
|
+
private loadIVSPlayerSDK;
|
|
34
|
+
private createVideoElement;
|
|
35
|
+
private initializePlayer;
|
|
36
|
+
load(playbackUrl: string): Promise<void>;
|
|
37
|
+
play(): Promise<void>;
|
|
38
|
+
pause(): void;
|
|
39
|
+
togglePlayPause(): void;
|
|
40
|
+
setVolume(volume: number): void;
|
|
41
|
+
getVolume(): number;
|
|
42
|
+
setMuted(muted: boolean): void;
|
|
43
|
+
toggleMute(): void;
|
|
44
|
+
setQuality(quality: string): void;
|
|
45
|
+
getQualities(): string[];
|
|
46
|
+
private updateQualities;
|
|
47
|
+
enterFullscreen(): Promise<void>;
|
|
48
|
+
exitFullscreen(): Promise<void>;
|
|
49
|
+
toggleFullscreen(): void;
|
|
50
|
+
isPlaying(): boolean;
|
|
51
|
+
isMuted(): boolean;
|
|
52
|
+
private showLoading;
|
|
53
|
+
private hideLoading;
|
|
54
|
+
private showError;
|
|
55
|
+
private hideError;
|
|
56
|
+
showNoStream(): void;
|
|
57
|
+
destroy(): void;
|
|
58
|
+
}
|