kplayer-ts 1.0.0 → 1.0.2

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
@@ -0,0 +1,477 @@
1
+ # KPlayer
2
+
3
+ A powerful, customizable HTML5 video player built with TypeScript.
4
+
5
+ ---
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install kplayer-ts
11
+ ```
12
+
13
+ Or load via CDN:
14
+
15
+ ```html
16
+ <div id="kplayer"></div>
17
+ <script src="kplayer.min.js"></script>
18
+ ```
19
+
20
+ ---
21
+
22
+ ## Quick Start
23
+
24
+ ```html
25
+ <div id="kplayer"></div>
26
+ ```
27
+
28
+ ```typescript
29
+ import KPlayer from "kplayer-ts";
30
+ import type { KPlayerOptions } from "kplayer-ts";
31
+
32
+ const dp = new KPlayer({
33
+ container: document.getElementById("kplayer"),
34
+ video: {
35
+ url: "demo.mp4",
36
+ pic: "demo.jpg",
37
+ thumbnails: "thumbnails.jpg",
38
+ },
39
+ });
40
+ ```
41
+
42
+ ---
43
+
44
+ ## Options
45
+
46
+ | Name | Default | Description |
47
+ |---|---|---|
48
+ | `container` | `document.querySelector('.kplayer')` | Player container element |
49
+ | `live` | `false` | Enable live mode |
50
+ | `autoplay` | `false` | Auto play video on load |
51
+ | `theme` | `'#b7daff'` | Main accent color |
52
+ | `loop` | `false` | Loop video playback |
53
+ | `lang` | `navigator.language` | UI language: `'en'`, `'mn'`, `'zh-cn'`, `'zh-tw'`, `'ko-kr'`, `'de'`, `'ja'`, `'ru'` |
54
+ | `screenshot` | `false` | Enable screenshot button (requires CORS) |
55
+ | `airplay` | `false` | Enable AirPlay (Safari only) |
56
+ | `chromecast` | `false` | Enable Chromecast |
57
+ | `hotkey` | `true` | Enable keyboard shortcuts |
58
+ | `preload` | `'auto'` | Values: `'none'`, `'metadata'`, `'auto'` |
59
+ | `volume` | `0.7` | Default volume (0–1). Player remembers user setting |
60
+ | `playbackSpeed` | `[0.5, 0.75, 1, 1.25, 1.5, 2]` | Playback speed options |
61
+ | `logo` | — | Logo URL shown in top-left corner |
62
+ | `mutex` | `true` | Pause other players when this one starts |
63
+ | `preventClickToggle` | `false` | Prevent play/pause toggle on player click |
64
+ | `video` | — | Video configuration object (see below) |
65
+ | `subtitle` | — | Subtitle configuration object (see below) |
66
+ | `highlight` | `[]` | Time markers on the progress bar |
67
+ | `contextmenu` | `[]` | Custom right-click menu items |
68
+ | `title` | — | Title bar configuration |
69
+ | `vastAD` | `false` | Enable VAST/VMAP ad support |
70
+ | `vastADURL` | — | VAST or VMAP ad tag URL |
71
+ | `ad` | — | Custom ad configuration |
72
+ | `pluginOptions` | — | Options passed to MSE plugins (hls, flv, dash, webtorrent) |
73
+
74
+ ### `video` options
75
+
76
+ | Name | Default | Description |
77
+ |---|---|---|
78
+ | `video.url` | — | Video URL |
79
+ | `video.pic` | — | Video poster/thumbnail image |
80
+ | `video.thumbnails` | — | Preview thumbnails image strip |
81
+ | `video.type` | `'auto'` | `'auto'`, `'hls'`, `'flv'`, `'dash'`, `'webtorrent'`, `'normal'`, or custom type |
82
+ | `video.customType` | — | Custom type handler functions (see MSE section) |
83
+ | `video.quality` | — | Array of quality levels (see Quality Switching) |
84
+ | `video.defaultQuality` | `0` | Default quality index |
85
+
86
+ ### `subtitle` options
87
+
88
+ | Name | Default | Description |
89
+ |---|---|---|
90
+ | `subtitle.url` | required | Subtitle URL (string) or array of subtitle objects |
91
+ | `subtitle.type` | `'webvtt'` | Subtitle format (`'webvtt'` supported) |
92
+ | `subtitle.fontSize` | `'20px'` | Subtitle font size |
93
+ | `subtitle.bottom` | `'40px'` | Distance from player bottom (e.g. `'10px'`, `'10%'`) |
94
+ | `subtitle.color` | `'#fff'` | Subtitle text color |
95
+ | `subtitle.defaultSubtitle` | — | Default subtitle lang or name |
96
+ | `subtitle.encrypt` | `false` | Enable AES-CBC encrypted subtitles |
97
+ | `subtitle.key` | — | AES key (hex string, 32 chars) |
98
+ | `subtitle.iv` | — | AES IV (hex string, 32 chars) |
99
+
100
+ ### `title` options
101
+
102
+ | Name | Default | Description |
103
+ |---|---|---|
104
+ | `title.title` | — | Title text |
105
+ | `title.description` | — | Description / episode info |
106
+ | `title.back` | `false` | Show back button |
107
+ | `title.onBack` | — | Callback when back button is clicked |
108
+
109
+ ---
110
+
111
+ ## Full Example
112
+
113
+ ```typescript
114
+ import KPlayer from "kplayer-ts";
115
+ import type { KPlayerOptions } from "kplayer-ts";
116
+
117
+ const dp = new KPlayer({
118
+ container: document.getElementById("kplayer"),
119
+ autoplay: false,
120
+ theme: "#FF0000",
121
+ loop: true,
122
+ lang: "mn",
123
+ screenshot: true,
124
+ hotkey: true,
125
+ preload: "auto",
126
+ logo: "logo.png",
127
+ volume: 0.7,
128
+ mutex: true,
129
+ title: {
130
+ title: "Video Title",
131
+ description: "Episode 1",
132
+ back: true,
133
+ },
134
+ video: {
135
+ url: "demo.m3u8",
136
+ pic: "poster.jpg",
137
+ thumbnails: "thumbnails.jpg",
138
+ type: "hls",
139
+ },
140
+ pluginOptions: {
141
+ hls: {
142
+ debug: false,
143
+ maxBufferLength: 30,
144
+ },
145
+ },
146
+ subtitle: {
147
+ url: [
148
+ { name: "English", url: "en.vtt", lang: "en" },
149
+ { name: "Монгол", url: "mn.vtt", lang: "mn" },
150
+ ],
151
+ defaultSubtitle: "mn",
152
+ fontSize: "25px",
153
+ bottom: "10%",
154
+ color: "#ffffff",
155
+ },
156
+ highlight: [
157
+ { text: "OP Start", time: 20 },
158
+ { text: "OP End", time: 120 },
159
+ { text: "END Start", time: 520 },
160
+ { text: "END End", time: 550 },
161
+ ],
162
+ contextmenu: [
163
+ { text: "GitHub", link: "https://github.com/kenji-07" },
164
+ {
165
+ text: "Log player",
166
+ click: (player) => console.log(player),
167
+ },
168
+ ],
169
+ });
170
+ ```
171
+
172
+ ---
173
+
174
+ ## API
175
+
176
+ ```typescript
177
+ dp.play() // Play video
178
+ dp.pause() // Pause video
179
+ dp.toggle() // Toggle play/pause
180
+ dp.seek(time: number) // Seek to time in seconds
181
+ dp.speed(rate: number) // Set playback rate
182
+ dp.volume(percentage, nostorage?, nonotice?) // Set volume (0–1)
183
+ dp.notice(text, time?, opacity?) // Show notification
184
+ dp.switchQuality(index: number) // Switch quality (manual list)
185
+ dp.destroy() // Destroy player instance
186
+ ```
187
+
188
+ ### Properties
189
+
190
+ ```typescript
191
+ dp.video // Native HTMLVideoElement
192
+ dp.video.currentTime // Current playback position (seconds)
193
+ dp.video.duration // Total duration (seconds)
194
+ dp.video.paused // Whether video is paused
195
+ dp.plugins.hls // hls.js instance (when type: 'hls')
196
+ dp.plugins.flvjs // flv.js instance (when type: 'flv')
197
+ dp.plugins.dash // dash.js instance (when type: 'dash')
198
+ ```
199
+
200
+ ### Fullscreen
201
+
202
+ ```typescript
203
+ dp.fullScreen.request('browser') // Browser fullscreen
204
+ dp.fullScreen.request('web') // Web (page-level) fullscreen
205
+ dp.fullScreen.cancel('browser')
206
+ dp.fullScreen.cancel('web')
207
+ dp.fullScreen.toggle('browser')
208
+ dp.fullScreen.toggle('web')
209
+ ```
210
+
211
+ ---
212
+
213
+ ## Events
214
+
215
+ ```typescript
216
+ dp.on('play', () => console.log('playing'));
217
+ dp.on('ended', () => console.log('ended'));
218
+ ```
219
+
220
+ ### Video Events
221
+
222
+ `abort` · `canplay` · `canplaythrough` · `durationchange` · `emptied` · `ended` · `error` · `loadeddata` · `loadedmetadata` · `loadstart` · `pause` · `play` · `playing` · `progress` · `ratechange` · `seeked` · `seeking` · `stalled` · `suspend` · `timeupdate` · `volumechange` · `waiting`
223
+
224
+ ### Player Events
225
+
226
+ `screenshot` · `thumbnails_show` · `thumbnails_hide` · `contextmenu_show` · `contextmenu_hide` · `notice_show` · `notice_hide` · `quality_start` · `quality_end` · `destroy` · `resize` · `fullscreen` · `fullscreen_cancel` · `webfullscreen` · `webfullscreen_cancel` · `subtitle_show` · `subtitle_hide` · `subtitle_change` · `title_back`
227
+
228
+ ---
229
+
230
+ ## Quality Switching
231
+
232
+ ### Manual quality list
233
+
234
+ Provide a `quality` array with names and URLs. The player renders a quality menu automatically.
235
+
236
+ ```typescript
237
+ const dp = new KPlayer({
238
+ container: document.getElementById("kplayer"),
239
+ video: {
240
+ quality: [
241
+ { name: "HD", url: "demo.m3u8", type: "hls" },
242
+ { name: "SD", url: "demo.mp4", type: "normal" },
243
+ ],
244
+ defaultQuality: 0,
245
+ pic: "poster.jpg",
246
+ thumbnails: "thumbnails.jpg",
247
+ },
248
+ });
249
+ ```
250
+
251
+ ### HLS adaptive quality (auto)
252
+
253
+ When `type: 'hls'` is used, KPlayer automatically builds a quality menu from the HLS manifest levels, including an **Auto** option. Switching triggers `switching-quality` and `switched-quality` notices.
254
+
255
+ ---
256
+
257
+ ## MSE Support
258
+
259
+ ### HLS
260
+
261
+ Requires [hls.js](https://github.com/video-dev/hls.js).
262
+
263
+ ```typescript
264
+ import Hls from "hls.js";
265
+ (window as any).Hls = Hls;
266
+
267
+ const dp = new KPlayer({
268
+ container: document.getElementById("kplayer"),
269
+ video: {
270
+ url: "demo.m3u8",
271
+ type: "hls",
272
+ },
273
+ pluginOptions: {
274
+ hls: {
275
+ debug: false,
276
+ maxBufferLength: 30,
277
+ startLevel: -1, // -1 = auto
278
+ abrBandWidthFactor: 0.95,
279
+ fragLoadingMaxRetry: 6,
280
+ enableWorker: true,
281
+ // Request headers
282
+ xhrSetup: (xhr, url) => {
283
+ xhr.setRequestHeader("Authorization", "Bearer your-token");
284
+ },
285
+ },
286
+ },
287
+ });
288
+
289
+ console.log(dp.plugins.hls); // hls.js instance
290
+ ```
291
+
292
+ Using `customType`:
293
+
294
+ ```typescript
295
+ const dp = new KPlayer({
296
+ container: document.getElementById("kplayer"),
297
+ video: {
298
+ url: "demo.m3u8",
299
+ type: "customHls",
300
+ customType: {
301
+ customHls: (video, player) => {
302
+ const hls = new Hls({ debug: false });
303
+ hls.loadSource(video.src);
304
+ hls.attachMedia(video);
305
+ },
306
+ },
307
+ },
308
+ });
309
+ ```
310
+
311
+ ### MPEG-DASH
312
+
313
+ Requires [dash.js](https://github.com/Dash-Industry-Forum/dash.js).
314
+
315
+ ```typescript
316
+ const dp = new KPlayer({
317
+ container: document.getElementById("kplayer"),
318
+ video: {
319
+ url: "demo.mpd",
320
+ type: "dash",
321
+ },
322
+ pluginOptions: {
323
+ dash: {
324
+ // dash.js config
325
+ },
326
+ },
327
+ });
328
+
329
+ console.log(dp.plugins.dash); // dash.js instance
330
+ ```
331
+
332
+ ### FLV
333
+
334
+ Requires [flv.js](https://github.com/bilibili/flv.js).
335
+
336
+ ```typescript
337
+ const dp = new KPlayer({
338
+ container: document.getElementById("kplayer"),
339
+ video: {
340
+ url: "demo.flv",
341
+ type: "flv",
342
+ },
343
+ pluginOptions: {
344
+ flv: {
345
+ mediaDataSource: {},
346
+ config: {},
347
+ },
348
+ },
349
+ });
350
+
351
+ console.log(dp.plugins.flvjs); // flv.js instance
352
+ ```
353
+
354
+ ### WebTorrent
355
+
356
+ Requires [WebTorrent](https://github.com/webtorrent/webtorrent).
357
+
358
+ ```typescript
359
+ const dp = new KPlayer({
360
+ container: document.getElementById("kplayer"),
361
+ video: {
362
+ url: "magnet:?xt=...",
363
+ type: "webtorrent",
364
+ },
365
+ pluginOptions: {
366
+ webtorrent: {
367
+ // WebTorrent config
368
+ },
369
+ },
370
+ });
371
+
372
+ console.log(dp.plugins.webtorrent); // WebTorrent instance
373
+ ```
374
+
375
+ ### Custom MSE library
376
+
377
+ ```typescript
378
+ const dp = new KPlayer({
379
+ container: document.getElementById("kplayer"),
380
+ video: {
381
+ url: "demo.m3u8",
382
+ type: "customHls",
383
+ customType: {
384
+ customHls: (video, player) => {
385
+ const hls = new Hls({
386
+ p2pConfig: { live: false },
387
+ });
388
+ hls.loadSource(video.src);
389
+ hls.attachMedia(video);
390
+ },
391
+ },
392
+ },
393
+ });
394
+ ```
395
+
396
+ ---
397
+
398
+ ## Ads
399
+
400
+ ### Custom ads (image / text / video)
401
+
402
+ ```typescript
403
+ const dp = new KPlayer({
404
+ container: document.getElementById("kplayer"),
405
+ video: { url: "demo.mp4" },
406
+ ad: {
407
+ url: [
408
+ {
409
+ name: "Intro image ad",
410
+ type: "image",
411
+ url: "ad-banner.png",
412
+ deeplink: "https://example.com",
413
+ startTime: 0,
414
+ skipTime: 5,
415
+ },
416
+ {
417
+ name: "Mid-roll video ad",
418
+ type: "video",
419
+ url: "ad-video.mp4",
420
+ startTime: 120,
421
+ skipTime: 10,
422
+ },
423
+ {
424
+ name: "Text ad",
425
+ type: "text",
426
+ url: "Special offer – click to learn more",
427
+ backroundColor: "FF0000",
428
+ deeplink: "https://example.com",
429
+ startTime: 300,
430
+ skipTime: 5,
431
+ },
432
+ ],
433
+ },
434
+ });
435
+ ```
436
+
437
+ ### VAST / VMAP
438
+
439
+ ```typescript
440
+ const dp = new KPlayer({
441
+ container: document.getElementById("kplayer"),
442
+ video: { url: "demo.mp4" },
443
+ vastAD: true,
444
+ vastADURL: "https://your-ad-server.com/vmap.xml",
445
+ });
446
+ ```
447
+
448
+ ---
449
+
450
+ ## Keyboard Shortcuts
451
+
452
+ | Key | Action |
453
+ |---|---|
454
+ | `Space` | Play / Pause |
455
+ | `←` | Seek back 10s |
456
+ | `→` | Seek forward 10s |
457
+ | `↑` | Volume up |
458
+ | `↓` | Volume down |
459
+ | `Esc` | Exit web fullscreen |
460
+
461
+ ---
462
+
463
+ ## License
464
+
465
+ MIT
466
+
467
+ ---
468
+
469
+ ## Donation
470
+
471
+ If KPlayer has been useful to you, consider supporting its development. Your contribution helps keep the project maintained and growing.
472
+
473
+ | Platform | Link |
474
+ |---|---|
475
+ | 💖 GitHub Sponsors | [github.com/sponsors/kenji-07](https://github.com/sponsors/kenji-07) |
476
+
477
+ Thank you to all contributors and supporters! 🙏