node package manager

mediaelement-plugins

MediaElementJS

MediaElement.js Plugins

CDNJS

This repository contains plugins built for MediaElementJS.

Table of Contents

# Installation

Download the package from https://github.com/johndyer/mediaelement-plugins, and reference any plugins you need from dist folder and add any configuration related to the plugin.

Or you can use a CDN; check http://cdn.jsdelivr.net/npm/mediaelement-plugins/ or https://cdnjs.com/libraries/mediaelement-plugins.

For example, if you want to install Speed plugin do the following:

<script src="/path/to/mediaelement-and-player.min.js"></script>
<!-- Include any languages from `build/lang` folder -->
<script src="/path/to/dist/speed/speed.min,js"></script>
<!-- Translation file for plugin (includes ALL languages available on player)-->
<script src="/path/to/dist/speed/speed-i18n,js"></script>
<script>
    var player = new MediaElementPlayer('playerId', {
     defaultSpeed: 0.75,
     // other configuration elements 
    });
</script> 

Some of them will contain CSS styles so place them after the main player stylesheet:

<link rel="stylesheet" href="/path/to/mediaelementplayer.min.css">
<link rel="stylesheet" href="/path/to/dist/speed/speed.min.css">

# Guidelines to Contribute

## Node.js

Download it at https://nodejs.org/ and follow the steps to install it, or install node.js with npm.

Once installed, at the command prompt, type npm install, which will download all the necessary tools.

## General Conventions

  • Tab size is 8 for indentation.
  • ALWAYS make changes to the files in the /src/ directory, and NEVER in /dist/ directory. This is with the sole purpose of facilitating the merging (and further, the compiling) operation, and help people to see changes more easily.
  • Use JSDoc conventions to document code. This facilitates the contributions of other developers and ensures more quality in the product.
  • BEFORE PUSHING any changes, run npm run eslint to ensure code quality.
  • The file for the feature must be placed inside a folder matching its name, as well as any SVG/CSS elements needed (i.e, loop/loop.js).
  • Update package.json with a command under the script configuration to make sure it will be bundled and compiled properly. For more reference, review the file.
  • Make sure you also write comments about their purpose, and add them into the README file to keep documentation up-to-date.
  • DO NOT REINVENT THE WHEEL: Use the utilities that MediaElement provides for DOM manipulation/AJAX/etc. Check this link for more details.
  • You can also include CSS inside the feature folder, matching the name of the feature JS file and adding CSS styles for "legacy" and BEM naming convention.
  • If using an icon, its size MUST be 20x20px, so it matches all the rest of the icons' dimensions.
.mejs__[feature_name].mejs-[feature_name] {
    // all your styles
}

## Template to create a Feature

'use strict';
 
/**
 * [Name of feature]
 *
 * [Description]
 */
 
// If plugin needs translations, put here English one in this format: 
// mejs.i18n.en["mejs.id1"] = "String 1"; 
// mejs.i18n.en["mejs.id2"] = "String 2"; 
 
// Feature configuration 
Object.assign(mejs.MepDefaults, {
    // Any variable that can be configured by the end user belongs here. 
    // Make sure is unique by checking API and Configuration file. 
    // Add comments about the nature of each of these variables. 
});
 
 
Object.assign(MediaElementPlayer.prototype, {
 
    // Public variables (also documented according to JSDoc specifications) 
 
    /**
     * Feature constructor.
     *
     * Always has to be prefixed with `build` and the name that will be used in MepDefaults.features list
     * @param {MediaElementPlayer} player 
     * @param {HTMLElement} controls 
     * @param {HTMLElement} layers 
     * @param {HTMLElement} media 
     */
    build[feature_name] (player, controls, layers, media) {
        // This allows us to access options and other useful elements already set. 
        // Adding variables to the object is a good idea if you plan to reuse 
        // those variables in further operations. 
        const t = this;
 
        // All code required inside here to keep it private; 
        // otherwise, you can create more methods or add variables 
        // outside of this scope 
    },
 
    // Optionally, each feature can be destroyed setting a `clean` method 
 
    /**
     * Feature destructor.
     *
     * Always has to be prefixed with `clean` and the name that was used in MepDefaults.features list
     * @param {MediaElementPlayer} player 
     * @param {HTMLElement} controls 
     * @param {HTMLElement} layers 
     * @param {HTMLElement} media 
     */
    clean[feature_name] (player, controls, layers, media) {}
 
    // Other optional public methods (all documented according to JSDoc specifications) 
});

## Template for Translations

If translatable strings are part of the plugin, you will need to create a [feature_name]-i18n.js file with this format:

'use strict';
 
if (mejs.i18n.ca !== undefined) {
        mejs.i18n.ca["mejs.id1"] = "";
}
if (mejs.i18n.cs !== undefined) {
        mejs.i18n.cs["mejs.id1"] = "";
}
if (mejs.i18n.de !== undefined) {
        mejs.i18n.de["mejs.id1"] = "";
}
if (mejs.i18n.es !== undefined) {
        mejs.i18n.es["mejs.id1"] = "";
}
if (mejs.i18n.fr !== undefined) {
        mejs.i18n.fr["mejs.id1"] = "";
}
if (mejs.i18n.hr !== undefined) {
        mejs.i18n.hr["mejs.id1"] = "";
}
if (mejs.i18n.hu !== undefined) {
        mejs.i18n.hu["mejs.id1"] = "";
}
if (mejs.i18n.it !== undefined) {
        mejs.i18n.it["mejs.id1"] = "";
}
if (mejs.i18n.ja !== undefined) {
        mejs.i18n.ja["mejs.id1"] = "";
}
if (mejs.i18n.ko !== undefined) {
        mejs.i18n.ko["mejs.id1"] = "";
}
if (mejs.i18n.nl !== undefined) {
        mejs.i18n.nl["mejs.id1"] = "";
}
if (mejs.i18n.pl !== undefined) {
        mejs.i18n.pl["mejs.id1"] = "";
}
if (mejs.i18n.pt !== undefined) {
        mejs.i18n.pt["mejs.id1"] = "";
}
if (mejs.i18n['pt-BR'] !== undefined) {
        mejs.i18n['pt-BR']["mejs.id1"] = "";
}
if (mejs.i18n.ro !== undefined) {
        mejs.i18n.ro["mejs.id1"] = "";
}
if (mejs.i18n.ru !== undefined) {
        mejs.i18n.ru["mejs.id1"] = "";
}
if (mejs.i18n.sk !== undefined) {
        mejs.i18n.sk["mejs.id1"] = "";
}
if (mejs.i18n.sv !== undefined) {
        mejs.i18n.sv["mejs.id1"] = "";
}
if (mejs.i18n.uk !== undefined) {
        mejs.i18n.uk["mejs.id1"] = "";
}
if (mejs.i18n.zh !== undefined) {
        mejs.i18n.zh["mejs.id1"] = "";
}
if (mejs.i18n['zh-CN'] !== undefined) {
        mejs.i18n['zh-CN']["mejs.id1"] = "";
}

NOTE: The more languages are integrated on MediaElementPlayer, the bigger this template will become. So account for more languages.

Also, if you are adding a new language to MediaElementPlayer, you will need to add it in all the existing i18n files in the same way described in the template above.

### A word on ES6 for Features

All the features are written using Ecmascript 2015 specifications.

Seesrc/ directory, and check how the files were written to ensure compatibility.

Note: the for...of loop could have been used, but in order to bundle them and reduce the size of the bundled files, it is strongly recommended to avoid its use.

## Available plugins

Changelog

Changes available at Change Log