Giter Club home page Giter Club logo

gg-ez-vp's Introduction

GG EZ Video Player

Simple video player with minimal setup, intuitive API and straightforward features.

Player

Features:

  • Easy setup
  • Customizable controls (or use our slick defaults!)
  • Lightweight
  • Programmatic access to video playback APIs
  • Browser (UMD), CommonJS and ES module versions
  • VAST / VPAID Support for a single Linear Creative. Parsing is provided by dailymotion/vast-client-js. Note that at the time, only one Ad is loaded, and only Linear Creatives are played and tracked.

See the demo page

Table of contents

Installation

Browser

<!-- latest stable version -->
<script src="https://c.gumgum.com/vp/latest/gg-ez-vp.js">

<!-- beta version | synced with develop branch  -->
<script src="https://c.gumgum.com/vp/beta/gg-ez-vp.js">

<!-- or specific release, replace "1.x.x" with the release you want to use -->
<script src="https://c.gumgum.com/vp/1.x.x/gg-ez-vp.js">

Note: One of GumGum's solutions, is contextual advertising, as such, our CDN is blocked by ad blockers; if the scripts are not loading, disable the ad blocker or use an external CDN (TBD #21).

CommonJS

TODO: Installation

const GgEzVp = require('gg-ez-vp');

ES Modules

TODO: Installation

import GgEzVp from 'gg-ez-vp';

Usage

GgEzVp works by attaching itself to a unique container, ideally an empty <div> with a unique id:

<body>
    <div>
        <div class="randomContent">
            Some content
        </div>
        <div id="myVideo" class="myVideoStyles"></div>
    </div>
</body>

Then, to create a player instance:

// js
const minimalConfiguration = {
    container: 'myVideo',
    src: 'myvideo.mp4'
};

const ggEzVpInstance = new GgEzVp(minimalConfiguration);

This minimal configuration will create a unique video player instance using the defaults set by GgEzVp.

note: src and container are the only required options in the configuration object.

Customization

Options:

