aboutsummaryrefslogtreecommitdiffstats
path: root/readme.md
diff options
context:
space:
mode:
Diffstat (limited to 'readme.md')
-rw-r--r--readme.md328
1 files changed, 179 insertions, 149 deletions
diff --git a/readme.md b/readme.md
index 5c0b3636..ea1db868 100644
--- a/readme.md
+++ b/readme.md
@@ -8,26 +8,27 @@ A simple, lightweight, accessible and customizable HTML5, YouTube and Vimeo medi
## Features
-* **Accessible** - full support for VTT captions and screen readers
-* **[Customisable](#html)** - make the player look how you want with the markup you want
-* **Good HTML** - uses the _right_ elements. `<input type="range">` for volume and `<progress>` for progress and well, `<button>`s for buttons. There's no
+- **Accessible** - full support for VTT captions and screen readers
+- **[Customisable](#html)** - make the player look how you want with the markup you want
+- **Good HTML** - uses the _right_ elements. `<input type="range">` for volume and `<progress>` for progress and well, `<button>`s for buttons. There's no
`<span>` or `<a href="#">` button hacks
-* **Responsive** - works with any screen size
-* **HTML Video & Audio** - support for both formats
-* **[Embedded Video](#embeds)** - support for YouTube and Vimeo video playback
-* **[Monetization](#ads)** - make money from your videos
-* **[Streaming](#streaming)** - support for hls.js, Shaka and dash.js streaming playback
-* **[API](#api)** - toggle playback, volume, seeking, and more through a standardized API
-* **[Events](#events)** - no messing around with Vimeo and YouTube APIs, all events are standardized across formats
-* **[Fullscreen](#fullscreen)** - supports native fullscreen with fallback to "full window" modes
-* **[Shortcuts](#shortcuts)** - supports keyboard shortcuts
-* **Picture-in-Picture** - supports Safari's picture-in-picture mode
-* **Playsinline** - supports the `playsinline` attribute
-* **Speed controls** - adjust speed on the fly
-* **Multiple captions** - support for multiple caption tracks
-* **i18n support** - support for internationalization of controls
-* **No dependencies** - written in "vanilla" ES6 JavaScript, no jQuery required
-* **SASS** - to include in your build processes
+- **Responsive** - works with any screen size
+- **HTML Video & Audio** - support for both formats
+- **[Embedded Video](#embeds)** - support for YouTube and Vimeo video playback
+- **[Monetization](#ads)** - make money from your videos
+- **[Streaming](#try-plyr-online)** - support for hls.js, Shaka and dash.js streaming playback
+- **[API](#api)** - toggle playback, volume, seeking, and more through a standardized API
+- **[Events](#events)** - no messing around with Vimeo and YouTube APIs, all events are standardized across formats
+- **[Fullscreen](#fullscreen)** - supports native fullscreen with fallback to "full window" modes
+- **[Shortcuts](#shortcuts)** - supports keyboard shortcuts
+- **Picture-in-Picture** - supports Safari's picture-in-picture mode
+- **Playsinline** - supports the `playsinline` attribute
+- **Speed controls** - adjust speed on the fly
+- **Multiple captions** - support for multiple caption tracks
+- **i18n support** - support for internationalization of controls
+- **[Preview thumbnails](#preview-thumbnails)** - support for displaying preview thumbnails
+- **No dependencies** - written in "vanilla" ES6 JavaScript, no jQuery required
+- **SASS** - to include in your build processes
Oh and yes, it works with Bootstrap.
@@ -42,6 +43,7 @@ Some awesome folks have made plugins for CMSs and Components for JavaScript fram
| Type | Maintainer | Link |
| --------- | -------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| WordPress | Brandon Lavigne ([@drrobotnik](https://github.com/drrobotnik)) | [https://wordpress.org/plugins/plyr/](https://wordpress.org/plugins/plyr/) |
+| Angular | Simon Bobrov ([@smnbbrv](https://github.com/smnbbrv)) | [https://github.com/smnbbrv/ngx-plyr](https://github.com/smnbbrv/ngx-plyr) |
| React | Jose Miguel Bejarano ([@xDae](https://github.com/xDae)) | [https://github.com/xDae/react-plyr](https://github.com/xDae/react-plyr) |
| Vue | Gabe Dunn ([@redxtech](https://github.com/redxtech)) | [https://github.com/redxtech/vue-plyr](https://github.com/redxtech/vue-plyr) |
| Neos | Jon Uhlmann ([@jonnitto](https://github.com/jonnitto)) | [https://packagist.org/packages/jonnitto/plyr](https://packagist.org/packages/jonnitto/plyr) |
@@ -51,6 +53,10 @@ Some awesome folks have made plugins for CMSs and Components for JavaScript fram
Here's a quick run through on getting up and running. There's also a [demo on Codepen](http://codepen.io/sampotts/pen/jARJYp). You can grab all of the source with [NPM](https://www.npmjs.com/package/plyr) using `npm install plyr`.
+### Try Plyr online
+
+You can try Plyr in Codepen using our minimal templates: [HTML5 video](https://codepen.io/pen?template=bKeqpr), [HTML5 audio](https://codepen.io/pen?template=rKLywR), [YouTube](https://codepen.io/pen?template=GGqbbJ), [Vimeo](https://codepen.io/pen?template=bKeXNq). For Streaming we also have example integrations with: [Dash.js](https://codepen.io/pen?template=zaBgBy), [Hls.js](https://codepen.io/pen?template=oyLKQb) and [Shaka Player](https://codepen.io/pen?template=ZRpzZO)
+
### HTML
Plyr extends upon the standard [HTML5 media element](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement) markup so that's all you need for those types.
@@ -59,11 +65,11 @@ Plyr extends upon the standard [HTML5 media element](https://developer.mozilla.o
```html
<video poster="/path/to/poster.jpg" id="player" playsinline controls>
- <source src="/path/to/video.mp4" type="video/mp4">
- <source src="/path/to/video.webm" type="video/webm">
+ <source src="/path/to/video.mp4" type="video/mp4" />
+ <source src="/path/to/video.webm" type="video/webm" />
<!-- Captions are optional -->
- <track kind="captions" label="English captions" src="/path/to/captions.vtt" srclang="en" default>
+ <track kind="captions" label="English captions" src="/path/to/captions.vtt" srclang="en" default />
</video>
```
@@ -71,12 +77,12 @@ Plyr extends upon the standard [HTML5 media element](https://developer.mozilla.o
```html
<audio id="player" controls>
- <source src="/path/to/audio.mp3" type="audio/mp3">
- <source src="/path/to/audio.ogg" type="audio/ogg">
+ <source src="/path/to/audio.mp3" type="audio/mp3" />
+ <source src="/path/to/audio.ogg" type="audio/ogg" />
</audio>
```
-For YouTube and Vimeo players, Plyr uses progressive enhancement to enhance the default `<iframe>` embeds. Below are some examples. The `plyr__video-embed` classname will make the embed responsive. You can add the `autoplay`, `loop` and `playsinline` (YouTube only) query parameters to the URL and they will be set as config options automatically. For YouTube, the `origin` should be updated to reflect the domain you're hosting the embed on, or you can opt to omit it.
+For YouTube and Vimeo players, Plyr uses progressive enhancement to enhance the default `<iframe>` embeds. Below are some examples. The `plyr__video-embed` classname will make the embed responsive. You can add the `autoplay`, `loop`, `hl` (YouTube only) and `playsinline` (YouTube only) query parameters to the URL and they will be set as config options automatically. For YouTube, the `origin` should be updated to reflect the domain you're hosting the embed on, or you can opt to omit it.
#### YouTube embed
@@ -84,7 +90,12 @@ We recommend [progressive enhancement](https://www.smashingmagazine.com/2009/04/
```html
<div class="plyr__video-embed" id="player">
- <iframe src="https://www.youtube.com/embed/bTqVqk7FSmY?origin=https://plyr.io&amp;iv_load_policy=3&amp;modestbranding=1&amp;playsinline=1&amp;showinfo=0&amp;rel=0&amp;enablejsapi=1" allowfullscreen allowtransparency allow="autoplay"></iframe>
+ <iframe
+ src="https://www.youtube.com/embed/bTqVqk7FSmY?origin=https://plyr.io&amp;iv_load_policy=3&amp;modestbranding=1&amp;playsinline=1&amp;showinfo=0&amp;rel=0&amp;enablejsapi=1"
+ allowfullscreen
+ allowtransparency
+ allow="autoplay"
+ ></iframe>
</div>
```
@@ -104,7 +115,12 @@ Much the same as YouTube above.
```html
<div class="plyr__video-embed" id="player">
- <iframe src="https://player.vimeo.com/video/76979871?loop=false&amp;byline=false&amp;portrait=false&amp;title=false&amp;speed=true&amp;transparent=0&amp;gesture=media" allowfullscreen allowtransparency allow="autoplay"></iframe>
+ <iframe
+ src="https://player.vimeo.com/video/76979871?loop=false&amp;byline=false&amp;portrait=false&amp;title=false&amp;speed=true&amp;transparent=0&amp;gesture=media"
+ allowfullscreen
+ allowtransparency
+ allow="autoplay"
+ ></iframe>
</div>
```
@@ -120,45 +136,51 @@ Include the `plyr.js` script before the closing `</body>` tag and then in your J
```html
<script src="path/to/plyr.js"></script>
-<script>const player = new Plyr('#player');</script>
+<script>
+ const player = new Plyr('#player');
+</script>
```
See [initialising](#initialising) for more information on advanced setups.
-If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the JavaScript, you can use the following:
+You can use our CDN (provided by [Fastly](https://www.fastly.com/)) for the JavaScript. There's 2 versions; one with and one without [polyfills](#polyfills). My recommendation would be to manage polyfills seperately as part of your application but to make life easier you can use the polyfilled build.
```html
-<script src="https://cdn.plyr.io/3.3.6/plyr.js"></script>
+<script src="https://cdn.plyr.io/3.4.8/plyr.js"></script>
```
-_Note_: Be sure to read the [polyfills](#polyfills) section below about browser compatibility
+...or...
+
+```html
+<script src="https://cdn.plyr.io/3.4.8/plyr.polyfilled.js"></script>
+```
### CSS
Include the `plyr.css` stylsheet into your `<head>`
```html
-<link rel="stylesheet" href="path/to/plyr.css">
+<link rel="stylesheet" href="path/to/plyr.css" />
```
If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the default CSS, you can use the following:
```html
-<link rel="stylesheet" href="https://cdn.plyr.io/3.3.6/plyr.css">
+<link rel="stylesheet" href="https://cdn.plyr.io/3.4.8/plyr.css" />
```
### SVG Sprite
The SVG sprite is loaded automatically from our CDN (provided by [Fastly](https://www.fastly.com/)). To change this, see the [options](#options) below. For
-reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.3.6/plyr.svg`.
+reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.4.8/plyr.svg`.
## Ads
-Plyr has partnered up with [vi.ai](http://vi.ai/publisher-video-monetization/?aid=plyrio) to offer monetization options for your videos. Getting setup is easy:
+Plyr has partnered up with [vi.ai](https://vi.ai/publisher-video-monetization/?aid=plyrio) to offer monetization options for your videos. Getting setup is easy:
-* [Sign up for a vi.ai account](http://vi.ai/publisher-video-monetization/?aid=plyrio)
-* Grab your publisher ID from the code snippet
-* Enable ads in the [config options](#options) and enter your publisher ID
+- [Sign up for a vi.ai account](https://vi.ai/publisher-video-monetization/?aid=plyrio)
+- Grab your publisher ID from the code snippet
+- Enable ads in the [config options](#options) and enter your publisher ID
Any questions regarding the ads can be sent straight to vi.ai and any issues with rendering raised through GitHub issues.
@@ -167,7 +189,7 @@ Any questions regarding the ads can be sent straight to vi.ai and any issues wit
### SASS
You can use `bundle.scss` file included in `/src` as part of your build and change variables to suit your design. The SASS require you to
-use the [autoprefixer](https://www.npmjs.com/package/gulp-autoprefixer) plugin (you be should already!) as all declarations use the W3C definitions.
+use the [autoprefixer](https://www.npmjs.com/package/gulp-autoprefixer) plugin (you should be already!) as all declarations use the W3C definitions.
The HTML markup uses the BEM methodology with `plyr` as the block, e.g. `.plyr__controls`. You can change the class hooks in the options to match any custom CSS
you write. Check out the JavaScript source for more on this.
@@ -205,10 +227,10 @@ WebVTT captions are supported. To add a caption track, check the HTML example ab
You can specify a range of arguments for the constructor to use:
-* A CSS string selector that's compatible with [`querySelector`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector)
-* A [`HTMLElement`](https://developer.mozilla.org/en/docs/Web/API/HTMLElement)
-* A [`NodeList]`(https://developer.mozilla.org/en-US/docs/Web/API/NodeList)
-* A [jQuery](https://jquery.com) object
+- A CSS string selector that's compatible with [`querySelector`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector)
+- A [`HTMLElement`](https://developer.mozilla.org/en/docs/Web/API/HTMLElement)
+- A [`NodeList`](https://developer.mozilla.org/en-US/docs/Web/API/NodeList)
+- A [jQuery](https://jquery.com) object
_Note_: If a `NodeList`, `Array`, or jQuery object are passed, the first element will be used for setup. To setup multiple players, see [setting up multiple players](#setting-up-multiple-players) below.
@@ -267,46 +289,55 @@ In all cases, the constructor will return a Plyr object that can be used with th
Options can be passed as an object to the constructor as above or as JSON in `data-plyr-config` attribute on each of your target elements:
```html
-<video src="/path/to/video.mp4" id="player" controls data-plyr-config='{ "title": "This is an example video", "volume": 1, "debug": true }'></video>
+<video
+ src="/path/to/video.mp4"
+ id="player"
+ controls
+ data-plyr-config="{ &quot;title&quot;: &quot;This is an example video&quot;, &quot;volume&quot;: 1, &quot;debug&quot;: true }"
+></video>
```
Note the single quotes encapsulating the JSON and double quotes on the object keys. Only string values need double quotes.
-| Option | Type | Default | Description |
-| -------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `enabled` | Boolean | `true` | Completely disable Plyr. This would allow you to do a User Agent check or similar to programmatically enable or disable Plyr for a certain UA. Example below. |
-| `debug` | Boolean | `false` | Display debugging information in the console |
-| `controls` | Array, Function or Element | `['play-large', 'play', 'progress', 'current-time', 'mute', 'volume', 'captions', 'settings', 'pip', 'airplay', 'fullscreen']` | If a function is passed, it is assumed your method will return either an element or HTML string for the controls. Three arguments will be passed to your function; `id` (the unique id for the player), `seektime` (the seektime step in seconds), and `title` (the media title). See [controls.md](controls.md) for more info on how the html needs to be structured. |
-| `settings` | Array | `['captions', 'quality', 'speed', 'loop']` | If you're using the default controls are used then you can specify which settings to show in the menu |
-| `i18n` | Object | See [defaults.js](/src/js/defaults.js) | Used for internationalization (i18n) of the text within the UI. |
-| `loadSprite` | Boolean | `true` | Load the SVG sprite specified as the `iconUrl` option (if a URL). If `false`, it is assumed you are handling sprite loading yourself. |
-| `iconUrl` | String | `null` | Specify a URL or path to the SVG sprite. See the [SVG section](#svg) for more info. |
-| `iconPrefix` | String | `plyr` | Specify the id prefix for the icons used in the default controls (e.g. "plyr-play" would be "plyr"). This is to prevent clashes if you're using your own SVG sprite but with the default controls. Most people can ignore this option. |
-| `blankUrl` | String | `https://cdn.plyr.io/static/blank.mp4` | Specify a URL or path to a blank video file used to properly cancel network requests. |
-| `autoplay` | Boolean | `false` | Autoplay the media on load. This is generally advised against on UX grounds. It is also disabled by default in some browsers. If the `autoplay` attribute is present on a `<video>` or `<audio>` element, this will be automatically set to true. |
-| `autopause`&sup1; | Boolean | `true` | Only allow one player playing at once. |
-| `seekTime` | Number | `10` | The time, in seconds, to seek when a user hits fast forward or rewind. |
-| `volume` | Number | `1` | A number, between 0 and 1, representing the initial volume of the player. |
-| `muted` | Boolean | `false` | Whether to start playback muted. If the `muted` attribute is present on a `<video>` or `<audio>` element, this will be automatically set to true. |
-| `clickToPlay` | Boolean | `true` | Click (or tap) of the video container will toggle play/pause. |
-| `disableContextMenu` | Boolean | `true` | Disable right click menu on video to <em>help</em> as very primitive obfuscation to prevent downloads of content. |
-| `hideControls` | Boolean | `true` | Hide video controls automatically after 2s of no mouse or focus movement, on control element blur (tab out), on playback start or entering fullscreen. As soon as the mouse is moved, a control element is focused or playback is paused, the controls reappear instantly. |
-| `resetOnEnd` | Boolean | false | Reset the playback to the start once playback is complete. |
-| `keyboard` | Object | `{ focused: true, global: false }` | Enable [keyboard shortcuts](#shortcuts) for focused players only or globally |
-| `tooltips` | Object | `{ controls: false, seek: true }` | `controls`: Display control labels as tooltips on `:hover` & `:focus` (by default, the labels are screen reader only). `seek`: Display a seek tooltip to indicate on click where the media would seek to. |
-| `duration` | Number | `null` | Specify a custom duration for media. |
-| `displayDuration` | Boolean | `true` | Displays the duration of the media on the "metadataloaded" event (on startup) in the current time display. This will only work if the `preload` attribute is not set to `none` (or is not set at all) and you choose not to display the duration (see `controls` option). |
-| `invertTime` | Boolean | `true` | Display the current time as a countdown rather than an incremental counter. |
-| `toggleInvert` | Boolean | `true` | Allow users to click to toggle the above. |
-| `listeners` | Object | `null` | Allows binding of event listeners to the controls before the default handlers. See the `defaults.js` for available listeners. If your handler prevents default on the event (`event.preventDefault()`), the default handler will not fire. |
-| `captions` | Object | `{ active: false, language: window.navigator.language.split('-')[0] }` | `active`: Toggles if captions should be active by default. `language`: Sets the default language to load (if available). |
-| `fullscreen` | Object | `{ enabled: true, fallback: true, iosNative: false }` | `enabled`: Toggles whether fullscreen should be enabled. `fallback`: Allow fallback to a full-window solution. `iosNative`: whether to use native iOS fullscreen when entering fullscreen (no custom controls) |
-| `ratio` | String | `16:9` | The aspect ratio you want to use for embedded players. |
-| `storage` | Object | `{ enabled: true, key: 'plyr' }` | `enabled`: Allow use of local storage to store user settings. `key`: The key name to use. |
-| `speed` | Object | `{ selected: 1, options: [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2] }` | `selected`: The default speed for playback. `options`: Options to display in the menu. Most browsers will refuse to play slower than 0.5. |
-| `quality` | Object | `{ default: 'default', options: ['hd2160', 'hd1440', 'hd1080', 'hd720', 'large', 'medium', 'small', 'tiny', 'default'] }` | Currently only supported by YouTube. `default` is the default quality level, determined by YouTube. `options` are the options to display. |
-| `loop` | Object | `{ active: false }` | `active`: Whether to loop the current video. If the `loop` attribute is present on a `<video>` or `<audio>` element, this will be automatically set to true This is an object to support future functionality. |
-| `ads` | Object | `{ enabled: false, publisherId: '' }` | `enabled`: Whether to enable vi.ai ads. `publisherId`: Your unique vi.ai publisher ID. |
+| Option | Type | Default | Description |
+| -------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `enabled` | Boolean | `true` | Completely disable Plyr. This would allow you to do a User Agent check or similar to programmatically enable or disable Plyr for a certain UA. Example below. |
+| `debug` | Boolean | `false` | Display debugging information in the console |
+| `controls` | Array, Function or Element | `['play-large', 'play', 'progress', 'current-time', 'mute', 'volume', 'captions', 'settings', 'pip', 'airplay', 'fullscreen']` | If a function is passed, it is assumed your method will return either an element or HTML string for the controls. Three arguments will be passed to your function; `id` (the unique id for the player), `seektime` (the seektime step in seconds), and `title` (the media title). See [controls.md](controls.md) for more info on how the html needs to be structured. |
+| `settings` | Array | `['captions', 'quality', 'speed', 'loop']` | If you're using the default controls are used then you can specify which settings to show in the menu |
+| `i18n` | Object | See [defaults.js](/src/js/config/defaults.js) | Used for internationalization (i18n) of the text within the UI. |
+| `loadSprite` | Boolean | `true` | Load the SVG sprite specified as the `iconUrl` option (if a URL). If `false`, it is assumed you are handling sprite loading yourself. |
+| `iconUrl` | String | `null` | Specify a URL or path to the SVG sprite. See the [SVG section](#svg) for more info. |
+| `iconPrefix` | String | `plyr` | Specify the id prefix for the icons used in the default controls (e.g. "plyr-play" would be "plyr"). This is to prevent clashes if you're using your own SVG sprite but with the default controls. Most people can ignore this option. |
+| `blankVideo` | String | `https://cdn.plyr.io/static/blank.mp4` | Specify a URL or path to a blank video file used to properly cancel network requests. |
+| `autoplay` | Boolean | `false` | Autoplay the media on load. This is generally advised against on UX grounds. It is also disabled by default in some browsers. If the `autoplay` attribute is present on a `<video>` or `<audio>` element, this will be automatically set to true. |
+| `autopause`&sup1; | Boolean | `true` | Only allow one player playing at once. |
+| `seekTime` | Number | `10` | The time, in seconds, to seek when a user hits fast forward or rewind. |
+| `volume` | Number | `1` | A number, between 0 and 1, representing the initial volume of the player. |
+| `muted` | Boolean | `false` | Whether to start playback muted. If the `muted` attribute is present on a `<video>` or `<audio>` element, this will be automatically set to true. |
+| `clickToPlay` | Boolean | `true` | Click (or tap) of the video container will toggle play/pause. |
+| `disableContextMenu` | Boolean | `true` | Disable right click menu on video to <em>help</em> as very primitive obfuscation to prevent downloads of content. |
+| `hideControls` | Boolean | `true` | Hide video controls automatically after 2s of no mouse or focus movement, on control element blur (tab out), on playback start or entering fullscreen. As soon as the mouse is moved, a control element is focused or playback is paused, the controls reappear instantly. |
+| `resetOnEnd` | Boolean | false | Reset the playback to the start once playback is complete. |
+| `keyboard` | Object | `{ focused: true, global: false }` | Enable [keyboard shortcuts](#shortcuts) for focused players only or globally |
+| `tooltips` | Object | `{ controls: false, seek: true }` | `controls`: Display control labels as tooltips on `:hover` & `:focus` (by default, the labels are screen reader only). `seek`: Display a seek tooltip to indicate on click where the media would seek to. |
+| `duration` | Number | `null` | Specify a custom duration for media. |
+| `displayDuration` | Boolean | `true` | Displays the duration of the media on the "metadataloaded" event (on startup) in the current time display. This will only work if the `preload` attribute is not set to `none` (or is not set at all) and you choose not to display the duration (see `controls` option). |
+| `invertTime` | Boolean | `true` | Display the current time as a countdown rather than an incremental counter. |
+| `toggleInvert` | Boolean | `true` | Allow users to click to toggle the above. |
+| `listeners` | Object | `null` | Allows binding of event listeners to the controls before the default handlers. See the `defaults.js` for available listeners. If your handler prevents default on the event (`event.preventDefault()`), the default handler will not fire. |
+| `captions` | Object | `{ active: false, language: 'auto', update: false }` | `active`: Toggles if captions should be active by default. `language`: Sets the default language to load (if available). 'auto' uses the browser language. `update`: Listen to changes to tracks and update menu. This is needed for some streaming libraries, but can result in unselectable language options). |
+| `fullscreen` | Object | `{ enabled: true, fallback: true, iosNative: false }` | `enabled`: Toggles whether fullscreen should be enabled. `fallback`: Allow fallback to a full-window solution (`true`/`false`/`'force'`). `iosNative`: whether to use native iOS fullscreen when entering fullscreen (no custom controls) |
+| `ratio` | String | `16:9` | The aspect ratio you want to use for embedded players. |
+| `storage` | Object | `{ enabled: true, key: 'plyr' }` | `enabled`: Allow use of local storage to store user settings. `key`: The key name to use. |
+| `speed` | Object | `{ selected: 1, options: [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2] }` | `selected`: The default speed for playback. `options`: Options to display in the menu. Most browsers will refuse to play slower than 0.5. |
+| `quality` | Object | `{ default: 'default', options: ['hd2160', 'hd1440', 'hd1080', 'hd720', 'large', 'medium', 'small', 'tiny', 'default'] }` | Currently only supported by YouTube. `default` is the default quality level, determined by YouTube. `options` are the options to display. |
+| `loop` | Object | `{ active: false }` | `active`: Whether to loop the current video. If the `loop` attribute is present on a `<video>` or `<audio>` element, this will be automatically set to true This is an object to support future functionality. |
+| `ads` | Object | `{ enabled: false, publisherId: '' }` | `enabled`: Whether to enable advertisements. `publisherId`: Your unique [vi.ai](https://vi.ai/publisher-video-monetization/?aid=plyrio) publisher ID. |
+| `urls` | Object | See source. | If you wish to override any API URLs then you can do so here. You can also set a custom download URL for the download button. |
+| `vimeo` | Object | `{ byline: false, portrait: false, title: false, speed: true, transparent: false }` | See [Vimeo embed options](https://github.com/vimeo/player.js/#embed-options). Some are set automatically based on other config options, namely: `loop`, `autoplay`, `muted`, `gesture`, `playsinline` |
+| `youtube` | Object | `{ noCookie: false, rel: 0, showinfo: 0, iv_load_policy: 3, modestbranding: 1 }` | See [YouTube embed options](https://developers.google.com/youtube/player_parameters#Parameters). The only custom option is `noCookie` to use an alternative to YouTube that doesn't use cookies (useful for GDPR, etc). Some are set automatically based on other config options, namely: `autoplay`, `hl`, `controls`, `disablekb`, `playsinline`, `cc_load_policy`, `cc_lang_pref`, `widget_referrer` |
+| `previewThumbnails` | Object | `{ enabled: false, src: '' }` | `enabled`: Whether to enable the preview thumbnails (they must be generated by you). `src` must be either a string or an array of strings representing URLs for the VTT files containing the image URL(s). Learn more about [preview thumbnails](#preview-thumbnails) below. |
1. Vimeo only
@@ -357,8 +388,9 @@ player.fullscreen.enter(); // Enter fullscreen
| `fullscreen.exit()` | - | Exit fullscreen. |
| `fullscreen.toggle()` | - | Toggle fullscreen. |
| `airplay()` | - | Trigger the airplay dialog on supported devices. |
-| `toggleControls(toggle)` | Boolean | Toggle the controls based on the specified boolean. |
+| `toggleControls(toggle)` | Boolean | Toggle the controls (video only). Takes optional truthy value to force it on/off. |
| `on(event, function)` | String, Function | Add an event listener for the specified event. |
+| `once(event, function)` | String, Function | Add an event listener for the specified event once. |
| `off(event, function)` | String, Function | Remove an event listener for the specified event. |
| `supports(type)` | String | Check support for a mime type. |
| `destroy()` | - | Destroy the instance and garbage collect any elements. |
@@ -382,31 +414,32 @@ player.currentTime; // 10
player.fullscreen.active; // false;
```
-| Property | Getter | Setter | Description |
-| -------------------- | ------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| `isHTML5` | ✓ | - | Returns a boolean indicating if the current player is HTML5. |
-| `isEmbed` | ✓ | - | Returns a boolean indicating if the current player is an embedded player. |
-| `playing` | ✓ | - | Returns a boolean indicating if the current player is playing. |
-| `paused` | ✓ | - | Returns a boolean indicating if the current player is paused. |
-| `stopped` | ✓ | - | Returns a boolean indicating if the current player is stopped. |
-| `ended` | ✓ | - | Returns a boolean indicating if the current player has finished playback. |
-| `buffered` | ✓ | - | Returns a float between 0 and 1 indicating how much of the media is buffered |
-| `currentTime` | ✓ | ✓ | Gets or sets the currentTime for the player. The setter accepts a float in seconds. |
-| `seeking` | ✓ | - | Returns a boolean indicating if the current player is seeking. |
-| `duration` | ✓ | - | Returns the duration for the current media. |
-| `volume` | ✓ | ✓ | Gets or sets the volume for the player. The setter accepts a float between 0 and 1. |
-| `muted` | ✓ | ✓ | Gets or sets the muted state of the player. The setter accepts a boolean. |
-| `hasAudio` | ✓ | - | Returns a boolean indicating if the current media has an audio track. |
-| `speed` | ✓ | ✓ | Gets or sets the speed for the player. The setter accepts a value in the options specified in your config. Generally the minimum should be 0.5. |
-| `quality`&sup1; | ✓ | ✓ | Gets or sets the quality for the player. The setter accepts a value from the options specified in your config. |
-| `loop` | ✓ | ✓ | Gets or sets the current loop state of the player. The setter accepts a boolean. |
-| `source` | ✓ | ✓ | Gets or sets the current source for the player. The setter accepts an object. See [source setter](#source-setter) below for examples. |
-| `poster` | ✓ | ✓ | Gets or sets the current poster image for the player. The setter accepts a string; the URL for the updated poster image. |
-| `autoplay` | ✓ | ✓ | Gets or sets the autoplay state of the player. The setter accepts a boolean. |
-| `language` | ✓ | ✓ | Gets or sets the preferred captions language for the player. The setter accepts an ISO two-letter language code. Support for the languages is dependent on the captions you include. |
-| `fullscreen.active` | ✓ | - | Returns a boolean indicating if the current player is in fullscreen mode. |
-| `fullscreen.enabled` | ✓ | - | Returns a boolean indicating if the current player has fullscreen enabled. |
-| `pip` | ✓ | ✓ | Gets or sets the picture-in-picture state of the player. The setter accepts a boolean. This currently only supported on Safari 10+ on MacOS Sierra+ and iOS 10+. |
+| Property | Getter | Setter | Description |
+| -------------------- | ------ | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `isHTML5` | ✓ | - | Returns a boolean indicating if the current player is HTML5. |
+| `isEmbed` | ✓ | - | Returns a boolean indicating if the current player is an embedded player. |
+| `playing` | ✓ | - | Returns a boolean indicating if the current player is playing. |
+| `paused` | ✓ | - | Returns a boolean indicating if the current player is paused. |
+| `stopped` | ✓ | - | Returns a boolean indicating if the current player is stopped. |
+| `ended` | ✓ | - | Returns a boolean indicating if the current player has finished playback. |
+| `buffered` | ✓ | - | Returns a float between 0 and 1 indicating how much of the media is buffered |
+| `currentTime` | ✓ | ✓ | Gets or sets the currentTime for the player. The setter accepts a float in seconds. |
+| `seeking` | ✓ | - | Returns a boolean indicating if the current player is seeking. |
+| `duration` | ✓ | - | Returns the duration for the current media. |
+| `volume` | ✓ | ✓ | Gets or sets the volume for the player. The setter accepts a float between 0 and 1. |
+| `muted` | ✓ | ✓ | Gets or sets the muted state of the player. The setter accepts a boolean. |
+| `hasAudio` | ✓ | - | Returns a boolean indicating if the current media has an audio track. |
+| `speed` | ✓ | ✓ | Gets or sets the speed for the player. The setter accepts a value in the options specified in your config. Generally the minimum should be 0.5. |
+| `quality`&sup1; | ✓ | ✓ | Gets or sets the quality for the player. The setter accepts a value from the options specified in your config. |
+| `loop` | ✓ | ✓ | Gets or sets the current loop state of the player. The setter accepts a boolean. |
+| `source` | ✓ | ✓ | Gets or sets the current source for the player. The setter accepts an object. See [source setter](#the-source-setter) below for examples. |
+| `poster` | ✓ | ✓ | Gets or sets the current poster image for the player. The setter accepts a string; the URL for the updated poster image. |
+| `autoplay` | ✓ | ✓ | Gets or sets the autoplay state of the player. The setter accepts a boolean. |
+| `currentTrack` | ✓ | ✓ | Gets or sets the caption track by index. `-1` means the track is missing or captions is not active |
+| `language` | ✓ | ✓ | Gets or sets the preferred captions language for the player. The setter accepts an ISO two-letter language code. Support for the languages is dependent on the captions you include. If your captions don't have any language data, or if you have multiple tracks with the same language, you may want to use `currentTrack` instead. |
+| `fullscreen.active` | ✓ | - | Returns a boolean indicating if the current player is in fullscreen mode. |
+| `fullscreen.enabled` | ✓ | - | Returns a boolean indicating if the current player has fullscreen enabled. |
+| `pip`&sup2; | ✓ | ✓ | Gets or sets the picture-in-picture state of the player. The setter accepts a boolean. This currently only supported on Safari 10+ (on MacOS Sierra+ and iOS 10+) and Chrome 70+. |
1. YouTube only. HTML5 will follow.
2. HTML5 only
@@ -425,10 +458,12 @@ player.source = {
{
src: '/path/to/movie.mp4',
type: 'video/mp4',
+ size: 720,
},
{
src: '/path/to/movie.webm',
type: 'video/webm',
+ size: 1080,
},
],
poster: '/path/to/poster.jpg',
@@ -553,6 +588,7 @@ player.on('ready', event => {
| `loadstart` | Sent when loading of the media begins. |
| `loadeddata` | The first frame of the media has finished loading. |
| `loadedmetadata` | The media's metadata has finished loading; all attributes now contain as much useful information as they're going to. |
+| `qualitychange` | The quality of playback has changed. |
| `canplay` | Sent when enough data is available that the media can be played, at least for a couple of frames. This corresponds to the `HAVE_ENOUGH_DATA` `readyState`. |
| `canplaythrough` | Sent when the ready state changes to `CAN_PLAY_THROUGH`, indicating that the entire media can be played without interruption, assuming the download rate remains at least at the current level. _Note:_ Manually setting the `currentTime` will eventually fire a `canplaythrough` event in firefox. Other browsers might not fire this event. |
| `stalled` | Sent when the user agent is trying to fetch media data, but data is unexpectedly not forthcoming. |
@@ -563,11 +599,9 @@ player.on('ready', event => {
#### YouTube only
-| Event Type | Description |
-| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `statechange` | The state of the player has changed. The code can be accessed via `event.detail.code`. Possible values are `-1`: Unstarted, `0`: Ended, `1`: Playing, `2`: Paused, `3`: Buffering, `5`: Video cued. See the [YouTube Docs](https://developers.google.com/youtube/iframe_api_reference#onStateChange) for more information. |
-| `qualitychange` | The quality of playback has changed. |
-| `qualityrequested` | A change to playback quality has been requested. _Note:_ A change to quality can only be _requested_ via the API. There is no guarantee the quality will change to the level requested. You should listen to the `qualitychange` event for true changes. |
+| Event Type | Description |
+| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `statechange` | The state of the player has changed. The code can be accessed via `event.detail.code`. Possible values are `-1`: Unstarted, `0`: Ended, `1`: Playing, `2`: Paused, `3`: Buffering, `5`: Video cued. See the [YouTube Docs](https://developers.google.com/youtube/iframe_api_reference#onStateChange) for more information. |
_Note:_ These events also bubble up the DOM. The event target will be the container element.
@@ -579,8 +613,8 @@ YouTube and Vimeo are currently supported and function much like a HTML5 video.
to access the API's directly. You can do so via the `embed` property of your player object - e.g. `player.embed`. You can then use the relevant methods from the
third party APIs. More info on the respective API's here:
-* [YouTube iframe API Reference](https://developers.google.com/youtube/iframe_api_reference)
-* [Vimeo player.js Reference](https://github.com/vimeo/player.js)
+- [YouTube iframe API Reference](https://developers.google.com/youtube/iframe_api_reference)
+- [Vimeo player.js Reference](https://github.com/vimeo/player.js)
_Note_: Not all API methods may work 100%. Your mileage may vary. It's better to use the Plyr API where possible.
@@ -603,17 +637,6 @@ document then the shortcuts will work when any element has focus, apart from an
| `C` | Toggle captions |
| `L` | Toggle loop |
-## Streaming
-
-Because Plyr is an extension of the standard HTML5 video and audio elements, third party streaming plugins can be used with Plyr. Massive thanks to Matias
-Russitto ([@russitto](https://github.com/russitto)) for working on this. Here's a few examples:
-
-* Using [hls.js](https://github.com/dailymotion/hls.js) - [Demo](http://codepen.io/sampotts/pen/JKEMqB)
-* Using [Shaka](https://github.com/google/shaka-player) - [Demo](http://codepen.io/sampotts/pen/zBNpVR)
-* Using [dash.js](https://github.com/Dash-Industry-Forum/dash.js) - [Demo](http://codepen.io/sampotts/pen/BzpJXN)
-
-_Note_: These need updating to use the new v3 syntax but would still work.
-
## Fullscreen
Fullscreen in Plyr is supported by all browsers that [currently support it](http://caniuse.com/#feat=fullscreen).
@@ -637,6 +660,12 @@ Plyr supports the last 2 versions of most _modern_ browsers.
2. Native player used (no support for `<progress>` or `<input type="range">`) but the API is supported. No native fullscreen support, fallback can be used (see [options](#options)).
3. Polyfills required. See below.
+## Preview thumbnails
+
+It's possible to display preview thumbnails as per the demo when you hover over the scrubber or while you are scrubbing in the main video area. This can be used for all video types but is easiest with HTML5 of course. You will need to generate the sprite or images yourself. This is possible using something like AWS transcoder to generate the frames and then combine them into a sprite image. Sprites are recommended for performance reasons - they will be much faster to download and easier to compress into a small file size making them load faster.
+
+You can see the example VTT files [here](https://cdn.plyr.io/static/demo/thumbs/100p.vtt) and [here](https://cdn.plyr.io/static/demo/thumbs/240p.vtt) for how the sprites are done. The coordinates are set as the `xywh` hash on the URL in the order X Offset, Y Offset, Width, Height (e.g. `240p-00001.jpg#xywh=1708,480,427,240` is offset `1708px` from the left, `480px` from the top and is `427x240px`. If you want to include images per frame, this is also possible but will be slower, resulting in a degraded experience.
+
### Polyfills
Plyr uses ES6 which isn't supported in all browsers quite yet. This means some features will need to be polyfilled to be available otherwise you'll run into issues. We've elected to not burden the ~90% of users that do support these features with extra JS and instead leave polyfilling to you to work out based on your needs. The easiest method I've found is to use [polyfill.io](https://polyfill.io) which provides polyfills based on user agent. This is the method the demo uses.
@@ -651,9 +680,9 @@ const supported = Plyr.supported('video', 'html5', true);
The arguments are:
-* Media type (`audio` or `video`)
-* Provider (`html5`, `youtube` or `vimeo`)
-* Whether the player has the `playsinline` attribute (only applicable to iOS 10+)
+- Media type (`audio` or `video`)
+- Provider (`html5`, `youtube` or `vimeo`)
+- Whether the player has the `playsinline` attribute (only applicable to iOS 10+)
### Disable support programatically
@@ -686,33 +715,34 @@ Plyr is developed by [@sam_potts](https://twitter.com/sam_potts) / [sampotts.me]
Plyr costs money to run, not only my time. I donate my time for free as I enjoy building Plyr but unfortunately have to pay for domains, hosting, and more. Any help with costs is appreciated...
-* [Donate via Patron](https://www.patreon.com/plyr)
-* [Donate via PayPal](https://www.paypal.me/pottsy/20usd)
+- [Donate via Patreon](https://www.patreon.com/plyr)
+- [Donate via PayPal](https://www.paypal.me/pottsy/20usd)
## Mentions
-* [ProductHunt](https://www.producthunt.com/tech/plyr)
-* [The Changelog](http://thechangelog.com/plyr-simple-html5-media-player-custom-controls-webvtt-captions/)
-* [HTML5 Weekly #177](http://html5weekly.com/issues/177)
-* [Responsive Design #149](http://us4.campaign-archive2.com/?u=559bc631fe5294fc66f5f7f89&id=451a61490f)
-* [Web Design Weekly #174](https://web-design-weekly.com/2015/02/24/web-design-weekly-174/)
-* [Hacker News](https://news.ycombinator.com/item?id=9136774)
-* [Web Platform Daily](http://webplatformdaily.org/releases/2015-03-04)
-* [LayerVault Designer News](https://news.layervault.com/stories/45394-plyr--a-simple-html5-media-player)
-* [The Treehouse Show #131](https://teamtreehouse.com/library/episode-131-origami-react-responsive-hero-images)
-* [noupe.com](http://www.noupe.com/design/html5-plyr-is-a-responsive-and-accessible-video-player-94389.html)
+- [ProductHunt](https://www.producthunt.com/tech/plyr)
+- [The Changelog](http://thechangelog.com/plyr-simple-html5-media-player-custom-controls-webvtt-captions/)
+- [HTML5 Weekly #177](http://html5weekly.com/issues/177)
+- [Responsive Design #149](http://us4.campaign-archive2.com/?u=559bc631fe5294fc66f5f7f89&id=451a61490f)
+- [Web Design Weekly #174](https://web-design-weekly.com/2015/02/24/web-design-weekly-174/)
+- [Hacker News](https://news.ycombinator.com/item?id=9136774)
+- [Web Platform Daily](http://webplatformdaily.org/releases/2015-03-04)
+- [LayerVault Designer News](https://news.layervault.com/stories/45394-plyr--a-simple-html5-media-player)
+- [The Treehouse Show #131](https://teamtreehouse.com/library/episode-131-origami-react-responsive-hero-images)
+- [noupe.com](http://www.noupe.com/design/html5-plyr-is-a-responsive-and-accessible-video-player-94389.html)
## Used by
-* [Selz.com](https://selz.com)
-* [Peugeot.fr](http://www.peugeot.fr/marque-et-technologie/technologies/peugeot-i-cockpit.html)
-* [Peugeot.de](http://www.peugeot.de/modelle/modellberater/208-3-turer/fotos-videos.html)
-* [TomTom.com](http://prioritydriving.tomtom.com/)
-* [DIGBMX](http://digbmx.com/)
-* [Grime Archive](https://grimearchive.com/)
-* [koel - A personal music streaming server that works.](http://koel.phanan.net/)
-* [Oscar Radio](http://oscar-radio.xyz/)
-* [Sparkk TV](https://www.sparkktv.com/)
+- [Selz.com](https://selz.com)
+- [Peugeot.fr](http://www.peugeot.fr/marque-et-technologie/technologies/peugeot-i-cockpit.html)
+- [Peugeot.de](http://www.peugeot.de/modelle/modellberater/208-3-turer/fotos-videos.html)
+- [TomTom.com](http://prioritydriving.tomtom.com/)
+- [DIGBMX](http://digbmx.com/)
+- [Grime Archive](https://grimearchive.com/)
+- [koel - A personal music streaming server that works.](http://koel.phanan.net/)
+- [Oscar Radio](http://oscar-radio.xyz/)
+- [Sparkk TV](https://www.sparkktv.com/)
+- [@halfhalftravel](https://www.halfhalftravel.com/)
Let me know on [Twitter](https://twitter.com/sam_potts) I can add you to the above list. It'd be awesome to see how you're using Plyr :-)
@@ -720,8 +750,8 @@ Let me know on [Twitter](https://twitter.com/sam_potts) I can add you to the abo
Credit to the PayPal HTML5 Video player from which Plyr's caption functionality was originally ported from:
-* [PayPal's Accessible HTML5 Video Player](https://github.com/paypal/accessible-html5-video-player)
-* [An awesome guide for Plyr in Japanese!](http://syncer.jp/how-to-use-plyr-io) by [@arayutw](https://twitter.com/arayutw)
+- [PayPal's Accessible HTML5 Video Player](https://github.com/paypal/accessible-html5-video-player)
+- [An awesome guide for Plyr in Japanese!](http://syncer.jp/how-to-use-plyr-io) by [@arayutw](https://twitter.com/arayutw)
## Thanks