Comparar commits

..

141 Commits

Autor SHA1 Mensagem Data
Steve Heffernan 7b73c2725e Added back in reverted #630 2013-09-04 13:33:27 -07:00
Steve Heffernan 8f53e514de Merge branch 'stable' of github.com:videojs/video.js into stable 2013-09-04 13:30:36 -07:00
Steve Heffernan c39dd5567e Fixed changelog version 2013-09-04 13:30:28 -07:00
Steve Heffernan 8e9db2d662 Rotating CHANGELOG 2013-09-04 13:28:12 -07:00
Steve Heffernan 52c577995c Bump version to 4.2.0 2013-09-04 13:26:45 -07:00
Steve Heffernan efe7a12ccb Fixed IE8 tests and flaky fonts 2013-09-04 11:48:19 -07:00
Steve Heffernan f146ebb179 Fixed the getAttributes test in ie8, which reports all attrs, whether or not they were set 2013-09-03 11:27:50 -07:00
Steve Heffernan 72bf48cf36 Fixed the custom fallback message test which would break when ie8 capitalized tag names 2013-09-03 10:48:48 -07:00
Steve Heffernan e6ecbfe824 Added a line to the changelog 2013-08-27 13:13:07 -07:00
Steve Heffernan 0ccb6dd156 Removed spinner gradient to improve performance 2013-08-27 13:11:08 -07:00
Steve Heffernan 62b4f799b9 Merge branch 'spinner-fixes' of git://github.com/ChALkeR/video.js into ChALkeR-spinner-fixes 2013-08-27 12:53:46 -07:00
Steve Heffernan bd789b8613 Added a line to the changelog 2013-08-27 10:27:41 -07:00
Steve Heffernan 4772e4680b Merge branch '636-incompatible' of git://github.com/jelbourn/video.js into jelbourn-636-incompatible
Conflicts:
	test/unit/player.js
2013-08-27 10:26:32 -07:00
Steve Heffernan 26cc24c59d Merge branch 'export-addremove-class' of git://github.com/theonion/video.js into theonion-export-addremove-class
Conflicts:
	src/js/exports.js
	test/unit/api.js
2013-08-26 16:40:40 -07:00
Steve Heffernan 4bc269992e Adding line to CHANGELOG 2013-08-26 16:31:57 -07:00
Trevor Cook 07351ada80 Close GH-632: Ensure tech is defined before checking tech.isReady_ fixes #631. 2013-08-26 16:31:07 -07:00
Steve Heffernan acb4a43d8a Minor modifications to #627 2013-08-26 16:23:33 -07:00
Steve Heffernan 75dd7c5a3c Adding line to CHANGELOG 2013-08-26 16:14:10 -07:00
David LaPalomento f515ac0236 Close GH-627: Use dashes to format invalid times. 2013-08-26 16:13:54 -07:00
Steve Heffernan 6418531d0c Merge pull request #702 from dmlap/feature/expose-volume-menu
Feature/expose volume menu
2013-08-26 08:54:39 -07:00
Steve Heffernan a04932eaf9 Adding line to CHANGELOG 2013-08-25 19:30:37 -07:00
Steve Heffernan 96f6c2388a Close GH-706: Minor code improvements for lib.js. closes #580. 2013-08-25 19:30:19 -07:00
Steve Heffernan 8721202ec1 Adding line to CHANGELOG 2013-08-25 18:51:24 -07:00
Steve Heffernan 92d16d6409 Close GH-705: Changed tech.feature keys to strings to support external techs. closes #466. 2013-08-25 18:50:59 -07:00
Steve Heffernan 7c2ae3f68c Adding line to CHANGELOG 2013-08-23 15:05:23 -07:00
Jeremy West 7ab3d190f2 Close GH-605: added RTMP support. fixes #559. 2013-08-23 15:05:04 -07:00
David LaPalomento 29668ec45b Fix issue with fractional computed dimensions on Chrome
Chrome 29 on OS X (at least) seems to report fractional dimensions occasionally when integer values are assigned. For example, '123px' might be translated to '123.999998458px'. Parse the value and round it to ignore this slight discrepancy.
2013-08-23 14:16:53 -04:00
David LaPalomento bd18f5b25f Export VolumeMenuButton
Add the volumemenubutton to the list of unminified properties for gcc. Create a test case to verify it doesn't get accidentally removed at some point.
2013-08-23 14:15:58 -04:00
Steve Heffernan 5a6fa37623 Adding line to CHANGELOG 2013-08-19 12:37:38 -07:00
Andrew Abramov e520e1eba4 Close GH-683: gruntfile: removed new line symbol from output_wrapper. fixes #679. 2013-08-19 12:36:43 -07:00
Сковорода Никита Андреевич 2f68bfc7c1 Fix spinner position. 2013-08-19 05:13:40 +04:00
Steve Heffernan acf6d67e0d Updated changelog note 2013-08-09 14:34:20 -07:00
Steve Heffernan d47f78f5d1 Adding line to CHANGELOG 2013-08-09 14:29:52 -07:00
Andy Niccolai 02de927043 Close GH-672: Control bar updates. Fixes #556, Fixes #500, Fixes #374, Fixes #403, Fixes #441, Fixes #193, Fixes #602, Fixes #561, Fixes #281 2013-08-09 14:29:22 -07:00
Jeremy Elbourn 20e2d4e984 Merge branch 'master' of https://github.com/videojs/video.js into 636-incompatible 2013-08-05 14:23:05 -04:00
Jeremy Elbourn ff9165b7da Default incompatibility msg w/ other global options fixes #636 2013-08-05 14:19:20 -04:00
Sean Bloomfield f7a72b1f20 exporting addClass and removeClass. added api existence tests for fadeIn,fadeOut,addClass,removeClass 2013-07-30 15:58:00 -05:00
Steve Heffernan 9030a5655e Revert "Close GH-630: prevent default action for simple html5 media events. fixes #573, fixes #620 (duplicate bug)."
This reverts commit 15544c3d05.
2013-07-30 11:31:33 -07:00
Steve Heffernan 699c476575 Merge pull request #660 from videojs/stable
Close GH-630: prevent default action for simple html5 media events. fixe...
2013-07-30 11:25:07 -07:00
Steve Heffernan b5b0f42888 Adding line to CHANGELOG 2013-07-30 11:12:45 -07:00
Cameron Tangney 15544c3d05 Close GH-630: prevent default action for simple html5 media events. fixes #573, fixes #620 (duplicate bug). 2013-07-30 11:12:30 -07:00
Steve Heffernan 8010b77eb3 Adding line to CHANGELOG 2013-07-30 10:43:27 -07:00
Dominic 15fab6df81 Close GH-654: Export createItems call to enable plugins to hook into process. Fixes #648 2013-07-30 10:43:11 -07:00
Steve Heffernan 89fb86bff7 Adding line to CHANGELOG 2013-07-29 15:49:30 -07:00
Mykhailo Stadnyk 75ff27307d Close GH-643: Fix Player.buffered() to more correct behavior. 2013-07-29 15:48:25 -07:00
Steve Heffernan 1d972a0686 Adding line to CHANGELOG 2013-07-29 15:33:30 -07:00
David Elner 334ff59ff0 Close GH-659: Allow event handlers registered with one() to be removed with off().. Fixes #658 2013-07-29 15:33:10 -07:00
Steve Heffernan a809954495 Exporting component.player. fixes #647 2013-07-29 10:48:10 -07:00
Steve Heffernan 7936d7967d Merge pull request #655 from johneke/master
Add player.dispose() API documentation to api.md
2013-07-29 08:15:43 -07:00
johneke aa64669ca3 Fixed due to feedback from code review
Fixed due to feedback from code review
2013-07-29 11:13:00 -04:00
johneke a726b07538 Add player.dispose() API documentation to api.md 2013-07-25 20:05:28 -04:00
Steve Heffernan ca96297ef9 Adding line to CHANGELOG 2013-07-22 12:14:56 -04:00
Dominic a38ce63474 Close GH-648: Added export for vjs.MenuButton. Fixes #647 2013-07-22 12:14:35 -04:00
Steve Heffernan c8ee76b80e Adding line to CHANGELOG 2013-07-19 20:19:13 -07:00
Steve Heffernan 1eca8add85 Close GH-644: LESS for CSS. 2013-07-19 20:18:39 -07:00
Steve Heffernan 2b1bb60f7e Merge branch 'master' of github.com:videojs/video.js 2013-07-19 10:47:41 -07:00
Steve Heffernan 5aa1ff59b3 Added block quote to readme. 2013-07-19 10:47:30 -07:00
Steve Heffernan 59af460ad4 Merge pull request #639 from eXon/patch-1
Fixed broken link
2013-07-18 16:11:23 -07:00
Jeremy West a449cb043a Close GH-614: added dispose event. fixes #613. 2013-07-18 14:39:14 -07:00
Steve Heffernan 9d424c61f4 Fixed broken on-page link
contribute-code -> contributing-code
2013-07-18 11:48:23 -07:00
Steve Heffernan 91da153c02 Updated readme and contrib guide. closes #645 close #397
With changes from @sh1ps and myself
2013-07-17 17:51:29 -07:00
Steve Heffernan 150facab44 Merge branch 'contrib-guide' of git://github.com/BCjwhisenant/video-js into BCjwhisenant-contrib-guide
Conflicts:
	CONTRIBUTING.md
2013-07-17 17:49:19 -07:00
Benoit Tremblay 3716f3b1f0 Fixed broken link 2013-07-14 11:34:25 -04:00
Jeremy Elbourn 918ee040e1 Allow setting a custom incompatible video message. fixes #636 2013-07-12 16:05:25 -04:00
BCJwhisenant 1c606779c3 Removed an extraneous section at the bottom about Pull Requests.
(since we recommend further up the page to use contribflow)
2013-07-10 12:05:38 -04:00
Steve Heffernan fdf7f4f228 Bump version to 4.1.0 2013-06-28 15:58:25 -07:00
Steve Heffernan c82611d506 Rotating CHANGELOG 2013-06-28 15:56:43 -07:00
Steve Heffernan ed8ed4dd94 Merge branch 'stable' into release/4-1
Conflicts:
	CHANGELOG.md
	contrib.json
	src/js/cdn.js
2013-06-28 15:48:33 -07:00
Steve Heffernan 9f647ef081 Fixed an issue where the tag player reference wasn't getting killed in the minified version 2013-06-28 15:42:47 -07:00
Steve Heffernan c616695e4d Fixed an issue where tag was undefined in iOS 2013-06-28 15:02:21 -07:00
Steve Heffernan 52751a0d67 Adding line to CHANGELOG 2013-06-28 13:07:05 -07:00
Steve Heffernan ffd308e305 Close GH-609: Captions fixes. Fixes #564, Fixes #542 2013-06-28 13:06:50 -07:00
Steve Heffernan b4a07a3d9d Adding line to CHANGELOG 2013-06-28 13:04:00 -07:00
Steve Heffernan db97df69dc Close GH-606: Fix IE9 canPlayType error. Fixes #519 2013-06-28 13:03:38 -07:00
BCJwhisenant 8f45f93c84 A small substitution 2013-06-27 15:21:19 -04:00
BCJwhisenant b6667dfaf6 changes to the contrib guide, based on Apurva's review. 2013-06-27 15:08:10 -04:00
Steve Heffernan 23fc4cca35 Adding line to CHANGELOG 2013-06-26 15:06:10 -07:00
Gary Katsevman 00a043f1e1 Close GH-470: Augment userAgent detection. 2013-06-26 15:05:50 -07:00
BCJwhisenant 9abe53a32e updated the contrib guide to use contribflow commands
fixed a typo
2013-06-26 16:02:34 -04:00
Steve Heffernan 8e5cf7a69d Fixed up some changelog issues 2013-06-24 13:00:19 -07:00
Steve Heffernan fd39878f8b Adding line to CHANGELOG 2013-06-24 12:48:11 -07:00
Steve Heffernan 1ddef27903 Close GH-588: Export bufferedPercent. 2013-06-24 12:47:47 -07:00
Steve Heffernan 19a33cc7c7 Adding line to CHANGELOG 2013-06-24 12:38:30 -07:00
Jon Zepernick 02a1057ff4 Close GH-593: When autoplay = true, delete tag.poster instead of setting to null. 2013-06-24 12:38:05 -07:00
Steve Heffernan a040ce61ad Adding line to CHANGELOG 2013-06-24 12:08:30 -07:00
Sean Bloomfield 042076043b Close GH-581: export Component.prototype.fadeIn/Out. 2013-06-24 12:07:39 -07:00
Steve Heffernan 38d119e75d Merge pull request #585 from fluf1024/patch-1
Changed VideoJS -> videojs in api.md
2013-06-24 11:40:39 -07:00
fluf1024 93c6645744 Changed VideoJS -> videojs in api.md
I think, it's the proper name of the component in the default set.
2013-06-20 08:13:02 +02:00
Steve Heffernan 85c6b46ec8 Merge pull request #576 from Mikhus/master
Some minor code improvements
2013-06-17 11:19:41 -07:00
mstadnyk 1e199da117 Code guidelines fixed 2013-06-17 01:02:29 +03:00
mstadnyk 3a40dcd883 Several minor code improvements.
Actually, tracks.js contains several pieces of code which could
be re-written more effectively. The problem is that in some places
there are conditional checks like this:

    if (condition) {
        call_setter( true);
    } else {
        call_setter( false);
    }

which could be re-written to:

    call_setter( condition);

