UNPKG

@flosportsinc/ng-video-autoplay

Version:

Simple way to ensure videos autoplay even if they need to be muted first.

299 lines (293 loc) 11.8 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('rxjs/operators'), require('rxjs'), require('typescript-monads')) : typeof define === 'function' && define.amd ? define('@flosportsinc/ng-video-autoplay', ['exports', '@angular/core', 'rxjs/operators', 'rxjs', 'typescript-monads'], factory) : (global = global || self, factory((global.flosportsinc = global.flosportsinc || {}, global.flosportsinc['ng-video-autoplay'] = {}), global.ng.core, global.rxjs.operators, global.rxjs, global.typescriptMonads)); }(this, function (exports, core, operators, rxjs, typescriptMonads) { 'use strict'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ // tslint:disable:no-object-mutation /** @type {?} */ var filterHalted = (/** * @param {?} source * @return {?} */ function (source) { return source.pipe(operators.filter((/** * @param {?} res * @return {?} */ function (res) { return res.halted === true; }))); }); /** @type {?} */ var tryPlayVideoAsIs = (/** * @param {?} source * @return {?} */ function (source) { return source.pipe(operators.flatMap((/** * @param {?} videoElement * @return {?} */ function (videoElement) { return videoElement.play() .then((/** * @return {?} */ function () { return ({ videoElement: videoElement, halted: false }); })) .catch((/** * @return {?} */ function () { return ({ videoElement: videoElement, halted: true }); })); })), filterHalted); }); /** @type {?} */ var tryPlayVideoMuted = (/** * @param {?} source * @return {?} */ function (source) { return source.pipe(operators.map((/** * @param {?} res * @return {?} */ function (res) { res.videoElement.muted = true; res.videoElement.volume = 0; return res.videoElement; })), tryPlayVideoAsIs); }) // 1) attempt to play as-is (including autoplay + unmuted) // 2) attempt to play muted, showing unmite button // 3) show click to play ; // 1) attempt to play as-is (including autoplay + unmuted) // 2) attempt to play muted, showing unmite button // 3) show click to play var FloVideoAutoplayDirective = /** @class */ (function () { function FloVideoAutoplayDirective(elmRef, rd) { var _this = this; this.elmRef = elmRef; this.rd = rd; this.floVideoAutoplay = true; this.floVideoAutoplayIndex = 0; this.onDestroySource = new rxjs.Subject(); this.onDestroy = this.onDestroySource.pipe(operators.share()); this.canExecute = (/** * @return {?} */ function () { return _this.floVideoAutoplay === true || _this.floVideoAutoplay === ''; }); this.maybeVideoElement = (/** * @return {?} */ function () { return typescriptMonads.maybe(_this.elmRef.nativeElement).filter((/** * @param {?} e * @return {?} */ function (e) { return e.nodeName === 'VIDEO'; })); }); this.maybeUnmuteActionRef = (/** * @return {?} */ function () { return typescriptMonads.maybe(_this.floVideoAutoplayClickUnmuteRef).filter((/** * @param {?} a * @return {?} */ function (a) { return (/** @type {?} */ (a)) !== ''; })); }); this.maybePlayActionRef = (/** * @return {?} */ function () { return typescriptMonads.maybe(_this.floVideoAutoplayClickPlayRef).filter((/** * @param {?} a * @return {?} */ function (a) { return (/** @type {?} */ (a)) !== ''; })); }); this.hideRef = (/** * @param {?} ref * @return {?} */ function (ref) { return _this.rd.setStyle(ref, 'display', 'none'); }); this.showRef = (/** * @param {?} ref * @return {?} */ function (ref) { return _this.rd.setStyle(ref, 'display', 'block'); }); this.volumeChange = (/** * @param {?} videoElement * @return {?} */ function (videoElement) { return rxjs.fromEvent(videoElement, 'volumechange', { passive: true }).pipe(operators.map((/** * @param {?} evt * @return {?} */ function (evt) { return (/** @type {?} */ (evt.target)); })), operators.share(), operators.takeUntil(_this.onDestroy)); }); this.initOnVideo = (/** * @param {?} videoElement * @return {?} */ function (videoElement) { return rxjs.fromEvent(videoElement, 'loadstart').pipe(operators.tap((/** * @return {?} */ function () { return videoElement.setAttribute('autoplay', 'true'); })), operators.map((/** * @param {?} evt * @return {?} */ function (evt) { return (/** @type {?} */ (evt.target)); })), tryPlayVideoAsIs, tryPlayVideoMuted, operators.take(1)).subscribe((/** * @param {?} res * @return {?} */ function (res) { res.videoElement.preload = 'none'; res.videoElement.muted = false; res.videoElement.volume = 1; _this.maybePlayActionRef().tapSome(_this.showRef); })); }); this.runUnmuteSequence = (/** * @param {?} actionRef * @return {?} */ function (actionRef) { return (/** * @param {?} runOnce * @return {?} */ function (runOnce) { return (/** * @param {?} videoElement * @return {?} */ function (videoElement) { videoElement.setAttribute('autoplay', 'true'); rxjs.fromEvent(actionRef, 'click').pipe(operators.takeUntil(_this.onDestroy)).subscribe((/** * @return {?} */ function () { videoElement.muted = false; videoElement.volume = 1; })); _this.volumeChange(videoElement).pipe(operators.filter((/** * @param {?} v * @return {?} */ function (v) { return !v.muted || v.volume > 0; })), operators.takeUntil(_this.onDestroy)) .subscribe((/** * @return {?} */ function () { return _this.hideRef(actionRef); })); /** @type {?} */ var showRef = _this.volumeChange(videoElement).pipe(operators.filter((/** * @param {?} v * @return {?} */ function (v) { return v.muted || v.volume <= 0; }))); (runOnce ? showRef.pipe(operators.take(1)) : showRef).subscribe((/** * @return {?} */ function () { return _this.showRef(actionRef); })); }); }); }); } /** * @return {?} */ FloVideoAutoplayDirective.prototype.ngAfterContentInit = /** * @return {?} */ function () { var _this = this; if (!this.canExecute()) { return; } this.maybeVideoElement().tapSome(this.initOnVideo); this.videos.map((/** * @param {?} a * @return {?} */ function (a) { return a.nativeElement; })).forEach(this.initOnVideo); this.maybeUnmuteActionRef().tapSome((/** * @param {?} ref * @return {?} */ function (ref) { _this.hideRef(ref); typescriptMonads.either(_this.maybeVideoElement().valueOrUndefined(), typescriptMonads.maybe(_this.videos.toArray()[_this.floVideoAutoplayIndex]).map((/** * @param {?} a * @return {?} */ function (a) { return a.nativeElement; })).valueOrUndefined()) .tap({ left: _this.runUnmuteSequence(ref)(false), right: _this.runUnmuteSequence(ref)(true) }); })); this.maybePlayActionRef().tapSome((/** * @param {?} actionRef * @return {?} */ function (actionRef) { _this.hideRef(actionRef); rxjs.fromEvent(actionRef, 'click').pipe(operators.takeUntil(_this.onDestroy)).subscribe((/** * @return {?} */ function () { _this.hideRef(actionRef); _this.maybeVideoElement().tapSome((/** * @param {?} v * @return {?} */ function (v) { return v.play(); })); })); })); }; /** * @return {?} */ FloVideoAutoplayDirective.prototype.ngOnDestroy = /** * @return {?} */ function () { this.onDestroySource.next(); this.onDestroySource.complete(); }; FloVideoAutoplayDirective.decorators = [ { type: core.Directive, args: [{ selector: '[floVideoAutoplay]' },] } ]; /** @nocollapse */ FloVideoAutoplayDirective.ctorParameters = function () { return [ { type: core.ElementRef }, { type: core.Renderer2 } ]; }; FloVideoAutoplayDirective.propDecorators = { floVideoAutoplay: [{ type: core.Input }], floVideoAutoplayClickUnmuteRef: [{ type: core.Input }], floVideoAutoplayClickPlayRef: [{ type: core.Input }], floVideoAutoplayIndex: [{ type: core.Input }], videos: [{ type: core.ContentChildren, args: ['floVideoAutoplay', { descendants: true },] }] }; return FloVideoAutoplayDirective; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ var FloVideoAutoplayModule = /** @class */ (function () { function FloVideoAutoplayModule() { } FloVideoAutoplayModule.decorators = [ { type: core.NgModule, args: [{ declarations: [ FloVideoAutoplayDirective ], exports: [ FloVideoAutoplayDirective ] },] } ]; return FloVideoAutoplayModule; }()); exports.FloVideoAutoplayModule = FloVideoAutoplayModule; exports.ɵa = FloVideoAutoplayDirective; Object.defineProperty(exports, '__esModule', { value: true }); })); //# sourceMappingURL=flosportsinc-ng-video-autoplay.umd.js.map