@gcorevideo/player 2.28.35 → 2.29.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 +22 -1
- package/assets/{subtitles → cc}/style.scss +5 -0
- package/assets/media-control/media-control.scss +8 -6
- package/assets/multi-camera/multicamera.ejs +27 -23
- package/assets/multi-camera/style.scss +7 -34
- package/assets/style/main.scss +2 -2
- package/dist/core.js +24 -28
- package/dist/index.css +384 -402
- package/dist/index.embed.js +54 -84
- package/dist/index.js +122 -219
- package/docs/api/player.md +22 -9
- package/docs/api/player.mediacontrol.setkeepvisible.md +56 -0
- package/docs/api/player.multicamera.md +0 -28
- package/docs/api/player.multiccamerasourceinfo.md +27 -0
- package/docs/api/{player.multicamera.unbindevents.md → player.multisourcesmode.md} +4 -7
- package/docs/api/player.sourcecontroller.md +0 -37
- package/lib/playback/BasePlayback.d.ts +1 -0
- package/lib/playback/BasePlayback.d.ts.map +1 -1
- package/lib/playback/BasePlayback.js +3 -0
- package/lib/playback/dash-playback/DashPlayback.d.ts +3 -1
- package/lib/playback/dash-playback/DashPlayback.d.ts.map +1 -1
- package/lib/playback/dash-playback/DashPlayback.js +9 -22
- package/lib/playback/hls-playback/HlsPlayback.d.ts +2 -1
- package/lib/playback/hls-playback/HlsPlayback.d.ts.map +1 -1
- package/lib/playback/hls-playback/HlsPlayback.js +4 -0
- package/lib/playback/types.d.ts +9 -0
- package/lib/playback/types.d.ts.map +1 -1
- package/lib/playback.types.d.ts +0 -6
- package/lib/playback.types.d.ts.map +1 -1
- package/lib/plugins/multi-camera/MultiCamera.d.ts +21 -4
- package/lib/plugins/multi-camera/MultiCamera.d.ts.map +1 -1
- package/lib/plugins/multi-camera/MultiCamera.js +70 -134
- package/lib/plugins/source-controller/SourceController.d.ts +0 -39
- package/lib/plugins/source-controller/SourceController.d.ts.map +1 -1
- package/lib/plugins/source-controller/SourceController.js +0 -39
- package/lib/plugins/subtitles/ClosedCaptions.d.ts +1 -1
- package/lib/plugins/subtitles/ClosedCaptions.d.ts.map +1 -1
- package/lib/plugins/subtitles/ClosedCaptions.js +32 -22
- package/lib/testUtils.d.ts +1 -0
- package/lib/testUtils.d.ts.map +1 -1
- package/lib/testUtils.js +3 -0
- package/lib/utils/mediaSources.d.ts +4 -0
- package/lib/utils/mediaSources.d.ts.map +1 -1
- package/lib/utils/mediaSources.js +8 -6
- package/package.json +1 -1
- package/src/playback/BasePlayback.ts +4 -0
- package/src/playback/dash-playback/DashPlayback.ts +11 -29
- package/src/playback/hls-playback/HlsPlayback.ts +5 -1
- package/src/playback/types.ts +10 -0
- package/src/playback.types.ts +0 -6
- package/src/plugins/multi-camera/MultiCamera.ts +103 -166
- package/src/plugins/source-controller/SourceController.ts +0 -39
- package/src/plugins/subtitles/ClosedCaptions.ts +35 -21
- package/src/plugins/subtitles/__tests__/ClosedCaptions.test.ts +73 -112
- package/src/plugins/subtitles/__tests__/__snapshots__/ClosedCaptions.test.ts.snap +3 -3
- package/src/testUtils.ts +3 -0
- package/src/utils/mediaSources.ts +10 -6
- package/tsconfig.tsbuildinfo +1 -1
- package/docs/api/player.multicamera.activebyid.md +0 -67
- /package/assets/{subtitles → cc}/combobox.ejs +0 -0
- /package/assets/{subtitles → cc}/string.ejs +0 -0
package/README.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# Gcore video player
|
|
2
|
+
|
|
2
3
|
$
|
|
3
4
|
|
|
4
5
|
## Installation
|
|
@@ -15,7 +16,7 @@ Or use a script on the CDN directly in your HTML:
|
|
|
15
16
|
|
|
16
17
|
## Usage
|
|
17
18
|
|
|
18
|
-
See the complete example app on Vercel:
|
|
19
|
+
See the complete example app on Vercel: <https://github.com/dmitritz/gcore-videoplayer-js-nuxt>
|
|
19
20
|
|
|
20
21
|
### Plain HTML example
|
|
21
22
|
|
|
@@ -83,3 +84,23 @@ See the complete example app on Vercel: [https://github.com/dmitritz/gcore-video
|
|
|
83
84
|
## Documentation
|
|
84
85
|
|
|
85
86
|
- [API reference](./docs/api/index.md)
|
|
87
|
+
|
|
88
|
+
## Development
|
|
89
|
+
|
|
90
|
+
### Log level
|
|
91
|
+
|
|
92
|
+
Detailed logs can be useful in local development while debugging or watching tests output.
|
|
93
|
+
Log level of the player core and components can be controlled by configuring a LogTracer:
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import { LogTracer, Logger, setTracer } from '@gcorevideo/utils'
|
|
97
|
+
// ...
|
|
98
|
+
Logger.enable('*') // log everything; you can use glob-like patterns, such as 'gplayer', 'plugins.*' or 'playback.*'
|
|
99
|
+
setTracer(new LogTracer('AudioTracks.test'))
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
When debugging an app that use the player as a dependency,
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
import { LogTracer, Logger, setTracer } from '@gcorevideo/player'
|
|
106
|
+
```
|
|
@@ -186,6 +186,7 @@
|
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
.media-control-indicator {
|
|
189
|
+
|
|
189
190
|
&[data-position],
|
|
190
191
|
&[data-duration] {
|
|
191
192
|
display: flex;
|
|
@@ -394,6 +395,7 @@
|
|
|
394
395
|
}
|
|
395
396
|
}
|
|
396
397
|
}
|
|
398
|
+
|
|
397
399
|
.seek-time {
|
|
398
400
|
height: 26px;
|
|
399
401
|
line-height: 26px;
|
|
@@ -472,37 +474,37 @@
|
|
|
472
474
|
font-size: var(--gplayer-mc-font-size-dropdown);
|
|
473
475
|
text-align: right;
|
|
474
476
|
height: 30px;
|
|
475
|
-
|
|
477
|
+
|
|
476
478
|
a {
|
|
477
479
|
display: block;
|
|
478
480
|
text-decoration: none;
|
|
479
481
|
text-overflow: ellipsis;
|
|
480
482
|
overflow: hidden;
|
|
481
483
|
white-space: nowrap;
|
|
482
|
-
|
|
484
|
+
|
|
483
485
|
// height: 30px;
|
|
484
486
|
padding: 5px 10px;
|
|
485
487
|
line-height: 20px;
|
|
486
488
|
color: #fffffe; // TODO color var
|
|
487
|
-
|
|
489
|
+
|
|
488
490
|
&:hover {
|
|
489
491
|
text-decoration: none;
|
|
490
492
|
background-color: rgb(0 0 0 / 40%);
|
|
491
493
|
color: var(--gplayer-mc-text-color);
|
|
492
494
|
}
|
|
493
495
|
}
|
|
494
|
-
|
|
496
|
+
|
|
495
497
|
&.current a {
|
|
496
498
|
color: #f00;
|
|
497
499
|
}
|
|
498
|
-
|
|
500
|
+
|
|
499
501
|
&:first-child {
|
|
500
502
|
a {
|
|
501
503
|
border-bottom-left-radius: 4px;
|
|
502
504
|
border-bottom-right-radius: 4px;
|
|
503
505
|
}
|
|
504
506
|
}
|
|
505
|
-
|
|
507
|
+
|
|
506
508
|
&:last-child {
|
|
507
509
|
a {
|
|
508
510
|
border-top-left-radius: 4px;
|
|
@@ -1,29 +1,33 @@
|
|
|
1
|
-
<button data-multicamera-button class='gcore-skin-button-color'>
|
|
1
|
+
<button data-multicamera-button class='gcore-skin-button-color media-control-button'>
|
|
2
2
|
<span class="multicamera-icon"></span>
|
|
3
3
|
</button>
|
|
4
4
|
|
|
5
5
|
<ul class="gcore-skin-bg-color">
|
|
6
|
-
<% for (var i
|
|
7
|
-
<% if(!streams[i].live && multisources_mode
|
|
6
|
+
<% for (var i=0; i < streams.length; i++) { %>
|
|
7
|
+
<% if(!streams[i].live && multisources_mode==='only_live' ) { %>
|
|
8
8
|
<% continue; %>
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
<% } %>
|
|
10
|
+
<li>
|
|
11
|
+
<div class="multicamera-item" data-multicamera-selector-live="<%= streams[i].live %>"
|
|
12
|
+
data-multicamera-selector-select="<%= streams[i].id %>">
|
|
13
|
+
<div class="multicamera-screenshot">
|
|
14
|
+
<% if (streams[i].screenshot) { %>
|
|
15
|
+
<img src="<%= streams[i].screenshot %>" alt="<%= streams[i].title %>" />
|
|
16
|
+
<% } %>
|
|
17
|
+
</div>
|
|
18
|
+
<div class="multicamera-text gcore-skin-text-color">
|
|
19
|
+
<% if (streams[i].title) { %>
|
|
20
|
+
<div class="multicamera-title gcore-skin-text-color">
|
|
21
|
+
<%= streams[i].title %>
|
|
22
|
+
</div>
|
|
23
|
+
<% } %>
|
|
24
|
+
<% if (streams[i].description) { %>
|
|
25
|
+
<div class="multicamera-description gcore-skin-text-color">
|
|
26
|
+
<%= streams[i].description %>
|
|
27
|
+
</div>
|
|
28
|
+
<% } %>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
</li>
|
|
16
32
|
<% } %>
|
|
17
|
-
|
|
18
|
-
<div class="multicamera-text gcore-skin-text-color">
|
|
19
|
-
<% if (streams[i].title) { %>
|
|
20
|
-
<div class="multicamera-title gcore-skin-text-color"><%= streams[i].title %></div>
|
|
21
|
-
<% } %>
|
|
22
|
-
<% if (streams[i].description) { %>
|
|
23
|
-
<div class="multicamera-description gcore-skin-text-color"><%= streams[i].description %></div>
|
|
24
|
-
<% } %>
|
|
25
|
-
</div>
|
|
26
|
-
</div>
|
|
27
|
-
</li>
|
|
28
|
-
<% } %>
|
|
29
|
-
</ul>
|
|
33
|
+
</ul>
|
|
@@ -5,11 +5,8 @@
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
.multicamera[data-multicamera] {
|
|
8
|
-
float: right;
|
|
9
|
-
margin-top: 4px;
|
|
10
8
|
position: relative;
|
|
11
|
-
|
|
12
|
-
width: 20px;
|
|
9
|
+
order: 80;
|
|
13
10
|
|
|
14
11
|
button {
|
|
15
12
|
background-color: transparent;
|
|
@@ -20,10 +17,15 @@
|
|
|
20
17
|
font-size: 14px;
|
|
21
18
|
padding: 0;
|
|
22
19
|
|
|
20
|
+
display: flex;
|
|
21
|
+
align-items: center;
|
|
22
|
+
justify-content: center;
|
|
23
|
+
width: 24px;
|
|
24
|
+
height: 20px;
|
|
25
|
+
|
|
23
26
|
svg {
|
|
24
27
|
height: 20px;
|
|
25
28
|
position: relative;
|
|
26
|
-
margin-top: 6px;
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
&:hover {
|
|
@@ -33,13 +35,6 @@
|
|
|
33
35
|
&.changing {
|
|
34
36
|
animation: pulse 0.5s infinite alternate;
|
|
35
37
|
}
|
|
36
|
-
|
|
37
|
-
span.quality-arrow {
|
|
38
|
-
width: 9px;
|
|
39
|
-
height: 6px;
|
|
40
|
-
margin-top: 11px;
|
|
41
|
-
margin-left: 5px;
|
|
42
|
-
}
|
|
43
38
|
}
|
|
44
39
|
|
|
45
40
|
&>ul {
|
|
@@ -135,27 +130,5 @@
|
|
|
135
130
|
}
|
|
136
131
|
}
|
|
137
132
|
}
|
|
138
|
-
|
|
139
|
-
a {
|
|
140
|
-
color: #444;
|
|
141
|
-
padding: 2px 10px;
|
|
142
|
-
display: block;
|
|
143
|
-
text-decoration: none;
|
|
144
|
-
|
|
145
|
-
&:hover {
|
|
146
|
-
background-color: #555;
|
|
147
|
-
color: white;
|
|
148
|
-
|
|
149
|
-
a {
|
|
150
|
-
color: white;
|
|
151
|
-
text-decoration: none;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
&.current a {
|
|
157
|
-
color: #f00;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
133
|
}
|
|
161
134
|
}
|
package/assets/style/main.scss
CHANGED
package/dist/core.js
CHANGED
|
@@ -12686,6 +12686,9 @@ var PlayerEvent;
|
|
|
12686
12686
|
PlayerEvent["VolumeUpdate"] = "volumeupdate";
|
|
12687
12687
|
})(PlayerEvent || (PlayerEvent = {}));
|
|
12688
12688
|
|
|
12689
|
+
const MIME_TYPES_HLS = ['application/x-mpegurl', 'application/vnd.apple.mpegurl'];
|
|
12690
|
+
const MIME_TYPE_HLS = MIME_TYPES_HLS[0];
|
|
12691
|
+
const MIME_TYPE_DASH = 'application/dash+xml';
|
|
12689
12692
|
// TODO rewrite using the Playback classes and canPlay static methods
|
|
12690
12693
|
function buildMediaSourcesList(sources, priorityTransport = 'dash') {
|
|
12691
12694
|
const playbacks = Loader.registeredPlaybacks;
|
|
@@ -12725,22 +12728,21 @@ function wrapSource(s) {
|
|
|
12725
12728
|
}
|
|
12726
12729
|
function guessMimeType(s) {
|
|
12727
12730
|
if (s.endsWith('.mpd')) {
|
|
12728
|
-
return
|
|
12731
|
+
return MIME_TYPE_DASH;
|
|
12729
12732
|
}
|
|
12730
12733
|
if (s.endsWith('.m3u8')) {
|
|
12731
|
-
|
|
12732
|
-
return 'application/x-mpegurl';
|
|
12734
|
+
return MIME_TYPE_HLS;
|
|
12733
12735
|
}
|
|
12734
12736
|
}
|
|
12735
12737
|
function isDashSource(source, mimeType) {
|
|
12736
12738
|
if (mimeType) {
|
|
12737
|
-
return mimeType ===
|
|
12739
|
+
return mimeType === MIME_TYPE_DASH; // TODO consider video/mp4
|
|
12738
12740
|
}
|
|
12739
12741
|
return source.endsWith('.mpd');
|
|
12740
12742
|
}
|
|
12741
12743
|
function isHlsSource(source, mimeType) {
|
|
12742
12744
|
if (mimeType) {
|
|
12743
|
-
return
|
|
12745
|
+
return MIME_TYPES_HLS.includes(mimeType.toLowerCase());
|
|
12744
12746
|
}
|
|
12745
12747
|
return source.endsWith('.m3u8');
|
|
12746
12748
|
}
|
|
@@ -12807,6 +12809,9 @@ class BasePlayback extends HTML5Video$1 {
|
|
|
12807
12809
|
super._onPlaying();
|
|
12808
12810
|
this.trigger(Events$1.PLAYBACK_MEDIACONTROL_ENABLE);
|
|
12809
12811
|
}
|
|
12812
|
+
setTextTrack(id) {
|
|
12813
|
+
// noop
|
|
12814
|
+
}
|
|
12810
12815
|
}
|
|
12811
12816
|
|
|
12812
12817
|
var PlaybackEvents;
|
|
@@ -12829,6 +12834,7 @@ const T$3 = 'playback.dash';
|
|
|
12829
12834
|
class DashPlayback extends BasePlayback {
|
|
12830
12835
|
_levels = [];
|
|
12831
12836
|
_currentLevel = AUTO$1;
|
|
12837
|
+
_currentTextTrackId = -1;
|
|
12832
12838
|
// true when the actual duration is longer than hlsjs's live sync point
|
|
12833
12839
|
// when this is false playableRegionDuration will be the actual duration
|
|
12834
12840
|
// when this is true playableRegionDuration will exclude the time after the sync point
|
|
@@ -12961,7 +12967,11 @@ class DashPlayback extends BasePlayback {
|
|
|
12961
12967
|
streaming: {
|
|
12962
12968
|
text: {
|
|
12963
12969
|
defaultEnabled: false,
|
|
12964
|
-
|
|
12970
|
+
// NOTE: dispatchForManualRendering is not correctly implemented in DASH.js;
|
|
12971
|
+
// it does not work when there are multiple text tracks.
|
|
12972
|
+
// CUE_ENTER and CUE_EXIT events might be dispatched additionally
|
|
12973
|
+
// for a track, other than the currently active one.
|
|
12974
|
+
// dispatchForManualRendering: true, // TODO only when useNativeSubtitles is not true?
|
|
12965
12975
|
},
|
|
12966
12976
|
},
|
|
12967
12977
|
}, this.options.dash);
|
|
@@ -13005,24 +13015,6 @@ class DashPlayback extends BasePlayback {
|
|
|
13005
13015
|
this._dash.on(_.events.PLAYBACK_RATE_CHANGED, (e) => {
|
|
13006
13016
|
this.trigger(PlaybackEvents.PLAYBACK_RATE_CHANGED, e.playbackRate);
|
|
13007
13017
|
});
|
|
13008
|
-
this._dash.on(_.events.TRACK_CHANGE_RENDERED, (e) => {
|
|
13009
|
-
if (e.mediaType === 'audio') {
|
|
13010
|
-
this.trigger(Events$1.PLAYBACK_AUDIO_CHANGED, toClapprTrack$1(e.newMediaInfo));
|
|
13011
|
-
}
|
|
13012
|
-
});
|
|
13013
|
-
this._dash.on(_.events.CUE_ENTER, (e) => {
|
|
13014
|
-
this.oncueenter?.({
|
|
13015
|
-
end: e.end,
|
|
13016
|
-
id: e.id,
|
|
13017
|
-
start: e.start,
|
|
13018
|
-
text: e.text,
|
|
13019
|
-
});
|
|
13020
|
-
});
|
|
13021
|
-
this._dash.on(_.events.CUE_EXIT, (e) => {
|
|
13022
|
-
this.oncueexit?.({
|
|
13023
|
-
id: e.id,
|
|
13024
|
-
});
|
|
13025
|
-
});
|
|
13026
13018
|
}
|
|
13027
13019
|
render() {
|
|
13028
13020
|
this._ready();
|
|
@@ -13332,14 +13324,14 @@ class DashPlayback extends BasePlayback {
|
|
|
13332
13324
|
this._dash?.setTextTrack(this.closedCaptionsTrackId);
|
|
13333
13325
|
}
|
|
13334
13326
|
setTextTrack(id) {
|
|
13327
|
+
this._currentTextTrackId = id;
|
|
13335
13328
|
this._dash?.setTextTrack(id);
|
|
13336
13329
|
}
|
|
13337
13330
|
/**
|
|
13338
13331
|
* @override
|
|
13339
13332
|
*/
|
|
13340
13333
|
get closedCaptionsTracks() {
|
|
13341
|
-
|
|
13342
|
-
return tt;
|
|
13334
|
+
return this.getTextTracks();
|
|
13343
13335
|
}
|
|
13344
13336
|
getTextTracks() {
|
|
13345
13337
|
return this._dash?.getTracksFor('text').map((t, index) => ({
|
|
@@ -13349,7 +13341,7 @@ class DashPlayback extends BasePlayback {
|
|
|
13349
13341
|
id: index,
|
|
13350
13342
|
label: getTextTrackLabel(t) || "",
|
|
13351
13343
|
language: t.lang,
|
|
13352
|
-
mode: "hidden",
|
|
13344
|
+
mode: this._currentTextTrackId === index ? "showing" : "hidden",
|
|
13353
13345
|
},
|
|
13354
13346
|
})) || [];
|
|
13355
13347
|
}
|
|
@@ -50861,7 +50853,11 @@ class HlsPlayback extends BasePlayback {
|
|
|
50861
50853
|
this.trigger(Events$1.PLAYBACK_AUDIO_CHANGED, toClapprTrack(track));
|
|
50862
50854
|
}
|
|
50863
50855
|
setTextTrack(id) {
|
|
50856
|
+
if (id === this._hls.subtitleTrack) {
|
|
50857
|
+
return;
|
|
50858
|
+
}
|
|
50864
50859
|
this._hls.subtitleTrack = id;
|
|
50860
|
+
this.cues = [];
|
|
50865
50861
|
}
|
|
50866
50862
|
/**
|
|
50867
50863
|
* @override
|
|
@@ -51481,7 +51477,7 @@ class Player {
|
|
|
51481
51477
|
}
|
|
51482
51478
|
}
|
|
51483
51479
|
|
|
51484
|
-
var version$1 = "2.
|
|
51480
|
+
var version$1 = "2.29.0";
|
|
51485
51481
|
|
|
51486
51482
|
var packages = {
|
|
51487
51483
|
"node_modules/@clappr/core": {
|