diff options
Diffstat (limited to 'readme.md')
-rw-r--r-- | readme.md | 214 |
1 files changed, 139 insertions, 75 deletions
@@ -1,18 +1,19 @@ Plyr is a simple, lightweight, accessible and customizable HTML5, YouTube and Vimeo media player that supports [_modern_](#browser-support) browsers. -[Checkout the demo](https://plyr.io) - [Donate](#donate) - [Slack](https://bit.ly/plyr-chat) - [](https://badge.fury.io/js/plyr) +[Checkout the demo](https://plyr.io) - [Donate](#donate) - [Slack](https://bit.ly/plyr--chat) + +[](https://badge.fury.io/js/plyr) [](https://gitpod.io/#https://github.com/sampotts/plyr) [](https://opencollective.com/plyr) [](https://plyr.io) # Features +- 📼 **HTML Video & Audio, YouTube & Vimeo** - support for the major formats - 💪 **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 +- 🔧 **[Customizable](#html)** - make the player look how you want with the markup you want +- 😎 **Clean 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](#demos)** - support for hls.js, Shaka and dash.js streaming playback - 🎛 **[API](#api)** - toggle playback, volume, seeking, and more through a standardized API @@ -25,7 +26,7 @@ Plyr is a simple, lightweight, accessible and customizable HTML5, YouTube and Vi - 📖 **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 +- 🤟 **No frameworks** - written in "vanilla" ES6 JavaScript, no jQuery required - 💁♀️ **SASS** - to include in your build processes ### Demos @@ -109,7 +110,15 @@ Or the `<div>` non progressively enhanced method: ## JavaScript -Include the `plyr.js` script before the closing `</body>` tag and then in your JS create a new instance of Plyr as below. +You can use Plyr as an ES6 module as follows: + +```javascript +import Plyr from 'plyr'; + +const player = new Plyr('#player'); +``` + +Alternatively you can include the `plyr.js` script before the closing `</body>` tag and then in your JS create a new instance of Plyr as below. ```html <script src="path/to/plyr.js"></script> @@ -123,18 +132,18 @@ See [initialising](#initialising) for more information on advanced setups. 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.5.4/plyr.js"></script> +<script src="https://cdn.plyr.io/3.5.10/plyr.js"></script> ``` ...or... ```html -<script src="https://cdn.plyr.io/3.5.4/plyr.polyfilled.js"></script> +<script src="https://cdn.plyr.io/3.5.10/plyr.polyfilled.js"></script> ``` ## CSS -Include the `plyr.css` stylsheet into your `<head>` +Include the `plyr.css` stylsheet into your `<head>`. ```html <link rel="stylesheet" href="path/to/plyr.css" /> @@ -143,13 +152,13 @@ Include the `plyr.css` stylsheet into your `<head>` 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.5.4/plyr.css" /> +<link rel="stylesheet" href="https://cdn.plyr.io/3.5.10/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.5.4/plyr.svg`. +reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.5.10/plyr.svg`. # Ads @@ -161,12 +170,40 @@ Plyr has partnered up with [vi.ai](https://vi.ai/publisher-video-monetization/?a Any questions regarding the ads can be sent straight to vi.ai and any issues with rendering raised through GitHub issues. +If you do not wish to use Vi, you can set your own `ads.tagUrl` [option](#options). + # Advanced -## SASS +## Custom CSS + +If you want to change any design tokens used for the rendering of the player, you can do so using [CSS Custom Properties](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties). + +Here's a list of the properties and what they are used for: + +| Name | Description | Fallback | +| ------------------- | ----------------------------------------------- | --------------------- | +| `--plyr-color-main` | The main branding color - used for highlighting | `hsl(198, 100%, 50%)` | + +You can set them in your CSS: + +```css +.player { + --plyr-color-main: #1ac266; +} +``` + +...or in your HTML: -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 should be already!) as all declarations use the W3C definitions. +```html +<video class="player" style="--plyr-color-main: #1ac266;"> + ... +</vieo> +``` + +### SASS + +You can use `plyr.scss` file included in `/src/sass` as part of your build and change variables to suit your design. The SASS requires you to +use [autoprefixer](https://www.npmjs.com/package/gulp-autoprefixer) (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. @@ -204,7 +241,7 @@ 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 [CSS string selector](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors) - A [`HTMLElement`](https://developer.mozilla.org/en/docs/Web/API/HTMLElement) - A [jQuery](https://jquery.com) object @@ -212,7 +249,7 @@ _Note_: If a `NodeList`, `Array`, or jQuery object are passed, the first element #### Single player -Passing a [string selector](https://developer.mozilla.org/en-US/docs/Web/API/NodeList): +Passing a CSS string selector that's compatible with [`querySelector`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector): ```javascript const player = new Plyr('#player'); @@ -238,7 +275,7 @@ You have two choices here. You can either use a simple array loop to map the con const players = Array.from(document.querySelectorAll('.js-player')).map(p => new Plyr(p)); ``` -...or use a static method where you can pass a [string selector](https://developer.mozilla.org/en-US/docs/Web/API/NodeList), a [NodeList](https://developer.mozilla.org/en-US/docs/Web/API/NodeList), an [Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) of elements, or a [JQuery](https://jquery.com) object: +...or use a static method where you can pass a [CSS string selector](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors), a [NodeList](https://developer.mozilla.org/en-US/docs/Web/API/NodeList), an [Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) of [HTMLElement](https://developer.mozilla.org/en/docs/Web/API/HTMLElement), or a [JQuery](https://jquery.com) object: ```javascript const players = Plyr.setup('.js-player'); @@ -269,7 +306,7 @@ Note the single quotes encapsulating the JSON and double quotes on the object ke | `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 | +| `settings` | Array | `['captions', 'quality', 'speed', 'loop']` | If the default controls are used, 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. | @@ -295,10 +332,10 @@ Note the single quotes encapsulating the JSON and double quotes on the object ke | `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 | `null` | Force an aspect ratio for all videos. The format is `'w:h'` - e.g. `'16:9'` or `'4:3'`. If this is not specified then the default for HTML5 and Vimeo is to use the native resolution of the video. As dimensions are not available from YouTube via SDK, 16:9 is forced as a sensible default. | | `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. | +| `speed` | Object | `{ selected: 1, options: [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2] }` | `selected`: The default speed for playback. `options`: The speed options to display in the UI. YouTube and Vimeo will ignore any options outside of the 0.5-2 range, so options outside of this range will be hidden automatically. | | `quality` | Object | `{ default: 576, options: [4320, 2880, 2160, 1440, 1080, 720, 576, 480, 360, 240] }` | `default` is the default quality level (if it exists in your sources). `options` are the options to display. This is used to filter the available sources. | | `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. | +| `ads` | Object | `{ enabled: false, publisherId: '', tagUrl: '' }` | `enabled`: Whether to enable advertisements. `publisherId`: Your unique [vi.ai](https://vi.ai/publisher-video-monetization/?aid=plyrio) publisher ID. `tagUrl` is a URL for a custom VAST tag if you're not using Vi. | | `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` | @@ -342,30 +379,30 @@ player.play(); // Start playback player.fullscreen.enter(); // Enter fullscreen ``` -| Method | Parameters | Description | -| ------------------------ | ---------------- | ---------------------------------------------------------------------------------------------------------- | -| `play()`¹ | - | Start playback. | -| `pause()` | - | Pause playback. | -| `togglePlay(toggle)` | Boolean | Toggle playback, if no parameters are passed, it will toggle based on current status. | -| `stop()` | - | Stop playback and reset to start. | -| `restart()` | - | Restart playback. | -| `rewind(seekTime)` | Number | Rewind playback by the specified seek time. If no parameter is passed, the default seek time will be used. | -| `forward(seekTime)` | Number | Fast forward by the specified seek time. If no parameter is passed, the default seek time will be used. | -| `increaseVolume(step)` | Number | Increase volume by the specified step. If no parameter is passed, the default step will be used. | -| `decreaseVolume(step)` | Number | Increase volume by the specified step. If no parameter is passed, the default step will be used. | -| `toggleCaptions(toggle)` | Boolean | Toggle captions display. If no parameter is passed, it will toggle based on current status. | -| `fullscreen.enter()` | - | Enter fullscreen. If fullscreen is not supported, a fallback "full window/viewport" is used instead. | -| `fullscreen.exit()` | - | Exit fullscreen. | -| `fullscreen.toggle()` | - | Toggle fullscreen. | -| `airplay()` | - | Trigger the airplay dialog on supported devices. | -| `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. | - -1. For HTML5 players, `play()` will return a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) in _some_ browsers - WebKit and Mozilla [according to MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/play) at time of writing. +| Method | Parameters | Description | +| -------------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------- | +| `play()`¹ | - | Start playback. | +| `pause()` | - | Pause playback. | +| `togglePlay(toggle)`¹ | Boolean | Toggle playback, if no parameters are passed, it will toggle based on current status. | +| `stop()` | - | Stop playback and reset to start. | +| `restart()` | - | Restart playback. | +| `rewind(seekTime)` | Number | Rewind playback by the specified seek time. If no parameter is passed, the default seek time will be used. | +| `forward(seekTime)` | Number | Fast forward by the specified seek time. If no parameter is passed, the default seek time will be used. | +| `increaseVolume(step)` | Number | Increase volume by the specified step. If no parameter is passed, the default step will be used. | +| `decreaseVolume(step)` | Number | Increase volume by the specified step. If no parameter is passed, the default step will be used. | +| `toggleCaptions(toggle)` | Boolean | Toggle captions display. If no parameter is passed, it will toggle based on current status. | +| `fullscreen.enter()` | - | Enter fullscreen. If fullscreen is not supported, a fallback "full window/viewport" is used instead. | +| `fullscreen.exit()` | - | Exit fullscreen. | +| `fullscreen.toggle()` | - | Toggle fullscreen. | +| `airplay()` | - | Trigger the airplay dialog on supported devices. | +| `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. | + +1. For HTML5 players, `play()` will return a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) for most browsers - e.g. Chrome, Firefox, Opera, Safari and Edge [according to MDN](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/play) at time of writing. ## Getters and Setters @@ -438,6 +475,9 @@ player.source = { }, ], poster: '/path/to/poster.jpg', + previewThumbnails: { + src: '/path/to/thumbnails.vtt', + }, tracks: [ { kind: 'captions', @@ -507,13 +547,14 @@ player.source = { _Note:_ `src` property for YouTube and Vimeo can either be the video ID or the whole URL. -| Property | Type | Description | -| -------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `type` | String | Either `video` or `audio`. _Note:_ YouTube and Vimeo are currently not supported as audio sources. | -| `title` | String | _Optional._ Title of the new media. Used for the `aria-label` attribute on the play button, and outer container. YouTube and Vimeo are populated automatically. | -| `sources` | Array | This is an array of sources. For HTML5 media, the properties of this object are mapped directly to HTML attributes so more can be added to the object if required. | -| `poster`¹ | String | The URL for the poster image (HTML5 video only). | -| `tracks`¹ | String | An array of track objects. Each element in the array is mapped directly to a track element and any keys mapped directly to HTML attributes so as in the example above, it will render as `<track kind="captions" label="English" srclang="en" src="https://cdn.selz.com/plyr/1.0/example_captions_en.vtt" default>` and similar for the French version. Booleans are converted to HTML5 value-less attributes. | +| Property | Type | Description | +| ------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `type` | String | Either `video` or `audio`. _Note:_ YouTube and Vimeo are currently not supported as audio sources. | +| `title` | String | _Optional._ Title of the new media. Used for the `aria-label` attribute on the play button, and outer container. YouTube and Vimeo are populated automatically. | +| `sources` | Array | This is an array of sources. For HTML5 media, the properties of this object are mapped directly to HTML attributes so more can be added to the object if required. | +| `poster`¹ | String | The URL for the poster image (HTML5 video only). | +| `tracks`¹ | String | An array of track objects. Each element in the array is mapped directly to a track element and any keys mapped directly to HTML attributes so as in the example above, it will render as `<track kind="captions" label="English" srclang="en" src="https://cdn.selz.com/plyr/1.0/example_captions_en.vtt" default>` and similar for the French version. Booleans are converted to HTML5 value-less attributes. | +| `previewThumbnails`¹ | Object | The same object like in the `previewThumbnails` constructor option. This means you can either change the thumbnails vtt via the `src` key or disable the thumbnails plugin for the next video by passing `{ enabled: false }`. | 1. HTML5 only @@ -622,16 +663,16 @@ Fullscreen in Plyr is supported by all browsers that [currently support it](http Plyr supports the last 2 versions of most _modern_ browsers. -| Browser | Supported | -| ------------- | ------------- | -| Safari | ✓ | -| Mobile Safari | ✓¹ | -| Firefox | ✓ | -| Chrome | ✓ | -| Opera | ✓ | -| Edge | ✓ | -| IE11 | ✓³ | -| IE10 | ✓²³ | +| Browser | Supported | +| ------------- | --------------- | +| Safari | ✓ | +| Mobile Safari | ✓¹ | +| Firefox | ✓ | +| Chrome | ✓ | +| Opera | ✓ | +| Edge | ✓ | +| IE11 | ✓³ | +| IE10 | ✓<sup>2,3</sup> | 1. Mobile Safari on the iPhone forces the native player for `<video>` unless the `playsinline` attribute is present. Volume controls are also disabled as they are handled device wide. 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)). @@ -655,7 +696,7 @@ The arguments are: - Provider (`html5`, `youtube` or `vimeo`) - Whether the player has the `playsinline` attribute (only applicable to iOS 10+) -## Disable support programatically +## Disable support programmatically The `enabled` option can be used to disable certain User Agents. For example, if you don't want to use Plyr for smartphones, you could use: @@ -671,14 +712,15 @@ If a User Agent is disabled but supports `<video>` and `<audio>` natively, it wi Some awesome folks have made plugins for CMSs and Components for JavaScript frameworks: -| 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) | -| Kirby | Dominik Pschenitschni ([@dpschen](https://github.com/dpschen)) | [https://github.com/dpschen/kirby-plyrtag](https://github.com/dpschen/kirby-plyrtag) | +| 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 | Chintan Prajapati ([@chintan9](https://github.com/chintan9)) | [https://github.com/chintan9/plyr-react](https://github.com/chintan9/plyr-react) | +| 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) | +| Kirby | Dominik Pschenitschni ([@dpschen](https://github.com/dpschen)) | [https://github.com/dpschen/kirby-plyrtag](https://github.com/dpschen/kirby-plyrtag) | +| REDAXO | FriendsOfRedaxo / skerbis ([@skerbis](https://friendsofredaxo.github.io)) | [https://github.com/FriendsOfREDAXO/plyr](https://github.com/FriendsOfREDAXO/plyr) | # Issues @@ -703,6 +745,7 @@ Plyr costs money to run, not only my time. I donate my time for free as I enjoy - [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/) +- [Front End Focus #177](https://frontendfoc.us/issues/177) - [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) @@ -722,13 +765,11 @@ Plyr costs money to run, not only my time. I donate my time for free as I enjoy - [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 :-) +If you want to be added to the list, open a pull request. It'd be awesome to see how you're using Plyr 😎 # Useful links and credits -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) +- [PayPal's Accessible HTML5 Video Player (which Plyr was originally ported from)](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 @@ -741,6 +782,29 @@ Massive thanks to [Fastly](https://www.fastly.com/) for providing the CDN servic Massive thanks to [Sentry](https://sentry.io/) for providing the logging services for the demo site. +## Contributors + +### Code Contributors + +This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. + +<a href="https://github.com/sampotts/plyr/graphs/contributors"><img src="https://opencollective.com/plyr/contributors.svg?width=890&button=false" /></a> + +### Financial Contributors + +Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/plyr/contribute)] + +#### Individuals + +<a href="https://opencollective.com/plyr"><img src="https://opencollective.com/plyr/individuals.svg?width=890"></a> + +#### Organizations + +Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/plyr/contribute)] + +<a href="https://opencollective.com/plyr/organization/0/website"><img src="https://opencollective.com/plyr/organization/0/avatar.svg"></a> +<a href="https://opencollective.com/plyr/organization/1/website"><img src="https://opencollective.com/plyr/organization/1/avatar.svg"></a><a href="https://opencollective.com/plyr/organization/2/website"><img src="https://opencollective.com/plyr/organization/2/avatar.svg"></a> + # Copyright and License [The MIT license](license.md) |