├── test ├── unit │ ├── control-bar.js │ ├── setup.js │ ├── tracks.js │ ├── menu.js │ ├── util.js │ ├── test-helpers.js │ ├── core.js │ ├── poster.js │ ├── mediafaker.js │ ├── core-object.js │ ├── controls.js │ ├── media.html5.js │ ├── flash.js │ ├── events.js │ ├── plugins.js │ ├── component.js │ ├── api.js │ └── lib.js ├── karma-qunit-shim.js ├── minified.html ├── minified-api.html ├── qunit-externs.js ├── index.html └── karma.conf.js.example ├── .travis.yml ├── src ├── css │ ├── font │ │ ├── vjs.eot │ │ ├── vjs.ttf │ │ ├── vjs.woff │ │ └── vjs.svg │ ├── video-js.png │ ├── video-js.fw.png │ └── video-js.font.dev.svg └── js │ ├── plugins.js │ ├── media │ ├── flash.externs.js │ ├── loader.js │ └── media.js │ ├── big-play-button.js │ ├── control-bar │ ├── live-display.js │ ├── control-bar.js │ ├── fullscreen-toggle.js │ ├── play-toggle.js │ ├── volume-menu-button.js │ ├── mute-toggle.js │ ├── volume-control.js │ ├── time-display.js │ └── progress-control.js │ ├── util.js │ ├── loading-spinner.js │ ├── cdn.js │ ├── setup.js │ ├── poster.js │ ├── json.js │ ├── button.js │ ├── player.externs.js │ ├── core.js │ ├── core-object.js │ ├── menu.js │ ├── slider.js │ └── exports.js ├── .npmignore ├── .editorconfig ├── bower.json ├── .gitignore ├── docs ├── api │ ├── vjs.media.md │ ├── vjs.JSON.md │ ├── vjs.CoreObject.md │ └── vjs.md ├── guides │ ├── skins.md │ ├── components.md │ ├── api.md │ ├── plugins.md │ ├── glossary.md │ ├── tech.md │ ├── options.md │ └── setup.md └── index.md ├── LICENSE ├── component.json ├── browsers.json ├── .bunyipconfig.js.example ├── .jshintrc ├── README.md ├── sandbox ├── index.html.example └── plugin.html.example └── package.json /test/unit/control-bar.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/unit/setup.js: -------------------------------------------------------------------------------- 1 | module('Setup'); 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.8 -------------------------------------------------------------------------------- /src/css/font/vjs.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/em/video.js/master/src/css/font/vjs.eot -------------------------------------------------------------------------------- /src/css/font/vjs.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/em/video.js/master/src/css/font/vjs.ttf -------------------------------------------------------------------------------- /src/css/font/vjs.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/em/video.js/master/src/css/font/vjs.woff -------------------------------------------------------------------------------- /src/css/video-js.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/em/video.js/master/src/css/video-js.png -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Exclude everything but the contents of the dist directory. 2 | **/* 3 | !dist/** 4 | -------------------------------------------------------------------------------- /src/css/video-js.fw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/em/video.js/master/src/css/video-js.fw.png -------------------------------------------------------------------------------- /test/karma-qunit-shim.js: -------------------------------------------------------------------------------- 1 | var fixture = document.createElement('div'); 2 | fixture.id = 'qunit-fixture'; 3 | document.body.appendChild(fixture); 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org - unify code style 2 | # plugins for text editors: editorconfig.org/#download 3 | root = true 4 | 5 | [*] 6 | indent_style = space 7 | indent_size = 2 8 | end_of_line = lf 9 | charset = utf-8 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true -------------------------------------------------------------------------------- /src/js/plugins.js: -------------------------------------------------------------------------------- 1 | /** 2 | * the method for registering a video.js plugin 3 | * 4 | * @param {String} name The name of the plugin 5 | * @param {Function} init The function that is run when the player inits 6 | */ 7 | vjs.plugin = function(name, init){ 8 | vjs.Player.prototype[name] = init; 9 | }; 10 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "video.js", 3 | "description": "An HTML5 and Flash video player with a common API and skin for both.", 4 | "version": "4.5.2", 5 | "main": [ 6 | "dist/video-js/video.js", 7 | "dist/video-js/video-js.css" 8 | ], 9 | "keywords": [ 10 | "videojs", 11 | "html5", 12 | "flash", 13 | "video", 14 | "player" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | dist/* 3 | build/files/* 4 | docs/api/* 5 | dev.html 6 | projects 7 | .zenflow-log 8 | test/*.map 9 | .bunyipconfig.js 10 | .s3config.json 11 | 12 | node_modules 13 | npm-debug.log 14 | 15 | sandbox/* 16 | !sandbox/*.example 17 | 18 | # ignore any Karma conf.js files in the test/ directory 19 | test/*.conf.js 20 | 21 | *.swp 22 | *.swo 23 | 24 | *.orig 25 | 26 | *results.xml 27 | *.log 28 | -------------------------------------------------------------------------------- /docs/api/vjs.media.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # vjs.media 4 | 5 | 6 | --- 7 | 8 | ## INDEX 9 | 10 | - [UNDEFINED](#undefined) 11 | - [ApiMethods](#apimethods) 12 | 13 | --- 14 | 15 | ## UNDEFINED 16 | 17 | ### ApiMethods 18 | > List of default API methods for any MediaTechController 19 | 20 | _defined in_: [src/js/media/media.js#L168](https://github.com/videojs/video.js/blob/master/src/js/media/media.js#L168) 21 | 22 | --- 23 | 24 | -------------------------------------------------------------------------------- /test/unit/tracks.js: -------------------------------------------------------------------------------- 1 | module('Tracks'); 2 | 3 | test('should place title list item into ul', function() { 4 | var player, chaptersButton; 5 | 6 | player = PlayerTest.makePlayer(); 7 | 8 | chaptersButton = new vjs.ChaptersButton(player); 9 | 10 | var menuContentElement = chaptersButton.el().getElementsByTagName('UL')[0]; 11 | var titleElement = menuContentElement.children[0]; 12 | 13 | ok(titleElement.innerHTML === 'Chapters', 'title element placed in ul'); 14 | 15 | player.dispose(); 16 | }); -------------------------------------------------------------------------------- /test/unit/menu.js: -------------------------------------------------------------------------------- 1 | module('MenuButton'); 2 | 3 | test('should place title list item into ul', function() { 4 | var player, menuButton; 5 | 6 | player = PlayerTest.makePlayer(); 7 | 8 | menuButton = new vjs.MenuButton(player, { 9 | 'title': 'testTitle' 10 | }); 11 | 12 | var menuContentElement = menuButton.el().getElementsByTagName('UL')[0]; 13 | var titleElement = menuContentElement.children[0]; 14 | 15 | ok(titleElement.innerHTML === 'TestTitle', 'title element placed in ul'); 16 | 17 | player.dispose(); 18 | }); -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2013 Brightcove, Inc. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /docs/api/vjs.JSON.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # vjs.JSON 4 | 5 | 6 | --- 7 | 8 | ## INDEX 9 | 10 | - [METHODS](#methods) 11 | - [parse](#parse-text-reviver-) 12 | 13 | --- 14 | 15 | ## METHODS 16 | 17 | ### parse( text, [reviver] ) 18 | > parse the json 19 | 20 | ##### PARAMETERS: 21 | * __text__ `String` The JSON string to parse 22 | * __reviver__ `Function` _(OPTIONAL)_ Optional function that can transform the results 23 | 24 | ##### RETURNS: 25 | * `Object|Array` The parsed JSON 26 | 27 | _defined in_: [src/js/json.js#L34](https://github.com/videojs/video.js/blob/master/src/js/json.js#L34) 28 | 29 | --- 30 | 31 | -------------------------------------------------------------------------------- /component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "video.js", 3 | "description": "An HTML5 and Flash video player with a common API and skin for both.", 4 | "version": "4.5.2", 5 | "keywords": [ 6 | "videojs", 7 | "html5", 8 | "flash", 9 | "video", 10 | "player" 11 | ], 12 | "scripts": ["dist/video-js/video.dev.js"], 13 | "styles": ["dist/video-js/video-js.css"], 14 | "files": ["dist/video-js/video-js.swf"], 15 | "fonts": [ 16 | "dist/video-js/font/vjs.eot", 17 | "dist/video-js/font/vjs.svg", 18 | "dist/video-js/font/vjs.ttf", 19 | "dist/video-js/font/vjs.woff" 20 | ], 21 | "main": "dist/video-js/video.dev.js" 22 | } 23 | -------------------------------------------------------------------------------- /test/unit/util.js: -------------------------------------------------------------------------------- 1 | module('util'); 2 | 3 | test('should merge options objects', function(){ 4 | var ob1, ob2, ob3; 5 | 6 | ob1 = { 7 | a: true, 8 | b: { b1: true, b2: true, b3: true }, 9 | c: true 10 | }; 11 | 12 | ob2 = { 13 | // override value 14 | a: false, 15 | // merge sub-option values 16 | b: { b1: true, b2: false, b4: true }, 17 | // add new option 18 | d: true 19 | }; 20 | 21 | ob3 = vjs.util.mergeOptions(ob1, ob2); 22 | 23 | deepEqual(ob3, { 24 | a: false, 25 | b: { b1: true, b2: false, b3: true, b4: true }, 26 | c: true, 27 | d: true 28 | }, 'options objects merged correctly'); 29 | }); 30 | -------------------------------------------------------------------------------- /test/unit/test-helpers.js: -------------------------------------------------------------------------------- 1 | var PlayerTest = { 2 | makeTag: function(){ 3 | var videoTag = document.createElement('video'); 4 | videoTag.id = 'example_1'; 5 | videoTag.className = 'video-js vjs-default-skin'; 6 | return videoTag; 7 | }, 8 | makePlayer: function(playerOptions, videoTag){ 9 | var player; 10 | 11 | videoTag = videoTag || PlayerTest.makeTag(); 12 | 13 | var fixture = document.getElementById('qunit-fixture'); 14 | fixture.appendChild(videoTag); 15 | 16 | playerOptions = playerOptions || {}; 17 | playerOptions['techOrder'] = ['mediaFaker']; 18 | 19 | return player = new videojs.Player(videoTag, playerOptions); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /browsers.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "os": "win", 4 | "browser": "chrome", 5 | "version": "27.0" 6 | }, 7 | { 8 | "os": "win", 9 | "browser": "firefox", 10 | "version": "20.0" 11 | }, 12 | { 13 | "os": "win", 14 | "browser": "ie", 15 | "version": "9.0" 16 | }, 17 | { 18 | "os": "win", 19 | "browser": "ie", 20 | "version": "10.0" 21 | }, 22 | { 23 | "os": "ios", 24 | "device": "iPhone 5", 25 | "version": "6.0" 26 | }, 27 | { 28 | "os": "ios", 29 | "device": "iPad 3rd (6.0)", 30 | "version": "6.0" 31 | }, 32 | { 33 | "os": "android", 34 | "device": "Samsung Galaxy Tab 2 10.1", 35 | "version": "4.0" 36 | } 37 | ] 38 | -------------------------------------------------------------------------------- /.bunyipconfig.js.example: -------------------------------------------------------------------------------- 1 | /* 2 | Bunyip is a tool for multi-browser/device testing 3 | https://github.com/ryanseddon/bunyip 4 | It uses a few service under the hood including: 5 | Browsertack - http://browserstack.com 6 | Pagekite https://pagekite.net 7 | You'll need accounts at both to use bunyip 8 | You'll also need to download and install pagekite.py 9 | */ 10 | var config = { 11 | "browserstack": { 12 | "username": "your-browserstack-email@example.com", 13 | "password": "your browserstack password", 14 | "timeout": 300 15 | }, 16 | "port": 9000, 17 | "tunnellink": "your-subdomain.pagekite.me", 18 | "tunnel": "pagekite.py your-subdomain.pagekite.me" 19 | }; 20 | 21 | module.exports = config; 22 | -------------------------------------------------------------------------------- /src/js/media/flash.externs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Externs for video-js.swf. Externs are functions 3 | * that the compiler shouldn't obfuscate. 4 | */ 5 | 6 | /** 7 | * @param {string} name 8 | */ 9 | HTMLObjectElement.prototype.vjs_getProperty = function(name) {}; 10 | 11 | /** 12 | * @param {string} name 13 | * @param {string|number} value 14 | */ 15 | HTMLObjectElement.prototype.vjs_setProperty = function(name, value) {}; 16 | 17 | /** 18 | * Control methods 19 | */ 20 | HTMLObjectElement.prototype.vjs_play = function() {}; 21 | HTMLObjectElement.prototype.vjs_pause = function() {}; 22 | HTMLObjectElement.prototype.vjs_load = function() {}; 23 | 24 | /** 25 | * @param {string} src 26 | */ 27 | HTMLObjectElement.prototype.vjs_src = function(src) {}; 28 | -------------------------------------------------------------------------------- /src/js/big-play-button.js: -------------------------------------------------------------------------------- 1 | /* Big Play Button 2 | ================================================================================ */ 3 | /** 4 | * Initial play button. Shows before the video has played. The hiding of the 5 | * big play button is done via CSS and player states. 6 | * @param {vjs.Player|Object} player 7 | * @param {Object=} options 8 | * @class 9 | * @constructor 10 | */ 11 | vjs.BigPlayButton = vjs.Button.extend(); 12 | 13 | vjs.BigPlayButton.prototype.createEl = function(){ 14 | return vjs.Button.prototype.createEl.call(this, 'div', { 15 | className: 'vjs-big-play-button', 16 | innerHTML: '', 17 | 'aria-label': 'play video' 18 | }); 19 | }; 20 | 21 | vjs.BigPlayButton.prototype.onClick = function(){ 22 | this.player_.play(); 23 | }; 24 | -------------------------------------------------------------------------------- /src/js/control-bar/live-display.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Displays the live indicator 3 | * TODO - Future make it click to snap to live 4 | * @param {vjs.Player|Object} player 5 | * @param {Object=} options 6 | * @constructor 7 | */ 8 | vjs.LiveDisplay = vjs.Component.extend({ 9 | init: function(player, options){ 10 | vjs.Component.call(this, player, options); 11 | } 12 | }); 13 | 14 | vjs.LiveDisplay.prototype.createEl = function(){ 15 | var el = vjs.Component.prototype.createEl.call(this, 'div', { 16 | className: 'vjs-live-controls vjs-control' 17 | }); 18 | 19 | this.contentEl_ = vjs.createEl('div', { 20 | className: 'vjs-live-display', 21 | innerHTML: 'Stream Type LIVE', 22 | 'aria-live': 'off' 23 | }); 24 | 25 | el.appendChild(this.contentEl_); 26 | 27 | return el; 28 | }; 29 | -------------------------------------------------------------------------------- /src/js/control-bar/control-bar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Container of main controls 3 | * @param {vjs.Player|Object} player 4 | * @param {Object=} options 5 | * @class 6 | * @constructor 7 | * @extends vjs.Component 8 | */ 9 | vjs.ControlBar = vjs.Component.extend(); 10 | 11 | vjs.ControlBar.prototype.options_ = { 12 | loadEvent: 'play', 13 | children: { 14 | 'playToggle': {}, 15 | 'currentTimeDisplay': {}, 16 | 'timeDivider': {}, 17 | 'durationDisplay': {}, 18 | 'remainingTimeDisplay': {}, 19 | 'liveDisplay': {}, 20 | 'progressControl': {}, 21 | 'fullscreenToggle': {}, 22 | 'volumeControl': {}, 23 | 'muteToggle': {} 24 | // 'volumeMenuButton': {} 25 | } 26 | }; 27 | 28 | vjs.ControlBar.prototype.createEl = function(){ 29 | return vjs.createEl('div', { 30 | className: 'vjs-control-bar' 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "evil" : true, 3 | "validthis": true, 4 | "browser" : true, 5 | "debug" : true, 6 | "boss" : true, 7 | "expr" : true, 8 | "eqnull" : true, 9 | "quotmark" : "single", 10 | "sub" : true, 11 | "trailing" : true, 12 | "undef" : true, 13 | "laxbreak" : true, 14 | "predef" : [ 15 | "_V_", 16 | "videojs", 17 | "vjs", 18 | "goog", 19 | "console", 20 | 21 | "require", 22 | "define", 23 | "module", 24 | "exports", 25 | 26 | "PlayerTest", 27 | "asyncTest", 28 | "deepEqual", 29 | "equal", 30 | "expect", 31 | "module", 32 | "notDeepEqual", 33 | "notEqual", 34 | "notStrictEqual", 35 | "ok", 36 | "QUnit", 37 | "raises", 38 | "start", 39 | "stop", 40 | "strictEqual", 41 | "test" 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /test/minified.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Video.js Test Suite 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 21 | 22 |
23 |

Video.js Test Suite

24 |

25 |
26 |

27 |
    28 |
    29 |
    30 | 31 | 32 | -------------------------------------------------------------------------------- /src/js/control-bar/fullscreen-toggle.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Toggle fullscreen video 3 | * @param {vjs.Player|Object} player 4 | * @param {Object=} options 5 | * @class 6 | * @extends vjs.Button 7 | */ 8 | vjs.FullscreenToggle = vjs.Button.extend({ 9 | /** 10 | * @constructor 11 | * @memberof vjs.FullscreenToggle 12 | * @instance 13 | */ 14 | init: function(player, options){ 15 | vjs.Button.call(this, player, options); 16 | } 17 | }); 18 | 19 | vjs.FullscreenToggle.prototype.buttonText = 'Fullscreen'; 20 | 21 | vjs.FullscreenToggle.prototype.buildCSSClass = function(){ 22 | return 'vjs-fullscreen-control ' + vjs.Button.prototype.buildCSSClass.call(this); 23 | }; 24 | 25 | vjs.FullscreenToggle.prototype.onClick = function(){ 26 | if (!this.player_.isFullScreen()) { 27 | this.player_.requestFullScreen(); 28 | this.el_.children[0].children[0].innerHTML = 'Non-Fullscreen'; // change the button text to "Non-Fullscreen" 29 | } else { 30 | this.player_.cancelFullScreen(); 31 | this.el_.children[0].children[0].innerHTML = 'Fullscreen'; // change the button to "Fullscreen" 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /src/js/util.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Utility functions namespace 3 | * @namespace 4 | * @type {Object} 5 | */ 6 | vjs.util = {}; 7 | 8 | /** 9 | * Merge two options objects, 10 | * recursively merging any plain object properties as well. 11 | * Previously `deepMerge` 12 | * 13 | * @param {Object} obj1 Object to override values in 14 | * @param {Object} obj2 Overriding object 15 | * @return {Object} New object -- obj1 and obj2 will be untouched 16 | */ 17 | vjs.util.mergeOptions = function(obj1, obj2){ 18 | var key, val1, val2; 19 | 20 | // make a copy of obj1 so we're not ovewriting original values. 21 | // like prototype.options_ and all sub options objects 22 | obj1 = vjs.obj.copy(obj1); 23 | 24 | for (key in obj2){ 25 | if (obj2.hasOwnProperty(key)) { 26 | val1 = obj1[key]; 27 | val2 = obj2[key]; 28 | 29 | // Check if both properties are pure objects and do a deep merge if so 30 | if (vjs.obj.isPlain(val1) && vjs.obj.isPlain(val2)) { 31 | obj1[key] = vjs.util.mergeOptions(val1, val2); 32 | } else { 33 | obj1[key] = obj2[key]; 34 | } 35 | } 36 | } 37 | return obj1; 38 | }; 39 | 40 | 41 | -------------------------------------------------------------------------------- /test/unit/core.js: -------------------------------------------------------------------------------- 1 | module('Core'); 2 | 3 | test('should create a video tag and have access children in old IE', function(){ 4 | var fixture = document.getElementById('qunit-fixture'); 5 | 6 | fixture.innerHTML += ''; 7 | 8 | var vid = document.getElementById('test_vid_id'); 9 | 10 | ok(vid.childNodes.length === 1); 11 | ok(vid.childNodes[0].getAttribute('type') === 'video/mp4'); 12 | }); 13 | 14 | test('should return a video player instance', function(){ 15 | var fixture = document.getElementById('qunit-fixture'); 16 | fixture.innerHTML += ''; 17 | 18 | var player = videojs('test_vid_id'); 19 | ok(player, 'created player from tag'); 20 | ok(player.id() === 'test_vid_id'); 21 | ok(videojs.players['test_vid_id'] === player, 'added player to global reference'); 22 | 23 | var playerAgain = videojs('test_vid_id'); 24 | ok(player === playerAgain, 'did not create a second player from same tag'); 25 | 26 | var tag2 = document.getElementById('test_vid_id2'); 27 | var player2 = videojs(tag2); 28 | ok(player2.id() === 'test_vid_id2', 'created player from element'); 29 | }); 30 | -------------------------------------------------------------------------------- /src/js/media/loader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * The Media Loader is the component that decides which playback technology to load 3 | * when the player is initialized. 4 | * 5 | * @constructor 6 | */ 7 | vjs.MediaLoader = vjs.Component.extend({ 8 | /** @constructor */ 9 | init: function(player, options, ready){ 10 | vjs.Component.call(this, player, options, ready); 11 | 12 | // If there are no sources when the player is initialized, 13 | // load the first supported playback technology. 14 | if (!player.options_['sources'] || player.options_['sources'].length === 0) { 15 | for (var i=0,j=player.options_['techOrder']; i Video.js is a web video player built from the ground up for an HTML5 world. It supports HTML5 and Flash video, as well as YouTube and Vimeo (through [plugins](https://github.com/videojs/video.js/wiki/Plugins)). It supports video playback on desktops and mobile devices. This project was started mid 2010, and the player is now used on over 50,000 websites. 4 | 5 | Visit [videojs.com](http://videojs.com) for an overview, download options, and instructions on how to use the player on your site. 6 | 7 | ## Contributing 8 | Video.js is a free and open source library, and we appreciate any help you're willing to give. Check out the [contributing guide](CONTRIBUTING.md). 9 | 10 | ## Building your own Video.js from source 11 | To build your own custom version read the section on [contributing code](CONTRIBUTING.md#contributing-code) and ["Building your own copy"](CONTRIBUTING.md#building-your-own-copy-of-videojs) in the contributing guide. 12 | 13 | ## License 14 | 15 | Video.js is licensed under the Apache License, Version 2.0. [View the license file](LICENSE) 16 | 17 | Copyright 2014 Brightcove, Inc. 18 | -------------------------------------------------------------------------------- /docs/guides/skins.md: -------------------------------------------------------------------------------- 1 | Skins 2 | ===== 3 | 4 | The default Video.js skin is made using HTML and CSS, so there's no need to learn a complicated skinning language to update colors or even create an entirely new skin. 5 | 6 | ## Icons 7 | 8 | New in version 4.0 is the use of font icons. All of the icons (play, pause, etc.) use the new custom font, which allows the icons to be scaled and colored just like any other text font. 9 | 10 | All of the icons are available as variables in the [LESS](https://github.com/videojs/video.js/blob/master/src/css/video-js.less#L87-L99) source, making it easy to replace icons (such as the loading spinner). The easiest way to try this out is by using the [player skin designer](http://designer.videojs.com/). 11 | 12 | ![available icons](https://i.cloudup.com/wb51GGDDnJ.png) 13 | 14 | ## Customization 15 | 16 | When you create a new skin, you can either override styles in the default skin: 17 | 18 | ```css 19 | .vjs-default-skin .vjs-play-progress { background: #900; } 20 | ``` 21 | 22 | Or remove the 'vjs-default-skin' class from the video tag and create a new skin from scratch. 23 | 24 | ```html 25 |