@gcorevideo/player 2.29.0 → 2.30.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 +108 -0
- package/dist/core.js +81 -22
- package/dist/index.css +370 -370
- package/dist/index.embed.js +80 -23
- package/dist/index.js +459 -87
- package/docs/api/player.md +37 -0
- package/docs/api/player.player.getplugin.md +59 -0
- package/docs/api/player.player.md +14 -0
- package/docs/api/player.tokenrefreshoptions.gettoken.md +13 -0
- package/docs/api/player.tokenrefreshoptions.ipbound.md +13 -0
- package/docs/api/player.tokenrefreshoptions.md +115 -0
- package/docs/api/player.tokenrefreshoptions.ontokenrefreshed.md +13 -0
- package/docs/api/player.tokenrefreshoptions.refreshleadseconds.md +13 -0
- package/docs/api/player.tokenrefreshplugin.md +50 -0
- package/docs/api/player.tokenresponse.client_ip.md +13 -0
- package/docs/api/player.tokenresponse.expires.md +13 -0
- package/docs/api/player.tokenresponse.md +153 -0
- package/docs/api/player.tokenresponse.token.md +13 -0
- package/docs/api/player.tokenresponse.token_ip.md +13 -0
- package/docs/api/player.tokenresponse.url.md +13 -0
- package/docs/api/player.tokenresponse.url_ip.md +13 -0
- package/lib/Player.d.ts +9 -0
- package/lib/Player.d.ts.map +1 -1
- package/lib/Player.js +11 -0
- package/lib/index.plugins.d.ts +1 -0
- package/lib/index.plugins.d.ts.map +1 -1
- package/lib/index.plugins.js +1 -0
- package/lib/playback/dash-playback/DashPlayback.d.ts.map +1 -1
- package/lib/playback/dash-playback/DashPlayback.js +5 -1
- package/lib/playback/hls-playback/HlsPlayback.d.ts +1 -1
- package/lib/playback/hls-playback/HlsPlayback.d.ts.map +1 -1
- package/lib/playback/hls-playback/HlsPlayback.js +23 -20
- package/lib/playback/hls-playback/RangesList.d.ts +7 -0
- package/lib/playback/hls-playback/RangesList.d.ts.map +1 -0
- package/lib/playback/hls-playback/RangesList.js +41 -0
- package/lib/plugins/subtitles/ClosedCaptions.d.ts.map +1 -1
- package/lib/plugins/subtitles/ClosedCaptions.js +0 -2
- package/lib/plugins/token-refresh/TokenRefreshPlugin.d.ts +119 -0
- package/lib/plugins/token-refresh/TokenRefreshPlugin.d.ts.map +1 -0
- package/lib/plugins/token-refresh/TokenRefreshPlugin.js +318 -0
- package/lib/plugins/token-refresh/index.d.ts +2 -0
- package/lib/plugins/token-refresh/index.d.ts.map +1 -0
- package/lib/plugins/token-refresh/index.js +1 -0
- package/package.json +1 -1
- package/src/Player.ts +12 -0
- package/src/index.plugins.ts +1 -0
- package/src/playback/dash-playback/DashPlayback.ts +6 -1
- package/src/playback/hls-playback/HlsPlayback.ts +40 -37
- package/src/playback/hls-playback/RangesList.ts +45 -0
- package/src/playback/hls-playback/__tests__/RangesList.test.ts +60 -0
- package/src/plugins/subtitles/ClosedCaptions.ts +0 -5
- package/src/plugins/token-refresh/TokenRefreshPlugin.ts +425 -0
- package/src/plugins/token-refresh/index.ts +5 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -145,6 +145,7 @@ export default class DashPlayback extends BasePlayback {
|
|
|
145
145
|
this._dash = dash;
|
|
146
146
|
this._dash.initialize();
|
|
147
147
|
if (this.options.dash) {
|
|
148
|
+
const { requestInterceptor, ...dashSettings } = this.options.dash;
|
|
148
149
|
const settings = $.extend(true, {
|
|
149
150
|
streaming: {
|
|
150
151
|
text: {
|
|
@@ -156,8 +157,11 @@ export default class DashPlayback extends BasePlayback {
|
|
|
156
157
|
// dispatchForManualRendering: true, // TODO only when useNativeSubtitles is not true?
|
|
157
158
|
},
|
|
158
159
|
},
|
|
159
|
-
},
|
|
160
|
+
}, dashSettings);
|
|
160
161
|
this._dash.updateSettings(settings);
|
|
162
|
+
if (typeof requestInterceptor === 'function') {
|
|
163
|
+
this._dash.addRequestInterceptor(requestInterceptor);
|
|
164
|
+
}
|
|
161
165
|
}
|
|
162
166
|
this._dash.attachView(this.el);
|
|
163
167
|
this._dash.setAutoPlay(false);
|
|
@@ -5,7 +5,6 @@ import { BasePlayback } from '../BasePlayback.js';
|
|
|
5
5
|
import { AudioTrack } from '@clappr/core/types/base/playback/playback.js';
|
|
6
6
|
import { VTTCueInfo } from '../types.js';
|
|
7
7
|
export default class HlsPlayback extends BasePlayback {
|
|
8
|
-
private _ccTracksUpdated;
|
|
9
8
|
private _currentFragment;
|
|
10
9
|
private _currentLevel;
|
|
11
10
|
private _durationExcludesAfterLiveSyncPoint;
|
|
@@ -33,6 +32,7 @@ export default class HlsPlayback extends BasePlayback {
|
|
|
33
32
|
id: string;
|
|
34
33
|
}) => void) | null;
|
|
35
34
|
private cues;
|
|
35
|
+
private cuesByTrack;
|
|
36
36
|
private currentCueId;
|
|
37
37
|
/**
|
|
38
38
|
* @internal
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HlsPlayback.d.ts","sourceRoot":"","sources":["../../../src/playback/hls-playback/HlsPlayback.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,EACZ,MAAM,IAAI,SAAS,EAMnB,KAAK,kBAAkB,EAMxB,MAAM,QAAQ,CAAA;AAEf,OAAO,EAIL,YAAY,EAEb,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAG7C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAGjD,OAAO,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAA;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"HlsPlayback.d.ts","sourceRoot":"","sources":["../../../src/playback/hls-playback/HlsPlayback.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,13 +9,13 @@ import { PlaybackErrorCode, } from '../../playback.types.js';
|
|
|
9
9
|
import { isHlsSource } from '../../utils/mediaSources.js';
|
|
10
10
|
import { BasePlayback } from '../BasePlayback.js';
|
|
11
11
|
import { CLAPPR_VERSION } from '../../build.js';
|
|
12
|
+
import { RangesList } from './RangesList.js';
|
|
12
13
|
const { now } = Utils;
|
|
13
14
|
const AUTO = -1;
|
|
14
15
|
const DEFAULT_RECOVER_ATTEMPTS = 16;
|
|
15
16
|
Events.register('PLAYBACK_FRAGMENT_PARSING_METADATA');
|
|
16
17
|
const T = 'playback.hls';
|
|
17
18
|
export default class HlsPlayback extends BasePlayback {
|
|
18
|
-
_ccTracksUpdated = false;
|
|
19
19
|
_currentFragment = null;
|
|
20
20
|
_currentLevel = null;
|
|
21
21
|
_durationExcludesAfterLiveSyncPoint = false;
|
|
@@ -40,7 +40,8 @@ export default class HlsPlayback extends BasePlayback {
|
|
|
40
40
|
_timeUpdateTimer = null;
|
|
41
41
|
oncueenter = null;
|
|
42
42
|
oncueexit = null;
|
|
43
|
-
cues =
|
|
43
|
+
cues = null;
|
|
44
|
+
cuesByTrack = {};
|
|
44
45
|
currentCueId = null;
|
|
45
46
|
/**
|
|
46
47
|
* @internal
|
|
@@ -237,7 +238,6 @@ export default class HlsPlayback extends BasePlayback {
|
|
|
237
238
|
}
|
|
238
239
|
this._manifestParsed = false;
|
|
239
240
|
// this._ccIsSetup = false
|
|
240
|
-
this._ccTracksUpdated = false;
|
|
241
241
|
this._setInitialState();
|
|
242
242
|
this._hls.destroy();
|
|
243
243
|
this._hls = null;
|
|
@@ -291,12 +291,20 @@ export default class HlsPlayback extends BasePlayback {
|
|
|
291
291
|
this._hls.on(HlsEvents.AUDIO_TRACK_SWITCHED, (evt, data) => this._onAudioTrackSwitched(evt, data));
|
|
292
292
|
this._hls.on(HlsEvents.CUES_PARSED, (evt, data) => {
|
|
293
293
|
data.cues?.forEach((cue) => {
|
|
294
|
-
this.cues
|
|
294
|
+
if (!this.cues) {
|
|
295
|
+
const trackId = this._hls.subtitleTrack;
|
|
296
|
+
if (!this.cuesByTrack[trackId]) {
|
|
297
|
+
this.cuesByTrack[trackId] = new RangesList();
|
|
298
|
+
}
|
|
299
|
+
this.cues = this.cuesByTrack[trackId];
|
|
300
|
+
}
|
|
301
|
+
const cueInfo = {
|
|
295
302
|
id: cue.id,
|
|
296
303
|
start: cue.startTime,
|
|
297
304
|
end: cue.endTime,
|
|
298
305
|
text: cue.text,
|
|
299
|
-
}
|
|
306
|
+
};
|
|
307
|
+
this.cues.insert(cue.startTime, cue.endTime, cueInfo);
|
|
300
308
|
});
|
|
301
309
|
});
|
|
302
310
|
this.bindCustomListeners();
|
|
@@ -523,7 +531,7 @@ export default class HlsPlayback extends BasePlayback {
|
|
|
523
531
|
}
|
|
524
532
|
}
|
|
525
533
|
reload() {
|
|
526
|
-
this.cues =
|
|
534
|
+
this.cues = null;
|
|
527
535
|
this.currentCueId = null;
|
|
528
536
|
this._hls?.startLoad(-1);
|
|
529
537
|
}
|
|
@@ -588,9 +596,7 @@ export default class HlsPlayback extends BasePlayback {
|
|
|
588
596
|
}
|
|
589
597
|
triggerCues() {
|
|
590
598
|
const currentTime = this.getCurrentTime();
|
|
591
|
-
|
|
592
|
-
// TODO build a search tree
|
|
593
|
-
const cue = this.cues.find((cue) => currentTime >= cue.start && currentTime <= cue.end);
|
|
599
|
+
const cue = this.cues?.find(currentTime);
|
|
594
600
|
if (cue) {
|
|
595
601
|
this.currentCueId = cue.id;
|
|
596
602
|
this.oncueenter?.(cue);
|
|
@@ -634,20 +640,14 @@ export default class HlsPlayback extends BasePlayback {
|
|
|
634
640
|
destroy() {
|
|
635
641
|
this._stopTimeUpdateTimer();
|
|
636
642
|
this._destroyHLSInstance();
|
|
643
|
+
this.cues = null;
|
|
644
|
+
this.cuesByTrack = {};
|
|
637
645
|
return super.destroy();
|
|
638
646
|
}
|
|
639
647
|
_updatePlaybackType(evt, data) {
|
|
640
648
|
const prevPlaybackType = this._playbackType;
|
|
641
649
|
this._playbackType = (data.details.live ? Playback.LIVE : Playback.VOD);
|
|
642
650
|
this._onLevelUpdated(evt, data);
|
|
643
|
-
// Live stream subtitle tracks detection hack (may not immediately available)
|
|
644
|
-
// if (
|
|
645
|
-
// this._ccTracksUpdated &&
|
|
646
|
-
// this._playbackType === Playback.LIVE &&
|
|
647
|
-
// this.hasClosedCaptionsTracks
|
|
648
|
-
// ) {
|
|
649
|
-
// this._onSubtitleLoaded()
|
|
650
|
-
// }
|
|
651
651
|
if (prevPlaybackType !== this._playbackType) {
|
|
652
652
|
this._updateSettings();
|
|
653
653
|
}
|
|
@@ -868,7 +868,10 @@ export default class HlsPlayback extends BasePlayback {
|
|
|
868
868
|
return;
|
|
869
869
|
}
|
|
870
870
|
this._hls.subtitleTrack = id;
|
|
871
|
-
this.
|
|
871
|
+
if (!this.cuesByTrack[id]) {
|
|
872
|
+
this.cuesByTrack[id] = new RangesList();
|
|
873
|
+
}
|
|
874
|
+
this.cues = this.cuesByTrack[id];
|
|
872
875
|
}
|
|
873
876
|
/**
|
|
874
877
|
* @override
|
|
@@ -877,7 +880,7 @@ export default class HlsPlayback extends BasePlayback {
|
|
|
877
880
|
return this.getTextTracks();
|
|
878
881
|
}
|
|
879
882
|
getTextTracks() {
|
|
880
|
-
return this._hls?.subtitleTracks.map((t) => ({
|
|
883
|
+
return (this._hls?.subtitleTracks.map((t) => ({
|
|
881
884
|
id: t.id,
|
|
882
885
|
name: t.name,
|
|
883
886
|
track: {
|
|
@@ -885,7 +888,7 @@ export default class HlsPlayback extends BasePlayback {
|
|
|
885
888
|
label: t.name,
|
|
886
889
|
language: t.lang,
|
|
887
890
|
},
|
|
888
|
-
})) || [];
|
|
891
|
+
})) || []);
|
|
889
892
|
}
|
|
890
893
|
}
|
|
891
894
|
HlsPlayback.canPlay = function (resource, mimeType) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RangesList.d.ts","sourceRoot":"","sources":["../../../src/playback/hls-playback/RangesList.ts"],"names":[],"mappings":"AACA,qBAAa,UAAU,CAAC,CAAC;IAEvB,OAAO,CAAC,KAAK,CAAkC;IAE/C,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAK3C,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI;IAShC,OAAO,CAAC,SAAS;CAyBlB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export class RangesList {
|
|
2
|
+
// TODO write an efficient implementation
|
|
3
|
+
items = [];
|
|
4
|
+
insert(start, end, value) {
|
|
5
|
+
const index = this.findIndex((start + end) / 2);
|
|
6
|
+
this.items.splice(index, 0, [start, end, value]);
|
|
7
|
+
}
|
|
8
|
+
find(position) {
|
|
9
|
+
const index = this.findIndex(position);
|
|
10
|
+
const item = this.items[index];
|
|
11
|
+
if (!item || item[0] > position || item[1] < position) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
return item[2];
|
|
15
|
+
}
|
|
16
|
+
findIndex(position) {
|
|
17
|
+
let low = 0;
|
|
18
|
+
let high = this.items.length;
|
|
19
|
+
let index = 0;
|
|
20
|
+
while (low < high) {
|
|
21
|
+
index = low + Math.floor((high - low) / 2);
|
|
22
|
+
const item = this.items[index];
|
|
23
|
+
if (item[0] > position) {
|
|
24
|
+
if (index === low) {
|
|
25
|
+
return index;
|
|
26
|
+
}
|
|
27
|
+
high = index;
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (item[1] <= position) {
|
|
31
|
+
if (index === high - 1) {
|
|
32
|
+
return index + 1;
|
|
33
|
+
}
|
|
34
|
+
low = index + 1;
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
return index;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClosedCaptions.d.ts","sourceRoot":"","sources":["../../../src/plugins/subtitles/ClosedCaptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,YAAY,EAAwB,MAAM,cAAc,CAAA;AAOzE,OAAO,+BAA+B,CAAA;
|
|
1
|
+
{"version":3,"file":"ClosedCaptions.d.ts","sourceRoot":"","sources":["../../../src/plugins/subtitles/ClosedCaptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,YAAY,EAAwB,MAAM,cAAc,CAAA;AAOzE,OAAO,+BAA+B,CAAA;AAgBtC;;;GAGG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAA;CAC3B,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,qBAAa,cAAe,SAAQ,YAAY;IAC9C,OAAO,CAAC,iBAAiB,CAAQ;IAEjC,OAAO,CAAC,MAAM,CAAQ;IAEtB,OAAO,CAAC,IAAI,CAAQ;IAEpB,OAAO,CAAC,kBAAkB,CAAa;IAEvC,OAAO,CAAC,KAAK,CAA6B;IAE1C,OAAO,CAAC,MAAM,CAAsB;IAEpC,OAAO,CAAC,KAAK,CAA2B;IAExC;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,IAAI,gBAAgB;;MAEnB;IAED;;OAEG;IACH,MAAM,KAAK,OAAO,WAEjB;IAED,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAyB;IAEhE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAuB;IAE3D;;OAEG;IACH,IAAa,UAAU;;MAItB;IAED;;OAEG;IACH,IAAa,MAAM;;;MAKlB;IAED,OAAO,KAAK,mBAAmB,GAI9B;IAED,OAAO,CAAC,qBAAqB;IAO7B;;OAEG;IACM,UAAU;IAWnB,OAAO,CAAC,WAAW;IAuBnB,OAAO,CAAC,kBAAkB;IAiD1B,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,mBAAmB;IAK3B,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,aAAa;IAuCrB,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,iBAAiB;IAqBzB;;OAEG;IACH,IAAI;IAcJ;;OAEG;IACH,IAAI;IAgBJ,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,UAAU;IAUlB;;OAEG;IACM,MAAM;IAmCf,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,UAAU;IAWlB,OAAO,CAAC,YAAY;IAapB,OAAO,CAAC,sBAAsB;IAwB9B,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,yBAAyB;IAiBjC,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,KAAK;IAOb,OAAO,KAAK,kBAAkB,GAO7B;IAED,OAAO,KAAK,aAAa,GAExB;IAED,OAAO,KAAK,YAAY,GAEvB;IAED,OAAO,KAAK,YAAY,QAEvB;IAED,OAAO,KAAK,aAAa,QAMxB;IAED,OAAO,CAAC,SAAS,CAA+C;CACjE"}
|
|
@@ -331,8 +331,6 @@ export class ClosedCaptions extends UICorePlugin {
|
|
|
331
331
|
// event.target does not exist for some reason in tests
|
|
332
332
|
const id = Number((event.target ?? event.currentTarget).dataset?.item ??
|
|
333
333
|
'-1');
|
|
334
|
-
// TODO review, make configurable, and emit event in addition
|
|
335
|
-
// localStorage.setItem(LOCAL_STORAGE_CC_ID, id) // TODO store language instead?
|
|
336
334
|
this.userSelectedItemId = id;
|
|
337
335
|
this.selectItem(this.findById(id));
|
|
338
336
|
this.hideMenu();
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { CorePlugin } from '@clappr/core';
|
|
2
|
+
/**
|
|
3
|
+
* Response shape expected from your token-refresh API endpoint.
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export interface TokenResponse {
|
|
7
|
+
/** Plain (non-IP-bound) secure token */
|
|
8
|
+
token: string;
|
|
9
|
+
/** IP-bound secure token */
|
|
10
|
+
token_ip: string;
|
|
11
|
+
/** Client IP address (informational) */
|
|
12
|
+
client_ip: string;
|
|
13
|
+
/** Unix timestamp (seconds) when both tokens expire */
|
|
14
|
+
expires: number;
|
|
15
|
+
/** Ready-to-use HLS master playlist URL with plain token embedded */
|
|
16
|
+
url: string;
|
|
17
|
+
/** Ready-to-use HLS master playlist URL with IP-bound token embedded */
|
|
18
|
+
url_ip: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Configuration options for {@link TokenRefreshPlugin}.
|
|
22
|
+
* @public
|
|
23
|
+
*/
|
|
24
|
+
export interface TokenRefreshOptions {
|
|
25
|
+
/**
|
|
26
|
+
* Async function called each time a fresh token is needed.
|
|
27
|
+
* Must return a {@link TokenResponse}.
|
|
28
|
+
*/
|
|
29
|
+
getToken: () => Promise<TokenResponse>;
|
|
30
|
+
/**
|
|
31
|
+
* When `true`, the IP-bound variant (`token_ip` / `url_ip`) is used.
|
|
32
|
+
* Defaults to `false`.
|
|
33
|
+
*/
|
|
34
|
+
ipBound?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Seconds before the token expiry timestamp to request a fresh token.
|
|
37
|
+
* Defaults to `5`.
|
|
38
|
+
*/
|
|
39
|
+
refreshLeadSeconds?: number;
|
|
40
|
+
/**
|
|
41
|
+
* Optional callback invoked after every successful token refresh.
|
|
42
|
+
*/
|
|
43
|
+
onTokenRefreshed?: (data: TokenResponse) => void;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* `PLUGIN` — automatic token refresh for Gcore protected-content streams.
|
|
47
|
+
*
|
|
48
|
+
* Supports all three playback engines:
|
|
49
|
+
*
|
|
50
|
+
* | Engine | Mechanism | Interruption |
|
|
51
|
+
* |--------|-----------|--------------|
|
|
52
|
+
* | **hls.js** | Custom loader rewrites every request URL | None |
|
|
53
|
+
* | **dash.js** | `addRequestInterceptor` rewrites every request URL | None |
|
|
54
|
+
* | **Native `<video>`** (Safari ≤ iOS 14.4) | Source reload + seek restore | Brief |
|
|
55
|
+
*
|
|
56
|
+
* @public
|
|
57
|
+
* @remarks
|
|
58
|
+
* Register the plugin once before creating any player instance:
|
|
59
|
+
* ```ts
|
|
60
|
+
* import { Player, TokenRefreshPlugin } from '@gcorevideo/player'
|
|
61
|
+
* Player.registerPlugin(TokenRefreshPlugin)
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* Then pass `tokenRefresh` in `PlayerConfig`:
|
|
65
|
+
* ```ts
|
|
66
|
+
* const player = new Player({
|
|
67
|
+
* sources: [{ source: initialUrl, mimeType: 'application/x-mpegURL' }],
|
|
68
|
+
* tokenRefresh: {
|
|
69
|
+
* getToken: () => fetch('https://…/token').then(r => r.json()),
|
|
70
|
+
* ipBound: false,
|
|
71
|
+
* refreshLeadSeconds: 5,
|
|
72
|
+
* onTokenRefreshed: (data) => console.log('new token expires', data.expires),
|
|
73
|
+
* },
|
|
74
|
+
* })
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* Safari native — opt-in Service Worker for fully seamless refresh:
|
|
79
|
+
* ```js
|
|
80
|
+
* // Register token-refresh-sw.js (see example/ directory)
|
|
81
|
+
* // and omit tokenRefresh config — the SW handles rewriting.
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
export declare class TokenRefreshPlugin extends CorePlugin {
|
|
85
|
+
/** @internal */
|
|
86
|
+
static get type(): 'core';
|
|
87
|
+
/** @internal */
|
|
88
|
+
get name(): string;
|
|
89
|
+
/** @internal */
|
|
90
|
+
get supportedVersion(): {
|
|
91
|
+
min: string;
|
|
92
|
+
};
|
|
93
|
+
/** Token state extracted from the currently-managed source URL */
|
|
94
|
+
private originalState;
|
|
95
|
+
/** Latest token state (updated after each refresh) */
|
|
96
|
+
private currentState;
|
|
97
|
+
/** Scheduled refresh timer handle */
|
|
98
|
+
private refreshTimer;
|
|
99
|
+
/** Playback time (seconds) to restore after a native-video source reload */
|
|
100
|
+
private savedPosition;
|
|
101
|
+
/** True when using native HTML5 Video playback (no request interception) */
|
|
102
|
+
private isNativePlayback;
|
|
103
|
+
/** Set in destroy(); short-circuits late timer callbacks and getToken() resolutions */
|
|
104
|
+
private destroyed;
|
|
105
|
+
/** @internal */
|
|
106
|
+
bindEvents(): void;
|
|
107
|
+
/** @internal */
|
|
108
|
+
destroy(): void;
|
|
109
|
+
private onContainersCreated;
|
|
110
|
+
private injectHlsLoader;
|
|
111
|
+
private injectDashInterceptor;
|
|
112
|
+
private reloadNativeSource;
|
|
113
|
+
private onActiveContainerChangedForNative;
|
|
114
|
+
private scheduleRefresh;
|
|
115
|
+
private performRefresh;
|
|
116
|
+
private get opts();
|
|
117
|
+
private clearTimer;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=TokenRefreshPlugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TokenRefreshPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/token-refresh/TokenRefreshPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,UAAU,EAAU,MAAM,cAAc,CAAA;AAQrE;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAA;IACb,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAA;IACjB,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAA;IACf,qEAAqE;IACrE,GAAG,EAAE,MAAM,CAAA;IACX,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,QAAQ,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAA;IACtC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B;;OAEG;IACH,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAA;CACjD;AAgED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,qBAAa,kBAAmB,SAAQ,UAAU;IAChD,gBAAgB;IAChB,MAAM,KAAK,IAAI,IAAI,MAAM,CAExB;IAED,gBAAgB;IAChB,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,gBAAgB;IAChB,IAAI,gBAAgB;;MAEnB;IAED,kEAAkE;IAClE,OAAO,CAAC,aAAa,CAA0B;IAC/C,sDAAsD;IACtD,OAAO,CAAC,YAAY,CAA0B;IAC9C,qCAAqC;IACrC,OAAO,CAAC,YAAY,CAA6C;IACjE,4EAA4E;IAC5E,OAAO,CAAC,aAAa,CAAsB;IAC3C,4EAA4E;IAC5E,OAAO,CAAC,gBAAgB,CAAQ;IAChC,uFAAuF;IACvF,OAAO,CAAC,SAAS,CAAQ;IAEzB,gBAAgB;IACP,UAAU,IAAI,IAAI;IAQ3B,gBAAgB;IACP,OAAO,IAAI,IAAI;IAMxB,OAAO,CAAC,mBAAmB;IA8D3B,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,qBAAqB;YAmBf,kBAAkB;IA+ChC,OAAO,CAAC,iCAAiC;IAiBzC,OAAO,CAAC,eAAe;YAmBT,cAAc;IAmC5B,OAAO,KAAK,IAAI,GAEf;IAED,OAAO,CAAC,UAAU;CAMnB"}
|