Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

openplayerjs

Package Overview
Dependencies
Maintainers
1
Versions
88
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

openplayerjs - npm Package Compare versions

Comparing version 1.4.1 to 1.5.0

22

CHANGELOG.md

@@ -0,1 +1,23 @@

<a name="1.5.0"></a>
# [1.5.0](https://github.com/openplayerjs/openplayerjs/compare/v1.4.1...v1.5.0) (2018-11-20)
### Bug Fixes
* **ads:** Dispatched new event to show loading state on ads; fixed dimensions on Ad when starting to play; fixed typo in waiting event ([e87466a](https://github.com/openplayerjs/openplayerjs/commit/e87466a))
* **ads:** Fixed issue when player is not recovering after Ads error ([d6b83b0](https://github.com/openplayerjs/openplayerjs/commit/d6b83b0))
* **ads:** Fixed issue where double requests to media were made non-mobile devices after Ads ended ([c63dc94](https://github.com/openplayerjs/openplayerjs/commit/c63dc94))
* **demo:** Reverted demo to original state ([74a4b0b](https://github.com/openplayerjs/openplayerjs/commit/74a4b0b))
* **player:** Added missing events to display/hide loader image ([d7808f0](https://github.com/openplayerjs/openplayerjs/commit/d7808f0))
* **player:** Hid default captions layer to favor player's captions layer ([ecdb4b5](https://github.com/openplayerjs/openplayerjs/commit/ecdb4b5))
* **player:** Modified autoplay workflow to verify current media content instead of video placeholder; removed unnecessary code in Ads to verify autoplay capabilities ([ddb08e1](https://github.com/openplayerjs/openplayerjs/commit/ddb08e1))
* **player:** Moved loader hiding outside of timer on `play` event ([9503041](https://github.com/openplayerjs/openplayerjs/commit/9503041))
### Features
* **player:** Allowed displaying the Pause button correctly and added new flag to control the time it will take to disappear once video starts playing ([d02afa2](https://github.com/openplayerjs/openplayerjs/commit/d02afa2))
<a name="1.4.1"></a>

@@ -2,0 +24,0 @@ ## [1.4.1](https://github.com/openplayerjs/openplayerjs/compare/v1.4.0...v1.4.1) (2018-11-01)

4

package.json
{
"name": "openplayerjs",
"version": "1.4.1",
"version": "1.5.0",
"author": {

@@ -72,3 +72,3 @@ "name": "Rafael Miranda",

"postcss-loader": "^3.0.0",
"release-it": "^7.4.5",
"release-it": "^8.0.0",
"standard-version": "^4.3.0",

@@ -75,0 +75,0 @@ "style-loader": "^0.23.0",

@@ -17,3 +17,3 @@ ![openplayer](https://user-images.githubusercontent.com/910829/46182430-d4c0f380-c299-11e8-89a8-c7554a70b66c.png)

* **Supports IE11+ and all modern browsers**: its CSS and code is compatible with all modern browsers.
* **Supports IE11+ (Win8) and all modern browsers**: its CSS and code is compatible with all modern browsers. IE11+ on Win7 requires an MP4/MP3 fallback to work correctly.
* **Lightweight library**: Less than `20kb` when gzipped.

@@ -88,4 +88,7 @@ * **Monetize video and audio content** with video advertising using VAST, VPAID or VMAP Ads, supported by the amazing [Interactive Media Ads SDK](https://developers.google.com/interactive-media-ads/) (IMA SDK) library.

var player = new OpenPlayer('[player ID]', [valid VAST/VPAID URL|List of VAST/VPAID URLs], [`true|false` for fullscreen effect by default], {
// Number of ms that takes the player to hide the Play button once it starts playing (video only)
// (bt default, `350`)
hidePlayBtnTimer,
// Number of seconds to rewind/forward media
// (by default, player will rewind/forward 5% of the total duration of media)
// (by default, player will rewind/forward 5% of the total duration of media)
step,

@@ -92,0 +95,0 @@ ads: {

@@ -177,2 +177,3 @@ import Captions from './controls/captions';

this._stopControlTimer();
this.player.playBtn.setAttribute('aria-hidden', 'false');
this.player.getContainer().classList.remove('op-controls--hidden');

@@ -184,2 +185,3 @@ this._startControlTimer(2500);

if (isMediaVideo) {
this.player.playBtn.setAttribute('aria-hidden', 'false');
this.player.getContainer().classList.remove('op-controls--hidden');

@@ -262,2 +264,3 @@ this._startControlTimer(2500);

this.player.getContainer().classList.add('op-controls--hidden');
this.player.playBtn.setAttribute('aria-hidden', 'true');
this._stopControlTimer();

@@ -264,0 +267,0 @@ const event = addEvent('controlshidden');

@@ -119,6 +119,50 @@ import CustomMedia from './interfaces/custom-media';

* It will loop the media list found until it reached the first element that can be played.
*
* If none of them can be played, automatically the method destroys the `Media` object.
*
* @see [[Native.load]]
*/
public load(): void {
this._loadSources(this.mediaFiles);
if (!this.mediaFiles.length) {
throw new TypeError('Media not set');
}
// Remove previous media if any is detected and it's different from current one
if (this.media && typeof this.media.destroy === 'function') {
const sameMedia = this.mediaFiles.length === 1 && this.mediaFiles[0].src === this.media.media.src;
if (!sameMedia) {
this.media.destroy();
}
}
// Loop until first playable source is found
this.mediaFiles.some(media => {
try {
this.media = this._invoke(media);
} catch (e) {
this.media = new HTML5Media(this.element, media);
}
// If not valid, make one last attempt to check if it plays with native HTML5
const canPlay = this.canPlayType(media.type);
if (!canPlay) {
this.media = new HTML5Media(this.element, media);
return this.canPlayType(media.type);
}
return canPlay;
});
try {
if (this.media === null) {
throw new TypeError('Media cannot be played with any valid media type');
}
this.media.promise.then(() => {
this.media.load();
});
} catch (e) {
// destroy media
this.media.destroy();
throw e;
}
}

@@ -340,55 +384,2 @@

/**
* Load the first playable source from one or many sources available in the video/audio tag.
*
* If none of them can be played, automatically the method destroys the `Media` object.
* @param {Source[]} sources
* @private
* @memberof Media
*/
private _loadSources(sources: Source[]): void {
if (!sources.length) {
throw new TypeError('Media not set');
}
// Remove previous media if any is detected and it's different from current one
if (this.media && typeof this.media.destroy === 'function') {
const sameMedia = sources.length === 1 && sources[0].src === this.media.media.src;
if (!sameMedia) {
this.media.destroy();
}
}
// Loop until first playable source is found
sources.some(media => {
try {
this.media = this._invoke(media);
} catch (e) {
this.media = new HTML5Media(this.element, media);
}
// If not valid, make one last attempt to check if it plays with native HTML5
const canPlay = this.canPlayType(media.type);
if (!canPlay) {
this.media = new HTML5Media(this.element, media);
return this.canPlayType(media.type);
}
return canPlay;
});
try {
if (this.media === null) {
throw new TypeError('Media cannot be played with any valid media type');
}
this.media.promise.then(() => {
this.media.load();
});
} catch (e) {
// destroy media
this.media.destroy();
throw e;
}
}
/**
* Gather all media sources within the video/audio/iframe tags.

@@ -395,0 +386,0 @@ *

@@ -7,3 +7,3 @@ import Options from '../interfaces/ads/options';

import { isVideo, loadScript } from '../utils/general';
import { isAutoplaySupported } from '../utils/media';
// import { isAutoplaySupported } from '../utils/media';

@@ -132,3 +132,3 @@ declare const google: any;

*/
private ads: string|string[];
private ads: string | string[];

@@ -179,3 +179,3 @@ /**

/**
* Flag to indicate if Ad can be played via `autoplay` attribute.
* Flag to indicate if Ad should be played automatically with sound
*

@@ -185,21 +185,14 @@ * @type boolean

*/
private autoplayAllowed: boolean = false;
private autoStart: boolean = false;
/**
* Flag to indicate if Ad can autoplayed while muted.
* Flag to indicate if Ad should be played automatically without sound
*
* @type boolean
* @private
* @type {boolean}
* @memberof Ads
*/
private autoplayRequiresMuted: boolean = false;
private autoStartMuted: boolean = false;
/**
* Flag to indicate if Ad should be played automatically
*
* @type boolean
* @memberof Ads
*/
private autoStart: boolean = false;
/**
* Flag to indicate if player requested play.

@@ -288,3 +281,3 @@ *

*/
constructor(media: Media, ads: string|string[], labels: any, autoStart?: boolean, options?: Options) {
constructor(media: Media, ads: string | string[], autoStart?: boolean, autoStartMuted?: boolean, options?: Options) {
const defaultOpts = {

@@ -298,2 +291,3 @@ debug: false,

this.autoStart = autoStart || false;
this.autoStartMuted = autoStartMuted || false;
this.adsOptions = { ...defaultOpts, ...options };

@@ -305,53 +299,6 @@ this.playTriggered = false;

const path = this.adsOptions.debug ? this.adsOptions.url.replace(/(\.js$)/, '_debug.js') : this.adsOptions.url;
this.promise = (typeof google === 'undefined' || typeof google.ima === 'undefined') ?
loadScript(path) : new Promise(resolve => resolve());
// Test browser capabilities to autoplay Ad if `autoStart` is flagged as true
if (this.autoStart === true) {
isAutoplaySupported(autoplay => {
this.autoplayAllowed = autoplay;
}, muted => {
this.autoplayRequiresMuted = muted;
}, () => {
if (this.autoplayRequiresMuted || IS_IOS) {
this.adsMuted = true;
this.media.muted = true;
this.adsVolume = 0;
this.media.volume = 0;
const e = addEvent('volumechange');
this.element.dispatchEvent(e);
const volumeEl = document.createElement('div');
const action = IS_IOS || IS_ANDROID ? labels.tap : labels.click;
volumeEl.className = 'op-player__unmute';
volumeEl.innerHTML = `<span>${action}</span>`;
volumeEl.addEventListener('click', () => {
this.adsMuted = false;
this.media.muted = false;
this.adsVolume = this.originalVolume;
this.media.volume = this.originalVolume;
this.adsManager.setVolume(this.originalVolume);
const event = addEvent('volumechange');
this.element.dispatchEvent(event);
// Remove element
volumeEl.remove();
});
const target = this.element.parentElement;
target.insertBefore(volumeEl, target.firstChild);
}
this.promise = (typeof google === 'undefined' || typeof google.ima === 'undefined') ?
loadScript(path) : new Promise(resolve => resolve());
this.promise.then(this.load.bind(this));
});
} else {
this.promise = (typeof google === 'undefined' || typeof google.ima === 'undefined') ?
loadScript(path) : new Promise(resolve => resolve());
this.promise.then(this.load.bind(this));
}
this.promise.then(this.load.bind(this));
return this;

@@ -363,5 +310,6 @@ }

*
* @param {bool} force
* @memberof Ads
*/
public load(): void {
public load(force: boolean = false): void {
this.adsStarted = true;

@@ -395,7 +343,6 @@ this.adsContainer = document.createElement('div');

// Request Ads automatically if `autoplay` was set
if (this.autoStart === true) {
if (this.autoStart === true || this.autoStartMuted === true || force === true) {
if (!this.adsDone) {
this.adsDone = true;
this.adDisplayContainer.initialize();
this.media.load();
}

@@ -415,14 +362,9 @@ this._requestAds();

this.adDisplayContainer.initialize();
this.media.load();
if (IS_IOS || IS_ANDROID) {
this.preloadContent = this._contentLoadedAction;
this.element.addEventListener(
'loadedmetadata',
this._contentLoadedAction.bind(this),
false);
this.media.load();
} else {
this.element.addEventListener('loadedmetadata', this._contentLoadedAction.bind(this));
} else {
this._contentLoadedAction();
}
}
return;

@@ -645,7 +587,9 @@ }

if (!this.mediaStarted) {
const waitingEvent = addEvent('waiting');
this.element.dispatchEvent(waitingEvent);
const loadedEvent = addEvent('loadedmetadata');
this.element.dispatchEvent(loadedEvent);
const resizeEvent = addEvent('resize');
window.dispatchEvent(resizeEvent);
this.resizeAds();
this.mediaStarted = true;

@@ -660,3 +604,9 @@ }

this.element.dispatchEvent(playEvent);
let resized;
if (!resized) {
this.resizeAds();
resized = true;
}
if (this.media.ended) {

@@ -723,3 +673,3 @@ this.adsEnded = false;

this.destroy();
this.load();
this.load(true);
} else {

@@ -733,3 +683,3 @@ if (this.adsManager) {

}
if (this.autoStart === true || this.adsStarted === true) {
if (this.autoStart === true || this.autoStartMuted === true || this.adsStarted === true) {
this.adsActive = false;

@@ -841,2 +791,3 @@ this._resumeMedia();

*
* @private
* @memberof Ads

@@ -846,5 +797,9 @@ */

this.element.addEventListener('ended', this._contentEndedListener.bind(this));
this.media.src = this.mediaSources;
this.element.addEventListener('loadedmetadata', this._loadedMetadataHandler.bind(this));
this.media.load();
if (IS_IOS || IS_ANDROID) {
this.media.src = this.mediaSources;
} else {
const event = addEvent('loadedmetadata');
this.element.dispatchEvent(event);
}
}

@@ -911,4 +866,4 @@

this.adsRequest.linearAdSlotHeight = height;
this.adsRequest.setAdWillAutoPlay(this.autoplayAllowed);
this.adsRequest.setAdWillPlayMuted(this.autoplayRequiresMuted);
this.adsRequest.setAdWillAutoPlay(this.autoStart);
this.adsRequest.setAdWillPlayMuted(this.autoStartMuted);
this.adsLoader.requestAds(this.adsRequest);

@@ -915,0 +870,0 @@ }

@@ -99,2 +99,10 @@ import 'core-js/es6/array';

/**
* Button to play media.
*
* @type HTMLButtonElement
* @memberof Player
*/
public playBtn: HTMLButtonElement;
/**
* Unique identified for the current player instance.

@@ -122,3 +130,3 @@ *

*/
private ads?: string|string[];
private ads?: string | string[];

@@ -144,10 +152,2 @@ /**

/**
* Button to play media.
*
* @type HTMLButtonElement
* @memberof Player
*/
private playBtn: HTMLButtonElement;
/**
* Element to indicate that media is being loaded.

@@ -209,2 +209,11 @@ *

/**
* Flag that indicates if autoplay algorithm has been applied.
*
* @see [[Player._autoplay]]
* @type boolean
* @memberof Player
*/
private processedAutoplay: boolean = false;
/**
* Container for other player options.

@@ -226,2 +235,3 @@ *

private defaultOptions: PlayerOptions = {
hidePlayBtnTimer: 350,
labels: {

@@ -264,3 +274,3 @@ captions: 'CC/Subtitles',

*/
constructor(element: HTMLMediaElement | string, ads?: string|string[], fill?: boolean, options?: PlayerOptions) {
constructor(element: HTMLMediaElement | string, ads?: string | string[], fill?: boolean, options?: PlayerOptions) {
this.element = element instanceof HTMLMediaElement ? element : (document.getElementById(element) as HTMLMediaElement);

@@ -293,3 +303,2 @@ if (this.element) {

this._setEvents();
this._autoplay();
Player.instances[this.id] = this;

@@ -358,2 +367,5 @@ }

if (this.autoplay && !this.processedAutoplay && isVideo(this.element)) {
el.removeEventListener('canplay', this._autoplay.bind(this));
}
this.controls.destroy();

@@ -622,9 +634,10 @@

try {
if (this.autoplay && isVideo(this.element)) {
this.element.addEventListener('canplay', this._autoplay.bind(this));
}
this.media = new Media(this.element, this.options, this.autoplay, Player.customMedia);
this.media.load();
if (this.ads) {
if (!this.autoplay && this.ads) {
const adsOptions = this.options && this.options.ads ? this.options.ads : undefined;
const labels = this.options.labels;
this.adsInstance = new Ads(this.media, this.ads, labels, this.autoplay, adsOptions);
this.adsInstance = new Ads(this.media, this.ads, false, false, adsOptions);
}

@@ -709,3 +722,13 @@ } catch (e) {

this.events.waiting = () => {
const el = this.activeElement();
this.playBtn.setAttribute('aria-hidden', 'true');
this.loader.setAttribute('aria-hidden', el instanceof Media || IS_ANDROID || IS_IOS ? 'false' : 'true');
};
this.events.durationchange = () => {
const el = this.activeElement();
this.playBtn.setAttribute('aria-hidden', 'true');
this.loader.setAttribute('aria-hidden', el instanceof Media || IS_ANDROID || IS_IOS ? 'false' : 'true');
};
this.events.canplay = () => {
this.playBtn.setAttribute('aria-hidden', 'true');
this.loader.setAttribute('aria-hidden', 'true');

@@ -724,10 +747,12 @@ };

this.events.play = () => {
const el = this.activeElement();
this.playBtn.classList.add('op-player__play--paused');
this.loader.setAttribute('aria-hidden', el instanceof Media || IS_ANDROID || IS_IOS ? 'false' : 'true');
setTimeout(() => {
this.playBtn.setAttribute('aria-hidden', 'true');
this.loader.setAttribute('aria-hidden', 'true');
}, 350);
}, this.options.hidePlayBtnTimer);
};
this.events.playing = () => {
this.playBtn.setAttribute('aria-hidden', 'true');
this.loader.setAttribute('aria-hidden', 'true');
};

@@ -738,3 +763,3 @@ this.events.pause = () => {

const el = this.activeElement();
this.playBtn.setAttribute('aria-hidden', el instanceof Media ? 'false' : 'true');
this.playBtn.setAttribute('aria-hidden', el instanceof Media || IS_ANDROID || IS_IOS ? 'false' : 'true');
};

@@ -815,5 +840,7 @@ }

private _autoplay() {
if (this.autoplay) {
this.autoplay = false;
isAutoplaySupported(autoplay => {
if (!this.processedAutoplay) {
this.processedAutoplay = true;
this.element.removeEventListener('canplay', this._autoplay.bind(this));
isAutoplaySupported(this.element, autoplay => {
this.canAutoplay = autoplay;

@@ -849,5 +876,11 @@ }, muted => {

target.insertBefore(volumeEl, target.firstChild);
} else {
this.activeElement().muted = false;
this.activeElement().volume = this.volume;
}
if (!this.adsInstance && (this.canAutoplay || this.canAutoplayMuted)) {
if (this.ads) {
const adsOptions = this.options && this.options.ads ? this.options.ads : undefined;
this.adsInstance = new Ads(this.media, this.ads, this.canAutoplay, this.canAutoplayMuted, adsOptions);
} else if (this.canAutoplay || this.canAutoplayMuted) {
this.play();

@@ -854,0 +887,0 @@ }

@@ -85,2 +85,3 @@ /**

* @export
* @param {HTMLMediaElement} media Callback to determine if browser can autoplay.
* @param {function} autoplay Callback to determine if browser can autoplay.

@@ -90,12 +91,8 @@ * @param {function} muted Callback to determine if browser requires media to be muted.

*/
export function isAutoplaySupported(autoplay: (n: any) => any, muted: (n: any) => any, callback: () => any): void {
const videoContent = document.createElement('video');
// Use a video WITH audio to test properly browser's capabilities.
videoContent.src = 'https://platform.galio.nl/op/media/xsmall.mp4';
const playPromise = videoContent.play();
export function isAutoplaySupported(media: HTMLMediaElement, autoplay: (n: any) => any, muted: (n: any) => any, callback: () => any): void {
const playPromise = media.play();
if (playPromise !== undefined) {
playPromise.then(() => {
// Umuted autoplay works.
videoContent.pause();
media.pause();
autoplay(true);

@@ -106,7 +103,7 @@ muted(false);

// Unmuted autoplay failed. New attempt with muted autoplay.
videoContent.volume = 0;
videoContent.muted = true;
videoContent.play().then(() => {
media.volume = 0;
media.muted = true;
media.play().then(() => {
// Muted autoplay works.
videoContent.pause();
media.pause();
autoplay(true);

@@ -117,4 +114,4 @@ muted(true);

// Both muted and unmuted autoplay failed. Fallback to click to play.
videoContent.volume = 1;
videoContent.muted = false;
media.volume = 1;
media.muted = false;
autoplay(false);

@@ -126,4 +123,4 @@ muted(false);

} else {
autoplay(!videoContent.paused || 'Promise' in window && playPromise instanceof Promise);
videoContent.pause();
autoplay(!media.paused || 'Promise' in window && playPromise instanceof Promise);
media.pause();
muted(false);

@@ -130,0 +127,0 @@ callback();

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc