├── .gitignore ├── LICENSE.md ├── README.md ├── addThis ├── README.md ├── index.html ├── video-js.min.css ├── video.dev.js ├── videojs.addThis.css └── videojs.addThis.js ├── automute ├── automute.js └── automute.less ├── callToAction ├── callToAction.js └── callToAction.less ├── dimTheLights ├── README.md ├── dimTheLights.css └── dimTheLights.js ├── googleAnalytics └── videojs.ga.js ├── hideControlsOnPause └── videojs.hideControlsOnPause.js ├── logo ├── Readme.md ├── logo.css └── logo.js ├── playlist ├── playlist-caption.js ├── playlist-controls.js ├── playlist-item.js ├── playlist-slider.js ├── playlist.js ├── playlist.less ├── responsive.css └── scroll-indicator.js ├── replayState ├── replayState.css └── replayState.js ├── resize ├── videojs.resize.css └── videojs.resize.js ├── showPosterAtEnd └── videojs.showPosterAtEnd.js ├── socialOverlay ├── README.md ├── socialOverlay.css └── socialOverlay.js └── themeLoader └── videojs.themeLoader.js /.gitignore: -------------------------------------------------------------------------------- 1 | /.DS_Store 2 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Brian Kelley 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | video-js-4-plugins 2 | ================== 3 | 4 | A collection of plugins for Video.js 4.x 5 | 6 | 7 | Just starting to throw these up, each will have a readme with links to a demo and how-to. 8 | -------------------------------------------------------------------------------- /addThis/README.md: -------------------------------------------------------------------------------- 1 | #addThis Video.js Plugin# 2 | This creates a "share" menu in the control bar for video.js. Currently it only supports creating links for the some of the more popular sites, and a "more" link that opens a new window with the entire list of shareable sites. 3 | 4 | ##Usage## 5 | #####This plugin requires you to use the unminified dev build##### 6 | Just include the `addThis: {}` item in the `plugins` object for the default config. In the examples below, reddit and delicious have been disabled due to font-awesome not having icons for them. I reccomend using the Font-Awesome-More set here: https://github.com/gregoryloucas/Fontstrap 7 | 8 | ####HTML#### 9 | ````html 10 | 11 | 12 | 13 | 14 | HTML5 Video Player 15 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 32 | 33 | 34 | 35 | ```` 36 | ####Javascript#### 37 | ````html 38 | 39 | 40 | 41 | 42 | HTML5 Video Player 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 62 | 63 | 78 | 79 | 80 | ```` 81 | 82 | ##Options## 83 | ####Enable links: #### 84 | - **facebook** *(boolean)* 85 | - **twitter** *(boolean)* 86 | - **googleplus** *(boolean)* 87 | - **linkedin** *(boolean)* 88 | - **pinterest** *(boolean)* 89 | - **delicious** *(boolean)* 90 | - **reddit** *(boolean)* 91 | - **email** *(boolean)* 92 | - **embed** *(boolean)* *Custom* 93 | - **more** *(boolean)* 94 | - **website_url** *(string)* must start with http(s):// 95 | 96 | ####Configuration: #### 97 | - **pubid** *(string)* Your publisher profile ID (analytics). (NOT REQUIRED to use this plugin) 98 | - **ct** *(string)* Enable click tracking (shared page must have AddThis client code to measure clicks) 99 | - **email_template** *(string)* Email template to use for email sharing (requires pubid param) 100 | - **share_url** *(string)* To share a different url than the current page, specify here. 101 | 102 | ##Useful Links## 103 | Available Services - http://www.addthis.com/services/list 104 | 105 | AddThis Endpoints - http://support.addthis.com/customer/portal/articles/381265-addthis-sharing-endpoints 106 | 107 | -------------------------------------------------------------------------------- /addThis/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | HTML5 Video Player 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |

videojs version: 4.9.0