This improvement saves some bytes of code length, traffic and should
also work more effectively by utilizing less machine resources
2013-06-17 00:18:21 +03:00
Steve Heffernan afc39f711f Normalized CDN language value 2013-06-12 14:44:14 -07:00
Steve Heffernan 8a728a80ac Added uglifyjs which somehow got dropped from #571 2013-06-11 15:35:14 -07:00
Steve Heffernan d932cffd50 Added line to changelog for 4.0.4 2013-06-11 15:29:20 -07:00
Steve Heffernan 6fe5513f30 Bump version to 4.0.4 2013-06-11 15:27:49 -07:00
Steve Heffernan 138b1381c2 Adding line to CHANGELOG 2013-06-11 15:25:40 -07:00
Steve Heffernan 60d389e1f8 Close GH-571: Add analtyics to current CDN version. Fixes #568 2013-06-11 15:25:19 -07:00
Steve Heffernan 93e3b38132 Adding line to CHANGELOG 2013-06-11 15:15:26 -07:00
Steve Heffernan b02f879bf3 Close GH-568: Google Analytics Tracking for CDN. 2013-06-11 15:14:36 -07:00
Steve Heffernan 9997d0a7ef Merge pull request #570 from nsufaisal/patch-1
Update api.md
2013-06-11 10:02:58 -07:00
nsufaisal 3dd0b1d234 Update api.md 2013-06-11 20:49:21 +06:00
Steve Heffernan d27c3102e9 Adding line to CHANGELOG 2013-06-05 10:28:13 -07:00
Steve Heffernan d5d97bd64f Close GH-560: Export global players object. 2013-06-05 10:27:38 -07:00
Steve Heffernan 0ddf8af452 Adding line to CHANGELOG 2013-06-03 13:20:47 -07:00
Steve Heffernan f6bd819c5c Close GH-555: Export requestFullScreen(). 2013-06-03 13:19:46 -07:00
Steve Heffernan 21cd77358a Adding line to CHANGELOG 2013-05-31 16:09:34 -07:00
Steve Heffernan 847e392e0c Close GH-524: Blocking user text selection by default on player components. fixes #46. 2013-05-31 16:09:07 -07:00
Steve Heffernan 8799984a8c Adding line to CHANGELOG 2013-05-31 10:31:57 -07:00
Steve Heffernan 0c4c30a3bd Close GH-553: Turn on tech method queuing. 2013-05-31 10:31:18 -07:00
Steve Heffernan 4db3dba068 Updated contrib.json to match new contribflow values 2013-05-31 09:50:16 -07:00
Steve Heffernan 46731c40c3 Merge branch 'master' of github.com:videojs/video.js 2013-05-31 09:48:18 -07:00
Steve Heffernan 5bc5c40f8a Updated changelog to match new contribflow template 2013-05-31 09:48:02 -07:00
Steve Heffernan d5fe1c40d8 Merge pull request #547 from DracoLi/patch-1
Updated API, changed `size` to `dimensions`
2013-05-29 10:47:01 -07:00
Draco Li 6251acdf56 Updated API, changed size to dimensions
There's no `size()` only `dimensions()`, so updated API to reflect this.
2013-05-29 12:03:40 -03:00
Steve Heffernan 0f21f86521 Merge branch 'stable' 2013-05-28 15:33:31 -07:00
Steve Heffernan ed5ac285c3 Adding line to CHANGELOG 2013-05-28 15:33:09 -07:00
Steve Heffernan 880be64f48 Bump version to 4.0.3 2013-05-28 15:31:11 -07:00
Steve Heffernan 753ce48e21 Close GH-546: Fix for exit-fullscreen bug in 4.0. fixes #497. 2013-05-28 15:29:42 -07:00
Philippe Normand 6b4d811b2f Close GH-515: createEl: dispose reference to cloned element. Fixes #514 2013-05-23 18:40:14 -07:00
Steve Heffernan baac2af4ab Merge branch 'stable' 2013-05-23 13:15:18 -07:00
Steve Heffernan 731ec4fa0b Adding line to CHANGELOG 2013-05-23 13:14:43 -07:00
Steve Heffernan 8dd88d1626 Bump version to 4.0.2 2013-05-23 13:12:43 -07:00
Steve Heffernan 0fe7348456 Close GH-535: Adding version numbers in build. Minifying CSS.. 2013-05-23 13:10:29 -07:00
Steve Heffernan a7dd81f82f Merge branch 'stable' 2013-05-22 18:36:12 -07:00
Steve Heffernan d4168cd2b6 Adding line to CHANGELOG 2013-05-22 18:34:50 -07:00
Steve Heffernan 36c92404c3 Bump version to 4.0.1 2013-05-22 18:16:13 -07:00
Steve Heffernan 1f23529cf0 Merge branch 'stable' 2013-05-22 17:25:12 -07:00
Steve Heffernan 68d5cb996a Close GH-532: Added ie fix to font loading.. 2013-05-22 17:01:55 -07:00
Steve Heffernan fe36ae172d Updated contrib.json to have org and project names. 2013-05-20 16:34:57 -07:00
Steve Heffernan a6a443bac3 Updated contrib.json to use new videojs org 2013-05-20 16:02:31 -07:00
Steve Heffernan b3d4ed6459 Added date to changelog 2013-05-20 15:02:26 -07:00
Steve Heffernan f4ac570297 Updated to new changelog layout. Deleted changelog2 test file. 2013-05-20 14:57:48 -07:00
BCjwhisenant c9bba46846 cleaned up more grammar and syntax. 2013-03-22 14:16:27 -04:00
BCjwhisenant d40c33cf65 another clarification to CONTRIBUTING.md 2013-03-22 14:14:22 -04:00
BCjwhisenant 30949a3c83 more updates to CONTRIBUTING.md 2013-03-22 14:11:03 -04:00
BCjwhisenant 5dbb9aabc7 more changes to the CONTRIBUTING.md guide
added guides for the grunt tasks for feature and issue management
2013-03-22 14:07:21 -04:00
BCjwhisenant dc9934b765 Fixed (hopefully) some minor list formatting 2013-03-19 14:03:05 -04:00
BCjwhisenant bf804d5571 Merge commit '80802e68d8f00ac27799a968295b11bd8c8ad19c' into contrib-guide 2013-03-19 13:58:55 -04:00
BCjwhisenant c17d5890d0 clarified some language
added a note about turning off npm colors for windows users
2013-03-19 12:32:13 -04:00
BCjwhisenant 80802e68d8 Fixed formatting in some of the instructions 2013-03-15 22:30:25 -03:00
BCjwhisenant ff957fa9f5 changes to the contributing guide. 2013-03-15 21:20:40 -04:00
54 arquivos alterados com 2540 adições e 1447 exclusões
-10
Ver Arquivo
@@ -1,10 +0,0 @@
---
confirm_review: true
backup_remote: false
release_branch: stable
project: videojs
qa_branch: false
staging_branch: false
development_branch: master
remote: origin
confirm_staging: false
+91 -46
Ver Arquivo
@@ -1,41 +1,92 @@
* Added a plugins interface
* Added automated test suite and support for Travis CI.
CHANGELOG
=========
## Unreleased (HEAD)
_(none)_
--------------------
## 4.2.0 (2013-09-04)
* Added LESS as a CSS preprocessor for the default skin ([view](https://github.com/videojs/video.js/pull/644))
* Exported MenuButtons for use in the API ([view](https://github.com/videojs/video.js/pull/648))
* Fixed ability to remove listeners added with one() ([view](https://github.com/videojs/video.js/pull/659))
* Updated buffered() to account for multiple loaded ranges ([view](https://github.com/videojs/video.js/pull/643))
* Exported createItems() for custom menus ([view](https://github.com/videojs/video.js/pull/654))
* Preventing media events from bubbling up the DOM ([view](https://github.com/videojs/video.js/pull/630))
* Major reworking of the control bar and many issues fixed ([view](https://github.com/videojs/video.js/pull/672))
* Fixed an issue with minifiying the code on Windows systems ([view](https://github.com/videojs/video.js/pull/683))
* Added support for RTMP streaming through Flash ([view](https://github.com/videojs/video.js/pull/605))
* Made tech.features available to external techs ([view](https://github.com/videojs/video.js/pull/705))
* Minor code improvements ([view](https://github.com/videojs/video.js/pull/706))
* Updated time formatting to support NaN and Infinity ([view](https://github.com/videojs/video.js/pull/627))
* Fixed an `undefined` error in cases where no tech is loaded ([view](https://github.com/videojs/video.js/pull/632))
* Exported addClass and removeClass for player components ([view](https://github.com/videojs/video.js/pull/661))
* Made the fallback message customizable ([view](https://github.com/videojs/video.js/pull/638))
* Fixed an issue with the loading spinner placement and rotation ([view](https://github.com/videojs/video.js/pull/694))
* Fixed an issue with fonts being flaky in IE8
## 4.1.0 (2013-06-28)
* Turned on method queuing for unready playback technologies (flash) [view](https://github.com/videojs/video.js/pull/553)
* Blocking user text selection on player components [view](https://github.com/videojs/video.js/pull/524)
* Exported requestFullScreen() and cancelFullScreen() in the minified version [view](https://github.com/videojs/video.js/pull/555)
* Exported the global players reference, videojs.players [view](https://github.com/videojs/video.js/pull/560)
* Added google analytics to the CDN version ([view](https://github.com/videojs/video.js/pull/568))
* Exported fadeIn/fadeOut for the Component API ([view](https://github.com/videojs/video.js/pull/581))
* Fixed an IE poster error when autoplaying ([view](https://github.com/videojs/video.js/pull/593))
* Exported bufferedPercent for the API ([view](https://github.com/videojs/video.js/pull/588))
* Augmented user agent detection, specifically for Android versions ([view](https://github.com/videojs/video.js/pull/470))
* Fixed IE9 canPlayType error ([view](https://github.com/videojs/video.js/pull/606))
* Fixed various issues with captions ([view](https://github.com/videojs/video.js/pull/609))
## 4.0.4 (2013-06-11)
* Added google analytics to current CDN version. ([view](https://github.com/videojs/video.js/pull/571))
## 4.0.3 (2013-05-28)
* Fixed an bug with exiting fullscreen. [view](https://github.com/videojs/video.js/pull/546)
## 4.0.2 (2013-05-23)
* Correct version number for CDN swf url. Minify CSS. [view](https://github.com/videojs/video.js/pull/535)
## 4.0.1 (2013-05-22)
* Fixed old IE font loading [view](https://github.com/videojs/video.js/pull/532)
## 4.0.0 (2013-05-09)
* Improved performance through an 18% size reduction using Google Closure Compiler in advanced mode
* Greater stability through an automated cross-browser/device test suite using TravisCI, Bunyip, and Browserstack.
* New plugin interface and plugin listing for extending Video.js
* New default skin design that uses font icons for greater customization
* Responsive design and retina display support
* Improved accessibility through better ARIA support
* Moved to Apache 2.0 license
* 100% JavaScript development tool set including Grunt
* Updated docs to use Github markdown
* Allow disabling of default components
* Duration is now setable (need ed for HLS m3u8 files)
* Event binders (on/off/one) now return the player instance
* Stopped player from going back to beginningg on ended event.
* Stopped player from going back to beginning on ended event
* Added support for percent width/height and fluid layouts
* Improved load order of elements to reduce reflow.
* Changed addEvent function name to 'on'.
* Improved load order of elements to reduce reflow
* Changed addEvent function name to 'on'
* Removed conflicting array.indexOf function
* Added exitFullScreen to support BlackBerry devices (pull/143)
--------------------------------------------------------------------------------
^ ADD NEW CHANGES ABOVE ^
--------------------------------------------------------------------------------
CHANGELOG
=========
## 3.2.0 (2012-03-20)
* Updated docs with more options.
* Overhauled HTML5 Track support.
* Fixed Flash always autoplaying when setting source.
* Fixed localStorage context
* Updated 'fullscreenchange' event to be called even if the user presses escape to exit fullscreen.
* Automatically converting URsource URL to absolute for Flash fallback.
* Created new 'loadedalldata' event for when the source is completely downloaded
* Improved player.destroy(). Now removes elements and references.
* Refactored API to be more immediately available.
---- 3.0.3 / 2012-01-12 / doc-change -------------------------------------------
* Added line to docs to test zenflow
### Patches
* 3.2.1 (2012-04-06) Fixed setting width/height with javascript options
* 3.2.2 (2012-05-02) Fixed error with multiple controls fading listeners
* 3.2.3 (2012-11-12) Fixed chrome spinner continuing on seek
---- 3.0.4 / 2012-01-12 / undefined-source-fix ---------------------------------
* Fixing an undefined source when no sources exist on load
---- 3.0.5 / 2012-01-12 / event-layer-x-deprecation-fix ------------------------
* Removed deprecated event.layerX and layerY
---- 3.0.6 / 2012-01-12 / docs-url-fix -----------------------------------------
* Fixed wrong URL for CDN in docs
---- 3.0.7 / 2012-01-12 / fixing-ie8-poster-bug --------------------------------
* Fixed an ie8 breaking bug with the poster
---- 3.0.8 / 2012-01-23 / fix-ie-controls-hiding -------------------------------
* Fixed issue with controls not hiding in IE due to no opacity support
---- 3.1.0 / 2012-01-30 / leonardo ---------------------------------------------
## 3.1.0 (2012-01-30)
* Added CSS fix for Firefox 9 fullscreen (in the rare case that it's enabled)
* Replaced swfobject with custom embed to save file size.
* Added flash iframe-mode, an experimental method for getting around flash reloading issues.
@@ -49,22 +100,16 @@ CHANGELOG
* Made full-window mode more independent
* Added rakefile for release generation
---- 3.2.0 / 2012-03-20 / baxter -----------------------------------------------
* Updated docs with more options.
* Overhauled HTML5 Track support.
* Fixed Flash always autoplaying when setting source.
* Fixed localStorage context
* Updated 'fullscreenchange' event to be called even if the user presses escape to exit fullscreen.
* Automatically converting URsource URL to absolute for Flash fallback.
* Created new 'loadedalldata' event for when the source is completely downloaded
* Improved player.destroy(). Now removes elements and references.
* Refactored API to be more immediately available.
## 3.0.0 (2012-01-10)
* Same HTML/CSS Skin for both HTML5 and Flash video
* Super lightweight Flash fallback player for browsers that dont support HTML5 video
* Free CDN hosting
---- 3.2.1 / 2012-04-06 / options-width-fix ------------------------------------
* Fixed setting width/height with javascript options
---- 3.2.2 / 2012-05-02 / multiple-control-fades-fix ---------------------------
* Fixed error with multiple controls fading listeners
---- 3.2.3 / 2012-11-12 / fix-chrome-seeking-spinner ---------------------------
* Fixed chrome spinner continuing on seek
### Patches
* 3.0.2 (2012-01-12) Started tracking changes with zenflow
* 3.0.3 (2012-01-12) Added line to docs to test zenflow
* 3.0.4 (2012-01-12) Fixing an undefined source when no sources exist on load
* 3.0.5 (2012-01-12) Removed deprecated event.layerX and layerY
* 3.0.6 (2012-01-12) Fixed wrong URL for CDN in docs
* 3.0.7 (2012-01-12) Fixed an ie8 breaking bug with the poster
* 3.0.8 (2012-01-23) Fixed issue with controls not hiding in IE due to no opacity support
-50
Ver Arquivo
@@ -1,50 +0,0 @@
```
^ NEW CHANGES ABOVE ^
```
CHANGELOG
=========
#### 3.2.3 (2013-05-03)
* test line
* Added a plugins interface
* Added automated test suite and support for Travis CI.
* Updated docs to use Github markdown
* Allow disabling of default components
* Duration is now setable (need ed for HLS m3u8 files)
* Event binders (on/off/one) now return the player instance
* Stopped player from going back to beginningg on ended event.
* Added support for percent width/height and fluid layouts
* Improved load order of elements to reduce reflow.
* Changed addEvent function name to 'on'.
* Removed conflicting array.indexOf function
* Added exitFullScreen to support BlackBerry devices (pull/143)
## 5.0.0 (2013-02-02)
* Added a plugins interface ([261f2072](https://github.com/angular-ui/bootstrap/commit/261f2072))
* Added automated test suite and support for Travis CI.
* Updated docs to use Github markdown
* Allow disabling of default components
#### 4.1.2 (2013-02-02)
* Added a plugins interface ([261f2072](https://github.com/angular-ui/bootstrap/commit/261f2072))
### 4.1.0 (2013-02-02)
* Added a plugins interface ([261f2072](https://github.com/angular-ui/bootstrap/commit/261f2072))
* Added automated test suite and support for Travis CI.
* Updated docs to use Github markdown
* Allow disabling of default components
#### 4.0.2 (2013-02-02)
* Added a plugins interface ([261f2072](https://github.com/angular-ui/bootstrap/commit/261f2072))
#### 4.0.1 (2013-02-02)
* Added a plugins interface ([261f2072](https://github.com/angular-ui/bootstrap/commit/261f2072))
## 4.0.0 (2013-02-02)
* Added a plugins interface ([261f2072](https://github.com/angular-ui/bootstrap/commit/261f2072))
* Added automated test suite and support for Travis CI.
* Updated docs to use Github markdown
* Allow disabling of default components
+196 -112
Ver Arquivo
@@ -1,155 +1,244 @@
So you're telling me you want to spend some of your precious time giving back to this humble project? You're crazy. But since you're here...there are some ways you can help make Video.js a faster, easier, more compatible, and more fully-featured video player.
CONTRIBUTING
============
So you want to help out? Great! There's a number of ways you can get involved.
* Bug reports and fixes
* Features and changes (pull requests)
* [Answer questions](http://stackoverflow.com/questions/tagged/video.js) on Stack Overflow
* Other Video.js projects
* [File and discuss issues](#filing-issues)
* [Contribute code](#contributing-code)
* [Build and share plugins](docs/plugins.md)
* [Answer questions on Stack Overflow](http://stackoverflow.com/questions/tagged/video.js)
Don't miss the [code style guide](#code-style).
There's also other Video.js projects where you can help. (check the [video.js org](https://github.com/videojs) for an up-to-date list of projects)
# Getting started
* [Videojs.com](https://github.com/videojs/videojs.com)
* [Video.js flash player](https://github.com/videojs/video-js-swf)
* [Player skin designer](https://github.com/videojs/designer)
* [Contribflow](https://github.com/zencoder/contribflow)
1. [Download and install Node.js](http://nodejs.org/download/). Video.js uses Node for build and test automation.
There is a known issue between Node.js version 0.10.x and phantomjs. This will manifest itself during the node module installation (see step 4 below). For the time being, please install Node.js version 0.8.22 or earlier. You can find earlier versions of Node.js [here](http://nodejs.org/dist/).
Filing issues
-------------
[GitHub Issues](https://github.com/videojs/video.js/issues) are used for all discussions around the codebase, including **bugs**, **features**, and other **enhancements**.
2. [Fork](http://help.github.com/fork-a-repo/) and clone the video.js git repository.
### Reporting a Bug
```bash
# Clones your fork of the repo into the current directory in terminal
git clone https://github.com/<your-username>/video-js.git
# Navigate to the newly cloned directory
cd video-js
# Assigns the original repo to a remote called "upstream"
git remote add upstream https://github.com/zencoder/video-js.git
```
In the future, if you want to pull in updates to video.js that happened after you cloned the main repo, you can run:
```bash
git checkout master
git pull upstream master
```
3. Install the grunt-cli package so that you will have the correct version of grunt available from any project that needs it. This should be done as a global install:
```bash
npm install -g grunt-cli
```
4. Install required node.js modules using node package manager.
```bash
npm install
```
5. Build a local copy. Video.js uses [grunt](http://gruntjs.com), a node-based task automation tool for building and tesing. The following will compile a local copy in the dist/ directory and run tests. It will also create a sourcelist.js file that can be used to load the video.js source scripts in a page.
```bash
grunt
```
6. When you're ready to add a feature, make a change, or fix a bug, first create a new branch for it. Prefix the branch with the correspoding [issue number](https://github.com/zencoder/video-js/issues). If there isn't one, submit a new issue. Anything more complicated than simple docs changes should have an issue.
```bash
git checkout -b <####-branch-name>
```
Be sure to reference your issue in any commit message. Github allows you to do this though the [fixes or closes](https://github.com/blog/831-issues-2-0-the-next-generation) keywords.
```bash
My commit message. fixes #123
```
# Bugs
A bug is a _demonstrable problem_ that is caused by the code in the
repository. Good bug reports are extremely helpful - thank you!
**A bug is a demonstrable problem** that is caused by the code in the repository. Good bug reports are extremely helpful. Thank You!
Guidelines for bug reports:
1. **Use the [GitHub issue search](https://github.com/zencoder/video-js/issues)** &mdash; check if the issue has already been reported.
1. Use the [GitHub issue search](https://github.com/videojs/video.js/issues) &mdash; check if the issue has already been reported.
2. **Check if the issue has been fixed** &mdash; try to reproduce it using the latest `master` branch in the repository.
2. Check if the issue has already been fixed &mdash; try to reproduce it using the latest `master` branch in the repository.
3. **Isolate the problem** &mdash; ideally create a [reduced test
case](http://css-tricks.com/6263-reduced-test-cases/) and a live example.
3. Isolate the problem &mdash; **create a [reduced test case](http://css-tricks.com/6263-reduced-test-cases/)** with a live example. You can possibly use [this JSBin example](http://jsbin.com/axedog/7/edit) as a starting point.
A good bug report shouldn't leave others needing to chase you up for more information. Please try to be as detailed as possible in your report. What is your environment? What steps will reproduce the issue? What browser(s), OS, and devices experience the problem? What would you expect to be the outcome? All these
details will help people to fix any potential bugs.
A good bug report should be as detailed as possible, so that others won't have to follow up for the essential details.
Example:
Here's an example:
> Short and descriptive example bug report title
> Short yet concise Bug Summary
>
> A summary of the issue and the browser/OS environment in which it occurs. If
> suitable, include the steps required to reproduce the bug.
> Description:
> Happens on Windows 7 and OSX. Seen with IE9, Firefox 19 OSX, Chrome 21, Flash 11.6 and 11.2
>
> 1. This is the first step
> 2. This is the second step
> 3. Further steps, etc.
>
> `<url>` (a link to the reduced test case)
> Expected:
> (describe the expected outcome of the steps above)
>
> Actual:
> (describe what actually happens)
>
> `<url>` (a link to the reduced test case, if it exists)
>
> Any other information you want to share that is relevant to the issue being
> reported. This might include the lines of code that you have identified as
> causing the bug, and potential solutions (and your opinions on their
> merits).
**[File a bug report](https://github.com/h5bp/html5-boilerplate/issues/)**
**[File a bug report](https://github.com/videojs/video.js/issues/new)**
### NOTE: Testing Flash Locally in Chrome
Chrome 21+ (as of 2013/01/01) doens't run Flash files that are local and loaded into a locally accessed page (file:///). To get around this you need to [disable the version of Flash](http://helpx.adobe.com/flash-player/kb/flash-player-google-chrome.html#How_can_I_run_debugger_or_alternate_versions_of_Flash_Player_in_Google_Chrome) included with Chrome and enable a system-wide version of Flash.
### Requesting a Feature
1. [Check the plugin list](https://github.com/videojs/video.js/wiki/Plugins) for any plugins that may already support the feature.
2. [Search the issues](https://github.com/videojs/video.js/issues) for any previous requests for the same feature, and give a thumbs up or +1 on existing requests.
2. If no previous requests exist, create a new issue. Please be as clear as possible about why the feautre is needed and the intended use case.
**[Request a feature](https://github.com/videojs/video.js/issues/new)**
Contributing code
-----------------
To contibute code you'll need to be able to build a copy of Video.js and run tests locally. There are a few requirements before getting started.
- Node.js -- Video.js uses Node for build and test automation. Node is available for Windows, Mac OS X, Linux, and SunOS, as well as source code if that doesn't scare you. [Download and install Node.js](http://nodejs.org/download/)
- grunt-cli -- Install grunt-cli globally so that you will have the correct version of grunt available for any project that needs it.
On Unix-based systems, you'll have to do this as a superuser:
```bash
sudo npm install -g grunt-cli
```
On Windows, you can just run:
```bash
npm install -g grunt-cli
```
- Contribflow -- A homegrown git workflow tool for managing feature/hotfix branches and submitting pull requests. If you have your own preferred git workflow, contribflow isn't required, but the following instructions will assume you're using it.
On Unix-based systems, you'll have to do this as a superuser:
```bash
sudo npm install -g contribflow
```
On Windows, you can just run:
```bash
npm install -g contribflow
```
### Building your own copy of Video.js
First, [fork](http://help.github.com/fork-a-repo/) the video.js git repository. At the top of every github page, there is a Fork button. Click it, and the forking process will copy Video.js into your own GitHub account.
Clone your fork of the repo into your code directory
```bash
git clone https://github.com/<your-username>/video.js.git
```
Navigate to the newly cloned directory
```bash
cd video.js
```
Assign the original repo to a remote called "upstream"
```
git remote add upstream https://github.com/videojs/video.js.git
```
>In the future, if you want to pull in updates to video.js that happened after you cloned the main repo, you can run:
>
> ```bash
> git checkout master
> git pull upstream master
> ```
Install the required node.js modules using node package manager
```bash
npm install
```
> A note to Windows developers: If you run npm commands, and you find that your command prompt colors have suddenly reversed, you can configure npm to set color to false to prevent this from happening.
> `npm config set color false`
> Note that this change takes effect when a new command prompt window is opened; the current window will not be affected.
Build a local copy of video.js and run tests
```bash
grunt
grunt test
```
At this point you should have a built copy of video.js in a directory named `dist`, and all tests should be passing.
### Making Changes
Whether you're adding something new, making something better, or fixing a bug, you'll first want to search the [GitHub issues](https://github.com/videojs/video.js/issues) and [plugins list](https://github.com/videojs/video.js/wiki/Plugins) to make sure you're aware of any previous discussion or work. If an unclaimed issue exists, claim it via a comment. If no issue exists for your change, submit one, follwing the [issue filing guidelines](#filing-issues).
There are two categories of changes in video.js land, features and hotfixes (Video.js follows a branching model similar to [gitflow](http://nvie.com/posts/a-successful-git-branching-model/)). Hotfixes are for urgent fixes that need to be released immediately as a patch. Features are for everything else (including non-urgent fixes). If you think you have a hotfix scenario, verify that (via comment) before starting the work. We'll focus on features here, but you can swap `hotfix` for `feature` in any command.
Start a new development branch
```bash
contrib feature start
```
You'll be prompted to name the branch. After that, contrib will create the branch locally, and use git to push it up to your origin, and track it. You're now ready to start building your feature or fixing that bug! Be sure to read the [Code Style Guide](#code-style-guide).
While you're developing, you can ensure your changes are working by writing tests (in the `test` directory) and running `grunt test`.
There's also a sandbox directory where you can add any file and it won't get tracked as a change. To start you can copy the example index file and see a working version of a player (using the local source code) by loading it in a browser.
```bash
cp sandbox/index.html.example sandbox/index.html
open sandbox/index.html
```
> #### NOTE: Testing Flash Locally in Chrome
> Chrome 21+ (as of 2013/01/01) doens't run Flash files that are local and loaded into a locally accessed page (file:///).
> To get around this you can do either of the following:
>
> 1. Do your development and testing using a local HTTP server.
>
> 2. [Disable the version of Flash included with Chrome](http://helpx.adobe.com/flash-player/kb/flash-player-google-chrome.html#How_can_I_run_debugger_or_alternate_versions_of_Flash_Player_in_Google_Chrome) and enable a system-wide version of Flash instead.
## Pull requests
Commit and push changes as you go (using git directly). Write thorough descriptions of your changes in your commit messages.
Good pull requests - patches, improvements, new features - are a fantastic help. They should remain focused in scope and avoid containing unrelated commits. If your contribution involves a significant amount of work or substantial changes to any part of the project, please open an issue to discuss it first.
```bash
git add .
git commit -av
git push
```
Make sure to adhere to the coding conventions used throughout a project (indentation, accurate comments, etc.). Please update any documentation that is relevant to the change you're making.
> GitHub allows you to close an issue through your commit message using the [fixes](https://github.com/blog/831-issues-2-0-the-next-generation) keyword.
>
> ```bash
> My commit message. fixes #123
> Testing: (briefly describe any testing here, for example, 'unit tests and cross-browser manual tests around playback and network interruption')
> ```
Please follow this process; it's the best way to get your work included in the project:
### Submitting your changes
1. [Fork](http://help.github.com/fork-a-repo/) the project, clone your fork, and configure the remotes:
First, thoroughly test your feature or fix, including writing tests to make sure your change doesn't get regressed in a future update. If you're fixing a bug, we recommend in addition to testing the fix itself, to do some testing around the areas that your fix has touched. For example, a brief smoketest of the player never hurts.
```bash
# Clones your fork of the repo into the current directory in terminal
git clone https://github.com/<your-username>/html5-boilerplate.git
# Navigate to the newly cloned directory
cd html5-boilerplate
# Assigns the original repo to a remote called "upstream"
git remote add upstream https://github.com/h5bp/html5-boilerplate.git
```
Make sure your changes are pushed to origin
2. If you cloned a while ago, get the latest changes from upstream:
```bash
git push
```
```bash
git checkout master
git pull upstream master
```
Use contrib to submit a a pull request (make sure you're in your feature branch)
3. Create a new topic branch to contain your feature, change, or fix:
```bash
contrib feature submit
```
```bash
git checkout -b <topic-branch-name>
```
You'll be prompted for title and description for the Pull Request. After that, contrib will use Git to submit your pull request to video.js.
4. Commit your changes in logical chunks. Please adhere to these [git commit message guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) or your pull request is unlikely be merged into the main project. Use git's [interactive rebase](https://help.github.com/articles/interactive-rebase) feature to tidy up your commits before making them public.
You're Done! (except for cleanup.) To clean up your feature or hotfix branch:
5. Locally merge (or rebase) the upstream development branch into your topic branch:
First, checkout your feature or issue branch:
```bash
git pull [--rebase] upstream master
```
```bash
git checkout (branchname)
```
6. Push your topic branch up to your fork:
Run this command to clean up your feature:
```bash
git push origin <topic-branch-name>
```
```bash
contrib feature delete
```
10. [Open a Pull Request](http://help.github.com/send-pull-requests/) with a clear title and description.
Run this command to clean up your bug fix:
# Code Style
```bash
contrib hotfix delete
```
> PLEASE NOTE: THIS WILL DELETE YOUR LOCAL AND REMOTE COPIES OF THE FEATURE.
> This is meant to clean up your local and remote branches, so make sure any changes you don't want to lose have been pulled into the parent project or another branch first.
Code Style Guide
----------------
Please follow [Google's JavaScript Style Guide](http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml) to the letter. If your editor supports [.editorconfig](http://editorconfig.org/#download) it will make it easier to manage differences from your own coding style.
### Style examples include:
@@ -162,11 +251,6 @@ Please follow [Google's JavaScript Style Guide](http://google-styleguide.googlec
If you happen to find something in the codebase that does not follow the style guide, that's a good opportunity to make your first contribution!
# Other Video.js Pojects
* [Video.js SWF](https://github.com/zencoder/video-js-swf) - The light-weight flash video player that makes flash work like HTML5 video. This allows player skins, plugins, and other features to work with both HTML5 and Flash.
* [Videojs.com](http://videojs.com) - The public site with helpful tools and information about Video.js.
---
### Doc Credit
This doc was inspired by some great contribution guide examples including [contribute.md template](https://github.com/contribute-md/contribute-md-template),
+70 -31
Ver Arquivo
@@ -1,8 +1,9 @@
module.exports = function(grunt) {
var pkg, s3, semver, version, verParts;
var pkg, s3, semver, version, verParts, uglify;
semver = require('semver');
pkg = grunt.file.readJSON('package.json');
uglify = require('uglify-js');
try {
s3 = grunt.file.readJSON('.s3config.json');
@@ -60,7 +61,7 @@ module.exports = function(grunt) {
minified_api: ['test/minified-api.html']
},
watch: {
files: [ 'src/**/*.js', 'test/unit/*.js' ],
files: [ 'src/**/*', 'test/unit/*.js', 'Gruntfile.js' ],
tasks: 'dev'
},
copy: {
@@ -77,17 +78,8 @@ module.exports = function(grunt) {
},
s3: {
options: s3,
prod: {
// Files to be uploaded.
minor: {
upload: [
{
src: 'dist/cdn/*',
dest: 'vjs/'+version.full+'/',
rel: 'dist/cdn/',
headers: {
'Cache-Control': 'public, max-age=31536000'
}
},
{
src: 'dist/cdn/*',
dest: 'vjs/'+version.majorMinor+'/',
@@ -97,6 +89,34 @@ module.exports = function(grunt) {
}
}
]
},
patch: {
upload: [
{
src: 'dist/cdn/*',
dest: 'vjs/'+version.full+'/',
rel: 'dist/cdn/',
headers: {
'Cache-Control': 'public, max-age=31536000'
}
}
]
}
},
cssmin: {
minify: {
expand: true,
cwd: 'build/files/',
src: ['video-js.css'],
dest: 'build/files/',
ext: '.min.css'
}
},
less: {
dev: {
files: {
'build/files/video-js.css': 'src/css/video-js.less'
}
}
}
});
@@ -106,14 +126,16 @@ module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-s3');
grunt.loadNpmTasks('contribflow');
// Default task.
grunt.registerTask('default', ['jshint', 'build', 'minify', 'dist']);
grunt.registerTask('default', ['jshint', 'less', 'build', 'minify', 'dist']);
// Development watch task
grunt.registerTask('dev', ['jshint', 'build', 'qunit:source']);
grunt.registerTask('test', ['jshint', 'build', 'minify', 'qunit']);
grunt.registerTask('dev', ['jshint', 'less', 'build', 'qunit:source']);
grunt.registerTask('test', ['jshint', 'less', 'build', 'minify', 'qunit']);
var fs = require('fs'),
gzip = require('zlib').gzip;
@@ -133,28 +155,34 @@ module.exports = function(grunt) {
sourceFiles[i] = sourceFiles[i].replace(/\\/g, '/');
}
// grunt.file.write('build/files/sourcelist.txt', sourceList.join(','));
// Allow time for people to update their index.html before they remove these
// grunt.file.write('build/files/sourcelist.js', 'var sourcelist = ["' + sourceFiles.join('","') + '"]');
// Create a combined sources file. https://github.com/zencoder/video-js/issues/287
var combined = '';
sourceFiles.forEach(function(result){
combined += grunt.file.read(result);
});
// Replace CDN version ref in js. Use major/minor version.
combined = combined.replace(/GENERATED_CDN_VSN/g, version.majorMinor);
grunt.file.write('build/files/combined.video.js', combined);
grunt.file.copy('src/css/video-js.css', 'build/files/video-js.css');
grunt.file.copy('src/css/video-js.png', 'build/files/video-js.png');
// Copy over other files
// grunt.file.copy('src/css/video-js.png', 'build/files/video-js.png');
grunt.file.copy('src/swf/video-js.swf', 'build/files/video-js.swf');
// grunt.file.copy('src/css/font/', 'build/files/font/');
// Inject version number into css file
var css = grunt.file.read('build/files/video-js.css');
css = css.replace(/GENERATED_AT_BUILD/g, version.full);
grunt.file.write('build/files/video-js.css', css);
// Copy over font files
grunt.file.recurse('src/css/font', function(absdir, rootdir, subdir, filename) {
// Block .DS_Store files
if ('filename'.substring(0,1) !== '.') {
grunt.file.copy(absdir, 'build/files/font/' + filename);
}
});
// Minify CSS
grunt.task.run(['cssmin']);
});
grunt.registerMultiTask('minify', 'Minify JS files using Closure Compiler.', function() {
@@ -175,24 +203,26 @@ module.exports = function(grunt) {
filePatterns = filePatterns.concat(this.data.src);
}
// Build closure compiler shell command
var command = 'java -jar build/compiler/compiler.jar'
+ ' --compilation_level ADVANCED_OPTIMIZATIONS'
// + ' --formatting=pretty_print'
+ ' --js_output_file=' + dest
+ ' --create_source_map ' + dest + '.map --source_map_format=V3'
+ ' --jscomp_warning=checkTypes --warning_level=VERBOSE'
+ ' --output_wrapper "/*! ' + pkg.copyright + ' */\n (function() {%output%})();//@ sourceMappingURL=video.js.map"';
+ ' --output_wrapper "/*! Video.js v' + version.full + ' ' + pkg.copyright + ' */ (function() {%output%})();//@ sourceMappingURL=video.js.map"';
// Add each js file
grunt.file.expand(filePatterns).forEach(function(file){
command += ' --js='+file;
});
// Add externs
externs.forEach(function(extern){
command += ' --externs='+extern;
});
// grunt.log.writeln(command)
// Run command
exec(command, { maxBuffer: 500*1024 }, function(err, stdout, stderr){
if (err) {
@@ -211,14 +241,18 @@ module.exports = function(grunt) {
grunt.registerTask('dist', 'Creating distribution', function(){
var exec = require('child_process').exec;
var done = this.async();
var css, jsmin, jsdev, cdnjs;
// Manually copy each source file
grunt.file.copy('build/files/minified.video.js', 'dist/video-js/video.js');
grunt.file.copy('build/files/combined.video.js', 'dist/video-js/video.dev.js');
grunt.file.copy('build/files/video-js.css', 'dist/video-js/video-js.css');
grunt.file.copy('build/files/video-js.min.css', 'dist/video-js/video-js.min.css');
grunt.file.copy('build/files/video-js.swf', 'dist/video-js/video-js.swf');
grunt.file.copy('build/demo-files/demo.html', 'dist/video-js/demo.html');
grunt.file.copy('build/demo-files/demo.captions.vtt', 'dist/video-js/demo.captions.vtt');
// Copy over font files
grunt.file.recurse('build/files/font', function(absdir, rootdir, subdir, filename) {
// Block .DS_Store files
if ('filename'.substring(0,1) !== '.') {
@@ -227,18 +261,23 @@ module.exports = function(grunt) {
});
// CDN version uses already hosted font files
// Minified version only
// doesn't need demo files
// Minified version only, doesn't need demo files
grunt.file.copy('build/files/minified.video.js', 'dist/cdn/video.js');
grunt.file.copy('build/files/video-js.css', 'dist/cdn/video-js.css');
grunt.file.copy('build/files/video-js.min.css', 'dist/cdn/video-js.css');
grunt.file.copy('build/files/video-js.swf', 'dist/cdn/video-js.swf');
var css = grunt.file.read('dist/cdn/video-js.css');
// Replace font urls with CDN versions
css = grunt.file.read('dist/cdn/video-js.css');
css = css.replace(/font\//g, '../f/1/');
grunt.file.write('dist/cdn/video-js.css', css);
// Add CDN-specfic JS
jsmin = grunt.file.read('dist/cdn/video.js');
// GA Tracking Pixel (manually building the pixel URL)
cdnjs = uglify.minify('src/js/cdn.js').code.replace('v0.0.0', 'v'+version.full);
grunt.file.write('dist/cdn/video.js', jsmin + cdnjs);
// Zip up into video-js-VERSION.zip
exec('cd dist && zip -r video-js-'+version.full+'.zip video-js && cd ..', { maxBuffer: 500*1024 }, function(err, stdout, stderr){
if (err) {
+8 -40
Ver Arquivo
@@ -1,50 +1,18 @@
# [Video.js - HTML5 and Flash Video Player](http://videojs.com) [![Build Status](https://travis-ci.org/zencoder/video-js.png?branch=master)](https://travis-ci.org/zencoder/video-js)
# [Video.js - HTML5 Video Player](http://videojs.com) [![Build Status](https://travis-ci.org/zencoder/video-js.png?branch=master)](https://travis-ci.org/zencoder/video-js)
Visit the main site at [videojs.com](http://videojs.com) for download options and instructions.
> 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.
### PLEASE EXCUSE OUR DUST
We're finishing up a big overhaul of the libary which includes
* Closure compiler advanced mode support for drastically better minification over previous versions
* Flashy new automated builds and test using node.js and grunt
Check out our [contributing guide](https://github.com/zencoder/video-js/blob/master/CONTRIBUTING.md) for info on building a local version.
## About
Video.js was built to provide a fast and easy way to embed and work with video in a web page.
It was built from the ground up with the assumption that HTML5 is the future of web video, however it supports Flash equally well for older browsers and for advanced features not yet supported in HTML5.
Some of the focuses of Video.js are:
- Universal browser and device support
- Fast player loading
- Easily skinned (themed/chromed) using just CSS
- A JavaScript API for controlling the video that works consistently across video platforms (HTML5, Flash, and soon other players like youtube) as well as devices
## Getting Started
Check out our [getting started guide](http://videojs.com/#section5).
Visit [videojs.com](http://videojs.com) for an overview, download options, and instructions on how to use the player on your site.
## Contributing
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).
Check out our [contributing guide](https://github.com/zencoder/video-js/blob/master/CONTRIBUTING.md).
## Building your own Video.js from source
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.
## License
Video.js is licensed under the Apache License, Version 2.0. [View the license file](LICENSE)
Copyright 2013 Brightcove, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-5
Ver Arquivo
@@ -1,5 +0,0 @@
---
major: 3
minor: 2
patch: 3
pre:
+1 -1
Ver Arquivo
@@ -23,7 +23,7 @@
<source src="http://video-js.zencoder.com/oceans-clip.mp4" type='video/mp4' />
<source src="http://video-js.zencoder.com/oceans-clip.webm" type='video/webm' />
<source src="http://video-js.zencoder.com/oceans-clip.ogv" type='video/ogg' />
<track kind="captions" src="demo.captions.vtt" srclang="en" label="English" />
<track kind="captions" src="demo.captions.vtt" srclang="en" label="English"></track><!-- Tracks need an ending tag thanks to IE9 -->
</video>
</body>
+4 -3
Ver Arquivo
@@ -1,6 +1,7 @@
{
"owner": "videojs",
"project": "video.js",
"developmentBranch": "master",
"releaseBranch": "stable",
"remote": "origin",
"upstream": "zencoder"
}
"remote": "origin"
}
+10 -2
Ver Arquivo
@@ -165,10 +165,10 @@ myPlayer.height(480);
```
### size(width, height) ###
### dimensions(width, height) ###
Changes the width and height of the video to the supplied width and height. This is more efficient if you're changing both width and height (only triggers the player's resize event once). Returns the player object.
```js
myPlayer.size(640,480);
myPlayer.dimensions(640,480);
```
@@ -186,6 +186,14 @@ myPlayer.cancelFullScreen();
```
### dispose() ###
Destroys the video player and does any necessary cleanup. This is especially helpful if you are dynamically adding and removing videos to/from the DOM. Use after removing videos from the DOM.
```js
myPlayer.dispose();
```
Events
------
You can attach event listeners to the player similarly to how you would for a video element.
+2 -2
Ver Arquivo
@@ -2,7 +2,7 @@
<h1>Video.js Documentation</h1>
The Video.js documentation is here to help you setup and use the player. These docs can be found and contributed to in the [Video.js library repository](https://github.com/zencoder/video-js/tree/master/docs).
The Video.js documentation is here to help you setup and use the player. These docs can be found and contributed to in the [Video.js library repository](https://github.com/videojs/video.js/tree/master/docs).
## Getting Started
@@ -24,4 +24,4 @@ The Video.js documentation is here to help you setup and use the player. These d
## Resources
* [Glossary](glossary.md) - Some helpful definitions.
* [Glossary](glossary.md) - Some helpful definitions.
+2 -2
Ver Arquivo
@@ -12,8 +12,8 @@ You can download the Video.js source and host it on your own servers, or use the
### CDN Version ###
```html
<link href="http://vjs.zencdn.net/4.0/video-js.css" rel="stylesheet">
<script src="http://vjs.zencdn.net/4.0/video.js"></script>
<link href="http://vjs.zencdn.net/4.1/video-js.css" rel="stylesheet">
<script src="http://vjs.zencdn.net/4.1/video.js"></script>
```
### Self Hosted. ###
+7 -5
Ver Arquivo
@@ -1,21 +1,23 @@
Skins
=====
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. New in version 3.0 is the use of a sprites image file (video-js.png). The image allows for a little bit more classy design, as well as compatibility with older versions of IE now that the HTML skin also shows when Flash is used for those browsers.
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.
You can view the uncompressed CSS for the default skin by downloading the latest version of Video.js or viewing [the source version](https://github.com/videojs/video.js/blob/master/src/css/video-js.css) on Github.
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.
You can either override styles in the default skin:
The easiest way to try this out is by using the [player skin designer](http://designer.videojs.com/).
When you create a new skin, you can either override styles in the default skin:
```css
.vjs-default-skin .vjs-play-progress { background: #900; }
```
Or remove the 'vjs-default-skin' class from the video tag and create your own skin.
Or remove the 'vjs-default-skin' class from the video tag and create a new skin from scratch.
```html
<video class="video-js my-custom-skin" ...>
```
More custom skins will be available for download soon. If you have one you'd like to contribute back, please email it to skins at videojs.
More custom skins will be available for download soon. If you have one you like you can share it by forking [this example on CodePen.io](http://codepen.io/heff/pen/EarCt), and adding a link on the [Skins wiki page](https://github.com/videojs/video.js/wiki/Skins).
+18
Ver Arquivo
@@ -49,6 +49,24 @@ When adding additional Tech to a video player, make sure to add the supported te
techOrder: ["html5", "flash", "other supported tech"]
});
Flash Technology
==================
The Flash playback tech is a part of the default `techOrder`. You may notice undesirable playback behavior in browsers that are subject to using this playback tech, in particular when scrubbing and seeking within a video. This behavior is a result of Flash's progressive video playback.
Enabling Streaming Playback
--------------------------------
In order to force the Flash tech to choose streaming playback, you need to provide a valid streaming source **before other valid Flash video sources**. This is necessary because of the source selection algorithm, where playback tech chooses the first possible source object with a valid type. Valid streaming `type` values include `rtmp/mp4` and `rtmp/flv`. The streaming `src` value requires valid connection and stream strings, separated by an `&`. An example of supplying a streaming source through your HTML markup might look like:
<source src="rtmp://your.streaming.provider.net/cfx/st/&mp4:path/to/video.mp4" type="rtmp/mp4">
<source src="http://your.static.provider.net/path/to/video.mp4" type="video/mp4">
<source src="http://your.static.provider.net/path/to/video.webm" type="video/webm">
You may optionally use the last `/` as the separator between connection and stream strings, for example:
<source src="rtmp://your.streaming.provider.net/cfx/st/mp4:video.mp4" type="rtmp/mp4">
All four RTMP protocols are valid in the `src` (RTMP, RTMPT, RTMPE, and RTMPS).
Youtube Technology
==================
To add a youtube source to your video tag, use the following source:
+5 -2
Ver Arquivo
@@ -1,7 +1,7 @@
{
"name": "video.js",
"description": "An HTML5 and Flash video player with a common API and skin for both.",
"version": "4.0.0",
"version": "4.2.0",
"copyright": "Copyright 2013 Brightcove, Inc. https://github.com/videojs/video.js/blob/master/LICENSE",
"keywords": [
"html5",
@@ -30,7 +30,10 @@
"mocha": "~1.8.1",
"contribflow": "~0.2.0",
"grunt-s3": "~0.2.0-alpha",
"semver": "~1.1.4"
"semver": "~1.1.4",
"grunt-contrib-cssmin": "~0.6.0",
"uglify-js": "~2.3.6",
"grunt-contrib-less": "~0.6.4"
},
"testling": {
"browsers": [
+7 -1
Ver Arquivo
@@ -4,11 +4,16 @@
<meta charset="utf-8" />
<title>Video.js Sandbox</title>
<link href="../src/css/video-js.css" rel="stylesheet" type="text/css">
<link href="../build/files/video-js.css" rel="stylesheet" type="text/css">
<!-- LOAD VIDEO.JS SOURCE FILES IN ORDER -->
<script src="../build/source-loader.js"></script>
<!-- Set the location of the flash SWF -->
<script>
vjs.options.flash.swf = '../src/swf/video-js.swf'
</script>
</head>
<body>
<p style="background-color:#eee; border: 1px solid #777; padding: 10px; font-size: .8em; line-height: 1.5em; font-family: Verdana, sans-serif;">You can use /sandbox/ for writing and testing your own code. Nothing in /sandbox/ will get checked into the repo, except files that end in .example, so please don't edit or add those files. To get started make a copy of index.html.example and rename it to index.html.</p>
@@ -19,6 +24,7 @@
<source src="http://video-js.zencoder.com/oceans-clip.mp4" type='video/mp4'>
<source src="http://video-js.zencoder.com/oceans-clip.webm" type='video/webm'>
<source src="http://video-js.zencoder.com/oceans-clip.ogv" type='video/ogg'>
<track kind="captions" src="../build/demo-files/demo.captions.vtt" srclang="en" label="English"></track><!-- Tracks need an ending tag thanks to IE9 -->
<p>Video Playback Not Supported</p>
</video>
+1 -1
Ver Arquivo
@@ -4,7 +4,7 @@
<meta charset="utf-8" />
<title>Video.js Plugin Example</title>
<link href="../src/css/video-js.css" rel="stylesheet" type="text/css">
<link href="../build/files/video-js.css" rel="stylesheet" type="text/css">
<!-- LOAD VIDEO.JS SOURCE FILES IN ORDER -->
<script src="../build/source-loader.js"></script>
-730
Ver Arquivo
@@ -1,730 +0,0 @@
/*
VideoJS Default Styles (http://videojs.com)
Version GENERATED_AT_BUILD
*/
/*
REQUIRED STYLES (be careful overriding)
================================================================================ */
/* When loading the player, the video tag is replaced with a DIV,
that will hold the video tag or object tag for other playback methods.
The div contains the video playback element (Flash or HTML5) and controls, and sets the width and height of the video.
** If you want to add some kind of border/padding (e.g. a frame), or special positioning, use another containing element.
Otherwise you risk messing up control positioning and full window mode. **
*/
.video-js {
background-color: #000;
position: relative;
padding: 0;
/* Start with 10px for base font size so other dimensions can be em based and easily calculable. */
font-size: 10px;
/* Allow poster to be vertially aligned. */
vertical-align: middle;
/* display: table-cell; */ /*This works in Safari but not Firefox.*/
}
/* Playback technology elements expand to the width/height of the containing div.
<video> or <object> */
.video-js .vjs-tech {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
/* Fix for Firefox 9 fullscreen (only if it is enabled). Not needed when checking fullScreenEnabled. */
.video-js:-moz-full-screen { position: absolute; }
/* Fullscreen Styles */
body.vjs-full-window {
padding: 0;
margin: 0;
height: 100%;
overflow-y: auto; /* Fix for IE6 full-window. http://www.cssplay.co.uk/layouts/fixed.html */
}
.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; /* IE6 Full-window (underscore hack) */
}
.video-js:-webkit-full-screen {
width: 100% !important; height: 100% !important;
}
/* Poster Styles */
.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%;
}
/* Text Track Styles */
/* Overall track holder for both captions and subtitles */
.video-js .vjs-text-track-display {
text-align: center;
position: absolute;
bottom: 4em;
left: 1em; /* Leave padding on left and right */
right: 1em;
font-family: Arial, sans-serif;
}
/* Individual tracks */
.video-js .vjs-text-track {
display: none;
font-size: 1.4em;
text-align: center;
margin-bottom: 0.1em;
/* Transparent black background, or fallback to all black (oldIE) */
background: rgb(0, 0, 0); background: rgba(0, 0, 0, 0.50);
}
.video-js .vjs-subtitles { color: #fff; } /* Subtitles are white */
.video-js .vjs-captions { color: #fc6; } /* Captions are yellow */
.vjs-tt-cue { display: block; }
/* Fading sytles, used to fade control bar. */
.vjs-fade-in {
display: block !important;
visibility: visible; /* Needed to make sure things hide in older browsers too. */
opacity: 1;
-webkit-transition: visibility 0.1s, opacity 0.1s;
-moz-transition: visibility 0.1s, opacity 0.1s;
-ms-transition: visibility 0.1s, opacity 0.1s;
-o-transition: visibility 0.1s, opacity 0.1s;
transition: visibility 0.1s, opacity 0.1s;
}
.vjs-fade-out {
display: block !important;
visibility: hidden;
opacity: 0;
-webkit-transition: visibility 1.5s, opacity 1.5s;
-moz-transition: visibility 1.5s, opacity 1.5s;
-ms-transition: visibility 1.5s, opacity 1.5s;
-o-transition: visibility 1.5s, opacity 1.5s;
transition: visibility 1.5s, opacity 1.5s;
/* Wait a moment before fading out the control bar */
-webkit-transition-delay: 2s;
-moz-transition-delay: 2s;
-ms-transition-delay: 2s;
-o-transition-delay: 2s;
transition-delay: 2s;
}
/* Hide disabled or unsupported controls */
.vjs-default-skin .vjs-hidden { display: none; }
.vjs-lock-showing {
display: block !important;
opacity: 1;
visibility: visible;
}
/* DEFAULT SKIN (override in another file to create new skins)
================================================================================
Instead of editing this file, I recommend creating your own skin CSS file to be included after this file,
so you can upgrade to newer versions easier. You can remove all these styles by removing the 'vjs-default-skin' class from the tag. */
/* Base UI Component Classes
-------------------------------------------------------------------------------- */
@font-face{
font-family: 'VideoJS';
src: url('font/vjs.eot');
src: url('font/vjs.eot') format('embedded-opentype'),
url('font/vjs.woff') format('woff'),
url('font/vjs.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
.vjs-default-skin {
color: #ccc;
}
/* Slider - used for Volume bar and Seek bar */
.vjs-default-skin .vjs-slider {
outline: 0; /* Replace browser focus hightlight with handle highlight */
position: relative;
cursor: pointer;
padding: 0;
background: rgb(50, 50, 50); /* IE8- Fallback */
background: rgba(100, 100, 100, 0.5);
}
.vjs-default-skin .vjs-slider:focus {
background: rgb(70, 70, 70); /* IE8- Fallback */
background: rgba(100, 100, 100, 0.70);
-webkit-box-shadow: 0 0 2em rgba(255, 255, 255, 1);
-moz-box-shadow: 0 0 2em rgba(255, 255, 255, 1);
box-shadow: 0 0 2em rgba(255, 255, 255, 1);
}
.vjs-default-skin .vjs-slider-handle {
position: absolute;
/* Needed for IE6 */
left: 0;
top: 0;
}
.vjs-default-skin .vjs-slider-handle:before {
/*content: "\f111";*/ /* Circle icon = f111 */
content: "\e009"; /* Square icon */
font-family: VideoJS;
font-size: 1em;
line-height: 1;
text-align: center;
text-shadow: 0em 0em 1em #fff;
position: absolute;
top: 0;
left: 0;
/* Rotate the square icon to make a diamond */
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
}
/* Control Bar
-------------------------------------------------------------------------------- */
/* The default control bar. Created by controls.js */
.vjs-default-skin .vjs-control-bar {
display: none; /* Start hidden */
position: absolute;
/* Distance from the bottom of the box/video. Keep 0. Use height to add more bottom margin. */
bottom: 0;
/* 100% width of player div */
left: 0;
right: 0;
/* Controls are absolutely position, so no padding necessary */
padding: 0;
margin: 0;
/* Height includes any margin you want above or below control items */
height: 3.0em;
background-color: rgb(0, 0, 0);
/* Slight blue so it can be seen more easily on black. */
background-color: rgba(7, 40, 50, 0.7);
/* Default font settings */
font-style: normal;
font-weight: normal;
font-family: Arial, sans-serif;
}
/* General styles for individual controls. */
.vjs-default-skin .vjs-control {
outline: none;
position: relative;
float: left;
text-align: center;
margin: 0;
padding: 0;
height: 3.0em;
width: 4em;
}
/* FontAwsome button icons */
.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,0.5);
}
/* Replacement for focus outline */
.vjs-default-skin .vjs-control:focus:before,
.vjs-default-skin .vjs-control:hover:before {
text-shadow: 0em 0em 1em rgba(255, 255, 255, 1);
}
.vjs-default-skin .vjs-control:focus { /* outline: 0; */ /* keyboard-only users cannot see the focus on several of the UI elements when this is set to 0 */ }
/* Hide control text visually, but have it available for screenreaders: h5bp.com/v */
.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; }
/* Play/Pause
-------------------------------------------------------------------------------- */
.vjs-default-skin .vjs-play-control {
width: 5em;
cursor: pointer;
}
.vjs-default-skin .vjs-play-control:before {
content: "\e001"; /* Play Icon */
}
.vjs-default-skin.vjs-playing .vjs-play-control:before {
content: "\e002"; /* Pause Icon */
}
/* Rewind
-------------------------------------------------------------------------------- */
/*.vjs-default-skin .vjs-rewind-control { width: 5em; cursor: pointer !important; }
.vjs-default-skin .vjs-rewind-control div { width: 19px; height: 16px; background: url('video-js.png'); margin: 0.5em auto 0; }
*/
/* Volume/Mute
-------------------------------------------------------------------------------- */
.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"; /* Full volume */
}
.vjs-default-skin .vjs-mute-control.vjs-vol-0:before,
.vjs-default-skin .vjs-volume-menu-button.vjs-vol-0:before {
content: "\e003"; /* No volume */
}
.vjs-default-skin .vjs-mute-control.vjs-vol-1:before,
.vjs-default-skin .vjs-volume-menu-button.vjs-vol-1:before {
content: "\e004"; /* Half volume */
}
.vjs-default-skin .vjs-mute-control.vjs-vol-2:before,
.vjs-default-skin .vjs-volume-menu-button.vjs-vol-2:before {
content: "\e005"; /* Full volume */
}
.vjs-default-skin .vjs-volume-control {
width: 5em;
float: right;
}
.vjs-default-skin .vjs-volume-bar {
width: 5em;
height: 0.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: 0.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: 0.5em;
height: 0.5em;
}
.vjs-default-skin .vjs-volume-handle:before {
font-size: 0.9em;
top: -0.2em;
left: -0.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-menu-button .vjs-volume-control {
height: 1.5em;
}*/
/* Progress
-------------------------------------------------------------------------------- */
.vjs-default-skin .vjs-progress-control {
position: absolute;
left: 0;
right: 0;
width: auto;
font-size: 0.3em;
height: 1em;
/* Set above the rest of the controls. */
top: -1em;
/* Shrink the bar slower than it grows. */
-webkit-transition: top 0.4s, height 0.4s, font-size 0.4s, -webkit-transform 0.4s;
-moz-transition: top 0.4s, height 0.4s, font-size 0.4s, -moz-transform 0.4s;
-o-transition: top 0.4s, height 0.4s, font-size 0.4s, -o-transform 0.4s;
transition: top 0.4s, height 0.4s, font-size 0.4s, transform 0.4s;
}
/* On hover, make the progress bar grow to something that's more clickable.
This simply changes the overall font for the progress bar, and this
updates both the em-based widths and heights, as wells as the icon font */
.vjs-default-skin:hover .vjs-progress-control {
font-size: .9em;
/* Even though we're not changing the top/height, we need to include them in
the transition so they're handled correctly. */
-webkit-transition: top 0.2s, height 0.2s, font-size 0.2s, -webkit-transform 0.2s;
-moz-transition: top 0.2s, height 0.2s, font-size 0.2s, -moz-transform 0.2s;
-o-transition: top 0.2s, height 0.2s, font-size 0.2s, -o-transform 0.2s;
transition: top 0.2s, height 0.2s, font-size 0.2s, transform 0.2s;
}
/* Box containing play and load progresses. Also acts as seek scrubber. */
.vjs-default-skin .vjs-progress-holder {
/* Placement within the progress control item */
height: 100%;
}
/* Progress Bars */
.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;
/* Needed for IE6 */
left: 0;
top: 0;
}
.vjs-default-skin .vjs-play-progress {
/*
Using a data URI to create the white diagonal lines with a transparent
background. Surprising works in IE8.
Created using http://www.patternify.com
Changing the first color value will change the bar color.
Also using a paralax effect to make the lines move backwards.
The -50% left position makes that happen.
*/
background: #66A8CC
url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAP0lEQVQIHWWMAQoAIAgDR/QJ/Ub//04+w7ZICBwcOg5FZi5iBB82AGzixEglJrd4TVK5XUJpskSTEvpdFzX9AB2pGziSQcvAAAAAAElFTkSuQmCC)
-50% 0 repeat;
}
.vjs-default-skin .vjs-load-progress {
background: rgb(100, 100, 100); /* IE8- Fallback */
background: rgba(255, 255, 255, 0.4);
}
.vjs-default-skin .vjs-seek-handle {
width: 1.5em;
height: 100%;
}
.vjs-default-skin .vjs-seek-handle:before {
padding-top: 0.1em; /* Minor adjustment */
}
/* Time Display
-------------------------------------------------------------------------------- */
.vjs-default-skin .vjs-time-controls {
font-size: 1em;
/* Align vertically by making the line height the same as the control bar */
line-height: 3em;
}
.vjs-default-skin .vjs-current-time { float: left; }
.vjs-default-skin .vjs-duration { float: left; }
/* Remaining time is in the HTML, but not included in default design */
.vjs-default-skin .vjs-remaining-time { display: none; float: left; }
.vjs-time-divider { float: left; line-height: 3em; }
/* Fullscreen
-------------------------------------------------------------------------------- */
.vjs-default-skin .vjs-fullscreen-control {
width: 3.8em;
cursor: pointer;
float: right;
}
.vjs-default-skin .vjs-fullscreen-control:before {
content: "\e000"; /* Enter full screen */
}
.vjs-default-skin.vjs-fullscreen .vjs-fullscreen-control:before {
content: "\e00b"; /* Exit full screen */
}
/* Big Play Button (at start)
---------------------------------------------------------*/
.vjs-default-skin .vjs-big-play-button {
display: block;
z-index: 2;
position: absolute;
top: 2em;
left: 2em;
width: 12.0em;
height: 8.0em;
margin: 0;
text-align: center;
vertical-align: middle;
cursor: pointer;
opacity: 1;
/* Need a slightly gray bg so it can be seen on black backgrounds */
background-color: rgb(40, 40, 40);
background-color: rgba(7, 40, 50, 0.7);
border: 0.3em solid rgb(50, 50, 50);
border-color: rgba(255, 255, 255, 0.25);
-webkit-border-radius: 25px;
-moz-border-radius: 25px;
border-radius: 25px;
-webkit-box-shadow: 0px 0px 1em rgba(255, 255, 255, 0.25);
-moz-box-shadow: 0px 0px 1em rgba(255, 255, 255, 0.25);
box-shadow: 0px 0px 1em rgba(255, 255, 255, 0.25);
-webkit-transition: border 0.4s, -webkit-box-shadow 0.4s, -webkit-transform 0.4s;
-moz-transition: border 0.4s, -moz-box-shadow 0.4s, -moz-transform 0.4s;
-o-transition: border 0.4s, -o-box-shadow 0.4s, -o-transform 0.4s;
transition: border 0.4s, box-shadow 0.4s, transform 0.4s;
}
.vjs-default-skin:hover .vjs-big-play-button,
.vjs-default-skin .vjs-big-play-button:focus {
outline: 0;
border-color: rgb(255, 255, 255);
border-color: rgba(255, 255, 255, 1);
/* IE8 needs a non-glow hover state */
background-color: rgb(80, 80, 80);
background-color: rgba(50, 50, 50, 0.75);
-webkit-box-shadow: 0 0 3em #fff;
-moz-box-shadow: 0 0 3em #fff;
box-shadow: 0 0 3em #fff;
-webkit-transition: border 0s, -webkit-box-shadow 0s, -webkit-transform 0s;
-moz-transition: border 0s, -moz-box-shadow 0s, -moz-transform 0s;
-o-transition: border 0s, -o-box-shadow 0s, -o-transform 0s;
transition: border 0s, box-shadow 0s, transform 0s;
}
.vjs-default-skin .vjs-big-play-button:before {
content: "\e001"; /* Play icon */
font-family: VideoJS;
font-size: 3em;
line-height: 2.66;
text-shadow: 0.05em 0.05em 0.1em #000;
text-align: center; /* Needed for IE8 */
position: absolute;
left: 0;
width: 100%;
height: 100%;
}
/* Loading Spinner
---------------------------------------------------------*/
.vjs-loading-spinner {
display: none;
position: absolute;
top: 50%;
left: 50%;
font-size: 5em;
line-height: 1;
width: 1em;
height: 1em;
margin-left: -0.5em;
margin-top: -0.5em;
opacity: 0.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"; /* Loading spinner icon */
font-family: VideoJS;
position: absolute;
width: 1em;
height: 1em;
text-align: center;
text-shadow: 0em 0em 0.1em #000;
}
/* Add a gradient to the spinner by overlaying another copy.
Text gradient plus a text shadow doesn't work
and `background-clip: text` only works in Webkit. */
.vjs-default-skin .vjs-loading-spinner:after {
content: "\e00a"; /* Loading spinner icon */
font-family: VideoJS;
position: absolute;
width: 1em;
height: 1em;
text-align: center;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
@-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); }
}
@-ms-keyframes spin {
0% { -ms-transform: rotate(0deg); }
100% { -ms-transform: rotate(359deg); }
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(359deg); }
}
/* Menu Buttons (Captions/Subtitles/etc.)
-------------------------------------------------------------------------------- */
.vjs-default-skin .vjs-menu-button {
float: right;
cursor: pointer;
}
.vjs-default-skin .vjs-menu {
display: none;
position: absolute;
bottom: 0;
left: 0em; /* (Width of vjs-menu - width of button) / 2 */
width: 0em;
height: 0em;
margin-bottom: 3em;
border-left: 2em solid transparent;
border-right: 2em solid transparent;
border-top: 1.55em solid rgb(0, 0, 0); /* Same top as ul bottom */
border-top-color: rgba(7, 40, 50, 0.5); /* Same as ul background */
}
/* Button Pop-up Menu */
.vjs-default-skin .vjs-menu-button .vjs-menu .vjs-menu-content {
display: block;
padding: 0; margin: 0;
position: absolute;
width: 10em;
bottom: 1.5em; /* Same bottom as vjs-menu border-top */
max-height: 15em;
overflow: auto;
left: -5em; /* Width of menu - width of button / 2 */
background-color: rgb(0, 0, 0);
background-color: rgba(7, 40, 50, 0.7);
-webkit-box-shadow: -20px -20px 0px rgba(255, 255, 255, 0.5);
-moz-box-shadow: 0 0 1em rgba(255, 255, 255, 0.5);
box-shadow: -0.2em -0.2em 0.3em rgba(255, 255, 255, 0.2);
}
/*.vjs-default-skin .vjs-menu-button:focus ul,*/ /* This is not needed because keyboard accessibility for the caption button is not handled with the focus any more. */
.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: 0.3em 0 0.3em 0;
line-height: 1.4em;
font-size: 1.2em;
font-weight: normal;
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 {
background-color: rgb(255, 255, 255);
background-color: rgba(255, 255, 255, 0.75);
color: #111;
outline: 0;
-webkit-box-shadow: 0 0 1em rgba(255, 255, 255, 1);
-moz-box-shadow: 0 0 1em rgba(255, 255, 255, 1);
box-shadow: 0 0 1em rgba(255, 255, 255, 1);
}
.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 0.3em 0;
font-weight: bold;
cursor: default;
}
/* Subtitles Button */
.vjs-default-skin .vjs-subtitles-button:before { content: "\e00c"; }
/* There's unfortunately no CC button in FontAwesome, so we need
to manually create one. Please +1 the fontawesome request.
https://github.com/FortAwesome/Font-Awesome/issues/968 */
.vjs-default-skin .vjs-captions-button {
font-size: 1em; /* Font icons are 1.5em */
}
.vjs-default-skin .vjs-captions-button:before {
content: "\e008";
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: none;
}
/* Replacement for focus outline */
.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 rgba(255, 255, 255, 1);
-moz-box-shadow: 0 0 1em rgba(255, 255, 255, 1);
box-shadow: 0 0 1em rgba(255, 255, 255, 1);
}
+936
Ver Arquivo
@@ -0,0 +1,936 @@
/*!
Video.js Default Styles (http://videojs.com)
Version GENERATED_AT_BUILD
Create your own skin at http://designer.videojs.com
*/
// To customize the player skin, change the values of the variables or edit the
// CSS below.
// (This file uses LESS. Learn more at http://lesscss.org/)
// The base font size controls the size of everything, not just text. All
// diminensions use em-based sizes so that the scale along with the font size.
// Try increasing it to 20px and see what happens.
@base-font-size: 10px;
@touch-device-font-size: 15px;
// The main font color controls the color of the text and the icons (font icons)
@main-font-color: #CCCCCC; // e.g. rgb(255, 255, 255) or #ffffff
// The default color of control backgrounds is mostly black but with a little
// bit of blue so it can still be seen on all black video frames, which are
// common.
@control-bg-color: #07141E; // e.g. rgb(255, 255, 255) or #ffffff
@control-bg-alpha: 0.7; // 1.0 = 100% opacity, 0.0 = 0% opacity
// The slider bar color is used for the progress bar and the volume bar
@slider-bar-color: #66A8CC; // e.g. rgb(255, 255, 255) or #ffffff
// The background of the progress bar and volume bar have a lined pattern that
// is created from a base64 encoded image. You can generate your own pattern at
// http://www.patternify.com/ then replace the value in the quotes with your own
@slider-bar-pattern: ~'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAP0lEQVQIHWWMAQoAIAgDR/QJ/Ub//04+w7ZICBwcOg5FZi5iBB82AGzixEglJrd4TVK5XUJpskSTEvpdFzX9AB2pGziSQcvAAAAAAElFTkSuQmCC';
// The color of the slider background
@slider-background-color: #333333;
@slider-background-alpha: 0.9; // 1.0 = 100% opacity, 0.0 = 0% opacity
// The "Big Play Button" is the play button that shows before the video plays.
// To center it set the align values to center and middle. The typical location
// of the button is the center, but there is trend towards moving it to a corner
// where it gets out of the way of valuable content in the poster image.
@big-play-align: left; // left, center, or right
@big-play-vertical-align: top; // top, middle, or bottom
// The button colors match the control colors by default but you can customize
// them by replace the variables (@control-bg-color) with your own color values.
@big-play-bg-color: @control-bg-color;
@big-play-bg-alpha: @control-bg-alpha;
// The font size is what makes the big play button, big. All width/height values
// use ems, which are a multiple of the font size.
// If the @base-font-size is 10px, then 3em equals 30px.
@big-play-font-size: 3em;
// Now that font size is set, the following em values will be a multiple of the
// new font size. If @big-play-font-size is 3em (30px), then setting the any of
// the following values to 2em would equal 60px. 2 * font-size
@big-play-margin: 0.5em;
@big-play-width: 4em;
@big-play-height: 2.6em;
@big-play-border-radius: 0.8em;
@big-play-border-width: 0.1em;
@big-play-border-color: #3b4249;
/* SKIN
================================================================================
The main class name for all skin-specific styles. To make your own skin,
replace all occurances of 'vjs-default-skin' with a new name. Then add your new
skin name to your video tag instead of the default skin.
e.g. <video class="video-js my-skin-name">
*/
.vjs-default-skin {
color: @main-font-color;
}
/* Custom Icon Font
--------------------------------------------------------------------------------
The control icons are from a custom font. Each icon corresponds to a character
(e.g. "\e001"). Font icons allow for easy scaling and coloring of icons.
*/
@font-face{
font-family: 'VideoJS';
src: url('font/vjs.eot');
src: url('font/vjs.eot?#iefix') format('embedded-opentype'),
url('font/vjs.woff') format('woff'),
url('font/vjs.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
// Icon font character values
@play-icon: "\e001";
@pause-icon: "\e002";
@volume-muted-icon: "\e003";
@volume-low-icon: "\e004";
@volume-mid-icon: "\e005";
@volume-high-icon: "\e006";
@fullscreen-enter-icon: "\e000";
@fullscreen-exit-icon: "\e00b";
@square-icon: "\e009";
@spinner-icon: "\e00a";
@subtitles-icon: "\e00c";
@captions-icon: "\e008";
/* Base UI Component Classes
--------------------------------------------------------------------------------
*/
/* Slider - used for Volume bar and Seek bar */
.vjs-default-skin .vjs-slider {
/* Replace browser focus hightlight with handle highlight *///
outline: 0;
position: relative;
cursor: pointer;
padding: 0;
.background-color-with-alpha(@slider-background-color, @slider-background-alpha);
}
.vjs-default-skin .vjs-slider:focus {
.box-shadow(0 0 2em #fff);
}
.vjs-default-skin .vjs-slider-handle {
position: absolute;
/* Needed for IE6 *///
left: 0;
top: 0;
}
.vjs-default-skin .vjs-slider-handle:before {
content: @square-icon;
font-family: VideoJS;
font-size: 1em;
line-height: 1;
text-align: center;
text-shadow: 0em 0em 1em #fff;
position: absolute;
top: 0;
left: 0;
/* Rotate the square icon to make a diamond *///
.transform(rotate(-45deg));
}
/* Control Bar
--------------------------------------------------------------------------------
The default control bar that is a container for most of the controls.
*/
.vjs-default-skin .vjs-control-bar {
/* Start hidden *///
display: none;
position: absolute;
/* Place control bar at the bottom of the player box/video.
If you want more margin below the control bar, add more height. *///
bottom: 0;
/* Use left/right to stretch to 100% width of player div *///
left: 0;
right: 0;
/* Height includes any margin you want above or below control items *///
height: 3.0em;
.background-color-with-alpha(@control-bg-color, @control-bg-alpha);
}
/* Show the control bar only once the video has started playing */
.vjs-default-skin.vjs-has-started .vjs-control-bar {
display: block;
/* Visibility needed to make sure things hide in older browsers too. */
visibility: visible;
opacity: 1;
@trans: visibility 0.1s, opacity 0.1s; // Var needed because of comma
.transition(@trans);
}
/* Hide the control bar when the video is playing and the user is inactive */
.vjs-default-skin.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar {
display: block;
visibility: hidden;
opacity: 0;
@trans: visibility 1.0s, opacity 1.0s;
.transition(@trans);
}
.vjs-default-skin.vjs-controls-disabled .vjs-control-bar {
display: none;
}
.vjs-default-skin.vjs-using-native-controls .vjs-control-bar {
display: none;
}
/* IE8 is flakey with fonts, and you have to change the actual content to force
fonts to show/hide properly.
- "\9" IE8 hack didn't work for this
- Found in XP IE8 from http://modern.ie. Does not show up in "IE8 mode" in IE9
*/
@ie8screen: ~"\0screen";
.vjs-default-skin.vjs-user-inactive.vjs-playing .vjs-control-bar :before {
@media @ie8screen { content: ""; }
}
/* General styles for individual controls. */
.vjs-default-skin .vjs-control {
outline: none;
position: relative;
float: left;
text-align: center;
margin: 0;
padding: 0;
height: 3.0em;
width: 4em;
}
/* FontAwsome button icons */
.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,0.5);
}
/* Replacement for focus outline */
.vjs-default-skin .vjs-control:focus:before,
.vjs-default-skin .vjs-control:hover:before {
text-shadow: 0em 0em 1em rgba(255, 255, 255, 1);
}
.vjs-default-skin .vjs-control:focus {
/* outline: 0; *///
/* keyboard-only users cannot see the focus on several of the UI elements when
this is set to 0 */
}
/* Hide control text visually, but have it available for screenreaders */
.vjs-default-skin .vjs-control-text {
.hide-visually;
}
/* Play/Pause
--------------------------------------------------------------------------------
*/
.vjs-default-skin .vjs-play-control {
width: 5em;
cursor: pointer;
}
.vjs-default-skin .vjs-play-control:before {
content: @play-icon;
}
.vjs-default-skin.vjs-playing .vjs-play-control:before {
content: @pause-icon;
}
/* Volume/Mute
-------------------------------------------------------------------------------- */
.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: @volume-high-icon;
}
.vjs-default-skin .vjs-mute-control.vjs-vol-0:before,
.vjs-default-skin .vjs-volume-menu-button.vjs-vol-0:before {
content: @volume-muted-icon;
}
.vjs-default-skin .vjs-mute-control.vjs-vol-1:before,
.vjs-default-skin .vjs-volume-menu-button.vjs-vol-1:before {
content: @volume-low-icon;
}
.vjs-default-skin .vjs-mute-control.vjs-vol-2:before,
.vjs-default-skin .vjs-volume-menu-button.vjs-vol-2:before {
content: @volume-mid-icon;
}
.vjs-default-skin .vjs-volume-control {
width: 5em;
float: right;
}
.vjs-default-skin .vjs-volume-bar {
width: 5em;
height: 0.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: 0.5em;
background: @slider-bar-color
url(@slider-bar-pattern)
-50% 0 repeat;
}
.vjs-default-skin .vjs-volume-bar .vjs-volume-handle {
width: 0.5em;
height: 0.5em;
}
.vjs-default-skin .vjs-volume-handle:before {
font-size: 0.9em;
top: -0.2em;
left: -0.2em;
width: 1em;
height: 1em;
}
.vjs-default-skin .vjs-volume-menu-button .vjs-menu .vjs-menu-content {
width: 6em;
left: -4em;
}
/* Progress
--------------------------------------------------------------------------------
*/
.vjs-default-skin .vjs-progress-control {
position: absolute;
left: 0;
right: 0;
width: auto;
font-size: 0.3em;
height: 1em;
/* Set above the rest of the controls. *///
top: -1em;
/* Shrink the bar slower than it grows. *///
.transition(all 0.4s);
}
/* On hover, make the progress bar grow to something that's more clickable.
This simply changes the overall font for the progress bar, and this
updates both the em-based widths and heights, as wells as the icon font */
.vjs-default-skin:hover .vjs-progress-control {
font-size: .9em;
/* Even though we're not changing the top/height, we need to include them in
the transition so they're handled correctly. */
.transition(all 0.2s);
}
/* Box containing play and load progresses. Also acts as seek scrubber. */
.vjs-default-skin .vjs-progress-holder {
height: 100%;
}
/* Progress Bars */
.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;
/* Needed for IE6 *///
left: 0;
top: 0;
}
.vjs-default-skin .vjs-play-progress {
/*
Using a data URI to create the white diagonal lines with a transparent
background. Surprisingly works in IE8.
Created using http://www.patternify.com
Changing the first color value will change the bar color.
Also using a paralax effect to make the lines move backwards.
The -50% left position makes that happen.
*/
background: @slider-bar-color
url(@slider-bar-pattern)
-50% 0 repeat;
}
.vjs-default-skin .vjs-load-progress {
background: rgb(100, 100, 100) /* IE8- Fallback */;
background: rgba(255, 255, 255, 0.4);
}
.vjs-default-skin .vjs-seek-handle {
width: 1.5em;
height: 100%;
}
.vjs-default-skin .vjs-seek-handle:before {
padding-top: 0.1em /* Minor adjustment */;
}
/* Time Display
--------------------------------------------------------------------------------
*/
.vjs-default-skin .vjs-time-controls {
font-size: 1em;
/* Align vertically by making the line height the same as the control bar *///
line-height: 3em;
}
.vjs-default-skin .vjs-current-time { float: left; }
.vjs-default-skin .vjs-duration { float: left; }
/* Remaining time is in the HTML, but not included in default design */
.vjs-default-skin .vjs-remaining-time { display: none; float: left; }
.vjs-time-divider { float: left; line-height: 3em; }
/* Fullscreen
--------------------------------------------------------------------------------
*/
.vjs-default-skin .vjs-fullscreen-control {
width: 3.8em;
cursor: pointer;
float: right;
}
.vjs-default-skin .vjs-fullscreen-control:before {
content: @fullscreen-enter-icon;
}
/* Switch to the exit icon when the player is in fullscreen */
.vjs-default-skin.vjs-fullscreen .vjs-fullscreen-control:before {
content: @fullscreen-exit-icon;
}
/* Big Play Button (play button at start)
--------------------------------------------------------------------------------
Positioning of the play button in the center or other corners can be done more
easily in the skin designer. http://designer.videojs.com/
*/
.vjs-default-skin .vjs-big-play-button {
// Calculate total width/height so we're able to center the button
@total-width: @big-play-width + (@big-play-border-width * 2);
@total-height: @big-play-height + (@big-play-border-width * 2);
// Position the button using the absolute-align mixin (bottom of page)
.absolute-align(@big-play-align, @big-play-margin, @total-width);
.absolute-align(@big-play-vertical-align, @big-play-margin, @total-height);
font-size: @big-play-font-size;
display: block;
z-index: 2;
position: absolute;
width: @big-play-width;
height: @big-play-height;
text-align: center;
vertical-align: middle;
cursor: pointer;
opacity: 1;
/* Need a slightly gray bg so it can be seen on black backgrounds *///
.background-color-with-alpha(@big-play-bg-color, @big-play-bg-alpha);
border: @big-play-border-width solid @big-play-border-color;
.border-radius(@big-play-border-radius);
.box-shadow(0px 0px 1em rgba(255, 255, 255, 0.25));
.transition(all 0.4s);
}
/* Hide if controls are disabled */
.vjs-default-skin.vjs-controls-disabled .vjs-big-play-button {
display: none;
}
/* Hide when video starts playing */
.vjs-default-skin.vjs-has-started .vjs-big-play-button {
display: none;
}
/* Hide on mobile devices. Remove when we stop using native controls
by default on mobile */
.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;
/* IE8 needs a non-glow hover state *///
background-color: rgb(80, 80, 80);
background-color: rgba(50, 50, 50, 0.75);
.box-shadow(0 0 3em #fff);
.transition(all 0s);
}
.vjs-default-skin .vjs-big-play-button:before {
content: @play-icon;
font-family: VideoJS;
/* In order to center the play icon vertically we need to set the line height
to the same as the button height */
line-height: @big-play-height;
text-shadow: 0.05em 0.05em 0.1em #000;
text-align: center /* Needed for IE8 */;
position: absolute;
left: 0;
width: 100%;
height: 100%;
}
/* Loading Spinner
--------------------------------------------------------------------------------
*/
.vjs-loading-spinner {
display: none;
position: absolute;
top: 50%;
left: 50%;
font-size: 5em;
line-height: 1;
width: 1em;
height: 1em;
margin-left: -0.5em;
margin-top: -0.5em;
opacity: 0.75;
.animation(spin 1.5s infinite linear);
}
.vjs-default-skin .vjs-loading-spinner:before {
content: @spinner-icon;
font-family: VideoJS;
position: absolute;
top: 0;
left: 0;
width: 1em;
height: 1em;
text-align: center;
text-shadow: 0em 0em 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); }
}
/* Menu Buttons (Captions/Subtitles/etc.)
--------------------------------------------------------------------------------
*/
.vjs-default-skin .vjs-menu-button {
float: right;
cursor: pointer;
}
.vjs-default-skin .vjs-menu {
display: none;
position: absolute;
bottom: 0;
left: 0em; /* (Width of vjs-menu - width of button) / 2 */
width: 0em;
height: 0em;
margin-bottom: 3em;
border-left: 2em solid transparent;
border-right: 2em solid transparent;
border-top: 1.55em solid rgb(0, 0, 0); /* Same width top as ul bottom */
border-top-color: rgba(7, 40, 50, 0.5); /* Same as ul background */
}
/* Button Pop-up Menu */
.vjs-default-skin .vjs-menu-button .vjs-menu .vjs-menu-content {
display: block;
padding: 0; margin: 0;
position: absolute;
width: 10em;
bottom: 1.5em; /* Same bottom as vjs-menu border-top */
max-height: 15em;
overflow: auto;
left: -5em; /* Width of menu - width of button / 2 */
.background-color-with-alpha(@control-bg-color, @control-bg-alpha);
.box-shadow(-0.2em -0.2em 0.3em rgba(255, 255, 255, 0.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: 0.3em 0 0.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-with-alpha(rgb(255, 255, 255), 0.75);
.box-shadow(0 0 1em rgba(255, 255, 255, 1));
}
.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 0.3em 0;
font-weight: bold;
cursor: default;
}
/* Subtitles Button */
.vjs-default-skin .vjs-subtitles-button:before { content: @subtitles-icon; }
/* Captions Button */
.vjs-default-skin .vjs-captions-button:before {
content: @captions-icon;
}
/* Replacement for focus outline */
.vjs-default-skin .vjs-captions-button:focus .vjs-control-content:before,
.vjs-default-skin .vjs-captions-button:hover .vjs-control-content:before {
.box-shadow(0 0 1em rgba(255, 255, 255, 1));
}
/*
REQUIRED STYLES (be careful overriding)
================================================================================
When loading the player, the video tag is replaced with a DIV,
that will hold the video tag or object tag for other playback methods.
The div contains the video playback element (Flash or HTML5) and controls,
and sets the width and height of the video.
** If you want to add some kind of border/padding (e.g. a frame), or special
positioning, use another containing element. Otherwise you risk messing up
control positioning and full window mode. **
*/
.video-js {
background-color: #000;
position: relative;
padding: 0;
/* Start with 10px for base font size so other dimensions can be em based and
easily calculable. */
font-size: @base-font-size;
/* Allow poster to be vertially aligned. */
vertical-align: middle;
/* display: table-cell; */ /*This works in Safari but not Firefox.*/
/* Provide some basic defaults for fonts */
font-weight: normal;
font-style: normal;
/* Avoiding helvetica: issue #376 */
font-family: Arial, sans-serif;
/* Turn off user selection (text highlighting) by default.
The majority of player components will not be text blocks.
Text areas will need to turn user selection back on. */
.user-select(none);
}
/* Playback technology elements expand to the width/height of the containing div
<video> or <object> */
.video-js .vjs-tech {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
/* Fix for Firefox 9 fullscreen (only if it is enabled). Not needed when
checking fullScreenEnabled. */
.video-js:-moz-full-screen { position: absolute; }
/* Fullscreen Styles */
body.vjs-full-window {
padding: 0;
margin: 0;
height: 100%;
/* Fix for IE6 full-window. http://www.cssplay.co.uk/layouts/fixed.html *///
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;
/* IE6 full-window (underscore hack) *///
_position: absolute;
}
.video-js:-webkit-full-screen {
width: 100% !important;
height: 100% !important;
}
.video-js.vjs-fullscreen.vjs-user-inactive {
cursor: none;
}
/* Poster Styles */
.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%;
}
/* Hide the poster when native controls are used otherwise it covers them */
.video-js.vjs-using-native-controls .vjs-poster {
display: none;
}
/* Text Track Styles */
/* Overall track holder for both captions and subtitles */
.video-js .vjs-text-track-display {
text-align: center;
position: absolute;
bottom: 4em;
/* Leave padding on left and right *///
left: 1em;
right: 1em;
}
/* Individual tracks */
.video-js .vjs-text-track {
display: none;
font-size: 1.4em;
text-align: center;
margin-bottom: 0.1em;
/* Transparent black background, or fallback to all black (oldIE) *///
.background-color-with-alpha(rgb(0, 0, 0), 0.5);
}
.video-js .vjs-subtitles { color: #fff /* Subtitles are white */; }
.video-js .vjs-captions { color: #fc6 /* Captions are yellow */; }
.vjs-tt-cue { display: block; }
/* Hide disabled or unsupported controls */
.vjs-default-skin .vjs-hidden { display: none; }
.vjs-lock-showing {
display: block !important;
opacity: 1;
visibility: visible;
}
// MIXINS
// =============================================================================
// Mixins are a LESS feature and are used to add vendor prefixes to CSS rules
// when needed.
// https://developer.mozilla.org/en-US/docs/Web/CSS/box-shadow
.box-shadow (@string: 0 0 1em rgba(0, 0, 0, 0.25)) {
/* box-shadow *///
-webkit-box-shadow: @string;
-moz-box-shadow: @string;
box-shadow: @string;
}
// https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius
.border-radius (@string: 5px) {
/* border-radius *///
-webkit-border-radius: @string;
-moz-border-radius: @string;
border-radius: @string;
}
// https://developer.mozilla.org/en-US/docs/Web/CSS/transition
.transition (@string: all 1s linear) {
/* transition *///
-webkit-transition: @string;
-moz-transition: @string;
-o-transition: @string;
transition: @string;
}
// https://developer.mozilla.org/en-US/docs/Web/CSS/transition
.transition-delay (@string: 1s) {
/* transition-delay *///
-webkit-transition-delay: @string;
-moz-transition-delay: @string;
-o-transition-delay: @string;
transition-delay: @string;
}
// https://developer.mozilla.org/en-US/docs/Web/CSS/animation
.animation (@string: spin 1s infinite linear) {
/* animation *///
-webkit-animation: @string;
-moz-animation: @string;
-o-animation: @string;
animation: @string;
}
// https://developer.mozilla.org/en-US/docs/Web/CSS/transform
.transform (@string: rotate(-45deg)) {
/* transform *///
-webkit-transform: @string;
-moz-transform: @string;
-ms-transform: @string;
-o-transform: @string;
transform: @string;
}
// https://developer.mozilla.org/en-US/docs/Web/CSS/user-select
.user-select (@string: none) {
/* user-select *///
-webkit-user-select: @string;
-moz-user-select: @string;
-ms-user-select: @string;
user-select: @string;
}
// Hide something visually but keep available for screen readers.
// http://h5bp.com/v
.hide-visually () {
/* hide-visually *///
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position:
absolute;
width: 1px;
}
// Align an object with absolute positioning
// Used to align the Big Play Button in the corners or center
.absolute-align (@align, @margin, @length) when (@align = top) {
top: @margin;
}
.absolute-align (@align, @margin, @length) when (@align = bottom) {
bottom: @margin;
}
.absolute-align (@align, @margin, @length) when (@align = left) {
left: @margin;
}
.absolute-align (@align, @margin, @length) when (@align = right) {
right: @margin;
}
.absolute-align (@align, @margin, @length) when (@align = center) {
/* Center it horizontally *///
left: 50%;
margin-left: -(@length / 2);
}
.absolute-align (@align, @margin, @length) when (@align = middle) {
/* Center it vertically *///
top: 50%;
margin-top: -(@length / 2);
}
// http://stackoverflow.com/questions/637921/opacity-of-background-but-not-the-text
.background-color-with-alpha (@color, @alpha) {
@rgba: rgba(red(@color), green(@color), blue(@color), @alpha);
/* background-color-with-alpha *///
background-color: @color;
background-color: @rgba;
// No longer using MS filters because they break border radius in IE9
// @argb: argb(@rgba);
// filter: ~"progid:DXImageTransform.Microsoft.gradient(startColorstr=@{argb}, endColorstr=@{argb})";
// -ms-filter: ~"progid:DXImageTransform.Microsoft.gradient(startColorstr=@{argb}, endColorstr=@{argb})";
}
.border-color-with-alpha (@color, @alpha) {
@rgba: rgba(red(@color), green(@color), blue(@color), @alpha);
/* border-color-with-alpha *///
border-color: @color;
border-color: @rgba;
}
// NOTES ON LESS (tracking learnings so we don't forget)
// =============================================================================
// * We want this file to continue to be accessible by people who don't know
// LESS but know CSS. This means finding the balance between using the most
// valuable LESS features (e.g. variables) and keeping it looking like CSS.
// So it's best to avoid advanced LESS features like conditional statements.
// (we're using one for the big play button position because that's a hot
// topic)
//
// * We care about the readability of the CSS output of LESS, which means we
// have to be careful about what features of LESS we use. (if you're building
// your own skin this may not apply)
// 1. Comments inside of rules (strangely) have an extra line added after
// them in the CSS output. To avoid this we can add a LESS comment after
// the CSS comment.
// /* comment *///
//
// 2. In a rule with nested rules, any comments outside of a rule are moved
// to the top of the parent rule. i.e. it might look like:
// /* title of rule 1 */
// /* title of rule 2 */
// .rule1 {}
// .rule2 {}
// This is why we aren't using nested rules inside of the
// vjs-default-skin class.
/* -----------------------------------------------------------------------------
The original source of this file lives at
https://github.com/videojs/video.js/blob/master/src/css/video-js.less */
+3 -19
Ver Arquivo
@@ -1,24 +1,13 @@
/* Big Play Button
================================================================================ */
/**
* Initial play button. Shows before the video has played.
* Initial play button. Shows before the video has played. The hiding of the
* big play button is done via CSS and player states.
* @param {vjs.Player|Object} player
* @param {Object=} options
* @constructor
*/
vjs.BigPlayButton = vjs.Button.extend({
/** @constructor */
init: function(player, options){
vjs.Button.call(this, player, options);
if (!player.controls()) {
this.hide();
}
player.on('play', vjs.bind(this, this.hide));
// player.on('ended', vjs.bind(this, this.show));
}
});
vjs.BigPlayButton = vjs.Button.extend();
vjs.BigPlayButton.prototype.createEl = function(){
return vjs.Button.prototype.createEl.call(this, 'div', {
@@ -29,10 +18,5 @@ vjs.BigPlayButton.prototype.createEl = function(){
};
vjs.BigPlayButton.prototype.onClick = function(){
// Go back to the beginning if big play button is showing at the end.
// Have to check for current time otherwise it might throw a 'not ready' error.
//if(this.player_.currentTime()) {
//this.player_.currentTime(0);
//}
this.player_.play();
};
+3 -2
Ver Arquivo
@@ -12,7 +12,9 @@ vjs.Button = vjs.Component.extend({
vjs.Component.call(this, player, options);
var touchstart = false;
this.on('touchstart', function() {
this.on('touchstart', function(event) {
// Stop click and other mouse events from triggering also
event.preventDefault();
touchstart = true;
});
this.on('touchmove', function() {
@@ -24,7 +26,6 @@ vjs.Button = vjs.Component.extend({
self.onClick(event);
}
event.preventDefault();
event.stopPropagation();
});
this.on('click', this.onClick);
+56
Ver Arquivo
@@ -0,0 +1,56 @@
/**
* Google Analytics tracking pixel for the freely hosted version of Video.js
* at vjs.zencdn.net. We'll use this data to develop a support matrix of
* browsers and devices, and possibly track errors.
*
* This code generates the GA tracking URL without requiring the GA javascript
* library.
*
* @type {Image}
*/
;(function(i,w,n,e,l){
l=w.location;
// Setting the source of an image will load the URL even without adding to dom
// Using //www, still seems to work for https even though ssl.google is used by google
i.src='//www.google-analytics.com/__utm.gif'
// Version
+'?utmwv=5.4.2'
// ID
+'&utmac=UA-16505296-2'
// Sessions
// &utms=2
// Cache breaker (using utmcc to do this)
+'&utmn='+1
+'&utmhn='+e(l.hostname)
// Encoding
// &utmcs=UTF-8
+'&utmsr='+w.screen.availWidth+'x'+w.screen.availHeight
// Browser window
// &utmvp=1057x1105
// Color depth
// &utmsc=24-bit
+'&utmul='+(n.language||n.userLanguage||'').toLowerCase()
// Java
// &utmje=1
// Flash version
// &utmfl=11.7%20r700
// Page title
// &utmdt=HTML5%20Video%20Player%20%7C%20Video.js
// Adsense
// &utmhid=1112291628
// Referrer, '-' is none
// Using current page as referrer so stats show up cleaner than "Direct"
+'&utmr='+e(l.href)
+'&utmp='+e(l.hostname+l.pathname)
// Current time stamp
// &utmht=1370890439353
// ?
// &utmu=q
// Cookies! Manually setting visitor ID and setting everything else to 1
// Random number used as cache buster instead of utmn
+'&utmcc=__utma%3D1.'+Math.floor(Math.random()*1e10)+'.1.1.1.1%3B'
// Custom Var: vjsv is the variable name and 1.0.0 is the VJS version
+'&utme=8(vjsv)9(v0.0.0)'
;
})(new Image(),window,navigator,encodeURIComponent);
+49 -27
Ver Arquivo
@@ -45,6 +45,8 @@ vjs.Component = vjs.CoreObject.extend({
* Dispose of the component and all child components.
*/
vjs.Component.prototype.dispose = function(){
this.trigger('dispose');
// Dispose all children.
if (this.children_) {
for (var i = this.children_.length - 1; i >= 0; i--) {
@@ -537,26 +539,6 @@ vjs.Component.prototype.hide = function(){
return this;
};
/**
* Fade a component in using CSS
* @return {vjs.Component}
*/
vjs.Component.prototype.fadeIn = function(){
this.removeClass('vjs-fade-out');
this.addClass('vjs-fade-in');
return this;
};
/**
* Fade a component out using CSS
* @return {vjs.Component}
*/
vjs.Component.prototype.fadeOut = function(){
this.removeClass('vjs-fade-in');
this.addClass('vjs-fade-out');
return this;
};
/**
* Lock an item in its visible state. To be used with fadeIn/fadeOut.
* @return {vjs.Component}
@@ -581,15 +563,8 @@ vjs.Component.prototype.unlockShowing = function(){
vjs.Component.prototype.disable = function(){
this.hide();
this.show = function(){};
this.fadeIn = function(){};
};
// TODO: Get enable working
// vjs.Component.prototype.enable = function(){
// this.fadeIn = vjs.Component.prototype.fadeIn;
// this.show = vjs.Component.prototype.show;
// };
/**
* If a value is provided it will change the width of the player to that value
* otherwise the width is returned
@@ -691,3 +666,50 @@ vjs.Component.prototype.dimension = function(widthOrHeight, num, skipListeners){
// }
}
};
/**
* Emit 'tap' events when touch events are supported. We're requireing them to
* be enabled because otherwise every component would have this extra overhead
* unnecessarily, on mobile devices where extra overhead is especially bad.
*
* This is being implemented so we can support taps on the video element
* toggling the controls.
*/
vjs.Component.prototype.emitTapEvents = function(){
var touchStart, touchTime, couldBeTap, noTap;
// Track the start time so we can determine how long the touch lasted
touchStart = 0;
this.on('touchstart', function(event) {
// Record start time so we can detect a tap vs. "touch and hold"
touchStart = new Date().getTime();
// Reset couldBeTap tracking
couldBeTap = true;
});
noTap = function(){
couldBeTap = false;
};
// TODO: Listen to the original target. http://youtu.be/DujfpXOKUp8?t=13m8s
this.on('touchmove', noTap);
this.on('touchleave', noTap);
this.on('touchcancel', noTap);
// When the touch ends, measure how long it took and trigger the appropriate
// event
this.on('touchend', function() {
// Proceed only if the touchmove/leave/cancel event didn't happen
if (couldBeTap === true) {
// Measure how long the touch lasted
touchTime = new Date().getTime() - touchStart;
// The touch needs to be quick in order to consider it a tap
if (touchTime < 250) {
this.trigger('tap');
// It may be good to copy the touchend event object and change the
// type to tap, if the other event properties aren't exact after
// vjs.fixEvent runs (e.g. event.target)
}
}
});
};
+1 -59
Ver Arquivo
@@ -4,55 +4,7 @@
* @param {Object=} options
* @constructor
*/
vjs.ControlBar = vjs.Component.extend({
/** @constructor */
init: function(player, options){
vjs.Component.call(this, player, options);
if (!player.controls()) {
this.disable();
}
player.one('play', vjs.bind(this, function(){
var touchstart,
fadeIn = vjs.bind(this, this.fadeIn),
fadeOut = vjs.bind(this, this.fadeOut);
this.fadeIn();
if ( !('ontouchstart' in window) ) {
this.player_.on('mouseover', fadeIn);
this.player_.on('mouseout', fadeOut);
this.player_.on('pause', vjs.bind(this, this.lockShowing));
this.player_.on('play', vjs.bind(this, this.unlockShowing));
}
touchstart = false;
this.player_.on('touchstart', function() {
touchstart = true;
});
this.player_.on('touchmove', function() {
touchstart = false;
});
this.player_.on('touchend', vjs.bind(this, function(event) {
var idx;
if (touchstart) {
idx = this.el().className.search('fade-in');
if (idx !== -1) {
this.fadeOut();
} else {
this.fadeIn();
}
}
touchstart = false;
if (!this.player_.paused()) {
event.preventDefault();
}
}));
}));
}
});
vjs.ControlBar = vjs.Component.extend();
vjs.ControlBar.prototype.options_ = {
loadEvent: 'play',
@@ -75,13 +27,3 @@ vjs.ControlBar.prototype.createEl = function(){
className: 'vjs-control-bar'
});
};
vjs.ControlBar.prototype.fadeIn = function(){
vjs.Component.prototype.fadeIn.call(this);
this.player_.trigger('controlsvisible');
};
vjs.ControlBar.prototype.fadeOut = function(){
vjs.Component.prototype.fadeOut.call(this);
this.player_.trigger('controlshidden');
};
+3 -3
Ver Arquivo
@@ -12,11 +12,11 @@ vjs.MuteToggle = vjs.Button.extend({
player.on('volumechange', vjs.bind(this, this.update));
// hide mute toggle if the current tech doesn't support volume control
if (player.tech && player.tech.features && player.tech.features.volumeControl === false) {
if (player.tech && player.tech.features && player.tech.features['volumeControl'] === false) {
this.addClass('vjs-hidden');
}
player.on('loadstart', vjs.bind(this, function(){
if (player.tech.features && player.tech.features.volumeControl === false) {
if (player.tech.features && player.tech.features['volumeControl'] === false) {
this.addClass('vjs-hidden');
} else {
this.removeClass('vjs-hidden');
@@ -66,4 +66,4 @@ vjs.MuteToggle.prototype.update = function(){
vjs.removeClass(this.el_, 'vjs-vol-'+i);
}
vjs.addClass(this.el_, 'vjs-vol-'+level);
};
};
+19 -1
Ver Arquivo
@@ -65,7 +65,25 @@ vjs.SeekBar.prototype.updateARIAAttributes = function(){
};
vjs.SeekBar.prototype.getPercent = function(){
return this.player_.currentTime() / this.player_.duration();
var currentTime;
// Flash RTMP provider will not report the correct time
// immediately after a seek. This isn't noticeable if you're
// seeking while the video is playing, but it is if you seek
// while the video is paused.
if (this.player_.techName === 'Flash' && this.player_.seeking()) {
var cache = this.player_.getCache();
if (cache.lastSetCurrentTime) {
currentTime = cache.lastSetCurrentTime;
}
else {
currentTime = this.player_.currentTime();
}
}
else {
currentTime = this.player_.currentTime();
}
return currentTime / this.player_.duration();
};
vjs.SeekBar.prototype.onMouseDown = function(event){
+5 -6
Ver Arquivo
@@ -65,8 +65,9 @@ vjs.DurationDisplay.prototype.createEl = function(){
};
vjs.DurationDisplay.prototype.updateContent = function(){
if (this.player_.duration()) {
this.content.innerHTML = '<span class="vjs-control-text">Duration Time </span>' + vjs.formatTime(this.player_.duration()); // label the duration time for screen reader users
var duration = this.player_.duration();
if (duration) {
this.content.innerHTML = '<span class="vjs-control-text">Duration Time </span>' + vjs.formatTime(duration); // label the duration time for screen reader users
}
};
@@ -122,12 +123,10 @@ vjs.RemainingTimeDisplay.prototype.createEl = function(){
vjs.RemainingTimeDisplay.prototype.updateContent = function(){
if (this.player_.duration()) {
if (this.player_.duration()) {
this.content.innerHTML = '<span class="vjs-control-text">Remaining Time </span>' + '-'+ vjs.formatTime(this.player_.remainingTime());
}
this.content.innerHTML = '<span class="vjs-control-text">Remaining Time </span>' + '-'+ vjs.formatTime(this.player_.remainingTime());
}
// Allows for smooth scrubbing, when player can't keep up.
// var time = (this.player_.scrubbing) ? this.player_.getCache().currentTime : this.player_.currentTime();
// this.content.innerHTML = vjs.formatTime(time, this.player_.duration());
};
};
+3 -3
Ver Arquivo
@@ -10,11 +10,11 @@ vjs.VolumeControl = vjs.Component.extend({
vjs.Component.call(this, player, options);
// hide volume controls when they're not supported by the current tech
if (player.tech && player.tech.features && player.tech.features.volumeControl === false) {
if (player.tech && player.tech.features && player.tech.features['volumeControl'] === false) {
this.addClass('vjs-hidden');
}
player.on('loadstart', vjs.bind(this, function(){
if (player.tech.features && player.tech.features.volumeControl === false) {
if (player.tech.features && player.tech.features['volumeControl'] === false) {
this.addClass('vjs-hidden');
} else {
this.removeClass('vjs-hidden');
@@ -131,4 +131,4 @@ vjs.VolumeLevel.prototype.createEl = function(){
return vjs.SliderHandle.prototype.createEl.call(this, 'div', {
className: 'vjs-volume-handle'
});
};
};
+17 -9
Ver Arquivo
@@ -3,7 +3,9 @@
*/
// HTML5 Shiv. Must be in <head> to support older browsers.
document.createElement('video');document.createElement('audio');
document.createElement('video');
document.createElement('audio');
document.createElement('track');
/**
* Doubles as the main function for users to create a player instance and also
@@ -71,7 +73,7 @@ vjs.options = {
// techOrder: ['flash','html5'],
'html5': {},
'flash': { 'swf': vjs.ACCESS_PROTOCOL + 'vjs.zencdn.net/4.0/video-js.swf' },
'flash': {},
// Default of web browser is 300x150. Should rely on source width/height.
'width': 300,
@@ -87,17 +89,23 @@ vjs.options = {
'loadingSpinner': {},
'bigPlayButton': {},
'controlBar': {}
}
},
// Default message to show when a video cannot be played.
'notSupportedMessage': 'Sorry, no compatible source and playback ' +
'technology were found for this video. Try using another browser ' +
'like <a href="http://bit.ly/ccMUEC">Chrome</a> or download the ' +
'latest <a href="http://adobe.ly/mwfN1">Adobe Flash Player</a>.'
};
// Set CDN Version of swf
// The added (+) blocks the replace from changing this GENERATED_CDN_VSN string
if (vjs.CDN_VERSION !== 'GENERATED'+'_CDN_VSN') {
videojs.options['flash']['swf'] = vjs.ACCESS_PROTOCOL + 'vjs.zencdn.net/'+vjs.CDN_VERSION+'/video-js.swf';
}
/**
* Global player list
* @type {Object}
*/
vjs.players = {};
// Set CDN Version of swf
if (vjs.CDN_VERSION != 'GENERATED_CDN_VSN') {
videojs.options['flash']['swf'] = vjs.ACCESS_PROTOCOL + 'vjs.zencdn.net/'+vjs.CDN_VERSION+'/video-js.swf';
}
+12 -6
Ver Arquivo
@@ -174,7 +174,10 @@ vjs.fixEvent = function(event) {
// which makes copying more difficult.
// TODO: Probably best to create a whitelist of event props
for (var key in old) {
event[key] = old[key];
// Safari 6.0.3 warns you if you try to copy deprecated layerX/Y
if (key !== 'layerX' && key !== 'layerY') {
event[key] = old[key];
}
}
// The event occurred on this element
@@ -274,8 +277,9 @@ vjs.trigger = function(elem, event) {
elemData.dispatcher.call(elem, event);
}
// Unless explicitly stopped, recursively calls this function to bubble the event up the DOM.
if (parent && !event.isPropagationStopped()) {
// Unless explicitly stopped or the event does not bubble (e.g. media events)
// recursively calls this function to bubble the event up the DOM.
if (parent && !event.isPropagationStopped() && event.bubbles !== false) {
vjs.trigger(parent, event);
// If at the top of the DOM, triggers the default action unless disabled.
@@ -326,8 +330,10 @@ vjs.trigger = function(elem, event) {
* @return {[type]}
*/
vjs.one = function(elem, type, fn) {
vjs.on(elem, type, function(){
vjs.off(elem, type, arguments.callee);
var func = function(){
vjs.off(elem, type, func);
fn.apply(this, arguments);
});
};
func.guid = fn.guid = fn.guid || vjs.guid++;
vjs.on(elem, type, func);
};
+13
Ver Arquivo
@@ -29,6 +29,7 @@ goog.exportSymbol('videojs', vjs);
goog.exportSymbol('_V_', vjs);
goog.exportSymbol('videojs.options', vjs.options);
goog.exportSymbol('videojs.players', vjs.players);
// Allow external components to use global cache
goog.exportSymbol('videojs.cache', vjs.cache);
@@ -37,6 +38,7 @@ goog.exportSymbol('videojs.cache', vjs.cache);
// goog.exportProperty(vjs.CoreObject, 'create', vjs.CoreObject.create);
goog.exportSymbol('videojs.Component', vjs.Component);
goog.exportProperty(vjs.Component.prototype, 'player', vjs.Component.prototype.player);
goog.exportProperty(vjs.Component.prototype, 'dispose', vjs.Component.prototype.dispose);
goog.exportProperty(vjs.Component.prototype, 'createEl', vjs.Component.prototype.createEl);
goog.exportProperty(vjs.Component.prototype, 'el', vjs.Component.prototype.el);
@@ -53,9 +55,15 @@ goog.exportProperty(vjs.Component.prototype, 'width', vjs.Component.prototype.wi
goog.exportProperty(vjs.Component.prototype, 'height', vjs.Component.prototype.height);
goog.exportProperty(vjs.Component.prototype, 'dimensions', vjs.Component.prototype.dimensions);
goog.exportProperty(vjs.Component.prototype, 'ready', vjs.Component.prototype.ready);
goog.exportProperty(vjs.Component.prototype, 'addClass', vjs.Component.prototype.addClass);
goog.exportProperty(vjs.Component.prototype, 'removeClass', vjs.Component.prototype.removeClass);
goog.exportSymbol('videojs.Player', vjs.Player);
goog.exportProperty(vjs.Player.prototype, 'dispose', vjs.Player.prototype.dispose);
goog.exportProperty(vjs.Player.prototype, 'requestFullScreen', vjs.Player.prototype.requestFullScreen);
goog.exportProperty(vjs.Player.prototype, 'cancelFullScreen', vjs.Player.prototype.cancelFullScreen);
goog.exportProperty(vjs.Player.prototype, 'bufferedPercent', vjs.Player.prototype.bufferedPercent);
goog.exportProperty(vjs.Player.prototype, 'usingNativeControls', vjs.Player.prototype.usingNativeControls);
goog.exportSymbol('videojs.MediaLoader', vjs.MediaLoader);
goog.exportSymbol('videojs.TextTrackDisplay', vjs.TextTrackDisplay);
@@ -79,11 +87,16 @@ goog.exportSymbol('videojs.SeekHandle', vjs.SeekHandle);
goog.exportSymbol('videojs.VolumeControl', vjs.VolumeControl);
goog.exportSymbol('videojs.VolumeBar', vjs.VolumeBar);
goog.exportSymbol('videojs.VolumeLevel', vjs.VolumeLevel);
goog.exportSymbol('videojs.VolumeMenuButton', vjs.VolumeMenuButton);
goog.exportSymbol('videojs.VolumeHandle', vjs.VolumeHandle);
goog.exportSymbol('videojs.MuteToggle', vjs.MuteToggle);
goog.exportSymbol('videojs.PosterImage', vjs.PosterImage);
goog.exportSymbol('videojs.Menu', vjs.Menu);
goog.exportSymbol('videojs.MenuItem', vjs.MenuItem);
goog.exportSymbol('videojs.MenuButton', vjs.MenuButton);
goog.exportProperty(vjs.MenuButton.prototype, 'createItems', vjs.MenuButton.prototype.createItems);
goog.exportProperty(vjs.TextTrackButton.prototype, 'createItems', vjs.TextTrackButton.prototype.createItems);
goog.exportProperty(vjs.ChaptersButton.prototype, 'createItems', vjs.ChaptersButton.prototype.createItems);
goog.exportSymbol('videojs.SubtitlesButton', vjs.SubtitlesButton);
goog.exportSymbol('videojs.CaptionsButton', vjs.CaptionsButton);
+70 -37
Ver Arquivo
@@ -7,9 +7,11 @@ var hasOwnProp = Object.prototype.hasOwnProperty;
* @return {Element}
*/
vjs.createEl = function(tagName, properties){
var el = document.createElement(tagName || 'div');
var el, propName;
for (var propName in properties){
el = document.createElement(tagName || 'div');
for (propName in properties){
if (hasOwnProp.call(properties, propName)) {
//el[propName] = properties[propName];
// Not remembering why we were checking for dash
@@ -103,10 +105,9 @@ vjs.obj.merge = function(obj1, obj2){
* @return {Object} New object. Obj1 and Obj2 will be untouched.
*/
vjs.obj.deepMerge = function(obj1, obj2){
var key, val1, val2, objDef;
objDef = '[object Object]';
var key, val1, val2;
// Make a copy of obj1 so we're not ovewriting original values.
// make a copy of obj1 so we're not ovewriting original values.
// like prototype.options_ and all sub options objects
obj1 = vjs.obj.copy(obj1);
@@ -273,15 +274,19 @@ vjs.addClass = function(element, classToAdd){
* @param {String} classToAdd Classname to remove
*/
vjs.removeClass = function(element, classToRemove){
var classNames, i;
if (element.className.indexOf(classToRemove) == -1) { return; }
var classNames = element.className.split(' ');
// IE8 Does not support array.indexOf so using a for loop
for (var i = classNames.length - 1; i >= 0; i--) {
classNames = element.className.split(' ');
// no arr.indexOf in ie8, and we don't want to add a big shim
for (i = classNames.length - 1; i >= 0; i--) {
if (classNames[i] === classToRemove) {
classNames.splice(i,1);
}
}
// classNames.splice(classNames.indexOf(classToRemove),1);
element.className = classNames.join(' ');
};
@@ -304,9 +309,9 @@ vjs.USER_AGENT = navigator.userAgent;
* @type {Boolean}
* @constant
*/
vjs.IS_IPHONE = !!vjs.USER_AGENT.match(/iPhone/i);
vjs.IS_IPAD = !!vjs.USER_AGENT.match(/iPad/i);
vjs.IS_IPOD = !!vjs.USER_AGENT.match(/iPod/i);
vjs.IS_IPHONE = (/iPhone/i).test(vjs.USER_AGENT);
vjs.IS_IPAD = (/iPad/i).test(vjs.USER_AGENT);
vjs.IS_IPOD = (/iPod/i).test(vjs.USER_AGENT);
vjs.IS_IOS = vjs.IS_IPHONE || vjs.IS_IPAD || vjs.IS_IPOD;
vjs.IOS_VERSION = (function(){
@@ -314,17 +319,36 @@ vjs.IOS_VERSION = (function(){
if (match && match[1]) { return match[1]; }
})();
vjs.IS_ANDROID = !!vjs.USER_AGENT.match(/Android.*AppleWebKit/i);
vjs.IS_ANDROID = (/Android/i).test(vjs.USER_AGENT);
vjs.ANDROID_VERSION = (function() {
var match = vjs.USER_AGENT.match(/Android (\d+)\./i);
if (match && match[1]) {
return match[1];
// This matches Android Major.Minor.Patch versions
// ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned
var match = vjs.USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i),
major,
minor;
if (!match) {
return null;
}
major = match[1] && parseFloat(match[1]);
minor = match[2] && parseFloat(match[2]);
if (major && minor) {
return parseFloat(match[1] + '.' + match[2]);
} else if (major) {
return major;
} else {
return null;
}
return null;
})();
// Old Android is defined as Version older than 2.3, and requiring a webkit version of the android browser
vjs.IS_OLD_ANDROID = vjs.IS_ANDROID && (/webkit/i).test(vjs.USER_AGENT) && vjs.ANDROID_VERSION < 2.3;
vjs.IS_FIREFOX = function(){ return !!vjs.USER_AGENT.match('Firefox'); };
vjs.IS_FIREFOX = (/Firefox/i).test(vjs.USER_AGENT);
vjs.IS_CHROME = (/Chrome/i).test(vjs.USER_AGENT);
vjs.TOUCH_ENABLED = ('ontouchstart' in window);
/**
* Get an element's attribute values, as defined on the HTML tag
@@ -335,28 +359,28 @@ vjs.IS_FIREFOX = function(){ return !!vjs.USER_AGENT.match('Firefox'); };
* @return {Object}
*/
vjs.getAttributeValues = function(tag){
var obj = {};
var obj, knownBooleans, attrs, attrName, attrVal;
// Known boolean attributes
// We can check for matching boolean properties, but older browsers
// won't know about HTML5 boolean attributes that we still read from.
// Bookending with commas to allow for an easy string search.
var knownBooleans = ','+'autoplay,controls,loop,muted,default'+',';
obj = {};
// known boolean attributes
// we can check for matching boolean properties, but older browsers
// won't know about HTML5 boolean attributes that we still read from
knownBooleans = ','+'autoplay,controls,loop,muted,default'+',';
if (tag && tag.attributes && tag.attributes.length > 0) {
var attrs = tag.attributes;
var attrName, attrVal;
attrs = tag.attributes;
for (var i = attrs.length - 1; i >= 0; i--) {
attrName = attrs[i].name;
attrVal = attrs[i].value;
// Check for known booleans
// The matching element property will return a value for typeof
// check for known booleans
// the matching element property will return a value for typeof
if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(','+attrName+',') !== -1) {
// The value of an included boolean attribute is typically an empty string ('')
// which would equal false if we just check for a false value.
// We also don't want support bad code like autoplay='false'
// the value of an included boolean attribute is typically an empty
// string ('') which would equal false if we just check for a false value.
// we also don't want support bad code like autoplay='false'
attrVal = (attrVal !== null) ? true : false;
}
@@ -428,13 +452,21 @@ vjs.el = function(id){
* @return {String} Time formatted as H:MM:SS or M:SS
*/
vjs.formatTime = function(seconds, guide) {
guide = guide || seconds; // Default to using seconds as guide
// Default to using seconds as guide
guide = guide || seconds;
var s = Math.floor(seconds % 60),
m = Math.floor(seconds / 60 % 60),
h = Math.floor(seconds / 3600),
gm = Math.floor(guide / 60 % 60),
gh = Math.floor(guide / 3600);
// handle invalid times
if (isNaN(seconds) || seconds === Infinity) {
// '-' is false for all relational operators (e.g. <, >=) so this setting
// will add the minimum number of fields specified by the guide
h = m = s = '-';
}
// Check if we need to show hours
h = (h > 0 || gh > 0) ? h + ':' : '';
@@ -461,8 +493,8 @@ vjs.unblockTextSelection = function(){ document.onselectstart = function () { re
* @param {String} string String to trim
* @return {String} Trimmed string
*/
vjs.trim = function(string){
return string.toString().replace(/^\s+/, '').replace(/\s+$/, '');
vjs.trim = function(str){
return (str+'').replace(/^\s+|\s+$/g, '');
};
/**
@@ -500,7 +532,7 @@ vjs.createTimeRange = function(start, end){
* @param {Function=} onError Error callback
*/
vjs.get = function(url, onSuccess, onError){
var local = (url.indexOf('file:') === 0 || (window.location.href.indexOf('file:') === 0 && url.indexOf('http') === -1));
var local, request;
if (typeof XMLHttpRequest === 'undefined') {
window.XMLHttpRequest = function () {
@@ -511,14 +543,15 @@ vjs.get = function(url, onSuccess, onError){
};
}
var request = new XMLHttpRequest();
request = new XMLHttpRequest();
try {
request.open('GET', url);
} catch(e) {
onError(e);
}
local = (url.indexOf('file:') === 0 || (window.location.href.indexOf('file:') === 0 && url.indexOf('http') === -1));
request.onreadystatechange = function() {
if (request.readyState === 4) {
if (request.status === 200 || local && request.status === 0) {
+87 -13
Ver Arquivo
@@ -64,7 +64,14 @@ vjs.Flash = vjs.MediaTechController.extend({
// If source was supplied pass as a flash var.
if (source) {
flashVars['src'] = encodeURIComponent(vjs.getAbsoluteURL(source.src));
if (source.type && vjs.Flash.isStreamingType(source.type)) {
var parts = vjs.Flash.streamToParts(source.src);
flashVars['rtmpConnection'] = encodeURIComponent(parts.connection);
flashVars['rtmpStream'] = encodeURIComponent(parts.stream);
}
else {
flashVars['src'] = encodeURIComponent(vjs.getAbsoluteURL(source.src));
}
}
// Add placeholder to player div
@@ -182,9 +189,6 @@ vjs.Flash = vjs.MediaTechController.extend({
// Update reference to playback technology element
tech.el_ = el;
// Now that the element is ready, make a click on the swf play the video
vjs.on(el, 'click', tech.bind(tech.onClick));
// Make sure swf is actually ready. Sometimes the API isn't actually yet.
vjs.Flash.checkReady(tech);
});
@@ -227,10 +231,16 @@ vjs.Flash.prototype.pause = function(){
};
vjs.Flash.prototype.src = function(src){
// Make sure source URL is abosolute.
src = vjs.getAbsoluteURL(src);
this.el_.vjs_src(src);
if (vjs.Flash.isStreamingSrc(src)) {
src = vjs.Flash.streamToParts(src);
this.setRtmpConnection(src.connection);
this.setRtmpStream(src.stream);
}
else {
// Make sure source URL is abosolute.
src = vjs.getAbsoluteURL(src);
this.el_.vjs_src(src);
}
// Currently the SWF doesn't autoplay if you load a source later.
// e.g. Load player w/ no source, wait 2s, set src.
@@ -240,6 +250,20 @@ vjs.Flash.prototype.src = function(src){
}
};
vjs.Flash.prototype.currentSrc = function(){
var src = this.el_.vjs_getProperty('currentSrc');
// no src, check and see if RTMP
if (src == null) {
var connection = this.rtmpConnection(),
stream = this.rtmpStream();
if (connection && stream) {
src = vjs.Flash.streamFromParts(connection, stream);
}
}
return src;
};
vjs.Flash.prototype.load = function(){
this.el_.vjs_load();
};
@@ -263,7 +287,7 @@ vjs.Flash.prototype.enterFullScreen = function(){
// Create setters and getters for attributes
var api = vjs.Flash.prototype,
readWrite = 'preload,currentTime,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted'.split(','),
readWrite = 'rtmpConnection,rtmpStream,preload,currentTime,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted'.split(','),
readOnly = 'error,currentSrc,networkState,readyState,seeking,initialTime,duration,startOffsetTime,paused,played,seekable,ended,videoTracks,audioTracks,videoWidth,videoHeight,textTracks'.split(',');
// Overridden: buffered
@@ -304,7 +328,7 @@ vjs.Flash.isSupported = function(){
};
vjs.Flash.canPlaySource = function(srcObj){
if (srcObj.type in vjs.Flash.formats) { return 'maybe'; }
if (srcObj.type in vjs.Flash.formats || srcObj.type in vjs.Flash.streamingFormats) { return 'maybe'; }
};
vjs.Flash.formats = {
@@ -314,6 +338,11 @@ vjs.Flash.formats = {
'video/m4v': 'MP4'
};
vjs.Flash.streamingFormats = {
'rtmp/mp4': 'MP4',
'rtmp/flv': 'FLV'
};
vjs.Flash['onReady'] = function(currSwf){
var el = vjs.el(currSwf);
@@ -328,9 +357,6 @@ vjs.Flash['onReady'] = function(currSwf){
// Update reference to playback technology element
tech.el_ = el;
// Now that the element is ready, make a click on the swf play the video
tech.on('click', tech.onClick);
vjs.Flash.checkReady(tech);
};
@@ -453,3 +479,51 @@ vjs.Flash.getEmbedCode = function(swf, flashVars, params, attributes){
return objTag + attrsString + '>' + paramsString + '</object>';
};
vjs.Flash.streamFromParts = function(connection, stream) {
return connection + '&' + stream;
};
vjs.Flash.streamToParts = function(src) {
var parts = {
connection: '',
stream: ''
};
if (! src) {
return parts;
}
// Look for the normal URL separator we expect, '&'.
// If found, we split the URL into two pieces around the
// first '&'.
var connEnd = src.indexOf('&');
var streamBegin;
if (connEnd !== -1) {
streamBegin = connEnd + 1;
}
else {
// If there's not a '&', we use the last '/' as the delimiter.
connEnd = streamBegin = src.lastIndexOf('/') + 1;
if (connEnd === 0) {
// really, there's not a '/'?
connEnd = streamBegin = src.length;
}
}
parts.connection = src.substring(0, connEnd);
parts.stream = src.substring(streamBegin, src.length);
return parts;
};
vjs.Flash.isStreamingType = function(srcType) {
return srcType in vjs.Flash.streamingFormats;
};
// RTMP has four variations, any string starting
// with one of these protocols should be valid
vjs.Flash.RTMP_RE = /^rtmp[set]?:\/\//i;
vjs.Flash.isStreamingSrc = function(src) {
return vjs.Flash.RTMP_RE.test(src);
};
+64 -34
Ver Arquivo
@@ -13,13 +13,13 @@ vjs.Html5 = vjs.MediaTechController.extend({
/** @constructor */
init: function(player, options, ready){
// volume cannot be changed from 1 on iOS
this.features.volumeControl = vjs.Html5.canControlVolume();
this.features['volumeControl'] = vjs.Html5.canControlVolume();
// In iOS, if you move a video element in the DOM, it breaks video playback.
this.features.movingMediaElementInDOM = !vjs.IS_IOS;
this.features['movingMediaElementInDOM'] = !vjs.IS_IOS;
// HTML video is able to automatically resize when going to fullscreen
this.features.fullscreenResize = true;
this.features['fullscreenResize'] = true;
vjs.MediaTechController.call(this, player, options, ready);
@@ -35,21 +35,26 @@ vjs.Html5 = vjs.MediaTechController.extend({
this.el_.src = source.src;
}
// Determine if native controls should be used
// Our goal should be to get the custom controls on mobile solid everywhere
// so we can remove this all together. Right now this will block custom
// controls on touch enabled laptops like the Chrome Pixel
if (vjs.TOUCH_ENABLED && player.options()['nativeControlsForTouch'] !== false) {
this.useNativeControls();
}
// Chrome and Safari both have issues with autoplay.
// In Safari (5.1.1), when we move the video element into the container div, autoplay doesn't work.
// In Chrome (15), if you have autoplay + a poster + no controls, the video gets hidden (but audio plays)
// This fixes both issues. Need to wait for API, so it updates displays correctly
player.ready(function(){
if (this.options_['autoplay'] && this.paused()) {
this.tag.poster = null; // Chrome Fix. Fixed in Chrome v16.
if (this.tag && this.options_['autoplay'] && this.paused()) {
delete this.tag['poster']; // Chrome Fix. Fixed in Chrome v16.
this.play();
}
});
this.on('click', this.onClick);
this.setupTriggers();
this.triggerReady();
}
});
@@ -67,10 +72,12 @@ vjs.Html5.prototype.createEl = function(){
// Check if this browser supports moving the element into the box.
// On the iPhone video will break if you move the element,
// So we have to create a brand new element.
if (!el || this.features.movingMediaElementInDOM === false) {
if (!el || this.features['movingMediaElementInDOM'] === false) {
// If the original tag is still there, remove it.
if (el) {
el['player'] = null;
player.tag = null;
player.el().removeChild(el);
el = el.cloneNode(false);
} else {
@@ -114,6 +121,37 @@ vjs.Html5.prototype.eventHandler = function(e){
e.stopPropagation();
};
vjs.Html5.prototype.useNativeControls = function(){
var tech, player, controlsOn, controlsOff, cleanUp;
tech = this;
player = this.player();
// If the player controls are enabled turn on the native controls
tech.setControls(player.controls());
// Update the native controls when player controls state is updated
controlsOn = function(){
tech.setControls(true);
};
controlsOff = function(){
tech.setControls(false);
};
player.on('controlsenabled', controlsOn);
player.on('controlsdisabled', controlsOff);
// Clean up when not using native controls anymore
cleanUp = function(){
player.off('controlsenabled', controlsOn);
player.off('controlsdisabled', controlsOff);
};
tech.on('dispose', cleanUp);
player.on('usingcustomcontrols', cleanUp);
// Update the state of the player to using native controls
player.usingNativeControls(true);
};
vjs.Html5.prototype.play = function(){ this.el_.play(); };
vjs.Html5.prototype.pause = function(){ this.el_.pause(); };
@@ -177,39 +215,35 @@ vjs.Html5.prototype.currentSrc = function(){ return this.el_.currentSrc; };
vjs.Html5.prototype.preload = function(){ return this.el_.preload; };
vjs.Html5.prototype.setPreload = function(val){ this.el_.preload = val; };
vjs.Html5.prototype.autoplay = function(){ return this.el_.autoplay; };
vjs.Html5.prototype.setAutoplay = function(val){ this.el_.autoplay = val; };
vjs.Html5.prototype.controls = function(){ return this.el_.controls; }
vjs.Html5.prototype.setControls = function(val){ this.el_.controls = !!val; }
vjs.Html5.prototype.loop = function(){ return this.el_.loop; };
vjs.Html5.prototype.setLoop = function(val){ this.el_.loop = val; };
vjs.Html5.prototype.error = function(){ return this.el_.error; };
// networkState: function(){ return this.el_.networkState; },
// readyState: function(){ return this.el_.readyState; },
vjs.Html5.prototype.seeking = function(){ return this.el_.seeking; };
// initialTime: function(){ return this.el_.initialTime; },
// startOffsetTime: function(){ return this.el_.startOffsetTime; },
// played: function(){ return this.el_.played; },
// seekable: function(){ return this.el_.seekable; },
vjs.Html5.prototype.ended = function(){ return this.el_.ended; };
// videoTracks: function(){ return this.el_.videoTracks; },
// audioTracks: function(){ return this.el_.audioTracks; },
// videoWidth: function(){ return this.el_.videoWidth; },
// videoHeight: function(){ return this.el_.videoHeight; },
// textTracks: function(){ return this.el_.textTracks; },
// defaultPlaybackRate: function(){ return this.el_.defaultPlaybackRate; },
// playbackRate: function(){ return this.el_.playbackRate; },
// mediaGroup: function(){ return this.el_.mediaGroup; },
// controller: function(){ return this.el_.controller; },
vjs.Html5.prototype.defaultMuted = function(){ return this.el_.defaultMuted; };
/* HTML5 Support Testing ---------------------------------------------------- */
vjs.Html5.isSupported = function(){
return !!document.createElement('video').canPlayType;
return !!vjs.TEST_VID.canPlayType;
};
vjs.Html5.canPlaySource = function(srcObj){
return !!document.createElement('video').canPlayType(srcObj.type);
// IE9 on Windows 7 without MediaPlayer throws an error here
// https://github.com/videojs/video.js/issues/519
try {
return !!vjs.TEST_VID.canPlayType(srcObj.type);
} catch(e) {
return '';
}
// TODO: Check Type
// If no Type, check ext
// Check Media Type
@@ -227,13 +261,9 @@ vjs.Html5.Events = 'loadstart,suspend,abort,error,emptied,stalled,loadedmetadata
// HTML5 Feature detection and Device Fixes --------------------------------- //
// Android
if (vjs.IS_ANDROID) {
// Override Android 2.2 and less canPlayType method which is broken
if (vjs.ANDROID_VERSION < 3) {
document.createElement('video').constructor.prototype.canPlayType = function(type){
return (type && type.toLowerCase().indexOf('video/mp4') != -1) ? 'maybe' : '';
};
}
if (vjs.IS_OLD_ANDROID) {
document.createElement('video').constructor.prototype.canPlayType = function(type){
return (type && type.toLowerCase().indexOf('video/mp4') != -1) ? 'maybe' : '';
};
}
+137 -29
Ver Arquivo
@@ -1,5 +1,6 @@
/**
* @fileoverview Media Technology Controller - Base class for media playback technology controllers like Flash and HTML5
* @fileoverview Media Technology Controller - Base class for media playback
* technology controllers like Flash and HTML5
*/
/**
@@ -13,48 +14,155 @@ vjs.MediaTechController = vjs.Component.extend({
init: function(player, options, ready){
vjs.Component.call(this, player, options, ready);
// Make playback element clickable
// this.addEvent('click', this.proxy(this.onClick));
// player.triggerEvent('techready');
this.initControlsListeners();
}
});
// destroy: function(){},
// createElement: function(){},
/**
* Set up click and touch listeners for the playback element
* On desktops, a click on the video itself will toggle playback,
* on a mobile device a click on the video toggles controls.
* (toggling controls is done by toggling the user state between active and
* inactive)
*
* A tap can signal that a user has become active, or has become inactive
* e.g. a quick tap on an iPhone movie should reveal the controls. Another
* quick tap should hide them again (signaling the user is in an inactive
* viewing state)
*
* In addition to this, we still want the user to be considered inactive after
* a few seconds of inactivity.
*
* Note: the only part of iOS interaction we can't mimic with this setup
* is a touch and hold on the video element counting as activity in order to
* keep the controls showing, but that shouldn't be an issue. A touch and hold on
* any controls will still keep the user active
*/
vjs.MediaTechController.prototype.initControlsListeners = function(){
var player, tech, activateControls, deactivateControls;
tech = this;
player = this.player();
var activateControls = function(){
if (player.controls() && !player.usingNativeControls()) {
tech.addControlsListeners();
}
};
deactivateControls = vjs.bind(tech, tech.removeControlsListeners);
// Set up event listeners once the tech is ready and has an element to apply
// listeners to
this.ready(activateControls);
player.on('controlsenabled', activateControls);
player.on('controlsdisabled', deactivateControls);
};
vjs.MediaTechController.prototype.addControlsListeners = function(){
var preventBubble, userWasActive;
// Some browsers (Chrome & IE) don't trigger a click on a flash swf, but do
// trigger mousedown/up.
// http://stackoverflow.com/questions/1444562/javascript-onclick-event-over-flash-object
// Any touch events are set to block the mousedown event from happening
this.on('mousedown', this.onClick);
// We need to block touch events on the video element from bubbling up,
// otherwise they'll signal activity prematurely. The specific use case is
// when the video is playing and the controls have faded out. In this case
// only a tap (fast touch) should toggle the user active state and turn the
// controls back on. A touch and move or touch and hold should not trigger
// the controls (per iOS as an example at least)
//
// We always want to stop propagation on touchstart because touchstart
// at the player level starts the touchInProgress interval. We can still
// report activity on the other events, but won't let them bubble for
// consistency. We don't want to bubble a touchend without a touchstart.
this.on('touchstart', function(event) {
// Stop the mouse events from also happening
event.preventDefault();
event.stopPropagation();
// Record if the user was active now so we don't have to keep polling it
userWasActive = this.player_.userActive();
});
preventBubble = function(event){
event.stopPropagation();
if (userWasActive) {
this.player_.reportUserActivity();
}
};
// Treat all touch events the same for consistency
this.on('touchmove', preventBubble);
this.on('touchleave', preventBubble);
this.on('touchcancel', preventBubble);
this.on('touchend', preventBubble);
// Turn on component tap events
this.emitTapEvents();
// The tap listener needs to come after the touchend listener because the tap
// listener cancels out any reportedUserActivity when setting userActive(false)
this.on('tap', this.onTap);
};
/**
* Handle a click on the media element. By default will play the media.
*
* On android browsers, having this toggle play state interferes with being
* able to toggle the controls and toggling play state with the play button
* Remove the listeners used for click and tap controls. This is needed for
* toggling to controls disabled, where a tap/touch should do nothing.
*/
vjs.MediaTechController.prototype.onClick = (function(){
if (vjs.IS_ANDROID) {
return function () {};
} else {
return function () {
if (this.player_.controls()) {
if (this.player_.paused()) {
this.player_.play();
} else {
this.player_.pause();
}
}
};
vjs.MediaTechController.prototype.removeControlsListeners = function(){
// We don't want to just use `this.off()` because there might be other needed
// listeners added by techs that extend this.
this.off('tap');
this.off('touchstart');
this.off('touchmove');
this.off('touchleave');
this.off('touchcancel');
this.off('touchend');
this.off('click');
this.off('mousedown');
};
/**
* Handle a click on the media element. By default will play/pause the media.
*/
vjs.MediaTechController.prototype.onClick = function(event){
// We're using mousedown to detect clicks thanks to Flash, but mousedown
// will also be triggered with right-clicks, so we need to prevent that
if (event.button !== 0) return;
// When controls are disabled a click should not toggle playback because
// the click is considered a control
if (this.player().controls()) {
if (this.player().paused()) {
this.player().play();
} else {
this.player().pause();
}
}
})();
};
/**
* Handle a tap on the media element. By default it will toggle the user
* activity state, which hides and shows the controls.
*/
vjs.MediaTechController.prototype.onTap = function(){
this.player().userActive(!this.player().userActive());
};
vjs.MediaTechController.prototype.features = {
volumeControl: true,
'volumeControl': true,
// Resizing plugins using request fullscreen reloads the plugin
fullscreenResize: false,
'fullscreenResize': false,
// Optional events that we can manually mimic with timers
// currently not triggered by video-js-swf
progressEvents: false,
timeupdateEvents: false
'progressEvents': false,
'timeupdateEvents': false
};
vjs.media = {};
+1 -1
Ver Arquivo
@@ -128,7 +128,7 @@ vjs.MenuButton.prototype.createMenu = function(){
}));
}
this.items = this.createItems();
this.items = this['createItems']();
if (this.items) {
// Add menu items to the menu
+241 -87
Ver Arquivo
@@ -24,22 +24,30 @@ vjs.Player = vjs.Component.extend({
this.poster_ = options['poster'];
// Set controls
this.controls_ = options['controls'];
// Use native controls for iOS and Android by default
// until controls are more stable on those devices.
if (options['customControlsOnMobile'] !== true && (vjs.IS_IOS || vjs.IS_ANDROID)) {
tag.controls = options['controls'];
this.controls_ = false;
} else {
// Original tag settings stored in options
// now remove immediately so native controls don't flash.
tag.controls = false;
}
// Original tag settings stored in options
// now remove immediately so native controls don't flash.
// May be turned back on by HTML5 tech if nativeControlsForTouch is true
tag.controls = false;
// Run base component initializing with new options.
// Builds the element through createEl()
// Inits and embeds any child components in opts
vjs.Component.call(this, this, options, ready);
// Update controls className. Can't do this when the controls are initially
// set because the element doesn't exist yet.
if (this.controls()) {
this.addClass('vjs-controls-enabled');
} else {
this.addClass('vjs-controls-disabled');
}
// TODO: Make this smarter. Toggle user state between touching/mousing
// using events, since devices can have both touch and mouse events.
// if (vjs.TOUCH_ENABLED) {
// this.addClass('vjs-touch-enabled');
// }
// Firstplay event implimentation. Not sold on the event yet.
// Could probably just check currentTime==0?
this.one('play', function(e){
@@ -71,6 +79,8 @@ vjs.Player = vjs.Component.extend({
this[key](val);
}, this);
}
this.listenForUserActivity();
}
});
@@ -86,7 +96,9 @@ vjs.Player = vjs.Component.extend({
vjs.Player.prototype.options_ = vjs.options;
vjs.Player.prototype.dispose = function(){
// this.isReady_ = false;
this.trigger('dispose');
// prevent dispose from being called twice
this.off('dispose');
// Kill reference to this player
vjs.players[this.id_] = null;
@@ -113,22 +125,18 @@ vjs.Player.prototype.getTagSettings = function(tag){
// Get tag children settings
if (tag.hasChildNodes()) {
var child, childName,
children = tag.childNodes,
i = 0,
j = children.length;
var children, child, childName, i, j;
for (; i < j; i++) {
children = tag.childNodes;
for (i=0,j=children.length; i<j; i++) {
child = children[i];
// Change case needed: http://ejohn.org/blog/nodename-case-sensitivity/
childName = child.nodeName.toLowerCase();
if (childName === 'source') {
options['sources'].push(vjs.getAttributeValues(child));
} else if (childName === 'track') {
options['tracks'].push(vjs.getAttributeValues(child));
}
}
}
@@ -148,12 +156,23 @@ vjs.Player.prototype.createEl = function(){
// so we'll need to turn off any default tracks if we're manually doing
// captions and subtitles. videoElement.textTracks
if (tag.hasChildNodes()) {
var nrOfChildNodes = tag.childNodes.length;
for (var i=0,j=tag.childNodes;i<nrOfChildNodes;i++) {
if (j[0].nodeName.toLowerCase() == 'source' || j[0].nodeName.toLowerCase() == 'track') {
tag.removeChild(j[0]);
var nodes, nodesLength, i, node, nodeName, removeNodes;
nodes = tag.childNodes;
nodesLength = nodes.length;
removeNodes = [];
while (nodesLength--) {
node = nodes[nodesLength];
nodeName = node.nodeName.toLowerCase();
if (nodeName === 'source' || nodeName === 'track') {
removeNodes.push(node);
}
}
for (i=0; i<removeNodes.length; i++) {
tag.removeChild(removeNodes[i]);
}
}
// Make sure tag ID exists
@@ -203,7 +222,7 @@ vjs.Player.prototype.loadTech = function(techName, source){
// So we need to remove it if we're not loading HTML5
} else if (techName !== 'Html5' && this.tag) {
this.el_.removeChild(this.tag);
this.tag.player = null;
this.tag['player'] = null;
this.tag = null;
}
@@ -216,12 +235,12 @@ vjs.Player.prototype.loadTech = function(techName, source){
this.player_.triggerReady();
// Manually track progress in cases where the browser/flash player doesn't report it.
if (!this.features.progressEvents) {
if (!this.features['progressEvents']) {
this.player_.manualProgressOn();
}
// Manually track timeudpates in cases where the browser/flash player doesn't report it.
if (!this.features.timeupdateEvents) {
if (!this.features['timeupdateEvents']) {
this.player_.manualTimeUpdatesOn();
}
};
@@ -286,7 +305,7 @@ vjs.Player.prototype.manualProgressOn = function(){
this.tech.one('progress', function(){
// Update known progress support for this playback technology
this.features.progressEvents = true;
this.features['progressEvents'] = true;
// Turn off manual progress tracking
this.player_.manualProgressOff();
@@ -325,7 +344,7 @@ vjs.Player.prototype.manualTimeUpdatesOn = function(){
// Watch for native timeupdate event
this.tech.one('timeupdate', function(){
// Update known progress support for this playback technology
this.features.timeupdateEvents = true;
this.features['timeupdateEvents'] = true;
// Turn off manual progress tracking
this.player_.manualTimeUpdatesOff();
});
@@ -368,6 +387,8 @@ vjs.Player.prototype.onFirstPlay = function(){
if(this.options_['starttime']){
this.currentTime(this.options_['starttime']);
}
this.addClass('vjs-has-started');
};
vjs.Player.prototype.onPause = function(){
@@ -392,7 +413,7 @@ vjs.Player.prototype.onError = function(e) {
vjs.log('Video Error', e);
};
vjs.Player.prototype.onFullscreenChange = function(e) {
vjs.Player.prototype.onFullscreenChange = function() {
if (this.isFullScreen) {
this.addClass('vjs-fullscreen');
} else {
@@ -416,7 +437,7 @@ vjs.Player.prototype.getCache = function(){
// Pass values to the playback tech
vjs.Player.prototype.techCall = function(method, arg){
// If it's not ready yet, call method when it is
if (this.tech && this.tech.isReady_) {
if (this.tech && !this.tech.isReady_) {
this.tech.ready(function(){
this[method](arg);
});
@@ -435,12 +456,7 @@ vjs.Player.prototype.techCall = function(method, arg){
// Get calls can't wait for the tech, and sometimes don't need to.
vjs.Player.prototype.techGet = function(method){
// Make sure there is a tech
// if (!this.tech) {
// return;
// }
if (this.tech.isReady_) {
if (this.tech && this.tech.isReady_) {
// Flash likes to die and reload when you hide or reposition it.
// In these cases the object methods go away and we get errors.
@@ -537,11 +553,12 @@ vjs.Player.prototype.remainingTime = function(){
vjs.Player.prototype.buffered = function(){
var buffered = this.techGet('buffered'),
start = 0,
buflast = buffered.length - 1,
// Default end to 0 and store in values
end = this.cache_.bufferEnd = this.cache_.bufferEnd || 0;
if (buffered && buffered.length > 0 && buffered.end(0) !== end) {
end = buffered.end(0);
if (buffered && buflast >= 0 && buffered.end(buflast) !== end) {
end = buffered.end(buflast);
// Storing values allows them be overridden by setBufferedFromProgress
this.cache_.bufferEnd = end;
}
@@ -593,7 +610,11 @@ vjs.Player.prototype.requestFullScreen = function(){
// take the controls fullscreen as well as the video
// Trigger fullscreenchange event after change
vjs.on(document, requestFullScreen.eventName, vjs.bind(this, function(){
// We have to specifically add this each time, and remove
// when cancelling fullscreen. Otherwise if there's multiple
// players on a page, they would all be reacting to the same fullscreen
// events
vjs.on(document, requestFullScreen.eventName, vjs.bind(this, function(e){
this.isFullScreen = document[requestFullScreen.isFullScreen];
// If cancelling fullscreen, remove event listener.
@@ -601,37 +622,18 @@ vjs.Player.prototype.requestFullScreen = function(){
vjs.off(document, requestFullScreen.eventName, arguments.callee);
}
this.trigger('fullscreenchange');
}));
// Flash and other plugins get reloaded when you take their parent to fullscreen.
// To fix that we'll remove the tech, and reload it after the resize has finished.
if (this.tech.features.fullscreenResize === false && this.options_['flash']['iFrameMode'] !== true) {
this.pause();
this.unloadTech();
vjs.on(document, requestFullScreen.eventName, vjs.bind(this, function(){
vjs.off(document, requestFullScreen.eventName, arguments.callee);
this.loadTech(this.techName, { src: this.cache_.src });
}));
this.el_[requestFullScreen.requestFn]();
} else {
this.el_[requestFullScreen.requestFn]();
}
this.trigger('fullscreenchange');
this.el_[requestFullScreen.requestFn]();
} else if (this.tech.supportsFullScreen()) {
// we can't take the video.js controls fullscreen but we can go fullscreen
// with native controls
this.techCall('enterFullScreen');
} else {
// fullscreen isn't supported so we'll just stretch the video element to
// fill the viewport
this.enterFullWindow();
this.trigger('fullscreenchange');
}
@@ -641,31 +643,11 @@ vjs.Player.prototype.requestFullScreen = function(){
vjs.Player.prototype.cancelFullScreen = function(){
var requestFullScreen = vjs.support.requestFullScreen;
this.isFullScreen = false;
// Check for browser element fullscreen support
if (requestFullScreen) {
// Flash and other plugins get reloaded when you take their parent to fullscreen.
// To fix that we'll remove the tech, and reload it after the resize has finished.
if (this.tech.features.fullscreenResize === false && this.options_['flash']['iFrameMode'] !== true) {
this.pause();
this.unloadTech();
vjs.on(document, requestFullScreen.eventName, vjs.bind(this, function(){
vjs.off(document, requestFullScreen.eventName, arguments.callee);
this.loadTech(this.techName, { src: this.cache_.src });
}));
document[requestFullScreen.cancelFn]();
} else {
document[requestFullScreen.cancelFn]();
}
this.trigger('fullscreenchange');
document[requestFullScreen.cancelFn]();
} else if (this.tech.supportsFullScreen()) {
this.techCall('exitFullScreen');
} else {
@@ -768,7 +750,7 @@ vjs.Player.prototype.src = function(source){
}
} else {
this.el_.appendChild(vjs.createEl('p', {
innerHTML: 'Sorry, no compatible source and playback technology were found for this video. Try using another browser like <a href="http://bit.ly/ccMUEC">Chrome</a> or download the latest <a href="http://adobe.ly/mwfN1">Adobe Flash Player</a>.'
innerHTML: this.options()['notSupportedMessage']
}));
}
@@ -873,19 +855,188 @@ vjs.Player.prototype.controls_;
* @param {Boolean} controls Set controls to showing or not
* @return {Boolean} Controls are showing
*/
vjs.Player.prototype.controls = function(controls){
if (controls !== undefined) {
vjs.Player.prototype.controls = function(bool){
if (bool !== undefined) {
bool = !!bool; // force boolean
// Don't trigger a change event unless it actually changed
if (this.controls_ !== controls) {
this.controls_ = !!controls; // force boolean
this.trigger('controlschange');
if (this.controls_ !== bool) {
this.controls_ = bool;
if (bool) {
this.removeClass('vjs-controls-disabled');
this.addClass('vjs-controls-enabled');
this.trigger('controlsenabled');
} else {
this.removeClass('vjs-controls-enabled');
this.addClass('vjs-controls-disabled');
this.trigger('controlsdisabled');
}
}
return this;
}
return this.controls_;
};
vjs.Player.prototype.usingNativeControls_;
/**
* Toggle native controls on/off. Native controls are the controls built into
* devices (e.g. default iPhone controls), Flash, or other techs
* (e.g. Vimeo Controls)
*
* **This should only be set by the current tech, because only the tech knows
* if it can support native controls**
*
* @param {Boolean} bool True signals that native controls are on
* @return {vjs.Player} Returns the player
*/
vjs.Player.prototype.usingNativeControls = function(bool){
if (bool !== undefined) {
bool = !!bool; // force boolean
// Don't trigger a change event unless it actually changed
if (this.usingNativeControls_ !== bool) {
this.usingNativeControls_ = bool;
if (bool) {
this.addClass('vjs-using-native-controls');
this.trigger('usingnativecontrols');
} else {
this.removeClass('vjs-using-native-controls');
this.trigger('usingcustomcontrols');
}
}
return this;
}
return this.usingNativeControls_;
};
vjs.Player.prototype.error = function(){ return this.techGet('error'); };
vjs.Player.prototype.ended = function(){ return this.techGet('ended'); };
vjs.Player.prototype.seeking = function(){ return this.techGet('seeking'); };
// When the player is first initialized, trigger activity so components
// like the control bar show themselves if needed
vjs.Player.prototype.userActivity_ = true;
vjs.Player.prototype.reportUserActivity = function(event){
this.userActivity_ = true;
};
vjs.Player.prototype.userActive_ = true;
vjs.Player.prototype.userActive = function(bool){
if (bool !== undefined) {
bool = !!bool;
if (bool !== this.userActive_) {
this.userActive_ = bool;
if (bool) {
// If the user was inactive and is now active we want to reset the
// inactivity timer
this.userActivity_ = true;
this.removeClass('vjs-user-inactive');
this.addClass('vjs-user-active');
this.trigger('useractive');
} else {
// We're switching the state to inactive manually, so erase any other
// activity
this.userActivity_ = false;
// Chrome/Safari/IE have bugs where when you change the cursor it can
// trigger a mousemove event. This causes an issue when you're hiding
// the cursor when the user is inactive, and a mousemove signals user
// activity. Making it impossible to go into inactive mode. Specifically
// this happens in fullscreen when we really need to hide the cursor.
//
// When this gets resolved in ALL browsers it can be removed
// https://code.google.com/p/chromium/issues/detail?id=103041
this.tech.one('mousemove', function(e){
e.stopPropagation();
e.preventDefault();
});
this.removeClass('vjs-user-active');
this.addClass('vjs-user-inactive');
this.trigger('userinactive');
}
}
return this;
}
return this.userActive_;
};
vjs.Player.prototype.listenForUserActivity = function(){
var onMouseActivity, onMouseDown, mouseInProgress, onMouseUp,
activityCheck, inactivityTimeout;
onMouseActivity = this.reportUserActivity;
onMouseDown = function() {
onMouseActivity();
// For as long as the they are touching the device or have their mouse down,
// we consider them active even if they're not moving their finger or mouse.
// So we want to continue to update that they are active
clearInterval(mouseInProgress);
// Setting userActivity=true now and setting the interval to the same time
// as the activityCheck interval (250) should ensure we never miss the
// next activityCheck
mouseInProgress = setInterval(vjs.bind(this, onMouseActivity), 250);
};
onMouseUp = function(event) {
onMouseActivity();
// Stop the interval that maintains activity if the mouse/touch is down
clearInterval(mouseInProgress);
};
// Any mouse movement will be considered user activity
this.on('mousedown', onMouseDown);
this.on('mousemove', onMouseActivity);
this.on('mouseup', onMouseUp);
// Listen for keyboard navigation
// Shouldn't need to use inProgress interval because of key repeat
this.on('keydown', onMouseActivity);
this.on('keyup', onMouseActivity);
// Consider any touch events that bubble up to be activity
// Certain touches on the tech will be blocked from bubbling because they
// toggle controls
this.on('touchstart', onMouseDown);
this.on('touchmove', onMouseActivity);
this.on('touchend', onMouseUp);
this.on('touchcancel', onMouseUp);
// Run an interval every 250 milliseconds instead of stuffing everything into
// the mousemove/touchmove function itself, to prevent performance degradation.
// `this.reportUserActivity` simply sets this.userActivity_ to true, which
// then gets picked up by this loop
// http://ejohn.org/blog/learning-from-twitter/
activityCheck = setInterval(vjs.bind(this, function() {
// Check to see if mouse/touch activity has happened
if (this.userActivity_) {
// Reset the activity tracker
this.userActivity_ = false;
// If the user state was inactive, set the state to active
this.userActive(true);
// Clear any existing inactivity timeout to start the timer over
clearTimeout(inactivityTimeout);
// In X seconds, if no more activity has occurred the user will be
// considered inactive
inactivityTimeout = setTimeout(vjs.bind(this, function() {
// Protect against the case where the inactivityTimeout can trigger just
// before the next user activity is picked up by the activityCheck loop
// causing a flicker
if (!this.userActivity_) {
this.userActive(false);
}
}), 2000);
}
}), 250);
// Clean up the intervals when we kill the player
this.on('dispose', function(){
clearInterval(activityCheck);
clearTimeout(inactivityTimeout);
});
};
// Methods to add support for
// networkState: function(){ return this.techCall('networkState'); },
@@ -920,6 +1071,7 @@ vjs.Player.prototype.ended = function(){ return this.techGet('ended'); };
// Current W3C Spec
// http://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#api
// Mozilla Draft: https://wiki.mozilla.org/Gecko:FullScreenAPI#fullscreenchange_event
// New: https://dvcs.w3.org/hg/fullscreen/raw-file/529a67b8d9f3/Overview.html
if (div.cancelFullscreen !== undefined) {
requestFS.requestFn = 'requestFullscreen';
requestFS.cancelFn = 'exitFullscreen';
@@ -953,3 +1105,5 @@ vjs.Player.prototype.ended = function(){ return this.techGet('ended'); };
}
})();
+4 -1
Ver Arquivo
@@ -40,5 +40,8 @@ vjs.PosterImage.prototype.createEl = function(){
};
vjs.PosterImage.prototype.onClick = function(){
this.player_.play();
// Only accept clicks when controls are enabled
if (this.player().controls()) {
this.player_.play();
}
};
+3 -15
Ver Arquivo
@@ -742,11 +742,7 @@ vjs.TextTrackMenuItem.prototype.onClick = function(){
};
vjs.TextTrackMenuItem.prototype.update = function(){
if (this.track.mode() == 2) {
this.selected(true);
} else {
this.selected(false);
}
this.selected(this.track.mode() == 2);
};
/**
@@ -786,11 +782,7 @@ vjs.OffTextTrackMenuItem.prototype.update = function(){
}
}
if (off) {
this.selected(true);
} else {
this.selected(false);
}
this.selected(off);
};
/* Captions Button
@@ -999,11 +991,7 @@ vjs.ChaptersTrackMenuItem.prototype.update = function(){
currentTime = this.player_.currentTime();
// vjs.log(currentTime, cue.startTime);
if (cue.startTime <= currentTime && currentTime < cue.endTime) {
this.selected(true);
} else {
this.selected(false);
}
this.selected(cue.startTime <= currentTime && currentTime < cue.endTime);
};
// Add Buttons to controlBar
Arquivo binário não exibido.
+4 -2
Ver Arquivo
@@ -12,13 +12,14 @@
<script src="../test/qunit/qunit/qunit.js"></script>
<!-- Video.js CSS -->
<link rel="stylesheet" href="../src/css/video-js.css" type="text/css">
<link rel="stylesheet" href="../build/files/video-js.css" type="text/css">
<script type="text/javascript">
(function(){
// ADD NEW TEST FILES HERE
window.tests = [
'test/unit/test-helpers.js',
'test/unit/core-object.js',
'test/unit/lib.js',
'test/unit/events.js',
@@ -28,7 +29,8 @@
'test/unit/core.js',
'test/unit/media.html5.js',
'test/unit/controls.js',
'test/unit/plugins.js'
'test/unit/plugins.js',
'test/unit/flash.js'
];
var projectRoot = '../';
+2 -1
Ver Arquivo
@@ -8,7 +8,7 @@
<script src="../test/qunit/qunit/qunit.js"></script>
<!-- Video.js CSS -->
<link rel="stylesheet" href="../src/css/video-js.css" type="text/css">
<link rel="stylesheet" href="../build/files/video-js.css" type="text/css">
<!-- LIB COMPILED WITH NOT COMPILED TESTS
Check publicly available APIs against compiled lib
@@ -18,6 +18,7 @@
// ADD NEW TEST FILES HERE
var tests = [
'test/unit/test-helpers.js',
'test/unit/api.js'
];
var projectRoot = '../';
+1 -1
Ver Arquivo
@@ -8,7 +8,7 @@
<script src="../test/qunit/qunit/qunit.js"></script>
<!-- Video.js CSS -->
<link rel="stylesheet" href="../src/css/video-js.css" type="text/css">
<link rel="stylesheet" href="../build/files/video-js.css" type="text/css">
<!-- SOURCE COMPILED WITH TESTS
grunt-contrib-qunit doesn't support query vars, so making this script
+73 -8
Ver Arquivo
@@ -1,13 +1,36 @@
module('Player Minified');
var PlayerTest = {
makeTag: function(){
var videoTag = document.createElement('video');
videoTag.id = 'example_1';
videoTag.className = 'video-js vjs-default-skin';
return videoTag;
}
};
test('should be able to access expected player API methods', function() {
var player = PlayerTest.makePlayer();
// Native HTML5 Methods
ok(player.play, 'play exists');
ok(player.pause, 'pause exists');
ok(player.paused, 'paused exists');
ok(player.src, 'src exists');
ok(player.currentTime, 'currentTime exists');
ok(player.duration, 'duration exists');
ok(player.buffered, 'buffered exists');
ok(player.volume, 'volume exists');
ok(player.muted, 'muted exists');
ok(player.width, 'width exists');
ok(player.height, 'height exists');
ok(player.requestFullScreen, 'requestFullScreen exists');
ok(player.cancelFullScreen, 'cancelFullScreen exists');
// Added player methods
ok(player.ready, 'ready exists');
ok(player.on, 'on exists');
ok(player.off, 'off exists');
ok(player.one, 'one exists');
ok(player.bufferedPercent, 'bufferedPercent exists');
ok(player.dimensions, 'dimensions exists');
ok(player.addClass, 'addClass exists');
ok(player.removeClass, 'removeClass exists');
ok(player.usingNativeControls, 'usingNativeControls exists');
player.dispose();
});
test('should export ready api call to public', function() {
var videoTag = PlayerTest.makeTag();
@@ -20,6 +43,35 @@ test('should export ready api call to public', function() {
player.dispose();
});
test('should export useful components to the public', function () {
ok(videojs.ControlBar, 'ControlBar should be public');
ok(videojs.Button, 'Button should be public');
ok(videojs.PlayToggle, 'PlayToggle should be public');
ok(videojs.FullscreenToggle, 'FullscreenToggle should be public');
ok(videojs.BigPlayButton, 'BigPlayButton should be public');
ok(videojs.LoadingSpinner, 'LoadingSpinner should be public');
ok(videojs.CurrentTimeDisplay, 'CurrentTimeDisplay should be public');
ok(videojs.DurationDisplay, 'DurationDisplay should be public');
ok(videojs.TimeDivider, 'TimeDivider should be public');
ok(videojs.RemainingTimeDisplay, 'RemainingTimeDisplay should be public');
ok(videojs.Slider, 'Slider should be public');
ok(videojs.ProgressControl, 'ProgressControl should be public');
ok(videojs.SeekBar, 'SeekBar should be public');
ok(videojs.LoadProgressBar, 'LoadProgressBar should be public');
ok(videojs.PlayProgressBar, 'PlayProgressBar should be public');
ok(videojs.SeekHandle, 'SeekHandle should be public');
ok(videojs.VolumeControl, 'VolumeControl should be public');
ok(videojs.VolumeBar, 'VolumeBar should be public');
ok(videojs.VolumeLevel, 'VolumeLevel should be public');
ok(videojs.VolumeMenuButton, 'VolumeMenuButton should be public');
ok(videojs.VolumeHandle, 'VolumeHandle should be public');
ok(videojs.MuteToggle, 'MuteToggle should be public');
ok(videojs.PosterImage, 'PosterImage should be public');
ok(videojs.Menu, 'Menu should be public');
ok(videojs.MenuItem, 'MenuItem should be public');
ok(videojs.MenuButton, 'MenuButton should be public');
});
test('should be able to initialize player twice on the same tag using string reference', function() {
var videoTag = PlayerTest.makeTag();
var id = videoTag.id;
@@ -37,3 +89,16 @@ test('should be able to initialize player twice on the same tag using string ref
player = videojs('example_1');
player.dispose();
});
test('videojs.players should be availble after minification', function() {
var videoTag = PlayerTest.makeTag();
var id = videoTag.id;
var fixture = document.getElementById('qunit-fixture');
fixture.appendChild(videoTag);
var player = videojs(id);
ok(videojs.players[id] === player, 'videojs.players is available');
player.dispose();
});
+30
Ver Arquivo
@@ -82,8 +82,12 @@ test('should dispose of component and children', function(){
var data = vjs.getData(comp.el());
var id = comp.el()[vjs.expando];
var hasDisposed = false;
comp.on('dispose', function(){ hasDisposed = true; });
comp.dispose();
ok(hasDisposed, 'component fired dispose event');
ok(!comp.children(), 'component children were deleted');
ok(!comp.el(), 'component element was deleted');
ok(!child.children(), 'child children were deleted');
@@ -217,3 +221,29 @@ test('should use a defined content el for appending children', function(){
ok(comp.el().childNodes[0]['id'] === 'contentEl', 'Content El should still exist');
ok(comp.el().childNodes[0].childNodes[0] !== child.el(), 'Child el should be removed.');
});
test('should emit a tap event', function(){
expect(1);
// Fake touch support. Real touch support isn't needed for this test.
var origTouch = vjs.TOUCH_ENABLED;
vjs.TOUCH_ENABLED = true;
var comp = new vjs.Component(getFakePlayer(), {});
comp.emitTapEvents();
comp.on('tap', function(){
ok(true, 'Tap event emitted');
});
comp.trigger('touchstart');
comp.trigger('touchend');
// This second test should not trigger another tap event because
// a touchmove is happening
comp.trigger('touchstart');
comp.trigger('touchmove');
comp.trigger('touchend');
// Reset to orignial value
vjs.TOUCH_ENABLED = origTouch;
});
Ver Arquivo
+4 -4
Ver Arquivo
@@ -11,7 +11,7 @@ test('should hide volume control if it\'s not supported', function(){
ready: noop,
tech: {
features: {
volumeControl: false
'volumeControl': false
}
},
volume: function(){},
@@ -43,7 +43,7 @@ test('should test and toggle volume control on `loadstart`', function(){
},
tech: {
features: {
volumeControl: true
'volumeControl': true
}
}
};
@@ -56,7 +56,7 @@ test('should test and toggle volume control on `loadstart`', function(){
ok(muteToggle.el().className.indexOf('vjs-hidden') < 0,
'muteToggle is hidden initially');
player.tech.features.volumeControl = false;
player.tech.features['volumeControl'] = false;
for (i = 0; i < listeners.length; i++) {
listeners[i]();
}
@@ -66,7 +66,7 @@ test('should test and toggle volume control on `loadstart`', function(){
ok(muteToggle.el().className.indexOf('vjs-hidden') >= 0,
'muteToggle does not hide itself');
player.tech.features.volumeControl = true;
player.tech.features['volumeControl'] = true;
for (i = 0; i < listeners.length; i++) {
listeners[i]();
}
+25
Ver Arquivo
@@ -89,3 +89,28 @@ test('should stop immediate propagtion', function(){
vjs.trigger(el, 'test');
});
test('should bubble up DOM unless bubbles == false', function(){
expect(3);
var outer = document.createElement('div');
var inner = outer.appendChild(document.createElement('div'));
// Verify that if bubbles === true, event bubbles up dom.
vjs.on(inner, 'bubbles', function(e){
ok(true, 'Inner listener fired');
});
vjs.on(outer, 'bubbles', function(e){
ok(true, 'Outer listener fired');
});
vjs.trigger(inner, { type:'bubbles', target:inner, bubbles:true });
// Only change 'bubbles' to false, and verify only inner handler is called.
vjs.on(inner, 'nobub', function(e){
ok(true, 'Inner listener fired');
});
vjs.on(outer, 'nobub', function(e){
ok(false, 'Outer listener fired');
});
vjs.trigger(inner, { type:'nobub', target:inner, bubbles:false });
});
+48
Ver Arquivo
@@ -0,0 +1,48 @@
module('Flash');
var streamToPartsAndBack = function(url) {
var parts = vjs.Flash.streamToParts(url);
return vjs.Flash.streamFromParts(parts.connection, parts.stream);
};
test('test using both streamToParts and streamFromParts', function() {
ok('rtmp://myurl.com/&isthis' === streamToPartsAndBack('rtmp://myurl.com/isthis'));
ok('rtmp://myurl.com/&isthis' === streamToPartsAndBack('rtmp://myurl.com/&isthis'));
ok('rtmp://myurl.com/isthis/&andthis' === streamToPartsAndBack('rtmp://myurl.com/isthis/andthis'));
});
test('test streamToParts', function() {
var parts = vjs.Flash.streamToParts('http://myurl.com/streaming&/is/fun');
ok(parts.connection === 'http://myurl.com/streaming');
ok(parts.stream === '/is/fun');
parts = vjs.Flash.streamToParts('http://myurl.com/&streaming&/is/fun');
ok(parts.connection === 'http://myurl.com/');
ok(parts.stream === 'streaming&/is/fun');
parts = vjs.Flash.streamToParts('http://myurl.com/streaming/is/fun');
ok(parts.connection === 'http://myurl.com/streaming/is/');
ok(parts.stream === 'fun');
parts = vjs.Flash.streamToParts('whatisgoingonhere');
ok(parts.connection === 'whatisgoingonhere');
ok(parts.stream === '');
parts = vjs.Flash.streamToParts();
ok(parts.connection === '');
ok(parts.stream === '');
});
test('test isStreamingSrc', function() {
var isStreamingSrc = vjs.Flash.isStreamingSrc;
ok(isStreamingSrc('rtmp://streaming.is/fun'));
ok(isStreamingSrc('rtmps://streaming.is/fun'));
ok(isStreamingSrc('rtmpe://streaming.is/fun'));
ok(isStreamingSrc('rtmpt://streaming.is/fun'));
// test invalid protocols
ok(!isStreamingSrc('rtmp:streaming.is/fun'));
ok(!isStreamingSrc('rtmpz://streaming.is/fun'));
ok(!isStreamingSrc('http://streaming.is/fun'));
ok(!isStreamingSrc('https://streaming.is/fun'));
ok(!isStreamingSrc('file://streaming.is/fun'));
});
+44 -6
Ver Arquivo
@@ -110,10 +110,38 @@ test('should read tag attributes from elements, including HTML5 in all browsers'
var sourceVals = vjs.getAttributeValues(document.getElementById('source'));
var trackVals = vjs.getAttributeValues(document.getElementById('track'));
deepEqual(vid1Vals, { 'autoplay': true, 'controls': true, 'data-test': 'asdf', 'data-empty-string': '', 'id': 'vid1', 'loop': true, 'muted': true, 'poster': 'http://www2.videojs.com/img/video-js-html5-video-player.png', 'preload': 'none', 'src': 'http://google.com' });
deepEqual(vid2Vals, { 'id': 'vid2' });
deepEqual(sourceVals, {'title': 'test', 'media': 'fdsa', 'type': 'video/mp4', 'src': 'http://google.com', 'id': 'source' });
deepEqual(trackVals, { 'default': true, /* IE no likey default key */ 'id': 'track', 'kind': 'captions', 'label': 'testlabel', 'src': 'http://google.com', 'srclang': 'en', 'title': 'test' });
// was using deepEqual, but ie8 would send all properties as attributes
// vid1
equal(vid1Vals['autoplay'], true);
equal(vid1Vals['controls'], true);
equal(vid1Vals['data-test'], 'asdf');
equal(vid1Vals['data-empty-string'], '');
equal(vid1Vals['id'], 'vid1');
equal(vid1Vals['loop'], true);
equal(vid1Vals['muted'], true);
equal(vid1Vals['poster'], 'http://www2.videojs.com/img/video-js-html5-video-player.png');
equal(vid1Vals['preload'], 'none');
equal(vid1Vals['src'], 'http://google.com');
// vid2
equal(vid2Vals['id'], 'vid2');
// sourceVals
equal(sourceVals['title'], 'test');
equal(sourceVals['media'], 'fdsa');
equal(sourceVals['type'], 'video/mp4');
equal(sourceVals['src'], 'http://google.com');
equal(sourceVals['id'], 'source');
// trackVals
equal(trackVals['default'], true);
equal(trackVals['id'], 'track');
equal(trackVals['kind'], 'captions');
equal(trackVals['label'], 'testlabel');
equal(trackVals['src'], 'http://google.com');
equal(trackVals['srclang'], 'en');
equal(trackVals['title'], 'test');
});
test('should get the right style values for an element', function(){
@@ -130,8 +158,10 @@ test('should get the right style values for an element', function(){
el.style.height = '100%';
el.style.width = '123px';
ok(vjs.getComputedDimension(el, 'height') === '1000px');
ok(vjs.getComputedDimension(el, 'width') === '123px');
// integer px values may get translated int very-close floats in Chrome/OS X
// so round the dimensions to ignore this
equal(Math.round(parseFloat(vjs.getComputedDimension(el, 'height'))), 1000, 'the computed height is equal');
equal(Math.round(parseFloat(vjs.getComputedDimension(el, 'width'))), 123, 'the computed width is equal');
});
test('should insert an element first in another', function(){
@@ -192,6 +222,14 @@ test('should format time as a string', function(){
ok(vjs.formatTime(1,360000) === '0:00:01');
});
test('should format invalid times as dashes', function(){
equal(vjs.formatTime(Infinity, 90), '-:-');
equal(vjs.formatTime(NaN), '-:-');
// equal(vjs.formatTime(NaN, 216000), '-:--:--');
equal(vjs.formatTime(10, Infinity), '0:00:10');
equal(vjs.formatTime(90, NaN), '1:30');
});
test('should create a fake timerange', function(){
var tr = vjs.createTimeRange(0, 10);
ok(tr.start() === 0);
+6 -1
Ver Arquivo
@@ -21,10 +21,15 @@ test('should re-link the player if the tech is moved', function(){
var player, tech, el;
el = document.createElement('div');
el.innerHTML = '<div />';
player = {
id: function(){ return 'id'; },
el: function(){ return el; },
options_: {},
options: function(){ return {}; },
controls: function(){ return false; },
usingNativeControls: function(){ return false; },
on: function(){ return this; },
ready: function(){}
};
tech = new vjs.Html5(player, {});
@@ -32,4 +37,4 @@ test('should re-link the player if the tech is moved', function(){
tech.createEl();
strictEqual(player, tech.el()['player']);
});
});
+5
Ver Arquivo
@@ -31,8 +31,13 @@ vjs.MediaFaker.prototype.createEl = function(){
};
vjs.MediaFaker.prototype.currentTime = function(){ return 0; };
vjs.MediaFaker.prototype.seeking = function(){ return false; };
vjs.MediaFaker.prototype.volume = function(){ return 0; };
vjs.MediaFaker.prototype.muted = function(){ return false; };
vjs.MediaFaker.prototype.pause = function(){ return false; };
vjs.MediaFaker.prototype.supportsFullScreen = function(){ return false; };
vjs.MediaFaker.prototype.features = {};
vjs.MediaFaker.prototype.buffered = function(){ return {}; };
// Export vars for Closure Compiler
vjs['MediaFaker'] = vjs.MediaFaker;
+129 -29
Ver Arquivo
@@ -1,27 +1,5 @@
module('Player');
var PlayerTest = {
makeTag: function(){
var videoTag = document.createElement('video');
videoTag.id = 'example_1';
videoTag.className = 'video-js vjs-default-skin';
return videoTag;
},
makePlayer: function(playerOptions){
var player;
var videoTag = PlayerTest.makeTag();
var fixture = document.getElementById('qunit-fixture');
fixture.appendChild(videoTag);
var opts = vjs.obj.merge({
'techOrder': ['mediaFaker']
}, playerOptions);
return player = new vjs.Player(videoTag, opts);
}
};
// Compiler doesn't like using 'this' in setup/teardown.
// module("Player", {
// /**
@@ -130,7 +108,8 @@ test('should get tag, source, and track settings', function(){
player.dispose();
ok(tag['player'] === null, 'tag player ref killed');
ok(tag['player'] !== player, 'tag player ref killed');
ok(!vjs.players['example_1'], 'global player ref killed');
ok(player.el() === null, 'player el killed');
});
@@ -232,21 +211,142 @@ test('should be able to initialize player twice on the same tag using string ref
player.dispose();
});
test('should set controls and trigger event', function() {
expect(3);
test('should set controls and trigger events', function() {
expect(6);
var player = PlayerTest.makePlayer({ 'controls': false });
ok(player.controls() === false, 'controls set through options');
var hasDisabledClass = player.el().className.indexOf('vjs-controls-disabled');
ok(hasDisabledClass !== -1, 'Disabled class added to player');
player.controls(true);
ok(player.controls() === true, 'controls updated');
var hasEnabledClass = player.el().className.indexOf('vjs-controls-enabled');
ok(hasEnabledClass !== -1, 'Disabled class added to player');
player.on('controlschange', function(){
ok(true, 'controlschange fired once');
player.on('controlsenabled', function(){
ok(true, 'enabled fired once');
});
player.on('controlsdisabled', function(){
ok(true, 'disabled fired once');
});
player.controls(false);
// Check for unnecessary controlschange events
player.controls(false);
player.controls(true);
// Check for unnecessary events
player.controls(true);
player.dispose();
});
// Can't figure out how to test fullscreen events with tests
// Browsers aren't triggering the events at least
// asyncTest('should trigger the fullscreenchange event', function() {
// expect(3);
// var player = PlayerTest.makePlayer();
// player.on('fullscreenchange', function(){
// ok(true, 'fullscreenchange event fired');
// ok(this.isFullScreen === true, 'isFullScreen is true');
// ok(this.el().className.indexOf('vjs-fullscreen') !== -1, 'vjs-fullscreen class added');
// player.dispose();
// start();
// });
// player.requestFullScreen();
// });
test('should toggle user the user state between active and inactive', function(){
var player = PlayerTest.makePlayer({});
expect(9);
ok(player.userActive(), 'User should be active at player init');
player.on('userinactive', function(){
ok(true, 'userinactive event triggered');
});
player.on('useractive', function(){
ok(true, 'useractive event triggered');
});
player.userActive(false);
ok(player.userActive() === false, 'Player state changed to inactive');
ok(player.el().className.indexOf('vjs-user-active') === -1, 'Active class removed');
ok(player.el().className.indexOf('vjs-user-inactive') !== -1, 'Inactive class added');
player.userActive(true);
ok(player.userActive() === true, 'Player state changed to active');
ok(player.el().className.indexOf('vjs-user-inactive') === -1, 'Inactive class removed');
ok(player.el().className.indexOf('vjs-user-active') !== -1, 'Active class added');
player.dispose();
});
test('should add a touch-enabled classname when touch is supported', function(){
var player;
expect(1);
// Fake touch support. Real touch support isn't needed for this test.
var origTouch = vjs.TOUCH_ENABLED;
vjs.TOUCH_ENABLED = true;
player = PlayerTest.makePlayer({});
ok(player.el().className.indexOf('vjs-touch-enabled'), 'touch-enabled classname added');
vjs.TOUCH_ENABLED = origTouch;
player.dispose();
});
test('should allow for tracking when native controls are used', function(){
var player = PlayerTest.makePlayer({});
expect(6);
// Make sure native controls is false before starting test
player.usingNativeControls(false);
player.on('usingnativecontrols', function(){
ok(true, 'usingnativecontrols event triggered');
});
player.on('usingcustomcontrols', function(){
ok(true, 'usingcustomcontrols event triggered');
});
player.usingNativeControls(true);
ok(player.usingNativeControls() === true, 'Using native controls is true');
ok(player.el().className.indexOf('vjs-using-native-controls') !== -1, 'Native controls class added');
player.usingNativeControls(false);
ok(player.usingNativeControls() === false, 'Using native controls is false');
ok(player.el().className.indexOf('vjs-using-native-controls') === -1, 'Native controls class removed');
player.dispose();
});
test('should use custom message when encountering an unsupported video type',
function() {
videojs.options['notSupportedMessage'] = 'Video no go <a href="">link</a>';
var fixture = document.getElementById('qunit-fixture');
var html =
'<video id="example_1">' +
'<source src="fake.foo" type="video/foo">' +
'</video>';
fixture.innerHTML += html;
var tag = document.getElementById('example_1');
var player = new vjs.Player(tag);
var incompatibilityMessage = player.el().getElementsByTagName('p')[0];
// ie8 capitalizes tag names
equal(incompatibilityMessage.innerHTML.toLowerCase(), 'video no go <a href="">link</a>');
player.dispose();
});
+20
Ver Arquivo
@@ -0,0 +1,20 @@
var PlayerTest = {
makeTag: function(){
var videoTag = document.createElement('video');
videoTag.id = 'example_1';
videoTag.className = 'video-js vjs-default-skin';
return videoTag;
},
makePlayer: function(playerOptions){
var player;
var videoTag = PlayerTest.makeTag();
var fixture = document.getElementById('qunit-fixture');
fixture.appendChild(videoTag);
playerOptions = playerOptions || {};
playerOptions['techOrder'] = ['mediaFaker'];
return player = new videojs.Player(videoTag, playerOptions);
}
};