ez-vid-ang 0.0.7 → 0.0.10
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 +69 -2
- package/fesm2022/ez-vid-ang.mjs +69 -53
- package/fesm2022/ez-vid-ang.mjs.map +1 -1
- package/package.json +6 -2
- package/types/ez-vid-ang.d.ts +9 -5
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# EzVidAng (Easy Video Angular)
|
|
2
2
|
|
|
3
|
-
Highly configurable and easy-to-use Angular component library for video playback and streaming.
|
|
3
|
+
Highly configurable, performant and easy-to-use Angular component library for video playback and streaming.
|
|
4
4
|
|
|
5
5
|
> [!CAUTION]
|
|
6
6
|
> This package is still under development and is not ready for use in production. Use at your own risk.
|
|
@@ -16,6 +16,9 @@ Highly configurable and easy-to-use Angular component library for video playback
|
|
|
16
16
|
▶️ **Inspired by modern players** – Familiar UX similar to popular platforms<br/>
|
|
17
17
|
📱 **Responsive design** - Works across all screen sizes and devices<br/>
|
|
18
18
|
|
|
19
|
+
## Example project
|
|
20
|
+
|
|
21
|
+
Example project can be found on [Stackblitz](https://stackblitz.com/edit/stackblitz-starters-sr5wp23n)
|
|
19
22
|
|
|
20
23
|
## Version compatibility
|
|
21
24
|
|
|
@@ -55,7 +58,57 @@ Add the required styles to your angular.json:
|
|
|
55
58
|
```
|
|
56
59
|
> [!NOTE]
|
|
57
60
|
> *eva-icons-and-fonts.scss* is optional if you provide custom icons and fonts for all components. It includes a prepared *.woff* file and utility classes for default icon usage.
|
|
58
|
-
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
> [!IMPORTANT]
|
|
64
|
+
> **If you want to use HLS streaming directive you must install latest version of the hls.js.**
|
|
65
|
+
>
|
|
66
|
+
> ```
|
|
67
|
+
> npm i hls.js
|
|
68
|
+
>```
|
|
69
|
+
> **And add the required script to your angular.json**
|
|
70
|
+
> ```
|
|
71
|
+
> {
|
|
72
|
+
> "projects": {
|
|
73
|
+
> "your_project": {
|
|
74
|
+
> "architect": {
|
|
75
|
+
> "build": {
|
|
76
|
+
> "options": {
|
|
77
|
+
> "scripts": [
|
|
78
|
+
> "node_modules/hls.js/dist/hls.min.js"
|
|
79
|
+
> ]
|
|
80
|
+
> }
|
|
81
|
+
> }
|
|
82
|
+
> }
|
|
83
|
+
> }
|
|
84
|
+
> }
|
|
85
|
+
> }
|
|
86
|
+
> ```
|
|
87
|
+
|
|
88
|
+
> [!IMPORTANT]
|
|
89
|
+
> **If you want to use DASH streaming directive you must install v5 of the dash.js.**
|
|
90
|
+
>
|
|
91
|
+
> ```
|
|
92
|
+
> npm i dashjs
|
|
93
|
+
>```
|
|
94
|
+
> **And add the required script to your angular.json**
|
|
95
|
+
> ```
|
|
96
|
+
> {
|
|
97
|
+
> "projects": {
|
|
98
|
+
> "your_project": {
|
|
99
|
+
> "architect": {
|
|
100
|
+
> "build": {
|
|
101
|
+
> "options": {
|
|
102
|
+
> "scripts": [
|
|
103
|
+
> "node_modules/dashjs/dist/modern/esm/dash.all.min.js"
|
|
104
|
+
> ]
|
|
105
|
+
> }
|
|
106
|
+
> }
|
|
107
|
+
> }
|
|
108
|
+
> }
|
|
109
|
+
> }
|
|
110
|
+
> }
|
|
111
|
+
> ```
|
|
59
112
|
|
|
60
113
|
Import the needed components and types into your standalone component or NgModule:
|
|
61
114
|
```
|
|
@@ -116,3 +169,17 @@ Library has four groups of components. You can click on the name to go to the do
|
|
|
116
169
|
- [**EvaControls**](documentation/controls) – Video control components and pipes
|
|
117
170
|
- [**EvaBuffering**](documentation/buffering) – Loading and buffering indicators
|
|
118
171
|
- [**EvaStreaming**](documentation/streaming) – Directives for live streaming support
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
### 💖 Support This Project
|
|
175
|
+
|
|
176
|
+
If you wish to make a donation you can click the widget.
|
|
177
|
+
[](https://ko-fi.com/K3K01AFMO6)
|
|
178
|
+
|
|
179
|
+
Your support helps:
|
|
180
|
+
- Maintain the project
|
|
181
|
+
- Add new features
|
|
182
|
+
- Fix bugs
|
|
183
|
+
- Provide long-term updates
|
|
184
|
+
|
|
185
|
+
Thank you for your generosity! 🙏
|
package/fesm2022/ez-vid-ang.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { EventEmitter, signal, Injectable, inject, input, ChangeDetectionStrategy, Component, output, computed, Pipe, ElementRef, NgZone, HostListener, Renderer2, viewChild, effect, Directive, SecurityContext
|
|
2
|
+
import { EventEmitter, signal, Injectable, inject, input, ChangeDetectionStrategy, Component, output, computed, Pipe, ElementRef, NgZone, HostListener, Renderer2, viewChild, effect, Directive, SecurityContext } from '@angular/core';
|
|
3
3
|
import { BehaviorSubject, Subject, fromEvent, throttleTime, merge, takeUntil } from 'rxjs';
|
|
4
4
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
5
5
|
|
|
@@ -206,6 +206,7 @@ class EvaApi {
|
|
|
206
206
|
* Subscribed to by `EvaPictureInPicture` to keep its icon state in sync.
|
|
207
207
|
*/
|
|
208
208
|
pictureInPictureSubject = new BehaviorSubject(false);
|
|
209
|
+
lastActiveVolume = 1;
|
|
209
210
|
// ─── Buffering Detection ──────────────────────────────────────────────────
|
|
210
211
|
/** Timeout reference used by the position-polling buffering detection. Cleared on each `timeupdate`. */
|
|
211
212
|
bufferingTimeout;
|
|
@@ -348,6 +349,7 @@ class EvaApi {
|
|
|
348
349
|
*/
|
|
349
350
|
setPlaybackSpeed(speed) {
|
|
350
351
|
if (!this.validateVideoAndPlayerBeforeAction()) {
|
|
352
|
+
console.log("nemam element za playback speed na vrijednost: " + speed);
|
|
351
353
|
return;
|
|
352
354
|
}
|
|
353
355
|
this.assignedVideoElement.playbackRate = speed;
|
|
@@ -364,18 +366,18 @@ class EvaApi {
|
|
|
364
366
|
}
|
|
365
367
|
/**
|
|
366
368
|
* Returns the current video volume as a normalized value (`0` to `1`).
|
|
367
|
-
* Falls back to `
|
|
369
|
+
* Falls back to `1` (the default initial volume) if the player is not yet ready.
|
|
368
370
|
* Called from `EvaMute` and `EvaVolume` on initialization.
|
|
369
371
|
*/
|
|
370
372
|
getVideoVolume() {
|
|
371
373
|
if (!this.validateVideoAndPlayerBeforeAction()) {
|
|
372
|
-
return
|
|
374
|
+
return 1;
|
|
373
375
|
}
|
|
374
376
|
return this.assignedVideoElement.volume;
|
|
375
377
|
}
|
|
376
378
|
/**
|
|
377
379
|
* Toggles mute/unmute by setting volume to `0` if currently audible,
|
|
378
|
-
* or restoring it to
|
|
380
|
+
* or restoring it to last volume value if currently muted.
|
|
379
381
|
* Called from `EvaMute`.
|
|
380
382
|
*/
|
|
381
383
|
muteOrUnmuteVideo() {
|
|
@@ -386,7 +388,7 @@ class EvaApi {
|
|
|
386
388
|
this.assignedVideoElement.volume = 0;
|
|
387
389
|
}
|
|
388
390
|
else {
|
|
389
|
-
this.assignedVideoElement.volume =
|
|
391
|
+
this.assignedVideoElement.volume = this.lastActiveVolume;
|
|
390
392
|
}
|
|
391
393
|
}
|
|
392
394
|
/**
|
|
@@ -401,12 +403,15 @@ class EvaApi {
|
|
|
401
403
|
}
|
|
402
404
|
if (volume < 0) {
|
|
403
405
|
this.assignedVideoElement.volume = 0;
|
|
406
|
+
this.lastActiveVolume = 0;
|
|
404
407
|
}
|
|
405
408
|
else if (volume > 1) {
|
|
406
409
|
this.assignedVideoElement.volume = 1;
|
|
410
|
+
this.lastActiveVolume = 1;
|
|
407
411
|
}
|
|
408
412
|
else {
|
|
409
413
|
this.assignedVideoElement.volume = volume;
|
|
414
|
+
this.lastActiveVolume = volume;
|
|
410
415
|
}
|
|
411
416
|
}
|
|
412
417
|
// ─── Event Listener Callbacks ─────────────────────────────────────────────
|
|
@@ -1443,7 +1448,7 @@ function validateAndTransformPlaybackSpeeds(v) {
|
|
|
1443
1448
|
}
|
|
1444
1449
|
function validateAndPrepareStartingVideoVolume(v) {
|
|
1445
1450
|
if (v === undefined) {
|
|
1446
|
-
return
|
|
1451
|
+
return 1;
|
|
1447
1452
|
}
|
|
1448
1453
|
if (v < 0) {
|
|
1449
1454
|
return 0;
|
|
@@ -1511,7 +1516,7 @@ function videoConfigurationDefaultSetter(v) {
|
|
|
1511
1516
|
v.preload = "auto";
|
|
1512
1517
|
}
|
|
1513
1518
|
if (!v.startingVolume) {
|
|
1514
|
-
v.startingVolume =
|
|
1519
|
+
v.startingVolume = 1;
|
|
1515
1520
|
}
|
|
1516
1521
|
return v;
|
|
1517
1522
|
}
|
|
@@ -2920,22 +2925,27 @@ class EvaPlaybackSpeed {
|
|
|
2920
2925
|
selectedIndex = signal(0, ...(ngDevMode ? [{ debugName: "selectedIndex" }] : []));
|
|
2921
2926
|
/** Bound reference to the click-outside handler, stored for removal in `ngOnDestroy`. */
|
|
2922
2927
|
clickOutsideListener;
|
|
2928
|
+
playerReady$ = null;
|
|
2923
2929
|
/**
|
|
2924
2930
|
* Sets the initial playback speed based on `evaDefaultPlaybackSpeed` and `evaPlaybackSpeeds`,
|
|
2925
2931
|
* then attaches a document-level click listener to close the dropdown when clicking outside.
|
|
2926
2932
|
*/
|
|
2927
2933
|
ngOnInit() {
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2934
|
+
if (!this.evaAPI.isPlayerReady) {
|
|
2935
|
+
this.playerReady$ = this.evaAPI.playerReadyEvent.subscribe(() => {
|
|
2936
|
+
const speeds = this.evaPlaybackSpeeds();
|
|
2937
|
+
const defaultSpeed = this.evaDefaultPlaybackSpeed();
|
|
2938
|
+
const index = speeds.indexOf(defaultSpeed);
|
|
2939
|
+
if (index !== -1) {
|
|
2940
|
+
this.currentSpeed.set(defaultSpeed);
|
|
2941
|
+
this.selectedIndex.set(index);
|
|
2942
|
+
}
|
|
2943
|
+
else if (speeds.length > 0) {
|
|
2944
|
+
this.currentSpeed.set(speeds[0]);
|
|
2945
|
+
this.selectedIndex.set(0);
|
|
2946
|
+
}
|
|
2947
|
+
this.evaAPI.setPlaybackSpeed(index !== 1 ? defaultSpeed : speeds[0]);
|
|
2948
|
+
});
|
|
2939
2949
|
}
|
|
2940
2950
|
// Listen for clicks outside
|
|
2941
2951
|
this.clickOutsideListener = this.handleClickOutside.bind(this);
|
|
@@ -2943,6 +2953,7 @@ class EvaPlaybackSpeed {
|
|
|
2943
2953
|
}
|
|
2944
2954
|
/** Removes the document-level click-outside listener to prevent memory leaks. */
|
|
2945
2955
|
ngOnDestroy() {
|
|
2956
|
+
this.playerReady$?.unsubscribe();
|
|
2946
2957
|
if (this.clickOutsideListener) {
|
|
2947
2958
|
document.removeEventListener('click', this.clickOutsideListener, true);
|
|
2948
2959
|
}
|
|
@@ -4469,12 +4480,11 @@ class EvaTrackSelector {
|
|
|
4469
4480
|
if (this.evaAPI.assignedVideoElement) {
|
|
4470
4481
|
Array.from(this.evaAPI.assignedVideoElement.textTracks)
|
|
4471
4482
|
.forEach(textTrack => {
|
|
4472
|
-
if (textTrack.label === tr.label) {
|
|
4473
|
-
|
|
4474
|
-
}
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
}
|
|
4483
|
+
// if (textTrack.label === tr.label) {
|
|
4484
|
+
// textTrack.mode = "showing";
|
|
4485
|
+
// } else {
|
|
4486
|
+
textTrack.mode = "hidden";
|
|
4487
|
+
// }
|
|
4478
4488
|
});
|
|
4479
4489
|
}
|
|
4480
4490
|
this.evaAPI.subtitlesChanged(tr);
|
|
@@ -4766,6 +4776,7 @@ class EvaVolume {
|
|
|
4766
4776
|
videoVolume;
|
|
4767
4777
|
/** Subscription to volume changes from `EvaApi`. Cleaned up in `ngOnDestroy`. */
|
|
4768
4778
|
videoVolumeSub = null;
|
|
4779
|
+
playerReady$ = null;
|
|
4769
4780
|
/** Cleanup function returned by `Renderer2.listen` for the `mousemove`/`touchmove` document listener. */
|
|
4770
4781
|
mouseMoveListener;
|
|
4771
4782
|
/** Cleanup function returned by `Renderer2.listen` for the `mouseup`/`touchend` document listener. */
|
|
@@ -4778,10 +4789,16 @@ class EvaVolume {
|
|
|
4778
4789
|
* external volume changes (e.g. from the mute button).
|
|
4779
4790
|
*/
|
|
4780
4791
|
ngOnInit() {
|
|
4781
|
-
// Initialize volume signal
|
|
4782
4792
|
const initialVolume = this.evaAPI.getVideoVolume();
|
|
4783
4793
|
this.videoVolume = signal(initialVolume, ...(ngDevMode ? [{ debugName: "videoVolume" }] : []));
|
|
4784
|
-
this.
|
|
4794
|
+
if (!this.evaAPI.isPlayerReady) {
|
|
4795
|
+
this.playerReady$ = this.evaAPI.playerReadyEvent.subscribe(() => {
|
|
4796
|
+
// Initialize volume signal
|
|
4797
|
+
const initialVolume = this.evaAPI.getVideoVolume();
|
|
4798
|
+
this.videoVolume.set(initialVolume);
|
|
4799
|
+
this.ariaValue.set(String(Math.round(initialVolume * 100)));
|
|
4800
|
+
});
|
|
4801
|
+
}
|
|
4785
4802
|
// Subscribe to volume changes from API
|
|
4786
4803
|
this.videoVolumeSub = this.evaAPI.videoVolumeSubject.subscribe(volume => {
|
|
4787
4804
|
if (volume !== null) {
|
|
@@ -4797,6 +4814,7 @@ class EvaVolume {
|
|
|
4797
4814
|
ngOnDestroy() {
|
|
4798
4815
|
// Clean up subscription
|
|
4799
4816
|
this.videoVolumeSub?.unsubscribe();
|
|
4817
|
+
this.playerReady$?.unsubscribe();
|
|
4800
4818
|
// Clean up event listeners if component destroyed while dragging
|
|
4801
4819
|
this.removeDocumentListeners();
|
|
4802
4820
|
// Clean up announce timeout
|
|
@@ -5586,6 +5604,7 @@ class EvaVideoConfigurationDirective {
|
|
|
5586
5604
|
evaAPI = inject(EvaApi);
|
|
5587
5605
|
elementRef = inject((ElementRef));
|
|
5588
5606
|
sanitizer = inject(DomSanitizer);
|
|
5607
|
+
videoConfigurationDone = output();
|
|
5589
5608
|
/**
|
|
5590
5609
|
* The configuration object to apply to the native `<video>` element.
|
|
5591
5610
|
*
|
|
@@ -5617,6 +5636,7 @@ class EvaVideoConfigurationDirective {
|
|
|
5617
5636
|
ngAfterViewInit() {
|
|
5618
5637
|
this.isViewInitialized = true;
|
|
5619
5638
|
this.applyConfiguration();
|
|
5639
|
+
this.videoConfigurationDone.emit();
|
|
5620
5640
|
}
|
|
5621
5641
|
/**
|
|
5622
5642
|
* Iterates over all supported `EvaVideoElementConfiguration` properties and
|
|
@@ -5637,6 +5657,13 @@ class EvaVideoConfigurationDirective {
|
|
|
5637
5657
|
return;
|
|
5638
5658
|
}
|
|
5639
5659
|
const config = this.evaVideoConfig();
|
|
5660
|
+
// Volume — validated and clamped to [0, 1] by validateAndPrepareStartingVideoVolume,
|
|
5661
|
+
// assigned as a typed number, no sanitization needed
|
|
5662
|
+
if (config.startingVolume) {
|
|
5663
|
+
let v = validateAndPrepareStartingVideoVolume(config.startingVolume);
|
|
5664
|
+
this.elementRef.nativeElement.volume = v;
|
|
5665
|
+
this.evaAPI.setVideoVolume(v);
|
|
5666
|
+
}
|
|
5640
5667
|
// Numeric properties — assigned as typed numbers, no sanitization needed
|
|
5641
5668
|
if (config.width) {
|
|
5642
5669
|
this.elementRef.nativeElement.width = config.width;
|
|
@@ -5679,14 +5706,9 @@ class EvaVideoConfigurationDirective {
|
|
|
5679
5706
|
if (config.poster) {
|
|
5680
5707
|
this.elementRef.nativeElement.poster = this.sanitizer.sanitize(SecurityContext.URL, config.poster) ?? '';
|
|
5681
5708
|
}
|
|
5682
|
-
// Volume — validated and clamped to [0, 1] by validateAndPrepareStartingVideoVolume,
|
|
5683
|
-
// assigned as a typed number, no sanitization needed
|
|
5684
|
-
if (config.startingVolume) {
|
|
5685
|
-
this.elementRef.nativeElement.volume = validateAndPrepareStartingVideoVolume(config.startingVolume);
|
|
5686
|
-
}
|
|
5687
5709
|
}
|
|
5688
5710
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: EvaVideoConfigurationDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
5689
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.2", type: EvaVideoConfigurationDirective, isStandalone: true, selector: "video[evaVideoConfiguration]", inputs: { evaVideoConfig: { classPropertyName: "evaVideoConfig", publicName: "evaVideoConfig", isSignal: true, isRequired: true, transformFunction: null } }, usesOnChanges: true, ngImport: i0 });
|
|
5711
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.2", type: EvaVideoConfigurationDirective, isStandalone: true, selector: "video[evaVideoConfiguration]", inputs: { evaVideoConfig: { classPropertyName: "evaVideoConfig", publicName: "evaVideoConfig", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { videoConfigurationDone: "videoConfigurationDone" }, usesOnChanges: true, ngImport: i0 });
|
|
5690
5712
|
}
|
|
5691
5713
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: EvaVideoConfigurationDirective, decorators: [{
|
|
5692
5714
|
type: Directive,
|
|
@@ -5694,7 +5716,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
|
|
|
5694
5716
|
selector: 'video[evaVideoConfiguration]',
|
|
5695
5717
|
standalone: true
|
|
5696
5718
|
}]
|
|
5697
|
-
}], propDecorators: { evaVideoConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "evaVideoConfig", required: true }] }] } });
|
|
5719
|
+
}], propDecorators: { videoConfigurationDone: [{ type: i0.Output, args: ["videoConfigurationDone"] }], evaVideoConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "evaVideoConfig", required: true }] }] } });
|
|
5698
5720
|
|
|
5699
5721
|
/**
|
|
5700
5722
|
* Root player component for the Eva video player.
|
|
@@ -5768,7 +5790,7 @@ class EvaPlayer {
|
|
|
5768
5790
|
/**
|
|
5769
5791
|
* References to the `<track>` elements rendered in the template for subtitle support.
|
|
5770
5792
|
*/
|
|
5771
|
-
evaVideoTrackElements = viewChildren("evaVideoTracks"
|
|
5793
|
+
// private readonly evaVideoTrackElements = viewChildren<ElementRef<HTMLTrackElement>>("evaVideoTracks");
|
|
5772
5794
|
subtitleChangeSubject = null;
|
|
5773
5795
|
subtitlesTimeout = null;
|
|
5774
5796
|
activeSubtitleLabel = null;
|
|
@@ -5784,10 +5806,17 @@ class EvaPlayer {
|
|
|
5784
5806
|
//when number of tracks is change we must restart all mutation observers as some may become invalid
|
|
5785
5807
|
this.playerMainAPI.updateAndPrepareTracks(changes["evaVideoTracks"].currentValue);
|
|
5786
5808
|
if (!changes["evaVideoTracks"].firstChange) {
|
|
5787
|
-
this.prepareSubtitles();
|
|
5809
|
+
// this.prepareSubtitles();
|
|
5788
5810
|
}
|
|
5789
5811
|
}
|
|
5790
5812
|
}
|
|
5813
|
+
ngOnInit() {
|
|
5814
|
+
// prevent NG0100
|
|
5815
|
+
const defaultTrack = this.evaVideoTracks().find(t => t.default && t.kind === 'subtitles');
|
|
5816
|
+
if (defaultTrack) {
|
|
5817
|
+
this.activeSubtitleLabel = defaultTrack.label ?? null;
|
|
5818
|
+
}
|
|
5819
|
+
}
|
|
5791
5820
|
/**
|
|
5792
5821
|
* Assigns the native `<video>` element to `EvaApi` and signals that the player
|
|
5793
5822
|
* is ready for use. Also logs the presence of any HLS or DASH streaming directives.
|
|
@@ -5806,7 +5835,6 @@ class EvaPlayer {
|
|
|
5806
5835
|
}
|
|
5807
5836
|
}
|
|
5808
5837
|
});
|
|
5809
|
-
this.playerMainAPI.onPlayerReady();
|
|
5810
5838
|
}
|
|
5811
5839
|
/** Reserved for future teardown logic. */
|
|
5812
5840
|
ngOnDestroy() {
|
|
@@ -5817,28 +5845,16 @@ class EvaPlayer {
|
|
|
5817
5845
|
this.playerFullscreenAPI.destroy();
|
|
5818
5846
|
this.playerMainAPI.destroy();
|
|
5819
5847
|
}
|
|
5820
|
-
|
|
5821
|
-
|
|
5822
|
-
clearTimeout(this.subtitlesTimeout);
|
|
5823
|
-
}
|
|
5824
|
-
this.subtitlesTimeout = setTimeout(() => {
|
|
5825
|
-
let trackRef = this.evaVideoTrackElements().find(a => {
|
|
5826
|
-
let tt = a.nativeElement.track;
|
|
5827
|
-
return tt && tt.mode === "showing" && tt.kind === "subtitles";
|
|
5828
|
-
});
|
|
5829
|
-
if (!trackRef) {
|
|
5830
|
-
this.playerMainAPI.currentSubtitleCue.set(null);
|
|
5831
|
-
return;
|
|
5832
|
-
}
|
|
5833
|
-
}, 200);
|
|
5848
|
+
videoConfigReady() {
|
|
5849
|
+
this.playerMainAPI.onPlayerReady();
|
|
5834
5850
|
}
|
|
5835
5851
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: EvaPlayer, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5836
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: EvaPlayer, isStandalone: true, selector: "eva-player", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: true, transformFunction: null }, evaVideoSources: { classPropertyName: "evaVideoSources", publicName: "evaVideoSources", isSignal: true, isRequired: true, transformFunction: null }, evaVideoConfiguration: { classPropertyName: "evaVideoConfiguration", publicName: "evaVideoConfiguration", isSignal: true, isRequired: false, transformFunction: null }, evaVideoTracks: { classPropertyName: "evaVideoTracks", publicName: "evaVideoTracks", isSignal: true, isRequired: false, transformFunction: null }, evaNotSupportedText: { classPropertyName: "evaNotSupportedText", publicName: "evaNotSupportedText", isSignal: true, isRequired: false, transformFunction: null } }, providers: [EvaApi, EvaFullscreenAPI], viewQueries: [{ propertyName: "evaVideoElement", first: true, predicate: ["evaVideoElement"], descendants: true, isSignal: true }
|
|
5852
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: EvaPlayer, isStandalone: true, selector: "eva-player", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: true, transformFunction: null }, evaVideoSources: { classPropertyName: "evaVideoSources", publicName: "evaVideoSources", isSignal: true, isRequired: true, transformFunction: null }, evaVideoConfiguration: { classPropertyName: "evaVideoConfiguration", publicName: "evaVideoConfiguration", isSignal: true, isRequired: false, transformFunction: null }, evaVideoTracks: { classPropertyName: "evaVideoTracks", publicName: "evaVideoTracks", isSignal: true, isRequired: false, transformFunction: null }, evaNotSupportedText: { classPropertyName: "evaNotSupportedText", publicName: "evaNotSupportedText", isSignal: true, isRequired: false, transformFunction: null } }, providers: [EvaApi, EvaFullscreenAPI], viewQueries: [{ propertyName: "evaVideoElement", first: true, predicate: ["evaVideoElement"], descendants: true, isSignal: true }], usesOnChanges: true, ngImport: i0, template: "<video #evaVideoElement [id]=\"id()\" evaMediaEventListeners evaVideoConfiguration\n\t[evaVideoConfig]=\"evaVideoConfiguration()\" (videoConfigurationDone)=\"videoConfigReady()\">\n\t@for (vs of evaVideoSources(); track $index) {\n\t<source #evaVideoSources [type]=\"vs.type\" [src]=\"vs.src\" />\n\t}\n\t@if(evaNotSupportedText()){\n\t<p>{{evaNotSupportedText()}}</p>\n\t}\n\n\t@for (t of evaVideoTracks(); track $index) {\n\t<track #evaVideoTracks [default]=\"t.default\" [kind]=\"t.kind\" [label]=\"t.label\" [src]=\"t.src\" [srclang]=\"t.srclang\"\n\t\t[ariaLabel]=\"t.label\" evaCueChange\n\t\t[evaCueChangeActive]=\"t.kind === 'subtitles' && activeSubtitleLabel === t.label\" />\n\t}\n</video>\n\n<ng-content></ng-content>", styles: [":host{display:block;position:relative;padding:0;margin:0;border:0;border-radius:0;overflow:hidden}:host>video{display:block;width:100%;object-fit:contain;object-position:0 0;transition:padding-bottom var(--eva-transition-duration) ease-in-out}:host(video::cue){font-family:var(--eva-font-family);color:unset;background-color:transparent;font-size:0px;text-decoration:none;text-shadow:none}\n"], dependencies: [{ kind: "directive", type: EvaMediaEventListenersDirective, selector: "video[evaMediaEventListeners]" }, { kind: "directive", type: EvaVideoConfigurationDirective, selector: "video[evaVideoConfiguration]", inputs: ["evaVideoConfig"], outputs: ["videoConfigurationDone"] }, { kind: "directive", type: EvaCueChangeDirective, selector: "track[evaCueChange]", inputs: ["evaCueChangeActive"] }] });
|
|
5837
5853
|
}
|
|
5838
5854
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: EvaPlayer, decorators: [{
|
|
5839
5855
|
type: Component,
|
|
5840
|
-
args: [{ selector: 'eva-player', imports: [EvaMediaEventListenersDirective, EvaVideoConfigurationDirective, EvaCueChangeDirective], providers: [EvaApi, EvaFullscreenAPI], template: "<video #evaVideoElement [id]=\"id()\" evaMediaEventListeners evaVideoConfiguration\n\t[evaVideoConfig]=\"evaVideoConfiguration()\">\n\t@for (vs of evaVideoSources(); track $index) {\n\t<source #evaVideoSources [type]=\"vs.type\" [src]=\"vs.src\" />\n\t}\n\t@if(evaNotSupportedText()){\n\t<p>{{evaNotSupportedText()}}</p>\n\t}\n\n\t@for (t of evaVideoTracks(); track $index) {\n\t<track #evaVideoTracks [default]=\"t.default\" [kind]=\"t.kind\" [label]=\"t.label\" [src]=\"t.src\" [srclang]=\"t.srclang\"\n\t\t[ariaLabel]=\"t.label\" evaCueChange\n\t\t[evaCueChangeActive]=\"t.kind === 'subtitles' && activeSubtitleLabel === t.label\" />\n\t}\n</video>\n\n<ng-content></ng-content>", styles: [":host{display:block;position:relative;padding:0;margin:0;border:0;border-radius:0;overflow:hidden}:host>video{display:block;width:100%;object-fit:contain;object-position:0 0;transition:padding-bottom var(--eva-transition-duration) ease-in-out}:host
|
|
5841
|
-
}], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: true }] }], evaVideoSources: [{ type: i0.Input, args: [{ isSignal: true, alias: "evaVideoSources", required: true }] }], evaVideoConfiguration: [{ type: i0.Input, args: [{ isSignal: true, alias: "evaVideoConfiguration", required: false }] }], evaVideoTracks: [{ type: i0.Input, args: [{ isSignal: true, alias: "evaVideoTracks", required: false }] }], evaNotSupportedText: [{ type: i0.Input, args: [{ isSignal: true, alias: "evaNotSupportedText", required: false }] }], evaVideoElement: [{ type: i0.ViewChild, args: ['evaVideoElement', { isSignal: true }] }]
|
|
5856
|
+
args: [{ selector: 'eva-player', imports: [EvaMediaEventListenersDirective, EvaVideoConfigurationDirective, EvaCueChangeDirective], providers: [EvaApi, EvaFullscreenAPI], template: "<video #evaVideoElement [id]=\"id()\" evaMediaEventListeners evaVideoConfiguration\n\t[evaVideoConfig]=\"evaVideoConfiguration()\" (videoConfigurationDone)=\"videoConfigReady()\">\n\t@for (vs of evaVideoSources(); track $index) {\n\t<source #evaVideoSources [type]=\"vs.type\" [src]=\"vs.src\" />\n\t}\n\t@if(evaNotSupportedText()){\n\t<p>{{evaNotSupportedText()}}</p>\n\t}\n\n\t@for (t of evaVideoTracks(); track $index) {\n\t<track #evaVideoTracks [default]=\"t.default\" [kind]=\"t.kind\" [label]=\"t.label\" [src]=\"t.src\" [srclang]=\"t.srclang\"\n\t\t[ariaLabel]=\"t.label\" evaCueChange\n\t\t[evaCueChangeActive]=\"t.kind === 'subtitles' && activeSubtitleLabel === t.label\" />\n\t}\n</video>\n\n<ng-content></ng-content>", styles: [":host{display:block;position:relative;padding:0;margin:0;border:0;border-radius:0;overflow:hidden}:host>video{display:block;width:100%;object-fit:contain;object-position:0 0;transition:padding-bottom var(--eva-transition-duration) ease-in-out}:host(video::cue){font-family:var(--eva-font-family);color:unset;background-color:transparent;font-size:0px;text-decoration:none;text-shadow:none}\n"] }]
|
|
5857
|
+
}], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: true }] }], evaVideoSources: [{ type: i0.Input, args: [{ isSignal: true, alias: "evaVideoSources", required: true }] }], evaVideoConfiguration: [{ type: i0.Input, args: [{ isSignal: true, alias: "evaVideoConfiguration", required: false }] }], evaVideoTracks: [{ type: i0.Input, args: [{ isSignal: true, alias: "evaVideoTracks", required: false }] }], evaNotSupportedText: [{ type: i0.Input, args: [{ isSignal: true, alias: "evaNotSupportedText", required: false }] }], evaVideoElement: [{ type: i0.ViewChild, args: ['evaVideoElement', { isSignal: true }] }] } });
|
|
5842
5858
|
|
|
5843
5859
|
/**
|
|
5844
5860
|
* DASH streaming directive for the Eva video player.
|