ngx-plyr
Version:
Angular 6+ bindings for [plyr video and audio player](https://github.com/sampotts/plyr). Supports everything that original library supports.
359 lines (353 loc) • 12 kB
JavaScript
import * as Plyr from 'plyr';
import { __decorate, __metadata } from 'tslib';
import { ElementRef, NgZone, Renderer2, Input, ViewChild, Output, Component, NgModule } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { filter, first, switchMap } from 'rxjs/operators';
class DefaultPlyrDriver {
create(params) {
return new Plyr(params.videoElement, params.options);
}
updateSource(params) {
params.plyr.source = params.source;
}
destroy(params) {
params.plyr.destroy();
}
}
let PlyrComponent = class PlyrComponent {
constructor(elementRef, ngZone, renderer) {
this.elementRef = elementRef;
this.ngZone = ngZone;
this.renderer = renderer;
this.playerChange = new BehaviorSubject(null);
this.events = new Map();
this.plyrType = 'video';
// ngx-plyr events
this.plyrInit = this.playerChange.pipe(filter(player => !!player));
// standard media events
this.plyrProgress = this.createLazyEvent('progress');
this.plyrPlaying = this.createLazyEvent('playing');
this.plyrPlay = this.createLazyEvent('play');
this.plyrPause = this.createLazyEvent('pause');
this.plyrTimeUpdate = this.createLazyEvent('timeupdate');
this.plyrVolumeChange = this.createLazyEvent('volumechange');
this.plyrSeeking = this.createLazyEvent('seeking');
this.plyrSeeked = this.createLazyEvent('seeked');
this.plyrRateChange = this.createLazyEvent('ratechange');
this.plyrEnded = this.createLazyEvent('ended');
this.plyrEnterFullScreen = this.createLazyEvent('enterfullscreen');
this.plyrExitFullScreen = this.createLazyEvent('exitfullscreen');
this.plyrCaptionsEnabled = this.createLazyEvent('captionsenabled');
this.plyrCaptionsDisabled = this.createLazyEvent('captionsdisabled');
this.plyrLanguageChange = this.createLazyEvent('languagechange');
this.plyrControlsHidden = this.createLazyEvent('controlshidden');
this.plyrControlsShown = this.createLazyEvent('controlsshown');
this.plyrReady = this.createLazyEvent('ready');
// HTML5 events
this.plyrLoadStart = this.createLazyEvent('loadstart');
this.plyrLoadedData = this.createLazyEvent('loadeddata');
this.plyrLoadedMetadata = this.createLazyEvent('loadedmetadata');
this.plyrQualityChange = this.createLazyEvent('qualitychange');
this.plyrCanPlay = this.createLazyEvent('canplay');
this.plyrCanPlayThrough = this.createLazyEvent('canplaythrough');
this.plyrStalled = this.createLazyEvent('stalled');
this.plyrWaiting = this.createLazyEvent('waiting');
this.plyrEmptied = this.createLazyEvent('emptied');
this.plyrCueChange = this.createLazyEvent('cuechange');
this.plyrError = this.createLazyEvent('error');
// YouTube events
this.plyrStateChange = this.createLazyEvent('statechange');
this.subscriptions = [];
}
get player() {
return this.playerChange.getValue();
}
ngOnChanges(changes) {
this.subscriptions.push(this.plyrInit.pipe(first()).subscribe((player) => {
const reinitTriggers = [changes.plyrOptions, changes.plyrPlaysInline, changes.plyrCrossOrigin].filter(t => !!t);
if (reinitTriggers.length) {
if (reinitTriggers.some(t => !t.firstChange)) {
this.initPlyr(true);
}
}
else {
this.updatePlyrSource(player);
}
}));
}
ngOnDestroy() {
this.destroyPlayer();
this.subscriptions.forEach(s => s.unsubscribe());
}
ngAfterViewInit() {
this.initPlyr();
}
initPlyr(force = false) {
if (force || !this.player) {
this.ngZone.runOutsideAngular(() => {
this.destroyPlayer();
this.driver = this.plyrDriver || new DefaultPlyrDriver();
this.ensureVideoElement();
const newPlayer = this.driver.create({
videoElement: this.videoElement,
options: this.plyrOptions,
});
this.updatePlyrSource(newPlayer);
this.playerChange.next(newPlayer);
});
}
}
updatePlyrSource(plyr) {
this.driver.updateSource({
videoElement: this.videoElement,
plyr,
source: {
type: this.plyrType,
title: this.plyrTitle,
sources: this.plyrSources,
poster: this.plyrPoster,
tracks: this.plyrTracks,
},
});
}
// see https://stackoverflow.com/a/53704102/1990451
createLazyEvent(name) {
return this.plyrInit.pipe(switchMap(() => new Observable(observer => this.on(name, (data) => this.ngZone.run(() => observer.next(data))))));
}
destroyPlayer() {
if (this.player) {
Array.from(this.events.keys()).forEach(name => this.off(name));
this.driver.destroy({
plyr: this.player,
});
this.videoElement = null;
}
}
get hostElement() {
return this.elementRef.nativeElement;
}
// this method is required because the plyr inserts clone of the original element on destroy
// so we catch the clone element right here and reuse it
ensureVideoElement() {
const videoElement = this.hostElement.querySelector('video');
if (videoElement) {
this.videoElement = videoElement;
}
else {
this.videoElement = this.renderer.createElement('video');
this.videoElement.controls = true;
if (this.plyrCrossOrigin) {
this.videoElement.setAttribute('crossorigin', '');
}
if (this.plyrPlaysInline) {
this.videoElement.setAttribute('playsinline', '');
}
this.renderer.appendChild(this.hostElement, this.videoElement);
}
}
on(name, handler) {
this.events.set(name, handler);
this.player.on(name, handler);
}
off(name) {
this.player.off(name, this.events.get(name));
this.events.delete(name);
}
};
PlyrComponent.ctorParameters = () => [
{ type: ElementRef },
{ type: NgZone },
{ type: Renderer2 }
];
__decorate([
Input(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrDriver", void 0);
__decorate([
Input(),
__metadata("design:type", String)
], PlyrComponent.prototype, "plyrType", void 0);
__decorate([
Input(),
__metadata("design:type", String)
], PlyrComponent.prototype, "plyrTitle", void 0);
__decorate([
Input(),
__metadata("design:type", String)
], PlyrComponent.prototype, "plyrPoster", void 0);
__decorate([
Input(),
__metadata("design:type", Array)
], PlyrComponent.prototype, "plyrSources", void 0);
__decorate([
Input(),
__metadata("design:type", Array)
], PlyrComponent.prototype, "plyrTracks", void 0);
__decorate([
Input(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrOptions", void 0);
__decorate([
Input(),
__metadata("design:type", Boolean)
], PlyrComponent.prototype, "plyrCrossOrigin", void 0);
__decorate([
Input(),
__metadata("design:type", Boolean)
], PlyrComponent.prototype, "plyrPlaysInline", void 0);
__decorate([
ViewChild('v'),
__metadata("design:type", ElementRef)
], PlyrComponent.prototype, "vr", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrInit", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrProgress", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrPlaying", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrPlay", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrPause", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrTimeUpdate", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrVolumeChange", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrSeeking", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrSeeked", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrRateChange", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrEnded", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrEnterFullScreen", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrExitFullScreen", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrCaptionsEnabled", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrCaptionsDisabled", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrLanguageChange", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrControlsHidden", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrControlsShown", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrReady", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrLoadStart", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrLoadedData", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrLoadedMetadata", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrQualityChange", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrCanPlay", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrCanPlayThrough", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrStalled", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrWaiting", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrEmptied", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrCueChange", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrError", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], PlyrComponent.prototype, "plyrStateChange", void 0);
PlyrComponent = __decorate([
Component({
selector: 'plyr, [plyr]',
template: "",
exportAs: 'plyr',
styles: [""]
}),
__metadata("design:paramtypes", [ElementRef,
NgZone,
Renderer2])
], PlyrComponent);
let PlyrModule = class PlyrModule {
};
PlyrModule = __decorate([
NgModule({
declarations: [
PlyrComponent,
],
exports: [
PlyrComponent,
]
})
], PlyrModule);
/**
* Generated bundle index. Do not edit.
*/
export { DefaultPlyrDriver, PlyrComponent, PlyrModule };
//# sourceMappingURL=ngx-plyr.js.map