key defaultValue required description
container null true either a node's id or the DOM node itself where the player will be loaded to
src null true string or array of strings used to retrieve video and/or VAST
width null false by default the player will take available space, unless width is specified
height null false by default the player will take available space, unless height is specified
controls object false specific controls configurations, see Controls section below
autoplay false false whether to play the video automatically or not
volume 1 false initial volume for playback must be between 0.0 and 1
muted true false video will be muted by default
playsinline true false A Boolean attribute indicating that the video is to be played within the element's playback area.
poster null false source for an image to be used as video poster
preload 'auto' false standard HTML values for preload (none
loop false false whether to loop video or not
isVAST false false enables support for a single VAST / VPAID TAG to be parsed and used as source, will force displaying the ad controls
adControls false false forces displaying the ad controls instead of the regular contols

Controls

Besides the programmatic interaction with the player, there are also a number of controls displayed by default, they can be toggled by passing a controls property in the initial configuration. See the Styles section for information on how to customize the visuals.

Player

controlName defaultValue description
timestamp true display the current time of the video in the format [m:ss]
volume true display the volume controls (mute toggle and range input)
volumeRange true the volume range input can be hidden if only the volume button is needed
progress true display the playback progress bar, clicking on the bar will set the video currentTime to the selected percentage (except on Ads)
play true show the play/pause button
expand true show the expand to fullscreen button
timestampAd false used only for Ads, will display the remaining time in the format [Ad ss]
skip false used only for Ads, will display a skip button

Additionally, passing the adControls: true option, will display a different set of controls for Ads:

Ad Controls

controlName defaultValue description
timestampAd true display the remainingTime time of the ad in the format [Ad ss].
skip true display a skip button, pressing it will emit the 'skip' event
progress true the progress bar will display, but it won't show the scrub, nor it be possible to set the time with it
play true show the play/pause button
expand true show the expand to fullscreen button

Note: the timestamp control will be disabled when adControls is true and instead timestampAd will be displayed.

Control configuration examples

// Controls off
const controlsOffConfig = {
    container: 'myVideo',
    src: 'myvideo.mp4',
    controls: false
};

// timestamp and volume off
const customControls = {
    container: 'myVideo',
    src: 'myvideo.mp4',
    controls: {
        timestamp: false,
        volume: false
    }
};

// ad timestamp, skip and expand off
const customControls = {
    container: 'myVideo',
    src: 'myvideo.mp4',
    adControls: true, // will enable ad controls
    controls: {
        timestampAd: false,
        expand: false,
        skip: false
    }
};

Styles

To use the default styles, just include the styles.css file before loading the player's javascript:

<!-- latest version of the styles -->
<link src="https://c.gumgum.com/vp/latest/gg-ez-vp.css">

The default styles that can be overridden by any custom styles you may need:

.gg-ez-vp--play {
    background: url('/images/my-custom-play-btn.png');
    width: 40px;
    height: 40px;
}

.gg-ez-vp--progress-filled {
    background: red;
}

It is encouraged to override the styles rather than completely writing your own.

Use these selectors to override the styles:

selector component
.gg-ez-vp player container
.gg-ez-vp--viewer video element
.gg-ez-vp--controls control bar
.gg-ez-vp--timestamp current video time
.gg-ez-vp--timestamp-break bar dividing currentime / duration
.gg-ez-vp--timestamp-ad ad remaining time
.gg-ez-vp--volume volume controls container
.gg-ez-vp--volume-control volume slider container
.gg-ez-vp--volume-control-slider volume slider
.gg-ez-vp--input-range volume slider input styles
.gg-ez-vp--progress progress container
.gg-ez-vp--progress-bar progress track
.gg-ez-vp--progress-filled progress bar fill
.gg-ez-vp--progress-filled:after progress bar scrub
.gg-ez-vp--button-icon play and volume buttons
.gg-ez-vp--button-icon.mute muted state of the volume control
.gg-ez-vp--button-icon.low low volume state of the volume control (under 33%)
.gg-ez-vp--button-icon.medium medium volume state of the volume control (between 34% and 66%)
.gg-ez-vp--button-icon.high high volume state of the volume control (above 66%)
.gg-ez-vp--button-icon.play shown while video is not playing on the play control
.gg-ez-vp--button-icon.pause shown while video is playing on the play control
.gg-ez-vp--button-icon.replay shown after the video ends
.gg-ez-vp--button-icon.expand expand button icon
.gg-ez-vp--blocker invisible div that can be used to prevent clicks on VPAID/VAST thumbnails
.gg-ez-vp--slot invisible div used as VPAID slot

There are also a few modifier selectors applied to the container .gg-ez-vp:

selector description
.gg-ez-vp--no-scrub applied on adControls: true. Prevents displaying the scrub and adjusts ad styles.
.gg-ez-vp--skip applied when the skip button will be displayed
.gg-ez-vp--volume-only adjusts the styles when only the volume toggle button is displayed
.gg-ez-vp--touchscreen added when the device uses a touchscreen, this will show all enabled controls instead of activating them on hover

See src/styles.css for all styles.

Public methods

method name parameters description
destroy none removes all instance and video tag listeners, removes the player from the DOM leaving behind the original container
fullscreenToggle none toggles the fullscreen mode
getCurrentTime none returns the currentTime from the video tag, this data is also provided by the playback-progress event
muteUnmute none toggle video sound on/off
mute none disable video sound (sets volume to 0)
unmute none enable video sound (sets volume to last value)
on eventName, listenerFn attaches a listener function to either the video tag or the player instance, the function will be run every time the event is fired, see events
once eventName, listenerFn attaches a listener function to either the video tag or the player instance, the function will fire just on time, see events
pause none stop video playback
playPause none toggle pause state on/off
play none start video playback
volume float number sets the video volume, see volume configuration
getVolume float number gets the video volume
getDuration number gets the video duration

Accessible properties

All properties are read-only:

property name type description
ready boolean helps identify when the video/ad is rendered and ready for playback
dataReady boolean helps identify when the player has all the data it needs to render the video and all listeners have been set
config object current player's configuration, see Options
player DOM node current video tag, it is not recommended to interact directly with it, and instead rely on the player's methods, but is provided if necessary
dimensions object current player dimensions
VPAIDWrapper object wrapper that allows direct interaction with a VPAID creative if available, it is not recommended to interact directly with it, but it is possible if necessary

Events

Listen for any <video> tag events or GgEzVp events:

ggEzVpInstance.on('play', myPlayListener);
ggEzVpInstance.on('playback-progress', myPlaybackListener);

Listen to them only once:

ggEzVpInstance.once('play', myPlayListener);
ggEzVpInstance.once('playback-progress', myProgressListener);

The player also emits custom events to extend the video tag behavior:

event name description payload
data-ready emitted when a source for the video is received, either by configuration or after asynchronous VAST parsing undefined
playback-progress emitted when the video currentTime changes { remainingTime, readableTime, duration, currentTime, fancyCurrentTime, fancyDuration }
player-click emitted when clicks are detected inside the container element click event
pre-destroy emitted before removing listeners and the container node undefined
ready emitted when the class is ready for playback undefined
resize emitted when video tag changes either width or height { width, height }
skip emitted when the skip button is pressed undefined
expand emitted when the fullscreen is toggled boolean isFullscreen
error emitted when player encounters an error error message or object

Custom events are provided by Nano Events

VAST

VAST 4.2 is supported, thanks to dailymotion/vast-client-js. If a VPAID is detected, it will be loaded and executed, otherwise, the player will track and emit all the events in the VAST tag.

Inline VAST example

The player also accepts Inline VAST XML being returned from many SSPs. Therefore a Blob URL object needs to be created.

const src = `<?xml version="1.0" encoding="UTF-8"?>
<VAST xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vast.xsd" version="3.0">
    <Ad>
        <InLine>
            <Creatives>
                <Creative sequence="1">
                    <Linear>
                        <Duration>00:01:00</Duration>
                        <VideoClicks>
                            <ClickThrough id="GDFP"><![CDATA[https://iabtechlab.com]]></ClickThrough>
                        </VideoClicks>
                        <MediaFiles>
                            <MediaFile id="GDFP" delivery="progressive" type="video/mp4"><![CDATA[https://aba.gumgum.com/13861/8/big_buck_bunny_640x360.mp4]]></MediaFile>
                        </MediaFiles>
                    </Linear>
                </Creative>
            </Creatives>
        </InLine>
    </Ad>
</VAST>`;

const blob = new Blob([src], { type: 'text/xml' });
const config = {
    container: 'myVideo',
    src: URL.createObjectURL(blob),
    isVAST: true
};
const ggEzVpInstance = new GgEzVp(config);

VPAID

The player is capable of playing VPAID 2.0 if the src is a VAST tag and isVAST is set to true in the configuration. Player events will not be set immediately, instead they will be stored and attached after the VPAID has emitted the onAdLoaded event.

Event mapping

All VPAID events are emmitted, additionally, some of them will also fire a custom event:

VPAID event name GgEzVp event name
AdLoaded data-ready
AdStarted play
AdPlaying play
AdVideoStart play
AdPaused pause
AdStopped ended
AdRemainingTimeChange playback-progress
AdDurationChange playback-progress
AdVideoFirstQuartile playback-progress
AdVideoMidpoint playback-progress
AdVideoThirdQuartile playback-progress
AdVideoComplete playback-progress
AdError error

It is encouraged to use these events mapped by the player, but if you require listening to other events, all VPAID events are emitted as well with exception of the AdRemainingTimeChange event (use playback-progress instead). All data is retrieved from the VPAID creative, not the video tag itself.

Development

yarn install to install dependencies

yarn start to fire dev server and node watcher, the server can be accessed at localhost:8080, and the demo at localhost:8080/demo

See scripts section of package.json for all available scripts

gg-ez-vp's People

Contributors

dependabot[bot] avatar estavillo avatar lbenmore avatar luizmendez avatar mnicole avatar torbenbrodt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

gg-ez-vp's Issues

Volume is read-only in mobile safari

On iOS this.player.volume will always return 1, we should rely on the muted property to validate the volume icons to show and how to toggle mute.

On iOS devices, the audio level is always under the user’s physical control. The volume property is not settable in JavaScript. Reading the volume property always returns 1.

https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html

VAST clickthru not working

Clickthru on VAST/VPAID is not working, this could be due to the events being captured by the player, or because the click event is not implemented.

For VPAID, clicks should be delegated to the VPAIDWrapper.

For VAST, the click event from vastTracker should be listened to, and a new window should open with the received URL.

In both cases, the player-click event should be emitted to allow users to perform any other actions on upon it.

Display controls on touchscreens

Our controls depend on :hover which doesn't behave in the same way in touchscreen devices.
As a fix (while someone with better design skills reviews it), we should display the enabled controls at all times.

Allow using any selector for the container property

Our current code allows two types for the container property, one is a DOM node that will be used as is, the other is a string that represents an id for the node to use.

We could improve this further by allowing the user to pass any selector allowed by querySelector.

If we detect that the value given is not a node and includes a special character, we will use querySelector, if there is no special char, we fallback to getElementById

Create examples page

The examples should show different ways to configure the player and interact with its instances.

Allow disabling seeking

It is only possible to disable changing the current time of the video when using ad controls, disabling this functionality should be possible on regular video as well.

Autoplay attribute does not work for VPAID

Adding autoplay: true to the config doesn't allow VPAID to play automatically. This could be handled internally by waiting on the ready event, but, should we do this or leave it for the user to decide when to play?

VPAID loading is inconsistent

VPAID loading is inconsistent and depending on the browser, more likely to fail, this could be due to a race condition between the moment startAd is called and the VPAID is loaded

Make Ad controls optional

Enforcing Ad controls for VAST limits how much the user can customize the player, instead the controls should be opt-in in the configuration.

Should we keep MOAT references?

We don't really do anything special for MOAT, we expect the users to do it themselves, we should consider removing the reference to MOAT in the docs.

Simplify rollup.config.js

Our current process has a lot of duplication, processes like postcss will run up to three times, even though we only generate one css file.

Add "loading" UI before emitting "ready" event

Fixing #60 made the VAST load times more noticeable, it would be a good idea to include a UI when the video is loading, for both VAST and media sources. See Loading Dots.

This style could show by default and be removed on the function that emits the ready event.

Video autoplay not working on some mobile browsers

Video autoplay doesn't work on certain mobile browsers:

  • Safari: Video files won't autoplay on either thumbnail and expanded video, VPAID will only autoplay after interaction with the player.
  • Edge: VPAID thumbnail not playing for some video files
  • Firefox: Found a small video that didn't render, but did play, could be just a media issue

Create a workflow for beta versions

Similar to our production workflow, we should have another either for tags prepended with beta- or pushes to the develop branch to upload a test version to /vp/beta/.

Preload SVG icons in a better way

To preload the SVG icons, we're looking for the possible URL where the file was loaded from, instead, it would be better to load them in some other way, for example, treating them as modules.

Create an action to upload dist to a public CDN

GumGum's CDN is likely to be used only internally, and external users could face issues loading the library from our CDN when there are ad blockers enabled.

Uploading the dist/ script to a publicCDN will prevent network errors for external users.

Ad controls are not visible in mobile

#4 enabled displaying controls at all times on touchscreens, but this was not enabled for ad controls. because of this, only the Skip button and progress bar are shown.

Volume icons flash the first time they are loaded

Loading the player the first time and playing around with the volume range results in the volume icon flashing as the different icons for each state are loaded. Icons could be preloaded by their corresponding component.

VPAID cannot be replayed after completion

The current implementation doesn't allow to replay VPAID after they are finished and cleaned up. I think this could be fixed by calling the VPAIDWrapper.startAd again, or maybe even __runVPAID again.

Optimize rollup bundles

Our current rollup bundle could use:

  • Code minification
  • CSS minification
  • Include ours and our dependencies' licenses

VAST support

delegate VAST support to the VAST Tracker included with vast-client-js

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.