499 lines
18 KiB
Markdown
499 lines
18 KiB
Markdown
|
# Usage
|
||
|
|
||
|
* [Initialize player](#initialize)
|
||
|
* [Automatic start](#automatic)
|
||
|
* [Vanilla JavaScript](#vanilla)
|
||
|
* [jQuery](#jquery)
|
||
|
* [NPM/Meteor](#npm-meteor)
|
||
|
* [RequireJS](#requirejs)
|
||
|
* [React](#react)
|
||
|
* [Use Renderers](#renderers-usage)
|
||
|
* [Use `stretching` modes](#stretching-modes)
|
||
|
* [Responsive grid](#grid)
|
||
|
* [Setting new captions](#captions)
|
||
|
* [Destroy player](#destroy)
|
||
|
|
||
|
|
||
|
<a id="initialize"></a>
|
||
|
## Initialize player
|
||
|
|
||
|
You can use this as a standalone library if you wish, or just stick with the full MediaElementPlayer.
|
||
|
**IMPORTANT:** If you use `flash_video` renderer, it's always recommended to use `media.load()` inside the `success` callback to ensure that RTMP and FLV will play properly.
|
||
|
|
||
|
## Standalone
|
||
|
```html
|
||
|
<script>
|
||
|
// You can use either a string for the player ID (i.e., `player`),
|
||
|
// or `document.querySelector()` for any selector
|
||
|
var player = new MediaElement('player', {
|
||
|
pluginPath: "/path/to/shims/",
|
||
|
success: function(mediaElement, originalNode) {
|
||
|
// do things
|
||
|
|
||
|
}
|
||
|
});
|
||
|
|
||
|
</script>
|
||
|
```
|
||
|
|
||
|
<a id="automatic"></a>
|
||
|
### Automatic start
|
||
|
You can avoid running any startup scripts by adding `class="mejs__player"` to the `<video>` or `<audio>` tag. All the player configuration can be added through `data-mejsoptions` attribute.
|
||
|
```html
|
||
|
<video src="myvideo.mp4" width="320" height="240"
|
||
|
class="mejs__player"
|
||
|
data-mejsoptions='{"pluginPath": "/path/to/shims/", "alwaysShowControls": "true"}'></video>
|
||
|
```
|
||
|
|
||
|
<a id="vanilla"></a>
|
||
|
### Vanilla JavaScript
|
||
|
```html
|
||
|
<script>
|
||
|
// You can use either a string for the player ID (i.e., `player`),
|
||
|
// or `document.querySelector()` for any selector
|
||
|
var player = new MediaElementPlayer('player', {
|
||
|
pluginPath: "/path/to/shims/",
|
||
|
// When using `MediaElementPlayer`, an `instance` argument
|
||
|
// is available in the `success` callback
|
||
|
success: function(mediaElement, originalNode, instance) {
|
||
|
// do things
|
||
|
}
|
||
|
});
|
||
|
</script>
|
||
|
```
|
||
|
|
||
|
<a id="jquery"></a>
|
||
|
### jQuery
|
||
|
```html
|
||
|
<script>
|
||
|
$('#mediaplayer').mediaelementplayer({
|
||
|
pluginPath: "/path/to/shims/",
|
||
|
// When using jQuery's `mediaelementplayer`, an `instance` argument
|
||
|
// is available in the `success` callback
|
||
|
success: function(mediaElement, originalNode, instance) {
|
||
|
// do things
|
||
|
}
|
||
|
});
|
||
|
</script>
|
||
|
```
|
||
|
|
||
|
<a id="npm-meteor"></a>
|
||
|
### NPM/Meteor
|
||
|
```javascript
|
||
|
// To import only MediaElement class
|
||
|
import 'mediaelement/standalone';
|
||
|
|
||
|
// To import all the plugin (you will have access to the MediaElement and MediaElementPlayer classes,
|
||
|
// $.fn.mediaelementplayer plugin, all the native renderers, YouTube and Flash shims)
|
||
|
import 'mediaelement/full';
|
||
|
|
||
|
// To import renderers (i.e., Vimeo)
|
||
|
import 'mediaelement/build/renderers/vimeo';
|
||
|
|
||
|
// To import languages (i.e., Spanish)
|
||
|
import 'mediaelement/build/lang/es';
|
||
|
// Later on the code you need to use mejs.i18n.language('es') to set the language
|
||
|
```
|
||
|
|
||
|
**IMPORTANT**: To ensure you can use the `$.fn.mediaelementplayer` plugin, you will need to import jQuery as well in your bundle like follows:
|
||
|
|
||
|
1. Create a `jquery-global.js` file that contains:
|
||
|
```javascript
|
||
|
'use strict';
|
||
|
|
||
|
import jquery from 'jquery';
|
||
|
window.jQuery = jquery;
|
||
|
window.$ = jquery;
|
||
|
```
|
||
|
2. Import the `jquery-global.js` along with the desired package
|
||
|
```javascript
|
||
|
'use strict';
|
||
|
|
||
|
import '/path/to/jquery-global';
|
||
|
import 'mediaelement'; // or import `mediaelement/standalone` if you only want the shim but not the full player;
|
||
|
```
|
||
|
|
||
|
<a id="requirejs"></a>
|
||
|
### RequireJS
|
||
|
With `Require.js`, you will need the following setup if you are planning to use HLS, M(PEG)-DASH or FLV, given the way the packages are bundled.
|
||
|
|
||
|
To make it work, install via NPM any of the external libraries you will need (i.e., HLS.js).
|
||
|
```
|
||
|
npm install hls.js
|
||
|
```
|
||
|
In your code, include a `shim` for the external library and then assign the exported variable to the global scope.
|
||
|
```javascript
|
||
|
requirejs.config({
|
||
|
// Other configuration
|
||
|
shim: {
|
||
|
// Other shims
|
||
|
'path/to/hls': {deps: ['require'], exports: "Hls"},
|
||
|
// If you only need the shim and not the player, use
|
||
|
//'path/to/mediaelement': {deps: ['require'], exports: "MediaElement"}
|
||
|
'path/to/mediaelement-and-player': {deps: ['require'], exports: "MediaElementPlayer"}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// Later on the code...
|
||
|
require(['path/to/hls'], function (Hls) {
|
||
|
window.Hls = Hls;
|
||
|
require(['path/to/mediaelement-and-player'], function (MediaElementPlayer) {
|
||
|
var player = new MediaElementPlayer('media-id', {
|
||
|
// Player configuration
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
```
|
||
|
**IMPORTANT NOTE:** To keep Flash shims working you **MUST** setup the path where the shims are via `pluginPath`, and do not forget to add a slash at the end of the string. Please refer to the examples above. In Meteor, the right path to be used is `/packages/johndyer_mediaelement/build/`;
|
||
|
|
||
|
|
||
|
<a id="react"></a>
|
||
|
### React
|
||
|
With `React.js`, you will need to install the external libraries the same way as `Require`.
|
||
|
|
||
|
Once installed through NPM, you will be able to create your component using `MediaElement`. As an example:
|
||
|
|
||
|
**MediaElement.js**
|
||
|
```javascript
|
||
|
import React, { Component } from 'react';
|
||
|
import 'hls.js';
|
||
|
import 'mediaelement';
|
||
|
|
||
|
// Import stylesheet and shims
|
||
|
import 'mediaelement/build/mediaelementplayer.min.css';
|
||
|
import 'mediaelement/build/mediaelement-flash-video.swf';
|
||
|
|
||
|
export default class MediaElement extends Component {
|
||
|
|
||
|
state = {}
|
||
|
|
||
|
success(media, node, instance) {
|
||
|
// Your action when media was successfully loaded
|
||
|
}
|
||
|
|
||
|
error(media) {
|
||
|
// Your action when media had an error loading
|
||
|
}
|
||
|
|
||
|
render() {
|
||
|
|
||
|
const
|
||
|
props = this.props,
|
||
|
sources = JSON.parse(props.sources),
|
||
|
tracks = JSON.parse(props.tracks),
|
||
|
sourceTags = [],
|
||
|
tracksTags = []
|
||
|
;
|
||
|
|
||
|
for (let i = 0, total = sources.length; i < total; i++) {
|
||
|
const source = sources[i];
|
||
|
sourceTags.push(`<source src="${source.src}" type="${source.type}">`);
|
||
|
}
|
||
|
|
||
|
for (let i = 0, total = tracks.length; i < total; i++) {
|
||
|
const track = tracks[i];
|
||
|
tracksTags.push(`<track src="${track.src}" kind="${track.kind}" srclang="${track.lang}"${(track.label ? ` label=${track.label}` : '')}>`);
|
||
|
}
|
||
|
|
||
|
const
|
||
|
mediaBody = `${sourceTags.join("\n")}
|
||
|
${tracksTags.join("\n")}`,
|
||
|
mediaHtml = props.mediaType === 'video' ?
|
||
|
`<video id="${props.id}" width="${props.width}" height="${props.height}"${(props.poster ? ` poster=${props.poster}` : '')}
|
||
|
${(props.controls ? ' controls' : '')}${(props.preload ? ` preload="${props.preload}"` : '')}>
|
||
|
${mediaBody}
|
||
|
</video>` :
|
||
|
`<audio id="${props.id}" width="${props.width}" controls>
|
||
|
${mediaBody}
|
||
|
</audio>`
|
||
|
;
|
||
|
|
||
|
return (<div dangerouslySetInnerHTML={{__html: mediaHtml}}></div>);
|
||
|
|
||
|
}
|
||
|
|
||
|
componentDidMount() {
|
||
|
|
||
|
const {MediaElementPlayer} = global;
|
||
|
|
||
|
if (!MediaElementPlayer) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const options = Object.assign({}, JSON.parse(this.props.options), {
|
||
|
// Read the Notes below for more explanation about how to set up the path for shims
|
||
|
pluginPath: './static/media/',
|
||
|
success: (media, node, instance) => this.success(media, node, instance),
|
||
|
error: (media, node) => this.error(media, node)
|
||
|
});
|
||
|
|
||
|
this.setState({player: new MediaElementPlayer(this.props.id, options)});
|
||
|
}
|
||
|
|
||
|
componentWillUnmount() {
|
||
|
if (this.state.player) {
|
||
|
this.state.player.remove();
|
||
|
this.setState({player: null});
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
So you can use your component like as follows.
|
||
|
|
||
|
**App.js**
|
||
|
```javascript
|
||
|
import React, { Component } from 'react';
|
||
|
import './App.css';
|
||
|
import MediaElement from './MediaElement';
|
||
|
|
||
|
export default class App extends Component {
|
||
|
|
||
|
// Other code
|
||
|
|
||
|
render() {
|
||
|
const
|
||
|
sources = [
|
||
|
{src: 'http://www.streambox.fr/playlists/test_001/stream.m3u8', type: 'application/x-mpegURL'},
|
||
|
{src: 'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4', type: 'video/mp4'},
|
||
|
{src: 'rtmp://firehose.cul.columbia.edu:1935/vod/mp4:sample.mp4', type: 'video/rtmp'}
|
||
|
],
|
||
|
config = {},
|
||
|
tracks = {}
|
||
|
;
|
||
|
|
||
|
return (
|
||
|
<MediaElement
|
||
|
id="player1"
|
||
|
mediaType="video"
|
||
|
preload="none"
|
||
|
controls
|
||
|
width="640"
|
||
|
height="360"
|
||
|
poster=""
|
||
|
sources={JSON.stringify(sources)}
|
||
|
options={JSON.stringify(config)}
|
||
|
tracks={JSON.stringify(tracks)}
|
||
|
/>);
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
**IMPORTANT NOTES**
|
||
|
* If you want to support Flash renderers, you **MUST** activate a file loader in WebPack's configuration file in order to send the shims to the correct location (`./static/media/` in the example above). Something like this:
|
||
|
```javascript
|
||
|
module: {
|
||
|
// All previous code
|
||
|
loaders: [
|
||
|
// All previous loaders
|
||
|
{
|
||
|
test: /\.swf$/,
|
||
|
loader: 'file',
|
||
|
query: {
|
||
|
name: 'static/media/[name].[ext]'
|
||
|
}
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
```
|
||
|
* For other renderers that cannot be installed through NPM, such as YouTube, you might need to load their script through `componentDidMount` method:
|
||
|
```javascript
|
||
|
componentDidMount() {
|
||
|
let loaded = false;
|
||
|
if (!loaded) {
|
||
|
const tag = document.createElement('script');
|
||
|
tag.src = '//www.youtube.com/player_api';
|
||
|
const firstScriptTag = document.getElementsByTagName('script')[0];
|
||
|
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
|
||
|
loaded = true;
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
<a id="renderers-usage"></a>
|
||
|
## Use Renderers
|
||
|
|
||
|
After the `MediaElement` package has been loaded, include any renderer(s) you are planning to use that not part of the main bundle (`mediaelement-and-player.js`). For example, to include Vimeo and Twitch support:
|
||
|
|
||
|
```html
|
||
|
<script src="/path/to/mediaelement-and-player.min.js"></script>
|
||
|
<script src="/path/to/renderers/vimeo.min.js"></script>
|
||
|
<script src="/path/to/renderers/twitch.min.js"></script>
|
||
|
```
|
||
|
By default, all the renderers will be called by their IDs and the plugin will try to detect the best one.
|
||
|
|
||
|
However, if you need to use just a subset of renderers in a specific order, you must list their IDs using `renderers` option when configuring your player.
|
||
|
|
||
|
```javascript
|
||
|
|
||
|
// Use globally native M(PEG)-DASH renderer first, then Flash shim
|
||
|
mejs.Renderers.order = ['native_dash', 'flash_dash'];
|
||
|
|
||
|
$('video, audio').mediaelementplayer({
|
||
|
renderers: ['native_dash', 'flash_dash'], // Use only M(PEG)DASH renderers
|
||
|
// More configuration
|
||
|
});
|
||
|
```
|
||
|
|
||
|
`MediaElement` can invoke methods from the current renderer's API. An example using native HLS:
|
||
|
```javascript
|
||
|
$('video').mediaelementplayer({
|
||
|
pluginPath: '../build/',
|
||
|
// All the config related to HLS
|
||
|
hls: {
|
||
|
debug: true
|
||
|
},
|
||
|
// More configuration parameters...
|
||
|
|
||
|
success: function(media, node, instance) {
|
||
|
// Use the conditional to detect if you are using `native_hls` renderer for that given media;
|
||
|
// otherwise, you don't need it
|
||
|
if (Hls !== undefined) {
|
||
|
media.addEventListener(Hls.Events.MEDIA_ATTACHED, function () {
|
||
|
// All the code when this event is reached...
|
||
|
console.log('Media attached!');
|
||
|
});
|
||
|
|
||
|
// Manifest file was parsed, invoke loading method
|
||
|
media.addEventListener(Hls.Events.MANIFEST_PARSED, function () {
|
||
|
// All the code when this event is reached...
|
||
|
console.log('Manifest parsed!');
|
||
|
|
||
|
});
|
||
|
|
||
|
media.addEventListener(Hls.Events.FRAG_PARSING_METADATA, function (event, data) {
|
||
|
// All the code when this event is reached...
|
||
|
console.log(data);
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
```
|
||
|
<a id="renderers-list"></a>
|
||
|
Below are listed the renderers with their IDs and player instance to execute other methods from APIs.
|
||
|
|
||
|
Renderer | ID | Reference | MIME Type(s)
|
||
|
--- | -- | --- | ---
|
||
|
Native video/audio | `html5` | --- | video/mp4, audio/mp4, video/webm, audio/mpeg, audio/mp3, audio/ogg, audio/oga, video/ogg
|
||
|
HLS native | `native_hls` | [`hls.js` API](https://github.com/dailymotion/hls.js/blob/master/doc/API.md) | application/x-mpegURL, vnd.apple.mpegURL
|
||
|
M(PEG)-DASH native | `native_dash` | [`dash.js` Documentation](http://cdn.dashjs.org/latest/jsdoc/index.html) | application/dash+xml
|
||
|
FLV native | `native_flv` | [`flv.js` API](https://github.com/Bilibili/flv.js/blob/master/docs/api.md) | video/flv
|
||
|
SoundCloud | `soundcloud_iframe` | [SoundCloud Widget API](https://developers.soundcloud.com/docs/api/html5-widget) | video/soundcloud, video/x-soundcloud
|
||
|
Facebook | `facebook` | --- | video/facebook, video/x-facebook
|
||
|
Vimeo | `vimeo_iframe` | [Vimeo Player API](https://github.com/vimeo/player.js) | video/vimeo, video/x-vimeo
|
||
|
YouTube | `youtube_iframe` | [YouTube IFrame Player API](https://developers.google.com/youtube/iframe_api_reference) | video/youtube, video/x-youtube
|
||
|
DailyMotion | `dailymotion_iframe` | [Dailymotion Player API](https://developer.dailymotion.com/player#player-api) | video/dailymotion, video/x-dailymotion
|
||
|
Twitch | `twitch_iframe` | [Twitch Emded API](https://github.com/justintv/Twitch-API/blob/master/embed-video.md) | video/twitch, video/x-twitch
|
||
|
Video shim | `flash_video` | --- | video/mp4, video/rtmp, audio/rtmp, rtmp/mp4, audio/mp4
|
||
|
Audio shim | `flash_audio` | --- | audio/mp3
|
||
|
OGG Audio shim | `flash_audio_ogg` | --- | audio/ogg, audio/oga
|
||
|
HLS shim | `flash_hls` | [FlasHLS Events](https://github.com/mangui/flashls/blob/dev/API.md) | application/x-mpegURL, vnd.apple.mpegURL
|
||
|
M(PEG)-DASH shim | `flash_dash` | --- |application/dash+xml
|
||
|
|
||
|
To know how well-supported are each one of the formats, visit http://caniuse.com/
|
||
|
|
||
|
**IMPORTANT NOTES**
|
||
|
1. Only renderers prefixed as __native__, YouTube, and Flash shim, are integrated by default on the player. The rest of the renderers are stored in the `build/renderers` folder.
|
||
|
2. For `flash_hls`, you can use the events listed on https://github.com/mangui/flashls/blob/dev/API.md by prepending __on__ followed by the event name in camelcase notation;
|
||
|
i.e., to call `FRAGMENT_PLAYING`, you need to write `onFragmentPlaying` on JS. The events that return objects will have the info in the `data` attribute of the object; the rest, on the `message` attribute.
|
||
|
|
||
|
|
||
|
**Notes**
|
||
|
* Support for `wmv` and `wma` has been dropped since most of the major players are not supporting it as well.
|
||
|
* `ogg` formats will not play consistently in all browsers so it is strongly recommended a MP3 fallback for audio, or MP4 for video.
|
||
|
* `wav` and `webm` formats will only play on Browsers that support it natively since there is currently no Flash fallback to allow them to play in other browsers.
|
||
|
* `flv` and `mpd` will not work on iOS since it doesn't support MSE; for `mpd` use a `m3u8` fallback.
|
||
|
* Soundcloud can play with `html5` renderer using the following URL format: `https://api.soundcloud.com/tracks/XXX/stream?client_id=XXX`
|
||
|
|
||
|
|
||
|
<a id="streching-modes"></a>
|
||
|
## Use `stretching` modes
|
||
|
|
||
|
`MediaElementPlayer` accepts 4 different stretching modes. The following table describes how to set each one of them.
|
||
|
|
||
|
Mode | Setup
|
||
|
---- | -------
|
||
|
auto | Mode by default, this mode checks if there are any elements in the `video`/`audio` tag to turn the _responsive_ mode; if not, will set it up in _none_ mode.
|
||
|
responsive | Can be turned on by setting `max-width: 100%` style (inline, or in the stylesheet), or `width="100%" height="100%"` attributes in the `video`/`audio` tag. In Javascript, set in the player's configuration `stretching: 'responsive'` (preferred) or `videoWidth: '100%' videoHeight: '100%'`.
|
||
|
fill | This mode will crop the video to adapt it to the dimensions of the parent container by only setting up `stretching: 'fill'`. It is encouraged to set up the parent's `height` to `100%` to make it work as expected.
|
||
|
none | Use `width` and `height` attributes specified in the `video`/`audio` tags and no `max-width: 100%` or `width="100%" height="100%"` attributes; otherwise, use the `stretching: 'none'` configuration element to achieve this.
|
||
|
|
||
|
|
||
|
<a id="grid"></a>
|
||
|
## Responsive grid
|
||
|
|
||
|
Since `MediaElement` can adapt its size to be responsive, some might be tempted to use CSS or Javascript to create a responsive grid of videos.
|
||
|
|
||
|
So far, right now the best plugin to be used with `MediaElement` for this task has been [Flexr](http://flexrgrid.com/).
|
||
|
|
||
|
|
||
|
<a id="captions"></a>
|
||
|
## Setting new captions
|
||
|
|
||
|
With `MediaElementPlayer`, the way to do it is just setting the new values for required attributes (`srclang`, `kind` and `src`) and optionally, `label`,
|
||
|
in the `track` tags for all browsers **EXCEPT Safari Desktop**.
|
||
|
|
||
|
With Safari Desktop in its latest version, due to a keyboard trap issue generated when appending the original `video` tag containing `track` element during the construction
|
||
|
of the player, it is necessary to create `track` tags with the attributes specified above, and override the `trackFiles` array.
|
||
|
```javascript
|
||
|
var player = new MediaElementPlayer('#player');
|
||
|
|
||
|
const track = document.createElement('track');
|
||
|
track.kind = 'subtitles';
|
||
|
track.label = 'English';
|
||
|
track.src = '/path/to/captions.vtt';
|
||
|
track.srclang = 'en';
|
||
|
|
||
|
// In this example, we are assuming there is only on `track` tag;
|
||
|
// if there are more, implement your logic to override the necessary one(s)
|
||
|
if (player.trackFiles !== null) {
|
||
|
player.trackFiles = [track];
|
||
|
}
|
||
|
```
|
||
|
|
||
|
Once you set up the new values for the track attributes, or defined the workflow for Safari, it is required to register the new track(s) as follows:
|
||
|
```javascript
|
||
|
player.findTracks();
|
||
|
// This way we are ensuring ALL tracks are being loaded, starting from the first one
|
||
|
player.loadTrack(0);
|
||
|
// Set the default language using the ID of the language.
|
||
|
// Check the radio buttons generated by the player to see the ID you want to set, or use `none`
|
||
|
player.setTrack('mep_0_track_0_subtitles_en');
|
||
|
```
|
||
|
|
||
|
<a id="destroy"></a>
|
||
|
## Destroy player
|
||
|
|
||
|
In order to destroy the player, you must pause the player and then invoke the `remove()` method.
|
||
|
```javascript
|
||
|
|
||
|
var player = new MediaElementPlayer('#player');
|
||
|
|
||
|
// Using jQuery:
|
||
|
// var playerId = $('#mediaplayer').closest('.mejs__container').attr('id');
|
||
|
// var player = mejs.players[playerId];
|
||
|
|
||
|
|
||
|
if (!player.paused) {
|
||
|
player.pause();
|
||
|
}
|
||
|
|
||
|
player.remove();
|
||
|
|
||
|
// If you wanna destroy COMPLETELY the player (including also the `video` tag) use the above and also the following:
|
||
|
var videos = document.getElementsByTagName('video');
|
||
|
for( var i = 0, total = videos.length; i < total; i++ ){
|
||
|
videos[i].parentNode.removeChild(videos[i]);
|
||
|
}
|
||
|
|
||
|
// Using jQuery:
|
||
|
// $('video').each(function() {
|
||
|
// $(this).remove();
|
||
|
// });
|
||
|
```
|
||
|
|
||
|
Same code can be used for `<audio>` elements.
|
||
|
|
||
|
________
|
||
|
[Back to Main](../README.md)
|