@nomercy-entertainment/nomercy-video-player 0.3.2 → 0.3.4
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/dist/index.d.ts +2 -2
- package/dist/index.js +39 -31
- package/dist/types.d.ts +1 -1
- package/package.json +1 -1
- package/public/locales/nl.json +245 -0
- package/src/index.ts +52 -50
- package/src/types.ts +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -151,10 +151,10 @@ declare class NMPlayer<T> extends Base<T> {
|
|
|
151
151
|
createBaseStyles(): void;
|
|
152
152
|
createSubtitleFontFamily(): void;
|
|
153
153
|
createSubtitleOverlay(): void;
|
|
154
|
-
setSubtitleStyle(style: SubtitleStyle): void;
|
|
154
|
+
setSubtitleStyle(style: Partial<SubtitleStyle>): void;
|
|
155
155
|
getSubtitleStyle(): SubtitleStyle;
|
|
156
156
|
private applySubtitleStyle;
|
|
157
|
-
computeSubtitlePosition: (cue: Cue, videoElement: HTMLVideoElement,
|
|
157
|
+
computeSubtitlePosition: (cue: Cue, videoElement: HTMLVideoElement, subtitleArea: HTMLElement, subtitleText: HTMLElement) => void;
|
|
158
158
|
/**
|
|
159
159
|
* This method is called every time event of the video element.
|
|
160
160
|
* It will generate the content of the subtitle overlay.
|
package/dist/index.js
CHANGED
|
@@ -122,28 +122,24 @@ class NMPlayer extends base_1.Base {
|
|
|
122
122
|
console.error('Failed to fetch file contents', reason);
|
|
123
123
|
});
|
|
124
124
|
};
|
|
125
|
-
this.computeSubtitlePosition = (cue, videoElement,
|
|
126
|
-
if (!videoElement || !
|
|
125
|
+
this.computeSubtitlePosition = (cue, videoElement, subtitleArea, subtitleText) => {
|
|
126
|
+
if (!videoElement || !subtitleArea || !subtitleText) {
|
|
127
127
|
return;
|
|
128
128
|
}
|
|
129
129
|
const videoHeight = videoElement.clientHeight;
|
|
130
|
-
const safeZoneHeight = subtitleSafeZone.clientHeight;
|
|
131
130
|
const subtitleHeight = subtitleArea.clientHeight;
|
|
132
|
-
|
|
131
|
+
// Handle vertical positioning
|
|
133
132
|
if (typeof cue.linePosition === "number") {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
133
|
+
const verticalPos = cue.linePosition === 50
|
|
134
|
+
? `${50 - (subtitleHeight / videoHeight * 50)}%` // Center
|
|
135
|
+
: `${cue.linePosition}%`; // Specified position
|
|
136
|
+
subtitleArea.style.bottom = '';
|
|
137
|
+
subtitleArea.style.top = verticalPos;
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
subtitleArea.style.top = '';
|
|
141
|
+
subtitleArea.style.bottom = '3%';
|
|
141
142
|
}
|
|
142
|
-
const safeZoneTop = subtitleSafeZone.getBoundingClientRect().top - videoElement.getBoundingClientRect().top;
|
|
143
|
-
const safeZoneBottom = safeZoneTop + safeZoneHeight;
|
|
144
|
-
const buffer = 10;
|
|
145
|
-
insetTop = Math.max(safeZoneTop + buffer, Math.min(insetTop, safeZoneBottom - subtitleHeight - buffer));
|
|
146
|
-
subtitleArea.style.inset = `${insetTop}px 0px 0px`;
|
|
147
143
|
// Handle alignment
|
|
148
144
|
subtitleArea.classList.remove("aligned-start", "aligned-center", "aligned-end");
|
|
149
145
|
if (cue.alignment === "start" || cue.alignment === "left") {
|
|
@@ -155,16 +151,16 @@ class NMPlayer extends base_1.Base {
|
|
|
155
151
|
else if (cue.alignment === "end" || cue.alignment === "right") {
|
|
156
152
|
subtitleArea.classList.add("aligned-end");
|
|
157
153
|
}
|
|
158
|
-
// Handle
|
|
154
|
+
// Handle width
|
|
159
155
|
if (cue.size >= 0 && cue.size <= 100) {
|
|
160
|
-
subtitleArea.
|
|
161
|
-
subtitleArea.style.
|
|
162
|
-
subtitleArea.style.
|
|
156
|
+
subtitleArea.style.width = `calc(${cue.size}% - 6%)`;
|
|
157
|
+
subtitleArea.style.left = `calc(${(100 - cue.size) / 2}% + 3%)`;
|
|
158
|
+
subtitleArea.style.right = `calc(${(100 - cue.size) / 2}% + 3%)`;
|
|
163
159
|
}
|
|
164
160
|
else {
|
|
165
|
-
subtitleArea.
|
|
166
|
-
subtitleArea.style.
|
|
167
|
-
subtitleArea.style.
|
|
161
|
+
subtitleArea.style.width = '100%';
|
|
162
|
+
subtitleArea.style.left = '3%';
|
|
163
|
+
subtitleArea.style.right = '3%';
|
|
168
164
|
}
|
|
169
165
|
};
|
|
170
166
|
this.inactivityTimeout = null;
|
|
@@ -497,11 +493,16 @@ class NMPlayer extends base_1.Base {
|
|
|
497
493
|
writing-mode: horizontal-tb;
|
|
498
494
|
unicode-bidi: plaintext;
|
|
499
495
|
white-space: pre-line;
|
|
496
|
+
padding: 0.5rem 0;
|
|
500
497
|
position: absolute;
|
|
501
498
|
height: fit-content;
|
|
502
499
|
font-size: 28px;
|
|
503
500
|
}
|
|
504
501
|
|
|
502
|
+
.nomercyplayer:has(.subtitle-text:empty) .subtitle-overlay .subtitle-area {
|
|
503
|
+
display: none;
|
|
504
|
+
}
|
|
505
|
+
|
|
505
506
|
.nomercyplayer .subtitle-overlay .subtitle-area.aligned-start {
|
|
506
507
|
text-align: left;
|
|
507
508
|
}
|
|
@@ -526,11 +527,17 @@ class NMPlayer extends base_1.Base {
|
|
|
526
527
|
|
|
527
528
|
.nomercyplayer .subtitle-overlay .subtitle-text {
|
|
528
529
|
white-space: pre-line;
|
|
529
|
-
|
|
530
|
+
padding: 0 0.5rem;
|
|
531
|
+
display: inline-flex;
|
|
532
|
+
line-height: 1.2;
|
|
530
533
|
writing-mode: horizontal-tb;
|
|
531
534
|
unicode-bidi: plaintext;
|
|
532
535
|
}
|
|
533
536
|
|
|
537
|
+
.nomercyplayer .subtitle-overlay .subtitle-text:empty {
|
|
538
|
+
display: none;
|
|
539
|
+
}
|
|
540
|
+
|
|
534
541
|
.nomercyplayer .subtitle-text,
|
|
535
542
|
.nomercyplayer .subtitle-text[data-language="eng"] {
|
|
536
543
|
font-family: 'ReithSans', sans-serif;
|
|
@@ -642,21 +649,16 @@ class NMPlayer extends base_1.Base {
|
|
|
642
649
|
this.subtitleOverlay = this.createElement('div', `${this.playerId}-subtitle-overlay`, true)
|
|
643
650
|
.addClasses(['subtitle-overlay'])
|
|
644
651
|
.appendTo(this.container);
|
|
645
|
-
this.subtitleSafeZone = this.createElement('div', `${this.playerId}-subtitle-safezone`, true)
|
|
646
|
-
.addClasses(['subtitle-safezone'])
|
|
647
|
-
.appendTo(this.subtitleOverlay);
|
|
648
652
|
this.subtitleArea = this.createElement('div', `${this.playerId}-subtitle-area`, true)
|
|
649
653
|
.addClasses(['subtitle-area'])
|
|
650
|
-
.appendTo(this.
|
|
654
|
+
.appendTo(this.subtitleOverlay);
|
|
651
655
|
this.subtitleText = this.createElement('span', `${this.playerId}-subtitle-text`, true)
|
|
652
656
|
.addClasses(['subtitle-text'])
|
|
653
657
|
.appendTo(this.subtitleArea);
|
|
654
658
|
this.on('time', this.checkSubtitles.bind(this));
|
|
655
|
-
this.updateDisplayOverlay();
|
|
656
659
|
this.storage.get('subtitle-style', helpers_1.defaultSubtitleStyles)
|
|
657
660
|
.then((val) => {
|
|
658
661
|
this.subtitleStyle = val;
|
|
659
|
-
this.updateDisplayOverlay();
|
|
660
662
|
this.applySubtitleStyle();
|
|
661
663
|
});
|
|
662
664
|
}
|
|
@@ -669,6 +671,12 @@ class NMPlayer extends base_1.Base {
|
|
|
669
671
|
}
|
|
670
672
|
applySubtitleStyle() {
|
|
671
673
|
this.storage.set('subtitle-style', this.subtitleStyle).then();
|
|
674
|
+
Object.entries(this.subtitleStyle).forEach(([key, value]) => {
|
|
675
|
+
this.emit('set-subtitle-style', {
|
|
676
|
+
property: key,
|
|
677
|
+
value: value,
|
|
678
|
+
});
|
|
679
|
+
});
|
|
672
680
|
const { fontSize, fontFamily, textColor, textOpacity, backgroundColor, backgroundOpacity, edgeStyle, areaColor, windowOpacity } = this.subtitleStyle;
|
|
673
681
|
const areaElement = this.subtitleArea.style;
|
|
674
682
|
const textElement = this.subtitleText.style;
|
|
@@ -721,7 +729,7 @@ class NMPlayer extends base_1.Base {
|
|
|
721
729
|
this.subtitleText.appendChild(fragment);
|
|
722
730
|
this.subtitleText.setAttribute('data-language', this.getCaptionLanguage());
|
|
723
731
|
requestAnimationFrame(() => {
|
|
724
|
-
this.computeSubtitlePosition(subtitleCue, this.videoElement, this.
|
|
732
|
+
this.computeSubtitlePosition(subtitleCue, this.videoElement, this.subtitleArea, this.subtitleText);
|
|
725
733
|
});
|
|
726
734
|
}
|
|
727
735
|
this.subtitleOverlay.style.display = 'block';
|
package/dist/types.d.ts
CHANGED
|
@@ -345,7 +345,7 @@ export interface NMPlayer<Conf extends Partial<PlayerConfig> = {}> {
|
|
|
345
345
|
usePlugin(id: string): void;
|
|
346
346
|
volumeDown(): void;
|
|
347
347
|
volumeUp(): void;
|
|
348
|
-
setSubtitleStyle(style: SubtitleStyle): void;
|
|
348
|
+
setSubtitleStyle(style: Partial<SubtitleStyle>): void;
|
|
349
349
|
getSubtitleStyle(): SubtitleStyle;
|
|
350
350
|
emit(event: 'all', data?: any): void;
|
|
351
351
|
emit(event: 'ready', data?: any): void;
|
package/package.json
CHANGED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
{
|
|
2
|
+
"off": "Uit",
|
|
3
|
+
"und": "Onbekend",
|
|
4
|
+
"zxx": "Geen",
|
|
5
|
+
"contain": "Bevatten",
|
|
6
|
+
"cover": "Bedekken",
|
|
7
|
+
"fill": "Vullen",
|
|
8
|
+
|
|
9
|
+
"aar": "Afar",
|
|
10
|
+
"abk": "Abchazisch",
|
|
11
|
+
"afr": "Afrikaans",
|
|
12
|
+
"aka": "Akan",
|
|
13
|
+
"alb": "Albanees",
|
|
14
|
+
"amh": "Amhaars",
|
|
15
|
+
"ara": "Arabisch",
|
|
16
|
+
"arg": "Aragonees",
|
|
17
|
+
"arm": "Armeens",
|
|
18
|
+
"asm": "Assamees",
|
|
19
|
+
"ava": "Avarisch",
|
|
20
|
+
"ave": "Avestisch",
|
|
21
|
+
"aym": "Aymara",
|
|
22
|
+
"aze": "Azerbeidzjaans",
|
|
23
|
+
"bak": "Basjkiers",
|
|
24
|
+
"bam": "Bambara",
|
|
25
|
+
"baq": "Baskisch",
|
|
26
|
+
"bel": "Wit-Russisch",
|
|
27
|
+
"ben": "Bengaals",
|
|
28
|
+
"bih": "Bihari",
|
|
29
|
+
"bis": "Bislama",
|
|
30
|
+
"bos": "Bosnisch",
|
|
31
|
+
"bra": "Braziliaans",
|
|
32
|
+
"bre": "Bretons",
|
|
33
|
+
"bul": "Bulgaars",
|
|
34
|
+
"bur": "Birmees",
|
|
35
|
+
"cat": "Catalaans",
|
|
36
|
+
"cha": "Chamorro",
|
|
37
|
+
"che": "Tsjetsjeens",
|
|
38
|
+
"chi": "Chinees",
|
|
39
|
+
"chu": "Oudkerkslavisch",
|
|
40
|
+
"chv": "Tsjoevasjisch",
|
|
41
|
+
"cor": "Cornisch",
|
|
42
|
+
"cro": "Kroatisch",
|
|
43
|
+
"cos": "Corsicaans",
|
|
44
|
+
"cre": "Cree",
|
|
45
|
+
"cze": "Tsjechisch",
|
|
46
|
+
"dan": "Deens",
|
|
47
|
+
"div": "Divehi, Maldivisch",
|
|
48
|
+
"dut": "Nederlands",
|
|
49
|
+
"dzo": "Dzongkha",
|
|
50
|
+
"eng": "Engels",
|
|
51
|
+
"epo": "Esperanto",
|
|
52
|
+
"est": "Ests",
|
|
53
|
+
"ewe": "Ewe",
|
|
54
|
+
"fao": "Faeröers",
|
|
55
|
+
"fij": "Fijisch",
|
|
56
|
+
"fil": "Filipijns",
|
|
57
|
+
"fin": "Fins",
|
|
58
|
+
"fre": "Frans",
|
|
59
|
+
"fry": "West-Fries",
|
|
60
|
+
"ful": "Fulah",
|
|
61
|
+
"geo": "Georgisch",
|
|
62
|
+
"ger": "Duits",
|
|
63
|
+
"gla": "Schots-Gaelisch",
|
|
64
|
+
"gle": "Iers",
|
|
65
|
+
"glg": "Galicisch",
|
|
66
|
+
"glv": "Manx",
|
|
67
|
+
"gre": "Grieks",
|
|
68
|
+
"grn": "Guaraní",
|
|
69
|
+
"gsw": "Zwitserduits",
|
|
70
|
+
"guj": "Gujarati",
|
|
71
|
+
"hat": "Haïtiaans",
|
|
72
|
+
"hau": "Hausa",
|
|
73
|
+
"haw": "Hawaïaans",
|
|
74
|
+
"heb": "Hebreeuws",
|
|
75
|
+
"her": "Herero",
|
|
76
|
+
"hin": "Hindi",
|
|
77
|
+
"hmo": "Hiri Motu",
|
|
78
|
+
"hrv": "Kroatisch",
|
|
79
|
+
"hun": "Hongaars",
|
|
80
|
+
"ibo": "Igbo",
|
|
81
|
+
"ice": "IJslands",
|
|
82
|
+
"ido": "Ido",
|
|
83
|
+
"iii": "Sichuan Yi",
|
|
84
|
+
"iku": "Inuktitut",
|
|
85
|
+
"ile": "Interlingue",
|
|
86
|
+
"ina": "Interlingua",
|
|
87
|
+
"ind": "Indonesisch",
|
|
88
|
+
"ipk": "Inupiaq",
|
|
89
|
+
"ita": "Italiaans",
|
|
90
|
+
"jav": "Javaans",
|
|
91
|
+
"jpn": "Japans",
|
|
92
|
+
"kan": "Kannada",
|
|
93
|
+
"kas": "Kasjmiri",
|
|
94
|
+
"kau": "Kanuri",
|
|
95
|
+
"kaz": "Kazachs",
|
|
96
|
+
"khm": "Khmer",
|
|
97
|
+
"kik": "Kikuyu",
|
|
98
|
+
"kin": "Kinyarwanda",
|
|
99
|
+
"kir": "Kirgizisch",
|
|
100
|
+
"kom": "Komi",
|
|
101
|
+
"kon": "Kongo",
|
|
102
|
+
"kor": "Koreaans",
|
|
103
|
+
"kua": "Kwanyama",
|
|
104
|
+
"kur": "Koerdisch",
|
|
105
|
+
"lao": "Lao",
|
|
106
|
+
"lat": "Latijn",
|
|
107
|
+
"lav": "Lets",
|
|
108
|
+
"lim": "Limburgs",
|
|
109
|
+
"lin": "Lingala",
|
|
110
|
+
"lit": "Litouws",
|
|
111
|
+
"ltz": "Luxemburgs",
|
|
112
|
+
"lub": "Luba-Katanga",
|
|
113
|
+
"lug": "Ganda",
|
|
114
|
+
"mac": "Macedonisch",
|
|
115
|
+
"mah": "Marshallees",
|
|
116
|
+
"mal": "Malayalam",
|
|
117
|
+
"mao": "Maori",
|
|
118
|
+
"mar": "Marathi",
|
|
119
|
+
"may": "Maleis",
|
|
120
|
+
"mlg": "Malagassisch",
|
|
121
|
+
"mlt": "Maltees",
|
|
122
|
+
"mon": "Mongools",
|
|
123
|
+
"nau": "Nauruaans",
|
|
124
|
+
"nav": "Navajo",
|
|
125
|
+
"nbl": "Zuid-Ndebele",
|
|
126
|
+
"nde": "Noord-Ndebele",
|
|
127
|
+
"ndo": "Ndonga",
|
|
128
|
+
"nep": "Nepalees",
|
|
129
|
+
"nno": "Noors Nynorsk",
|
|
130
|
+
"nob": "Noors Bokmål",
|
|
131
|
+
"nor": "Noors",
|
|
132
|
+
"nya": "Chichewa",
|
|
133
|
+
"oci": "Occitaans",
|
|
134
|
+
"oji": "Ojibwe",
|
|
135
|
+
"ori": "Oriya",
|
|
136
|
+
"orm": "Oromo",
|
|
137
|
+
"oss": "Ossetisch",
|
|
138
|
+
"pan": "Punjabi",
|
|
139
|
+
"per": "Perzisch",
|
|
140
|
+
"pli": "Pali",
|
|
141
|
+
"pob": "Braziliaans Portugees",
|
|
142
|
+
"pol": "Pools",
|
|
143
|
+
"por": "Portugees",
|
|
144
|
+
"pus": "Pasjtoe",
|
|
145
|
+
"que": "Quechua",
|
|
146
|
+
"roh": "Reto-Romaans",
|
|
147
|
+
"rum": "Roemeens",
|
|
148
|
+
"run": "Kirundi",
|
|
149
|
+
"rus": "Russisch",
|
|
150
|
+
"sag": "Sango",
|
|
151
|
+
"san": "Sanskriet",
|
|
152
|
+
"sin": "Singalees",
|
|
153
|
+
"slo": "Slowaaks",
|
|
154
|
+
"slv": "Sloveens",
|
|
155
|
+
"sme": "Noord-Sami",
|
|
156
|
+
"smo": "Samoaans",
|
|
157
|
+
"sna": "Shona",
|
|
158
|
+
"snd": "Sindhi",
|
|
159
|
+
"som": "Somalisch",
|
|
160
|
+
"sot": "Zuid-Sotho",
|
|
161
|
+
"spa": "Spaans",
|
|
162
|
+
"srd": "Sardijns",
|
|
163
|
+
"srp": "Servisch",
|
|
164
|
+
"ssw": "Swazi",
|
|
165
|
+
"sun": "Soendanees",
|
|
166
|
+
"swa": "Swahili",
|
|
167
|
+
"swe": "Zweeds",
|
|
168
|
+
"tah": "Tahitiaans",
|
|
169
|
+
"tam": "Tamil",
|
|
170
|
+
"tat": "Tataars",
|
|
171
|
+
"tel": "Telugu",
|
|
172
|
+
"tgk": "Tadzjieks",
|
|
173
|
+
"tgl": "Tagalog",
|
|
174
|
+
"tha": "Thais",
|
|
175
|
+
"tib": "Tibetaans",
|
|
176
|
+
"tir": "Tigrinya",
|
|
177
|
+
"ton": "Tongaans",
|
|
178
|
+
"tsn": "Tswana",
|
|
179
|
+
"tso": "Tsonga",
|
|
180
|
+
"tuk": "Turkmeens",
|
|
181
|
+
"tur": "Turks",
|
|
182
|
+
"twi": "Twi",
|
|
183
|
+
"uig": "Oeigoers",
|
|
184
|
+
"ukr": "Oekraïens",
|
|
185
|
+
"urd": "Urdu",
|
|
186
|
+
"uzb": "Oezbeeks",
|
|
187
|
+
"ven": "Venda",
|
|
188
|
+
"vie": "Vietnamees",
|
|
189
|
+
"vol": "Volapük",
|
|
190
|
+
"wel": "Welsh",
|
|
191
|
+
"wln": "Waals",
|
|
192
|
+
"wol": "Wolof",
|
|
193
|
+
"xho": "Xhosa",
|
|
194
|
+
"yid": "Jiddisch",
|
|
195
|
+
"yor": "Yoruba",
|
|
196
|
+
"zha": "Zhuang",
|
|
197
|
+
"zul": "Zulu",
|
|
198
|
+
|
|
199
|
+
"none": "geen",
|
|
200
|
+
"Audio and subtitles": "Audio en ondertiteling",
|
|
201
|
+
"Audio": "Audio",
|
|
202
|
+
"AudioTracks": "Audio Sporen",
|
|
203
|
+
"Back": "Terug",
|
|
204
|
+
"Backward": "Achteruit",
|
|
205
|
+
"Buffering": "Bufferen",
|
|
206
|
+
"E": "A",
|
|
207
|
+
"Episode": "Aflevering",
|
|
208
|
+
"episodes": "afleveringen",
|
|
209
|
+
"Episodes": "Afleveringen",
|
|
210
|
+
"ExitFullscreen": "Verlaat Volledig Scherm",
|
|
211
|
+
"Forward": "Vooruit",
|
|
212
|
+
"Fullscreen": "Volledig Scherm",
|
|
213
|
+
"Language": "Taal",
|
|
214
|
+
"Loading playlist item": "Afspeellijst item laden",
|
|
215
|
+
"Loading playlist": "Afspeellijst laden",
|
|
216
|
+
"Muted": "Gedempt",
|
|
217
|
+
"Mute": "Dempen",
|
|
218
|
+
"Next Episode": "Volgende Aflevering",
|
|
219
|
+
"Next": "Volgende",
|
|
220
|
+
"Normal": "Normaal",
|
|
221
|
+
"Off": "Uit",
|
|
222
|
+
"Pause": "Pauze",
|
|
223
|
+
"Play from beginning": "Speel vanaf het begin",
|
|
224
|
+
"Play": "Afspelen",
|
|
225
|
+
"Playlist": "Afspeellijst",
|
|
226
|
+
"Previous Episode": "Vorige Aflevering",
|
|
227
|
+
"Previous": "Vorige",
|
|
228
|
+
"Quality": "Kwaliteit",
|
|
229
|
+
"Resume playback": "Afspelen hervatten",
|
|
230
|
+
"S": "S",
|
|
231
|
+
"seconds": "seconden",
|
|
232
|
+
"Seconds": "Seconden",
|
|
233
|
+
"Seek backward": "Achteruit zoeken",
|
|
234
|
+
"Seek forward": "Vooruit zoeken",
|
|
235
|
+
"Settings": "Instellingen",
|
|
236
|
+
"Something went wrong trying to play this item": "Er is iets misgegaan bij het afspelen van dit item",
|
|
237
|
+
"SPACE": "SPATIE",
|
|
238
|
+
"Speed": "Snelheid",
|
|
239
|
+
"Stop": "Stop",
|
|
240
|
+
"styled": "gestyled",
|
|
241
|
+
"Subtitle": "Ondertiteling",
|
|
242
|
+
"Subtitles": "Ondertiteling",
|
|
243
|
+
"Video": "Video",
|
|
244
|
+
"Watch credits": "Bekijk credits"
|
|
245
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -8,7 +8,7 @@ import type Plugin from './plugin';
|
|
|
8
8
|
|
|
9
9
|
import { defaultSubtitleStyles, getEdgeStyle, humanTime, pad, parseColorToHex, unique } from './helpers';
|
|
10
10
|
import {
|
|
11
|
-
PlaylistItem, PreviewTime, PlayerConfig, Stretching,
|
|
11
|
+
PlaylistItem, PreviewTime, PlayerConfig, Stretching,
|
|
12
12
|
TimeData, Track, TypeMappings, Chapter, Level, SubtitleStyle,
|
|
13
13
|
} from './types';
|
|
14
14
|
|
|
@@ -419,7 +419,7 @@ class NMPlayer<T> extends Base<T> {
|
|
|
419
419
|
this.videoElement.controls = this.options.controls ?? false;
|
|
420
420
|
this.videoElement.preload = this.options.preload ?? 'auto';
|
|
421
421
|
this.storage.get('muted', this.options.muted).then((val) => {
|
|
422
|
-
this.videoElement.muted = val == true;
|
|
422
|
+
this.videoElement.muted = val == true;
|
|
423
423
|
});
|
|
424
424
|
this.storage.get('volume', 100).then((val) => {
|
|
425
425
|
this.videoElement.volume = val ? val / 100 : 1;
|
|
@@ -510,11 +510,16 @@ class NMPlayer<T> extends Base<T> {
|
|
|
510
510
|
writing-mode: horizontal-tb;
|
|
511
511
|
unicode-bidi: plaintext;
|
|
512
512
|
white-space: pre-line;
|
|
513
|
+
padding: 0.5rem 0;
|
|
513
514
|
position: absolute;
|
|
514
515
|
height: fit-content;
|
|
515
516
|
font-size: 28px;
|
|
516
517
|
}
|
|
517
518
|
|
|
519
|
+
.nomercyplayer:has(.subtitle-text:empty) .subtitle-overlay .subtitle-area {
|
|
520
|
+
display: none;
|
|
521
|
+
}
|
|
522
|
+
|
|
518
523
|
.nomercyplayer .subtitle-overlay .subtitle-area.aligned-start {
|
|
519
524
|
text-align: left;
|
|
520
525
|
}
|
|
@@ -539,11 +544,17 @@ class NMPlayer<T> extends Base<T> {
|
|
|
539
544
|
|
|
540
545
|
.nomercyplayer .subtitle-overlay .subtitle-text {
|
|
541
546
|
white-space: pre-line;
|
|
542
|
-
|
|
547
|
+
padding: 0 0.5rem;
|
|
548
|
+
display: inline-flex;
|
|
549
|
+
line-height: 1.2;
|
|
543
550
|
writing-mode: horizontal-tb;
|
|
544
551
|
unicode-bidi: plaintext;
|
|
545
552
|
}
|
|
546
553
|
|
|
554
|
+
.nomercyplayer .subtitle-overlay .subtitle-text:empty {
|
|
555
|
+
display: none;
|
|
556
|
+
}
|
|
557
|
+
|
|
547
558
|
.nomercyplayer .subtitle-text,
|
|
548
559
|
.nomercyplayer .subtitle-text[data-language="eng"] {
|
|
549
560
|
font-family: 'ReithSans', sans-serif;
|
|
@@ -656,18 +667,13 @@ class NMPlayer<T> extends Base<T> {
|
|
|
656
667
|
|
|
657
668
|
createSubtitleOverlay(): void {
|
|
658
669
|
|
|
659
|
-
this.subtitleOverlay = this.createElement('div',
|
|
670
|
+
this.subtitleOverlay = this.createElement('div', `${this.playerId}-subtitle-overlay`, true)
|
|
660
671
|
.addClasses(['subtitle-overlay'])
|
|
661
672
|
.appendTo(this.container);
|
|
662
673
|
|
|
663
|
-
this.subtitleSafeZone = this.createElement('div', `${this.playerId}-subtitle-safezone`, true)
|
|
664
|
-
.addClasses(['subtitle-safezone'])
|
|
665
|
-
.appendTo(this.subtitleOverlay);
|
|
666
|
-
|
|
667
|
-
|
|
668
674
|
this.subtitleArea = this.createElement('div', `${this.playerId}-subtitle-area`, true)
|
|
669
675
|
.addClasses(['subtitle-area'])
|
|
670
|
-
.appendTo(this.
|
|
676
|
+
.appendTo(this.subtitleOverlay);
|
|
671
677
|
|
|
672
678
|
this.subtitleText = this.createElement('span', `${this.playerId}-subtitle-text`, true)
|
|
673
679
|
.addClasses(['subtitle-text'])
|
|
@@ -675,19 +681,15 @@ class NMPlayer<T> extends Base<T> {
|
|
|
675
681
|
|
|
676
682
|
this.on('time', this.checkSubtitles.bind(this));
|
|
677
683
|
|
|
678
|
-
|
|
679
|
-
this.updateDisplayOverlay();
|
|
680
|
-
|
|
681
684
|
this.storage.get<SubtitleStyle>('subtitle-style', defaultSubtitleStyles)
|
|
682
685
|
.then((val) => {
|
|
683
|
-
this.subtitleStyle = val;
|
|
684
|
-
this.updateDisplayOverlay();
|
|
686
|
+
this.subtitleStyle = val;
|
|
685
687
|
this.applySubtitleStyle();
|
|
686
688
|
});
|
|
687
689
|
}
|
|
688
690
|
|
|
689
691
|
|
|
690
|
-
setSubtitleStyle(style: SubtitleStyle): void {
|
|
692
|
+
setSubtitleStyle(style: Partial<SubtitleStyle>): void {
|
|
691
693
|
this.subtitleStyle = { ...this.subtitleStyle, ...style };
|
|
692
694
|
this.applySubtitleStyle();
|
|
693
695
|
}
|
|
@@ -700,6 +702,13 @@ class NMPlayer<T> extends Base<T> {
|
|
|
700
702
|
private applySubtitleStyle(): void {
|
|
701
703
|
this.storage.set('subtitle-style', this.subtitleStyle).then();
|
|
702
704
|
|
|
705
|
+
Object.entries(this.subtitleStyle).forEach(([key, value]) => {
|
|
706
|
+
this.emit('set-subtitle-style', {
|
|
707
|
+
property: key,
|
|
708
|
+
value: value,
|
|
709
|
+
});
|
|
710
|
+
});
|
|
711
|
+
|
|
703
712
|
const { fontSize, fontFamily, textColor,
|
|
704
713
|
textOpacity, backgroundColor, backgroundOpacity,
|
|
705
714
|
edgeStyle, areaColor, windowOpacity
|
|
@@ -724,33 +733,26 @@ class NMPlayer<T> extends Base<T> {
|
|
|
724
733
|
}
|
|
725
734
|
}
|
|
726
735
|
|
|
727
|
-
computeSubtitlePosition = (cue: Cue, videoElement: HTMLVideoElement,
|
|
728
|
-
if (!videoElement || !
|
|
736
|
+
computeSubtitlePosition = (cue: Cue, videoElement: HTMLVideoElement, subtitleArea: HTMLElement, subtitleText: HTMLElement) => {
|
|
737
|
+
if (!videoElement || !subtitleArea || !subtitleText) {
|
|
729
738
|
return;
|
|
730
739
|
}
|
|
731
740
|
|
|
732
741
|
const videoHeight = videoElement.clientHeight;
|
|
733
|
-
const safeZoneHeight = subtitleSafeZone.clientHeight;
|
|
734
742
|
const subtitleHeight = subtitleArea.clientHeight;
|
|
735
743
|
|
|
736
|
-
|
|
737
|
-
|
|
744
|
+
// Handle vertical positioning
|
|
738
745
|
if (typeof cue.linePosition === "number") {
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
} else {
|
|
743
|
-
insetTop = (videoHeight * (cue.linePosition / 100)) - (subtitleHeight * (cue.linePosition / 100));
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
const safeZoneTop = subtitleSafeZone.getBoundingClientRect().top - videoElement.getBoundingClientRect().top;
|
|
748
|
-
const safeZoneBottom = safeZoneTop + safeZoneHeight;
|
|
749
|
-
const buffer = 10;
|
|
750
|
-
|
|
751
|
-
insetTop = Math.max(safeZoneTop + buffer, Math.min(insetTop, safeZoneBottom - subtitleHeight - buffer));
|
|
746
|
+
const verticalPos = cue.linePosition === 50
|
|
747
|
+
? `${50 - (subtitleHeight / videoHeight * 50)}%` // Center
|
|
748
|
+
: `${cue.linePosition}%`; // Specified position
|
|
752
749
|
|
|
753
|
-
|
|
750
|
+
subtitleArea.style.bottom = '';
|
|
751
|
+
subtitleArea.style.top = verticalPos;
|
|
752
|
+
} else {
|
|
753
|
+
subtitleArea.style.top = '';
|
|
754
|
+
subtitleArea.style.bottom = '3%';
|
|
755
|
+
}
|
|
754
756
|
|
|
755
757
|
// Handle alignment
|
|
756
758
|
subtitleArea.classList.remove("aligned-start", "aligned-center", "aligned-end");
|
|
@@ -762,15 +764,15 @@ class NMPlayer<T> extends Base<T> {
|
|
|
762
764
|
subtitleArea.classList.add("aligned-end");
|
|
763
765
|
}
|
|
764
766
|
|
|
765
|
-
// Handle
|
|
767
|
+
// Handle width
|
|
766
768
|
if (cue.size >= 0 && cue.size <= 100) {
|
|
767
|
-
subtitleArea.
|
|
768
|
-
subtitleArea.style.
|
|
769
|
-
subtitleArea.style.
|
|
769
|
+
subtitleArea.style.width = `calc(${cue.size}% - 6%)`;
|
|
770
|
+
subtitleArea.style.left = `calc(${(100 - cue.size) / 2}% + 3%)`;
|
|
771
|
+
subtitleArea.style.right = `calc(${(100 - cue.size) / 2}% + 3%)`;
|
|
770
772
|
} else {
|
|
771
|
-
subtitleArea.
|
|
772
|
-
subtitleArea.style.
|
|
773
|
-
subtitleArea.style.
|
|
773
|
+
subtitleArea.style.width = '100%';
|
|
774
|
+
subtitleArea.style.left = '3%';
|
|
775
|
+
subtitleArea.style.right = '3%';
|
|
774
776
|
}
|
|
775
777
|
};
|
|
776
778
|
|
|
@@ -811,7 +813,7 @@ class NMPlayer<T> extends Base<T> {
|
|
|
811
813
|
this.subtitleText.appendChild(fragment);
|
|
812
814
|
this.subtitleText.setAttribute('data-language', this.getCaptionLanguage());
|
|
813
815
|
requestAnimationFrame(() => {
|
|
814
|
-
this.computeSubtitlePosition(subtitleCue, this.videoElement, this.
|
|
816
|
+
this.computeSubtitlePosition(subtitleCue, this.videoElement, this.subtitleArea, this.subtitleText);
|
|
815
817
|
});
|
|
816
818
|
}
|
|
817
819
|
|
|
@@ -1092,7 +1094,7 @@ class NMPlayer<T> extends Base<T> {
|
|
|
1092
1094
|
}
|
|
1093
1095
|
|
|
1094
1096
|
videoPlayer_loadedmetadataEvent(e: Event): void {
|
|
1095
|
-
const _e = e as Event & {target: HTMLVideoElement};
|
|
1097
|
+
const _e = e as Event & { target: HTMLVideoElement };
|
|
1096
1098
|
this.emit('loadedmetadata', this.videoElement);
|
|
1097
1099
|
this.emit('duration', this.videoPlayer_getTimeData(_e));
|
|
1098
1100
|
}
|
|
@@ -1102,14 +1104,14 @@ class NMPlayer<T> extends Base<T> {
|
|
|
1102
1104
|
}
|
|
1103
1105
|
|
|
1104
1106
|
videoPlayer_timeupdateEvent(e: Event): void {
|
|
1105
|
-
const _e = e as Event & {target: HTMLVideoElement};
|
|
1107
|
+
const _e = e as Event & { target: HTMLVideoElement };
|
|
1106
1108
|
if (Number.isNaN(_e.target.duration) || Number.isNaN(_e.target.currentTime)) return;
|
|
1107
1109
|
|
|
1108
1110
|
this.emit('time', this.videoPlayer_getTimeData(_e));
|
|
1109
1111
|
}
|
|
1110
1112
|
|
|
1111
1113
|
videoPlayer_durationchangeEvent(e: Event): void {
|
|
1112
|
-
const _e = e as Event & {target: HTMLVideoElement};
|
|
1114
|
+
const _e = e as Event & { target: HTMLVideoElement };
|
|
1113
1115
|
this.emit('duration', this.videoPlayer_getTimeData(_e));
|
|
1114
1116
|
|
|
1115
1117
|
this.emit('ready');
|
|
@@ -1134,7 +1136,7 @@ class NMPlayer<T> extends Base<T> {
|
|
|
1134
1136
|
this.volume = Math.round(this.videoElement.volume * 100);
|
|
1135
1137
|
}
|
|
1136
1138
|
|
|
1137
|
-
videoPlayer_getTimeData(_e: {target: HTMLVideoElement}): TimeData {
|
|
1139
|
+
videoPlayer_getTimeData(_e: { target: HTMLVideoElement }): TimeData {
|
|
1138
1140
|
return {
|
|
1139
1141
|
currentTime: _e.target.currentTime,
|
|
1140
1142
|
duration: _e.target.duration,
|
|
@@ -1438,7 +1440,7 @@ class NMPlayer<T> extends Base<T> {
|
|
|
1438
1440
|
|
|
1439
1441
|
const playlistItem = progressItem
|
|
1440
1442
|
.filter(i => i.progress)
|
|
1441
|
-
.sort((a,b) => new Date(b.progress!.date).getTime() - new Date(a.progress!.date).getTime())
|
|
1443
|
+
.sort((a, b) => new Date(b.progress!.date).getTime() - new Date(a.progress!.date).getTime())
|
|
1442
1444
|
.at(0);
|
|
1443
1445
|
|
|
1444
1446
|
if (!playlistItem?.progress) {
|
|
@@ -1540,7 +1542,7 @@ class NMPlayer<T> extends Base<T> {
|
|
|
1540
1542
|
|
|
1541
1543
|
}
|
|
1542
1544
|
|
|
1543
|
-
getParameterByName<T extends number|string>(name: string, url = window.location.href): T|null {
|
|
1545
|
+
getParameterByName<T extends number | string>(name: string, url = window.location.href): T | null {
|
|
1544
1546
|
name = name.replace(/[[\]]/gu, '\\$&');
|
|
1545
1547
|
|
|
1546
1548
|
const regex = new RegExp(`[?&]${name}(=([^&#]*)|&|#|$)`, 'u');
|
|
@@ -1803,7 +1805,7 @@ class NMPlayer<T> extends Base<T> {
|
|
|
1803
1805
|
this.translations[key] = value;
|
|
1804
1806
|
}
|
|
1805
1807
|
|
|
1806
|
-
addTranslations(translations: {key: string, value: string}[]): void {
|
|
1808
|
+
addTranslations(translations: { key: string, value: string }[]): void {
|
|
1807
1809
|
if (!this.translations) {
|
|
1808
1810
|
this.translations = {};
|
|
1809
1811
|
}
|
package/src/types.ts
CHANGED
|
@@ -368,7 +368,7 @@ export interface NMPlayer<Conf extends Partial<PlayerConfig> = {}> {
|
|
|
368
368
|
volumeDown(): void;
|
|
369
369
|
volumeUp(): void;
|
|
370
370
|
|
|
371
|
-
setSubtitleStyle(style: SubtitleStyle): void;
|
|
371
|
+
setSubtitleStyle(style: Partial<SubtitleStyle>): void;
|
|
372
372
|
getSubtitleStyle(): SubtitleStyle;
|
|
373
373
|
|
|
374
374
|
emit(event: 'all', data?: any): void;
|