Comparar commits

...

79 Commits

Autor SHA1 Mensagem Data
Pat O'Neill ec5b60329f chore: Add package-lock.json file. (#4641) 2017-10-19 11:49:04 -04:00
Pat O'Neill 0287f6e076 fix: Make sure we remove vjs-ended from the play toggle in all appropriate cases. (#4661) 2017-10-13 13:46:51 -04:00
Gary Katsevman e8511a5799 chore(gh-release): no console log on success (#4657)
We've been printing the resulting value from a successful call to the ghrelease, this was useful for debugging but isn't necessary anymore.
Add the result to the error conditional with some headings.
2017-10-10 11:35:50 -07:00
Gary Katsevman 69577790eb 6.3.3 2017-10-10 13:52:45 -04:00
Brandon Casey b1de506b43 fix: a possible breaking change caused by the use of remainingTimeDisplay (#4655) 2017-10-10 11:35:46 -04:00
TaeSoo 태수 6738f765da docs(hooks): Fix Typo (#4652) 2017-10-06 18:01:54 -07:00
Pat O'Neill 8ec61bbb20 6.3.2 2017-10-04 10:37:26 -04:00
Thijs Triemstra 85a34d1b49 docs: Document how to add a version number to a plugin (#4642) 2017-10-04 10:32:18 -04:00
Pat O'Neill 4658c7bad6 fix: Fix a typo in current time display component. (#4647) 2017-10-04 10:31:10 -04:00
Pat O'Neill 8878acc040 6.3.1 2017-10-03 13:11:27 -04:00
Pat O'Neill 20f7fe991f fix: Make sure time displays use correctly-formatted time. (#4643) 2017-10-03 12:52:58 -04:00
Pat O'Neill f0d9c240fe 6.3.0 2017-10-03 11:04:07 -04:00
Brandon Casey 445eb26722 feat: Add remainingTimeDisplay method to Player (#4620) 2017-10-02 16:29:40 -04:00
Thom 5ca0992cf1 chore(lang): Update Dutch (#4588) 2017-10-02 16:08:04 -04:00
ngoisaosang ac58dbf13a chore(lang): Update Vietnamese (#4625) 2017-10-02 16:04:57 -04:00
Alex Barstow 1ac8065ea6 feat: Do not set focus in sub-menus to prevent undesirable scrolling behavior in iOS (#4607) 2017-10-02 15:29:34 -04:00
Brandon Casey f51d36b053 feat: display currentTime as duration and remainingTime as 0 on ended (#4634) 2017-10-02 11:19:29 -04:00
Brandon Casey fa6f884409 refactor: Create a base time display class, and use it (#4633) 2017-10-02 10:58:30 -04:00
Brandon Casey 335bcded98 fix: reset to a play/pause button when seeking after ended (#4614) 2017-09-20 13:45:47 -04:00
Thijs Triemstra d8ea23e0c9 docs: update player reference in advanced plugins doc (#4622) 2017-09-20 10:55:29 -04:00
Erik Demaine 9d249bb23b docs: Document playbackRates (#4602) 2017-09-19 17:44:36 -04:00
greenkeeper[bot] 7929677f6f chore(package): update remark-validate-links to version 7.0.0 (#4585) 2017-09-19 17:21:39 -04:00
greenkeeper[bot] 6cd785ab7f chore(package): update grunt-browserify to version 5.2.0 (#4578) 2017-09-19 17:21:20 -04:00
Brandon Casey edde614822 chore: alias rollup-dev to watch for development (#4615) 2017-09-14 15:09:52 -04:00
ldayananda 9f969300d7 6.2.8 2017-09-01 13:37:46 -04:00
Matthew Boles 006fb3b705 docs: update to width and height doc comments (#4592) 2017-09-01 13:31:48 -04:00
Gary Katsevman 5e23048370 fix(package): remove pkg.module (#4594)
More info available in #4580.

Fixes #4580.
2017-08-31 16:16:41 -04:00
Gary Katsevman 95c4ae0404 fix: rely on browser or tech to handle autoplay (#4582)
When setting the source, we were calling `play` if `autoplay` was set. We shouldn't do that and instead we should rely on the browser or tech (like Flash) to handle it properly.
2017-08-30 14:29:08 -04:00
Gary Katsevman 9588602d48 docs(COLLABORATOR_GUIDE): how to release Video.js (#4586) 2017-08-30 14:22:04 -04:00
Pat O'Neill 6e2a302af8 6.2.7 2017-08-24 16:20:40 -04:00
Gary Katsevman fe63992bd1 fix: use typeof for checking preload option (#4574) 2017-08-17 17:48:17 -04:00
greenkeeper[bot] 7b251d0d35 chore(package): update rollup to version 0.47.5 (#4572) 2017-08-17 13:30:46 -04:00
Gary Katsevman 09ace0c625 6.2.6 2017-08-16 17:32:35 -04:00
Atef Ben Ali 3e63bf3d17 fix(lang): typos in ar.json (#4528) 2017-08-16 14:31:28 -04:00
Gary Katsevman d7f7e05b5c chore(package): update rollup to version 0.47.4 (#4570)
Closes #4561
2017-08-16 14:14:26 -04:00
greenkeeper[bot] 8c21f0afe0 chore(package): update grunt-browserify to version 5.1.0 (#4565) 2017-08-16 14:05:29 -04:00
greenkeeper[bot] f6f9998299 chore(package): update grunt-babel to version 7.0.0 (#4553) 2017-08-16 14:02:00 -04:00
Gary Katsevman d668c4976b fix: make boolean attributes set and check both the associated property and the attribute (#4562)
Make boolean attributes like muted set the property video.muted = {{boolean}} and the attribute video.setAttribute('muted', 'muted') when changing the value.
Also, in html5's createEl, we were setting/updating attributes for various properties but we were only setting the attributes and not also the properties but also autoplay was happening first rather than last which caused autoplay to fail because muted and playsinline weren't necessary set by that time.

Fix #4351.
2017-08-15 17:02:07 -04:00
Rafael Gaspar a6b8425f6b fix: playback rate default text (#4558)
Previously, the default text only said `1` now it says `1x` which matches the look after changing the playback rate.
2017-08-14 17:59:41 -04:00
mister-ben 1f3375e485 docs: updates to faq, language guide, and minor edits (#4556) 2017-08-14 17:02:48 -04:00
Gary Katsevman 19ebc0dda5 chore: improve dev and beginner experience (#4555)
Makes the output of dev rollup and babel watch more quiet.
Add a task to copy .example files over to non .example files if the non .example files are not present.
2017-08-14 16:58:57 -04:00
Gary Katsevman db55bbd3ec fix: remove 'use strict' from rollup because vttjs isn't strict (#4551) 2017-08-14 16:51:05 -04:00
greenkeeper[bot] 6233d14091 chore(package): update klaw-sync to version 3.0.0 (#4544) 2017-08-14 16:39:07 -04:00
Alex Barstow 0c337b3d67 Fix: issue where tracks are disabled and cuepoints are cleared in iOS native player (#4496)
In the HTML5 tech, when we go fullscreen to the native player, listen for change events and restore previous mode state for the metadata text tracks.
2017-08-14 16:36:36 -04:00
Kishan cd2f5106ca fix: set width and height for vjs-button like the SubsCaps button (#4548)
Add a width and height property of 100% to `.vjs-control .vjs-button` selector.

Fixes #4547.
2017-08-10 15:19:59 -04:00
Gary Katsevman 998c0042cb 6.2.5 2017-07-26 16:49:20 -04:00
Gary Katsevman ee014e2e04 fix: only change focus from BPB if not a mouse click (#4497) 2017-07-26 16:09:31 -04:00
Gary Katsevman fe95a7720a chore(greenkeeper): ignore webpack and uglify (#4518) 2017-07-26 13:29:39 -04:00
greenkeeper[bot] 7c80e1300a chore(package): update remark-cli to version 4.0.0 (#4508) 2017-07-25 17:08:26 -04:00
greenkeeper[bot] abb5d67eb2 chore(package): update remark-parse to version 4.0.0 (#4507) 2017-07-25 17:08:12 -04:00
greenkeeper[bot] bbd92ab813 chore(package): update remark-stringify to version 4.0.0 (#4506) 2017-07-25 17:07:21 -04:00
Gary Katsevman d889b660ac 6.2.4 2017-07-14 15:49:06 -04:00
Gary Katsevman 07594bcf59 chore: fix gh-release minimist call (#4489) 2017-07-14 15:48:49 -04:00
Gary Katsevman 14ae1e9658 6.2.3 2017-07-14 15:41:59 -04:00
Gary Katsevman b1ac2e0249 chore(gh-release): add prerelease flag and find right zip (#4488)
Add a --prerelease flag so we can run gh-release.js manually and mark releases as prerelease.
Also, get the correct zip file.
2017-07-14 15:27:48 -04:00
Gary Katsevman 269e504d26 6.2.2 2017-07-14 14:56:58 -04:00
Gary Katsevman 971f633c73 chore(package): update rollup to version 0.45.2 (#4487)
Closes #4475
2017-07-14 14:43:58 -04:00
Gary Katsevman 03fd402ea9 docs: make jsdoc generate anchor names so ToC links work (#4471)
Also, run some more explicit replacement queries so all ToC links work if they're generated differently from gfm.
2017-07-14 14:22:02 -04:00
Gary Katsevman 3a600d0eea chore: add automatic github release (#4466)
This will automatically do a github release with the correct changelog entry and the built zip file.
If a publish is made with `--tag next` it will mark the release as a pre-release.

To use, just add `VJS_GITHUB_USER` and `VJS_GITHUB_TOKEN` env variables as part of the publish command:
```sh
$ VJS_GITHUB_USER=gkatsev VJS_GITHUB_TOKEN=test_token npm publish --tag next
```
2017-07-14 14:21:07 -04:00
Alex Barstow 1e80e59614 test: add unit tests for player.duration() (#4459)
Unit tests for https://github.com/videojs/video.js/pull/4443
2017-07-14 14:20:37 -04:00
Pat O'Neill 7579fc1800 docs: Fix Player#src API documentation. (#4454) 2017-07-14 14:20:00 -04:00
Gary Katsevman 4f43616160 fix(playback rate menu): cycling rates via click (#4486)
In 6.0, we changed the way that Menu Buttons were being created by
wrapping an actual button with a menu sibling in a container. The
playback rate menu also had a rate value display. In 6.x, this rate
value display ended up coming on top of the button itself and capturing
it's clicks. So, we want to remove pointer-events from the rate-value
display and resize the actual button to be the size of the control.
2017-07-14 14:18:23 -04:00
Gary Katsevman 687aae50ff chore: switch to using chrome for testing PRs on travis (#4462) 2017-07-05 09:44:43 +10:00
Aeoril 6986dbb851 chore(build): remove unused var in build/version.js (#4458) 2017-07-04 11:11:29 +10:00
Gary Katsevman 39ff0f4fb6 6.2.1 2017-06-28 16:58:10 +10:00
Gary Katsevman 82c8b80548 fix: auto-removal remote text tracks being removed when not supposed to (#4450)
We added a feature so that remote text tracks can auto-removed when a source changes. However, in 6.x we changed the source behavior to be asynchronous meaning that some text tracks were accidentally being removed when they weren't supposed to be.
For example:
```js
var player = videojs('my-player');
player.src({src: 'video.mp4', type: 'video/mp4'});
 // set second arg to false so that they get auto-removed on source change
player.addRemoteTextTrack({kind: 'captions', src: 'text.vtt', srclang: 'en'}, false);
```
Now when the player loads, this captions track is actually missing because it was removed.

Instead of adding auto-removal tracks immediately to the list, wait until we've selected a source before adding them in.


Fixes #4403 and #4315.
2017-06-28 16:38:29 +10:00
Alex Barstow f5cc165cad fix: player.duration() should return NaN if duration is not known (#4443)
player.duration() currently returns 0 if the duration is not known, when it should return NaN. The problem is that if NaN is passed to player.duration() as an argument, we set the duration to 0. If player.cache_.duration was set to NaN by other means, player.duration() would still return 0.

Modify the player duration() method so that it will 1.) set the cached duration to NaN if it is passed in as an argument, and 2.) return the proper value when called without an argument.
2017-06-28 16:37:00 +10:00
mister-ben b4dc4f85b0 fix: Use passive event listeners for touchstart/touchmove (#4440)
If passive event listening is supported, we should use it.

Fixes #4432.
2017-06-28 16:36:06 +10:00
mister-ben b63666379d fix: Safari picture-in-picture triggers fullscreenchange (#4437)
When picture-in-picture mode is entered on Safari, `webkitbeginfullscreen` is triggered which results in a proxied `fullscreenchange` event and adding the fullscreen class to the player. That causes the tech element to collapse to zero height so that the "this video is playing in picture in picture" placeholder is not visible.
On `webkitbeginfullscreen` check whether the presentation mode is `picture-in-picture` before proxying `fullscreenchange` event.
2017-06-28 16:35:01 +10:00
Pat O'Neill 77ba3d13d9 perf: Various small performance improvements. (#4426)
These are a few performance improvements.

* Use textContent instead of innerHTML for text content.
* Construct TextTrackSettings content with HTML strings where possible because it's a bit faster than manual DOM construction.
* Do minimal DOM updates to time controls. This reduces our timeupdate footprint from ~2-2.5ms to ~1ms!
2017-06-28 16:32:58 +10:00
Jet Fontanilla 7f7ea70cb7 fix: IE10 issue for disableOthers when property access results in "permission denied" (#4395)
Fixes #4378
2017-06-28 16:32:04 +10:00
mister-ben e0824c8294 fix: Update translations to match correct string (#4383)
The lang files were translating "all settings to the default values" instead of "restore all settings to the default values".
2017-06-28 16:31:44 +10:00
Pat O'Neill cc6e82442f docs: Fix links in API docs for several Player events. (#4427) 2017-06-27 09:53:08 +10:00
Caley Shem-Crumrine 97021554cd docs: Update name of FullscreenToggle in documentation (#4410) 2017-06-27 09:52:05 +10:00
Pat O'Neill c4bbe5d120 chore(sandbox): Fix paths in sandbox files. (#4416) 2017-06-27 09:51:05 +10:00
Gary Katsevman 66a0d23e05 chore(package): update husky to version 0.14.1 (#4444)
Closes #4436
2017-06-27 09:44:28 +10:00
greenkeeper[bot] 4bce4a2954 chore(package): update rollup-watch to version 4.0.0 (#4396) 2017-06-27 09:43:42 +10:00
greenkeeper[bot] f87b12c3af chore(package): update rollup to version 0.42.0 (#4392) 2017-06-27 09:43:18 +10:00
ldayananda 9329e3ef8e docs: Fixing player.remoteTextTracks jsdoc (#4417)
Fixes the sidebar link on the docs site for remoteTextTracks.
2017-06-19 16:01:01 -04:00
65 arquivos alterados com 16050 adições e 1282 exclusões
+2 -1
Ver Arquivo
@@ -35,6 +35,7 @@
},
"plugins": ["plugins/markdown"],
"markdown": {
"tags": ["example"]
"tags": ["example"],
"idInHeadings": true
}
}
+5 -1
Ver Arquivo
@@ -2,7 +2,7 @@ language: node_js
node_js:
- 4.4
before_install:
- export CHROME_BIN=chromium-browser
- export CHROME_BIN=/usr/bin/google-chrome
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
after_failure:
@@ -26,8 +26,12 @@ env:
- secure: gglh7xDnURKfXp9T543DD7NG1pQ8HeWh1XtRspBAwr0H7RqJBVDqqODSYSPRFhfld7M6sYmvQIXgil7XlyefnKNTXqCarvaoTg3lbip8kSltXMiNw2V6AVpsQGuja7+XbaM0do70ETTKjW4Kw6wnxEHb78BvGN/hXIeqizUAjanlDAjd7fouaxpTBIbMESe2rI+WRHPis1cmnv8v70Mrh/8Un/NO4gkebGyvA47LTDNIaVqIVjonsndr8WjMv1/PNxQ8LyCO6D64MufrobS7Sec+VuN30apwEsBw8v82MK/MZ3qXu0lUp4+ERTbuc/rymh2wDFTQeG20Kf/NTauSaH6f414KNzIRFj0/xyLAzVZKIscXM2DKXMuskkZuvHLZvaspnZWcPYTjPZl0P88N0RBqnoLdR80dR5bDljNwU2QnSBeol/q1wXNEr6I1VTRFOB+qsHrD1blVMB1I5W3I0ti1aQ7XtgMOGi1kcPb4oFcJdl+3dLFDnyRyaNfdMOnOZYBBHdQCo19Mj/L+nqPGWeeYiEAM6JsuhNjHn5Za5nGf1ztXTimVPOQjyATin0x9kST3soLWSVmdW2dBHUGDVSMhvoLLR+nKSdNQ0KfpqtgrzeLxoVnRYHVBlih41tapM9IG/6BMYnDMaRcc0i54YeUP4oxlxGSyASIenkAgC6w=
- secure: WtIEOSnqDkCZuTlBsxwlVwaRpVTbz7ol8+XSJIZb0aFo1lLisF9cz6s9WrAfX36MaxIcDN9LFZkpXzMvNrNkZWQa1kacGWH1rbx0SiiQ8LMweAcKdnZ5uXlSplBxbJ8bZfXKB1sIHsOsYw/vWhHKkcsDUkAEzQrIiMOhuoUV3s0uKM0knKXIAfNIF0EbDzLIojm+nm+F0n5vM60LRdKesaSt/o2p2LKxdZVoFGrg48D7bdA9VEfMWWRL/evDxJmnX4p+AjBc7mklqZ5F2pYsY6XXQuuS+2Sy+lnxz01kLg+RC4Cpv5dyYfK3h0j8KeyK8IuixycVONWVe9rANq8UaIsMrRN+6uDSC8zXiH4P+h6UDMm3jetc2ZyAfhBA8OyIs5QEShae2Rd7Y3WFJxBp6UVgyj6SkXGxrEdb1ZJgTTl4dyqiP0bYrLePNP2qSJ6OTfNdG791HF077uzXI96ABdMG54Wv9N9T/hmxKwV2Lajx/GZJMmHuwT9tkHKhkcxWea1HYam9QYSFUyJ5THfNk2A9u/r8DkL62MZ85zIQBisrlFjbPAGRejq6qyirBJPAy+FCjhM+oO/i2f2bGkkAfHGT0Og1BcrWVXs54yWdO7UZgie2F+Rmdwinb/GxebZJ+21ZQ4OkVr2t1Skr/PRni9+U7q/6xCLwUJgx45XJ0FE=
sudo: false
dist: trusty
cache:
directories:
- node_modules
addons:
firefox: latest
apt:
packages:
- google-chrome-stable
+186
Ver Arquivo
@@ -1,3 +1,189 @@
<a name="6.3.3"></a>
## [6.3.3](https://github.com/videojs/video.js/compare/v6.3.2...v6.3.3) (2017-10-10)
### Bug Fixes
* a possible breaking change caused by the use of remainingTimeDisplay ([#4655](https://github.com/videojs/video.js/issues/4655)) ([b1de506](https://github.com/videojs/video.js/commit/b1de506))
### Documentation
* **hooks:** Fix Typo ([#4652](https://github.com/videojs/video.js/issues/4652)) ([6738f76](https://github.com/videojs/video.js/commit/6738f76))
<a name="6.3.2"></a>
## [6.3.2](https://github.com/videojs/video.js/compare/v6.3.1...v6.3.2) (2017-10-04)
### Bug Fixes
* Fix a typo in current time display component. ([#4647](https://github.com/videojs/video.js/issues/4647)) ([4658c7b](https://github.com/videojs/video.js/commit/4658c7b))
### Documentation
* Document how to add a version number to a plugin ([#4642](https://github.com/videojs/video.js/issues/4642)) ([85a34d1](https://github.com/videojs/video.js/commit/85a34d1))
<a name="6.3.1"></a>
## [6.3.1](https://github.com/videojs/video.js/compare/v6.3.0...v6.3.1) (2017-10-03)
### Bug Fixes
* Make sure time displays use correctly-formatted time. ([#4643](https://github.com/videojs/video.js/issues/4643)) ([20f7fe9](https://github.com/videojs/video.js/commit/20f7fe9))
<a name="6.3.0"></a>
# [6.3.0](https://github.com/videojs/video.js/compare/v6.2.8...v6.3.0) (2017-10-03)
### Features
* Add remainingTimeDisplay method to Player ([#4620](https://github.com/videojs/video.js/issues/4620)) ([445eb26](https://github.com/videojs/video.js/commit/445eb26))
* display currentTime as duration and remainingTime as 0 on ended ([#4634](https://github.com/videojs/video.js/issues/4634)) ([f51d36b](https://github.com/videojs/video.js/commit/f51d36b))
* Do not set focus in sub-menus to prevent undesirable scrolling behavior in iOS ([#4607](https://github.com/videojs/video.js/issues/4607)) ([1ac8065](https://github.com/videojs/video.js/commit/1ac8065))
### Bug Fixes
* reset to a play/pause button when seeking after ended ([#4614](https://github.com/videojs/video.js/issues/4614)) ([335bcde](https://github.com/videojs/video.js/commit/335bcde))
### Chores
* alias rollup-dev to watch for development ([#4615](https://github.com/videojs/video.js/issues/4615)) ([edde614](https://github.com/videojs/video.js/commit/edde614))
* **lang:** Update Dutch ([#4588](https://github.com/videojs/video.js/issues/4588)) ([5ca0992](https://github.com/videojs/video.js/commit/5ca0992))
* **lang:** Update Vietnamese ([#4625](https://github.com/videojs/video.js/issues/4625)) ([ac58dbf](https://github.com/videojs/video.js/commit/ac58dbf))
* **package:** update grunt-browserify to version 5.2.0 ([#4578](https://github.com/videojs/video.js/issues/4578)) ([6cd785a](https://github.com/videojs/video.js/commit/6cd785a))
* **package:** update remark-validate-links to version 7.0.0 ([#4585](https://github.com/videojs/video.js/issues/4585)) ([7929677](https://github.com/videojs/video.js/commit/7929677))
### Code Refactoring
* Create a base time display class, and use it ([#4633](https://github.com/videojs/video.js/issues/4633)) ([fa6f884](https://github.com/videojs/video.js/commit/fa6f884))
### Documentation
* Document playbackRates ([#4602](https://github.com/videojs/video.js/issues/4602)) ([9d249bb](https://github.com/videojs/video.js/commit/9d249bb))
* update player reference in advanced plugins doc ([#4622](https://github.com/videojs/video.js/issues/4622)) ([d8ea23e](https://github.com/videojs/video.js/commit/d8ea23e))
<a name="6.2.8"></a>
## [6.2.8](https://github.com/videojs/video.js/compare/v6.2.7...v6.2.8) (2017-09-01)
### Bug Fixes
* rely on browser or tech to handle autoplay ([#4582](https://github.com/videojs/video.js/issues/4582)) ([95c4ae0](https://github.com/videojs/video.js/commit/95c4ae0))
* **package:** remove pkg.module ([#4594](https://github.com/videojs/video.js/issues/4594)) ([5e23048](https://github.com/videojs/video.js/commit/5e23048)), closes [#4580](https://github.com/videojs/video.js/issues/4580)
### Documentation
* **COLLABORATOR_GUIDE:** how to release Video.js ([#4586](https://github.com/videojs/video.js/issues/4586)) ([9588602](https://github.com/videojs/video.js/commit/9588602))
* update to width and height doc comments ([#4592](https://github.com/videojs/video.js/issues/4592)) ([006fb3b](https://github.com/videojs/video.js/commit/006fb3b))
<a name="6.2.7"></a>
## [6.2.7](https://github.com/videojs/video.js/compare/v6.2.6...v6.2.7) (2017-08-24)
### Bug Fixes
* use typeof for checking preload option ([#4574](https://github.com/videojs/video.js/issues/4574)) ([fe63992](https://github.com/videojs/video.js/commit/fe63992))
### Chores
* **package:** update rollup to version 0.47.5 ([#4572](https://github.com/videojs/video.js/issues/4572)) ([7b251d0](https://github.com/videojs/video.js/commit/7b251d0))
<a name="6.2.6"></a>
## [6.2.6](https://github.com/videojs/video.js/compare/v6.2.5...v6.2.6) (2017-08-16)
### Bug Fixes
* make boolean attributes set and check both the associated property and the attribute ([#4562](https://github.com/videojs/video.js/issues/4562)) ([d668c49](https://github.com/videojs/video.js/commit/d668c49)), closes [#4351](https://github.com/videojs/video.js/issues/4351)
* playback rate default text ([#4558](https://github.com/videojs/video.js/issues/4558)) ([a6b8425](https://github.com/videojs/video.js/commit/a6b8425))
* remove 'use strict' from rollup because vttjs isn't strict ([#4551](https://github.com/videojs/video.js/issues/4551)) ([db55bbd](https://github.com/videojs/video.js/commit/db55bbd))
* set width and height for vjs-button like the SubsCaps button ([#4548](https://github.com/videojs/video.js/issues/4548)) ([cd2f510](https://github.com/videojs/video.js/commit/cd2f510)), closes [#4547](https://github.com/videojs/video.js/issues/4547)
* **lang:** typos in ar.json ([#4528](https://github.com/videojs/video.js/issues/4528)) ([3e63bf3](https://github.com/videojs/video.js/commit/3e63bf3))
### Chores
* improve dev and beginner experience ([#4555](https://github.com/videojs/video.js/issues/4555)) ([19ebc0d](https://github.com/videojs/video.js/commit/19ebc0d))
* **package:** update grunt-babel to version 7.0.0 ([#4553](https://github.com/videojs/video.js/issues/4553)) ([f6f9998](https://github.com/videojs/video.js/commit/f6f9998))
* **package:** update grunt-browserify to version 5.1.0 ([#4565](https://github.com/videojs/video.js/issues/4565)) ([8c21f0a](https://github.com/videojs/video.js/commit/8c21f0a))
* **package:** update klaw-sync to version 3.0.0 ([#4544](https://github.com/videojs/video.js/issues/4544)) ([6233d14](https://github.com/videojs/video.js/commit/6233d14))
* **package:** update rollup to version 0.47.4 ([#4570](https://github.com/videojs/video.js/issues/4570)) ([d7f7e05](https://github.com/videojs/video.js/commit/d7f7e05)), closes [#4561](https://github.com/videojs/video.js/issues/4561)
### Documentation
* updates to faq, language guide, and minor edits ([#4556](https://github.com/videojs/video.js/issues/4556)) ([1f3375e](https://github.com/videojs/video.js/commit/1f3375e))
<a name="6.2.5"></a>
## [6.2.5](https://github.com/videojs/video.js/compare/v6.2.4...v6.2.5) (2017-07-26)
### Bug Fixes
* only change focus from BPB if not a mouse click ([#4497](https://github.com/videojs/video.js/issues/4497)) ([ee014e2](https://github.com/videojs/video.js/commit/ee014e2))
### Chores
* **greenkeeper:** ignore webpack and uglify ([#4518](https://github.com/videojs/video.js/issues/4518)) ([fe95a77](https://github.com/videojs/video.js/commit/fe95a77))
* **package:** update remark-cli to version 4.0.0 ([#4508](https://github.com/videojs/video.js/issues/4508)) ([7c80e13](https://github.com/videojs/video.js/commit/7c80e13))
* **package:** update remark-parse to version 4.0.0 ([#4507](https://github.com/videojs/video.js/issues/4507)) ([abb5d67](https://github.com/videojs/video.js/commit/abb5d67))
* **package:** update remark-stringify to version 4.0.0 ([#4506](https://github.com/videojs/video.js/issues/4506)) ([bbd92ab](https://github.com/videojs/video.js/commit/bbd92ab))
<a name="6.2.4"></a>
## [6.2.4](https://github.com/videojs/video.js/compare/v6.2.3...v6.2.4) (2017-07-14)
### Chores
* fix gh-release minimist call ([#4489](https://github.com/videojs/video.js/issues/4489)) ([07594bc](https://github.com/videojs/video.js/commit/07594bc))
<a name="6.2.3"></a>
## [6.2.3](https://github.com/videojs/video.js/compare/v6.2.2...v6.2.3) (2017-07-14)
### Chores
* **gh-release:** add prerelease flag and find right zip ([#4488](https://github.com/videojs/video.js/issues/4488)) ([b1ac2e0](https://github.com/videojs/video.js/commit/b1ac2e0))
<a name="6.2.2"></a>
## [6.2.2](https://github.com/videojs/video.js/compare/v6.2.1...v6.2.2) (2017-07-14)
### Bug Fixes
* **playback rate menu:** cycling rates via click ([#4486](https://github.com/videojs/video.js/issues/4486)) ([4f43616](https://github.com/videojs/video.js/commit/4f43616))
### Chores
* **build:** remove unused var in build/version.js ([#4458](https://github.com/videojs/video.js/issues/4458)) ([6986dbb](https://github.com/videojs/video.js/commit/6986dbb))
* add automatic github release ([#4466](https://github.com/videojs/video.js/issues/4466)) ([3a600d0](https://github.com/videojs/video.js/commit/3a600d0))
* switch to using chrome for testing PRs on travis ([#4462](https://github.com/videojs/video.js/issues/4462)) ([687aae5](https://github.com/videojs/video.js/commit/687aae5))
* **package:** update rollup to version 0.45.2 ([#4487](https://github.com/videojs/video.js/issues/4487)) ([971f633](https://github.com/videojs/video.js/commit/971f633)), closes [#4475](https://github.com/videojs/video.js/issues/4475)
### Documentation
* Fix Player#src API documentation. ([#4454](https://github.com/videojs/video.js/issues/4454)) ([7579fc1](https://github.com/videojs/video.js/commit/7579fc1))
* make jsdoc generate anchor names so ToC links work ([#4471](https://github.com/videojs/video.js/issues/4471)) ([03fd402](https://github.com/videojs/video.js/commit/03fd402))
### Tests
* add unit tests for player.duration() ([#4459](https://github.com/videojs/video.js/issues/4459)) ([1e80e59](https://github.com/videojs/video.js/commit/1e80e59))
<a name="6.2.1"></a>
## [6.2.1](https://github.com/videojs/video.js/compare/v6.2.0...v6.2.1) (2017-06-28)
### Bug Fixes
* auto-removal remote text tracks being removed when not supposed to ([#4450](https://github.com/videojs/video.js/issues/4450)) ([82c8b80](https://github.com/videojs/video.js/commit/82c8b80)), closes [#4403](https://github.com/videojs/video.js/issues/4403) [#4315](https://github.com/videojs/video.js/issues/4315)
* IE10 issue for disableOthers when property access results in "permission denied" ([#4395](https://github.com/videojs/video.js/issues/4395)) ([7f7ea70](https://github.com/videojs/video.js/commit/7f7ea70)), closes [#4378](https://github.com/videojs/video.js/issues/4378)
* player.duration() should return NaN if duration is not known ([#4443](https://github.com/videojs/video.js/issues/4443)) ([f5cc165](https://github.com/videojs/video.js/commit/f5cc165))
* Safari picture-in-picture triggers fullscreenchange ([#4437](https://github.com/videojs/video.js/issues/4437)) ([b636663](https://github.com/videojs/video.js/commit/b636663))
* Update translations to match correct string ([#4383](https://github.com/videojs/video.js/issues/4383)) ([e0824c8](https://github.com/videojs/video.js/commit/e0824c8))
* Use passive event listeners for touchstart/touchmove ([#4440](https://github.com/videojs/video.js/issues/4440)) ([b4dc4f8](https://github.com/videojs/video.js/commit/b4dc4f8)), closes [#4432](https://github.com/videojs/video.js/issues/4432)
### Chores
* **package:** update husky to version 0.14.1 ([#4444](https://github.com/videojs/video.js/issues/4444)) ([66a0d23](https://github.com/videojs/video.js/commit/66a0d23)), closes [#4436](https://github.com/videojs/video.js/issues/4436)
* **package:** update rollup to version 0.42.0 ([#4392](https://github.com/videojs/video.js/issues/4392)) ([f87b12c](https://github.com/videojs/video.js/commit/f87b12c))
* **package:** update rollup-watch to version 4.0.0 ([#4396](https://github.com/videojs/video.js/issues/4396)) ([4bce4a2](https://github.com/videojs/video.js/commit/4bce4a2))
* **sandbox:** Fix paths in sandbox files. ([#4416](https://github.com/videojs/video.js/issues/4416)) ([c4bbe5d](https://github.com/videojs/video.js/commit/c4bbe5d))
### Documentation
* Fix links in API docs for several Player events. ([#4427](https://github.com/videojs/video.js/issues/4427)) ([cc6e824](https://github.com/videojs/video.js/commit/cc6e824))
* Fixing player.remoteTextTracks jsdoc ([#4417](https://github.com/videojs/video.js/issues/4417)) ([9329e3e](https://github.com/videojs/video.js/commit/9329e3e))
* Update name of FullscreenToggle in documentation ([#4410](https://github.com/videojs/video.js/issues/4410)) ([9702155](https://github.com/videojs/video.js/commit/9702155))
### Performance Improvements
* Various small performance improvements. ([#4426](https://github.com/videojs/video.js/issues/4426)) ([77ba3d1](https://github.com/videojs/video.js/commit/77ba3d1))
<a name="6.2.0"></a>
# [6.2.0](https://github.com/videojs/video.js/compare/v6.1.0...v6.2.0) (2017-05-30)
+142 -15
Ver Arquivo
@@ -259,23 +259,16 @@ git reset --hard upstream/master
## video.js releases
Releasing video.js is partially automated through [`conrib.json`](/contrib.json) scripts. To do a release, you need a couple of things: npm access, GitHub personal access token.
Releasing video.js is partially automated through various scripts.
To do a release, you need a couple of things: npm access, GitHub personal access token.
Releases in video.js are done on npm and GitHub and eventually posted on the CDN. These
are the instructions for the npm/GitHub releases.
Releases in video.js are done on npm and GitHub and eventually posted on the CDN.
These are the instructions for the npm/GitHub releases.
When we do a release, we release it as a `next` tag on npm first and then at least a week later, we promote this release to `latest` on npm.
### Getting dependencies
#### Install contrib
You can install it globally
```sh
npm i -g contrib/contrib
```
#### npm access
To see who currently has access run this:
@@ -285,6 +278,7 @@ npm owner ls video.js
```
If you are a core committer, you can request access to npm from one of the current owners.
Access is managed via an [npm organization][npm org] for [Video.js][vjs npm].
#### GitHub personal access token
@@ -292,23 +286,146 @@ This is used to make a GitHub release on videojs. You can get a token from the [
After generating one, make sure to keep it safe because GitHub will not show the token for you again. A good place to save it is Lastpass Secure Notes.
### Deciding what type of version release
Since we follow the [conventional changelog conventions][conventions],
all commits are prepended with a type, most commonly `feat` and `fix`.
If all the commits are fix or other types such as `test` or `chore`, then the release will be a `patch` release.
If there's even one `feat`, the release will be a `minor` release.
If any commit has a `BREAKING CHANGE` footer, then the release will be a `major` release.
Most common releases will be either `patch` or `minor`.
### Doing a release
To do a release, check out the master branch
It is also recommended you have a clean clone of Video.js for each release line you want to release.
That means having a folder for master/v6 and one for 5.x.
This is because 5.x and 6.x have different versions expecations for release process and have different dependencies.
Plus, during development you could end up with a dirty repo, so, it just usually easier if you have a clean release repo.
```sh
# for v6
git clone git@github.com:videojs/video.js.git videojs-6-release
# for v5
git clone git@github.com:videojs/video.js.git videojs-5-release
```
#### Video.js 6
Make sure go to the master branch and grab the latest updates.
```sh
git checkout master
git pull origin master
```
Then run the contrib command to do the next release. Don't forget to provide your GitHub token so the GitHub release goes through.
At this point, you should run `npm install` because dependencies may have changed.
Then, it's mostly a standard npm package release process with running `npm version`, followed by an `npm publish`.
```sh
VJS_GITHUB_USER=gkatsev VJS_GITHUB_TOKEN=my-personal-access-token contrib release next patch
npm version {major|minor|patch}
```
This makes a patch release, you can also do a `minor` and a `major` release.
Depending on the commits that have been merged, you can choose from `major`, `minor`, or `patch` as the versioning values.
See [deciding what type of version release section](#deciding-what-type-of-version-release).
Optionally, you can run `git show` now to verify that the version update and CHANGELOG automation worked as expected.
Afterwards, you want to push the commit and the tag to the repo.
It's necessary to do this before running `npm publish` because our GitHub release automation
relies on the commit being available on GitHub.
```sh
git push --tags origin master
```
Finally, run `npm publish` with an appropriate tag. Don't forget to supply your token.
```sh
VJS_GITHUB_USER=gkatsev VJS_GITHUB_TOKEN=my-personal-access-token npm publish --tag next
```
After it's done, verify that the GitHub release has the correct changelog output.
This is to make sure that the CHANGELOG didn't get garbled and isn't missing pieces.
If the GitHub release did not work correctly, such as if the GitHub token was not provided,
you can run it manually:
```sh
VJS_GITHUB_USER=gkatsev VJS_GITHUB_TOKEN=123 node build/gh-release.js --prelease
```
#### Video.js 5
Make sure to go to the 5.x branch and grab the latest updates.
```sh
git checkout 5.x
git pull origin 5.x
```
> *Note:* you probably need to delete v6 tags due to the way that the our CHANGELOG lib works.
>
> You can run this to delete them:
> ```sh
> git tag | grep '^v6' | xargs git tag -d
> ```
> This will find all tags that start with `^v6` and delete them.
At this point, you should run `npm install` because dependencies may have changed.
Then, we have a script that automates most of the steps for publishing. It's a little trickier than publishing v6.
##### Edit git-semver-tags
You'll need to edit `git-semver-tags` to support our usage of tags that are not part of the branch.
In the file `node_modules/conventional-changelog-cli/node_modules/conventional-changelog/node_modules/conventional-changelog-core/node_modules/git-semver-tags/index.js`, edit the line that says sets the `cmd` to be:
```js
var cmd = 'git log --all --date-order --decorate --no-color';
```
#### And now for the release
After getting rid of the tags and getting the latest updates, you can just run the release script:
```sh
VJS_GITHUB_USER=gkatsev VJS_GITHUB_TOKEN=123 ./build/bin/release-next.sh
```
It will prompt you for a version change type, so, input `patch` or `minor` or `major`.
See [deciding what type of version release section](#deciding-what-type-of-version-release).
When it's done building everything, it'll show you the commit that's made via the default pager (i.e., less).
At this point you can verify that things look normal rather than, for example, missing all the CSS.
After exiting the pager, it'll make sure you want to continue with publishing.
It will automatically release it as a `next-5` tag on npm.
Then push the local changes up:
```sh
git push --tags origin 5.x
```
Also, you'll need to copy the CHANGELOG for this version and manually edit the GitHub release to include it.
The current release's CHANGELOG could be copied from the [raw CHANGELOG.md file][raw chg] (or locally from the markdown file)
and then pasted into the correct [GitHub release](https://github.com/videojs/video.js/releases).
### Deploy as a patch to the CDN
Follow the steps on the [CDN repo][] for the CDN release process.
If it's a `next` or `next-5` release, only publish the patch version to the CDN.
When the version gets promoted to `latest` or `latest-5`, the corresponding `minor` or `latest` version should be published to the CDN.
### Announcement
An announcement should automatically make it's way to #announcements channel on [slack][], it uses IFTTT and might take a while.
You can also post it to twitter or ask someone (like @gkatsev) to post on your behalf.
If it's a large enough release, consider writing a blog post as well.
## Doc credit
@@ -319,3 +436,13 @@ This collaborator guide was heavily inspired by [node.js's guide](https://github
[pr template]: /.github/PULL_REQUEST_TEMPLATE.md
[conventions]: https://github.com/videojs/conventional-changelog-videojs/blob/master/convention.md
[vjs npm]: http://npmjs.com/org/videojs
[npm org]: https://docs.npmjs.com/misc/orgs
[slack]: http://slack.videojs.com
[CDN repo]: https://github.com/videojs/cdn
[raw chg]: https://raw.githubusercontent.com/videojs/video.js/5.x/CHANGELOG.md
+33
Ver Arquivo
@@ -0,0 +1,33 @@
var unified = require('unified');
var markdown = require('remark-parse');
var stringify = require('remark-stringify');
var fs = require('fs');
module.exports = function() {
var processor = unified()
.use(markdown, {commonmark: true})
.use(stringify);
var ast = processor.parse(fs.readFileSync('./CHANGELOG.md'));
var changelog = [];
changelog.push(processor.stringify(ast.children[0]));
// start at 1 so we get the first anchor tag
// and can break on the second
for (var i = 1; i < ast.children.length; i++) {
var item = processor.stringify(ast.children[i]);
if (/^<a name="/.test(item)) {
break;
}
if (/^###/.test(item)) {
item = '\n' + item + '\n';
}
changelog.push(item);
}
return changelog.join('\n');
};
+25 -1
Ver Arquivo
@@ -5,7 +5,31 @@ var apiPath = path.join(__dirname, '..', 'docs', 'api');
var replacements = [
{find: /\/docs\/guides\/(.+)\.md/g, replace: 'tutorial-$1.html'},
{find: /tutorial-tech.html/g, replace: 'tutorial-tech_.html'},
{find: /\/docs\/guides\//g, replace: '#'}
{find: /\/docs\/guides\//g, replace: '#'},
{find: /(\<h[1-6] id="(?:.*)?)video-js(.*)?"\>/g, replace: '$1videojs$2">'},
{find: /(\<h[1-6] id="(?:.*)?)don-t(.*)?"\>/g, replace: '$1dont$2">'},
{find: /(\<h[1-6] id="(?:.*)?)node-js(.*)?"\>/g, replace: '$1nodejs$2">'},
{find: /(\<h[1-6] id="(?:.*)?)vtt-js(.*)?"\>/g, replace: '$1vttjs$2">'},
{find: /(\<h[1-6] id=")-(.*)("\>)/g, replace: '$1$2$3'},
{find: /(\<h[1-6] id=")(.*)-("\>)/g, replace: '$1$2$3'},
{find: /(\<h[1-6] id=".*)-docs-guides-.*-md("\>)/g, replace: '$1$2'},
// replace all children with children-1
{find: /\<h3 id="children"\>/g, replace: '<h3 id="children-1">'},
// remove the -1 from the first item
{find: /\<h3 id="children-1"\>/, replace: '<h3 id="children">'},
{find: '<h4 id="nativecontrolsfortouch">', replace: '<h4 id="nativecontrolsfortouch-1">'},
{find: '<h3 id="videojs-(audio|video)track">', replace: '<h3 id="videojs$1track">'},
{find: '<h3 id="text-tracks">', replace: '<h3 id="text-tracks-1">'},
{find: '<h2 id="q-how-can-i-hide-the-links-to-my-video-subtitles-audio-tracks">',
replace: '<h2 id="q-how-can-i-hide-the-links-to-my-videosubtitlesaudiotracks">'},
{find: '<h3 id="dispose-http-docs-videojs-com-player-html-dispose">',
replace: '<h3 id="dispose">'},
{find: '<h4 id="effect-on-player-width-and-player-height">',
replace: '<h4 id="effect-on-playerwidth-and-playerheight">'},
{find: '<h4 id="i-want-to-have-a-single-source-and-dont-care-about-live-adaptive-streaming">',
replace: '<h4 id="i-want-to-have-a-single-source-and-dont-care-about-liveadaptive-streaming">'},
{find: '<h2 id="api-docs-api">', replace: '<h2 id="api-docs">'},
{find: '<h2 id="guides-docs-guides">', replace: '<h2 id="guides">'}
];
+44
Ver Arquivo
@@ -0,0 +1,44 @@
var ghrelease = require('gh-release');
var currentChangelog = require('./current-changelog.js');
var safeParse = require('safe-json-parse/tuple');
var pkg = require('../package.json')
var minimist = require('minimist');
var args = minimist(process.argv.slice(2), {
boolean: ['prerelease'],
default: {
prerelease: false
},
alias: {
p: 'prerelease'
}
});
var options = {
owner: 'videojs',
repo: 'video.js',
body: currentChangelog(),
assets: ['./dist/video-js-'+pkg.version+'.zip'],
endpoint: 'https://api.github.com',
auth: {
username: process.env.VJS_GITHUB_USER,
password: process.env.VJS_GITHUB_TOKEN
}
};
var tuple = safeParse(process.env.npm_config_argv);
var npmargs = tuple[0] ? [] : tuple[1].cooked;
if (args.prerelease || npmargs.some(function(arg) { return /next/.test(arg); })) {
options.prerelease = true;
}
ghrelease(options, function(err, result) {
if (err) {
console.error('Unable to publish release to github');
console.error('err:', err);
console.error('result:', result);
} else {
console.log('Publish release to github!');
}
});
+2 -2
Ver Arquivo
@@ -466,7 +466,7 @@ module.exports = function(grunt) {
}
},
babel: {
command: 'npm run babel -- --watch',
command: 'npm run babel -- --watch --quiet',
options: {
preferLocal: true
}
@@ -575,7 +575,7 @@ module.exports = function(grunt) {
});
// Run while developing
grunt.registerTask('dev', ['connect:dev', 'concurrent:dev']);
grunt.registerTask('dev', ['sandbox', 'connect:dev', 'concurrent:dev']);
grunt.registerTask('watchAll', ['build', 'connect:dev', 'concurrent:watchAll']);
grunt.registerTask('test-a11y', ['copy:a11y', 'accessibility']);
+9 -2
Ver Arquivo
@@ -26,6 +26,10 @@ const args = minimist(process.argv.slice(2), {
}
});
if (args.watch) {
args.progress = false;
}
const compiledLicense = _.template(fs.readFileSync('./build/license-header.txt', 'utf8'));
const bannerData = _.pick(pkg, ['version', 'copyright']);
@@ -71,6 +75,7 @@ const es = {
legacy: true
},
banner: compiledLicense(Object.assign({includesVtt: true}, bannerData)),
useStrict: false,
format: 'es',
dest: 'dist/video.es.js'
};
@@ -94,6 +99,7 @@ const umd = {
legacy: true
},
banner: compiledLicense(Object.assign({includesVtt: true}, bannerData)),
useStrict: false,
format: 'umd',
dest: 'dist/video.js'
};
@@ -134,10 +140,11 @@ const minifiedNovttUmd = Object.assign({}, _.cloneDeep(minifiedUmd), {
minifiedNovttUmd.options.plugins.unshift(ignore(['videojs-vtt.js']));
function runRollup({options, format, dest, banner}) {
function runRollup({options, useStrict, format, dest, banner}) {
rollup(options)
.then(function(bundle) {
bundle.write({
useStrict,
format,
dest,
banner,
@@ -161,7 +168,7 @@ if (!args.watch) {
runRollup(novttUmd);
}
} else {
const props = ['format', 'dest', 'banner'];
const props = ['format', 'dest', 'banner', 'useStrict'];
const watchers = [
['es', watch({rollup},
Object.assign({},
+33
Ver Arquivo
@@ -0,0 +1,33 @@
const fs = require('fs');
const path = require('path');
const klawSync = require('klaw-sync');
module.exports = function(grunt) {
grunt.registerTask('sandbox', 'copy over sandbox example files if necessary', function() {
const files = klawSync('sandbox/').filter((file) => path.extname(file.path) === '.example');
const changes = files.map(function(file) {
const p = path.parse(file.path);
const nonExample = path.join(p.dir, p.name);
return {
file: file.path,
copy: nonExample
};
})
.filter(function(change) {
return !fs.existsSync(change.copy);
});
changes.forEach(function(change) {
grunt.file.copy(change.file, change.copy);
});
if (changes.length) {
grunt.log.writeln("Updated Sandbox files for:");
grunt.log.writeln('\t' + changes.map((chg) => chg.copy).join('\n\t'));
} else {
grunt.log.writeln("No sandbox updates necessary");
}
});
};
-1
Ver Arquivo
@@ -7,7 +7,6 @@ if (tuple[0]) {
}
var sh = require('shelljs');
var version = process.env.npm_package_version;
var prereleaseType = npm_config_argv['remain'][0];
var approvedTypes = {
'major': 1,
-442
Ver Arquivo
@@ -1,442 +0,0 @@
{
"meta": {
"org": "videojs",
"name": "video.js",
"requirements": [
{
"name": "git",
"info": "http://git-scm.com"
},
{
"name": "node.js",
"info": "http://nodejs.org"
}
],
"urls": {
"repo_api": "https://api.github.com/repos/videojs/video.js",
"repo_ui": "https://github.com/videojs/video.js"
},
"branches": {
"development": "master",
"release": "stable"
}
},
"install": {
"desc": "Fork, download, and setup the project",
"steps": [
{ "prompt": "confirm", "desc": "You will now be taken to Github where you will choose an account to fork the project under. Remember which account you choose." },
{ "exec": "open https://github.com/{{meta.org}}/{{meta.name}}/fork" },
{ "prompt": "text", "desc": "Which account did you choose? (no '@')", "id": "owner" },
{ "exec": "git clone https://github.com/{{ owner }}/{{ meta.name }}.git" },
{ "exec": "cd {{ meta.name }}", "desc": "Change to the project directory" },
{ "include": "setup" }
]
},
"setup": {
"desc": "Set up version control and install dependencies",
"steps": [
[ "git fetch origin", "Get all git branches" ],
[ "git checkout -b stable origin/stable", "Create the stable branch for patches" ],
[ "git remote add upstream https://github.com/{{meta.org}}/{{meta.name}}.git", "Add the upstream project as a remote for pulling changes" ],
[ "git fetch upstream", "Get all upstream branches and changes" ],
{ "include": "update all" },
[ "grunt", "Build the library" ]
]
},
"update": {
"all": {
"steps": [
{ "include": "update stable" },
{ "include": "update master" },
[ "npm install", "Download dependencies"]
]
},
"local": {
"master": {
"steps": [
[ "git checkout master", "Switch to the development branch" ],
[ "git pull upstream master", "Get any changes to master in the main project" ]
]
},
"stable": {
"steps": [
[ "git checkout stable", "Switch to the release branch" ],
[ "git pull upstream stable", "Get any changes to stable in the main project" ]
]
},
"patch": {
"steps": [
[ "git checkout patch", "Switch to the patch branch" ],
[ "git pull upstream patch", "Get any changes to patch in the main project" ]
]
}
},
"remote": {
"master": {
"steps": [
{ "include": "update local master" },
[ "git push origin master", "Push any changes to your copy of the main project" ]
]
},
"stable": {
"steps": [
{ "include": "update local stable" },
[ "git push origin stable", "Push any changes to your copy of the main project" ]
]
},
"patch": {
"steps": [
{ "include": "update local patch" },
[ "git push origin patch", "Push any changes to your copy of the main project" ]
]
}
},
"master": {
"steps": [
{ "include": "update remote master" }
]
},
"stable": {
"steps": [
{ "include": "update remote stable" }
]
},
"patch": {
"steps": [
{ "include": "update remote patch" }
]
}
},
"test": "grunt test" ,
"watch": "grunt watch",
"server": "grunt connect",
"feature": {
"desc": "Create a new feature or general enhancement",
"baseBranch": "master",
"start": {
"desc": "Start a new feature",
"steps": [
{ "include": "update {{meta.branches.development}}" },
{ "include": "branch start" }
]
},
"save": {
"desc": "Save changes to your feature",
"steps": [{ "include": "branch save" }]
},
"submit": {
"desc": "Submit a pull request for a feature when it's finished",
"steps": [{ "include": "pull_request submit" }]
},
"delete": {
"desc": "Delete the current feature branch",
"steps": [{ "include": "branch delete" }]
},
"review": {
"desc": "Review a submitted feature",
"steps": [{ "include": "pull_request review" }]
},
"modify": {
"desc": "Modify a submitted feature that you are reviewing",
"steps": [{ "include": "pull_request modify" }]
},
"accept": {
"desc": "Merge a submitted feature",
"steps": [
{ "include": "update {{meta.branches.development}}" },
{ "include": "pull_request accept" }
]
}
},
"patch": {
"desc": "Create an urgent fix for the latest stable version",
"baseBranch": "stable",
"start": {
"desc": "Start a new patch",
"finished": "Make your changes and then run `contrib patch submit`",
"steps": [
{ "include": "update {{meta.branches.release}}" },
{ "include": "branch start" }
]
},
"save": {
"desc": "Save changes to your feature",
"steps": [{ "include": "branch save" }]
},
"submit": {
"desc": "Submit a pull request for a patch when it's finished",
"steps": [{ "include": "pull_request submit" }]
},
"delete": {
"desc": "Delete the current patch branch",
"steps": [{ "include": "branch delete" }]
},
"review": {
"desc": "Review a submitted patch",
"steps": [{ "include": "pull_request review" }]
},
"modify": {
"desc": "Modify a submitted patch that you are reviewing",
"steps": [{ "include": "pull_request modify" }]
},
"accept": {
"desc": "Merge a submitted patch",
"steps": [
{ "include": "update {{meta.branches.release}}" },
{ "include": "pull_request accept" },
[ "git checkout master", "Checkout the developmet branch" ],
[ "git merge stable", "Merge the patch changes" ],
[ "git push upstream master", "Push the development changes" ]
]
}
},
"report": {
"desc": "Submit a bug report",
"steps": [
{ "prompt": "text", "desc": "Create a title that is descriptive of the problem", "id": "title" },
{ "prompt": "text", "desc": "What did you do? (steps to reproduce)", "id": "reproduce" },
{ "prompt": "text", "desc": "What did you expect to happen?", "id": "expected" },
{ "prompt": "text", "desc": "What actually happened?", "id": "actual" },
{ "prompt": "text", "desc": "What version of video.js are you using?", "id": "version" },
{ "prompt": "text", "desc": "Are you using any video.js plugins?", "id": "plugins" },
{ "prompt": "text", "desc": "What browsers/platforms did you experience this in (e.g. Win 7, IE10; Android 4, Chrome;)?", "id": "browsers" },
{ "prompt": "text", "desc": "Is there a URL to a live example, or a jsbin (e.g. http://jsbin.com/axedog/9999/edit)?", "id": "example" },
{ "prompt": "text", "desc": "Are there any other details you'd like to provide?", "id": "details" },
{ "open": "{{meta.urls.repo_ui}}/issues/new?title={{title}}&body=**Steps to reproduce:**\n> {{reproduce}}\n\n**What was expected:**\n> {{expected}}\n\n**What Happened:**\n> {{actual}}\n\n**Video.js Version:**\n> {{version}}\n\n**Plugins:**\n> {{plugins}}\n\n**Browsers experienced on:**\n> {{browsers}}\n\n**Example:**\n> {{example}}\n\n**Other details:**\n> {{details}}" }
],
"finished": "Thanks for submitting a bug report! One of our contributors will address it as soon as possible."
},
"request": {
"desc": "Submit a feature/enhancement request",
"steps": [
{ "prompt": "text", "desc": "Create a title that is descriptive of the enhancement", "id": "title" },
{ "prompt": "text", "desc": "Describe the feature/enhancement (be as detailed as possible so it's clear who, why, and how it would be used)", "id": "describe" },
{ "prompt": "text", "desc": "Is there any existing documentation or related specifications?", "id": "docs" },
{ "prompt": "text", "desc": "Are there any existing examples?", "id": "examples" },
{ "prompt": "confirm", "desc": "You will be redirected to Github where you can submit this issue, OK?" },
{ "open": "{{meta.urls.repo_ui}}/issues/new?title={{ title }}&body=**Describe the feature/enhancement:**\n> {{ describe }}\n\n**Existing docs/specs:**\n> {{ docs }}\n\n**Existing examples:**\n> {{ examples }}" }
],
"finished": "Thanks for submitting a feature request! One of our contributors will address it as soon as possible."
},
"release": {
"desc": "Create and publish releases",
"patch": {
"release_type": "patch",
"description": "Create a patch release from the release branch (stable)",
"steps": [{ "include": "release run" }]
},
"minor": {
"description": "Create a minor release from the development branch (master)",
"release_type": "minor",
"steps": [
{ "include": "update local master" },
{ "include": "update local stable" },
[ "git merge master", "Copy the latest development changes to the release branch" ],
{ "include": "release run" },
[ "git checkout master", "Checkout the developmet branch" ],
[ "git merge stable", "Merge package changes into the dev brach" ],
[ "git push upstream master", "Push the dev branch changes to the repo" ]
]
},
"next": {
"patch": {
"description": "Create a patch release and tag it @next on npm",
"release_type": "patch",
"steps": [{ "include": "release run_next" }]
},
"minor": {
"description": "Create a minor release and tag it @next on npm",
"release_type": "minor",
"steps": [{ "include": "release run_next" }]
},
"major": {
"description": "Create a major release and tag it @next on npm",
"release_type": "major",
"steps": [{ "include": "release run_next" }]
}
},
"prerelease": {
"release_type": "prerelease",
"steps": [{ "include": "release run_next" }]
},
"run_next": {
"steps": [
{ "include": "branch check" },
{ "include": "update local master" },
[ "git checkout -b temp-release-branch master","Create a temporary branch for the dist" ],
[ "grunt version:{{release_type}}", "Bump package versions" ],
[ "./build/bin/version", "Return the current VJS Version from the package.json file", "version" ],
[ "npm run changelog", "Update the changelog with the new release" ],
[ "git commit -am 'v{{version}}'", "Add and commit the package changes" ],
[ "git checkout master", "Checkout the developmet branch" ],
[ "git merge temp-release-branch", "Merge package changes into the dev brach" ],
[ "git push upstream master", "Push the dev branch changes to the repo" ],
[ "git checkout temp-release-branch", "Checkout the temp branch again" ],
[ "grunt dist", "Build the dist" ],
[ "git add es5 dist --force", "Add the (otherwise ignored) release files" ],
[ "git commit -m 'v{{version}} dist'", "Commit the dist changes" ],
[ "git tag -a v{{version}} -m 'v{{version}}'", "Tag the release" ],
[ "git push upstream --tags", "Push the new tag to the repo" ],
[ "grunt github-release:prerelease", "Create a new pre-release on Github" ],
[ "npm publish --tag next", "Publish to npm as 'next'" ],
[ "git checkout master", "Checkout the developmet branch" ],
[ "git branch -D temp-release-branch", "Delete the temp release branch" ]
]
},
"run": {
"steps": [
{ "include": "branch check" },
{ "include": "update local stable" },
[ "npm install", "Ensure dependency updates have been installed" ],
[ "grunt test", "Run tests" ],
[ "grunt version:{{release_type}}", "Bump package versions" ],
[ "./build/bin/version", "Return the current VJS Version from the package.json file", "version" ],
[ "npm run changelog", "Update the changelog with the new release" ],
[ "git commit -am 'v{{version}}'", "Add and commit the package changes" ],
[ "git push upstream stable", "Push the release branch changes to the repo" ],
[ "git checkout -b temp-release-branch stable","Create a temporary branch for the dist" ],
[ "grunt dist", "Build the dist" ],
[ "git add es5 dist --force", "Add the (otherwise ignored) release files" ],
[ "git commit -m 'v{{version}} dist'", "Commit the dist changes" ],
[ "git tag -a v{{version}} -m 'v{{version}}'", "Tag the release" ],
[ "git push upstream --tags", "Push the new tag to the repo" ],
[ "npm publish", "Publish to npm" ],
[ "grunt github-release:release", "Create a new release on Github" ],
[ "git checkout stable", "Checkout the developmet branch" ],
[ "git branch -D temp-release-branch", "Delete the temp release branch" ]
]
}
},
"branch": {
"private": true,
"start": {
"steps": [
{ "prompt": "text", "id": "name", "desc": "Name the branch" },
{ "exec": "git checkout -b {{name}} {{baseBranch}}", "desc": "Create the branch" },
{ "exec": "git push -u origin {{name}}", "desc": "Push the branch to your remote copy of the project" }
]
},
"save": {
"desc": "Commit and push changes made to files in the project",
"steps": [
{ "include": "branch confirm" },
{ "prompt": "text", "id": "message", "desc": "Briefly describe the changes made" },
{ "exec": "git add .", "desc": "Add the changes" },
{ "exec": "git commit -m '{{message}}'", "desc": "Commit the changes" },
{ "exec": "git push origin {{branch_name}}", "desc": "Push the changes to your remote copy of the project" }
]
},
"check": {
"private": true,
"desc": "Check for unsaved changes",
"steps": [
{ "exec": "git diff --exit-code", "desc": "Ensure there's no unadded changes", "fail": "Make sure all changes have been saved (added and committed) or stashed" },
{ "exec": "git diff --cached --exit-code", "desc": "Ensure there's no uncommitted changes", "fail": "Make sure all changes have been saved (added and committed) or stashed" }
]
},
"name": {
"private": true,
"steps": [
{ "exec": "git rev-parse --abbrev-ref HEAD", "desc": "Get the current branch", "id": "branch_name" }
]
},
"confirm": {
"private": true,
"steps": [
{ "include": "branch name" },
{ "prompt": "confirm", "desc": "Are you sure *{{branch_name}}* is the correct branch?" }
]
},
"delete": {
"desc": "Delete the current branch",
"steps": [
{ "include": "branch confirm" },
{ "exec": "git checkout master", "desc": "Exit the branch being deleted" },
{ "exec": "git branch -D {{branch_name}}", "desc": "Delete the local copy of the branch" },
{ "exec": "git push origin :{{branch_name}}", "desc": "Delete the remote copy of the branch" }
]
}
},
"pull_request": {
"private": true,
"desc": "Pull request related commands",
"prepare": {
"private": true,
"steps": [
{ "include": "branch check" },
{ "include": "branch confirm" },
{ "include": "test" },
{ "prompt": "text", "desc": "Which github user or org are you submitting from?", "id": "user" }
]
},
"submit": {
"desc": "Submit a pull request for when the change is finished",
"steps": [
{ "include": "pull_request prepare" },
{ "open": "{{meta.urls.repo_ui}}/compare/videojs:{{baseBranch}}...{{user}}:{{branch_name}}", "desc": "Open the github pull request page" }
]
},
"review": {
"steps": [
{ "prompt": "text", "desc": "What is the the pull request number?", "id": "prNum" },
{ "get": "{{meta.urls.repo_api}}/pulls/{{prNum}}", "desc": "Get the PR information", "id": "pr" },
[ "git fetch {{pr.head.repo.ssh_url}} {{pr.head.ref}}", "Get the pull request changes but don't merge them" ],
[ "git merge-base master FETCH_HEAD", "Get the common ancestor commit", "base" ],
[ "git checkout -b review-{{pr.user.login}}-{{pr.head.ref}} {{base}}", "Create a new local branch for the pull request that has a base of the common commit" ],
[ "git merge FETCH_HEAD", "Merge in the pull request changes" ],
[ "npm install", "Install any new dependencies" ],
[ "grunt test", "Build and run tests" ]
]
},
"modify": {
"desc": "Submit a modification to a pull request that you are currently reviewing",
"steps": [
{ "include": "pull_request prepare" },
{ "prompt": "text", "desc": "What is the the pull request number?", "id": "prNum" },
{ "get": "{{meta.urls.repo_api}}/pulls/{{prNum}}", "desc": "Get the PR information", "id": "pr" },
{ "exec": "git push -u origin {{branch_name}}", "desc": "Push the changes to the remote repo" },
{ "open": "https://github.com/{{user}}/video.js/compare/{{pr.head.label}}...{{user}}:{{branch_name}}", "desc": "Open the github pull request page" }
]
},
"accept": {
"steps": [
{ "prompt": "text", "id": "prNum", "desc": "What is the the pull request number?" },
{ "get": "{{meta.urls.repo_api}}/pulls/{{prNum}}", "desc": "Get the PR information", "id": "pr" },
{ "get": "{{meta.urls.repo_api}}/pulls/{{prNum}}/commits", "desc": "Get the PR commits to access author info", "id": "prCommits" },
[ "git checkout -b {{pr.user.login}}/{{pr.head.ref}} {{pr.base.ref}}", "Create a new branch for merging the changes" ],
[ "git fetch {{pr.head.repo.ssh_url}} {{pr.head.ref}}", "Fetch the changes" ],
[ "git merge --no-commit --squash FETCH_HEAD", "Merge the changes in without committing so they can be squashed" ],
[ "grunt test", "Run tests to make sure they still pass" ],
{ "prompt": "text", "id": "line", "desc": "Describe this change in one line" },
[ "grunt chg-add:'{{{line}}} ([view](https\\://github.com/videojs/video.js/pull/{{prNum}}))'", "Add a line to the changelog" ],
[ "git add CHANGELOG.md", "Add the changlelog change to be committed" ],
[ "git commit -a --author='{{prCommits.[0].commit.author.name}} <{{prCommits.[0].commit.author.email}}>' -m '{{line}}. closes #{{prNum}}'", "Commit the changes" ],
{ "prompt": "confirm", "desc": "Does everything look ok?" },
[ "git checkout {{pr.base.ref}}", "Check out the base branch" ],
[ "git merge {{pr.user.login}}/{{pr.head.ref}}", "Merge the changes" ],
[ "git push origin {{pr.base.ref}}", "Push the changes to your remote copy of the project" ],
[ "git push upstream {{pr.base.ref}}", "Push the changes to the main project" ],
[ "git branch -D {{pr.user.login}}/{{pr.head.ref}}", "Delete the local branch used for merging" ]
]
}
}
}
+1 -1
Ver Arquivo
@@ -12,7 +12,7 @@
## Logging
Video.js includes a lightweight wrapper - `videojs.log` - around a subset of [the `console` API][console]. The available methods are `videojs.log`, `videojs.log.warn`, and `videojs.log.error`.
Video.js includes `videojs.log`, a lightweight wrapper around a subset of [the `console` API][console]. The available methods are `videojs.log`, `videojs.log.warn`, and `videojs.log.error`.
### API Overview
+1 -1
Ver Arquivo
@@ -10,7 +10,7 @@
## Overview
Events in video.js are setup so that they mimic the DOM API that is used on object, but also have helpful shorthand functions with the same functionality.
Events in Video.js are setup so that they mimic the DOM API that is used on object, but also have helpful shorthand functions with the same functionality.
## `on()` and `addEventListener()`
+130 -101
Ver Arquivo
@@ -2,109 +2,112 @@
## Table of Contents
* [Q: What is video.js?](#q-what-is-videojs)
* [Q: How do I install video.js?](#q-how-do-i-install-videojs)
* [Q: Is video.js on bower?](#q-is-videojs-on-bower)
* [Q: What do video.js version numbers mean?](#q-what-do-videojs-version-numbers-mean)
* [Q: What is Video.js?](#q-what-is-videojs)
* [Q: How do I install Video.js?](#q-how-do-i-install-videojs)
* [Q: Is Video.js on bower?](#q-is-videojs-on-bower)
* [Q: What do Video.js version numbers mean?](#q-what-do-videojs-version-numbers-mean)
* [Q: How can I troubleshoot playback issues?](#q-how-can-i-troubleshoot-playback-issues)
* [Q: A video does not play in a specific browser. Why?](#q-a-video-does-not-play-in-a-specific-browser-why)
* [Q: Why does the entire video download before playback? Why does the video load for a long time?](#q-why-does-the-entire-video-download-before-playback-why-does-the-video-load-for-a-long-time)
* [Q: I see an error thrown that mentions vdata12345. What is that?](#q-i-see-an-error-thrown-that-mentions-vdata12345-what-is-that)
* [Q: I think I found a bug with video.js or I want to add a feature. What should I do?](#q-i-think-i-found-a-bug-with-videojs-or-i-want-to-add-a-feature-what-should-i-do)
* [Q: I think I found a bug with Video.js or I want to add a feature. What should I do?](#q-i-think-i-found-a-bug-with-videojs-or-i-want-to-add-a-feature-what-should-i-do)
* [if you think that you can fix the issue or add the feature](#if-you-think-that-you-can-fix-the-issue-or-add-the-feature)
* [If you don't think you can fix the issue or add the feature](#if-you-dont-think-you-can-fix-the-issue-or-add-the-feature)
* [Q: What is a reduced test case?](#q-what-is-a-reduced-test-case)
* [Q: What media formats does video.js support?](#q-what-media-formats-does-videojs-support)
* [Q: What media formats does Video.js support?](#q-what-media-formats-does-videojs-support)
* [Q: How does Video.js choose which source to use?](#q-how-does-videojs-choose-which-source-to-use)
* [Q: How to I autoplay the video?](#q-how-to-i-autoplay-the-video)
* [Q: How can I autoplay a video on a mobile device?](#q-how-can-i-autoplay-a-video-on-a-mobile-device)
* [Q: How can I play RTMP video in video.js?](#q-how-can-i-play-rtmp-video-in-videojs)
* [Q: How can I play RTMP video in Video.js?](#q-how-can-i-play-rtmp-video-in-videojs)
* [Q: How can I hide the links to my video/subtitles/audio/tracks?](#q-how-can-i-hide-the-links-to-my-videosubtitlesaudiotracks)
* [Q: Can I turn off video.js logging?](#q-can-i-turn-off-videojs-logging)
* [Q: Can I turn off Video.js logging?](#q-can-i-turn-off-videojs-logging)
* [Q: What is a plugin?](#q-what-is-a-plugin)
* [Q: How do I make a plugin for video.js?](#q-how-do-i-make-a-plugin-for-videojs)
* [Q: Where can I find a list of video.js plugins?](#q-where-can-i-find-a-list-of-videojs-plugins)
* [Q: How do I make a plugin for Video.js?](#q-how-do-i-make-a-plugin-for-videojs)
* [Q: Where can I find a list of Video.js plugins?](#q-where-can-i-find-a-list-of-videojs-plugins)
* [Q: How can I get my plugin listed on the website?](#q-how-can-i-get-my-plugin-listed-on-the-website)
* [Q: Where can I find a list of video.js skins?](#q-where-can-i-find-a-list-of-videojs-skins)
* [Q: Does video.js work as an audio only player?](#q-does-videojs-work-as-an-audio-only-player)
* [Q: Does video.js support audio tracks?](#q-does-videojs-support-audio-tracks)
* [Q: Does video.js support video tracks?](#q-does-videojs-support-video-tracks)
* [Q: Does video.js support text tracks (captions, subtitles, etc)?](#q-does-videojs-support-text-tracks-captions-subtitles-etc)
* [Q: Does video.js support HLS (HTTP Live streaming) video?](#q-does-videojs-support-hls-http-live-streaming-video)
* [Q: Does video.js support MPEG Dash video?](#q-does-videojs-support-mpeg-dash-video)
* [Q: Does video.js support live video?](#q-does-videojs-support-live-video)
* [Q: Can video.js wrap around YouTube videos?](#q-can-videojs-wrap-around-youtube-videos)
* [Q: Can video.js wrap around Vimeo videos?](#q-can-videojs-wrap-around-vimeo-videos)
* [Q: Does video.js support DRM video?](#q-does-videojs-support-drm-video)
* [Q: Does video.js have any support for advertisement integrations?](#q-does-videojs-have-any-support-for-advertisement-integrations)
* [Q: Can video.js be required in node.js?](#q-can-videojs-be-required-in-nodejs)
* [Q: Does video.js work with webpack?](#q-does-videojs-work-with-webpack)
* [Q: Does video.js work with react?](#q-does-videojs-work-with-react)
* [Q: Where can I find a list of Video.js skins?](#q-where-can-i-find-a-list-of-videojs-skins)
* [Q: Does Video.js work as an audio only player?](#q-does-videojs-work-as-an-audio-only-player)
* [Q: Does Video.js support audio tracks?](#q-does-videojs-support-audio-tracks)
* [Q: Does Video.js support video tracks?](#q-does-videojs-support-video-tracks)
* [Q: Does Video.js support text tracks (captions, subtitles, etc)?](#q-does-videojs-support-text-tracks-captions-subtitles-etc)
* [Q: Does Video.js support HLS (HTTP Live streaming) video?](#q-does-videojs-support-hls-http-live-streaming-video)
* [Q: Does Video.js support MPEG Dash video?](#q-does-videojs-support-mpeg-dash-video)
* [Q: Does Video.js support live video?](#q-does-videojs-support-live-video)
* [Q: Can Video.js wrap around YouTube videos?](#q-can-videojs-wrap-around-youtube-videos)
* [Q: Can Video.js wrap around Vimeo videos?](#q-can-videojs-wrap-around-vimeo-videos)
* [Q: Does Video.js support DRM video?](#q-does-videojs-support-drm-video)
* [Q: Does Video.js have any support for advertisement integrations?](#q-does-videojs-have-any-support-for-advertisement-integrations)
* [Q: Can Video.js be required in node.js?](#q-can-videojs-be-required-in-nodejs)
* [Q: Does Video.js work with webpack?](#q-does-videojs-work-with-webpack)
* [Q: Does Video.js work with react?](#q-does-videojs-work-with-react)
## Q: What is video.js?
## Q: What is Video.js?
video.js is an extendable framework/library around the native video element. It does the following:
Video.js is an extendable framework/library around the native video element. It does the following:
* Offers a plugin API so that different types of video can be handed to the native
video element (e.g. [HLS][hls], [Flash][flash], HTML5 video, etc).
* Unifies the native video api across browsers (polyfilling support for features
* Unifies the native video API across browsers (polyfilling support for features
if necessary)
* Offers an extendable and themable UI
* Takes care of accessibility for the user (in-progress)
* Has a set of core plugins that offer support for tons of additional video formats.
* Ensures accessibility for keyboard and screen reader users
* Has a set of core plugins that offer support for additional video formats:
* [videojs-contrib-hls][hls]
* [videojs-contrib-dash][dash]
* Support for DRM video via a core plugin
* Supports DRM video via a core plugin:
* [videojs-contrib-eme][eme]
* Lots of plugins which offer support for all kinds of features. See the [plugin list on videojs.com][plugin-list]
* Is extensible with lots of plugins offering support for all kinds of features. See the [plugin list on videojs.com][plugin-list]
## Q: How do I install video.js?
## Q: How do I install Video.js?
Currently video.js can be installed using npm, serving a release file from
a github tag, or even using a CDN hosted version. For information on doing any of those
see the [install guide][install-guide].
Currently Video.js can be installed using npm, serving a release file from
a GitHub tag, or even using a CDN hosted version. For information on doing any of those
see the [setup guide][install-guide].
## Q: Is video.js on bower?
## Q: Is Video.js on bower?
Versions prior to video.js 6 do support bower, however, as of video.js 6, bower is no
Versions prior to Video.js 6 support bower, however, as of Video.js 6, bower is no
longer officially supported. Please see https://github.com/videojs/video.js/issues/4012
for more information.
## Q: What do video.js version numbers mean?
## Q: What do Video.js version numbers mean?
video.js follows [semver][semver] which means that the API should not change
Video.js follows [semver][semver] which means that the API should not change
out from under a user unless there is a major version increase.
## Q: How can I troubleshoot playback issues?
See the [troubleshooting guide][troubleshooting]. If troubleshooting does not
solve your issue, please submit a [pull request or an issue][pr-issue-question].
solve your issue, please ask in [Slack][slack] or submit an [issue][pr-issue-question].
When seeking help about a playback issue the problem is often specific to the video file used, the way the video is hosted or the browser, so make sure to include all of that information and a [reduced test case](#q-what-is-a-reduced-test-case).
## Q: A video does not play in a specific browser. Why?
See the [troubleshooting guide][troubleshooting]. If troubleshooting does not
solve your issue, please submit a [pull request or an issue][pr-issue-question].
solve your issue, please ask in [Slack][slack] or submit an [issue][pr-issue-question].
## Q: Why does the entire video download before playback? Why does the video load for a long time?
See the [troubleshooting guide][troubleshooting]. If troubleshooting does not
solve your issue, please submit a [pull request or an issue][pr-issue-question].
solve your issue, please ask in [Slack][slack] or submit an [issue][pr-issue-question].
## Q: I see an error thrown that mentions `vdata12345`. What is that?
See the [troubleshooting guide][troubleshooting]. If troubleshooting does not
solve your issue, please submit a [pull request or an issue][pr-issue-question].
solve your issue, please ask in [Slack][slack] or submit an [issue][pr-issue-question].
## Q: I think I found a bug with video.js or I want to add a feature. What should I do?
## Q: I think I found a bug with Video.js or I want to add a feature. What should I do?
### if you think that you can fix the issue or add the feature
### If you think that you can fix the issue or add the feature
Submit a pull request to the [video.js repo][vjs-prs].
A pull request would be very welcome in the [Video.js repo][vjs-prs].
Make sure to follow the [contributing guide][contributing-prs] and
the [pull request template][pr-template].
### If you don't think you can fix the issue or add the feature
Open an [issue on the video.js repo][vjs-issues]. Make
Open an [issue on the Video.js repo][vjs-issues]. Make
sure that you follow the [issue template][issue-template] and the
[contributing guide][contributing-issues] so that we can better assist you
with your issue.
@@ -113,18 +116,28 @@ with your issue.
A reduced test case is an example of the problem that you are facing in isolation.
Think of it as example page that reproduces the issue in the least amount of possible code.
It's important to add a reduced case. Even if the problem seems obvious it may not be to
others. Having a example to refer to also makes the difference between somebody being able
to take a look and immediately see what's wrong, and needing to take time to recreate what
they think you are describing.
We have a [starter example][starter-example] for reduced test cases. To learn more
about reduced test cases visit [css-tricks][reduced-test-case]
## Q: What media formats does video.js support?
## Q: What media formats does Video.js support?
This depends on the formats supported by the browser's HTML5 video element, and the playback
techs/plugins made available to video.js. For more information on media formats see the [troubleshooting guide][troubleshooting].
techs/plugins made available to Video.js. For more information on media formats see the [troubleshooting guide][troubleshooting].
## Q: How does Video.js choose which source to use?
When an array of sources is available, Video.js test each source in the order given. For each source, each tech in the [`techOrder`][techorder] will be checked to see if it can play it whether directly or via source handler (such as videojs-contrib-hls). The first match will be chosen.
## Q: How to I autoplay the video?
Video.js supports the standard html5 `autoplay` attribute on the video element.
It also supports it as an option to video.js or as a method invocation on the player.
It also supports it as an option to Video.js or as a method invocation on the player.
```html
<video autoplay controls class="video-js">
@@ -143,7 +156,7 @@ player.autoplay(true);
### Q: How can I autoplay a video on a mobile device?
Most mobile devices have blocked autoplaying videos until recently.
For mobile devices that don't support autoplaying, autoplay isn't supported by video.js.
For mobile devices that don't support autoplaying, autoplay isn't supported by Video.js.
For those devices that support autoplaying, like iOS10 and Chrome for Android 53+,
you must mute the video or have a video without audio tracks to be able to play it.
For example:
@@ -154,23 +167,28 @@ For example:
Will make an inline, muted, autoplaying video on an iPhone with iOS10.
## Q: How can I play RTMP video in video.js?
## Q: How can I play RTMP video in Video.js?
Make sure that the Flash tech is available -- RTMP is not playable on browsers without Flash including mobile. Flash will only be available on video.js 6 with the [videojs-flash package][flash], in previous versions it was builtin to video.js. Then, just set the rtmp source with an appropriate type -- `rtmp/mp4` or `rtmp/flv`.
The main thing to be aware of is that video.js splits the connection url and stream name with the `&` character.
So, you'd want to update the url to follow that format. For example: `rtmp://example.com/live&foo` or `rtmp://example.com/fms&mp4:path/to/file.mp4`.
RTMP requires Flash to play back. You'll need both a browser that supports Flash and the Flash tech.
If the server requires query parameters for authentication, these should be added to the connection part url, for example `rtmp://example.com/live?token=1234&foo`.
In Video.js version 6, the Flash tech is not included by default and is available as a separate [videojs-flash package][flash]. In previous versions it was builtin to Video.js.
The RTMP source should be set with an appropriate type -- `rtmp/mp4` or `rtmp/flv`.
Be aware of that Video.js splits the connection url and stream name with the `&` character, for example: `rtmp://example.com/live&foo` or `rtmp://example.com/fms&mp4:path/to/file.mp4`.
If the server requires query parameters for authentication, these should be added to the connection part URL, for example `rtmp://example.com/live?token=1234&foo`.
Bear in mind that mobile browsers do not support Flash, and modern desktop browsers make it increasingly difficult to use Flash or disable it by default for your end users. Consider moving to a modern format such as HLS or DASH.
## Q: How can I hide the links to my video/subtitles/audio/tracks?
It's impossible to hide the network requests a browser makes and difficult to
sufficiently obfuscate URLs in the source. Techniques such as token authentication may
help but are outside of the scope of video.js.
help but are outside of the scope of Video.js.
For content that must be highly secure [videojs-contrib-eme][eme] adds DRM support.
## Q: Can I turn off video.js logging?
## Q: Can I turn off Video.js logging?
Yes! This can be achieved by adding the following code _after_ including Video.js, but _before_ creating any player(s):
@@ -183,21 +201,19 @@ For more information, including which logging levels are available, check out th
## Q: What is a plugin?
A plugin is a group of reusable functionality that can be re-used by others. For instance a plugin could add
a button to video.js that makes the video replay 10 times in a row before it stops playback for good. If such
a button to Video.js that makes the video replay 10 times in a row before it stops playback for good. If such
a plugin existed and was published users could include it on their page to share that functionality.
## Q: How do I make a plugin for video.js?
## Q: How do I make a plugin for Video.js?
See the [plugin guide][plugin-guide] for information on making a plugin for video.js.
See the [plugin guide][plugin-guide] for information on making a plugin for Video.js.
<!-- TODO: Once these is a button guide, add this back in
## Q: How do I add a button to video.js?
See the [button guide][button-guide] for information on adding a button to video.js.
-->
## Q: How do I add a button to Video.js?
See the [components guide][components-guide] for an example of adding a button to Video.js.
## Q: Where can I find a list of video.js plugins?
## Q: Where can I find a list of Video.js plugins?
The official [list of plugins on videojs.com][plugin-list].
A list of plugins published to npm with the `videojs-plugin` keyword is maintained [on videojs.com][plugin-list].
## Q: How can I get my plugin listed on the website?
@@ -205,72 +221,73 @@ Add the 'videojs-plugin' [keyword to your array in package.json][npm-keywords]
and publish your package to npm. If you use the [plugin generator][generator] this will be done automatically for you. See
the [plugins guide][plugin-guide] for more information.
## Q: Where can I find a list of video.js skins?
## Q: Where can I find a list of Video.js skins?
See the [video.js github wiki][skins-list].
See the [Video.js GitHub wiki][skins-list].
## Q: Does video.js work as an audio only player?
## Q: Does Video.js work as an audio only player?
Yes! It can be used to play audio only files in a `<video>` or `<audio>` tag. The
difference being that the `<audio>` tag will not have a blank display area and the `<video>`
tag will. Note that audio only will not work with the Flash playback tech. The Flash playback tech will only be included in versions of video.js before 6. In Video.js 6 you will need to use the [videojs-flash package][flash].
Yes! It can be used to play audio only files in a `<video>` or `<audio>` tag.
Note that audio-only sources do not work with the Flash playback tech.
## Q: Does video.js support audio tracks?
## Q: Does Video.js support audio tracks?
Yes! See the [audio tracks guide][audio-tracks] for information on using audio tracks.
## Q: Does video.js support video tracks?
## Q: Does Video.js support video tracks?
The code for video tracks exists but it has not been tested. See the [video tracks guide][video-tracks]
Alternate video tracks support is in development. See [video tracks guide][video-tracks]
for more information on using video tracks.
## Q: Does video.js support text tracks (captions, subtitles, etc)?
## Q: Does Video.js support text tracks (captions, subtitles, etc)?
Yes! See the [text tracks guide][text-tracks] for information on using text tracks.
## Q: Does video.js support HLS (HTTP Live streaming) video?
## Q: Does Video.js support HLS (HTTP Live streaming) video?
video.js supports HLS video if the native HTML5 element supports HLS (e.g. Safari, Edge,
Chrome for Android, and iOS). For browsers without native support see the [videojs-contrib-hls][hls]
Video.js supports HLS video if the native HTML5 element supports HLS (e.g. Safari, Edge,
Chrome for Android, and iOS). For browsers without native support the [videojs-contrib-hls][hls]
project which adds support.
## Q: Does video.js support MPEG Dash video?
Note that for non-native playback of HLS it is essential that the server hosting the video sets [CORS headers][cors].
video.js itself does not support MPEG DASH, however an official project called [videojs-contrib-dash][dash]
adds support for MPEG DASH video.
## Q: Does Video.js support MPEG DASH video?
## Q: Does video.js support live video?
MPEG DASH support is provided byt the [videojs-contrib-dash][dash]
package.
Yes! Video.js adds support for live videos via the Flash tech tech which supports RTMP streams. In Video.js 6 you will have to use [videojs-flash][flash] to get this. In previous versions the Flash tech was builtin. The official HLS tech, [videojs-contrib-hls][hls], will add support for live HLS video
if you add it to your page with video.js.
Like HLS, DASH streams require [CORS headers][cors].
## Q: Can video.js wrap around YouTube videos?
## Q: Does Video.js support live video?
No. There is an official plugin that adds support. It is called [videojs-youtube][youtube].
Yes! Common formats for live are HLS or historically RTMP.
HLS is supported via [videojs-contrib-hls][hls]. and RTMP via [videojs-flash][flash].
## Q: Can video.js wrap around Vimeo videos?
## Q: Can Video.js play YouTube videos?
No. There is an official plugin that adds support. It is called [videojs-vimeo][vimeo].
There is an official plugin that adds support, [videojs-youtube][youtube].
## Q: Does video.js support DRM video?
## Q: Can Video.js play Vimeo videos?
No. There is an official plugin that adds support. It is called [videojs-contrib-eme][eme].
There is an official plugin that adds support, [videojs-vimeo][vimeo].
## Q: Does video.js have any support for advertisement integrations?
## Q: Does Video.js support DRM video?
No. There is an official plugin that adds support. It is called [videojs-contrib-ads][ads].
There is an official plugin that adds support, [videojs-contrib-eme][eme].
## Q: Can video.js be required in node.js?
## Q: Does Video.js have any support for advertisement integrations?
Yes! Please [submit an issue or open a pull request][pr-issue-question] if this does not work.
There is an official plugin that adds core advertising support, [videojs-contrib-ads][ads]. Further plugins build on this which handle the communication with the ad server and display of the ad, for instance [Google's IMA plugin][google-ima].
## Q: Does video.js work with webpack?
## Q: Can Video.js be required in node.js?
Yes! Please [submit an issue or open a pull request][pr-issue-question] if this does not work.
Yes! Video.js is [published on NPM][node].
We have a short guide that deals with small configurations that you will need to do. [Webpack and Videojs Configuration][webpack-guide].
## Q: Does Video.js work with webpack?
## Q: Does video.js work with react?
Yes! See the [Webpack and Video.js configuration guide][webpack-guide].
## Q: Does Video.js work with react?
Yes! See [ReactJS integration example][react-guide].
@@ -282,6 +299,10 @@ Yes! See [ReactJS integration example][react-guide].
[contributing-prs]: http://github.com/videojs/video.js/blob/master/CONTRIBUTING.md#contributing-code
[components-guide]: /docs/guides/components.md
[cors]: https://enable-cors.org
[dash]: http://github.com/videojs/videojs-contrib-dash
[debug-guide]: /docs/guides/debugging.md
@@ -292,12 +313,16 @@ Yes! See [ReactJS integration example][react-guide].
[generator]: https://github.com/videojs/generator-videojs-plugin
[google-ima]: https://github.com/googleads/videojs-ima
[hls]: http://github.com/videojs/videojs-contrib-hls
[install-guide]: http://videojs.com/getting-started/
[issue-template]: http://github.com/videojs/video.js/blob/master/.github/ISSUE_TEMPLATE.md
[node]: https://www.npmjs.com/package/video.js
[npm-keywords]: https://docs.npmjs.com/files/package.json#keywords
[plugin-guide]: /docs/guides/plugins.md
@@ -316,8 +341,12 @@ Yes! See [ReactJS integration example][react-guide].
[skins-list]: https://github.com/videojs/video.js/wiki/Skins
[slack]: https://videojs.slack.com
[starter-example]: http://jsbin.com/axedog/edit?html,output
[techorder]: [cors]: /docs/guides/options.md#techorder
[text-tracks]: /docs/guides/text-tracks.md
[troubleshooting]: /docs/guides/troubleshooting.md
+16 -16
Ver Arquivo
@@ -1,6 +1,6 @@
# Hooks
Hooks exist so that users can "hook" on to certain video.js player lifecycle
Hooks exist so that users can "hook" on to certain Video.js player lifecycle
## Table of Contents
@@ -14,27 +14,27 @@ Hooks exist so that users can "hook" on to certain video.js player lifecycle
## Current Hooks
Currently, the following hooks are avialable:
Currently, the following hooks are available:
### beforesetup
`beforesetup` is called just before the player is created. This allows:
* modification of the options passed to the video.js function (`videojs('some-id, options)`)
* modification of the options passed to the Video.js function (`videojs('some-id, options)`)
* modification of the dom video element that will be used for the player
`beforesetup` hook functions should:
* take two arguments
1. videoEl: dom video element that video.js is going to use to create a player
1. options: options that video.js was intialized with and will later pass to the player during creation
* return options that will merge and override options that video.js with intialized with
1. videoEl: dom video element that Video.js is going to use to create a player
1. options: options that Video.js was intialized with and will later pass to the player during creation
* return options that will merge and override options that Video.js with intialized with
Example: adding beforesetup hook
```js
var beforeSetup = function(videoEl, options) {
// videoEl.id will be some-id here, since that is what video.js
// videoEl.id will be some-id here, since that is what Video.js
// was created with
videoEl.className += ' some-super-class';
@@ -58,16 +58,16 @@ videojs('some-id', {autoplay: true, controls: true});
`setup` is called just after the player is created. This allows:
* plugin or custom functionalify to intialize on the player
* plugin or custom functionality to intialize on the player
* changes to the player object itself
`setup` hook functions:
* Take one argument
* player: the player that video.js created
* player: the player that Video.js created
* Don't have to return anything
Example: adding setup hook
Example: adding a setup hook
```js
var setup = function(player) {
@@ -76,7 +76,7 @@ Example: adding setup hook
};
var foo = function() {};
videojs.plugin('foo', foo);
videojs.registerPlugin('foo', foo);
videojs.hook('setup', setup);
var player = videojs('some-id', {autoplay: true, controls: true});
```
@@ -85,7 +85,7 @@ Example: adding setup hook
### Adding
In order to use hooks you must first include video.js in the page or script that you are using. Then you add hooks using `videojs.hook(<name>, function)` before running the `videojs()` function.
In order to use hooks you must first include Video.js in the page or script that you are using. Then you add hooks using `videojs.hook(<name>, function)` before running the `videojs()` function.
Example: adding hooks
@@ -102,13 +102,13 @@ videojs.hook('setup', function(player) {
var player = videojs('vid1', {autoplay: false});
```
After adding your hooks they will automatically be run at the correct time in the video.js lifecycle.
After adding your hooks they will automatically be run at the correct time in the Video.js lifecycle.
### Getting
To access the array of hooks that currently exists and will be run on the video.js object you can use the `videojs.hooks` function.
To access the array of hooks that currently exists and will be run on the Video.js object you can use the `videojs.hooks` function.
Example: getting all hooks attached to video.js
Example: getting all hooks attached to Video.js
```js
var beforeSetupHooks = videojs.hooks('beforesetup');
@@ -117,7 +117,7 @@ var setupHooks = videojs.hooks('setup');
### Removing
To stop hooks from being executed during the video.js lifecycle you will remove them using `videojs.removeHook`.
To stop hooks from being executed during the Video.js lifecycle you will remove them using `videojs.removeHook`.
Example: remove a hook that was defined by you
+27 -25
Ver Arquivo
@@ -1,8 +1,9 @@
# Languages
Multiple language support allows for users of non-English locales to natively interact with the Video.js player.
Video.js includes localization support to present text in a language other than the default English where appropriate.
For an up-to-date list of the languages Video.js supports, see the [languages folder (`lang`)][lang-supported]. These JSON files are converted to JavaScript during the Video.js build process.
For an up-to-date list of the languages Video.js supports, see the [languages folder (`lang`)][lang-supported].
Some translations may be less complete than others - see the [translations needed doc][translations-needed] for a table of strings that are missing from the translations available. Contributions are welcome to update those that are incomplete.
## Table of Contents
@@ -22,7 +23,9 @@ For an up-to-date list of the languages Video.js supports, see the [languages fo
## Using Video.js Languages
Video.js ships with multiple translations (in `dist/lang/`) in JavaScript files. Each of these files can be included in a web page to provide support for that language in _all_ Video.js players:
Video.js ships with multiple translations (in `dist/lang/`) in JavaScript files.
Add the lang script for each language you need to support.
Each of these files can be included in a web page to provide support for that language in _all_ Video.js players:
```html
<script src="//example.com/path/to/video.min.js"></script>
@@ -31,7 +34,7 @@ Video.js ships with multiple translations (in `dist/lang/`) in JavaScript files.
## Contributing to Video.js Translations
We welcome new translations and improvements to existing ones! Please see the [contributing document](../../CONTRIBUTING.md) to get started contributing to Video.js and continue reading for specifics on how to contribute to translations of Video.js...
We welcome new translations and improvements to existing ones! Please see the [contributing document](../../CONTRIBUTING.md) to get started contributing to Video.js and continue reading for specifics on how to contribute to translations of Video.js.
### JSON Format
@@ -50,11 +53,9 @@ Video.js uses a JSON object to describe a language, where the keys are English a
### File Naming
Translations are always found in the `lang/` directory.
Translations are found in the `lang/` directory.
Each file's name should be the [standard language code][lang-codes] that is most appropriate. For example, "es" for Spanish or "zh-CN" for Chinese.
Finally, each file's extension is always `.json`.
Each file's name should be the [standard language code][lang-codes] that is most appropriate, with a `.json` extension. For example, "es.json" for Spanish or "zh-CN.json" for simplified Chinese.
### Updating an Existing Translation
@@ -80,20 +81,14 @@ cp lang/en.json lang/${NEW_LANG_CODE}.json
Otherwise, the process is the same as [updating an existing translation](#updating-an-existing-translation).
## Advanced Language Usage
The instructions above for [using Video.js languages](#using-videojs-languages) should be sufficient for the majority of use-cases. However, languages can be provided at runtime.
In each case, these custom language definitions _take precedence over any Video.js-provided languages!_
### Adding Languages via the API
In addition to the stand-alone scripts provided by Video.js, the API supports manual definition of new languages via the `addLanguage` method. It takes two arguments: the [standard language code][lang-codes] and a [language definition object](#json-format).
```js
videojs.addLanguage('es', {
'Play': 'Reproducción',
'Pause': 'Pausa',
Play: 'Reproducción',
Pause: 'Pausa',
'Current Time': 'Tiempo reproducido',
'Duration Time': 'Duración total',
'Remaining Time': 'Tiempo restante',
@@ -101,7 +96,9 @@ videojs.addLanguage('es', {
});
```
### Per-Player Languages
`addLanguage()` will overwrite existing translations if the object includes strings previously translated. However text that has already been localised will not be updated after generation.
### Per-Player Translations
In addition to providing languages to Video.js itself, individual `Player` instances can be provided custom language support via [the `languages` option](/docs/guides/options.md#languages):
@@ -109,31 +106,34 @@ In addition to providing languages to Video.js itself, individual `Player` insta
// Provide a custom definition of Spanish to this player.
videojs('my-player', {
languages: {
es: {...}
es: {
Play: 'Reproducir'
}
}
});
```
### Setting Default Player Language
### Setting Player Language
Player instances can also have a default language via [the `language` option](/docs/guides/options.md#language):
The language used by a player instance may be set via [the `language` option](/docs/guides/options.md#language):
```js
// Set the default language to Spanish for this player.
// Set the language to Spanish for this player.
videojs('my-player', {
language: 'es'
});
```
Additionally, the `language` method of the player can be used to set the language after instantiation (e.g., `language('es')`). However, this is not recommended as it does not update the UI in place. _Setting the language via options is always preferred._
The `language` method of the player _can_ be used to set the language after instantiation with `language('es')`. However, this is generally not useful as it does not update text that is already in place.
### Determining Player Language
The player language is set to one of the following in descending priority:
* The language [specified in options](#setting-default-player-language)
* The language specified by the closest element with a `lang` attribute. This could be the player itself or a parent element. Usually, the document language is specified on the `<html>` tag.
* Browser language preference; the first language if more than one is configured
* The language specified by a `lang` attribute on the player element.
* The language specified by the closest parent element with a `lang` attribute, up to and including the `<html>` element.
* The browser language preference; the first language if more than one is configured
* English
#### Internal Language Selection
@@ -147,10 +147,12 @@ For information on translation/localization in plugins, see [the plugins guide](
Standard languages codes [are defined by the IANA][lang-codes].
For all existing/supported languages, please see the [languages lolder (`lang/`)][lang-supported] folder located in the project root.
For all existing/supported languages, please see the [languages folder (`lang/`)][lang-supported] folder located in the project root.
[lang-en]: /lang/en.json
[lang-supported]: /lang
[lang-codes]: http://www.iana.org/assignments/language-subtag-registry/language-subtag-registry
[translations-needed]: https://github.com/videojs/video.js/blob/master/docs/translations-needed.md
+49 -48
Ver Arquivo
@@ -26,6 +26,7 @@
* [languages](#languages)
* [nativeControlsForTouch](#nativecontrolsfortouch)
* [notSupportedMessage](#notsupportedmessage)
* [playbackRates](#playbackrates)
* [plugins](#plugins)
* [sourceOrder](#sourceorder)
* [sources](#sources)
@@ -36,8 +37,13 @@
* [${componentName}](#componentname)
* [Tech Options](#tech-options)
* [${techName}](#techname)
* [flash](#flash)
* [swf](#swf)
* [html5](#html5)
* [nativeControlsForTouch](#nativecontrolsfortouch-1)
* [nativeAudioTracks](#nativeaudiotracks)
* [nativeTextTracks](#nativetexttracks)
* [nativeVideoTracks](#nativevideotracks)
## Standard `<video>` Element Options
@@ -175,6 +181,24 @@ Explicitly set a default value for [the associated tech option](#nativecontrolsf
Allows overriding the default message that is displayed when Video.js cannot play back a media source.
### `playbackRates`
> Type: `Array`
An array of numbers strictly greater than 0, where 1 means regular speed
(100%), 0.5 means half-speed (50%), 2 means double-speed (200%), etc.
If specified, Video.js displays a control (of class `vjs-playback-rate`)
allowing the user to choose playback speed from among the array of choices.
The choices are presented in the specified order from bottom to top.
For example:
```js
videojs('my-player', {
playbackRates: [0.5, 1, 1.5, 2]
});
```
### `plugins`
> Type: `Object`
@@ -203,49 +227,6 @@ Although, since the `plugins` option is an object, the order of initialization i
See [the plugins guide][plugins] for more information on Video.js plugins.
### `sourceOrder`
> Type: `boolean`, Default: `false`
>
> **Note:** In video.js 6.0, this option will default to `true`. and that [videojs-flash](https://github.com/videojs/videojs-flash) will be required to use the flash tech.
Tells Video.js to prefer the order of [`sources`](#sources) over [`techOrder`](#techorder) in selecting a source and playback tech.
Given the following example:
```js
videojs('my-player', {
sourceOrder: true,
sources: [{
src: '//path/to/video.flv',
type: 'video/x-flv'
}, {
src: '//path/to/video.mp4',
type: 'video/mp4'
}, {
src: '//path/to/video.webm',
type: 'video/webm'
}],
techOrder: ['html5', 'flash']
});
```
Normally, the fact that HTML5 comes before Flash in the `techOrder` would mean Video.js would look for a compatible _source_ for HTML5 and would pick either the MP4 or WebM video (depending on browser support) only falling back to Flash if no compatible source for HTML5 was found.
However, because the `sourceOrder` is `true`, Video.js flips that process around. It will look for a compatible _tech_ for each source in order. Presumably, it would first find a match between the FLV (since it's first in the source order) and the Flash tech.
In summary, the default algorithm is:
* for each tech:
* for each source:
* if tech can play source, use this tech/source combo
With `sourceOrder: true`, the algorithm becomes:
* for each source:
* for each tech:
* if tech can play source, use this tech/source combo
### `sources`
> Type: `Array`
@@ -285,7 +266,7 @@ Defines the order in which Video.js techs are preferred. By default, this means
Allows overriding the default URL to vtt.js, which may be loaded asynchronously to polyfill support for `WebVTT`.
This option will be used in the "novtt" build of video.js (i.e. `video.novtt.js`). Otherwise, vtt.js is bundled with video.js.
This option will be used in the "novtt" build of Video.js (i.e. `video.novtt.js`). Otherwise, vtt.js is bundled with Video.js.
## Component Options
@@ -318,7 +299,7 @@ The `children` options can also be passed as an `Object`. In this case, it is us
videojs('my-player', {
children: {
controlBar: {
fullscreenControl: false
fullscreenToggle: false
}
}
});
@@ -333,7 +314,7 @@ Components can be given custom options via the _lower-camel-case variant of the
```js
videojs('my-player', {
controlBar: {
fullscreenControl: false
fullscreenToggle: false
}
});
```
@@ -346,7 +327,11 @@ videojs('my-player', {
Video.js playback technologies (i.e. "techs") can be given custom options as part of the options passed to the `videojs` function. They should be passed under the _lower-case variant of the tech name_ (e.g. `"flash"` or `"html5"`).
This is not used in most implementations, but one case where it may be is dictating where the Video.js SWF file is located for the `Flash` tech:
### `flash`
#### `swf`
Specifies where the Video.js SWF file is located for the `Flash` tech:
```js
videojs('my-player', {
@@ -356,24 +341,38 @@ videojs('my-player', {
});
```
However, this is a case where changing the global defaults is more useful:
However, changing the global defaults is generally more appropriate:
```js
videojs.options.flash.swf = '//path/to/videojs.swf'
```
### `html5`
#### `nativeControlsForTouch`
> Type: `boolean`
Only supported by the `Html5` tech, this option can be set to `true` to force native controls for touch devices.
#### `nativeAudioTracks`
> Type: `boolean`
Can be set to `false` to disable native audio track support. Most commonly used with [videojs-contrib-hls][videojs-contrib-hls].
#### `nativeTextTracks`
> Type: `boolean`
Can be set to `false` to force emulation of text tracks instead of native support. The `nativeCaptions` option also exists, but is simply an alias to `nativeTextTracks`.
#### `nativeVideoTracks`
> Type: `boolean`
Can be set to `false` to disable native video track support. Most commonly used with [videojs-contrib-hls][videojs-contrib-hls].
[plugins]: /docs/guides/plugins.md
[languages]: /docs/guides/languages.md
@@ -383,3 +382,5 @@ Can be set to `false` to force emulation of text tracks instead of native suppor
[lang-codes]: http://www.iana.org/assignments/language-subtag-registry/language-subtag-registry
[video-attrs]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video#Attributes
[videojs-contrib-hls]: https://github.com/videojs/videojs-contrib-hls
+16 -17
Ver Arquivo
@@ -99,7 +99,7 @@ Example
```js
var myPlayer = videojs('some-player-id');
myPlayer.src("http://www.example.com/path/to/video.mp4");
myPlayer.src('http://www.example.com/path/to/video.mp4');
myPlayer.ready(function() {
// get
var howLoudIsIt = myPlayer.volume();
@@ -113,7 +113,7 @@ Volume can also be muted (without actually changing the volume value) using the
```js
var myPlayer = videojs('some-player-id');
myPlayer.src("http://www.example.com/path/to/video.mp4");
myPlayer.src('http://www.example.com/path/to/video.mp4');
myPlayer.ready(function() {
// get, should be false
console.log(myPlayer.muted());
@@ -131,7 +131,7 @@ To check if the player is currently fullscreen call the `isFullscreen` function
```js
var myPlayer = videojs('some-player-id');
myPlayer.src("http://www.example.com/path/to/video.mp4");
myPlayer.src('http://www.example.com/path/to/video.mp4');
myPlayer.ready(function() {
// get, should be false
console.log(myPlayer.isFullscreen());
@@ -149,7 +149,7 @@ To request that the player enter fullscreen call `requestFullscreen`.
```js
var myPlayer = videojs('some-player-id');
myPlayer.src("http://www.example.com/path/to/video.mp4");
myPlayer.src('http://www.example.com/path/to/video.mp4');
myPlayer.ready(function() {
myPlayer.requestFullscreen();
});
@@ -160,7 +160,7 @@ To exit fullscreen call `exitFullscreen`
```js
var myPlayer = videojs('some-player-id');
myPlayer.src("http://www.example.com/path/to/video.mp4");
myPlayer.src('http://www.example.com/path/to/video.mp4');
myPlayer.ready(function() {
myPlayer.requestFullscreen();
myPlayer.exitFullscreen();
@@ -174,7 +174,7 @@ myPlayer.ready(function() {
```js
var myPlayer = videojs('some-player-id');
myPlayer.src("http://www.example.com/path/to/video.mp4");
myPlayer.src('http://www.example.com/path/to/video.mp4');
myPlayer.ready(function() {
myPlayer.play();
});
@@ -185,7 +185,7 @@ myPlayer.ready(function() {
```js
var myPlayer = videojs('some-player-id');
myPlayer.src("http://www.example.com/path/to/video.mp4");
myPlayer.src('http://www.example.com/path/to/video.mp4');
myPlayer.ready(function() {
myPlayer.play();
myPlayer.pause();
@@ -197,7 +197,7 @@ myPlayer.ready(function() {
```js
var myPlayer = videojs('some-player-id');
myPlayer.src("http://www.example.com/path/to/video.mp4");
myPlayer.src('http://www.example.com/path/to/video.mp4');
myPlayer.ready(function() {
// true
@@ -224,7 +224,7 @@ myPlayer.ready(function() {
```js
var myPlayer = videojs('some-player-id');
myPlayer.src("http://www.example.com/path/to/video.mp4");
myPlayer.src('http://www.example.com/path/to/video.mp4');
myPlayer.ready(function() {
// set current time to 2 minutes into the video
myPlayer.currentTime(120);
@@ -239,7 +239,7 @@ myPlayer.ready(function() {
```js
var myPlayer = videojs('some-player-id');
myPlayer.src("http://www.example.com/path/to/video.mp4");
myPlayer.src('http://www.example.com/path/to/video.mp4');
myPlayer.ready(function() {
var lengthOfVideo = myPlayer.duration();
});
@@ -249,7 +249,7 @@ myPlayer.ready(function() {
```js
var myPlayer = videojs('some-player-id');
myPlayer.src("http://www.example.com/path/to/video.mp4");
myPlayer.src('http://www.example.com/path/to/video.mp4');
myPlayer.ready(function() {
myPlayer.currentTime(10);
@@ -263,7 +263,7 @@ myPlayer.ready(function() {
```js
var myPlayer = videojs('some-player-id');
myPlayer.src("http://www.example.com/path/to/video.mp4");
myPlayer.src('http://www.example.com/path/to/video.mp4');
myPlayer.ready(function() {
var bufferedTimeRange = myPlayer.buffered();
@@ -288,7 +288,7 @@ myPlayer.ready(function() {
```js
var myPlayer = videojs('some-player-id');
myPlayer.src("http://www.example.com/path/to/video.mp4");
myPlayer.src('http://www.example.com/path/to/video.mp4');
myPlayer.ready(function() {
// example 0.11 aka 11%
var howMuchIsDownloaded = myPlayer.bufferedPercent();
@@ -302,7 +302,7 @@ Passing a source to the player via the API. (this can also be done using options
```js
var myPlayer = videojs('some-player-id');
myPlayer.src("http://www.example.com/path/to/video.mp4");
myPlayer.src('http://www.example.com/path/to/video.mp4');
```
**Source Object (or element):** A javascript object containing information
@@ -351,10 +351,9 @@ function on the player.
```js
var myPlayer = videojs('some-player-id');
myPlayer.src("http://www.example.com/path/to/video.mp4");
myPlayer.src('http://www.example.com/path/to/video.mp4');
myPlayer.ready(function() {
// function call throws an error if we
// dont add {IWillNotUseThisInPlugins: true}
// tech() will error with no argument
var tech = myPlayer.tech({IWillNotUseThisInPlugins: true});
});
```
+22 -11
Ver Arquivo
@@ -10,14 +10,6 @@ Because we view plugins as such an important part of Video.js, the organization
In short, the generator sets up plugin authors to focus on writing their plugin - not messing with tools.
* [videojs-spellbook][spellbook]
As of version 3, the plugin generator includes a new dependency: [videojs-spellbook][spellbook]. Spellbook is a kitchen sink plugin development tool: it builds plugins, creates tags, runs a development server, and more.
The benefit of Spellbook is that you can run the generator _once_ and receive updates and bugfixes in Spellbook without having to run the generator again and deal with Yeoman conflicts and other headaches.
As long as your plugin project follows the [conventions][standards], Spellbook should work on it!
## Writing a Basic Plugin
If you've written a Video.js plugin before, the basic plugin concept should be familiar. It's similar to a jQuery plugin in that the core idea is that you're adding a method to the player.
@@ -57,7 +49,7 @@ After that, any player will automatically have an `examplePlugin` method on its
## Writing an Advanced Plugin
Video.js 6 introduces advanced plugins: these are plugins that share a similar API with basic plugins, but are class-based and offer a range of extra features out of the box.
Video.js 6 introduced advanced plugins: these are plugins that share a similar API with basic plugins, but are class-based and offer a range of extra features out of the box.
While reading the following sections, you may want to refer to the [Plugin API docs][api-plugin] for more detail.
@@ -109,7 +101,7 @@ var ExamplePlugin = videojs.extend(Plugin, {
For now, this example advanced plugin does the exact same thing as the basic plugin described above - not to worry, we will make it more interesting as we continue!
### Register a Advanced Plugin
### Register an Advanced Plugin
The registration process for advanced plugins is identical to [the process for basic plugins](#register-a-basic-plugin).
@@ -233,6 +225,25 @@ The `dispose` method has several effects:
In addition, if the player is disposed, the disposal of all its advanced plugin instances will be triggered as well.
#### Version
Adding a version number to a plugin is done by defining a `VERSION` property on the plugin before registering it:
```js
ExamplePlugin.VERSION = '1.0.1';
videojs.registerPlugin('examplePlugin', ExamplePlugin);
```
Retrieve it using `videojs.getPluginVersion`:
```js
var version = videojs.getPluginVersion('examplePlugin');
console.log(version); // 1.0.1
```
Note that the [plugin generator](https://github.com/videojs/generator-videojs-plugin) already takes care of adding a version number for you.
### Advanced Example Advanced Plugin
What follows is a complete ES6 advanced plugin that logs a custom message when the player's state changes between playing and paused. It uses all the described advanced features:
@@ -259,7 +270,7 @@ class Advanced extends Plugin {
}
updateState() {
this.setState({playing: !player.paused()});
this.setState({playing: !this.player.paused()});
}
logState(changed) {
+5 -5
Ver Arquivo
@@ -1,8 +1,8 @@
# video.js and ReactJS integration
# Video.js and ReactJS integration
Here's a basic ReactJS player implementation.
It just instantiates the video.js player on `componentDidMount` and destroys it on `componentWillUnmount`.
It just instantiates the Video.js player on `componentDidMount` and destroys it on `componentWillUnmount`.
```jsx
import React from 'react';
@@ -10,7 +10,7 @@ import videojs from 'video.js'
export default class VideoPlayer extends React.Component {
componentDidMount() {
// instantiate video.js
// instantiate Video.js
this.player = videojs(this.videoNode, this.props, function onPlayerReady() {
console.log('onPlayerReady', this)
});
@@ -51,7 +51,7 @@ const videoJsOptions = {
return <VideoPlayer { ...videoJsOptions } />
```
Dont forget to include the video.js CSS, located at `video.js/dist/video-js.css`.
Don't forget to include the Video.js CSS, located at `video.js/dist/video-js.css`.
[options]: /docs/guides/options.md
@@ -132,7 +132,7 @@ export default vjsEpisodeList;
// ...
componentDidMount() {
// instantiate video.js
// instantiate Video.js
this.player = videojs(this.videoNode, this.props, function onPlayerReady() {
console.log('onPlayerReady', this)
});
+7 -1
Ver Arquivo
@@ -96,6 +96,8 @@ Alternatively, you can use the `data-setup` attribute to pass options as [JSON][
<video data-setup='{"controls": true, "autoplay": false, "preload": "auto"}'...>
```
> **Note:** You _must_ use single-quotes around the value of `data-setup` as it contains a JSON string which must use double quotes.
Finally, if you're not using the `data-setup` attribute to trigger the player setup, you can pass in an object of player options as the second argument to the `videojs` function:
```js
@@ -106,6 +108,8 @@ videojs('my-player', {
});
```
> **Note:** Do not use both `data-setup` and an options object.
### Global Defaults
Default options for all players can be found at `videojs.options` and can be changed directly. For example, to set `{autoplay: true}` for all future players:
@@ -171,7 +175,9 @@ player.on('ready', function() {
});
```
In each case, the callback is called asynchronously - _even if the player is already ready!_
In each case, the callback is called asynchronously.
An important distinction between the above methods is that adding an listener for `ready` with `on()` _must_ be done before the player is ready. With `player.ready()`, the function is called immediately if the player is already ready.
## Advanced Player Workflows
+47 -24
Ver Arquivo
@@ -1,12 +1,14 @@
# Playback Technology ("Tech")
Playback Technology refers to the specific browser or plugin technology used to play the video or audio. When using HTML5, the playback technology is the video or audio element. When using Flash, the playback technology is the specific Flash player used, e.g. Flowplayer, YouTube Player, video-js.swf, etc. (not just "Flash"). This could also include Silverlight, Quicktime, or any other plugin that will play back video in the browser, as long as there is an API wrapper written for it.
Playback Technology refers to the specific browser or plugin technology used to play the video or audio. When using HTML5, the playback technology is the video or audio element. When using Flash from [videojs-flash][flash], the playback technology is the video-js.swf Flash object. When using the [videojs-youtube][youtube] tech, the playback technology is the You Tube player. The tech also includes an API wrapper to translate between the Video.js controls and API to the specific playback technology used.
Essentially we're using HTML5 and plugins only as video decoders, and using HTML and JavaScript to create a consistent API and skinning experience across all of them.
Essentially we're using html5 and plugins only as video decoders, and using HTML and JavaScript to create a consistent API and skinning experience across all of them.
In addition to techs there are source handlers. Source handlers add the capability to play additional source types to techs. For example, the [videojs-contrib-hls][hls] source handler enables the HTML5 and Flash techs to play HLS.
## Building an API Wrapper
We'll write a more complete guide on writing a wrapper soon, but for now the best resource is the [Video.js](https://github.com/zencoder/video-js/tree/master/src) source where you can see how both the HTML5 and video-js.swf API wrappers were created.
We'll write a more complete guide on writing a wrapper soon, but for now the best resource is the [Video.js](https://github.com/videojs/video.js/tree/master/src/js/tech) source where you can see how the HTML5 API wrapper is created.
## Required Methods
@@ -39,7 +41,7 @@ exitFullScreen
## Adding Playback Technology
When adding additional Tech to a video player, make sure to add the supported tech to the video object.
When additional techs are added they are automatically added to the `techOrder`. You can modify the `techOrder` to change the priority of each tech.
### Tag Method:
@@ -57,47 +59,58 @@ videojs("videoID", {
## Technology Ordering
By default Video.js performs "Tech-first" ordering when it searches for a source/tech combination to play videos. This means that if you have two sources and two techs, video.js will try to play each video with the first tech in the `techOrder` option property before moving on to try the next playback technology.
When Video.js is given an array of sources, which to use is determined by finding the first supported source / tech combination. Each tech will be queried in the order specified in `techOrder` whether it can play the first source. The first match wins. If no tech can play the first source, then the next will be tested. It's important to set the `type` of each source correctly for this test to be accurate.
Tech-first ordering can present a problem if you have a `sourceHandler` that supports both `Html5` and `Flash` techs such as videojs-contrib-hls.
For example, given the following video element:
For example, given the following video element, assuming the [videojs-flash][flash] tech and [videojs-contrib-hls][hls] source handler are available:
```html
<video data-setup='{"techOrder": ["html5", "flash"]}'>
<!-- "techOrder": ["html5", "flash"] -->
<video
<source src="http://your.static.provider.net/path/to/video.m3u8" type="application/x-mpegURL">
<source src="http://your.static.provider.net/path/to/video.mp4" type="video/mp4">
</video>
```
There is a good chance that the mp4 source will be selected on platforms that do not have media source extensions. Video.js will try all sources against the first playback technology, in this case `Html5`, and select the first source that can play - in this case MP4.
The HLS source will be tested first. The first tech is html5.
* Safari can play HLS in a standard HTML5 video element, so HLS will be played using the html5 tech
* Chrome can't play HLS in the standard HTML5 video element on its own, but the videojs-contrib-hls source handler _can_ play HLS via [Media Source Extensions][mse] in HTML5. So HLS will be played in the html5 tech
* IE 10 can't play HLS natively, and doesn't support Media Source Extensions. As the source cannot be played in HTML5, the Flash tech can be tested. The videojs-contrib-hls source handler can play HLS in the Flash tech, so HLS will be played in the Flash tech.
In "Tech-first" mode, the tests run something like this:
Can video.m3u8 play with Html5? No...
Can video.mp4 play with Html5? Yes! Use the second source.
Video.js now provides another method of selecting the source - "Source-first" ordering. In this mode, Video.js tries the first source against every tech in `techOrder` before moving onto the next source.
With a player setup as follows:
Now take the same sources again with videojs-contrib-hls but without videojs-flash:
```html
<video data-setup='{"techOrder": ["html5", "flash"], "sourceOrder": true}'>
<!-- "techOrder": ["html5"] -->
<video
<source src="http://your.static.provider.net/path/to/video.m3u8" type="application/x-mpegURL">
<source src="http://your.static.provider.net/path/to/video.mp4" type="video/mp4">
</video>
```
The Flash-based HLS support will be tried before falling back to the MP4 source.
* Safari will play HLS in the html5 tech
* Chrome will play HLS in the html5 tech by means of videojs-contrib-hls
* IE 10 can't play HLS in either the html5 or Flash tech. Next the MP4 source will be tested. MP4 can be played by HTML5, so that source-tech pair will be used.
In "Source-first" mode, the tests run something like this:
Can video.m3u8 play with Html5? No...
Can video.m3u8 play with Flash? Yes! Use the first source.
This time, we have videojs-flash but not videojs-contrib-hls:
```html
<!-- "techOrder": ["html5", "flash"] -->
<video
<source src="http://your.static.provider.net/path/to/video.m3u8" type="application/x-mpegURL">
<source src="http://your.static.provider.net/path/to/video.mp4" type="video/mp4">
</video>
```
* Safari will play HLS in the html5 tech
* Chrome can't play HLS in the html5 or flash tech, so will play MP4 in the html5 tech.
* IE 10 also can't play HLS in either the html5 or Flash tech and will also play MP4 in the html5 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.
The Flash playback tech was previously included in Video.js core and was included in the default `techOrder`. As of version 6, the Flash tech was moved to a separate [videojs-flash plugin][flash] which you would need to include if you still need to use Flash.
### Enabling Streaming Playback
It's increasingly likely that end users don't have Flash or their browser has either disabled it or puts a click-to-play or other barrier to using it, so it's strongly recommended to use an alternative such as HLS.
### Enabling RTMP 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:
@@ -118,3 +131,13 @@ All four RTMP protocols are valid in the `src` (RTMP, RTMPT, RTMPE, and RTMPS).
#### A note on sandboxing and security
In some environments, such as Electron and NW.js apps, stricter policies are enforced, and `.swf` files wont be able to communicate with the outside world out of the box. To stream media, you have to add them to a special manifest of trusted files. [nw-flash-trust](https://github.com/szwacz/nw-flash-trust) makes this job easy.
Browsers also prevent the Flash tech from working when you load a page from the filesystem (with the `file:` protocol) and also in sandboxed iframes.
[flash]: https://github.com/videojs/videojs-flash
[hls]: https://github.com/videojs/videojs-contrib-hls
[mse]: https://en.wikipedia.org/wiki/Media_Source_Extensions
[youtube]: https://github.com/videojs/videojs-youtube
+3 -3
Ver Arquivo
@@ -11,7 +11,7 @@
* [extend()](#extend)
* [mergeOptions()](#mergeoptions)
* [bind()](#bind)
* [plugin()](#plugin)
* [registerPlugin()](#plugin)
* [xhr()](#xhr)
## `videojs()`
@@ -126,13 +126,13 @@ videojs.bind(someObj, function() {
});
```
## `plugin()`
## `registerPlugin()`
**See the [plugin guide](/docs/guides/plugins.md) in the docs for a more detailed example**
```js
// Make a plugin that alerts when the player plays
videojs.plugin('myPlugin', function(myPluginOptions) {
videojs.registerPlugin('myPlugin', function(myPluginOptions) {
myPluginOptions = myPluginOptions || {};
var player = this;
+1 -1
Ver Arquivo
@@ -1,6 +1,6 @@
# Using Webpack with Video.js
video.js, and the playback technologies such as videojs-contrib-hls all work in a Webpack based build environment. Here are several configuration changes specific to Webpack that will get you up and running.
Video.js, and the playback technologies such as videojs-contrib-hls all work in a Webpack based build environment. Here are several configuration changes specific to Webpack that will get you up and running.
## Video.js CSS:
To add the CSS that the player requires, simply add
+3 -3
Ver Arquivo
@@ -28,11 +28,11 @@ Guides explain general topics and use cases (e.g. setup). API docs are automatic
### [FAQ](/docs/guides/faq.md)
The frequently asked questions for video.js.
The frequently asked questions for Video.js.
### [Troubleshooting](/docs/guides/troubleshooting.md)
Troubleshooting help for video.js.
Troubleshooting help for Video.js.
## [Guides](/docs/guides/)
@@ -58,7 +58,7 @@ Tracks are used for displaying text information over a video, selecting differen
#### [Skins](/docs/guides/skins.md)
You can change the look of the player across playback technologies just by editing a CSS file. The skins documentation gives you a intro to how the HTML and CSS of the default skin is put together. For a list of skins you can check the [video.js wiki][skins-list].
You can change the look of the player across playback technologies just by editing a CSS file. The skins documentation gives you a intro to how the HTML and CSS of the default skin is put together. For a list of skins you can check the [Video.js wiki][skins-list].
#### [Plugins](/docs/guides/plugins.md)
+31 -38
Ver Arquivo
@@ -60,7 +60,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -118,7 +118,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -176,7 +176,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -234,7 +234,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -292,7 +292,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -350,19 +350,12 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
| | End of dialog window. |
| de.json (missing 8) | Audio Player |
| | Video Player |
| | Progress Bar |
| | progress bar timing: currentTime={1} duration={2} |
| | Volume Level |
| | Reset |
| | all settings to the default values |
| | End of dialog window. |
| de.json (Complete) | |
| el.json (missing 44) | Audio Player |
| | Video Player |
| | Replay |
@@ -402,7 +395,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -459,7 +452,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -517,7 +510,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -575,7 +568,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -633,7 +626,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -691,7 +684,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -749,7 +742,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -807,7 +800,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -865,7 +858,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -923,7 +916,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -981,7 +974,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -1028,7 +1021,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -1086,7 +1079,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -1137,7 +1130,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -1195,7 +1188,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -1238,7 +1231,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -1282,7 +1275,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -1341,7 +1334,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -1399,7 +1392,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -1410,7 +1403,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | progress bar timing: currentTime={1} duration={2} |
| | Volume Level |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | End of dialog window. |
| uk.json (missing 44) | Audio Player |
| | Video Player |
@@ -1451,7 +1444,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -1494,7 +1487,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -1538,7 +1531,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
@@ -1582,7 +1575,7 @@ This default value is hardcoded as a default to the localize method in the SeekB
| | Script |
| | Small Caps |
| | Reset |
| | all settings to the default values |
| | restore all settings to the default values |
| | Done |
| | Caption Settings Dialog |
| | Beginning of dialog window. Escape will cancel and close the window. |
+7 -7
Ver Arquivo
@@ -1,27 +1,27 @@
{
"Play": "تشغيل",
"Pause": "ايقاف",
"Pause": "إيقاف",
"Current Time": "الوقت الحالي",
"Duration Time": "Dauer",
"Duration Time": "مدة",
"Remaining Time": "الوقت المتبقي",
"Stream Type": "نوع التيار",
"LIVE": "مباشر",
"Loaded": "تم التحميل",
"Progress": "التقدم",
"Fullscreen": "ملء الشاشة",
"Non-Fullscreen": "غير ملء الشاشة",
"Non-Fullscreen": "تعطيل ملء الشاشة",
"Mute": "صامت",
"Unmute": "غير الصامت",
"Playback Rate": "معدل التشغيل",
"Subtitles": "الترجمة",
"subtitles off": "ايقاف الترجمة",
"subtitles off": "إيقاف الترجمة",
"Captions": "التعليقات",
"captions off": "ايقاف التعليقات",
"captions off": "إيقاف التعليقات",
"Chapters": "فصول",
"You aborted the media playback": "لقد ألغيت تشغيل الفيديو",
"A network error caused the media download to fail part-way.": "تسبب خطأ في الشبكة بفشل تحميل الفيديو بالكامل.",
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "لا يمكن تحميل الفيديو بسبب فشل في الخادم أو الشبكة ، أو فشل بسبب عدم امكانية قراءة تنسيق الفيديو.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "تم ايقاف تشغيل الفيديو بسبب مشكلة فساد أو لأن الفيديو المستخدم يستخدم ميزات غير مدعومة من متصفحك.",
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "لا يمكن تحميل الفيديو بسبب فشل في الخادوم أو الشبكة ، أو فشل بسبب عدم إمكانية قراءة تنسيق الفيديو.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "تم إيقاف تشغيل الفيديو بسبب مشكلة فساد أو لأن الفيديو المستخدم يستخدم ميزات غير مدعومة من متصفحك.",
"No compatible source was found for this media.": "فشل العثور على أي مصدر متوافق مع هذا الفيديو.",
"Play Video": "تشغيل الفيديو",
"Close": "أغلق",
+9 -1
Ver Arquivo
@@ -70,7 +70,15 @@
"Casual": "Zwanglos",
"Script": "Schreibeschrift",
"Small Caps": "Small-Caps",
"Reset": "Zurücksetzen",
"restore all settings to the default values": "Alle Einstellungen auf die Standardwerte zurücksetzen",
"Done": "Fertig",
"Caption Settings Dialog": "Einstellungsdialog für Untertitel",
"Beginning of dialog window. Escape will cancel and close the window.": "Anfang des Dialogfensters. Esc bricht ab und schließt das Fenster."
"Beginning of dialog window. Escape will cancel and close the window.": "Anfang des Dialogfensters. Esc bricht ab und schließt das Fenster.",
"End of dialog window.": "Ende des Dialogfensters.",
"Audio Player": "Audio-Player",
"Video Player": "Video-Player",
"Progress Bar": "Forschrittsbalken",
"progress bar timing: currentTime={1} duration={2}": "{1} von {2}",
"Volume Level": "Lautstärkestufe"
}
+1 -1
Ver Arquivo
@@ -76,7 +76,7 @@
"Script": "Script",
"Small Caps": "Small Caps",
"Reset": "Reset",
"all settings to the default values": "all settings to the default values",
"restore all settings to the default values": "restore all settings to the default values",
"Done": "Done",
"Caption Settings Dialog": "Caption Settings Dialog",
"Beginning of dialog window. Escape will cancel and close the window.": "Beginning of dialog window. Escape will cancel and close the window.",
+1 -1
Ver Arquivo
@@ -76,7 +76,7 @@
"Script": "Scripte",
"Small Caps": "Petites capitales",
"Reset": "Réinitialiser",
"all settings to the default values": "tous les paramètres aux valeurs par défaut",
"restore all settings to the default values": "Restaurer tous les paramètres aux valeurs par défaut",
"Done": "Terminé",
"Caption Settings Dialog": "Boîte de dialogue des paramètres des sous-titres transcrits",
"Beginning of dialog window. Escape will cancel and close the window.": "Début de la fenêtre de dialogue. La touche d'échappement annulera et fermera la fenêtre.",
+68 -21
Ver Arquivo
@@ -1,37 +1,84 @@
{
"Audio Player": "Audiospeler",
"Video Player": "Videospeler",
"Play": "Afspelen",
"Pause": "Pauze",
"Pause": "Pauzeren",
"Replay": "Opnieuw afspelen",
"Current Time": "Huidige tijd",
"Duration Time": "Looptijd",
"Duration Time": "Tijdsduur",
"Remaining Time": "Resterende tijd",
"Stream Type": "Streamtype",
"LIVE": "LIVE",
"Loaded": "Geladen",
"Progress": "Status",
"Progress": "Voortgang",
"Progress Bar": "Voortgangsbalk",
"progress bar timing: currentTime={1} duration={2}": "{1} van {2}",
"Fullscreen": "Volledig scherm",
"Non-Fullscreen": "Geen volledig scherm",
"Mute": "Geluid uit",
"Unmute": "Geluid aan",
"Playback Rate": "Weergavesnelheid",
"Mute": "Dempen",
"Unmute": "Niet dempen",
"Playback Rate": "Afspeelsnelheid",
"Subtitles": "Ondertiteling",
"subtitles off": "ondertiteling uit",
"Captions": "Bijschriften",
"captions off": "bijschriften uit",
"Chapters": "Hoofdstukken",
"Descriptions": "Beschrijvingen",
"descriptions off": "beschrijvingen off",
"You aborted the media playback": "U hebt de mediaweergave afgebroken.",
"A network error caused the media download to fail part-way.": "De mediadownload is mislukt door een netwerkfout.",
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "De media kon niet worden geladen, vanwege een server- of netwerkfout of doordat het formaat niet wordt ondersteund.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "De mediaweergave is afgebroken vanwege beschadigde data of het mediabestand gebruikt functies die niet door uw browser worden ondersteund.",
"No compatible source was found for this media.": "Voor deze media is geen ondersteunde bron gevonden.",
"Play Video": "Video Afspelen",
"descriptions off": "beschrijvingen uit",
"Audio Track": "Audiospoor",
"Volume Level": "Geluidsniveau",
"You aborted the media playback": "U heeft het afspelen van de media afgebroken",
"A network error caused the media download to fail part-way.": "Een netwerkfout heeft ervoor gezorgd dat het downloaden van de media halverwege is mislukt.",
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "De media kon niet worden geladen, dit komt doordat of de server of het netwerk mislukt of doordat het formaat niet wordt ondersteund.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Het afspelen van de media is afgebroken door een probleem met beschadeigde gegevens of doordat de media functies gebruikt die uw browser niet ondersteund.",
"No compatible source was found for this media.": "Er is geen geschikte bron voor deze media gevonden.",
"The media is encrypted and we do not have the keys to decrypt it.": "De media is versleuteld en we hebben de sleutels niet om deze te ontsleutelen.",
"Play Video": "Video afspelen",
"Close": "Sluiten",
"Modal Window": "Modal Venster",
"This is a modal window": "Dit is een modaal venster",
"This modal can be closed by pressing the Escape key or activating the close button.": "Dit modaal venster kan gesloten worden door op Escape te drukken of de 'sluiten' knop te activeren.",
", opens captions settings dialog": ", opent bijschriften instellingen venster",
", opens subtitles settings dialog": ", opent ondertiteling instellingen venster",
", opens descriptions settings dialog": ", opent beschrijvingen instellingen venster",
", selected": ", selected"
}
"Close Modal Dialog": "Extra venster sluiten",
"Modal Window": "Extra venster",
"This is a modal window": "Dit is een extra venster",
"This modal can be closed by pressing the Escape key or activating the close button.": "Dit venster kan worden gesloten door op de Escape-toets te drukken of door de sluiten-knop te activeren.",
", opens captions settings dialog": ", opent instellingen-venster voor bijschriften",
", opens subtitles settings dialog": ", opent instellingen-venster voor ondertitelingen",
", opens descriptions settings dialog": ", opent instellingen-venster voor beschrijvingen",
", selected": ", geselecteerd",
"captions settings": "bijschriften-instellingen",
"subtitles settings": "ondertiteling-instellingen",
"descriptions settings": "beschrijvingen-instellingen",
"Text": "Tekst",
"White": "Wit",
"Black": "Zwart",
"Red": "Rood",
"Green": "Groen",
"Blue": "Blauw",
"Yellow": "Geel",
"Magenta": "Magenta",
"Cyan": "Cyaan",
"Background": "Achtergrond",
"Window": "Venster",
"Transparent": "Transparant",
"Semi-Transparent": "Semi-transparant",
"Opaque": "Ondoorzichtig",
"Font Size": "Lettergrootte",
"Text Edge Style": "Stijl tekstrand",
"None": "Geen",
"Raised": "Verhoogd",
"Depressed": "Ingedrukt",
"Uniform": "Uniform",
"Dropshadow": "Schaduw",
"Font Family": "Lettertype",
"Proportional Sans-Serif": "Proportioneel sans-serif",
"Monospace Sans-Serif": "Monospace sans-serif",
"Proportional Serif": "Proportioneel serif",
"Monospace Serif": "Monospace serif",
"Casual": "Luchtig",
"Script": "Script",
"Small Caps": "Kleine hoofdletters",
"Reset": "Herstellen",
"restore all settings to the default values": "alle instellingen naar de standaardwaarden herstellen",
"Done": "Klaar",
"Caption Settings Dialog": "Venster voor bijschriften-instellingen",
"Beginning of dialog window. Escape will cancel and close the window.": "Begin van dialoogvenster. Escape zal annuleren en het venster sluiten.",
"End of dialog window.": "Einde van dialoogvenster."
}
+1 -1
Ver Arquivo
@@ -76,7 +76,7 @@
"Script": "Písané",
"Small Caps": "Malé kapitálky",
"Reset": "Resetovať",
"all settings to the default values": "všetky nastavenia na základné hodnoty",
"restore all settings to the default values": "všetky nastavenia na základné hodnoty",
"Done": "Hotovo",
"Caption Settings Dialog": "Okno nastavení popiskov",
"Beginning of dialog window. Escape will cancel and close the window.": "Začiatok okna. Klávesa Escape zruší a zavrie okno.",
+51 -8
Ver Arquivo
@@ -1,4 +1,6 @@
{
"Audio Player": "Trình phát Audio",
"Video Player": "Trình phát Video",
"Play": "Phát",
"Pause": "Tạm dừng",
"Replay": "Phát lại",
@@ -9,6 +11,8 @@
"LIVE": "TRỰC TIẾP",
"Loaded": "Đã tải",
"Progress": "Tiến trình",
"Progress Bar": "Thanh tiến trình",
"progress bar timing: currentTime={1} duration={2}": "{1} của {2}",
"Fullscreen": "Toàn màn hình",
"Non-Fullscreen": "Thoát toàn màn hình",
"Mute": "Tắt tiếng",
@@ -19,23 +23,62 @@
"Captions": "Chú thích",
"captions off": "tắt chú thích",
"Chapters": "Chương",
"Close Modal Dialog": "Đóng hộp thoại",
"Descriptions": "Mô tả",
"descriptions off": "tắt mô tả",
"Audio Track": "Track âm thanh",
"Volume Level": "Mức âm lượng",
"You aborted the media playback": "Bạn đã hủy việc phát lại media.",
"A network error caused the media download to fail part-way.": "Một lỗi mạng dẫn đến việc tải media bị lỗi.",
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Video không tải được, mạng hay server có lỗi hoặc định dạng không được hỗ trợ.",
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Phát media đã bị hủy do một sai lỗi hoặc media sử dụng những tính năng trình duyệt không hỗ trợ.",
"No compatible source was found for this media.": "Không có nguồn tương thích cho media này.",
"The media is encrypted and we do not have the keys to decrypt it.": "Media đã được mã hóa và chúng tôi không thể giải mã nó.",
"The media is encrypted and we do not have the keys to decrypt it.": "Media đã được mã hóa và chúng tôi không có để giải mã nó.",
"Play Video": "Phát Video",
"Close": "Đóng",
"Close Modal Dialog": "Đóng cửa sổ",
"Modal Window": "Cửa sổ",
"This is a modal window": "Đây là một cửa sổ",
"This modal can be closed by pressing the Escape key or activating the close button.": "Cửa sổ này có thể đóng lại bằng việc nhấn phím Esc hoặc kích hoạt nút đóng.",
", opens captions settings dialog": ", mở hộp thoại thiết lập chú thích",
", opens subtitles settings dialog": ", mở hộp thoại thiết lập phụ đề",
", opens descriptions settings dialog": ", mở hộp thoại thiết lập mô tả",
", selected": ", đã chọn"
}
"This modal can be closed by pressing the Escape key or activating the close button.": "Cửa sổ này có thể thoát bằng việc nhấn phím Esc hoặc kích hoạt nút đóng.",
", opens captions settings dialog": ", mở hộp thoại cài đặt chú thích",
", opens subtitles settings dialog": ", mở hộp thoại cài đặt phụ đề",
", opens descriptions settings dialog": ", mở hộp thoại cài đặt mô tả",
", selected": ", đã chọn",
"captions settings": "cài đặt chú thích",
"subtitles settings": "cài đặt phụ đề",
"descriptions settings": "cài đặt mô tả",
"Text": "Văn bản",
"White": "Trắng",
"Black": "Đen",
"Red": "Đỏ",
"Green": "Xanh lá cây",
"Blue": "Xanh da trời",
"Yellow": "Vàng",
"Magenta": "Đỏ tươi",
"Cyan": "Lam",
"Background": "Nền",
"Window": "Cửa sổ",
"Transparent": "Trong suốt",
"Semi-Transparent": "Bán trong suốt",
"Opaque": "Mờ",
"Font Size": "Kích cỡ phông chữ",
"Text Edge Style": "Dạng viền văn bản",
"None": "None",
"Raised": "Raised",
"Depressed": "Depressed",
"Uniform": "Uniform",
"Dropshadow": "Dropshadow",
"Font Family": "Phông chữ",
"Proportional Sans-Serif": "Proportional Sans-Serif",
"Monospace Sans-Serif": "Monospace Sans-Serif",
"Proportional Serif": "Proportional Serif",
"Monospace Serif": "Monospace Serif",
"Casual": "Casual",
"Script": "Script",
"Small Caps": "Small Caps",
"Reset": "Đặt lại",
"restore all settings to the default values": "khôi phục lại tất cả các cài đặt về giá trị mặc định",
"Done": "Xong",
"Caption Settings Dialog": "Hộp thoại cài đặt chú thích",
"Beginning of dialog window. Escape will cancel and close the window.": "Bắt đầu cửa sổ hộp thoại. Esc sẽ thoát và đóng cửa sổ.",
"End of dialog window.": "Kết thúc cửa sổ hộp thoại."
}
+14150
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+18 -11
Ver Arquivo
@@ -1,9 +1,8 @@
{
"name": "video.js",
"description": "An HTML5 and Flash video player with a common API and skin for both.",
"version": "6.2.0",
"version": "6.3.3",
"main": "./dist/video.cjs.js",
"module": "./dist/video.es.js",
"style": "./dist/video-js.css",
"copyright": "Copyright Brightcove, Inc. <https://www.brightcove.com/>",
"license": "Apache-2.0",
@@ -23,6 +22,7 @@
"rollup": "babel-node build/rollup.js",
"rollup-minify": "babel-node build/rollup.js --minify",
"rollup-dev": "babel-node build/rollup.js --watch",
"watch": "npm run rollup-dev",
"assets": "node build/assets.js",
"change": "grunt chg-add",
"clean": "grunt clean",
@@ -39,6 +39,7 @@
"docs:fix": "remark --output -- './**/*.md'",
"babel": "babel src/js -d es5",
"prepublish": "not-in-install && run-p docs:api build || in-install",
"publish": "node build/gh-release.js",
"prepush": "npm run lint -- --errors",
"version": "node build/version.js && git add CHANGELOG.md"
},
@@ -78,11 +79,12 @@
"es5-shim": "^4.1.3",
"es6-shim": "^0.35.1",
"filesize": "^3.5.6",
"gh-release": "^3.0.0",
"grunt": "^0.4.5",
"grunt-accessibility": "^5.0.0",
"grunt-babel": "^6.0.0",
"grunt-babel": "^7.0.0",
"grunt-banner": "^0.6.0",
"grunt-browserify": "5.0.0",
"grunt-browserify": "5.2.0",
"grunt-cli": "~1.2.0",
"grunt-concurrent": "^2.3.1",
"grunt-contrib-clean": "^1.0.0",
@@ -102,7 +104,7 @@
"grunt-videojs-languages": "0.0.4",
"grunt-zip": "0.17.1",
"humanize-duration": "^3.10.0",
"husky": "^0.13.1",
"husky": "^0.14.1",
"in-publish": "^2.0.0",
"istanbul": "^0.4.5",
"jsdoc": "^3.4.2",
@@ -118,7 +120,7 @@
"karma-qunit": "^1.2.0",
"karma-safari-launcher": "^1.0.0",
"karma-sinon": "^1.0.5",
"klaw-sync": "^1.1.2",
"klaw-sync": "^3.0.0",
"load-grunt-tasks": "^3.1.0",
"lodash": "^4.16.6",
"markdown-table": "^1.0.0",
@@ -127,12 +129,14 @@
"npm-run-all": "^4.0.2",
"proxyquireify": "^3.0.0",
"qunitjs": "1.23.1",
"remark-cli": "^3.0.0",
"remark-cli": "^4.0.0",
"remark-lint": "^6.0.0",
"remark-parse": "^4.0.0",
"remark-stringify": "^4.0.0",
"remark-toc": "^4.0.0",
"remark-validate-links": "^6.0.0",
"remark-validate-links": "^7.0.0",
"replace": "^0.3.0",
"rollup": "^0.41.6",
"rollup": "^0.47.5",
"rollup-plugin-babel": "^2.7.1",
"rollup-plugin-commonjs": "^8.0.2",
"rollup-plugin-filesize": "^1.2.1",
@@ -141,12 +145,13 @@
"rollup-plugin-node-resolve": "^3.0.0",
"rollup-plugin-progress": "^0.2.1",
"rollup-plugin-uglify": "^1.0.2",
"rollup-watch": "^3.2.2",
"rollup-watch": "^4.0.0",
"shelljs": "^0.7.5",
"sinon": "^1.16.1",
"time-grunt": "^1.1.1",
"tui-jsdoc-template": "^1.1.0",
"uglify-js": "~2.8.8",
"unified": "^6.1.5",
"videojs-doc-generator": "0.0.1",
"videojs-flash": "^2.0.0",
"videojs-standard": "^6.0.1",
@@ -170,7 +175,9 @@
"greenkeeper": {
"ignore": [
"qunitjs",
"sinon"
"sinon",
"webpack",
"uglify-js"
]
}
}
+3 -3
Ver Arquivo
@@ -5,16 +5,16 @@
<title>Video.js Sandbox</title>
<!-- Add ES5 shim and sham for IE8 -->
<script src="../build/temp/ie8/videojs-ie8.js"></script>
<script src="../dist/ie8/videojs-ie8.js"></script>
<!-- Load the source files -->
<link href="../build/temp/video-js.css" rel="stylesheet" type="text/css">
<script src="../build/temp/video.js"></script>
<script src="../dist/video.js"></script>
<script src="../node_modules/videojs-flash/dist/videojs-flash.js"></script>
<!-- Set the location of the flash SWF -->
<script>
videojs.options.flash.swf = '../build/temp/video-js.swf';
videojs.options.flash.swf = '../node_modules/videojs-flash/node_modules/videojs-swf/dist/video-js.swf';
</script>
</head>
<body>
+3 -3
Ver Arquivo
@@ -5,15 +5,15 @@
<title>Video.js Text Descriptions, Chapters &amp; Captions Example</title>
<!-- Add ES5 shim and sham for IE8 -->
<script src="../build/temp/ie8/videojs-ie8.js"></script>
<script src="../dist/ie8/videojs-ie8.js"></script>
<!-- Load the source files -->
<link href="../build/temp/video-js.css" rel="stylesheet" type="text/css">
<script src="../build/temp/video.js"></script>
<script src="../dist/video.js"></script>
<!-- Set the location of the flash SWF -->
<script>
videojs.options.flash.swf = '../build/temp/video-js.swf';
videojs.options.flash.swf = '../node_modules/videojs-flash/node_modules/videojs-swf/dist/video-js.swf';
</script>
</head>
+3 -3
Ver Arquivo
@@ -5,16 +5,16 @@
<title>Video.js Sandbox</title>
<!-- Add ES5 shim and sham for IE8 -->
<script src="../build/temp/ie8/videojs-ie8.js"></script>
<script src="../dist/ie8/videojs-ie8.js"></script>
<!-- Load the source files -->
<link href="../build/temp/video-js.css" rel="stylesheet" type="text/css">
<script src="../build/temp/video.js"></script>
<script src="../dist/video.js"></script>
<script src="../node_modules/videojs-flash/dist/videojs-flash.js"></script>
<!-- Set the location of the flash SWF -->
<script>
videojs.options.flash.swf = '../build/temp/video-js.swf';
videojs.options.flash.swf = '../node_modules/videojs-flash/node_modules/videojs-swf/dist/video-js.swf';
</script>
</head>
+2 -2
Ver Arquivo
@@ -5,7 +5,7 @@
<title>Video.js Sandbox</title>
<!-- Add ES5 shim and sham for IE8 -->
<script src="../build/temp/ie8/videojs-ie8.js"></script>
<script src="../dist/ie8/videojs-ie8.js"></script>
<!-- Load the source files -->
<link href="../build/temp/video-js.css" rel="stylesheet" type="text/css">
@@ -14,7 +14,7 @@
<!-- Set the location of the flash SWF -->
<script>
videojs.options.flash.swf = '../build/temp/video-js.swf';
videojs.options.flash.swf = '../node_modules/videojs-flash/node_modules/videojs-swf/dist/video-js.swf';
</script>
</head>
+3 -3
Ver Arquivo
@@ -6,15 +6,15 @@
<title>VideoJS Languages Demo</title>
<!-- Add ES5 shim and sham for IE8 -->
<script src="../build/temp/ie8/videojs-ie8.js"></script>
<script src="../dist/ie8/videojs-ie8.js"></script>
<!-- Load the source files -->
<link href="../build/temp/video-js.css" rel="stylesheet" type="text/css">
<script src="../build/temp/video.js"></script>
<script src="../dist/video.js"></script>
<!-- Set the location of the flash SWF -->
<script>
videojs.options.flash.swf = '../build/temp/video-js.swf';
videojs.options.flash.swf = '../node_modules/videojs-flash/node_modules/videojs-swf/dist/video-js.swf';
</script>
<!-- Add support for Spanish 'es' -->
+3 -3
Ver Arquivo
@@ -5,15 +5,15 @@
<title>Video.js Plugin Example</title>
<!-- Add ES5 shim and sham for IE8 -->
<script src="../build/temp/ie8/videojs-ie8.js"></script>
<script src="../dist/ie8/videojs-ie8.js"></script>
<!-- Load the source files -->
<link href="../build/temp/video-js.css" rel="stylesheet" type="text/css">
<script src="../build/temp/video.js"></script>
<script src="../dist/video.js"></script>
<!-- Set the location of the flash SWF -->
<script>
videojs.options.flash.swf = '../build/temp/video-js.swf';
videojs.options.flash.swf = '../node_modules/videojs-flash/node_modules/videojs-swf/dist/video-js.swf';
</script>
</head>
+5
Ver Arquivo
@@ -15,3 +15,8 @@
-moz-appearance: none;
appearance: none;
}
.vjs-control .vjs-button {
width: 100%;
height: 100%;
}
+7 -2
Ver Arquivo
@@ -1,12 +1,17 @@
// TODO: I feel like this should be a generic menu. Research later.
.vjs-playback-rate > .vjs-menu-button,
.vjs-playback-rate .vjs-playback-rate-value {
font-size: 1.5em;
line-height: 2;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.vjs-playback-rate .vjs-playback-rate-value {
pointer-events: none;
font-size: 1.5em;
line-height: 2;
text-align: center;
}
+29 -5
Ver Arquivo
@@ -11,6 +11,13 @@ import Component from './component.js';
* @extends Button
*/
class BigPlayButton extends Button {
constructor(player, options) {
super(player, options);
this.mouseused_ = false;
this.on('mousedown', this.handleMouseDown);
}
/**
* Builds the default DOM `className`.
@@ -36,6 +43,11 @@ class BigPlayButton extends Button {
handleClick(event) {
const playPromise = this.player_.play();
// exit early if clicked via the mouse
if (this.mouseused_ && event.clientX && event.clientY) {
return;
}
const cb = this.player_.getChild('controlBar');
const playToggle = cb && cb.getChild('playToggle');
@@ -44,14 +56,26 @@ class BigPlayButton extends Button {
return;
}
if (playPromise) {
playPromise.then(() => playToggle.focus());
const playFocus = () => playToggle.focus();
if (playPromise && playPromise.then) {
const ignoreRejectedPlayPromise = () => {};
playPromise.then(playFocus, ignoreRejectedPlayPromise);
} else {
this.setTimeout(function() {
playToggle.focus();
}, 1);
this.setTimeout(playFocus, 1);
}
}
handleKeyPress(event) {
this.mouseused_ = false;
super.handleKeyPress(event);
}
handleMouseDown(event) {
this.mouseused_ = true;
}
}
/**
+1 -1
Ver Arquivo
@@ -120,7 +120,7 @@ class ClickableComponent extends Component {
const localizedText = this.localize(text);
this.controlText_ = text;
this.controlTextEl_.innerHTML = localizedText;
Dom.textContent(this.controlTextEl_, localizedText);
if (!this.nonIconControl) {
// Set title attribute if only an icon is shown
el.setAttribute('title', localizedText);
+26
Ver Arquivo
@@ -57,6 +57,25 @@ class PlayToggle extends Button {
}
}
/**
* This gets called once after the video has ended and the user seeks so that
* we can change the replay button back to a play button.
*
* @param {EventTarget~Event} [event]
* The event that caused this function to run.
*
* @listens Player#seeked
*/
handleSeeked(event) {
this.removeClass('vjs-ended');
if (this.player_.paused()) {
this.handlePause(event);
} else {
this.handlePlay(event);
}
}
/**
* Add the vjs-playing class to the element so it can change appearance.
*
@@ -91,12 +110,19 @@ class PlayToggle extends Button {
/**
* Add the vjs-ended class to the element so it can change appearance
*
* @param {EventTarget~Event} [event]
* The event that caused this function to run.
*
* @listens Player#ended
*/
handleEnded(event) {
this.removeClass('vjs-playing');
this.addClass('vjs-ended');
// change the button text to "Replay"
this.controlText('Replay');
// on the next seek remove the replay button
this.one(this.player_, 'seeked', this.handleSeeked);
}
}
@@ -44,7 +44,7 @@ class PlaybackRateMenuButton extends MenuButton {
this.labelEl_ = Dom.createEl('div', {
className: 'vjs-playback-rate-value',
innerHTML: 1.0
innerHTML: '1x'
});
el.appendChild(this.labelEl_);
@@ -1,16 +1,15 @@
/**
* @file current-time-display.js
*/
import TimeDisplay from './time-display';
import Component from '../../component.js';
import * as Dom from '../../utils/dom.js';
import formatTime from '../../utils/format-time.js';
/**
* Displays the current time
*
* @extends Component
*/
class CurrentTimeDisplay extends Component {
class CurrentTimeDisplay extends TimeDisplay {
/**
* Creates an instance of this class.
@@ -23,32 +22,17 @@ class CurrentTimeDisplay extends Component {
*/
constructor(player, options) {
super(player, options);
this.on(player, 'timeupdate', this.updateContent);
this.on(player, 'ended', this.handleEnded);
}
/**
* Create the `Component`'s DOM element
* Builds the default DOM `className`.
*
* @return {Element}
* The element that was created.
* @return {string}
* The DOM `className` for this object.
*/
createEl() {
const el = super.createEl('div', {
className: 'vjs-current-time vjs-time-control vjs-control'
});
this.contentEl_ = Dom.createEl('div', {
className: 'vjs-current-time-display',
// label the current time for screen reader users
innerHTML: '<span class="vjs-control-text">Current Time </span>' + '0:00'
}, {
// tell screen readers not to automatically read the time as it changes
'aria-live': 'off'
});
el.appendChild(this.contentEl_);
return el;
buildCSSClass() {
return 'vjs-current-time';
}
/**
@@ -62,16 +46,36 @@ class CurrentTimeDisplay extends Component {
updateContent(event) {
// Allows for smooth scrubbing, when player can't keep up.
const time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
const localizedText = this.localize('Current Time');
const formattedTime = formatTime(time, this.player_.duration());
if (formattedTime !== this.formattedTime_) {
this.formattedTime_ = formattedTime;
this.contentEl_.innerHTML = `<span class="vjs-control-text">${localizedText}</span> ${formattedTime}`;
this.updateFormattedTime_(time);
}
/**
* When the player fires ended there should be no time left. Sadly
* this is not always the case, lets make it seem like that is the case
* for users.
*
* @param {EventTarget~Event} [event]
* The `ended` event that caused this to run.
*
* @listens Player#ended
*/
handleEnded(event) {
if (!this.player_.duration()) {
return;
}
this.updateFormattedTime_(this.player_.duration());
}
}
/**
* The text that should display over the `CurrentTimeDisplay`s controls. Added to for localization.
*
* @type {string}
* @private
*/
CurrentTimeDisplay.prototype.controlText_ = 'Current Time';
Component.registerComponent('CurrentTimeDisplay', CurrentTimeDisplay);
export default CurrentTimeDisplay;
@@ -1,16 +1,15 @@
/**
* @file duration-display.js
*/
import TimeDisplay from './time-display';
import Component from '../../component.js';
import * as Dom from '../../utils/dom.js';
import formatTime from '../../utils/format-time.js';
/**
* Displays the duration
*
* @extends Component
*/
class DurationDisplay extends Component {
class DurationDisplay extends TimeDisplay {
/**
* Creates an instance of this class.
@@ -24,37 +23,24 @@ class DurationDisplay extends Component {
constructor(player, options) {
super(player, options);
this.on(player, 'durationchange', this.updateContent);
this.on(player, [
'durationchange',
// Also listen for timeupdate and loadedmetadata because removing those
// listeners could have broken dependent applications/libraries. These
// can likely be removed for 6.0.
this.on(player, 'timeupdate', this.updateContent);
this.on(player, 'loadedmetadata', this.updateContent);
// Also listen for timeupdate (in the parent) and loadedmetadata because removing those
// listeners could have broken dependent applications/libraries. These
// can likely be removed for 7.0.
'loadedmetadata'
], this.throttledUpdateContent);
}
/**
* Create the `Component`'s DOM element
* Builds the default DOM `className`.
*
* @return {Element}
* The element that was created.
* @return {string}
* The DOM `className` for this object.
*/
createEl() {
const el = super.createEl('div', {
className: 'vjs-duration vjs-time-control vjs-control'
});
this.contentEl_ = Dom.createEl('div', {
className: 'vjs-duration-display',
// label the duration time for screen reader users
innerHTML: `<span class="vjs-control-text">${this.localize('Duration Time')}</span> 0:00`
}, {
// tell screen readers not to automatically read the time as it changes
'aria-live': 'off'
});
el.appendChild(this.contentEl_);
return el;
buildCSSClass() {
return 'vjs-duration';
}
/**
@@ -73,15 +59,18 @@ class DurationDisplay extends Component {
if (duration && this.duration_ !== duration) {
this.duration_ = duration;
const localizedText = this.localize('Duration Time');
const formattedTime = formatTime(duration);
// label the duration time for screen reader users
this.contentEl_.innerHTML = `<span class="vjs-control-text">${localizedText}</span> ${formattedTime}`;
this.updateFormattedTime_(duration);
}
}
}
/**
* The text that should display over the `DurationDisplay`s controls. Added to for localization.
*
* @type {string}
* @private
*/
DurationDisplay.prototype.controlText_ = 'Duration Time';
Component.registerComponent('DurationDisplay', DurationDisplay);
export default DurationDisplay;
@@ -1,16 +1,14 @@
/**
* @file remaining-time-display.js
*/
import TimeDisplay from './time-display';
import Component from '../../component.js';
import * as Dom from '../../utils/dom.js';
import formatTime from '../../utils/format-time.js';
/**
* Displays the time left in the video
*
* @extends Component
*/
class RemainingTimeDisplay extends Component {
class RemainingTimeDisplay extends TimeDisplay {
/**
* Creates an instance of this class.
@@ -23,33 +21,33 @@ class RemainingTimeDisplay extends Component {
*/
constructor(player, options) {
super(player, options);
this.on(player, 'timeupdate', this.updateContent);
this.on(player, 'durationchange', this.updateContent);
this.on(player, 'durationchange', this.throttledUpdateContent);
this.on(player, 'ended', this.handleEnded);
}
/**
* Create the `Component`'s DOM element
* Builds the default DOM `className`.
*
* @return {Element}
* The element that was created.
* @return {string}
* The DOM `className` for this object.
*/
createEl() {
const el = super.createEl('div', {
className: 'vjs-remaining-time vjs-time-control vjs-control'
});
buildCSSClass() {
return 'vjs-remaining-time';
}
this.contentEl_ = Dom.createEl('div', {
className: 'vjs-remaining-time-display',
// label the remaining time for screen reader users
innerHTML: `<span class="vjs-control-text">${this.localize('Remaining Time')}</span> -0:00`
}, {
// tell screen readers not to automatically read the time as it changes
'aria-live': 'off'
});
el.appendChild(this.contentEl_);
return el;
/**
* The remaining time display prefixes numbers with a "minus" character.
*
* @param {number} time
* A numeric time, in seconds.
*
* @return {string}
* A formatted time
*
* @private
*/
formatTime_(time) {
return '-' + super.formatTime_(time);
}
/**
@@ -62,22 +60,44 @@ class RemainingTimeDisplay extends Component {
* @listens Player#durationchange
*/
updateContent(event) {
if (this.player_.duration()) {
const localizedText = this.localize('Remaining Time');
const formattedTime = formatTime(this.player_.remainingTime());
if (formattedTime !== this.formattedTime_) {
this.formattedTime_ = formattedTime;
this.contentEl_.innerHTML = `<span class="vjs-control-text">${localizedText}</span> -${formattedTime}`;
}
if (!this.player_.duration()) {
return;
}
// Allows for smooth scrubbing, when player can't keep up.
// var time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
// this.contentEl_.innerHTML = vjs.formatTime(time, this.player_.duration());
// @deprecated We should only use remainingTimeDisplay
// as of video.js 7
if (this.player_.remainingTimeDisplay) {
this.updateFormattedTime_(this.player_.remainingTimeDisplay());
} else {
this.updateFormattedTime_(this.player_.remainingTime());
}
}
/**
* When the player fires ended there should be no time left. Sadly
* this is not always the case, lets make it seem like that is the case
* for users.
*
* @param {EventTarget~Event} [event]
* The `ended` event that caused this to run.
*
* @listens Player#ended
*/
handleEnded(event) {
if (!this.player_.duration()) {
return;
}
this.updateFormattedTime_(0);
}
}
/**
* The text that should display over the `RemainingTimeDisplay`s controls. Added to for localization.
*
* @type {string}
* @private
*/
RemainingTimeDisplay.prototype.controlText_ = 'Remaining Time';
Component.registerComponent('RemainingTimeDisplay', RemainingTimeDisplay);
export default RemainingTimeDisplay;
@@ -0,0 +1,129 @@
/**
* @file time-display.js
*/
import document from 'global/document';
import Component from '../../component.js';
import * as Dom from '../../utils/dom.js';
import {bind, throttle} from '../../utils/fn.js';
import formatTime from '../../utils/format-time.js';
/**
* Displays the time left in the video
*
* @extends Component
*/
class TimeDisplay extends Component {
/**
* Creates an instance of this class.
*
* @param {Player} player
* The `Player` that this class should be attached to.
*
* @param {Object} [options]
* The key/value store of player options.
*/
constructor(player, options) {
super(player, options);
this.throttledUpdateContent = throttle(bind(this, this.updateContent), 25);
this.on(player, 'timeupdate', this.throttledUpdateContent);
}
/**
* Create the `Component`'s DOM element
*
* @return {Element}
* The element that was created.
*/
createEl(plainName) {
const className = this.buildCSSClass();
const el = super.createEl('div', {
className: `${className} vjs-time-control vjs-control`
});
this.contentEl_ = Dom.createEl('div', {
className: `${className}-display`
}, {
// tell screen readers not to automatically read the time as it changes
'aria-live': 'off'
}, Dom.createEl('span', {
className: 'vjs-control-text',
textContent: this.localize(this.contentText_)
}));
this.updateTextNode_();
el.appendChild(this.contentEl_);
return el;
}
/**
* Updates the "remaining time" text node with new content using the
* contents of the `formattedTime_` property.
*
* @private
*/
updateTextNode_() {
if (this.textNode_) {
this.contentEl_.removeChild(this.textNode_);
}
this.textNode_ = document.createTextNode(this.formattedTime_ || '0:00');
this.contentEl_.appendChild(this.textNode_);
}
/**
* Generates a formatted time for this component to use in display.
*
* @param {number} time
* A numeric time, in seconds.
*
* @return {string}
* A formatted time
*
* @private
*/
formatTime_(time) {
return formatTime(time);
}
/**
* Updates the time display text node if it has what was passed in changed
* the formatted time.
*
* @param {number} time
* The time to update to
*
* @private
*/
updateFormattedTime_(time) {
const formattedTime = this.formatTime_(time);
if (formattedTime === this.formattedTime_) {
return;
}
this.formattedTime_ = formattedTime;
this.requestAnimationFrame(this.updateTextNode_);
}
/**
* To be filled out in the child class, should update the displayed time
* in accordance with the fact that the current time has changed.
*
* @param {EventTarget~Event} [event]
* The `timeupdate` event that caused this to run.
*
* @listens Player#timeupdate
*/
updateContent(event) {}
}
/**
* The text that should display over the `TimeDisplay`s controls. Added to for localization.
*
* @type {string}
* @private
*/
TimeDisplay.prototype.controlText_ = 'Time';
Component.registerComponent('TimeDisplay', TimeDisplay);
export default TimeDisplay;
+7 -2
Ver Arquivo
@@ -8,6 +8,7 @@ import * as Dom from '../utils/dom.js';
import * as Fn from '../utils/fn.js';
import * as Events from '../utils/events.js';
import toTitleCase from '../utils/to-title-case.js';
import { IS_IOS } from '../utils/browser.js';
import document from 'global/document';
/**
@@ -339,8 +340,12 @@ class MenuButton extends Component {
this.buttonPressed_ = true;
this.menu.lockShowing();
this.menuButton_.el_.setAttribute('aria-expanded', 'true');
// set the focus into the submenu
this.menu.focus();
// set the focus into the submenu, except on iOS where it is resulting in
// undesired scrolling behavior when the player is in an iframe
if (!IS_IOS && !Dom.isInFrame()) {
this.menu.focus();
}
}
}
+37 -26
Ver Arquivo
@@ -148,7 +148,7 @@ const TECH_EVENTS_RETRIGGER = [
/**
* Fires when the browser has loaded the current frame of the audio/video.
*
* @event player#loadeddata
* @event Player#loadeddata
* @type {event}
*/
/**
@@ -164,7 +164,7 @@ const TECH_EVENTS_RETRIGGER = [
/**
* Fires when the current playback position has changed.
*
* @event player#timeupdate
* @event Player#timeupdate
* @type {event}
*/
/**
@@ -180,7 +180,7 @@ const TECH_EVENTS_RETRIGGER = [
/**
* Fires when the playing speed of the audio/video is changed
*
* @event player#ratechange
* @event Player#ratechange
* @type {event}
*/
/**
@@ -212,7 +212,7 @@ const TECH_EVENTS_RETRIGGER = [
/**
* Fires when the volume has been changed
*
* @event player#volumechange
* @event Player#volumechange
* @type {event}
*/
/**
@@ -228,7 +228,7 @@ const TECH_EVENTS_RETRIGGER = [
/**
* Fires when the text track has been changed
*
* @event player#texttrackchange
* @event Player#texttrackchange
* @type {event}
*/
/**
@@ -605,10 +605,11 @@ class Player extends Component {
}
/**
* A getter/setter for the `Player`'s width.
* A getter/setter for the `Player`'s width. Returns the player's configured value.
* To get the current width use `currentWidth()`.
*
* @param {number} [value]
* The value to set the `Player's width to.
* The value to set the `Player`'s width to.
*
* @return {number}
* The current width of the `Player` when getting.
@@ -618,10 +619,11 @@ class Player extends Component {
}
/**
* A getter/setter for the `Player`'s height.
* A getter/setter for the `Player`'s height. Returns the player's configured value.
* To get the current height use `currentheight()`.
*
* @param {number} [value]
* The value to set the `Player's heigth to.
* The value to set the `Player`'s heigth to.
*
* @return {number}
* The current height of the `Player` when getting.
@@ -1076,7 +1078,6 @@ class Player extends Component {
} catch (e) {
log('deleting tag.poster throws in some browsers', e);
}
this.play();
}
}
@@ -1747,10 +1748,11 @@ class Player extends Component {
*/
duration(seconds) {
if (seconds === undefined) {
return this.cache_.duration || 0;
// return NaN if the duration is not known
return this.cache_.duration !== undefined ? this.cache_.duration : NaN;
}
seconds = parseFloat(seconds) || 0;
seconds = parseFloat(seconds);
// Standardize on Inifity for signaling video is live
if (seconds < 0) {
@@ -1785,6 +1787,17 @@ class Player extends Component {
return this.duration() - this.currentTime();
}
/**
* A remaining time function that is intented to be used when
* the time is to be displayed directly to the user.
*
* @return {number}
* The rounded time remaining in seconds
*/
remainingTimeDisplay() {
return Math.floor(this.duration()) - Math.floor(this.currentTime());
}
//
// Kind of like an array of portions of the video that have been downloaded.
@@ -2246,17 +2259,19 @@ class Player extends Component {
}
/**
* The source function updates the video source
* There are three types of variables you can pass as the argument.
* **URL string**: A URL to the the video file. Use this method if you are sure
* the current playback technology (HTML5/Flash) can support the source you
* provide. Currently only MP4 files can be used in both HTML5 and Flash.
* Get or set the video source.
*
* @param {Tech~SourceObject|Tech~SourceObject[]} [source]
* One SourceObject or an array of SourceObjects
* @param {Tech~SourceObject|Tech~SourceObject[]|string} [source]
* A SourceObject, an array of SourceObjects, or a string referencing
* a URL to a media source. It is _highly recommended_ that an object
* or array of objects is used here, so that source selection
* algorithms can take the `type` into account.
*
* @return {string}
* The current video source when getting
* If not provided, this method acts as a getter.
*
* @return {string|undefined}
* If the `source` argument is missing, returns the current source
* URL. Otherwise, returns nothing/undefined.
*/
src(source) {
// getter usage
@@ -2360,10 +2375,6 @@ class Player extends Component {
this.load();
}
if (this.options_.autoplay) {
this.play();
}
// Set the source synchronously if possible (#2326)
}, true);
@@ -3266,7 +3277,7 @@ class Player extends Component {
* @return {TextTrackList}
* The current remote text track list
*
* @method Player.prototype.textTracks
* @method Player.prototype.remoteTextTracks
*/
/**
+299 -205
Ver Arquivo
@@ -89,6 +89,9 @@ class Html5 extends Tech {
This may prevent text tracks from loading.`);
}
// prevent iOS Safari from disabling metadata text tracks during native playback
this.restoreMetadataTracksInIOSNativePlayer_();
// 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
@@ -114,6 +117,72 @@ class Html5 extends Tech {
super.dispose();
}
/**
* When a captions track is enabled in the iOS Safari native player, all other
* tracks are disabled (including metadata tracks), which nulls all of their
* associated cue points. This will restore metadata tracks to their pre-fullscreen
* state in those cases so that cue points are not needlessly lost.
*
* @private
*/
restoreMetadataTracksInIOSNativePlayer_() {
const textTracks = this.textTracks();
let metadataTracksPreFullscreenState;
// captures a snapshot of every metadata track's current state
const takeMetadataTrackSnapshot = () => {
metadataTracksPreFullscreenState = [];
for (let i = 0; i < textTracks.length; i++) {
const track = textTracks[i];
if (track.kind === 'metadata') {
metadataTracksPreFullscreenState.push({
track,
storedMode: track.mode
});
}
}
};
// snapshot each metadata track's initial state, and update the snapshot
// each time there is a track 'change' event
takeMetadataTrackSnapshot();
textTracks.addEventListener('change', takeMetadataTrackSnapshot);
const restoreTrackMode = () => {
for (let i = 0; i < metadataTracksPreFullscreenState.length; i++) {
const storedTrack = metadataTracksPreFullscreenState[i];
if (storedTrack.track.mode === 'disabled' && storedTrack.track.mode !== storedTrack.storedMode) {
storedTrack.track.mode = storedTrack.storedMode;
}
}
// we only want this handler to be executed on the first 'change' event
textTracks.removeEventListener('change', restoreTrackMode);
};
// when we enter fullscreen playback, stop updating the snapshot and
// restore all track modes to their pre-fullscreen state
this.on('webkitbeginfullscreen', () => {
textTracks.removeEventListener('change', takeMetadataTrackSnapshot);
// remove the listener before adding it just in case it wasn't previously removed
textTracks.removeEventListener('change', restoreTrackMode);
textTracks.addEventListener('change', restoreTrackMode);
});
// start updating the snapshot again after leaving fullscreen
this.on('webkitendfullscreen', () => {
// remove the listener before adding it just in case it wasn't previously removed
textTracks.removeEventListener('change', takeMetadataTrackSnapshot);
textTracks.addEventListener('change', takeMetadataTrackSnapshot);
// remove the restoreTrackMode handler in case it wasn't triggered during fullscreen playback
textTracks.removeEventListener('change', restoreTrackMode);
});
}
/**
* Proxy all native track list events to our track lists if the browser we are playing
* in supports that type of track list.
@@ -233,17 +302,27 @@ class Html5 extends Tech {
el.playerId = this.options_.playerId;
}
if (typeof this.options_.preload !== 'undefined') {
Dom.setAttribute(el, 'preload', this.options_.preload);
}
// Update specific tag settings, in case they were overridden
const settingsAttrs = ['autoplay', 'preload', 'loop', 'muted', 'playsinline'];
// `autoplay` has to be *last* so that `muted` and `playsinline` are present
// when iOS/Safari or other browsers attempt to autoplay.
const settingsAttrs = ['loop', 'muted', 'playsinline', 'autoplay'];
for (let i = settingsAttrs.length - 1; i >= 0; i--) {
const attr = settingsAttrs[i];
const overwriteAttrs = {};
const value = this.options_[attr];
if (typeof this.options_[attr] !== 'undefined') {
overwriteAttrs[attr] = this.options_[attr];
if (typeof value !== 'undefined') {
if (value) {
Dom.setAttribute(el, attr, attr);
} else {
Dom.removeAttribute(el, attr);
}
el[attr] = value;
}
Dom.setAttributes(el, overwriteAttrs);
}
return el;
@@ -368,24 +447,26 @@ class Html5 extends Tech {
// playback has started, which triggers the live display erroneously.
// Return NaN if playback has not started and trigger a durationupdate once
// the duration can be reliably known.
if (this.el_.duration === Infinity &&
browser.IS_ANDROID && browser.IS_CHROME) {
if (this.el_.currentTime === 0) {
// Wait for the first `timeupdate` with currentTime > 0 - there may be
// several with 0
const checkProgress = () => {
if (this.el_.currentTime > 0) {
// Trigger durationchange for genuinely live video
if (this.el_.duration === Infinity) {
this.trigger('durationchange');
}
this.off('timeupdate', checkProgress);
if (
this.el_.duration === Infinity &&
browser.IS_ANDROID &&
browser.IS_CHROME &&
this.el_.currentTime === 0
) {
// Wait for the first `timeupdate` with currentTime > 0 - there may be
// several with 0
const checkProgress = () => {
if (this.el_.currentTime > 0) {
// Trigger durationchange for genuinely live video
if (this.el_.duration === Infinity) {
this.trigger('durationchange');
}
};
this.off('timeupdate', checkProgress);
}
};
this.on('timeupdate', checkProgress);
return NaN;
}
this.on('timeupdate', checkProgress);
return NaN;
}
return this.el_.duration || NaN;
}
@@ -430,9 +511,12 @@ class Html5 extends Tech {
};
const beginFn = function() {
this.one('webkitendfullscreen', endFn);
if ('webkitPresentationMode' in this.el_ &&
this.el_.webkitPresentationMode !== 'picture-in-picture') {
this.one('webkitendfullscreen', endFn);
this.trigger('fullscreenchange', { isFullscreen: true });
this.trigger('fullscreenchange', { isFullscreen: true });
}
};
this.on('webkitbeginfullscreen', beginFn);
@@ -668,43 +752,6 @@ class Html5 extends Tech {
}
}
/**
* Get the value of `playsinline` from the media element. `playsinline` indicates
* to the browser that non-fullscreen playback is preferred when fullscreen
* playback is the native default, such as in iOS Safari.
*
* @method Html5#playsinline
* @return {boolean}
* - The value of `playsinline` from the media element.
* - True indicates that the media should play inline.
* - False indicates that the media should not play inline.
*
* @see [Spec]{@link https://html.spec.whatwg.org/#attr-video-playsinline}
*/
playsinline() {
return this.el_.hasAttribute('playsinline');
}
/**
* Set the value of `playsinline` from the media element. `playsinline` indicates
* to the browser that non-fullscreen playback is preferred when fullscreen
* playback is the native default, such as in iOS Safari.
*
* @method Html5#setPlaysinline
* @param {boolean} playsinline
* - True indicates that the media should play inline.
* - False indicates that the media should not play inline.
*
* @see [Spec]{@link https://html.spec.whatwg.org/#attr-video-playsinline}
*/
setPlaysinline(value) {
if (value) {
this.el_.setAttribute('playsinline', 'playsinline');
} else {
this.el_.removeAttribute('playsinline');
}
}
/**
* Gets available media playback quality metrics as specified by the W3C's Media
* Playback Quality API.
@@ -1090,7 +1137,195 @@ Html5.resetMediaElement = function(el) {
};
/* Native HTML5 element property wrapping ----------------------------------- */
// Wrap native boolean attributes with getters that check both property and attribute
// The list is as followed:
// muted, defaultMuted, autoplay, controls, loop, playsinline
[
/**
* Get the value of `muted` from the media element. `muted` indicates
* that the volume for the media should be set to silent. This does not actually change
* the `volume` attribute.
*
* @method Html5#muted
* @return {boolean}
* - True if the value of `volume` should be ignored and the audio set to silent.
* - False if the value of `volume` should be used.
*
* @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted}
*/
'muted',
/**
* Get the value of `defaultMuted` from the media element. `defaultMuted` indicates
* whether the media should start muted or not. Only changes the default state of the
* media. `muted` and `defaultMuted` can have different values. {@link Html5#muted} indicates the
* current state.
*
* @method Html5#defaultMuted
* @return {boolean}
* - The value of `defaultMuted` from the media element.
* - True indicates that the media should start muted.
* - False indicates that the media should not start muted
*
* @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-defaultmuted}
*/
'defaultMuted',
/**
* Get the value of `autoplay` from the media element. `autoplay` indicates
* that the media should start to play as soon as the page is ready.
*
* @method Html5#autoplay
* @return {boolean}
* - The value of `autoplay` from the media element.
* - True indicates that the media should start as soon as the page loads.
* - False indicates that the media should not start as soon as the page loads.
*
* @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay}
*/
'autoplay',
/**
* Get the value of `controls` from the media element. `controls` indicates
* whether the native media controls should be shown or hidden.
*
* @method Html5#controls
* @return {boolean}
* - The value of `controls` from the media element.
* - True indicates that native controls should be showing.
* - False indicates that native controls should be hidden.
*
* @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-controls}
*/
'controls',
/**
* Get the value of `loop` from the media element. `loop` indicates
* that the media should return to the start of the media and continue playing once
* it reaches the end.
*
* @method Html5#loop
* @return {boolean}
* - The value of `loop` from the media element.
* - True indicates that playback should seek back to start once
* the end of a media is reached.
* - False indicates that playback should not loop back to the start when the
* end of the media is reached.
*
* @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop}
*/
'loop',
/**
* Get the value of `playsinline` from the media element. `playsinline` indicates
* to the browser that non-fullscreen playback is preferred when fullscreen
* playback is the native default, such as in iOS Safari.
*
* @method Html5#playsinline
* @return {boolean}
* - The value of `playsinline` from the media element.
* - True indicates that the media should play inline.
* - False indicates that the media should not play inline.
*
* @see [Spec]{@link https://html.spec.whatwg.org/#attr-video-playsinline}
*/
'playsinline'
].forEach(function(prop) {
Html5.prototype[prop] = function() {
return this.el_[prop] || this.el_.hasAttribute(prop);
};
});
// Wrap native boolean attributes with setters that set both property and attribute
// The list is as followed:
// setMuted, setDefaultMuted, setAutoplay, setLoop, setPlaysinline
// setControls is special-cased above
[
/**
* Set the value of `muted` on the media element. `muted` indicates that the current
* audio level should be silent.
*
* @method Html5#setMuted
* @param {boolean} muted
* - True if the audio should be set to silent
* - False otherwise
*
* @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted}
*/
'muted',
/**
* Set the value of `defaultMuted` on the media element. `defaultMuted` indicates that the current
* audio level should be silent, but will only effect the muted level on intial playback..
*
* @method Html5.prototype.setDefaultMuted
* @param {boolean} defaultMuted
* - True if the audio should be set to silent
* - False otherwise
*
* @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-defaultmuted}
*/
'defaultMuted',
/**
* Set the value of `autoplay` on the media element. `autoplay` indicates
* that the media should start to play as soon as the page is ready.
*
* @method Html5#setAutoplay
* @param {boolean} autoplay
* - True indicates that the media should start as soon as the page loads.
* - False indicates that the media should not start as soon as the page loads.
*
* @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay}
*/
'autoplay',
/**
* Set the value of `loop` on the media element. `loop` indicates
* that the media should return to the start of the media and continue playing once
* it reaches the end.
*
* @method Html5#setLoop
* @param {boolean} loop
* - True indicates that playback should seek back to start once
* the end of a media is reached.
* - False indicates that playback should not loop back to the start when the
* end of the media is reached.
*
* @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop}
*/
'loop',
/**
* Set the value of `playsinline` from the media element. `playsinline` indicates
* to the browser that non-fullscreen playback is preferred when fullscreen
* playback is the native default, such as in iOS Safari.
*
* @method Html5#setPlaysinline
* @param {boolean} playsinline
* - True indicates that the media should play inline.
* - False indicates that the media should not play inline.
*
* @see [Spec]{@link https://html.spec.whatwg.org/#attr-video-playsinline}
*/
'playsinline'
].forEach(function(prop) {
Html5.prototype['set' + toTitleCase(prop)] = function(v) {
this.el_[prop] = v;
if (v) {
this.el_.setAttribute(prop, prop);
} else {
this.el_.removeAttribute(prop);
}
};
});
// Wrap native properties with a getter
// The list is as followed
// paused, currentTime, buffered, volume, poster, preload, error, seeking
// seekable, ended, playbackRate, defaultPlaybackRate, played, networkState
// readyState, videoWidth, videoHeight
[
/**
* Get the value of `paused` from the media element. `paused` indicates whether the media element
@@ -1142,35 +1377,6 @@ Html5.resetMediaElement = function(el) {
*/
'volume',
/**
* Get the value of `muted` from the media element. `muted` indicates
* that the volume for the media should be set to silent. This does not actually change
* the `volume` attribute.
*
* @method Html5#muted
* @return {boolean}
* - True if the value of `volume` should be ignored and the audio set to silent.
* - False if the value of `volume` should be used.
*
* @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted}
*/
'muted',
/**
* Get the value of `defaultMuted` from the media element. `defaultMuted` indicates
* that the volume for the media should be set to silent when the video first starts.
* This does not actually change the `volume` attribute. After playback has started `muted`
* will indicate the current status of the volume and `defaultMuted` will not.
*
* @method Html5.prototype.defaultMuted
* @return {boolean}
* - True if the value of `volume` should be ignored and the audio set to silent.
* - False if the value of `volume` should be used.
*
* @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-defaultmuted}
*/
'defaultMuted',
/**
* Get the value of `poster` from the media element. `poster` indicates
* that the url of an image file that can/will be shown when no media data is available.
@@ -1203,51 +1409,6 @@ Html5.resetMediaElement = function(el) {
*/
'preload',
/**
* Get the value of `autoplay` from the media element. `autoplay` indicates
* that the media should start to play as soon as the page is ready.
*
* @method Html5#autoplay
* @return {boolean}
* - The value of `autoplay` from the media element.
* - True indicates that the media should start as soon as the page loads.
* - False indicates that the media should not start as soon as the page loads.
*
* @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay}
*/
'autoplay',
/**
* Get the value of `controls` from the media element. `controls` indicates
* whether the native media controls should be shown or hidden.
*
* @method Html5#controls
* @return {boolean}
* - The value of `controls` from the media element.
* - True indicates that native controls should be showing.
* - False indicates that native controls should be hidden.
*
* @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-controls}
*/
'controls',
/**
* Get the value of `loop` from the media element. `loop` indicates
* that the media should return to the start of the media and continue playing once
* it reaches the end.
*
* @method Html5#loop
* @return {boolean}
* - The value of `loop` from the media element.
* - True indicates that playback should seek back to start once
* the end of a media is reached.
* - False indicates that playback should not loop back to the start when the
* end of the media is reached.
*
* @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop}
*/
'loop',
/**
* Get the value of the `error` from the media element. `error` indicates any
* MediaError that may have occured during playback. If error returns null there is no
@@ -1303,22 +1464,6 @@ Html5.resetMediaElement = function(el) {
*/
'ended',
/**
* Get the value of `defaultMuted` from the media element. `defaultMuted` indicates
* whether the media should start muted or not. Only changes the default state of the
* media. `muted` and `defaultMuted` can have different values. {@link Html5#muted} indicates the
* current state.
*
* @method Html5#defaultMuted
* @return {boolean}
* - The value of `defaultMuted` from the media element.
* - True indicates that the media should start muted.
* - False indicates that the media should not start muted
*
* @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-defaultmuted}
*/
'defaultMuted',
/**
* Get the value of `playbackRate` from the media element. `playbackRate` indicates
* the rate at which the media is currently playing back. Examples:
@@ -1434,6 +1579,8 @@ Html5.resetMediaElement = function(el) {
// Wrap native properties with a setter in this format:
// set + toTitleCase(name)
// The list is as follows:
// setVolume, setSrc, setPoster, setPreload, setPlaybackRate, setDefaultPlaybackRate
[
/**
* Set the value of `volume` on the media element. `volume` indicates the current
@@ -1448,32 +1595,6 @@ Html5.resetMediaElement = function(el) {
*/
'volume',
/**
* Set the value of `muted` on the media element. `muted` indicates that the current
* audio level should be silent.
*
* @method Html5#setMuted
* @param {boolean} muted
* - True if the audio should be set to silent
* - False otherwise
*
* @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted}
*/
'muted',
/**
* Set the value of `defaultMuted` on the media element. `defaultMuted` indicates that the current
* audio level should be silent, but will only effect the muted level on intial playback..
*
* @method Html5.prototype.setDefaultMuted
* @param {boolean} defaultMuted
* - True if the audio should be set to silent
* - False otherwise
*
* @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-defaultmuted}
*/
'defaultMuted',
/**
* Set the value of `src` on the media element. `src` indicates the current
* {@link Tech~SourceObject} for the media.
@@ -1518,35 +1639,6 @@ Html5.resetMediaElement = function(el) {
*/
'preload',
/**
* Set the value of `autoplay` on the media element. `autoplay` indicates
* that the media should start to play as soon as the page is ready.
*
* @method Html5#setAutoplay
* @param {boolean} autoplay
* - True indicates that the media should start as soon as the page loads.
* - False indicates that the media should not start as soon as the page loads.
*
* @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay}
*/
'autoplay',
/**
* Set the value of `loop` on the media element. `loop` indicates
* that the media should return to the start of the media and continue playing once
* it reaches the end.
*
* @method Html5#setLoop
* @param {boolean} loop
* - True indicates that playback should seek back to start once
* the end of a media is reached.
* - False indicates that playback should not loop back to the start when the
* end of the media is reached.
*
* @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop}
*/
'loop',
/**
* Set the value of `playbackRate` on the media element. `playbackRate` indicates
* the rate at which the media should play back. Examples:
@@ -1587,6 +1679,8 @@ Html5.resetMediaElement = function(el) {
});
// wrap native functions with a function
// The list is as follows:
// pause, load play
[
/**
* A wrapper around the media elements `pause` function. This will call the `HTML5`
+1 -1
Ver Arquivo
@@ -700,7 +700,7 @@ class Tech extends Component {
if (manualCleanup !== true) {
// create the TextTrackList if it doesn't exist
this.autoRemoteTextTracks_.addTrack(htmlTrackElement.track);
this.ready(() => this.autoRemoteTextTracks_.addTrack(htmlTrackElement.track));
}
return htmlTrackElement;
+1 -1
Ver Arquivo
@@ -19,7 +19,7 @@ import document from 'global/document';
*/
const disableOthers = function(list, track) {
for (let i = 0; i < list.length; i++) {
if (track.id === list[i].id) {
if (!Object.keys(list[i]).length || track.id === list[i].id) {
continue;
}
// another audio track is enabled, disable it
+88 -107
Ver Arquivo
@@ -299,8 +299,9 @@ class TextTrackSettings extends ModalDialog {
* @param {string} key
* Configuration key to use during creation.
*
* @return {Element}
* The DOM element that gets created.
* @return {string}
* An HTML string.
*
* @private
*/
createElSelect_(key, legendId = '', type = 'label') {
@@ -308,101 +309,94 @@ class TextTrackSettings extends ModalDialog {
const id = config.id.replace('%s', this.id_);
return [
createEl(type, {
id,
className: type === 'label' ? 'vjs-label' : '',
textContent: this.localize(config.label)
}, {
}),
createEl('select', {}, {
'aria-labelledby': `${legendId} ${id}`
}, config.options.map(o => {
`<${type} id="${id}" class="${type === 'label' ? 'vjs-label' : ''}">`,
this.localize(config.label),
`</${type}>`,
`<select aria-labelledby="${legendId} ${id}">`
].
concat(config.options.map(o => {
const optionId = id + '-' + o[1];
return createEl('option', {
id: optionId,
textContent: this.localize(o[1]),
value: o[0]
}, {
'aria-labelledby': `${legendId} ${id} ${optionId}`
});
}))
];
return [
`<option id="${optionId}" value="${o[0]}" `,
`aria-labelledby="${legendId} ${id} ${optionId}">`,
this.localize(o[1]),
'</option>'
].join('');
})).
concat('</select>').join('');
}
/**
* Create foreground color element for the component
*
* @return {Element}
* The element that was created.
* @return {string}
* An HTML string.
*
* @private
*/
createElFgColor_() {
const legend = createEl('legend', {
id: `captions-text-legend-${this.id_}`,
textContent: this.localize('Text')
});
const legendId = `captions-text-legend-${this.id_}`;
const select = this.createElSelect_('color', legend.id);
const opacity = createEl('span', {
className: 'vjs-text-opacity vjs-opacity'
}, undefined, this.createElSelect_('textOpacity', legend.id));
return createEl('fieldset', {
className: 'vjs-fg-color vjs-track-setting'
}, undefined, [legend].concat(select, opacity));
return [
'<fieldset class="vjs-fg-color vjs-track-setting">',
`<legend id="${legendId}">`,
this.localize('Text'),
'</legend>',
this.createElSelect_('color', legendId),
'<span class="vjs-text-opacity vjs-opacity">',
this.createElSelect_('textOpacity', legendId),
'</span>',
'</fieldset>'
].join('');
}
/**
* Create background color element for the component
*
* @return {Element}
* The element that was created
* @return {string}
* An HTML string.
*
* @private
*/
createElBgColor_() {
const legend = createEl('legend', {
id: `captions-background-${this.id_}`,
textContent: this.localize('Background')
});
const legendId = `captions-background-${this.id_}`;
const select = this.createElSelect_('backgroundColor', legend.id);
const opacity = createEl('span', {
className: 'vjs-bg-opacity vjs-opacity'
}, undefined, this.createElSelect_('backgroundOpacity', legend.id));
return createEl('fieldset', {
className: 'vjs-bg-color vjs-track-setting'
}, undefined, [legend].concat(select, opacity));
return [
'<fieldset class="vjs-bg-color vjs-track-setting">',
`<legend id="${legendId}">`,
this.localize('Background'),
'</legend>',
this.createElSelect_('backgroundColor', legendId),
'<span class="vjs-bg-opacity vjs-opacity">',
this.createElSelect_('backgroundOpacity', legendId),
'</span>',
'</fieldset>'
].join('');
}
/**
* Create window color element for the component
*
* @return {Element}
* The element that was created
* @return {string}
* An HTML string.
*
* @private
*/
createElWinColor_() {
const legend = createEl('legend', {
id: `captions-window-${this.id_}`,
textContent: this.localize('Window')
});
const legendId = `captions-window-${this.id_}`;
const select = this.createElSelect_('windowColor', legend.id);
const opacity = createEl('span', {
className: 'vjs-window-opacity vjs-opacity'
}, undefined, this.createElSelect_('windowOpacity', legend.id));
return createEl('fieldset', {
className: 'vjs-window-color vjs-track-setting'
}, undefined, [legend].concat(select, opacity));
return [
'<fieldset class="vjs-window-color vjs-track-setting">',
`<legend id="${legendId}">`,
this.localize('Window'),
'</legend>',
this.createElSelect_('windowColor', legendId),
'<span class="vjs-window-opacity vjs-opacity">',
this.createElSelect_('windowOpacity', legendId),
'</span>',
'</fieldset>'
].join('');
}
/**
@@ -415,12 +409,13 @@ class TextTrackSettings extends ModalDialog {
*/
createElColors_() {
return createEl('div', {
className: 'vjs-track-settings-colors'
}, undefined, [
this.createElFgColor_(),
this.createElBgColor_(),
this.createElWinColor_()
]);
className: 'vjs-track-settings-colors',
innerHTML: [
this.createElFgColor_(),
this.createElBgColor_(),
this.createElWinColor_()
].join('')
});
}
/**
@@ -432,21 +427,20 @@ class TextTrackSettings extends ModalDialog {
* @private
*/
createElFont_() {
const fontPercent = createEl('fieldset', {
className: 'vjs-font-percent vjs-track-setting'
}, undefined, this.createElSelect_('fontPercent', '', 'legend'));
const edgeStyle = createEl('fieldset', {
className: 'vjs-edge-style vjs-track-setting'
}, undefined, this.createElSelect_('edgeStyle', '', 'legend'));
const fontFamily = createEl('fieldset', {
className: 'vjs-font-family vjs-track-setting'
}, undefined, this.createElSelect_('fontFamily', '', 'legend'));
return createEl('div', {
className: 'vjs-track-settings-font'
}, undefined, [fontPercent, edgeStyle, fontFamily]);
className: 'vjs-track-settings-font">',
innerHTML: [
'<fieldset class="vjs-font-percent vjs-track-setting">',
this.createElSelect_('fontPercent', '', 'legend'),
'</fieldset>',
'<fieldset class="vjs-edge-style vjs-track-setting">',
this.createElSelect_('edgeStyle', '', 'legend'),
'</fieldset>',
'<fieldset class="vjs-font-family vjs-track-setting">',
this.createElSelect_('fontFamily', '', 'legend'),
'</fieldset>'
].join('')
});
}
/**
@@ -459,30 +453,17 @@ class TextTrackSettings extends ModalDialog {
*/
createElControls_() {
const defaultsDescription = this.localize('restore all settings to the default values');
const defaultsButton = createEl('button', {
className: 'vjs-default-button',
title: defaultsDescription,
innerHTML: `${this.localize('Reset')}<span class='vjs-control-text'> ${defaultsDescription}</span>`
});
const doneButton = createEl('button', {
className: 'vjs-done-button',
textContent: this.localize('Done')
});
return createEl('div', {
className: 'vjs-track-settings-controls'
}, undefined, [defaultsButton, doneButton]);
}
/**
* Create the component's DOM element
*
* @return {Element}
* The element that was created.
*/
createEl() {
return super.createEl();
className: 'vjs-track-settings-controls',
innerHTML: [
`<button class="vjs-default-button" title="${defaultsDescription}">`,
this.localize('Reset'),
`<span class="vjs-control-text"> ${defaultsDescription}</span>`,
'</button>',
`<button class="vjs-done-button">${this.localize('Done')}</button>`
].join('')
});
}
content() {
+1 -1
Ver Arquivo
@@ -18,7 +18,7 @@ import document from 'global/document';
*/
const disableOthers = function(list, track) {
for (let i = 0; i < list.length; i++) {
if (track.id === list[i].id) {
if (!Object.keys(list[i]).length || track.id === list[i].id) {
continue;
}
// another video track is enabled, disable it
+18 -1
Ver Arquivo
@@ -85,6 +85,23 @@ export function isEl(value) {
return isObject(value) && value.nodeType === 1;
}
/**
* Determines if the current DOM is embedded in an iframe.
*
* @return {boolean}
*
*/
export function isInFrame() {
// We need a try/catch here because Safari will throw errors when attempting
// to get either `parent` or `self`
try {
return window.parent !== window.self;
} catch (x) {
return true;
}
}
/**
* Creates functions to query the DOM using a given method.
*
@@ -375,7 +392,7 @@ export function getAttributes(tag) {
// 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
const knownBooleans = ',' + 'autoplay,controls,loop,muted,default' + ',';
const knownBooleans = ',' + 'autoplay,controls,playsinline,loop,muted,default,defaultMuted' + ',';
if (tag && tag.attributes && tag.attributes.length > 0) {
const attrs = tag.attributes;
+34 -1
Ver Arquivo
@@ -202,6 +202,33 @@ export function fixEvent(event) {
return event;
}
/**
* Whether passive event listeners are supported
*/
let _supportsPassive = false;
(function() {
try {
const opts = Object.defineProperty({}, 'passive', {
get() {
_supportsPassive = true;
}
});
window.addEventListener('test', null, opts);
} catch (e) {
// disregard
}
})();
/**
* Touch events Chrome expects to be passive
*/
const passiveEvents = [
'touchstart',
'touchmove'
];
/**
* Add an event listener to element
* It stores the handler function in a separate cache object
@@ -273,7 +300,13 @@ export function on(elem, type, fn) {
if (data.handlers[type].length === 1) {
if (elem.addEventListener) {
elem.addEventListener(type, data.dispatcher, false);
let options = false;
if (_supportsPassive &&
passiveEvents.indexOf(type) > -1) {
options = {passive: true};
}
elem.addEventListener(type, data.dispatcher, options);
} else if (elem.attachEvent) {
elem.attachEvent('on' + type, data.dispatcher);
}
+6 -1
Ver Arquivo
@@ -124,7 +124,7 @@ module.exports = function(config) {
'ie8_bs'
];
} else {
settings.browsers = ['Firefox'];
settings.browsers = ['chrome_travis'];
}
}
@@ -133,6 +133,11 @@ module.exports = function(config) {
function getCustomLaunchers(){
return {
chrome_travis: {
base: 'Chrome',
flags: ['--no-sandbox']
},
chrome_bs: {
base: 'BrowserStack',
browser: 'chrome',
+28
Ver Arquivo
@@ -1655,3 +1655,31 @@ QUnit.test('should add a class with major version', function(assert) {
player.dispose();
});
QUnit.test('player.duration() returns NaN if player.cache_.duration is undefined', function(assert) {
const player = TestHelpers.makePlayer();
player.cache_.duration = undefined;
assert.ok(Number.isNaN(player.duration()), 'returned NaN for unkown duration');
});
QUnit.test('player.duration() returns player.cache_.duration if it is defined', function(assert) {
const player = TestHelpers.makePlayer();
player.cache_.duration = 200;
assert.equal(player.duration(), 200, 'returned correct integer duration');
player.cache_.duration = 942;
assert.equal(player.duration(), 942, 'returned correct integer duration');
});
QUnit.test('player.duration() sets the value of player.cache_.duration', function(assert) {
const player = TestHelpers.makePlayer();
// set an arbitrary initial cached duration value for testing the setter functionality
player.cache_.duration = 1;
player.duration(NaN);
assert.ok(Number.isNaN(player.duration()), 'duration() set and get NaN duration value');
player.duration(200);
assert.equal(player.duration(), 200, 'duration() set and get integer duration value');
});
+5
Ver Arquivo
@@ -214,11 +214,14 @@ QUnit.test('switching sources should clear all remote tracks that are added with
const tech = new MyTech();
tech.triggerReady();
// set the initial source
tech.setSource({src: 'foo.mp4', type: 'mp4'});
// default value for manualCleanup is true
tech.addRemoteTextTrack({});
this.clock.tick(1);
assert.equal(warning,
'Calling addRemoteTextTrack without explicitly setting the "manualCleanup" parameter to `true` is deprecated and default to `false` in future version of video.js',
@@ -226,6 +229,7 @@ QUnit.test('switching sources should clear all remote tracks that are added with
// should be automatically cleaned up when source changes
tech.addRemoteTextTrack({}, false);
this.clock.tick(1);
assert.equal(tech.textTracks().length, 2, 'should have two text tracks at the start');
assert.equal(tech.remoteTextTrackEls().length,
@@ -238,6 +242,7 @@ QUnit.test('switching sources should clear all remote tracks that are added with
// change source to force cleanup of auto remote text tracks
tech.setSource({src: 'bar.mp4', type: 'mp4'});
this.clock.tick(1);
assert.equal(tech.textTracks().length,
1,
+52
Ver Arquivo
@@ -528,3 +528,55 @@ QUnit.test('removeRemoteTextTrack should be able to take both a track and the re
'the track element was removed correctly');
player.dispose();
});
if (Html5.isSupported()) {
QUnit.test('auto remove tracks should not clean up tracks added while source is being added', function(assert) {
const player = TestHelpers.makePlayer({
techOrder: ['html5'],
html5: {
nativeTextTracks: false
}
});
const track = {
kind: 'kind',
src: 'src',
language: 'language',
label: 'label',
default: 'default'
};
player.src({src: 'example.mp4', type: 'video/mp4'});
player.addRemoteTextTrack(track, false);
this.clock.tick(1);
assert.equal(player.textTracks().length, 1, 'we have one text track');
player.dispose();
});
QUnit.test('auto remove tracks added right before a source change will be cleaned up', function(assert) {
const player = TestHelpers.makePlayer({
techOrder: ['html5'],
html5: {
nativeTextTracks: false
}
});
const track = {
kind: 'kind',
src: 'src',
language: 'language',
label: 'label',
default: 'default'
};
player.addRemoteTextTrack(track, false);
player.src({src: 'example.mp4', type: 'video/mp4'});
this.clock.tick(1);
assert.equal(player.textTracks().length, 0, 'we do not have any tracks left');
player.dispose();
});
}