17 | 22 | 23 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /addThis/video-js.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | Video.js Default Styles (http://videojs.com) 3 | Version 4.2.1 4 | Create your own skin at http://designer.videojs.com 5 | */.vjs-default-skin{color:#ccc}@font-face{font-family:VideoJS;src:url(font/vjs.eot);src:url(font/vjs.eot?) format('embedded-opentype')}@font-face{font-family:VideoJS;src:url(data:application/x-font-woff;charset=utf-8;base64,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) format('woff'),url(fonts/vjs.ttf) format('truetype');font-weight:400;font-style:normal}.vjs-default-skin .vjs-slider{outline:0;position:relative;cursor:pointer;padding:0;background-color:#333;background-color:rgba(51,51,51,.9)}.vjs-default-skin .vjs-slider:focus{-webkit-box-shadow:0 0 2em #fff;-moz-box-shadow:0 0 2em #fff;box-shadow:0 0 2em #fff}.vjs-default-skin .vjs-slider-handle{position:absolute;left:0;top:0}.vjs-default-skin .vjs-slider-handle:before{content:"\e009";font-family:VideoJS;font-size:1em;line-height:1;text-align:center;text-shadow:0 0 1em #fff;position:absolute;top:0;left:0;-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-o-transform:rotate(-45deg);transform:rotate(-45deg)}.vjs-default-skin .vjs-control-bar{display:none;position:absolute;bottom:0;left:0;right:0;height:3em;background-color:#07141e;background-color:rgba(7,20,30,.7)}.vjs-default-skin.vjs-has-started .vjs-control-bar{display:block;visibility:visible;opacity:1;-webkit-transition:visibility .1s,opacity .1s;-moz-transition:visibility .1s,opacity .1s;-o-transition:visibility .1s,opacity .1s;transition:visibility .1s,opacity .1s}.vjs-default-skin.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{display:block;visibility:hidden;opacity:0;-webkit-transition:visibility 1s,opacity 1s;-moz-transition:visibility 1s,opacity 1s;-o-transition:visibility 1s,opacity 1s;transition:visibility 1s,opacity 1s}.vjs-default-skin.vjs-controls-disabled .vjs-control-bar{display:none}.vjs-default-skin.vjs-using-native-controls .vjs-control-bar{display:none}@media \0screen{.vjs-default-skin.vjs-user-inactive.vjs-playing .vjs-control-bar :before{content:""}}.vjs-default-skin .vjs-control{outline:0;position:relative;float:left;text-align:center;margin:0;padding:0;height:3em;width:4em}.vjs-default-skin .vjs-control:before{font-family:VideoJS;font-size:1.5em;line-height:2;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;text-shadow:1px 1px 1px rgba(0,0,0,.5)}.vjs-default-skin .vjs-control:focus:before,.vjs-default-skin .vjs-control:hover:before{text-shadow:0 0 1em #fff}.vjs-default-skin .vjs-control:focus{}.vjs-default-skin .vjs-control-text{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.vjs-default-skin .vjs-play-control{width:5em;cursor:pointer}.vjs-default-skin .vjs-play-control:before{content:"\e001"}.vjs-default-skin.vjs-playing .vjs-play-control:before{content:"\e002"}.video-js .vjs-volume-container{float:right}.video-js .vjs-volume-container-linear{width:9em;padding-right:1em}.vjs-default-skin .vjs-mute-control,.vjs-default-skin .vjs-volume-menu-button{cursor:pointer;float:right}.vjs-default-skin .vjs-mute-control:before,.vjs-default-skin .vjs-volume-menu-button:before{content:"\e006"}.vjs-default-skin .vjs-mute-control.vjs-vol-0:before,.vjs-default-skin .vjs-volume-menu-button.vjs-vol-0:before{content:"\e003"}.vjs-default-skin .vjs-mute-control.vjs-vol-1:before,.vjs-default-skin .vjs-volume-menu-button.vjs-vol-1:before{content:"\e004"}.vjs-default-skin .vjs-mute-control.vjs-vol-2:before,.vjs-default-skin .vjs-volume-menu-button.vjs-vol-2:before{content:"\e005"}.vjs-default-skin .vjs-volume-control{width:5em;float:right}.vjs-default-skin .vjs-volume-bar{width:5em;height:.6em;margin:1.1em auto 0}.vjs-default-skin .vjs-volume-menu-button .vjs-menu-content{height:2.9em}.vjs-default-skin .vjs-volume-level{position:absolute;top:0;left:0;height:.5em;background:#66a8cc url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAP0lEQVQIHWWMAQoAIAgDR/QJ/Ub//04+w7ZICBwcOg5FZi5iBB82AGzixEglJrd4TVK5XUJpskSTEvpdFzX9AB2pGziSQcvAAAAAAElFTkSuQmCC) -50% 0 repeat}.vjs-default-skin .vjs-volume-bar .vjs-volume-handle{width:.5em;height:.5em}.vjs-default-skin .vjs-volume-handle:before{font-size:.9em;top:-.2em;left:-.2em;width:1em;height:1em}.vjs-default-skin .vjs-volume-menu-button .vjs-menu .vjs-menu-content{width:6em;left:-4em}.vjs-default-skin .vjs-volume-menu-vertical .vjs-menu-content{left:-2em!important;width:4em!important;height:8em;padding-top:.5em}.vjs-default-skin .vjs-volume-menu-vertical .vjs-volume-bar{width:.6em;height:5em;margin:1.1em auto 0}.vjs-default-skin .vjs-volume-menu-vertical .vjs-volume-level{height:8em;width:100%;bottom:0;top:auto;background:#66a8cc url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAP0lEQVQIHWWMAQoAIAgDR/QJ/Ub//04+w7ZICBwcOg5FZi5iBB82AGzixEglJrd4TVK5XUJpskSTEvpdFzX9AB2pGziSQcvAAAAAAElFTkSuQmCC) -50% 0 repeat}.vjs-default-skin .vjs-progress-control{position:absolute;left:0;right:0;width:auto;font-size:.3em;height:1em;top:-1em;-webkit-transition:all .4s;-moz-transition:all .4s;-o-transition:all .4s;transition:all .4s}.vjs-default-skin:hover .vjs-progress-control{font-size:.9em;-webkit-transition:all .2s;-moz-transition:all .2s;-o-transition:all .2s;transition:all .2s}.vjs-default-skin .vjs-progress-holder{height:100%}.vjs-default-skin .vjs-progress-holder .vjs-play-progress,.vjs-default-skin .vjs-progress-holder .vjs-load-progress{position:absolute;display:block;height:100%;margin:0;padding:0;left:0;top:0}.vjs-default-skin .vjs-play-progress{background:#66a8cc url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAP0lEQVQIHWWMAQoAIAgDR/QJ/Ub//04+w7ZICBwcOg5FZi5iBB82AGzixEglJrd4TVK5XUJpskSTEvpdFzX9AB2pGziSQcvAAAAAAElFTkSuQmCC) -50% 0 repeat}.vjs-default-skin .vjs-load-progress{background:#646464;background:rgba(255,255,255,.4)}.vjs-default-skin .vjs-seek-handle{width:1.5em;height:100%}.vjs-default-skin .vjs-seek-handle:before{padding-top:.1em}.vjs-default-skin .vjs-time-controls{font-size:1em;line-height:3em}.vjs-default-skin .vjs-current-time{float:left}.vjs-default-skin .vjs-duration{float:left}.vjs-default-skin .vjs-remaining-time{display:none;float:left}.vjs-time-divider{float:left;line-height:3em}.vjs-default-skin .vjs-fullscreen-control{width:3.8em;cursor:pointer;float:right}.vjs-default-skin .vjs-fullscreen-control:before{content:"\e000"}.vjs-default-skin.vjs-fullscreen .vjs-fullscreen-control:before{content:"\e00b"}.vjs-default-skin .vjs-big-play-button{left:.5em;top:.5em;font-size:3em;display:block;z-index:2;position:absolute;width:4em;height:2.6em;text-align:center;vertical-align:middle;cursor:pointer;opacity:1;background-color:#07141e;background-color:rgba(7,20,30,.7);border:.1em solid #3b4249;-webkit-border-radius:.8em;-moz-border-radius:.8em;border-radius:.8em;-webkit-box-shadow:0 0 1em rgba(255,255,255,.25);-moz-box-shadow:0 0 1em rgba(255,255,255,.25);box-shadow:0 0 1em rgba(255,255,255,.25);-webkit-transition:all .4s;-moz-transition:all .4s;-o-transition:all .4s;transition:all .4s}.vjs-default-skin.vjs-controls-disabled .vjs-big-play-button{display:none}.vjs-default-skin.vjs-has-started .vjs-big-play-button{display:none}.vjs-default-skin.vjs-using-native-controls .vjs-big-play-button{display:none}.vjs-default-skin:hover .vjs-big-play-button,.vjs-default-skin .vjs-big-play-button:focus{outline:0;border-color:#fff;background-color:#505050;background-color:rgba(50,50,50,.75);-webkit-box-shadow:0 0 3em #fff;-moz-box-shadow:0 0 3em #fff;box-shadow:0 0 3em #fff;-webkit-transition:all 0s;-moz-transition:all 0s;-o-transition:all 0s;transition:all 0s}.vjs-default-skin .vjs-big-play-button:before{content:"\e001";font-family:VideoJS;line-height:2.6em;text-shadow:.05em .05em .1em #000;text-align:center;position:absolute;left:0;width:100%;height:100%}.vjs-loading-spinner{display:none;position:absolute;top:50%;left:50%;font-size:5em;line-height:1;width:1em;height:1em;margin-left:-.5em;margin-top:-.5em;opacity:.75;-webkit-animation:spin 1.5s infinite linear;-moz-animation:spin 1.5s infinite linear;-o-animation:spin 1.5s infinite linear;animation:spin 1.5s infinite linear}.vjs-default-skin .vjs-loading-spinner:before{content:"\e00a";font-family:VideoJS;position:absolute;top:0;left:0;width:1em;height:1em;text-align:center;text-shadow:0 0 .1em #000}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}}.vjs-default-skin .vjs-menu-button{float:right;cursor:pointer}.vjs-default-skin .vjs-menu{display:none;position:absolute;bottom:0;left:0;width:0;height:0;margin-bottom:3em;border-left:2em solid transparent;border-right:2em solid transparent;border-top:1.55em solid #000;border-top-color:rgba(7,40,50,.5)}.vjs-default-skin .vjs-menu-button .vjs-menu .vjs-menu-content{display:block;padding:0;margin:0;position:absolute;width:10em;bottom:1.5em;max-height:15em;overflow:auto;left:-5em;background-color:#07141e;background-color:rgba(7,20,30,.7);-webkit-box-shadow:-.2em -.2em .3em rgba(255,255,255,.2);-moz-box-shadow:-.2em -.2em .3em rgba(255,255,255,.2);box-shadow:-.2em -.2em .3em rgba(255,255,255,.2)}.vjs-default-skin .vjs-menu-button:hover .vjs-menu{display:block}.vjs-default-skin .vjs-menu-button ul li{list-style:none;margin:0;padding:.3em 0;line-height:1.4em;font-size:1.2em;text-align:center;text-transform:lowercase}.vjs-default-skin .vjs-menu-button ul li.vjs-selected{background-color:#000}.vjs-default-skin .vjs-menu-button ul li:focus,.vjs-default-skin .vjs-menu-button ul li:hover,.vjs-default-skin .vjs-menu-button ul li.vjs-selected:focus,.vjs-default-skin .vjs-menu-button ul li.vjs-selected:hover{outline:0;color:#111;background-color:#fff;background-color:rgba(255,255,255,.75);-webkit-box-shadow:0 0 1em #fff;-moz-box-shadow:0 0 1em #fff;box-shadow:0 0 1em #fff}.vjs-default-skin .vjs-menu-button ul li.vjs-menu-title{text-align:center;text-transform:uppercase;font-size:1em;line-height:2em;padding:0;margin:0 0 .3em;font-weight:700;cursor:default}.vjs-default-skin .vjs-subtitles-button:before{content:"\e00c"}.vjs-default-skin .vjs-captions-button:before{content:"\e008"}.vjs-default-skin .vjs-captions-button:focus .vjs-control-content:before,.vjs-default-skin .vjs-captions-button:hover .vjs-control-content:before{-webkit-box-shadow:0 0 1em #fff;-moz-box-shadow:0 0 1em #fff;box-shadow:0 0 1em #fff}.video-js{background-color:#000;position:relative;padding:0;font-size:10px;vertical-align:middle;font-weight:400;font-style:normal;font-family:Arial,sans-serif;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.video-js .vjs-tech{position:absolute;top:0;left:0;width:100%;height:100%}.video-js:-moz-full-screen{position:absolute}body.vjs-full-window{padding:0;margin:0;height:100%;overflow-y:auto}.video-js.vjs-fullscreen{position:fixed;overflow:hidden;z-index:1000;left:0;top:0;bottom:0;right:0;width:100%!important;height:100%!important;_position:absolute}.video-js:-webkit-full-screen{width:100%!important;height:100%!important}.video-js.vjs-fullscreen.vjs-user-inactive{cursor:none}.vjs-poster{background-repeat:no-repeat;background-position:50% 50%;background-size:contain;cursor:pointer;height:100%;margin:0;padding:0;position:relative;width:100%}.vjs-poster img{display:block;margin:0 auto;max-height:100%;padding:0;width:100%}.video-js.vjs-using-native-controls .vjs-poster{display:none}.video-js .vjs-text-track-display{text-align:center;position:absolute;bottom:4em;left:1em;right:1em}.video-js .vjs-text-track{display:none;font-size:1.4em;text-align:center;margin-bottom:.1em;background-color:#000;background-color:rgba(0,0,0,.5)}.video-js .vjs-subtitles{color:#fff}.video-js .vjs-captions{color:#fc6}.vjs-tt-cue{display:block}.vjs-default-skin .vjs-hidden{display:none}.vjs-lock-showing{display:block!important;opacity:1;visibility:visible} -------------------------------------------------------------------------------- /addThis/videojs.addThis.css: -------------------------------------------------------------------------------- 1 | 2 | .video-js .vjs-menu-button ul li { 3 | padding: 4px 0; 4 | list-style: none; 5 | } 6 | 7 | .video-js .vjs-control[class^="icon-"]:before, 8 | .video-js .vjs-control[class*=" icon-"]:before { 9 | font-family:'FontAwesome'; 10 | 11 | } 12 | 13 | 14 | .video-js .vjs-social-button .vjs-menu .vjs-menu-content { 15 | 16 | height: auto; 17 | max-height: none; 18 | } 19 | .video-js .vjs-social-button .vjs-menu .vjs-menu-content li.vjs-menu-item { 20 | width: 2.775em; 21 | float: left; 22 | font-size: 1.8em; 23 | padding: 5px 0; 24 | } 25 | 26 | .video-js .vjs-embed-window { 27 | position: fixed; 28 | z-index: 100; 29 | 30 | left: 35%; 31 | top: 40%; 32 | 33 | width: 30%; 34 | height: 20%; 35 | 36 | background: rgba(7, 40, 50, 0.7); 37 | -webkit-box-shadow: 0 0 1em rgba(255, 255, 255, 1); 38 | -moz-box-shadow: 0 0 1em rgba(255, 255, 255, 1); 39 | box-shadow: 0 0 1em rgba(255, 255, 255, 1); 40 | 41 | /* Fade */ 42 | 43 | -webkit-transition: visibility 0.5s, opacity 0.5s; 44 | -moz-transition: visibility 0.5s, opacity 0.5s; 45 | -ms-transition: visibility 0.5s, opacity 0.5s; 46 | -o-transition: visibility 0.5s, opacity 0.5s; 47 | transition: visibility 0.5s, opacity 0.5s; 48 | } 49 | 50 | /* Fading sytles, used to fade embed window. */ 51 | .video-js .vjs-embed-window.vjs-fade-in { 52 | display: block !important; 53 | visibility: visible; /* Needed to make sure things hide in older browsers too. */ 54 | opacity: 1; 55 | } 56 | .video-js .vjs-embed-window.vjs-fade-out { 57 | display: block !important; 58 | visibility: hidden; 59 | opacity: 0; 60 | } 61 | 62 | .video-js .vjs-embed-window .vjs-embed-title { 63 | margin-top: 0; 64 | padding: 5px 7px; 65 | background: rgba(16, 108, 136, 0.7); 66 | border-bottom: 2px solid rgba(27,201,255,0.7); 67 | color: #fff; 68 | } 69 | 70 | .video-js .vjs-embed-window textarea { 71 | width: 92%; 72 | height: 60%; 73 | margin: 0 2% 5px; 74 | padding: 2%; 75 | border: 0; 76 | background: rgba(27,201,255,0.5); 77 | color: #fff; 78 | } 79 | 80 | .video-js .vjs-embed-window .icon-remove-sign { 81 | position: absolute; 82 | top: 3px; 83 | right: 7px; 84 | 85 | cursor: pointer; 86 | 87 | font-size: 1.5em; 88 | color: #fff; 89 | } 90 | -------------------------------------------------------------------------------- /addThis/videojs.addThis.js: -------------------------------------------------------------------------------- 1 | // 2 | // Author: Brian Kelley 3 | // Description: Creates a "share" menu in the control bar. See the readme on github. 4 | // https://github.com/brianpkelley/video-js-4-plugins/blob/master/addThis/README.md 5 | // 6 | 7 | (function() { 8 | 9 | // AddThis optional parameters 10 | var pubid = false; 11 | var ct = false; 12 | var email_template = false; 13 | var share_url = false; 14 | var website_url = false; 15 | /*********************************************** 16 | * Social Item 17 | ***********************************************/ 18 | videojs.SocialItem = videojs.MenuItem.extend({ 19 | init: function(player, options){ 20 | 21 | videojs.MenuItem.call(this, player, options); 22 | if ( "embed" == options.kind ) { 23 | this.embedEl_ = new videojs.EmbedWindow(this.player(), {}); 24 | this.player().el().appendChild( this.embedEl_.el() ); 25 | } 26 | } 27 | }); 28 | 29 | videojs.SocialItem.prototype.createEl = function(type, props) { 30 | return vjs.Button.prototype.createEl.call(this, 'li', vjs.obj.merge({ 31 | className: 'vjs-menu-item', 32 | innerHTML: '' 33 | }, props)); 34 | }; 35 | 36 | videojs.SocialItem.prototype.onClick = function() { 37 | var serialize = function(obj) { 38 | var str = []; 39 | for(var p in obj) { 40 | str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); 41 | } 42 | return str.join("&"); 43 | } 44 | 45 | 46 | // Send this to AddThis.com 47 | // Available Services - http://www.addthis.com/services/list 48 | // http://support.addthis.com/customer/portal/articles/381265-addthis-sharing-endpoints 49 | // URL - http://api.addthis.com/oexchange/0.8/forward/SERVICE_TAG/offer?OPTIONS 50 | // Name Description Type Required? Example 51 | // url URL of the page being shared. string yes http://addthis.com 52 | // title Title of the page being shared. string no AddThis Home Page 53 | // description Short description of the page being shared. string no AddThis: One button. Your content everywhere. 54 | // pubid Your publisher profile ID (analytics). string no addthis 55 | // email_template Email template to use for email sharing (requires pubid param) string no my_template 56 | // ct Enable click tracking (shared page must have AddThis client code to measure clicks) string no ct=1 57 | 58 | var send = { 59 | 'url': share_url || document.location.href, 60 | 'title': document.title, 61 | 'description': 'Check out this cool video at '+document.location.href, 62 | 'pubid': pubid || null, 63 | 'email_template': email_template || null, 64 | 'ct': ct || null 65 | }; 66 | var width; 67 | var height; 68 | var kind = this.options().kind; 69 | 70 | var deserialize = function (s) { 71 | var query = {}; 72 | 73 | s.replace(/\b([^&=]*)=([^&=]*)\b/g, function (m, a, d) { 74 | if (typeof query[a] != 'undefined') { 75 | query[a] += ',' + d; 76 | } else { 77 | query[a] = d; 78 | } 79 | }); 80 | 81 | return query; 82 | } 83 | 84 | var src = this.player().currentSrc(); 85 | 86 | 87 | switch ( kind ) { 88 | // Special Cases 89 | ///////////////////////////// 90 | case 'embed': 91 | 92 | // Get current theme 93 | 94 | var pluginObj = this.player().options().plugins; 95 | var pluginStr = JSON.stringify( pluginObj ); 96 | 97 | // Change this code to suit your needs 98 | var embedCode = [ 99 | '', 100 | '', 101 | '' 105 | ].join('\n'); 106 | // Create Elements 107 | this.embedEl_.setEmbedCode( embedCode ); 108 | this.embedEl_.show(); 109 | 110 | [].slice.call( this.embedEl_.el().getElementsByTagName('textarea') )[0].select(); 111 | 112 | break; 113 | case 'link': 114 | if ( website_url ) { 115 | window.open(website_url, 'Website'); 116 | } 117 | break; 118 | case 'more': 119 | width = width || 550; 120 | height = height || 450; 121 | window.open('http://api.addthis.com/oexchange/0.8/offer??'+serialize(send), 'AddThis', 'height='+height+',width='+width+',modal=yes,alwaysRaised=yes'); 122 | break; 123 | 124 | 125 | 126 | 127 | // AddThis.com Forward Share API 128 | //////////////////////////////////////// 129 | 130 | case 'facebook': 131 | width = width || 550; 132 | height = height || 270; 133 | // Fall through 134 | case 'twitter': 135 | width = width || 550; 136 | height = height || 260; 137 | send.text = send.description.replace(/\shttp\:\/\/.*$/gi, ''); 138 | // Fall through 139 | case 'email': 140 | width = width || 550; 141 | height = height || 700; 142 | // Fall through 143 | default: 144 | width = width || 550; 145 | height = height || 450; 146 | window.open('http://api.addthis.com/oexchange/0.8/forward/'+kind+'/offer?'+serialize(send), 'AddThis', 'height='+height+',width='+width+',modal=yes,alwaysRaised=yes'); 147 | // http://support.addthis.com/customer/portal/articles/381265-addthis-sharing-endpoints 148 | // http://www.addthis.com/services/list 149 | } 150 | 151 | // This can be and is caught in the googleAnalytics Plugin 152 | videojs.trigger(this.player().el(),{type: 'socialclick', target: this.player().el(), kind: kind}); 153 | 154 | }; 155 | 156 | /*********************************************** 157 | * Social Menu Button 158 | ***********************************************/ 159 | videojs.SocialButton = videojs.MenuButton.extend({ 160 | init: function(player, options){ 161 | videojs.MenuButton.call(this, player, options); 162 | 163 | if ( this.items.length > 4 ) { 164 | this.menu.contentEl().style.width = "15em"; 165 | this.menu.contentEl().style.left = "-7.5em"; 166 | } 167 | 168 | 169 | this.on('click', this.onClick); 170 | } 171 | }); 172 | 173 | 174 | videojs.SocialButton.prototype.options_ = { 175 | facebook: true, 176 | twitter: true, 177 | googleplus: true, 178 | linkedin: true, 179 | pinterest: true, 180 | delicious: false, 181 | reddit: false, 182 | email: true, 183 | embed: false, 184 | //link: false, 185 | more: true 186 | }; 187 | 188 | videojs.SocialButton.prototype.available = { 189 | facebook: { 190 | 'label': 'Facebook', 191 | 'kind': 'facebook', 192 | 'iconClass': 'facebook' 193 | }, 194 | twitter: { 195 | 'label': 'Twitter', 196 | 'kind': 'twitter', 197 | 'iconClass': 'twitter' 198 | }, 199 | googleplus: { 200 | 'label': 'Google+', 201 | 'kind': 'google_plusone_share', 202 | 'iconClass': 'google-plus' 203 | }, 204 | linkedin: { 205 | 'label': 'LinkedIn+', 206 | 'kind': 'linkedin', 207 | 'iconClass': 'linkedin' 208 | }, 209 | pinterest: { 210 | 'label': 'Pinterest+', 211 | 'kind': 'pinterest', 212 | 'iconClass': 'pinterest' 213 | }, 214 | delicious: { 215 | 'label': 'Delicious', 216 | 'kind': 'delicious', 217 | 'iconClass': 'delicious' 218 | }, 219 | reddit: { 220 | 'label': 'Reddit', 221 | 'kind': 'reddit', 222 | 'iconClass': 'reddit' 223 | }, 224 | more: { 225 | 'label': 'More Services', 226 | 'kind': 'more', 227 | 'iconClass': 'plus' 228 | }, 229 | email: { 230 | 'label': 'Email', 231 | 'kind': 'email', 232 | 'iconClass': 'envelope' 233 | }, 234 | embed: { 235 | 'label': 'Embed', 236 | 'kind': 'embed', 237 | 'iconClass': 'code' 238 | }, 239 | website_url: { 240 | 'label': 'Link', 241 | 'kind': 'link', 242 | 'iconClass': 'globe' 243 | }, 244 | }; 245 | 246 | videojs.SocialButton.prototype.buttonText = 'Social'; 247 | /*videojs.SocialButton.prototype.createEl = function( props ) { 248 | return videojs.Component.prototype.createEl('div', { 249 | //className: 'vjs-social-button vjs-control vjs-menu-button '', 250 | //innerHTML: '
' + ('Social') + '
', 251 | role: 'button', 252 | 'aria-live': 'polite', // let the screen reader user know that the text of the button may change 253 | tabIndex: 0 254 | }); 255 | };*/ 256 | vjs.SocialButton.prototype.buildCSSClass = function(){ 257 | return 'vjs-social-button vjs-control icon-share ' + vjs.MenuButton.prototype.buildCSSClass.call(this); 258 | }; 259 | 260 | 261 | /** 262 | * Override default 263 | */ 264 | videojs.SocialButton.prototype.onClick = function() {}; 265 | 266 | /** 267 | * Responsible for creating the vjs.SocialItems to add to the menu 268 | */ 269 | videojs.SocialButton.prototype.createItems = function(){ 270 | var items = [], track; 271 | var options = this.options(); 272 | 273 | for ( var item in this.available ) { 274 | if ( this.available.hasOwnProperty( item ) && options[item] ) { 275 | items.push(new videojs.SocialItem(this.player_, this.available[item] )); 276 | } 277 | } 278 | 279 | return items; 280 | }; 281 | 282 | 283 | /*********************************************** 284 | * Embed window to grab the code 285 | ***********************************************/ 286 | videojs.EmbedWindow = videojs.Component.extend({ 287 | /** @constructor */ 288 | init: function(player, options){ 289 | videojs.Component.call(this, player, options); 290 | this.hide(); 291 | 292 | this.exitEl_ = new videojs.ExitButton(player,{}); 293 | this.exitEl_.on('click', videojs.bind(this, function() { 294 | this.hide(); 295 | })); 296 | this.el_.appendChild( this.exitEl_.el() ); 297 | 298 | this.textAreaEl_ = document.createElement('textarea'); 299 | this.textAreaEl_.style.fontSize = "10px"; 300 | if ( options.embedCode ) { 301 | this.setEmbedCode( options.embedCode ); 302 | } 303 | 304 | this.el_.appendChild( this.textAreaEl_ ); 305 | }, 306 | 307 | setEmbedCode: function(embedCode) { 308 | this.textAreaEl_.value = embedCode || ""; 309 | } 310 | }); 311 | 312 | videojs.EmbedWindow.prototype.createEl = function(player,options) { 313 | return videojs.Component.prototype.createEl(player, { 314 | className: 'vjs-embed-window ', 315 | innerHTML: '

Embed Code

', 316 | 'aria-live': 'polite', // let the screen reader user know that the text of the button may change 317 | tabIndex: 0 318 | }); 319 | } 320 | 321 | videojs.ExitButton = videojs.Button.extend({ 322 | /** @constructor */ 323 | init: function(player, options){ 324 | videojs.Component.call(this, player, options); 325 | } 326 | }); 327 | 328 | videojs.ExitButton.prototype.createEl = function(player,options) { 329 | return videojs.Component.prototype.createEl(player,{ 330 | className: 'vjs-button icon-remove-sign', 331 | innerHTML: '', 332 | role: 'button', 333 | 'aria-live': 'polite', // let the screen reader user know that the text of the button may change 334 | tabIndex: 0, 335 | style: 'font-size: 10px' 336 | }); 337 | } 338 | videojs.ExitButton.prototype.onClick = function() {}; 339 | 340 | 341 | 342 | 343 | 344 | // Note that we're not doing this in prototype.createEl() because 345 | // it won't be called by Component.init (due to name obfuscation). 346 | var createSocialButton = function(options) { 347 | var props = { 348 | className: 'vjs-social-button vjs-control vjs-menu-button icon-share', 349 | innerHTML: '
' + ('Social') + '
', 350 | role: 'button', 351 | 'aria-live': 'polite', // let the screen reader user know that the text of the button may change 352 | tabIndex: 0 353 | }; 354 | return videojs.Component.prototype.createEl(null, props); 355 | }; 356 | 357 | var social; 358 | videojs.plugin('addThis', function(options) { 359 | options = options || {}; 360 | 361 | if ( options.includeFontAwesome || options.includeFontAwesome === undefined ) { 362 | var tempLink = document.createElement('link'); 363 | tempLink.href = '//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css'; 364 | tempLink.rel = 'stylesheet'; 365 | document.getElementsByTagName('head')[0].appendChild( tempLink ); 366 | } 367 | 368 | if ( options.pubid ) { 369 | pubid = options.pubid; 370 | } 371 | if ( options.ct ) { 372 | ct = options.ct; 373 | } 374 | if ( options.email_template ) { 375 | email_template = options.email_template; 376 | } 377 | if ( options.share_url ) { 378 | share_url = options.share_url; 379 | } 380 | if ( options.website_url && options.website_url != /http(s)?:\/\//.test(options.website_url) && options.website_url != "") { 381 | website_url = options.website_url; 382 | } else { 383 | delete options.website_url; 384 | } 385 | 386 | var optionsClone = JSON.parse(JSON.stringify(options)); 387 | optionsClone.el = createSocialButton(options); 388 | 389 | 390 | social = this.controlBar.addChild( 'socialButton', options ); 391 | }); 392 | })(); -------------------------------------------------------------------------------- /automute/automute.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Automute/restart auto plays the player but muted. 3 | * @author Brian Kelley 4 | */ 5 | 6 | 7 | (function() { 8 | videojs.plugin('automute', automute); 9 | 10 | /** @namespace plugins.autoMuteRestart */ 11 | /** 12 | * Function responsible for auto playing and muting the player when a video loads. 13 | * Applies the classes "vjs-automute" and "vjs-automute-restart" to the videojs.bigPlayButton. 14 | * Once a user interacts with the player either by click on the bigPlayButton or by loading a new video, these classes are removed. 15 | * 16 | * @plugindesc Auto plays the plugin in a muted state. Can either play from current location or restart upon user interaction. 17 | * 18 | * @function automute 19 | * @memberof plugins.autoMuteRestart 20 | * @param {Object} [options] Specifies the options to overwrite. 21 | * @param {Boolean} [options.restart=false] Should the player restart when unmuted / played. 22 | */ 23 | function automute( options ) { 24 | 25 | options = videojs.obj.merge( { restart: false }, options ); 26 | 27 | var unMute, onLoadFn, onPauseFn, playFn, initialized; 28 | 29 | initialized = false; 30 | 31 | function removeAutomute () { 32 | //console.log( "begin removeAutomute" ); 33 | setTimeout(videojs.bind( this, function() { this.muted(false); } ), 0 ); 34 | videojs.addClass( this.el(), 'vjs-has-started' ); 35 | videojs.removeClass( this.bigPlayButton.el(), 'vjs-automute' ); 36 | videojs.removeClass( this.bigPlayButton.el(), 'vjs-automute-restart' ); 37 | this.bigPlayButton.hide(); 38 | 39 | this.off( 'play', playFn ); 40 | this.off( 'loadstart', unMute ); 41 | //this.off( 'pause', onPauseFn ); 42 | this.bigPlayButton.off( 'click', onPauseFn ); 43 | this.tech.off( 'mousedown', onPauseFn ); 44 | // Clear off any events that may be left over 45 | this.tech.off( 'mousedown', this.tech.onClick ); 46 | this.tech.on( 'mousedown', this.tech.onClick ); 47 | // console.log( "end removeAutomute" ); 48 | } 49 | 50 | onPauseFn = videojs.bind( this, function( e ) { 51 | // console.log( "onPause" ); 52 | e.stopImmediatePropagation(); 53 | if ( this.currentTime() == this.duration() ) { 54 | return; 55 | } 56 | 57 | 58 | if ( options.restart ) { 59 | this.trigger({type:'restartunmute'}); 60 | this.currentTime(0); 61 | } else { 62 | this.trigger({type:'autoplayunmute'}); 63 | } 64 | 65 | //this.play(); 66 | unMute(); 67 | }); 68 | 69 | // Setup the actions to un-automute the player only once the automute has been established 70 | unMute = videojs.bind( this, removeAutomute ); 71 | 72 | onLoadFn = videojs.bind( this, function() { 73 | // console.log( "onLoad" ); 74 | unMute(); 75 | }); 76 | 77 | 78 | 79 | playFn = videojs.bind(this, function() { 80 | 81 | this.muted(true); 82 | 83 | videojs.removeClass( this.el(), 'vjs-has-started' ); 84 | videojs.removeClass( this.el(), 'vjs-playing' ); 85 | 86 | 87 | this.bigPlayButton.show(); 88 | 89 | videojs.addClass( this.bigPlayButton.el(), 'vjs-automute' ); 90 | if ( options.restart ) { 91 | videojs.addClass( this.bigPlayButton.el(), 'vjs-automute-restart' ); 92 | } 93 | 94 | if ( initialized ) { 95 | return; 96 | } 97 | 98 | initialized = true; 99 | 100 | // They clicked the big play button 101 | this.bigPlayButton.one( 'click', onPauseFn); 102 | // Which paused it 103 | this.tech.one('mousedown', onPauseFn); 104 | this.tech.off('mousedown', this.tech.onClick ); 105 | 106 | 107 | // Will the playlist auto load the next item? 108 | if ( typeof this.playlist === 'object' && this.playlist.options().autoAdvance ) { 109 | //this.one( 'ended', function() {console.log( 'ended' ); }); 110 | this.one( 'playlistload', unMute ); 111 | } else { 112 | this.one( 'loadstart', unMute ); 113 | } 114 | 115 | }); 116 | 117 | this.on( 'play', playFn ); 118 | 119 | // Set autoplay and mute 120 | this.options_.autoplay = true; 121 | this.options_.automute = true; 122 | if ( options.restart ) { 123 | this.options_.automuterestart = true; 124 | } 125 | this.autoplay( true ); 126 | 127 | 128 | } 129 | })(); -------------------------------------------------------------------------------- /automute/automute.less: -------------------------------------------------------------------------------- 1 | .video-js .vjs-big-play-button.vjs-automute:before { 2 | content: "\e006"; 3 | font-size: .8em; 4 | line-height: 3.3em; 5 | z-index: 100; 6 | } 7 | 8 | .video-js .vjs-big-play-button.vjs-automute-restart:after { 9 | font-family: FontAwesome; 10 | font-weight: normal; 11 | font-style: normal; 12 | text-decoration: inherit; 13 | -webkit-font-smoothing: antialiased; 14 | content: "\f021"; 15 | 16 | height: 100%; 17 | width: 100%; 18 | line-height: 1.13em; 19 | font-size: 2.35em; 20 | opacity: .3; 21 | z-index: 50; 22 | } -------------------------------------------------------------------------------- /callToAction/callToAction.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | videojs.CallToAction = videojs.Component.extend({ 5 | init: function( player, options ) { 6 | var addButton = false; 7 | if ( options.el && options.el.nodeType === 1) { 8 | this.contentEl_ = options.el; 9 | delete options.el; 10 | } else { 11 | addButton = true; 12 | } 13 | 14 | videojs.Component.call( this, player, options ); 15 | 16 | if ( addButton ) { 17 | this.contentEl_ = this.callToActionContainer_; 18 | this.callToAction_ = this.addChild( 'callToActionButton', this.options_.link ); 19 | this.exitButton.on( 'click', videojs.bind( this, function() { 20 | this.player_.trigger({type: 'calltoactionclose', actionTime: this.getTime() }); 21 | this.conceal(); 22 | }) ); 23 | 24 | this.callToAction_.on('click', videojs.bind(this, function() { 25 | this.player_.trigger({type: 'calltoaction', actionTime: this.getTime() }); 26 | })); 27 | } 28 | 29 | this.timerDisplay.length( this.options_.timer ); 30 | 31 | this.player_.on( 'ended', videojs.bind( this, this.reveal ) ); 32 | 33 | 34 | this.on('click', function(e) { 35 | e.stopImmediatePropagation(); 36 | }); 37 | 38 | // Do we have a playlist and does it autoAdvance? 39 | this.playlistAutoAdvance = false; 40 | this.playlistCheckTimer = setTimeout( videojs.bind( this, this.playlistCheck ), 1 ); 41 | } 42 | }); 43 | 44 | 45 | videojs.CallToAction.prototype.createEl = function() { 46 | var el = videojs.Component.prototype.createEl(null, { 47 | className: 'vjs-call-to-action ', 48 | }); 49 | 50 | if ( this.contentEl_ && this.contentEl_.nodeType === 1 ) { 51 | el.appendChild( this.contentEl_ ); 52 | } else { 53 | this.title_ = videojs.createEl('h2',{ 54 | innerHTML: this.options_.title 55 | }); 56 | this.message_ = videojs.createEl('p',{ 57 | innerHTML: this.options_.text 58 | }); 59 | this.callToActionContainer_ = videojs.createEl('div', { 60 | className: 'link-container' 61 | }); 62 | /*this.callToAction_ = videojs.createEl('a',{ 63 | innerHTML: this.options_.link.text, 64 | href: this.options_.link.url, 65 | target: '_blank', 66 | name: 'callToAction' 67 | });*/ 68 | 69 | //this.callToActionContainer_.appendChild( this.callToAction_ ); 70 | 71 | el.appendChild( this.title_ ); 72 | el.appendChild( this.message_ ); 73 | el.appendChild( this.callToActionContainer_ ); 74 | } 75 | 76 | 77 | return el; 78 | }; 79 | 80 | videojs.CallToAction.prototype.options_ = { 81 | title: '', 82 | text: '', 83 | link: { 84 | url: '', 85 | text: '' 86 | }, 87 | el: null, 88 | timer: 30, 89 | children: { 90 | exitButton: {}, 91 | timerDisplay: { 92 | descriptionText: "Time till next item:", 93 | timeLabel: "s" 94 | } 95 | } 96 | }; 97 | 98 | videojs.CallToAction.prototype.playlistCheck = function() { 99 | if ( this.player_.playlist && this.player_.playlist.autoAdvanceFn ) { 100 | this.playlistAutoAdvance = true; 101 | this.autoAdvanceFn = this.player_.playlist.autoAdvanceFn; 102 | 103 | videojs.off( this.player().el(), 'ended', this.player_.playlist.autoAdvanceFn ); 104 | 105 | this.timerDisplay.on( 'complete', videojs.bind( this, this.timerComplete ) ); 106 | //this.player_.autoplay( false ); 107 | } else { 108 | this.timerDisplay.hide(); 109 | } 110 | 111 | }; 112 | 113 | videojs.CallToAction.prototype.reveal = function () { 114 | this.show(); 115 | 116 | if ( this.playlistAutoAdvance ) { 117 | // Load next item 118 | //this.player_.playlist.loadNext(); 119 | this.player_.pause(); 120 | // Show the timer 121 | this.timerDisplay.show(); 122 | // Start the display timer 123 | this.timerDisplay.start(); 124 | /* 125 | this.displayTime = this.options_.timer; 126 | this.displayTimerEl_.innerHTML = this.displayTime + " seconds"; 127 | */ 128 | } 129 | }; 130 | 131 | 132 | 133 | videojs.CallToAction.prototype.conceal = function() { 134 | this.hide(); 135 | this.timerDisplay.cancel(); 136 | }; 137 | 138 | 139 | videojs.CallToAction.prototype.timerComplete = function() { 140 | this.hide(); 141 | videojs.bind( this.player_.playlist, this.autoAdvanceFn )(); 142 | }; 143 | 144 | videojs.CallToAction.prototype.getTime = function() { 145 | this.timerDisplay.time_; 146 | }; 147 | 148 | 149 | 150 | 151 | 152 | videojs.CallToActionButton = videojs.Button.extend({ 153 | init: function( player, options ) { 154 | videojs.Button.call(this, player, options); 155 | this.name_ = "callToActionButton"; 156 | } 157 | }); 158 | videojs.CallToActionButton.prototype.createEl = function() { 159 | var props = { 160 | className: '', 161 | innerHTML: this.options_.text, 162 | role: 'button', 163 | 'aria-live': 'polite', // let the screen reader user know that the text of the button may change 164 | tabIndex: 0 165 | }; 166 | var el = videojs.Component.prototype.createEl('a', props); 167 | 168 | el.style.cursor = "pointer"; 169 | 170 | return el; 171 | }; 172 | videojs.CallToActionButton.prototype.onClick = function() { 173 | if ( this.options_.url ) { 174 | window.open(this.options_.url, 'CallToAction'); 175 | } 176 | }; 177 | 178 | 179 | 180 | 181 | 182 | 183 | if ( !videojs.ExitButton ) { 184 | /** 185 | * Exit button. 186 | * @class 187 | * @construtor 188 | * @param {vjs.Player|Object} player 189 | * @param {Object} options 190 | * @extends vjs.Button 191 | */ 192 | videojs.ExitButton = videojs.Button.extend({ 193 | init: function(player, options){ 194 | 195 | videojs.Component.call(this, player, options); 196 | } 197 | }); 198 | videojs.ExitButton.prototype.buttonText = "Exit"; 199 | videojs.ExitButton.prototype.buildCSSClass = function(){ 200 | // TODO: Change vjs-control to vjs-button? 201 | return 'vjs-control vjs-exit-button icon-remove-sign ' + vjs.Component.prototype.buildCSSClass.call(this); 202 | }; 203 | videojs.ExitButton.prototype.onClick = function() {}; 204 | } 205 | 206 | if ( !videojs.PauseButton ) { 207 | /** 208 | * Pause button. 209 | * @class 210 | * @construtor 211 | * @param {vjs.Player|Object} player 212 | * @param {Object} options 213 | * @extends vjs.Button 214 | */ 215 | videojs.PauseButton = videojs.Button.extend({ 216 | init: function(player, options){ 217 | videojs.Component.call(this, player, options); 218 | } 219 | }); 220 | videojs.PauseButton.prototype.buttonText = "Pause"; 221 | videojs.PauseButton.prototype.buildCSSClass = function(){ 222 | // TODO: Change vjs-control to vjs-button? 223 | return 'vjs-control vjs-pause-button icon-pause ' + vjs.Component.prototype.buildCSSClass.call(this); 224 | }; 225 | videojs.PauseButton.prototype.onClick = function() {}; 226 | } 227 | 228 | 229 | /** 230 | * Timer Display. 231 | * @class 232 | * @construtor 233 | * @param {vjs.Player|Object} player 234 | * @param {Object} options 235 | * @extends vjs.Component 236 | */ 237 | videojs.TimerDisplay = videojs.Component.extend({ 238 | init: function(player, options){ 239 | videojs.Component.call(this, player, options); 240 | this.pauseButton.on( 'click', videojs.bind( this, this.cancel ) ); 241 | } 242 | }); 243 | 244 | videojs.TimerDisplay.prototype.options_ = { 245 | descriptionText: '', 246 | timeLabel: 'seconds', 247 | children: { 248 | pauseButton: {} 249 | } 250 | }; 251 | 252 | videojs.TimerDisplay.prototype.createEl = function() { 253 | 254 | var el = videojs.Component.prototype.createEl(null, { 255 | className: this.buildCSSClass() 256 | }); 257 | 258 | this.descriptionText_ = videojs.Component.prototype.createEl( 'span', { 259 | innerHTML: this.options_.descriptionText 260 | }); 261 | 262 | this.timerText_ = videojs.Component.prototype.createEl( 'span', { 263 | className: 'vjs-time-left' 264 | }); 265 | 266 | el.appendChild( this.descriptionText_ ); 267 | el.appendChild( this.timerText_ ); 268 | return el; 269 | }; 270 | videojs.TimerDisplay.prototype.buildCSSClass = function(){ 271 | // TODO: Change vjs-control to vjs-button? 272 | return 'vjs-display-timer ' + vjs.Component.prototype.buildCSSClass.call(this); 273 | }; 274 | 275 | videojs.TimerDisplay.prototype.length = function() { 276 | if ( arguments.length ) { 277 | this.options_.length = arguments[0]; 278 | } 279 | return this.options_.length; 280 | }; 281 | 282 | videojs.TimerDisplay.prototype.start = function() { 283 | this.clear(); 284 | this.time_ = this.options_.length; 285 | this.play(); 286 | }; 287 | videojs.TimerDisplay.prototype.play = function() { 288 | this.update(); 289 | this.timer_ = setInterval( videojs.bind( this, this.update ), 1000 ); 290 | }; 291 | videojs.TimerDisplay.prototype.pause = function() { 292 | this.clear(); 293 | }; 294 | videojs.TimerDisplay.prototype.cancel = function() { 295 | this.clear(); 296 | this.time_ = 0; 297 | this.hide(); 298 | }; 299 | 300 | videojs.TimerDisplay.prototype.clear = function() { 301 | clearInterval( this.timer_ ); 302 | }; 303 | 304 | videojs.TimerDisplay.prototype.update = function() { 305 | this.timerText_.innerHTML = this.time_ + this.options_.timeLabel; 306 | this.time_--; 307 | 308 | if ( this.time_ <= 0 ) { 309 | this.clear(); 310 | this.trigger( 'complete', {} ); 311 | } 312 | 313 | }; 314 | })(); 315 | 316 | 317 | /** 318 | * @namespace plugins.callToAction 319 | */ 320 | /** 321 | * Displays a logo as a control bar button. Can be used to open a link in a new window. 322 | * 323 | * @memberof plugins.callToAction 324 | * @function callToAction 325 | * @param {Object} options Options object. 326 | * @param {String} [options.title] Title of the call to action slide. 327 | * @param {String} [options.text] A short message to include on the call to action slide. 328 | * @param {Object} [options.link] Object containing the link url and text. 329 | * @param {String} [options.link.url] The url for the call to action link. 330 | * @param {String} [options.link.text] The text to display on the call to action button. 331 | * @param {String|Element} [options.el] Either the id of the an element to use as the call to action slide, or a reference to the element. 332 | */ 333 | (function() { 334 | videojs.plugin('callToAction', function( options ) { 335 | 336 | options = options || {}; 337 | if ( (!options.link || !options.title) && !options.el ) { 338 | return; 339 | } 340 | 341 | if ( options.el ) { 342 | if ( typeof options.el === "string" && document.getElementById( options.el.replace('#','') ) ) { 343 | options.el = document.getElementById( options.el.replace('#','') ); 344 | this.callToAction = this.addChild('callToAction', options ); 345 | } else if ( options.el.nodeType === 1) { 346 | // We have a node, this node will be shown at the end of the video. 347 | this.callToAction = this.addChild('callToAction', options ); 348 | } else { 349 | console.warn( "VideoJs.CallToAction Aborting: Invalid element specified, neither html element or element id" ); 350 | } 351 | } else { 352 | // We don't have a node, we need to create one 353 | this.callToAction = this.addChild('callToAction', options ); 354 | } 355 | 356 | 357 | 358 | 359 | }); 360 | })(); 361 | -------------------------------------------------------------------------------- /callToAction/callToAction.less: -------------------------------------------------------------------------------- 1 | .vjs-call-to-action { 2 | background: rgba(25,25,25,.6); 3 | display: none; 4 | 5 | width: 100%; 6 | height: 100%; 7 | 8 | z-index: 1000; 9 | position: absolute; 10 | top: 0; 11 | left: 0; 12 | 13 | 14 | 15 | h2 { 16 | font-size: 32px; 17 | color: #fff; 18 | text-align: center; 19 | } 20 | 21 | p { 22 | margin: 1em; 23 | font-size: 18px; 24 | text-align: center; 25 | } 26 | 27 | .link-container { 28 | text-align: center; 29 | width: 100%; 30 | 31 | position: absolute; 32 | bottom: 75px; 33 | 34 | a { 35 | display: inline-block; 36 | 37 | padding: .5em 1em; 38 | 39 | font-size: 3em; 40 | font-weight: bold; 41 | 42 | text-align: center; 43 | text-decoration: none; 44 | 45 | color: #fff; 46 | 47 | background: #e48f2f; 48 | 49 | -webkit-box-shadow: 0 5px 0 0 rgba(234, 98, 1, 1), 0 5px 15px 0 rgba(0,0,0,1); 50 | box-shadow: 0 5px 0 0 rgba(234, 98, 1, 1), 0 5px 15px 0 rgba(0,0,0,1); 51 | 52 | border-radius: 15px; 53 | 54 | &:hover { 55 | margin-top: 1px; 56 | -webkit-box-shadow: 0 4px 0 0 rgba(234, 98, 1, 1), 0 4px 13px 0 rgba(0,0,0,1); 57 | box-shadow: 0 4px 0 0 rgba(234, 98, 1, 1), 0 4px 13px 0 rgba(0,0,0,1); 58 | } 59 | } 60 | } 61 | 62 | 63 | .vjs-control { 64 | 65 | width: 2em; 66 | height: 1.5em; 67 | 68 | &.vjs-exit-button { 69 | position: absolute; 70 | top: 10px; 71 | right: 10px; 72 | font-size: 20px; 73 | cursor: pointer; 74 | color: #fff; 75 | } 76 | 77 | &.vjs-pause-button { 78 | float: none; 79 | display: inline-block; 80 | &:before { 81 | position: static; 82 | display: inline-block; 83 | width: auto; 84 | height: auto; 85 | } 86 | } 87 | } 88 | 89 | 90 | 91 | .vjs-display-timer { 92 | position: absolute; 93 | bottom: 30px; 94 | right: 10px; 95 | color: #aaa; 96 | 97 | span { 98 | font-weight: normal; 99 | font-size: 14px; 100 | } 101 | 102 | .vjs-time-left { 103 | font-weight: bold; 104 | font-size: 20px; 105 | color: #fff; 106 | width: 50px; 107 | text-align: right; 108 | display: inline-block; 109 | } 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /dimTheLights/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Usage 3 | 4 | ### HTML: 5 | ``` 6 |