├── .gitignore ├── CNAME ├── Gruntfile.js ├── LICENSE ├── README.md ├── _config.yml ├── conf.json ├── docs ├── api │ ├── assets │ │ ├── api-doc-template-min.html │ │ ├── api-doc-template.html │ │ ├── create-doc-files-test.html │ │ └── create-doc-files.js │ ├── audio-track-button.html │ ├── big-play-button.html │ ├── button.html │ ├── caption-settings-menu-item.html │ ├── captions-button.html │ ├── captions-track.html │ ├── chapters-button.html │ ├── chapters-track-menu-item.html │ ├── chapters-track.html │ ├── clickable-component.html │ ├── close-button.html │ ├── component.html │ ├── control-bar.html │ ├── css │ │ ├── api-docs.css │ │ └── api-index.css │ ├── current-time-display.html │ ├── custom-control-spacer.html │ ├── duration-display.html │ ├── error-display.html │ ├── flash.html │ ├── fullscreen-toggle.html │ ├── fullscreen-toggle.json │ ├── html-track-element.html │ ├── html5.html │ ├── index.html │ ├── js │ │ ├── api-docs.js │ │ ├── api-index.js │ │ ├── doc-data-full.js │ │ ├── doc-data.js │ │ ├── doc-script.js │ │ └── highlight-syntax.js │ ├── live-display.html │ ├── load-progress-bar.html │ ├── loader.html │ ├── loading-spinner.html │ ├── md.html │ ├── menu-button.html │ ├── menu-item.html │ ├── menu.html │ ├── modal-dialog.html │ ├── mouse-time-display.html │ ├── mute-toggle.html │ ├── off-text-track-menu-item.html │ ├── play-progress-bar.html │ ├── play-toggle.html │ ├── playback-rate-menu-button.html │ ├── playback-rate-menu-item.html │ ├── player.html │ ├── popup-button.html │ ├── popup.html │ ├── poster-image.html │ ├── progress-control.html │ ├── remaining-time-display.html │ ├── seek-bar.html │ ├── seekhandle.html │ ├── slider.html │ ├── spacer.html │ ├── subtitles-button.html │ ├── subtitlestrack.html │ ├── tech.html │ ├── text-track-button.html │ ├── text-track-display.html │ ├── text-track-menu-item.html │ ├── text-track-settings.html │ ├── texttrack.html │ ├── time-divider.html │ ├── video.html │ ├── volume-bar.html │ ├── volume-control.html │ ├── volume-level.html │ └── volume-menu-button.html ├── css │ ├── guides-gh.css │ ├── guides.css │ └── main.css ├── examples │ ├── elephantsdream │ │ ├── captions.ar.vtt │ │ ├── captions.en.vtt │ │ ├── captions.ja.vtt │ │ ├── captions.ru.vtt │ │ ├── captions.sv.vtt │ │ ├── chapters.en.vtt │ │ ├── descriptions.en.vtt │ │ └── index.html │ ├── shared │ │ └── example-captions.vtt │ └── simple-embed │ │ └── index.html ├── fonts │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ └── fontawesome-webfont.woff2 ├── guides │ ├── api.html │ ├── audio-tracks.html │ ├── components.html │ ├── glossary.html │ ├── languages.html │ ├── options.html │ ├── plugins.html │ ├── removing-players.html │ ├── setup.html │ ├── skins.html │ ├── tech.html │ ├── text-tracks.html │ ├── tracks.html │ └── video-tracks.html ├── images │ └── logo.png ├── index.html └── js │ ├── guides.js │ ├── home.js │ └── index.js ├── index.html ├── package.json ├── plugins ├── commentConvert.js ├── commentsOnly.js ├── escapeHtml.js ├── eventDumper.js ├── markdown.js ├── overloadHelper.js ├── partial.js ├── railsTemplate.js ├── shout.js ├── sourcetag.js ├── summarize.js ├── test │ ├── fixtures │ │ ├── markdown.js │ │ ├── overloadHelper.js │ │ ├── railsTemplate.js.erb │ │ └── underscore.js │ └── specs │ │ ├── commentConvert.js │ │ ├── escapeHtml.js │ │ ├── markdown.js │ │ ├── overloadHelper.js │ │ ├── railsTemplate.js │ │ ├── shout.js │ │ ├── sourcetag.js │ │ ├── summarize.js │ │ └── underscore.js └── underscore.js ├── semicolon.txt ├── templates └── guide-template.html └── var-name.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | 29 | /video.js 30 | /cumulative.json 31 | /doc-data-full.js 32 | /doc-data.js 33 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | docs.videojs.com 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The Artistic License 2.0 2 | 3 | Copyright (c) 2015 Video.js 4 | 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | This license establishes the terms under which a given free software 11 | Package may be copied, modified, distributed, and/or redistributed. 12 | The intent is that the Copyright Holder maintains some artistic 13 | control over the development of that Package while still keeping the 14 | Package available as open source and free software. 15 | 16 | You are always permitted to make arrangements wholly outside of this 17 | license directly with the Copyright Holder of a given Package. If the 18 | terms of this license do not permit the full use that you propose to 19 | make of the Package, you should contact the Copyright Holder and seek 20 | a different licensing arrangement. 21 | 22 | Definitions 23 | 24 | "Copyright Holder" means the individual(s) or organization(s) 25 | named in the copyright notice for the entire Package. 26 | 27 | "Contributor" means any party that has contributed code or other 28 | material to the Package, in accordance with the Copyright Holder's 29 | procedures. 30 | 31 | "You" and "your" means any person who would like to copy, 32 | distribute, or modify the Package. 33 | 34 | "Package" means the collection of files distributed by the 35 | Copyright Holder, and derivatives of that collection and/or of 36 | those files. A given Package may consist of either the Standard 37 | Version, or a Modified Version. 38 | 39 | "Distribute" means providing a copy of the Package or making it 40 | accessible to anyone else, or in the case of a company or 41 | organization, to others outside of your company or organization. 42 | 43 | "Distributor Fee" means any fee that you charge for Distributing 44 | this Package or providing support for this Package to another 45 | party. It does not mean licensing fees. 46 | 47 | "Standard Version" refers to the Package if it has not been 48 | modified, or has been modified only in ways explicitly requested 49 | by the Copyright Holder. 50 | 51 | "Modified Version" means the Package, if it has been changed, and 52 | such changes were not explicitly requested by the Copyright 53 | Holder. 54 | 55 | "Original License" means this Artistic License as Distributed with 56 | the Standard Version of the Package, in its current version or as 57 | it may be modified by The Perl Foundation in the future. 58 | 59 | "Source" form means the source code, documentation source, and 60 | configuration files for the Package. 61 | 62 | "Compiled" form means the compiled bytecode, object code, binary, 63 | or any other form resulting from mechanical transformation or 64 | translation of the Source form. 65 | 66 | 67 | Permission for Use and Modification Without Distribution 68 | 69 | (1) You are permitted to use the Standard Version and create and use 70 | Modified Versions for any purpose without restriction, provided that 71 | you do not Distribute the Modified Version. 72 | 73 | 74 | Permissions for Redistribution of the Standard Version 75 | 76 | (2) You may Distribute verbatim copies of the Source form of the 77 | Standard Version of this Package in any medium without restriction, 78 | either gratis or for a Distributor Fee, provided that you duplicate 79 | all of the original copyright notices and associated disclaimers. At 80 | your discretion, such verbatim copies may or may not include a 81 | Compiled form of the Package. 82 | 83 | (3) You may apply any bug fixes, portability changes, and other 84 | modifications made available from the Copyright Holder. The resulting 85 | Package will still be considered the Standard Version, and as such 86 | will be subject to the Original License. 87 | 88 | 89 | Distribution of Modified Versions of the Package as Source 90 | 91 | (4) You may Distribute your Modified Version as Source (either gratis 92 | or for a Distributor Fee, and with or without a Compiled form of the 93 | Modified Version) provided that you clearly document how it differs 94 | from the Standard Version, including, but not limited to, documenting 95 | any non-standard features, executables, or modules, and provided that 96 | you do at least ONE of the following: 97 | 98 | (a) make the Modified Version available to the Copyright Holder 99 | of the Standard Version, under the Original License, so that the 100 | Copyright Holder may include your modifications in the Standard 101 | Version. 102 | 103 | (b) ensure that installation of your Modified Version does not 104 | prevent the user installing or running the Standard Version. In 105 | addition, the Modified Version must bear a name that is different 106 | from the name of the Standard Version. 107 | 108 | (c) allow anyone who receives a copy of the Modified Version to 109 | make the Source form of the Modified Version available to others 110 | under 111 | 112 | (i) the Original License or 113 | 114 | (ii) a license that permits the licensee to freely copy, 115 | modify and redistribute the Modified Version using the same 116 | licensing terms that apply to the copy that the licensee 117 | received, and requires that the Source form of the Modified 118 | Version, and of any works derived from it, be made freely 119 | available in that license fees are prohibited but Distributor 120 | Fees are allowed. 121 | 122 | 123 | Distribution of Compiled Forms of the Standard Version 124 | or Modified Versions without the Source 125 | 126 | (5) You may Distribute Compiled forms of the Standard Version without 127 | the Source, provided that you include complete instructions on how to 128 | get the Source of the Standard Version. Such instructions must be 129 | valid at the time of your distribution. If these instructions, at any 130 | time while you are carrying out such distribution, become invalid, you 131 | must provide new instructions on demand or cease further distribution. 132 | If you provide valid instructions or cease distribution within thirty 133 | days after you become aware that the instructions are invalid, then 134 | you do not forfeit any of your rights under this license. 135 | 136 | (6) You may Distribute a Modified Version in Compiled form without 137 | the Source, provided that you comply with Section 4 with respect to 138 | the Source of the Modified Version. 139 | 140 | 141 | Aggregating or Linking the Package 142 | 143 | (7) You may aggregate the Package (either the Standard Version or 144 | Modified Version) with other packages and Distribute the resulting 145 | aggregation provided that you do not charge a licensing fee for the 146 | Package. Distributor Fees are permitted, and licensing fees for other 147 | components in the aggregation are permitted. The terms of this license 148 | apply to the use and Distribution of the Standard or Modified Versions 149 | as included in the aggregation. 150 | 151 | (8) You are permitted to link Modified and Standard Versions with 152 | other works, to embed the Package in a larger work of your own, or to 153 | build stand-alone binary or bytecode versions of applications that 154 | include the Package, and Distribute the result without restriction, 155 | provided the result does not expose a direct interface to the Package. 156 | 157 | 158 | Items That are Not Considered Part of a Modified Version 159 | 160 | (9) Works (including, but not limited to, modules and scripts) that 161 | merely extend or make use of the Package, do not, by themselves, cause 162 | the Package to be a Modified Version. In addition, such works are not 163 | considered parts of the Package itself, and are not subject to the 164 | terms of this license. 165 | 166 | 167 | General Provisions 168 | 169 | (10) Any use, modification, and distribution of the Standard or 170 | Modified Versions is governed by this Artistic License. By using, 171 | modifying or distributing the Package, you accept this license. Do not 172 | use, modify, or distribute the Package, if you do not accept this 173 | license. 174 | 175 | (11) If your Modified Version has been derived from a Modified 176 | Version made by someone other than you, you are nevertheless required 177 | to ensure that your Modified Version complies with the requirements of 178 | this license. 179 | 180 | (12) This license does not grant you the right to use any trademark, 181 | service mark, tradename, or logo of the Copyright Holder. 182 | 183 | (13) This license includes the non-exclusive, worldwide, 184 | free-of-charge patent license to make, have made, use, offer to sell, 185 | sell, import and otherwise transfer the Package with respect to any 186 | patent claims licensable by the Copyright Holder that are necessarily 187 | infringed by the Package. If you institute patent litigation 188 | (including a cross-claim or counterclaim) against any party alleging 189 | that the Package constitutes direct or contributory patent 190 | infringement, then this Artistic License to you shall terminate on the 191 | date that such litigation is filed. 192 | 193 | (14) Disclaimer of Warranty: 194 | THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS 195 | IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED 196 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR 197 | NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL 198 | LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL 199 | BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 200 | DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF 201 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 202 | 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Video.js Documentation 2 | 3 | This repository is the home of the [Video.js Docs](http://docs.videojs.com/) 4 | 5 | This repo contains a grunt process that clones the video.js repo and generates the documentation: 6 | 7 | * Guides are copied and converted from markdown to html 8 | * Examples are copied 9 | * API docs are generated from the video.js source code comments 10 | 11 | ## Information on the grunt process 12 | 13 | * Dependencies: in the top level directory, run: 14 | `npm install` 15 | 16 | View the package to see what the dependencies are. 17 | 18 | * The plugins are the standard JSDoc plugins EXCEPT **commentsOnly.js**. This creates the files from which the docs are actually built. The plugin has been modified to leave blank lines where actual code exists in the source instead of removing all non-comment lines. 19 | * The **createFiles** task unconditionally overwrites existing files, which is intended. 20 | * The **Gruntfile.js** can be executed by simply using **grunt** at the command line. 21 | 22 | ## Contributing 23 | 24 | **No content is edited here.** If you want to add or make corrections to the content, do that in [https://github.com/videojs/video.js] and then enter an issue here to regenerate the docs. If you want to enhance or fix the doc generation process, fork this repo and send a pull request. 25 | 26 | Pull requests are welcome against the `master` branch. Merges into the `gh-pages` branch, from which the docs are served, will happen periodically. 27 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | exclude: [CNAME, README, plugins, conf.json, Gruntfile.js, semicolon.txt, var-name.txt] 2 | -------------------------------------------------------------------------------- /conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": { 3 | "allowUnknownTags": true 4 | }, 5 | "source": { 6 | "includePattern": ".+\\.js(doc)?$", 7 | "excludePattern": "(^|\\/|\\\\)_" 8 | }, 9 | "plugins": ["plugins/commentsOnly", "plugins/markdown"], 10 | "opts": { 11 | "explain": true, 12 | "recurse": true 13 | }, 14 | "templates": { 15 | "cleverLinks": false, 16 | "monospaceLinks": false, 17 | "default": { 18 | "outputSourceFiles": true 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /docs/api/assets/api-doc-template-min.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/api/assets/api-doc-template.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/api/assets/create-doc-files-test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 |

Check the console for results

12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /docs/api/assets/create-doc-files.js: -------------------------------------------------------------------------------- 1 | /** 2 | * get a subset of objects in array of objects 3 | * based on some property value 4 | * 5 | * @param {array} targetArray - array to search 6 | * @param {string} objProperty - object property to search 7 | * @param {string|number} value - value of the property to search for 8 | * @return {array} array of objects with matching property value 9 | */ 10 | function getSubArray(targetArray, objProperty, value) { 11 | var i, totalItems = targetArray.length, idxArr = []; 12 | for (i = 0; i < totalItems; i++) { 13 | if (targetArray[i][objProperty] === value) { 14 | idxArr.push(targetArray[i]); 15 | } 16 | } 17 | return idxArr; 18 | } 19 | 20 | /** 21 | * create the HTML files for the classes 22 | * @param {array} filenameArray - array of the filenames 23 | */ 24 | function createFiles(filenameArray) { 25 | var i, 26 | iMax = filenameArray.length, 27 | filename, 28 | contentStr = ' '; 29 | for (i = 0; i < iMax; i++) { 30 | filename = filenameArray[i]; 31 | // create file with name=filename and contents=contentStr 32 | } 33 | } 34 | 35 | function createFilenameArray(classData) { 36 | var filenameArray = [], 37 | i, 38 | iMax = classData.length, 39 | item, 40 | str; 41 | // extract the filenames from the class items 42 | for (i = 0; i < iMax; i++) { 43 | item = classData[i]; 44 | str = item.meta.filename; 45 | str = str.substr(str.lastIndexOf('/') + 1); 46 | str = str.replace('.js', '.html'); 47 | filenameArray.push(str); 48 | } 49 | // videojs is special case 50 | filenameArray.push('video.html'); 51 | filenameArray = filenameArray.sort(); 52 | console.log('filenameArray', filenameArray); 53 | // now create the files 54 | createFiles(filenameArray); 55 | } 56 | /** 57 | * extracts class items from doc data 58 | * @param {array} docData JSON output from JSDoc 59 | */ 60 | function getClassData(docData) { 61 | var classData = []; 62 | // extract the class items from the doc data 63 | classData = getSubArray(docData, 'kind', 'class'); 64 | // now create the array of filenames 65 | createFilenameArray(classData); 66 | } 67 | 68 | getClassData(docData); -------------------------------------------------------------------------------- /docs/api/captions-track.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/api/chapters-track.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/api/close-button.html: -------------------------------------------------------------------------------- 1 | CloseButton

API Index

Inherited Methods from Button

Inherited Methods from ClickableComponent

Inherited Methods from Component

CloseButton

The CloseButton component is a button which fires a "close" event 4 | when it is activated.

DEFINED IN: close-button.js line number: 4

EXTENDS: button.js

Constructor

CloseButton()
-------------------------------------------------------------------------------- /docs/api/css/api-docs.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #333; 3 | margin: 6em; 4 | margin-top: 4em; 5 | margin-right: 3em; 6 | font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; 7 | } 8 | 9 | @media (max-width: 700px) { 10 | .member-index { 11 | display: none; 12 | } 13 | .side-nav { 14 | float: none; 15 | } 16 | } 17 | 18 | a { 19 | color: #437ABE; 20 | text-decoration: none; 21 | } 22 | 23 | a:hover { 24 | text-decoration: underline; 25 | } 26 | 27 | h1, h2, h3 { 28 | margin-left: -1em; 29 | } 30 | 31 | h1 { 32 | border-bottom: 1px #CCC solid; 33 | font-size: 2.5em; 34 | } 35 | h2 { 36 | border-bottom: 1px #DDD solid; 37 | font-size: 2em; 38 | } 39 | 40 | h3 { 41 | font-size: 1.5em; 42 | } 43 | 44 | #memberIndex h4 { 45 | font-size: 1em; 46 | font-weight: normal; 47 | font-style: italic; 48 | } 49 | 50 | div { 51 | border-bottom: 1px #DDD solid; 52 | font-size: 1em; 53 | } 54 | 55 | pre { 56 | background-color: #F4F3EC; 57 | font-size: .8em; 58 | margin-bottom: 1.3rem; 59 | padding: .5rem; 60 | padding-left: 1rem; 61 | margin-top: 1rem; 62 | border-left: 5px solid rgb(99,99,99); 63 | -webkit-box-shadow: 5px 5px 10px rgba(192, 192, 192, 1.000); 64 | -moz-box-shadow: 5px 5px 10px rgba(192, 192, 192, 1.000); 65 | box-shadow: 5px 5px 10px rgba(192, 192, 192, 1.000); 66 | } 67 | code { 68 | font-size: 1em; 69 | font-family: source-code-pro, Monaco, Consolas, Menlo, "Lucida Console", monospace; 70 | border: none; 71 | } 72 | 73 | table { 74 | border-collapse: collapse; 75 | border: 1px #CCC solid; 76 | padding: 0; 77 | } 78 | 79 | 80 | th { 81 | background-color: #F4F3EC; 82 | border: 1px #CCC solid; 83 | margin: 0; 84 | padding: .5em; 85 | } 86 | 87 | td { 88 | border: 1px #DDD solid; 89 | margin: 0; 90 | padding: .5em; 91 | } 92 | 93 | .side-nav { 94 | float: right; 95 | width: 15%; 96 | padding-left: 3em; 97 | margin-left: 2em; 98 | margin-right: 1em; 99 | border: none; 100 | } 101 | .side-nav div { 102 | border: none; 103 | } 104 | 105 | .side-nav h2, .side-nav h3 { 106 | margin-left: 0; 107 | } 108 | #main { 109 | width: 70%; 110 | } 111 | 112 | div.section { 113 | border: none; 114 | } 115 | .description { 116 | border: none; 117 | } 118 | 119 | .deprecated { 120 | color: #990000; 121 | } -------------------------------------------------------------------------------- /docs/api/css/api-index.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #333; 3 | margin: 6em; 4 | font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; 5 | } 6 | 7 | a { 8 | color: #437ABE; 9 | text-decoration: none; 10 | } 11 | 12 | a:hover { 13 | text-decoration: underline; 14 | } 15 | 16 | h1, h2, h3 { 17 | margin-left: -1em; 18 | } 19 | 20 | h1 { 21 | border-bottom: 1px #CCC solid; 22 | font-size: 2.5em; 23 | } 24 | h2 { 25 | font-size: 2em; 26 | } 27 | 28 | h3 { 29 | font-size: 1.5em; 30 | } 31 | #top { 32 | border: none; 33 | } 34 | div.indexColumn { 35 | display: inline-block; 36 | width: 30%; 37 | vertical-align: top; 38 | } 39 | 40 | @media (max-width: 700px) { 41 | div.indexColumn { 42 | display: block; 43 | width: 100%; 44 | vertical-align: top; 45 | } 46 | 47 | 48 | .indexHeader { 49 | padding-left: 3em; 50 | } 51 | div, .section { 52 | border: none; 53 | } -------------------------------------------------------------------------------- /docs/api/fullscreen-toggle.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "comment": "/**\n * Toggle fullscreen video\n * @param {Player|Object} player\n * @param {Object=} options\n * @extends Button\n * @class FullScreenToggle\n */", 4 | "meta": { 5 | "range": [ 6 | 0, 7 | 141 8 | ], 9 | "filename": "fullscreen-toggle.js", 10 | "lineno": 1, 11 | "path": "/Users/mboles/git/BCL-LearningSamples/jsdoc-tests2", 12 | "code": {} 13 | }, 14 | "description": "

Toggle fullscreen video

", 15 | "params": [ 16 | { 17 | "type": { 18 | "names": [ 19 | "Player", 20 | "Object" 21 | ] 22 | }, 23 | "name": "player" 24 | }, 25 | { 26 | "type": { 27 | "names": [ 28 | "Object" 29 | ] 30 | }, 31 | "optional": true, 32 | "name": "options" 33 | } 34 | ], 35 | "augments": [ 36 | "Button" 37 | ], 38 | "kind": "class", 39 | "name": "FullScreenToggle", 40 | "longname": "FullScreenToggle", 41 | "scope": "global" 42 | }, 43 | { 44 | "comment": "/**\n * Allows sub components to stack CSS class names\n * @return {String}\n * @method buildCSSClass\n */", 45 | "meta": { 46 | "range": [ 47 | 143, 48 | 249 49 | ], 50 | "filename": "fullscreen-toggle.js", 51 | "lineno": 9, 52 | "path": "/Users/mboles/git/BCL-LearningSamples/jsdoc-tests2", 53 | "code": {} 54 | }, 55 | "description": "

Allows sub components to stack CSS class names

", 56 | "returns": [ 57 | { 58 | "type": { 59 | "names": [ 60 | "String" 61 | ] 62 | } 63 | } 64 | ], 65 | "kind": "function", 66 | "name": "buildCSSClass", 67 | "longname": "buildCSSClass", 68 | "scope": "global" 69 | }, 70 | { 71 | "comment": "/**\n * Handles the click\n * @method handleClick\n */", 72 | "meta": { 73 | "range": [ 74 | 251, 75 | 305 76 | ], 77 | "filename": "fullscreen-toggle.js", 78 | "lineno": 15, 79 | "path": "/Users/mboles/git/BCL-LearningSamples/jsdoc-tests2", 80 | "code": {} 81 | }, 82 | "description": "

Handles the click

", 83 | "kind": "function", 84 | "name": "handleClick", 85 | "longname": "handleClick", 86 | "scope": "global" 87 | }, 88 | { 89 | "kind": "package", 90 | "longname": "package:undefined", 91 | "files": [ 92 | "/Users/mboles/git/BCL-LearningSamples/jsdoc-tests2/fullscreen-toggle.js" 93 | ] 94 | } 95 | ] 96 | -------------------------------------------------------------------------------- /docs/api/html-track-element.html: -------------------------------------------------------------------------------- 1 | HTMLTrackElement

API Index

Inherited Methods from Button

Inherited Methods from ClickableComponent

Inherited Methods from Component

HTMLTrackElement

https://html.spec.whatwg.org/multipage/embedded-content.html#htmltrackelement

4 |

interface HTMLTrackElement : HTMLElement { 5 | attribute DOMString kind; 6 | attribute DOMString src; 7 | attribute DOMString srclang; 8 | attribute DOMString label; 9 | attribute boolean default;

10 |

const unsigned short NONE = 0; 11 | const unsigned short LOADING = 1; 12 | const unsigned short LOADED = 2; 13 | const unsigned short ERROR = 3; 14 | readonly attribute unsigned short readyState;

15 |

readonly attribute TextTrack track; 16 | };

DEFINED IN: html-track-element.js line number: 15

EXTENDS: button.js

Constructor

HTMLTrackElement( options )

Parameters

nameTypeRequiredDescription
optionsObjectyesTextTrack configuration
-------------------------------------------------------------------------------- /docs/api/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/api/js/api-index.js: -------------------------------------------------------------------------------- 1 | var BCLSVJS = (function (window, document, docData) { 2 | 'use strict'; 3 | var title = document.getElementsByTagName('title')[0], 4 | // data structures 5 | classes = [], 6 | // elements 7 | main, 8 | doc_body = document.getElementsByTagName('body')[0], 9 | // functions 10 | isDefined, 11 | findObjectsInArray, 12 | getSubArray, 13 | sortArray, 14 | createEl, 15 | bclslog, 16 | addHeaderContent, 17 | addIndex, 18 | init; 19 | /** 20 | * Logging function - safe for IE 21 | * @param {string} context - description of the data 22 | * @param {*} message - the data to be logged by the console 23 | * @return {} 24 | */ 25 | bclslog = function (context, message) { 26 | if (window['console'] && console['log']) { 27 | console.log(context, message); 28 | } 29 | return; 30 | }; 31 | /** 32 | * tests for all the ways a variable might be undefined or not have a value 33 | * @param {*} x the variable to test 34 | * @return {Boolean} true if variable is defined and has a value 35 | */ 36 | isDefined = function (x) { 37 | if (x !== '' && x !== null && x !== undefined && x !== NaN) { 38 | return true; 39 | } 40 | return false; 41 | }; 42 | /** 43 | * find indexes of a set of object in array of objects 44 | * based on some property value 45 | * generally useful for finding several objects 46 | * 47 | * @param {array} targetArray - array to search 48 | * @param {string} objProperty - object property to search 49 | * @param {string|number} value - value of the property to search for 50 | * @return {array} array of indexes for matching objects 51 | */ 52 | findObjectsInArray = function (targetArray, objProperty, value) { 53 | var i, totalItems = targetArray.length, newArr = []; 54 | for (i = 0; i < totalItems; i++) { 55 | if (targetArray[i][objProperty] === value) { 56 | newArr.push(i); 57 | } 58 | } 59 | return newArr; 60 | }; 61 | /** 62 | * get a subset of objects in array of objects 63 | * based on some property value 64 | * 65 | * @param {array} targetArray - array to search 66 | * @param {string} objProperty - object property to search 67 | * @param {string|number} value - value of the property to search for 68 | * @return {array} array of objects with matching property value 69 | */ 70 | getSubArray = function (targetArray, objProperty, value) { 71 | var i, totalItems = targetArray.length, idxArr = []; 72 | for (i = 0; i < totalItems; i++) { 73 | if (targetArray[i][objProperty] === value) { 74 | idxArr.push(targetArray[i]); 75 | } 76 | } 77 | return idxArr; 78 | }; 79 | /** 80 | * sort an array of objects based on an object property 81 | * @param {array} targetArray - array to sort 82 | * @param {string} objProperty - property whose value to sort on 83 | * @return {array} the sorted array 84 | */ 85 | sortArray = function (targetArray, objProperty) { 86 | targetArray.sort(function (a, b) { 87 | var propA = a[objProperty].toLowerCase(), propB = b[objProperty].toLowerCase(); 88 | // sort ascending; reverse propA and propB to sort descending 89 | if (propA < propB) { 90 | return -1; 91 | } else if (propA > propB) { 92 | return 1; 93 | } 94 | return 0; 95 | }); 96 | return targetArray; 97 | }; 98 | /** 99 | * create an element 100 | * @param {string} type - the element type 101 | * @param {object} attributes - attributes to add to the element 102 | * @return {object} the HTML element 103 | */ 104 | createEl = function (type, attributes) { 105 | var el; 106 | if (isDefined(type)) { 107 | el = document.createElement(type); 108 | if (isDefined(attributes)) { 109 | var attr; 110 | for (attr in attributes) { 111 | el.setAttribute(attr, attributes[attr]); 112 | } 113 | } 114 | return el; 115 | } 116 | }; 117 | /** 118 | * add the class header content 119 | */ 120 | addHeaderContent = function () { 121 | var doc_body = document.getElementsByTagName('body')[0], 122 | mainContent = createEl('div', {id: 'main'}), 123 | topSection = createEl('section', {id: 'top', class: 'section'}), 124 | mainLink = createEl('a', {href: '//docs.videojs.com/', style: 'float:right;font-weight:bold;margin-top:-3em;background-color:#ECEEF1;padding:2px 4px;'}), 125 | header = createEl('h1'), 126 | text = document.createTextNode('video.js API Documentation Index'), 127 | topP, 128 | topPtext, 129 | topLink, 130 | topLinkStrong; 131 | // add elements 132 | mainLink.appendChild(document.createTextNode('Documentation Home')); 133 | topSection.appendChild(mainLink); 134 | header.appendChild(text); 135 | topSection.appendChild(header); 136 | // add paragraph for videojs function 137 | topP = createEl('p'); 138 | topPtext = document.createTextNode('If you are new to video.js, look first at '); 139 | topP.appendChild(topPtext); 140 | topLink = createEl('a', {href: 'video.html'}); 141 | topP.appendChild(topLink); 142 | topPtext = document.createTextNode('videojs'); 143 | topLinkStrong = createEl('strong'); 144 | topLink.appendChild(topLinkStrong); 145 | topLinkStrong.appendChild(topPtext); 146 | topPtext = document.createTextNode(', which Doubles as the main function for users to create a player instance and also the main library object.'); 147 | topP.appendChild(topPtext); 148 | topSection.appendChild(topP); 149 | // add paragraph for the player class 150 | topP = createEl('p'); 151 | topPtext = document.createTextNode('Next, look at the '); 152 | topP.appendChild(topPtext); 153 | topLink = createEl('a', {href: 'player.html'}); 154 | topP.appendChild(topLink); 155 | topPtext = document.createTextNode('player'); 156 | topLinkStrong = createEl('strong'); 157 | topLink.appendChild(topLinkStrong); 158 | topLinkStrong.appendChild(topPtext); 159 | topPtext = document.createTextNode(' class. An instance of the Player class is created when any of the Video.js setup methods are used to initialize a video. The methods and events of the player object are the most commonly used for managing the player and playback.'); 160 | topP.appendChild(topPtext); 161 | topSection.appendChild(topP); 162 | // add the top section to the document 163 | mainContent.appendChild(topSection); 164 | doc_body.appendChild(mainContent); 165 | main = document.getElementById('main'); 166 | }; 167 | /** 168 | * add the side nav 169 | */ 170 | addIndex = function () { 171 | var section = createEl('section', {id: 'index', class: 'section'}), 172 | sectionHeader = createEl('h2'), 173 | classlists = {}, 174 | alphaArr = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'], 175 | firstLetter, 176 | numberAlphaItems = 0, 177 | itemsPerColumn, 178 | columnDiv, 179 | item, 180 | indexEls = [], 181 | indexListHolder, 182 | indexList, 183 | indexListHeader, 184 | listItem, 185 | listLink, 186 | listText, 187 | text, 188 | i, 189 | iMax, 190 | j, 191 | jMax, 192 | counter = 0; 193 | text = document.createTextNode('Index of classes'); 194 | sectionHeader.appendChild(text); 195 | // create alpha arrays 196 | iMax = classes.length; 197 | for (i = 0; i < iMax; i++) { 198 | item = classes[i]; 199 | firstLetter = item.name.charAt(0).toLowerCase(); 200 | // create alpha array if non-existent, push item 201 | if (isDefined(classlists[firstLetter]) === false) { 202 | classlists[firstLetter] = []; 203 | numberAlphaItems++; 204 | } 205 | classlists[firstLetter].push({name: item.name, filename: item.meta.filename}); 206 | } 207 | itemsPerColumn = Math.ceil(numberAlphaItems / 3); 208 | bclslog('classlists', classlists); 209 | iMax = alphaArr.length; 210 | for (i = 0; i < iMax; i++) { 211 | if (isDefined(classlists[alphaArr[i]])) { 212 | indexListHolder = createEl('div'); 213 | indexListHeader = createEl('h4', {class: 'indexHeader'}); 214 | text = document.createTextNode('~' + alphaArr[i].toUpperCase() + '~'); 215 | indexListHeader.appendChild(text); 216 | indexListHolder.appendChild(indexListHeader); 217 | indexList = createEl('ul'); 218 | indexListHolder.appendChild(indexList); 219 | jMax = classlists[alphaArr[i]].length; 220 | bclslog('jMax', jMax); 221 | for (j = 0; j < jMax; j++) { 222 | bclslog('classlists[alphaArr[i]', classlists[alphaArr[i]]); 223 | listItem = createEl('li'); 224 | indexList.appendChild(listItem); 225 | listLink = createEl('a', {href: classlists[alphaArr[i]][j].filename.replace('.js', '.html')}); 226 | listItem.appendChild(listLink); 227 | listText = document.createTextNode(classlists[alphaArr[i]][j].name); 228 | listLink.appendChild(listText); 229 | } 230 | indexEls.push(indexListHolder); 231 | } 232 | } 233 | section.appendChild(sectionHeader); 234 | iMax = indexEls.length; 235 | for (i = 0; i < iMax; i++) { 236 | if (counter > itemsPerColumn) { 237 | counter = 0; 238 | } 239 | if (counter === 0) { 240 | columnDiv = createEl('div', {class: 'indexColumn'}); 241 | section.appendChild(columnDiv); 242 | } 243 | columnDiv.appendChild(indexEls[i]); 244 | } 245 | main.appendChild(section); 246 | }; 247 | /** 248 | * init gets things going 249 | */ 250 | init = function () { 251 | var privateItems = [], 252 | videojs = {name: 'videojs', meta: {filename: 'video.js'}}, 253 | j; 254 | // get the data objects for all classes 255 | classes = getSubArray(docData, 'kind', 'class'); 256 | // videojs is a special case 257 | classes.push(videojs); 258 | bclslog('classes', classes); 259 | // set the doc title 260 | title.innerHTML = 'API Documentation Index'; 261 | // remove any private items 262 | privateItems = findObjectsInArray(classes, 'access', 'private'); 263 | bclslog('privateItems', privateItems); 264 | j = privateItems.length; 265 | bclslog('j', j); 266 | while (j > 0) { 267 | j--; 268 | classes.splice(privateItems[j], 1); 269 | } 270 | // sort the array 271 | classes = sortArray(classes, 'name'); 272 | bclslog('classes', classes); 273 | // now we're ready to roll 274 | addHeaderContent(); 275 | addIndex(); 276 | }; 277 | init(); 278 | return { 279 | 280 | }; 281 | })(window, document, docData); -------------------------------------------------------------------------------- /docs/api/js/highlight-syntax.js: -------------------------------------------------------------------------------- 1 | BCLSHighlighter = (function(hljs) { 2 | var codeBlocks = document.querySelectorAll('pre>code'), 3 | i, 4 | iMax, 5 | txt, 6 | reLT = new RegExp('<', 'g'), 7 | reGT = new RegExp('>;', 'g'); 8 | 9 | /** 10 | * tests for all the ways a variable might be undefined or not have a value 11 | * @param {*} x the variable to test 12 | * @return {Boolean} true if variable is defined and has a value 13 | */ 14 | function isDefined(x) { 15 | if (x === '' || x === null || x === undefined || x === NaN) { 16 | return false; 17 | } 18 | return true; 19 | }; 20 | 21 | if (isDefined(codeBlocks)) { 22 | iMax = codeBlocks.length; 23 | for (i = 0; i < iMax; i++) { 24 | txt = codeBlocks[i].innerHTML.toString(); 25 | txt = txt.replace(reLT, '<'); 26 | txt = txt.replace(reGT, '>'); 27 | codeBlocks[i].innerHTML = txt; 28 | hljs.highlightBlock(codeBlocks[i]); 29 | } 30 | } 31 | })(hljs); -------------------------------------------------------------------------------- /docs/api/loader.html: -------------------------------------------------------------------------------- 1 | MediaLoader

API Index

Inherited Methods from Component

MediaLoader

The Media Loader is the component that decides which playback technology to load 4 | when the player is initialized.

DEFINED IN: loader.js line number: 9

EXTENDS: component.js

Constructor

MediaLoader( player,[options],[ready] )

Parameters

nameTypeRequiredDescription
playerObjectyesMain Player
optionsObjectnoObject of option names and values
readyfunctionnoReady callback function
-------------------------------------------------------------------------------- /docs/api/md.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/api/seekhandle.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/api/subtitlestrack.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/api/text-track-button.html: -------------------------------------------------------------------------------- 1 | TextTrackButton

API Index

Inherited Methods from MenuButton

Inherited Methods from Button

Inherited Methods from ClickableComponent

Inherited Methods from Component

TextTrackButton

The base class for buttons that toggle specific text track types (e.g. subtitles)

DEFINED IN: text-track-button.js line number: 10

EXTENDS: menu-button.js

Constructor

TextTrackButton( player,[options] )

Parameters

nameTypeRequiredDescription
playerPlayer|Object
optionsObject
-------------------------------------------------------------------------------- /docs/api/texttrack.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/css/guides.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #333; 3 | /*margin: 6em;*/ 4 | margin-top: 2em; 5 | margin-right: 3em; 6 | margin-left: 1em; 7 | font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; 8 | position: relative; 9 | } 10 | 11 | .sidenav { 12 | position: fixed; 13 | height: 100%; 14 | right: 1em; 15 | max-width: 18%; 16 | display: inline-block; 17 | font-size: .7em; 18 | border: none; 19 | border-left: 1px solid #DDD; 20 | } 21 | 22 | .sidenav-list { 23 | list-style-type: none; 24 | } 25 | .sidenav-list>li { 26 | margin-bottom: .6em; 27 | } 28 | .main { 29 | position: absolute; 30 | right: 25%; 31 | padding-bottom: 40px; 32 | display: inline-block; 33 | max-width: 70%; 34 | } 35 | .footer { 36 | bottom: 0; 37 | right: 0; 38 | left: 0; 39 | position: fixed; 40 | width: 100%; 41 | text-align: center; 42 | padding: .2em; 43 | background-color: #EEE; 44 | } 45 | 46 | @media (max-width: 700px) { 47 | .member-index { 48 | display: none; 49 | } 50 | .side-nav { 51 | float: none; 52 | } 53 | } 54 | 55 | a { 56 | color: #437ABE; 57 | text-decoration: none; 58 | } 59 | 60 | a:hover { 61 | text-decoration: underline; 62 | } 63 | 64 | h1, h2, h3 { 65 | margin-left: -1em; 66 | } 67 | 68 | h1 { 69 | border-bottom: 1px #CCC solid; 70 | font-size: 2.5em; 71 | } 72 | h2 { 73 | border-bottom: 1px #DDD solid; 74 | font-size: 1.5em; 75 | } 76 | 77 | h3 { 78 | font-size: 1.5em; 79 | } 80 | 81 | #memberIndex h4 { 82 | font-size: 1em; 83 | font-weight: normal; 84 | font-style: italic; 85 | } 86 | 87 | div { 88 | border-bottom: 1px #DDD solid; 89 | font-size: 1em; 90 | } 91 | 92 | pre { 93 | background-color: #FDF6E3; 94 | font-size: .8em; 95 | margin-bottom: 1.3rem; 96 | padding: .5rem; 97 | padding-left: 1rem; 98 | margin-top: 1rem; 99 | border-left: 5px solid rgb(99,99,99); 100 | -webkit-box-shadow: 5px 5px 10px rgba(192, 192, 192, 1.000); 101 | -moz-box-shadow: 5px 5px 10px rgba(192, 192, 192, 1.000); 102 | box-shadow: 5px 5px 10px rgba(192, 192, 192, 1.000); 103 | } 104 | code { 105 | font-size: 1em; 106 | font-family: source-code-pro, Monaco, Consolas, Menlo, "Lucida Console", monospace; 107 | border: none; 108 | } 109 | 110 | table { 111 | border-collapse: collapse; 112 | border: 1px #CCC solid; 113 | padding: 0; 114 | } 115 | 116 | 117 | th { 118 | background-color: #F4F3EC; 119 | border: 1px #CCC solid; 120 | margin: 0; 121 | padding: .5em; 122 | } 123 | 124 | td { 125 | border: 1px #DDD solid; 126 | margin: 0; 127 | padding: .5em; 128 | } 129 | 130 | .side-nav { 131 | float: right; 132 | width: 15%; 133 | padding-left: 3em; 134 | margin-left: 2em; 135 | margin-right: 1em; 136 | border: none; 137 | } 138 | .side-nav div { 139 | border: none; 140 | } 141 | 142 | .side-nav h2, .side-nav h3 { 143 | margin-left: 0; 144 | } 145 | #main { 146 | width: 70%; 147 | } 148 | 149 | div.section { 150 | border: none; 151 | } 152 | .description { 153 | border: none; 154 | } 155 | 156 | .deprecated { 157 | color: #990000; 158 | } -------------------------------------------------------------------------------- /docs/examples/elephantsdream/captions.ar.vtt: -------------------------------------------------------------------------------- 1 | WEBVTT 2 | 3 | 1 4 | 00:00:15.042 --> 00:00:18.625 5 | ...إلى... إلى الشمال يمكن أن نرى 6 | ...يمكن أن نرى الـ 7 | 8 | 2 9 | 00:00:18.750 --> 00:00:20.958 10 | ...إلى اليمين يمكن أن نرى الـ 11 | 12 | 3 13 | 00:00:21.000 --> 00:00:23.125 14 | طاحنات الرؤوس... 15 | 16 | 4 17 | 00:00:23.208 --> 00:00:25.208 18 | كل شيئ آمن 19 | آمن كلية 20 | 21 | 5 22 | 00:00:26.333 --> 00:00:28.333 23 | إيمو ؟ 24 | 25 | 6 26 | 00:00:28.875 --> 00:00:30.958 27 | ! حذاري 28 | 29 | 7 30 | 00:00:47.125 --> 00:00:49.167 31 | هل أصبت ؟ 32 | 33 | 8 34 | 00:00:52.125 --> 00:00:54.833 35 | ...لا أظن ذلك 36 | وأنت ؟ 37 | 38 | 9 39 | 00:00:55.625 --> 00:00:57.625 40 | أنا بخير 41 | 42 | 10 43 | 00:00:57.667 --> 00:01:01.667 44 | ،قم يا إيمو 45 | المكان هنا غير آمن 46 | 47 | 11 48 | 00:01:02.208 --> 00:01:04.083 49 | لنذهب 50 | 51 | 12 52 | 00:01:04.167 --> 00:01:06.167 53 | وماذا بعد ؟ 54 | 55 | 13 56 | 00:01:06.167 --> 00:01:08.583 57 | ...سترى... سترى 58 | 59 | 14 60 | 00:01:16.167 --> 00:01:18.375 61 | إيمو، من هنا 62 | 63 | 15 64 | 00:01:34.958 --> 00:01:37.000 65 | ! إتبعني 66 | 67 | 16 68 | 00:02:11.125 --> 00:02:13.625 69 | ! أسرع يا إيمو 70 | 71 | 17 72 | 00:02:48.375 --> 00:02:50.375 73 | ! لست منتبها 74 | 75 | 18 76 | 00:02:50.750 --> 00:02:54.500 77 | ...أريد فقط أن أجيب الـ 78 | الهاتف... 79 | 80 | 19 81 | 00:02:55.000 --> 00:02:58.500 82 | ،إيمو، أنظر 83 | أقصد أنصت 84 | 85 | 20 86 | 00:02:59.750 --> 00:03:03.292 87 | عليك أن تتعلم الإصغاء 88 | 89 | 21 90 | 00:03:03.625 --> 00:03:05.917 91 | هذا ليس ضربا من اللهو 92 | 93 | 22 94 | 00:03:06.083 --> 00:03:09.958 95 | ...إنك 96 | أقصد إننا قد نموت بسهولة في هذا المكان 97 | 98 | 23 99 | 00:03:10.208 --> 00:03:14.125 100 | ...أنصت 101 | أنصت إلى أصوات الآلة 102 | 103 | 24 104 | 00:03:18.333 --> 00:03:20.417 105 | أنصت إلى نَفَسِك 106 | 107 | 25 108 | 00:04:27.208 --> 00:04:29.250 109 | ألا تمل أبدا من هذا ؟ 110 | 111 | 26 112 | 00:04:29.583 --> 00:04:31.583 113 | أمل ؟!؟ 114 | نعم - 115 | 116 | 27 117 | 00:04:31.750 --> 00:04:34.667 118 | إيمو؛ الآلة في دقتها... مثل الساعة 119 | 120 | 28 121 | 00:04:35.500 --> 00:04:37.708 122 | ...حركة ناشزة واحدة قد 123 | 124 | 29 125 | 00:04:37.833 --> 00:04:39.875 126 | تطرحك معجونا 127 | 128 | 30 129 | 00:04:41.042 --> 00:04:43.083 130 | ...أو ليست 131 | 132 | 31 133 | 00:04:43.125 --> 00:04:46.542 134 | ! عجينة يا إيمو 135 | أ هذا ما تريد ؟ أن تصبح عجينة ؟ 136 | 137 | 32 138 | 00:04:48.083 --> 00:04:50.083 139 | أيمو، أ هذا هدفك في الحياة ؟ 140 | 141 | 33 142 | 00:04:50.583 --> 00:04:52.667 143 | أن تصير عجينة ؟ 144 | 145 | 34 146 | 00:05:41.833 --> 00:05:43.875 147 | إيمو، أغمض عينيك 148 | 149 | 35 150 | 00:05:44.917 --> 00:05:47.000 151 | لماذا ؟ 152 | ! الآن - 153 | 154 | 36 155 | 00:05:53.750 --> 00:05:56.042 156 | حسن 157 | 158 | 37 159 | 00:05:59.542 --> 00:06:02.792 160 | ماذا ترى إلى شمالك يا إيمو ؟ 161 | 162 | 38 163 | 00:06:04.417 --> 00:06:06.500 164 | لا شيئ 165 | حقا ؟ - 166 | 167 | 39 168 | 00:06:06.542 --> 00:06:08.625 169 | لا، لا شيئ البتة 170 | 171 | 40 172 | 00:06:08.625 --> 00:06:12.417 173 | وماذا ترى إلى جهتك اليمنى يا إيمو ؟ 174 | 175 | 41 176 | 00:06:13.667 --> 00:06:17.833 177 | ،نفس الشيئ يا بروغ 178 | ! نفس الشيئ بالضبط؛ لا شيئ 179 | 180 | 42 181 | 00:06:17.875 --> 00:06:19.917 182 | عظيم 183 | 184 | 43 185 | 00:06:40.625 --> 00:06:42.958 186 | أنصت يا بروغ ! هل تسمع ذلك ؟ 187 | 188 | 44 189 | 00:06:43.625 --> 00:06:45.625 190 | هل نستطيع الذهاب إلى هناك ؟ 191 | 192 | 45 193 | 00:06:45.708 --> 00:06:47.792 194 | هناك ؟ 195 | نعم - 196 | 197 | 46 198 | 00:06:47.833 --> 00:06:49.833 199 | إنه غير آمن يا إيمو 200 | 201 | 47 202 | 00:06:49.917 --> 00:06:52.500 203 | صدقني، إنه غير آمن 204 | 205 | 48 206 | 00:06:53.292 --> 00:06:55.375 207 | ...لكن لعلي أستطيع 208 | 209 | 49 210 | 00:06:55.417 --> 00:06:57.417 211 | ...لكن 212 | ! لا - 213 | 214 | 50 215 | 00:06:57.667 --> 00:06:59.667 216 | ! لا 217 | 218 | 51 219 | 00:07:00.875 --> 00:07:03.750 220 | هل من أسئلة أخرى يا إيمو ؟ 221 | 222 | 52 223 | 00:07:04.250 --> 00:07:06.333 224 | لا 225 | 226 | 53 227 | 00:07:09.458 --> 00:07:11.542 228 | ...إيمو 229 | نعم - 230 | 231 | 54 232 | 00:07:11.875 --> 00:07:13.958 233 | ...لماذا يا إيمو... لماذا 234 | 235 | 55 236 | 00:07:15.292 --> 00:07:18.792 237 | لماذا لا تستطيع أن ترى حُسْن هذا المكان 238 | 239 | 56 240 | 00:07:18.833 --> 00:07:20.833 241 | ...والطريقة التي يعمل بها 242 | 243 | 57 244 | 00:07:20.875 --> 00:07:24.000 245 | وكيف... وكيف أنه غاية في الكمال 246 | 247 | 58 248 | 00:07:24.083 --> 00:07:27.417 249 | ! لا يا بروغ، لا أرى ذلك 250 | 251 | 59 252 | 00:07:27.542 --> 00:07:30.333 253 | لا أرى ذلك لأنه لا يوجد شيئ هناك 254 | 255 | 60 256 | 00:07:31.500 --> 00:07:35.333 257 | ثم لماذا يجب علي أن أسلم حياتي 258 | لشيئ لا وجود له ؟ 259 | 260 | 61 261 | 00:07:35.583 --> 00:07:37.625 262 | هل يمكنك أن تخبرني ؟ 263 | 264 | 62 265 | 00:07:37.708 --> 00:07:39.750 266 | ! أجبني 267 | 268 | 63 269 | 00:07:43.208 --> 00:07:47.333 270 | ...بروغ 271 | ! أنت معتوه يا هذا 272 | 273 | 64 274 | 00:07:47.375 --> 00:07:49.417 275 | ! إبعد عني 276 | 277 | 65 278 | 00:07:52.583 --> 00:07:55.083 279 | ! لا يا إيمو ! إنه فخ 280 | 281 | 66 282 | 00:07:55.833 --> 00:07:57.875 283 | ...إنه فخ 284 | 285 | 67 286 | 00:07:57.917 --> 00:08:01.750 287 | إلى جنبك الأيسر يمكنك أن ترى 288 | حدائق بابل المعلقة 289 | 290 | 68 291 | 00:08:02.250 --> 00:08:04.292 292 | هل تعجبك كفخ ؟ 293 | 294 | 69 295 | 00:08:05.458 --> 00:08:07.542 296 | لا يا أيمو 297 | 298 | 70 299 | 00:08:09.417 --> 00:08:12.792 300 | ...إلى جنبك الأيمن يمكنك رؤية 301 | حزر ماذا ؟ 302 | 303 | 71 304 | 00:08:13.000 --> 00:08:15.042 305 | ! عملاق رودس 306 | 307 | 72 308 | 00:08:15.125 --> 00:08:16.417 309 | ! لا 310 | 311 | 73 312 | 00:08:16.458 --> 00:08:20.500 313 | ،عملاق رودس 314 | وهو هنا خصيصا من أجلك يا بروغ 315 | 316 | 74 317 | 00:08:20.583 --> 00:08:22.583 318 | فقط من أجلك 319 | 320 | 75 321 | 00:08:51.333 --> 00:08:53.375 322 | إنه هناك 323 | 324 | 76 325 | 00:08:53.417 --> 00:08:55.500 326 | أنا أؤكد لك... إيمو 327 | 328 | 77 329 | 00:08:57.333 --> 00:09:00.000 330 | ...إنه 331 | -------------------------------------------------------------------------------- /docs/examples/elephantsdream/captions.en.vtt: -------------------------------------------------------------------------------- 1 | WEBVTT 2 | 3 | 1 4 | 00:00:15.000 --> 00:00:17.951 5 | At the left we can see... 6 | 7 | 2 8 | 00:00:18.166 --> 00:00:20.083 9 | At the right we can see the... 10 | 11 | 3 12 | 00:00:20.119 --> 00:00:21.962 13 | ...the head-snarlers 14 | 15 | 4 16 | 00:00:21.999 --> 00:00:24.368 17 | Everything is safe. 18 | Perfectly safe. 19 | 20 | 5 21 | 00:00:24.582 --> 00:00:27.035 22 | Emo? 23 | 24 | 6 25 | 00:00:28.206 --> 00:00:29.996 26 | Watch out! 27 | 28 | 7 29 | 00:00:47.037 --> 00:00:48.494 30 | Are you hurt? 31 | 32 | 8 33 | 00:00:51.994 --> 00:00:53.949 34 | I don't think so. 35 | You? 36 | 37 | 9 38 | 00:00:55.160 --> 00:00:56.985 39 | I'm Ok. 40 | 41 | 10 42 | 00:00:57.118 --> 00:01:01.111 43 | Get up. 44 | Emo. it's not safe here. 45 | 46 | 11 47 | 00:01:02.034 --> 00:01:03.573 48 | Let's go. 49 | 50 | 12 51 | 00:01:03.610 --> 00:01:05.114 52 | What's next? 53 | 54 | 13 55 | 00:01:05.200 --> 00:01:09.146 56 | You'll see! 57 | 58 | 14 59 | 00:01:16.032 --> 00:01:18.022 60 | Emo. 61 | This way. 62 | 63 | 15 64 | 00:01:34.237 --> 00:01:35.481 65 | Follow me! 66 | 67 | 16 68 | 00:02:11.106 --> 00:02:12.480 69 | Hurry Emo! 70 | 71 | 17 72 | 00:02:48.059 --> 00:02:49.930 73 | You're not paying attention! 74 | 75 | 18 76 | 00:02:50.142 --> 00:02:54.052 77 | I just want to answer the... 78 | ...phone. 79 | 80 | 19 81 | 00:02:54.974 --> 00:02:57.972 82 | Emo. look. 83 | I mean listen. 84 | 85 | 20 86 | 00:02:59.140 --> 00:03:02.008 87 | You have to learn to listen. 88 | 89 | 21 90 | 00:03:03.140 --> 00:03:04.965 91 | This is not some game. 92 | 93 | 22 94 | 00:03:05.056 --> 00:03:09.345 95 | You. I mean we. 96 | we could easily die out here. 97 | 98 | 23 99 | 00:03:10.014 --> 00:03:13.959 100 | Listen. 101 | listen to the sounds of the machine. 102 | 103 | 24 104 | 00:03:18.054 --> 00:03:20.009 105 | Listen to your breathing. 106 | 107 | 25 108 | 00:04:27.001 --> 00:04:28.956 109 | Well. don't you ever get tired of this? 110 | 111 | 26 112 | 00:04:29.084 --> 00:04:30.909 113 | Tired?!? 114 | 115 | 27 116 | 00:04:31.126 --> 00:04:34.491 117 | Emo. the machine is like clockwork. 118 | 119 | 28 120 | 00:04:35.083 --> 00:04:37.074 121 | One move out of place... 122 | 123 | 29 124 | 00:04:37.166 --> 00:04:39.121 125 | ...and you're ground to a pulp. 126 | 127 | 30 128 | 00:04:40.958 --> 00:04:42.004 129 | But isn't it - 130 | 131 | 31 132 | 00:04:42.041 --> 00:04:46.034 133 | Pulp. Emo! 134 | Is that what you want. pulp? 135 | 136 | 32 137 | 00:04:47.040 --> 00:04:48.995 138 | Emo. your goal in life... 139 | 140 | 33 141 | 00:04:50.081 --> 00:04:51.953 142 | ...pulp? 143 | 144 | 34 145 | 00:05:41.156 --> 00:05:43.028 146 | Emo. close your eyes. 147 | 148 | 35 149 | 00:05:44.156 --> 00:05:46.027 150 | Why? 151 | - Now! 152 | 153 | 36 154 | 00:05:51.155 --> 00:05:52.102 155 | Ok. 156 | 157 | 37 158 | 00:05:53.113 --> 00:05:54.688 159 | Good. 160 | 161 | 38 162 | 00:05:59.070 --> 00:06:02.103 163 | What do you see at your left side. Emo? 164 | 165 | 39 166 | 00:06:04.028 --> 00:06:05.899 167 | Nothing. 168 | - Really? 169 | 170 | 40 171 | 00:06:06.027 --> 00:06:07.105 172 | No. nothing at all. 173 | 174 | 41 175 | 00:06:07.944 --> 00:06:11.984 176 | And at your right. 177 | what do you see at your right side. Emo? 178 | 179 | 42 180 | 00:06:13.151 --> 00:06:16.102 181 | The same Proog. exactly the same... 182 | 183 | 43 184 | 00:06:16.942 --> 00:06:19.098 185 | ...nothing! 186 | - Great. 187 | 188 | 44 189 | 00:06:40.105 --> 00:06:42.724 190 | Listen Proog! Do you hear that! 191 | 192 | 45 193 | 00:06:43.105 --> 00:06:44.894 194 | Can we go here? 195 | 196 | 46 197 | 00:06:44.979 --> 00:06:47.894 198 | There? 199 | It isn't safe. Emo. 200 | 201 | 47 202 | 00:06:49.145 --> 00:06:52.013 203 | But... 204 | - Trust me. it's not. 205 | 206 | 48 207 | 00:06:53.020 --> 00:06:54.145 208 | Maybe I could... 209 | 210 | 49 211 | 00:06:54.181 --> 00:06:55.969 212 | No. 213 | 214 | 50 215 | 00:06:57.102 --> 00:06:59.934 216 | NO! 217 | 218 | 51 219 | 00:07:00.144 --> 00:07:03.058 220 | Any further questions. Emo? 221 | 222 | 52 223 | 00:07:03.976 --> 00:07:05.090 224 | No. 225 | 226 | 53 227 | 00:07:09.059 --> 00:07:10.089 228 | Emo? 229 | 230 | 54 231 | 00:07:11.142 --> 00:07:13.058 232 | Emo. why... 233 | 234 | 55 235 | 00:07:13.095 --> 00:07:14.022 236 | Emo... 237 | 238 | 56 239 | 00:07:14.058 --> 00:07:18.003 240 | ...why can't you see 241 | the beauty of this place? 242 | 243 | 57 244 | 00:07:18.141 --> 00:07:20.048 245 | The way it works. 246 | 247 | 58 248 | 00:07:20.140 --> 00:07:23.895 249 | How perfect it is. 250 | 251 | 59 252 | 00:07:23.932 --> 00:07:26.964 253 | No. Proog. I don't see. 254 | 255 | 60 256 | 00:07:27.056 --> 00:07:29.970 257 | I don't see because there's nothing there. 258 | 259 | 61 260 | 00:07:31.055 --> 00:07:34.965 261 | And why should I trust my 262 | life to something that isn't there? 263 | 264 | 62 265 | 00:07:35.055 --> 00:07:36.926 266 | Well can you tell me that? 267 | 268 | 63 269 | 00:07:37.054 --> 00:07:38.926 270 | Answer me! 271 | 272 | 64 273 | 00:07:42.970 --> 00:07:44.000 274 | Proog... 275 | 276 | 65 277 | 00:07:45.053 --> 00:07:46.985 278 | ...you're a sick man! 279 | 280 | 66 281 | 00:07:47.022 --> 00:07:48.918 282 | Stay away from me! 283 | 284 | 67 285 | 00:07:52.052 --> 00:07:54.884 286 | No! Emo! It's a trap! 287 | 288 | 68 289 | 00:07:55.135 --> 00:07:56.931 290 | Hah. it's a trap. 291 | 292 | 69 293 | 00:07:56.968 --> 00:08:01.043 294 | At the left side you can see 295 | the hanging gardens of Babylon! 296 | 297 | 70 298 | 00:08:01.967 --> 00:08:03.957 299 | How's that for a trap? 300 | 301 | 71 302 | 00:08:05.050 --> 00:08:06.922 303 | No. Emo. 304 | 305 | 72 306 | 00:08:09.008 --> 00:08:12.088 307 | At the right side you can see... 308 | ...well guess what... 309 | 310 | 73 311 | 00:08:12.924 --> 00:08:14.665 312 | ...the colossus of Rhodes! 313 | 314 | 74 315 | 00:08:15.132 --> 00:08:16.053 316 | No! 317 | 318 | 75 319 | 00:08:16.090 --> 00:08:21.919 320 | The colossus of Rhodes 321 | and it is here just for you Proog. 322 | 323 | 76 324 | 00:08:51.001 --> 00:08:52.923 325 | It is there... 326 | 327 | 77 328 | 00:08:52.959 --> 00:08:56.040 329 | I'm telling you. 330 | Emo... 331 | 332 | 78 333 | 00:08:57.000 --> 00:08:59.867 334 | ...it is. -------------------------------------------------------------------------------- /docs/examples/elephantsdream/captions.ja.vtt: -------------------------------------------------------------------------------- 1 | WEBVTT 2 | 3 | 1 4 | 00:00:15.042 --> 00:00:18.042 5 | 左に見えるのは… 6 | 7 | 2 8 | 00:00:18.750 --> 00:00:20.333 9 | 右に見えるのは… 10 | 11 | 3 12 | 00:00:20.417 --> 00:00:21.917 13 | …首刈り機 14 | 15 | 4 16 | 00:00:22.000 --> 00:00:24.625 17 | すべて安全 18 | 完璧に安全だ 19 | 20 | 5 21 | 00:00:26.333 --> 00:00:27.333 22 | イーモ? 23 | 24 | 6 25 | 00:00:28.875 --> 00:00:30.250 26 | 危ない! 27 | 28 | 7 29 | 00:00:47.125 --> 00:00:48.250 30 | ケガはないか? 31 | 32 | 8 33 | 00:00:51.917 --> 00:00:53.917 34 | ええ、多分… 35 | あなたは? 36 | 37 | 9 38 | 00:00:55.625 --> 00:00:57.125 39 | わしは平気だ 40 | 41 | 10 42 | 00:00:57.583 --> 00:01:01.667 43 | 起きてくれイーモ 44 | ここは危ない 45 | 46 | 11 47 | 00:01:02.208 --> 00:01:03.667 48 | 行こう 49 | 50 | 12 51 | 00:01:03.750 --> 00:01:04.917 52 | どこに? 53 | 54 | 13 55 | 00:01:05.875 --> 00:01:07.875 56 | すぐにわかるさ! 57 | 58 | 14 59 | 00:01:16.167 --> 00:01:18.375 60 | イーモ、こっちだ 61 | 62 | 15 63 | 00:01:34.958 --> 00:01:36.958 64 | ついて来るんだ! 65 | 66 | 16 67 | 00:02:11.583 --> 00:02:12.792 68 | イーモ、早く! 69 | 70 | 17 71 | 00:02:48.375 --> 00:02:50.083 72 | むやみにさわるな! 73 | 74 | 18 75 | 00:02:50.750 --> 00:02:54.500 76 | 僕はただ、電話に 77 | …出ようと 78 | 79 | 19 80 | 00:02:55.000 --> 00:02:58.208 81 | イーモ、見るんだ… 82 | いや、聞いてくれ 83 | 84 | 20 85 | 00:02:59.750 --> 00:03:02.292 86 | 君は「聞き方」を知る必要がある 87 | 88 | 21 89 | 00:03:03.625 --> 00:03:05.125 90 | これは遊びじゃない 91 | 92 | 22 93 | 00:03:06.167 --> 00:03:10.417 94 | 我々はここでは 95 | たやすく死ぬ 96 | 97 | 23 98 | 00:03:11.208 --> 00:03:14.125 99 | 機械の声を聞くんだ 100 | 101 | 24 102 | 00:03:18.333 --> 00:03:22.417 103 | 君の息づかいを聞くんだ 104 | 105 | 25 106 | 00:04:27.208 --> 00:04:29.250 107 | そんなことして疲れない? 108 | 109 | 26 110 | 00:04:29.583 --> 00:04:31.083 111 | 疲れる?! 112 | 113 | 27 114 | 00:04:31.750 --> 00:04:34.667 115 | この機械は非常に正確で 116 | 117 | 28 118 | 00:04:35.500 --> 00:04:37.708 119 | 一つ間違えば… 120 | 121 | 29 122 | 00:04:37.833 --> 00:04:40.792 123 | …地面に落ちてバラバラだ 124 | 125 | 30 126 | 00:04:41.042 --> 00:04:42.375 127 | え、でも― 128 | 129 | 31 130 | 00:04:42.417 --> 00:04:46.542 131 | バラバラだぞ、イーモ! 132 | それでいいのか? 133 | 134 | 32 135 | 00:04:48.083 --> 00:04:50.000 136 | バラバラで死ぬんだぞ? 137 | 138 | 33 139 | 00:04:50.583 --> 00:04:52.250 140 | バラバラだ! 141 | 142 | 34 143 | 00:05:41.833 --> 00:05:43.458 144 | イーモ、目を閉じるんだ 145 | 146 | 35 147 | 00:05:44.917 --> 00:05:46.583 148 | なぜ? 149 | ―早く! 150 | 151 | 36 152 | 00:05:53.750 --> 00:05:56.042 153 | それでいい 154 | 155 | 37 156 | 00:05:59.542 --> 00:06:03.792 157 | 左に見えるものは何だ、イーモ? 158 | 159 | 38 160 | 00:06:04.417 --> 00:06:06.000 161 | え…何も 162 | ―本当か? 163 | 164 | 39 165 | 00:06:06.333 --> 00:06:07.917 166 | 全く何も 167 | 168 | 40 169 | 00:06:08.042 --> 00:06:12.833 170 | では右は 171 | 何か見えるか、イーモ? 172 | 173 | 41 174 | 00:06:13.875 --> 00:06:16.917 175 | 同じだよプルーグ、全く同じ… 176 | 177 | 42 178 | 00:06:17.083 --> 00:06:18.583 179 | 何もない! 180 | 181 | 43 182 | 00:06:40.625 --> 00:06:43.208 183 | プルーグ!何か聞こえない? 184 | 185 | 44 186 | 00:06:43.625 --> 00:06:45.042 187 | あそこに行かないか? 188 | 189 | 45 190 | 00:06:45.208 --> 00:06:48.042 191 | あそこ? 192 | …安全じゃない 193 | 194 | 46 195 | 00:06:49.917 --> 00:06:52.500 196 | でも… 197 | ―本当に危ないぞ 198 | 199 | 47 200 | 00:06:53.292 --> 00:06:54.792 201 | 大丈夫だよ… 202 | 203 | 48 204 | 00:06:54.833 --> 00:06:56.333 205 | だめだ 206 | 207 | 49 208 | 00:06:57.667 --> 00:07:00.167 209 | だめだ! 210 | 211 | 50 212 | 00:07:00.875 --> 00:07:03.750 213 | まだ続ける気か、イーモ? 214 | 215 | 51 216 | 00:07:04.250 --> 00:07:05.917 217 | いいえ… 218 | 219 | 52 220 | 00:07:09.458 --> 00:07:10.833 221 | イーモ? 222 | 223 | 53 224 | 00:07:11.875 --> 00:07:13.542 225 | イーモ、なぜ… 226 | 227 | 54 228 | 00:07:13.583 --> 00:07:14.458 229 | イーモ… 230 | 231 | 55 232 | 00:07:14.500 --> 00:07:18.500 233 | …なぜここの美しさが 234 | 見えない? 235 | 236 | 56 237 | 00:07:18.833 --> 00:07:20.750 238 | 仕組みがこんなに… 239 | 240 | 57 241 | 00:07:20.875 --> 00:07:24.000 242 | こんなに完全なのに 243 | 244 | 58 245 | 00:07:24.083 --> 00:07:27.417 246 | もういいよ!プルーグ! 247 | 248 | 59 249 | 00:07:27.542 --> 00:07:30.333 250 | そこには何もないんだから 251 | 252 | 60 253 | 00:07:31.500 --> 00:07:35.333 254 | なぜ命を「ない」物に 255 | ゆだねなきゃ? 256 | 257 | 61 258 | 00:07:35.583 --> 00:07:37.125 259 | 教えてくれないか? 260 | 261 | 62 262 | 00:07:37.500 --> 00:07:39.167 263 | さあ! 264 | 265 | 63 266 | 00:07:43.208 --> 00:07:44.583 267 | プルーグ… 268 | 269 | 64 270 | 00:07:45.500 --> 00:07:47.333 271 | あなたは病気なんだ 272 | 273 | 65 274 | 00:07:47.375 --> 00:07:49.208 275 | 僕から離れてくれ 276 | 277 | 66 278 | 00:07:52.583 --> 00:07:55.083 279 | いかん!イーモ!ワナだ! 280 | 281 | 67 282 | 00:07:55.833 --> 00:07:57.167 283 | ワナだ? ふーん 284 | 285 | 68 286 | 00:07:57.208 --> 00:08:01.750 287 | 左に何が見える? 288 | バビロンの空中庭園! 289 | 290 | 69 291 | 00:08:02.250 --> 00:08:04.292 292 | これがワナとでも? 293 | 294 | 70 295 | 00:08:05.458 --> 00:08:07.125 296 | だめだ、イーモ 297 | 298 | 71 299 | 00:08:09.417 --> 00:08:12.792 300 | 右にあるのは… 301 | …すごい!… 302 | 303 | 72 304 | 00:08:13.000 --> 00:08:14.750 305 | …ロードス島の巨像だ! 306 | 307 | 73 308 | 00:08:15.833 --> 00:08:16.708 309 | やめろ! 310 | 311 | 74 312 | 00:08:16.750 --> 00:08:22.167 313 | この巨像はあなたの物 314 | プルーグ、あなたのだよ 315 | 316 | 75 317 | 00:08:51.333 --> 00:08:53.167 318 | いってるじゃないか… 319 | 320 | 76 321 | 00:08:53.208 --> 00:08:55.500 322 | そこにあるって、イーモ… 323 | 324 | 77 325 | 00:08:57.333 --> 00:09:00.000 326 | …あるって -------------------------------------------------------------------------------- /docs/examples/elephantsdream/captions.ru.vtt: -------------------------------------------------------------------------------- 1 | WEBVTT 2 | 3 | 1 4 | 00:00:14.958 --> 00:00:17.833 5 | Слева мы видим... 6 | 7 | 2 8 | 00:00:18.458 --> 00:00:20.208 9 | справа мы видим... 10 | 11 | 3 12 | 00:00:20.333 --> 00:00:21.875 13 | ...голово-клацов. 14 | 15 | 4 16 | 00:00:22.000 --> 00:00:24.583 17 | всё в порядке. 18 | в полном порядке. 19 | 20 | 5 21 | 00:00:26.333 --> 00:00:27.333 22 | Имо? 23 | 24 | 6 25 | 00:00:28.833 --> 00:00:30.250 26 | Осторожно! 27 | 28 | 7 29 | 00:00:47.125 --> 00:00:48.250 30 | Ты не ранен? 31 | 32 | 8 33 | 00:00:51.875 --> 00:00:53.875 34 | Вроде нет... 35 | а ты? 36 | 37 | 9 38 | 00:00:55.583 --> 00:00:57.125 39 | Я в порядке. 40 | 41 | 10 42 | 00:00:57.542 --> 00:01:01.625 43 | Вставай. 44 | Имо. здесь не безопасно. 45 | 46 | 11 47 | 00:01:02.208 --> 00:01:03.625 48 | Пойдём. 49 | 50 | 12 51 | 00:01:03.708 --> 00:01:05.708 52 | Что дальше? 53 | 54 | 13 55 | 00:01:05.833 --> 00:01:07.833 56 | Ты увидишь! 57 | 58 | 14 59 | 00:01:08.000 --> 00:01:08.833 60 | Ты увидишь... 61 | 62 | 15 63 | 00:01:16.167 --> 00:01:18.375 64 | Имо. сюда. 65 | 66 | 16 67 | 00:01:34.917 --> 00:01:35.750 68 | За мной! 69 | 70 | 17 71 | 00:02:11.542 --> 00:02:12.750 72 | Имо. быстрее! 73 | 74 | 18 75 | 00:02:48.375 --> 00:02:50.083 76 | Ты не обращаешь внимания! 77 | 78 | 19 79 | 00:02:50.708 --> 00:02:54.500 80 | Я только хотел ответить на ... 81 | ...звонок. 82 | 83 | 20 84 | 00:02:55.000 --> 00:02:58.208 85 | Имо. смотри. 86 | то есть слушай... 87 | 88 | 21 89 | 00:02:59.708 --> 00:03:02.292 90 | Ты должен учиться слушать. 91 | 92 | 22 93 | 00:03:03.250 --> 00:03:05.333 94 | Это не какая-нибудь игра. 95 | 96 | 23 97 | 00:03:06.000 --> 00:03:08.833 98 | Ты. вернее мы. легко можем погибнуть здесь. 99 | 100 | 24 101 | 00:03:10.000 --> 00:03:11.167 102 | Слушай... 103 | 104 | 25 105 | 00:03:11.667 --> 00:03:14.125 106 | слушай звуки машины. 107 | 108 | 26 109 | 00:03:18.333 --> 00:03:20.417 110 | Слушай своё дыхание. 111 | 112 | 27 113 | 00:04:27.208 --> 00:04:29.250 114 | И не надоест тебе это? 115 | 116 | 28 117 | 00:04:29.542 --> 00:04:31.083 118 | Надоест?!? 119 | 120 | 29 121 | 00:04:31.708 --> 00:04:34.625 122 | Имо! Машина - 123 | она как часовой механизм. 124 | 125 | 30 126 | 00:04:35.500 --> 00:04:37.667 127 | Одно движение не туда... 128 | 129 | 31 130 | 00:04:37.792 --> 00:04:39.750 131 | ...и тебя размелют в месиво! 132 | 133 | 32 134 | 00:04:41.042 --> 00:04:42.375 135 | А разве это не - 136 | 137 | 33 138 | 00:04:42.417 --> 00:04:46.500 139 | Месиво. Имо! 140 | ты этого хочешь? месиво? 141 | 142 | 34 143 | 00:04:48.083 --> 00:04:50.000 144 | Имо. твоя цель в жизни? 145 | 146 | 35 147 | 00:04:50.542 --> 00:04:52.250 148 | Месиво! 149 | 150 | 36 151 | 00:05:41.792 --> 00:05:43.458 152 | Имо. закрой глаза. 153 | 154 | 37 155 | 00:05:44.875 --> 00:05:46.542 156 | Зачем? 157 | - Ну же! 158 | 159 | 38 160 | 00:05:51.500 --> 00:05:52.333 161 | Ладно. 162 | 163 | 39 164 | 00:05:53.708 --> 00:05:56.042 165 | Хорошо. 166 | 167 | 40 168 | 00:05:59.500 --> 00:06:02.750 169 | Что ты видишь слева от себя. Имо? 170 | 171 | 41 172 | 00:06:04.417 --> 00:06:06.000 173 | Ничего. 174 | - Точно? 175 | 176 | 42 177 | 00:06:06.333 --> 00:06:07.875 178 | да. совсем ничего. 179 | 180 | 43 181 | 00:06:08.042 --> 00:06:12.708 182 | А справа от себя. 183 | что ты видишь справа от себя. Имо? 184 | 185 | 44 186 | 00:06:13.833 --> 00:06:16.875 187 | Да то же Пруг. в точности то же... 188 | 189 | 45 190 | 00:06:17.042 --> 00:06:18.500 191 | Ничего! 192 | 193 | 46 194 | 00:06:18.667 --> 00:06:19.500 195 | Прекрасно... 196 | 197 | 47 198 | 00:06:40.583 --> 00:06:42.917 199 | Прислушайся. Пруг! Ты слышишь это? 200 | 201 | 48 202 | 00:06:43.583 --> 00:06:45.042 203 | Может. мы пойдём туда? 204 | 205 | 49 206 | 00:06:45.208 --> 00:06:48.042 207 | Туда? 208 | Это не безопасно. Имо. 209 | 210 | 50 211 | 00:06:49.875 --> 00:06:52.500 212 | Но... 213 | - Поверь мне. это так. 214 | 215 | 51 216 | 00:06:53.292 --> 00:06:54.750 217 | Может я бы ... 218 | 219 | 52 220 | 00:06:54.792 --> 00:06:56.333 221 | Нет. 222 | 223 | 53 224 | 00:06:57.625 --> 00:06:59.583 225 | - Но... 226 | - НЕТ! 227 | 228 | 54 229 | 00:06:59.708 --> 00:07:00.833 230 | Нет! 231 | 232 | 55 233 | 00:07:00.833 --> 00:07:03.708 234 | Ещё вопросы. Имо? 235 | 236 | 56 237 | 00:07:04.250 --> 00:07:05.875 238 | Нет. 239 | 240 | 57 241 | 00:07:09.458 --> 00:07:10.792 242 | Имо? 243 | 244 | 58 245 | 00:07:11.833 --> 00:07:13.500 246 | Имо. почему... 247 | 248 | 59 249 | 00:07:13.542 --> 00:07:14.458 250 | Имо... 251 | 252 | 60 253 | 00:07:14.500 --> 00:07:18.500 254 | ...почему? почему ты не видишь 255 | красоты этого места? 256 | 257 | 61 258 | 00:07:18.792 --> 00:07:20.708 259 | То как оно работает. 260 | 261 | 62 262 | 00:07:20.833 --> 00:07:24.000 263 | Как совершенно оно. 264 | 265 | 63 266 | 00:07:24.083 --> 00:07:27.417 267 | Нет. Пруг. я не вижу. 268 | 269 | 64 270 | 00:07:27.500 --> 00:07:30.333 271 | Я не вижу. потому что здесь ничего нет. 272 | 273 | 65 274 | 00:07:31.375 --> 00:07:35.333 275 | И почему я должен доверять свою жизнь 276 | чему-то. чего здесь нет? 277 | 278 | 66 279 | 00:07:35.542 --> 00:07:37.125 280 | это ты мне можешь сказать? 281 | 282 | 67 283 | 00:07:37.500 --> 00:07:39.167 284 | Ответь мне! 285 | 286 | 68 287 | 00:07:43.208 --> 00:07:44.542 288 | Пруг... 289 | 290 | 69 291 | 00:07:45.500 --> 00:07:47.333 292 | Ты просто больной! 293 | 294 | 70 295 | 00:07:47.375 --> 00:07:48.500 296 | Отстань от меня. 297 | 298 | 71 299 | 00:07:48.625 --> 00:07:49.917 300 | Имо... 301 | 302 | 72 303 | 00:07:52.542 --> 00:07:55.083 304 | Нет! Имо! Это ловушка! 305 | 306 | 73 307 | 00:07:55.792 --> 00:07:57.167 308 | Это ловушка! 309 | 310 | 74 311 | 00:07:57.208 --> 00:08:01.708 312 | Слева от себя вы можете увидеть 313 | Висящие сады Семирамиды! 314 | 315 | 75 316 | 00:08:02.250 --> 00:08:04.292 317 | Сойдёт за ловушку? 318 | 319 | 76 320 | 00:08:05.458 --> 00:08:07.125 321 | Нет. Имо. 322 | 323 | 77 324 | 00:08:09.417 --> 00:08:12.750 325 | Справа от себя вы можете увидеть... 326 | ...угадай кого... 327 | 328 | 78 329 | 00:08:13.000 --> 00:08:14.708 330 | ...Колосса Родосского! 331 | 332 | 79 333 | 00:08:15.500 --> 00:08:16.625 334 | Нет! 335 | 336 | 80 337 | 00:08:16.667 --> 00:08:21.125 338 | Колосс Родосский! 339 | И он здесь специально для тебя. Пруг. 340 | 341 | 81 342 | 00:08:21.167 --> 00:08:22.208 343 | Специально для тебя... 344 | 345 | 82 346 | 00:08:51.333 --> 00:08:53.167 347 | Она здесь есть! 348 | 349 | 83 350 | 00:08:53.208 --> 00:08:55.500 351 | Говорю тебе. 352 | Имо... 353 | 354 | 84 355 | 00:08:57.333 --> 00:09:00.000 356 | ...она есть... есть... -------------------------------------------------------------------------------- /docs/examples/elephantsdream/captions.sv.vtt: -------------------------------------------------------------------------------- 1 | WEBVTT 2 | 3 | 1 4 | 00:00:15.042 --> 00:00:18.250 5 | Till vänster kan vi se... 6 | Ser vi... 7 | 8 | 2 9 | 00:00:18.708 --> 00:00:20.333 10 | Till höger ser vi... 11 | 12 | 3 13 | 00:00:20.417 --> 00:00:21.958 14 | ...huvudkaparna. 15 | 16 | 4 17 | 00:00:22.000 --> 00:00:24.792 18 | Allt är säkert. 19 | alldeles ofarligt. 20 | 21 | 5 22 | 00:00:24.917 --> 00:00:26.833 23 | Emo? 24 | 25 | 6 26 | 00:00:28.750 --> 00:00:30.167 27 | Se upp! 28 | 29 | 7 30 | 00:00:46.708 --> 00:00:48.750 31 | Är du skadad? 32 | 33 | 8 34 | 00:00:51.875 --> 00:00:54.458 35 | Jag tror inte det... 36 | Är du? 37 | 38 | 9 39 | 00:00:55.292 --> 00:00:57.333 40 | Jag är ok. 41 | 42 | 10 43 | 00:00:57.542 --> 00:01:01.625 44 | Res dig upp Emo. 45 | Det är inte säkert här. 46 | 47 | 11 48 | 00:01:02.208 --> 00:01:03.625 49 | Kom så går vi. 50 | 51 | 12 52 | 00:01:03.708 --> 00:01:05.708 53 | Vad nu då? 54 | 55 | 13 56 | 00:01:05.833 --> 00:01:07.833 57 | Du får se... 58 | 59 | 14 60 | 00:01:08.042 --> 00:01:10.417 61 | Du får se. 62 | 63 | 15 64 | 00:01:15.958 --> 00:01:18.375 65 | Emo. den här vägen. 66 | 67 | 16 68 | 00:01:34.417 --> 00:01:36.750 69 | Följ efter mig! 70 | 71 | 17 72 | 00:02:11.250 --> 00:02:13.250 73 | Skynda dig. Emo! 74 | 75 | 18 76 | 00:02:48.375 --> 00:02:50.583 77 | Du är inte uppmärksam! 78 | 79 | 19 80 | 00:02:50.708 --> 00:02:54.500 81 | Jag vill bara svara... 82 | ... i telefonen. 83 | 84 | 20 85 | 00:02:54.500 --> 00:02:58.208 86 | Emo. se här... 87 | Lyssna menar jag. 88 | 89 | 21 90 | 00:02:59.708 --> 00:03:02.292 91 | Du måste lära dig att lyssna. 92 | 93 | 22 94 | 00:03:03.292 --> 00:03:05.208 95 | Det här är ingen lek. 96 | 97 | 23 98 | 00:03:05.250 --> 00:03:08.917 99 | Du... Jag menar vi. 100 | vi skulle kunna dö här ute. 101 | 102 | 24 103 | 00:03:09.917 --> 00:03:11.417 104 | Lyssna... 105 | 106 | 25 107 | 00:03:11.708 --> 00:03:14.833 108 | Lyssna på ljuden från maskinen. 109 | 110 | 26 111 | 00:03:18.125 --> 00:03:21.417 112 | Lyssna på dina andetag. 113 | 114 | 27 115 | 00:04:26.625 --> 00:04:29.250 116 | Tröttnar du aldrig på det här? 117 | 118 | 28 119 | 00:04:29.542 --> 00:04:31.083 120 | Tröttnar!? 121 | 122 | 29 123 | 00:04:31.208 --> 00:04:33.458 124 | Emo. maskinen är som... 125 | 126 | 30 127 | 00:04:33.458 --> 00:04:35.333 128 | Som ett urverk. 129 | 130 | 31 131 | 00:04:35.417 --> 00:04:37.167 132 | Ett felsteg... 133 | 134 | 32 135 | 00:04:37.208 --> 00:04:39.750 136 | ...och du blir krossad. 137 | 138 | 33 139 | 00:04:41.042 --> 00:04:42.292 140 | Men är det inte - 141 | 142 | 34 143 | 00:04:42.292 --> 00:04:47.000 144 | Krossad. Emo! 145 | Är det vad du vill bli? Krossad till mos? 146 | 147 | 35 148 | 00:04:47.500 --> 00:04:50.542 149 | Emo. är det ditt mål i livet? 150 | 151 | 36 152 | 00:04:50.667 --> 00:04:53.250 153 | Att bli mos!? 154 | 155 | 37 156 | 00:05:41.375 --> 00:05:43.458 157 | Emo. blunda. 158 | 159 | 38 160 | 00:05:44.375 --> 00:05:46.542 161 | Varför då? 162 | - Blunda! 163 | 164 | 39 165 | 00:05:51.292 --> 00:05:55.042 166 | Ok. 167 | - Bra. 168 | 169 | 40 170 | 00:05:59.500 --> 00:06:02.750 171 | Vad ser du till vänster om dig Emo? 172 | 173 | 41 174 | 00:06:04.125 --> 00:06:06.292 175 | Ingenting. 176 | - Säker? 177 | 178 | 42 179 | 00:06:06.333 --> 00:06:07.958 180 | Ingenting alls. 181 | 182 | 43 183 | 00:06:08.042 --> 00:06:12.625 184 | Jaså. och till höger om dig... 185 | Vad ser du där. Emo? 186 | 187 | 44 188 | 00:06:13.750 --> 00:06:15.583 189 | Samma där Proog... 190 | 191 | 45 192 | 00:06:15.583 --> 00:06:18.083 193 | Exakt samma där. ingenting! 194 | 195 | 46 196 | 00:06:18.083 --> 00:06:19.667 197 | Perfekt. 198 | 199 | 47 200 | 00:06:40.500 --> 00:06:42.917 201 | Lyssna Proog! Hör du? 202 | 203 | 48 204 | 00:06:43.500 --> 00:06:45.125 205 | Kan vi gå dit? 206 | 207 | 49 208 | 00:06:45.208 --> 00:06:48.125 209 | Gå dit? 210 | Det är inte tryggt. 211 | 212 | 50 213 | 00:06:49.583 --> 00:06:52.583 214 | Men. men... 215 | - Tro mig. det inte säkert. 216 | 217 | 51 218 | 00:06:53.000 --> 00:06:54.292 219 | Men kanske om jag - 220 | 221 | 52 222 | 00:06:54.292 --> 00:06:56.333 223 | Nej. 224 | 225 | 53 226 | 00:06:57.208 --> 00:07:00.167 227 | Men - 228 | - Nej. NEJ! 229 | 230 | 54 231 | 00:07:00.917 --> 00:07:03.792 232 | Några fler frågor Emo? 233 | 234 | 55 235 | 00:07:04.250 --> 00:07:05.875 236 | Nej. 237 | 238 | 56 239 | 00:07:09.542 --> 00:07:11.375 240 | Emo? 241 | - Ja? 242 | 243 | 57 244 | 00:07:11.542 --> 00:07:15.667 245 | Emo. varför... 246 | 247 | 58 248 | 00:07:15.792 --> 00:07:18.583 249 | Varför kan du inte se skönheten i det här? 250 | 251 | 59 252 | 00:07:18.792 --> 00:07:21.708 253 | Hur det fungerar. 254 | 255 | 60 256 | 00:07:21.833 --> 00:07:24.000 257 | Hur perfekt det är. 258 | 259 | 61 260 | 00:07:24.083 --> 00:07:27.333 261 | Nej Proog. jag kan inte se det. 262 | 263 | 62 264 | 00:07:27.333 --> 00:07:30.333 265 | Jag ser det inte. för det finns inget där. 266 | 267 | 63 268 | 00:07:31.292 --> 00:07:35.333 269 | Och varför skulle jag lägga mitt liv 270 | i händerna på något som inte finns? 271 | 272 | 64 273 | 00:07:35.333 --> 00:07:37.083 274 | Kan du berätta det för mig? 275 | - Emo... 276 | 277 | 65 278 | 00:07:37.083 --> 00:07:39.167 279 | Svara mig! 280 | 281 | 66 282 | 00:07:43.500 --> 00:07:45.208 283 | Proog... 284 | 285 | 67 286 | 00:07:45.208 --> 00:07:47.083 287 | Du är inte frisk! 288 | 289 | 68 290 | 00:07:47.167 --> 00:07:49.292 291 | Håll dig borta från mig! 292 | 293 | 69 294 | 00:07:52.292 --> 00:07:55.083 295 | Nej! Emo! 296 | Det är en fälla! 297 | 298 | 70 299 | 00:07:55.375 --> 00:07:57.208 300 | Heh. det är en fälla. 301 | 302 | 71 303 | 00:07:57.208 --> 00:08:01.708 304 | På vänster sida ser vi... 305 | Babylons hängande trädgårdar! 306 | 307 | 72 308 | 00:08:01.958 --> 00:08:04.000 309 | Vad sägs om den fällan? 310 | 311 | 73 312 | 00:08:05.458 --> 00:08:07.333 313 | Nej. Emo. 314 | 315 | 74 316 | 00:08:08.917 --> 00:08:12.667 317 | Till höger ser vi... 318 | Gissa! 319 | 320 | 75 321 | 00:08:12.750 --> 00:08:15.125 322 | Rhodos koloss! 323 | 324 | 76 325 | 00:08:15.375 --> 00:08:16.500 326 | Nej! 327 | 328 | 77 329 | 00:08:16.500 --> 00:08:20.250 330 | Kolossen på Rhodos! 331 | Och den är här för din skull. Proog... 332 | 333 | 78 334 | 00:08:20.250 --> 00:08:23.250 335 | Bara för din skull. 336 | 337 | 79 338 | 00:08:50.917 --> 00:08:53.250 339 | Den är där... 340 | 341 | 80 342 | 00:08:53.625 --> 00:08:56.417 343 | Tro mig. 344 | Emo... 345 | 346 | 81 347 | 00:08:57.000 --> 00:09:00.000 348 | Det är den. 349 | Det är den... -------------------------------------------------------------------------------- /docs/examples/elephantsdream/chapters.en.vtt: -------------------------------------------------------------------------------- 1 | WEBVTT 2 | 3 | NOTE Created by Owen Edwards 2015. http://creativecommons.org/licenses/by/2.5/ 4 | NOTE Based on 'finalbreakdown.rtf', part of the prepoduction notes, which are: 5 | NOTE (c) Copyright 2006, Blender Foundation / 6 | NOTE Netherlands Media Art Institute / 7 | NOTE www.elephantsdream.org 8 | 9 | 1 10 | 00:00:00.000 --> 00:00:27.500 11 | Prologue 12 | 13 | 2 14 | 00:00:27.500 --> 00:01:10.000 15 | Switchboard trap 16 | 17 | 3 18 | 00:01:10.000 --> 00:03:25.000 19 | Telephone/Lecture 20 | 21 | 4 22 | 00:03:25.000 --> 00:04:52.000 23 | Typewriter 24 | 25 | 5 26 | 00:04:52.000 --> 00:06:19.500 27 | Proog shows Emo stuff 28 | 29 | 6 30 | 00:06:19.500 --> 00:07:09.000 31 | Which way 32 | 33 | 7 34 | 00:07:09.000 --> 00:07:45.000 35 | Emo flips out 36 | 37 | 8 38 | 00:07:45.000 --> 00:09:25.000 39 | Emo creates 40 | 41 | 9 42 | 00:09:25.000 --> 00:10:53.000 43 | Closing credits 44 | 45 | -------------------------------------------------------------------------------- /docs/examples/elephantsdream/descriptions.en.vtt: -------------------------------------------------------------------------------- 1 | WEBVTT 2 | License: CC BY 4.0 http://creativecommons.org/licenses/by/4.0/ 3 | Author: Silvia Pfeiffer 4 | 5 | 1 6 | 00:00:00.000 --> 00:00:05.000 7 | The orange open movie project presents 8 | 9 | 2 10 | 00:00:05.010 --> 00:00:12.000 11 | Introductory titles are showing on the background of a water pool with fishes swimming and mechanical objects lying on a stone floor. 12 | 13 | 3 14 | 00:00:12.010 --> 00:00:14.800 15 | elephants dream 16 | 17 | 4 18 | 00:00:26.100 --> 00:00:28.206 19 | Two people stand on a small bridge. 20 | 21 | 5 22 | 00:00:30.010 --> 00:00:40.000 23 | The old man, Proog, shoves the younger and less experienced Emo on the ground to save him from being mowed down by a barrage of jack plugs that whir back and forth between the two massive switch-board-like walls. 24 | 25 | 6 26 | 00:00:40.000 --> 00:00:47.000 27 | The plugs are oblivious of the two, endlessly channeling streams of bizarre sounds and data. 28 | 29 | 7 30 | 00:00:48.494 --> 00:00:51.994 31 | Emo sits on the bridge and checks his limbs. 32 | 33 | 8 34 | 00:01:09.150 --> 00:01:16.030 35 | After the squealing plugs move on, Proog makes sure that Emo is unharmed and urges him onwards through a crack in one of the plug-walls. 36 | 37 | 9 38 | 00:01:18.050 --> 00:01:24.000 39 | They walk through the narrow hall into a massive room that fades away into blackness on all sides. 40 | 41 | 10 42 | 00:01:24.050 --> 00:01:34.200 43 | Only one path is visible, suspended in mid-air that runs between thousands of dangling electric cables on which sit crowds of robin-like robotic birds. 44 | 45 | 11 46 | 00:01:36.000 --> 00:01:40.000 47 | As Proog and Emo enter the room, the birds begin to wake up and notice them. 48 | 49 | 12 50 | 00:01:42.000 --> 00:01:50.000 51 | Realizing the danger, Proog grabs Emo by the arm. 52 | 53 | 13 54 | 00:01:50.050 --> 00:02:00.000 55 | They run along the increasingly bizarre path as the birds begin to swarm. 56 | 57 | 14 58 | 00:02:00.050 --> 00:02:11.000 59 | All sound is blocked out by the birds which are making the same noises as the jack-plugs, garbled screaming and obscure sentences and static. 60 | 61 | 15 62 | 00:02:12.600 --> 00:02:17.000 63 | The path dead-ends, stopping in the middle of no-where above the infinite drop. 64 | 65 | 16 66 | 00:02:17.600 --> 00:02:22.000 67 | Proog turns around as the birds reach them and begin to dive-bomb at them. 68 | 69 | 17 70 | 00:02:22.600 --> 00:02:28.000 71 | At the last moment, Proog takes out an old candlestick phone and the birds dive into the speaker piece. 72 | 73 | 18 74 | 00:02:28.600 --> 00:02:31.000 75 | The screen cuts to black. 76 | 77 | 19 78 | 00:02:31.600 --> 00:02:38.000 79 | In the next scene, Proog stands at one end of a room, suspiciously watching what is probably the same candlestick phone, which is ringing. 80 | 81 | 20 82 | 00:02:38.500 --> 00:02:41.000 83 | Emo watches from the other side of the room. 84 | 85 | 21 86 | 00:02:41.500 --> 00:02:43.000 87 | The phone continues to ring. 88 | 89 | 22 90 | 00:02:43.500 --> 00:02:48.000 91 | After a while Emo approaches it to answer it, but Proog slaps his hand away. 92 | 93 | 23 94 | 00:02:57.972 --> 00:02:59.100 95 | Proog takes the ear-piece off the hook. 96 | 97 | 24 98 | 00:03:13.500 --> 00:03:18.054 99 | The phone speaker revealed a mass of clawed, fleshy polyps which scream and gibber obscenely. 100 | 101 | 25 102 | 00:03:25.000 --> 00:03:33.000 103 | There is a solemn silence as Emo looks around the room and the technical objects therein. 104 | 105 | 26 106 | 00:03:38.000 --> 00:03:44.000 107 | Emo laughs disbelievingly and Proog walks away. 108 | 109 | 27 110 | 00:03:46.000 --> 00:03:54.000 111 | In the next scene, the two enter another massive black room. 112 | 113 | 28 114 | 00:03:54.500 --> 00:04:04.000 115 | There is no path, the entry platform is the only structure that seems to be there except for another exit, lit distantly at the far side. 116 | 117 | 29 118 | 00:04:04.500 --> 00:04:14.000 119 | Proog takes a step forward into the void, and his feet are suddenly caught by giant typewriter arms that rocket up out of the blackness to catch his feet as he dances across mid-air. 120 | 121 | 30 122 | 00:04:14.500 --> 00:04:22.000 123 | Emo follows Proog with somewhat less enthusiasm as the older man leads the way. 124 | 125 | 31 126 | 00:04:52.000 --> 00:04:58.000 127 | They reach the end of the room and go through a hall into a small compartment. 128 | 129 | 32 130 | 00:05:02.000 --> 00:05:06.000 131 | Proog presses a button, and the door shuts. 132 | 133 | 33 134 | 00:05:06.500 --> 00:05:09.000 135 | It is an elevator. 136 | 137 | 34 138 | 00:05:09.500 --> 00:05:24.000 139 | The elevator lurches suddenly as it is grabbed by a giant mechanical arm and thrown upwards, rushing up through an ever-widening tunnel. 140 | 141 | 35 142 | 00:05:26.500 --> 00:05:32.000 143 | When it begins to slow down, another arm grabs the capsule and throws it even further up. 144 | 145 | 36 146 | 00:05:32.500 --> 00:05:40.000 147 | As it moves up, the walls unlock and fall away, leaving only the floor with the two on it, rushing higher and higher. 148 | 149 | 37 150 | 00:05:54.500 --> 00:05:59.000 151 | They exit the tunnel into a black sky and the platform reaches the peak of its arc. 152 | 153 | 38 154 | 00:06:19.500 --> 00:06:26.000 155 | The elevator begins to drop down another shaft, coming to rest as it slams into the floor of another room and bringing the two to a level stop. 156 | 157 | 39 158 | 00:06:26.500 --> 00:06:28.000 159 | A camera flashes. 160 | 161 | 40 162 | 00:06:28.010 --> 00:06:34.000 163 | They are in a large, dingy room filled with strange, generator-like devices and dotted with boxy holographic projectors. 164 | 165 | 41 166 | 00:06:34.500 --> 00:06:38.000 167 | One of them is projecting a portion of wall with a door in it right beside them. 168 | 169 | 42 170 | 00:06:38.500 --> 00:06:40.000 171 | The door seems harmless enough. 172 | 173 | 43 174 | 00:06:42.800 --> 00:06:45.100 175 | From behind the door comes light music. 176 | 177 | 44 178 | 00:06:56.000 --> 00:07:00.100 179 | Proog presses a button on his cane, which changes the holograph to another wall. 180 | 181 | 45 182 | 00:07:05.100 --> 00:07:11.000 183 | Proog finishes the wall, and boxes them into a Safe Room, out of the view of anything outside. 184 | 185 | 46 186 | 00:07:39.000 --> 00:07:42.500 187 | Proog slaps him, trying to bring him to his senses. 188 | 189 | 47 190 | 00:07:45.000 --> 00:07:52.000 191 | Emo storms away down the length of the room towards a wall he apparently cannot see and the wall begins to move, extending the length of the room. 192 | 193 | 48 194 | 00:08:00.000 --> 00:08:07.000 195 | The walls begin to discolour and mechanical roots start tearing through the walls to his left. 196 | 197 | 49 198 | 00:08:07.010 --> 00:08:09.000 199 | The roots move forwards toward Proog. 200 | 201 | 50 202 | 00:08:22.000 --> 00:08:31.000 203 | The rest of the safety wall crumples away as a pair of massive hands heave out of the ground and begin to attack. 204 | 205 | 51 206 | 00:08:31.010 --> 00:08:37.000 207 | Proog is knocked down by the shockwave, while Emo turns and begins to walk away, waving his finger around his temple in the 'crazy' sign. 208 | 209 | 52 210 | 00:08:37.010 --> 00:08:44.000 211 | In a last effort, Proog extricates himself from the tentacle roots, and cracks Emo over the back of the head with his cane. 212 | 213 | 53 214 | 00:08:44.500 --> 00:08:51.000 215 | As Emo collapses, everything falls away, and Proog and Emo are left in one tiny patch of light in the middle of blackness. 216 | 217 | 54 218 | 00:09:00.000 --> 00:09:20.000 219 | The scene fades to black while panning over a pile of tentacle roots lying on the ground. 220 | 221 | 55 222 | 00:09:26.000 --> 00:09:28.000 223 | Credits begin: 224 | 225 | 56 226 | 00:09:28.500 --> 00:09:35.000 227 | Orange Open Movie Team 228 | Director: Bassum Kurdali 229 | Art Director: Andreas Goralczyk 230 | 231 | 57 232 | 00:09:35.500 --> 00:09:39.000 233 | Music and Sound Design: Jan Morgenstern 234 | 235 | 58 236 | 00:09:39.500 --> 00:09:44.000 237 | Emo: Cas Jansen 238 | Proog: Tygo Gernandt 239 | 240 | 59 241 | 00:09:44.500 --> 00:09:50.000 242 | Screenplay: Pepijn Zwanenberg 243 | Original Concept & Scenario: Andreas Goralczyk, Bassam Kurdali, Ton Roosendaal 244 | 245 | 60 246 | 00:09:50.500 --> 00:10:24.000 247 | More people for 248 | Additional Artwork and Animation 249 | Texture Photography 250 | Software Development 251 | 3D Modelling, Animation, Rendering, Compiling Software 252 | Special Thanks to Open Source Projects 253 | Rendering Services Provided 254 | Hardware Sponsored 255 | Casting 256 | Sound FX, Foley, Dialogue Editing, Audio Mix and Post 257 | Voice Recording 258 | HDCam conversion 259 | Netherlands Media Art Institute Staff 260 | Blender Foundation Staff 261 | 262 | 61 263 | 00:10:24.500 --> 00:10:30.000 264 | Many Thanks to our Donation and DVD sponsors 265 | 266 | 62 267 | 00:10:30.500 --> 00:10:47.000 268 | Elephants Dream has been realised with financial support from 269 | The Netherlands Film Fund 270 | Mondriaan Foundation 271 | VSBfonds 272 | Uni-Verse / EU Sixth Framework Programme 273 | 274 | 63 275 | 00:10:47.500 --> 00:10:53.000 276 | Produced By 277 | Ton Roosendaal 278 | Copyright 2006 279 | Netherlands Media Art Institute / Montevideo 280 | Blender Foundation 281 | -------------------------------------------------------------------------------- /docs/examples/elephantsdream/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Video.js Text Descriptions, Chapters & Captions Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 19 | 20 | 21 | 22 |

This page demonstrates a text descriptions track (intended primarily for blind and visually impaired consumers of visual media)

23 | 24 | 28 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /docs/examples/shared/example-captions.vtt: -------------------------------------------------------------------------------- 1 | WEBVTT 2 | 3 | 00:00.700 --> 00:04.110 4 | Captions describe all relevant audio for the hearing impaired. 5 | [ Heroic music playing for a seagull ] 6 | 7 | 00:04.500 --> 00:05.000 8 | [ Splash!!! ] 9 | 10 | 00:05.100 --> 00:06.000 11 | [ Sploosh!!! ] 12 | 13 | 00:08.000 --> 00:09.225 14 | [ Splash...splash...splash splash splash ] 15 | 16 | 00:10.525 --> 00:11.255 17 | [ Splash, Sploosh again ] 18 | 19 | 00:13.500 --> 00:14.984 20 | Dolphin: eeeEEEEEeeee! 21 | 22 | 00:14.984 --> 00:16.984 23 | Dolphin: Squawk! eeeEEE? 24 | 25 | 00:25.000 --> 00:28.284 26 | [ A whole ton of splashes ] 27 | 28 | 00:29.500 --> 00:31.000 29 | Mine. Mine. Mine. 30 | 31 | 00:34.300 --> 00:36.000 32 | Shark: Chomp 33 | 34 | 00:36.800 --> 00:37.900 35 | Shark: CHOMP!!! 36 | 37 | 00:37.861 --> 00:41.193 38 | EEEEEEOOOOOOOOOOWHALENOISE 39 | 40 | 00:42.593 --> 00:45.611 41 | [ BIG SPLASH ] -------------------------------------------------------------------------------- /docs/examples/simple-embed/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Video.js | HTML5 Video Player 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /docs/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/videojs/docs/2aab67b2e50948c8e89513c68dd000d7b41dbc65/docs/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /docs/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/videojs/docs/2aab67b2e50948c8e89513c68dd000d7b41dbc65/docs/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/videojs/docs/2aab67b2e50948c8e89513c68dd000d7b41dbc65/docs/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /docs/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/videojs/docs/2aab67b2e50948c8e89513c68dd000d7b41dbc65/docs/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/videojs/docs/2aab67b2e50948c8e89513c68dd000d7b41dbc65/docs/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /docs/guides/api.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |

API

14 |

The Video.js API allows you to interact with the video through JavaScript, whether the browser is playing the video through HTML5 video, Flash, or any other supported playback technologies.

15 |

Referencing the Player

16 |

To use the API functions, you need access to the player object. Luckily this is easy to get. You just need to make sure your video tag has an ID. The example embed code has an ID of "example_video_1". If you have multiple videos on one page, make sure every video tag has a unique ID.

17 |
var myPlayer = videojs('example_video_1');
18 | 
19 |

(If the player hasn't been initialized yet via the data-setup attribute or another method, this will also initialize the player.)

20 |

Wait Until the Player is Ready

21 |

The time it takes Video.js to set up the video and API will vary depending on the playback technology being used (HTML5 will often be much faster to load than Flash). For that reason we want to use the player's 'ready' function to trigger any code that requires the player's API.

22 |
videojs("example_video_1").ready(function(){
23 |   var myPlayer = this;
24 | 
25 |   // EXAMPLE: Start playing the video.
26 |   myPlayer.play();
27 | 
28 | });
29 | 
30 |

API Methods

31 |

Now that you have access to a ready player, you can control the video, get values, or respond to video events. The Video.js API function names follow the HTML5 media API. The main difference is that getter/setter functions are used for video properties.

32 |

33 | // setting a property on a bare HTML5 video element
34 | myVideoElement.currentTime = "120";
35 | 
36 | // setting a property on a Video.js player
37 | myPlayer.currentTime(120);
38 | 
39 |

The full list of player API methods and events can be found in the player API docs.

40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /docs/guides/audio-tracks.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |

Audio Tracks

14 |

Audio Tracks are a function of HTML5 video for providing alternative audio track selections to the user, so that a track other than the main track can be played. Video.js makes audio tracks work across all browsers. There are currently five types of tracks:

15 | 22 |

Missing Funtionality

23 | 27 |

Adding to Video.js

28 |
29 |

Right now adding audio tracks in the HTML is unsupported. Audio Tracks must be added programatically.

30 |
31 |

You must add audio tracks programatically for the time being.

32 |

Attributes

33 |

Audio Track propertites and settings

34 |

kind

35 |

One of the five track types listed above. Kind defaults to empty string if no kind is included, or an invalid kind is used.

36 |

label

37 |

The label for the track that will be show to the user, for example in a menu that list the different languages available for audio tracks.

38 |

language

39 |

The two-letter code (valid BCP 47 language tag) for the language of the audio track, for example "en" for English. A list of language codes is available here.

40 |

enabled

41 |

If this track should be playing or not. In video.js we only allow one track to be enabled at a time. so if you enable more than one the last one to be enabled will end up being the only one.

42 |

Interacting with Audio Tracks

43 |

Doing something when a track becomes enabled

44 |

When a new track is enabled (other than the main track) an event is fired on the AudioTrackList called change you can listen to that event and do something with it. 45 | Here's an example:

46 |
// get the current players AudioTrackList object
47 | let tracks = player.audioTracks();
48 | 
49 | // listen to the change event
50 | tracks.addEventListener('change', function() {
51 | 
52 |   // print the currently enabled AudioTrack label
53 |   for (let i = 0; i < tracks.length; i++) {
54 |     let track = tracks[i];
55 | 
56 |     if (track.enabled) {
57 |       console.log(track.label);
58 |       return;
59 |     }
60 |   }
61 | });
62 | 
63 |

API

64 |

player.audioTracks() -> AudioTrackList

65 |

This is the main interface into the audio tracks of the player. 66 | It returns an AudioTrackList which is an array like object that contains all the AudioTrack on the player.

67 |

player.audioTracks().addTrack(AudioTrack)

68 |

Add an existing AudioTrack to the players internal list of AudioTracks.

69 |

player.audioTracks().removeTrack(AudioTrack)

70 |

Remove a track from the AudioTrackList currently on the player. if no track exists this will do nothing.

71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /docs/guides/components.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |

Components

14 |

The Video.js player is built on top of a simple, custom UI components architecture. The player class and all control classes inherit from the Component class, or a subclass of Component.

15 |
videojs.registerComponent('Control', videojs.extends(Component));
16 | videojs.registerComponent('Button', videojs.extends(videojs.getComponent('Control')));
17 | videojs.registerComponent('PlayToggle', videojs.extends(videojs.getComponent('Button')));
18 | 
19 |

The UI component architecture makes it easier to add child components to a parent component and build up an entire user interface, like the controls for the Video.js player.

20 |
// Adding a new control to the player
21 | myPlayer.addChild('BigPlayButton');
22 | 
23 |

Every component has an associated DOM element, and when you add a child component, it inserts the element of that child into the element of the parent.

24 |
myPlayer.addChild('BigPlayButton');
25 | 
26 |

Results in:

27 |
    <!-- Player Element -->
28 |     <div class="video-js">
29 |       <!-- BigPlayButton Element -->
30 |       <div class="vjs-big-play-button"></div>
31 |     </div>
32 | 
33 |

The actual default component structure of the Video.js player looks something like this:

34 |
Player
35 |     PosterImage
36 |     TextTrackDisplay
37 |     LoadingSpinner
38 |     BigPlayButton
39 |     ControlBar
40 |         PlayToggle
41 |         VolumeMenuButton
42 |         CurrentTimeDisplay (Hidden by default)
43 |         TimeDivider (Hidden by default)
44 |         DurationDisplay (Hidden by default)
45 |         ProgressControl
46 |             SeekBar
47 |               LoadProgressBar
48 |               MouseTimeDisplay
49 |               PlayProgressBar
50 |         LiveDisplay (Hidden by default)
51 |         RemainingTimeDisplay
52 |         CustomControlsSpacer (No UI)
53 |         ChaptersButton (Hidden by default)
54 |         SubtitlesButton (Hidden by default)
55 |         CaptionsButton (Hidden by default)
56 |         FullscreenToggle
57 |     ErrorDisplay
58 |     TextTrackSettings
59 | 

Progress Control

60 |

The progress control is made up of the SeekBar. The seekbar contains the load progress bar 61 | and the play progress bar. In addition, it contains the Mouse Time Display which 62 | is used to display the time tooltip that follows the mouse cursor. 63 | The play progress bar also has a time tooltip that show the current time.

64 |

By default, the progress control is sandwiched between the volume menu button and 65 | the remaining time display inside the control bar, but in some cases, a skin would 66 | want to move the progress control above the control bar and have it span the full 67 | width of the player, in those cases, it is less than ideal to have the tooltips 68 | get cut off or leave the bounds of the player. This can be prevented by setting the 69 | keepTooltipsInside option on the progress control. This also makes the tooltips use 70 | a real element instead of pseudo elements so targetting them with css will be different.

71 |
let player = videojs('myplayer', {
72 |   controlBar: {
73 |     progressControl: {
74 |       keepTooltipsInside: true
75 |     }
76 |   }
77 | });
78 | 
79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /docs/guides/glossary.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |

Glossary

14 |

Terms related to web video.

15 |

DOM (Document Object Model)

16 |

The container of elements on the page that must be loaded before you can interact with the elements with through Javascript. 17 | http://en.wikipedia.org/wiki/Document_Object_Model

18 |

Flash Fallback

19 |

The Flash video player (SWF) used to play a video when HTML5 isn't supported.

20 |

TimeRange

21 |

HTML5 Video

22 |

HTML is the markup language that makes up every page on the web. The newest version, HTML5, includes specifications for a video tag, that is meant to allow website developers to add a video to a page the same way they would add an image. In order for this to work, web browser developers (Mozilla, Apple, Microsoft, Google, Opera, etc.) have to build the video playback functionality into their browsers. The W3C has created directions on how video should work in browsers, and it’s up to browser developers to follow those directions, so that video works the same across all browsers. This doesn’t always happen thanks to technology, legal, and financial choices made by browser developers, but so far no one’s varying too far from the specifications. However the specifications are still being changed and refined, so browsers developers have to keep up with that as well.

23 |

Playing video in a web page may not seem so special since you can already view video on a web page through plugins like Flash Player, Quicktime, Silverlight, and RealPlayer, however this is a big step forward for standardizing video playback across web browsers and devices. The goal is that in the future, developers will only need to use one method for embedding a video, that’s based on open standards (not controlled by one company), and it will work everywhere.

24 |

A prime example of this is the iPhone and iPad. Apple has decided not to support Flash on their mobile devices, but they do support HTML5 video. Since Flash is currently the most common way video is added to web pages, most web video (aside from YouTube who has a special relationship with Apple) can’t be viewed on the iPhone or iPad. These devices are very popular, so many web sites are switching to hybrid HTML5/Flash player setups (like VideoJS).

25 |

Video Tag

26 |

There are a number of great resources that will give you an introduction to the video tag an how it is used including:

27 | 31 |

An if you really want to dig in, you can read the (W3C Spec)[http://www.w3.org/TR/html5/video.html]. (Warning - not for the faint of heart)

32 |

Skin

33 |

"Skin" refers to the design of the player's controls, also sometimes called the chrome. With VideoJS, new skins can be built simply by creating a new stylesheet.

34 |

Content Delivery Network (CDN)

35 |

A network of servers around the world that host copies of a file. When your browser requests one of these files, the CDN automatically determines which server is closest to your location and delivers the file from there. This drastically increases delivery time, especially internationally.

36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /docs/guides/options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |

Options

14 |

Setting Options

15 |

The Video.js embed code is simply an HTML5 video tag, so for many of the options you can use the standard tag attributes to set the options.

16 |
<video controls autoplay preload="auto" ...>
 17 | 
18 |

Alternatively, you can use the data-setup attribute to provide options in the JSON format. This is also how you would set options that aren't standard to the video tag.

19 |
<video data-setup='{ "controls": true, "autoplay": false, "preload": "auto" }'...>
 20 | 
21 |

Finally, if you're not using the data-setup attribute to trigger the player setup, you can pass in an object with the player options as the second argument in the javascript setup function.

22 |
videojs("example_video_1", { "controls": true, "autoplay": false, "preload": "auto" });
 23 | 
24 |

Individual Options

25 |
26 |

Note on Video Tag Attributes

27 |

With HTML5 video tag attributes that can only be true or false (boolean), you simply include the attribute (no equals sign) to turn it on, or exclude it to turn it off. For example, to turn controls on:

28 |
29 |

WRONG

30 |
<video controls="true" ...>
 31 | 
32 |

RIGHT

33 |
<video controls ...>
 34 | 
35 |
36 |

The biggest issue people run into is trying to set these values to false using false as the value (e.g. controls="false") which actually does the opposite and sets the value to true because the attribute is still included. If you need the attribute to include an equals sign for XHTML validation, you can set the attribute's value to the same as its name (e.g. controls="controls").

37 |
38 |

controls

39 |

The controls option sets whether or not the player has controls that the user can interact with. Without controls the only way to start the video playing is with the autoplay attribute or through the API.

40 |
<video controls ...>
 41 | or
 42 | { "controls": true }
 43 | 
44 |

autoplay

45 |

If autoplay is true, the video will start playing as soon as page is loaded (without any interaction from the user). 46 | NOT SUPPORTED BY APPLE iOS DEVICES. Apple blocks the autoplay functionality in an effort to protect it's customers from unwillingly using a lot of their (often expensive) monthly data plans. A user touch/click is required to start the video in this case.

47 |
<video autoplay ...>
 48 | or
 49 | { "autoplay": true }
 50 | 
51 |

preload

52 |

The preload attribute informs the browser whether or not the video data should begin downloading as soon as the video tag is loaded. The options are auto, metadata, and none.

53 |

'auto': Start loading the video immediately (if the browser agrees). Some mobile devices like iPhones and iPads will not preload the video in order to protect their users' bandwidth. This is why the value is called 'auto' and not something more final like 'true'.

54 |

'metadata': Load only the meta data of the video, which includes information like the duration and dimensions of the video.

55 |

'none': Don't preload any of the video data. This will wait until the user clicks play to begin downloading.

56 |
<video preload ...>
 57 | or
 58 | { "preload": "auto" }
 59 | 
60 |

poster

61 |

The poster attribute sets the image that displays before the video begins playing. This is often a frame of the video or a custom title screen. As soon as the user clicks play the image will go away.

62 |
<video poster="myPoster.jpg" ...>
 63 | or
 64 | { "poster": "myPoster.jpg" }
 65 | 
66 |

loop

67 |

The loop attribute causes the video to start over as soon as it ends. This could be used for a visual effect like clouds in the background.

68 |
<video loop ...>
 69 | or
 70 | { "loop": true }
 71 | 
72 |

width

73 |

The width attribute sets the display width of the video.

74 |
<video width="640" ...>
 75 | or
 76 | { "width": 640 }
 77 | 
78 |

height

79 |

The height attribute sets the display height of the video.

80 |
<video height="480" ...>
 81 | or
 82 | { "height": 480 }
 83 | 
84 |

Component Options

85 |

You can set the options for any single player component. For instance, if you wanted to remove the muteToggle button, which 86 | is a child of controlBar, you can just set that component to false:

87 |
var player = videojs('video-id', {
 88 |   controlBar: {
 89 |     muteToggle: false
 90 |   }
 91 | });
 92 | 
93 |

This also works using the data-setup attribute on the video element, just remember the options need to use proper JSON 94 | notation.

95 |
<video ... data-setup='{ "controlBar": { "muteToggle": false } }'></video>
 96 | 
97 |

The components guide has an excellent breakdown of the structure of a player, you 98 | just need to remember to nest child components in a children array for each level.

99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /docs/guides/plugins.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |

Plugins

14 |

If you've built something cool with Video.js, you can easily share it with the rest of the world by creating a plugin. Although, you can roll your own, you can also use generator-videojs-plugin, a Yeoman generator that provides scaffolding for video.js plugins including:

15 |
    16 |
  • Grunt for build management
  • 17 |
  • npm for dependency management
  • 18 |
  • QUnit for testing
  • 19 |
20 |

Step 1: Write Some Javascript

21 |

You may have already done this step. Code up something interesting and then wrap it in a function. At the most basic level, that's all a video.js plugin is. By convention, plugins take a hash of options as their first argument:

22 |
    function examplePlugin(options) {
23 |       this.on('play', function(e) {
24 |         console.log('playback has started!');
25 |       });
26 |     };
27 | 
28 |

When it's activated, this will be the Video.js player your plugin is attached to. You can use anything you'd like in the Video.js API when you're writing a plugin: change the src, mess up the DOM, or listen for and emit your own events.

29 |

Step 2: Registering A Plugin

30 |

It's time to give the rest of the world the opportunity to be awed by your genius. When your plugin is loaded, it needs to let Video.js know this amazing new functionality is now available:

31 |
    videojs.plugin('examplePlugin', examplePlugin);
32 | 
33 |

From this point on, your plugin will be added to the Video.js prototype and will show up as a property on every instance created. Make sure you choose a unique name that doesn't clash with any of the properties already in Video.js. Which leads us to...

34 |

Step 3: Using A Plugin

35 |

There are two ways to initialize a plugin. If you're creating your video tag dynamically, you can specify the plugins you'd like to initialize with it and any options you want to pass to them:

36 |
    videojs('vidId', {
37 |       plugins: {
38 |         examplePlugin: {
39 |           exampleOption: true
40 |         }
41 |       }
42 |     });
43 | 
44 |

If you've already initialized your video tag, you can activate a plugin at any time by calling its setup function directly:

45 |
    var video = videojs('cool-vid');
46 |     video.examplePlugin({ exampleOption: true });
47 | 
48 |

That's it. Head on over to the Video.js wiki and add your plugin to the list so everyone else can check it out.

49 |

How should I use the Video.js icons in my plugin?

50 |

If you'd like to use any of the icons available in the Video.js icon set, please target them via the CSS class names instead of codepoints. The codepoints may change between versions of the font, so using the class names ensures that your plugin will stay up to date with any font changes.

51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /docs/guides/removing-players.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |

Removing Players

14 |

Sometimes, you want to remove players after page load (in single page apps or modals, for instance). It's easy to manage, but there are some simple rules you need to follow.

15 |

Call .dispose()

16 |

To remove the html associated with your videojs player from the page always call the player's dispose() method:

17 |
var oldPlayer = document.getElementById('my-player');
18 | videojs(oldPlayer).dispose();
19 | 
20 |

This method will:

21 |
    22 |
  1. reset the internal state of videojs
  2. 23 |
  3. remove the player's dom from the page
  4. 24 |
25 |

Showing / Hiding a Player

26 |

For instance, if you have a modal that a player appears in, you should create the player when the modal pops up. When the modal hides, dispose the player. If you try to hide the Flash tech, things will go poorly. Even with other tech, calling dispose() on a player that's not needed will free up resources for the browser.

27 |

Why Is This Needed?

28 |

VideoJS internally tracks all players and their associated data by html id attribute. If you plan to create new players with the same id as previously created players, you'll need to call the player's dispose() method to clear VideoJS's internal state before creating the new player.

29 |

Signs You Did It Wrong

30 |
TypeError: this.el_.vjs_getProperty is not a function
31 | "VIDEOJS:" "Video.js: buffered unavailable on Hls playback technology element." TypeError: this.el_.vjs_getProperty is not a function
32 | Stack trace:
33 | ...
34 | 

If you encounter a console error in the browser similar to the above, you've probably forgotten to dispose() a player before removing it from the dom. This would happen when using the contrib-hls plugin.

35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /docs/guides/setup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |

Setup

14 |

Video.js is pretty easy to set up. It can take a matter of seconds to get the player up and working on your web page.

15 |

Step 1: Include the Video.js Javascript and CSS files in the head of your page.

16 |

You can download the Video.js source and host it on your own servers, or use the free CDN hosted version. As of Video.js 5.0, the source is transpiled from ES2015 (formerly known as ES6) to ES5, but IE8 only supports ES3. In order to continue to support IE8, we've bundled an ES5 shim and sham together and hosted it on the CDN.

17 |
<script src="//vjs.zencdn.net/ie8/1.1.1/videojs-ie8.min.js"></script>
 18 | 
19 |

CDN Version

20 |
<link href="//vjs.zencdn.net/5.4.6/video-js.min.css" rel="stylesheet">
 21 | <script src="//vjs.zencdn.net/5.4.6/video.min.js"></script>
 22 | 
23 |

Alternatively you can always go here to get the latest URL for videojs CDN.

24 |

We include a stripped down Google Analytics pixel that tracks a random percentage (currently 1%) of players loaded from the CDN. This allows us to see (roughly) what browsers are in use in the wild, along with other useful metrics such as OS and device. If you'd like to disable analytics, you can simply include the following global before including Video.js:

25 |
window.HELP_IMPROVE_VIDEOJS = false;
 26 | 
27 |

Install via package manager

28 |

NPM

29 |
$ npm install --save video.js
 30 | 

Bower

31 |
$ bower install --save video.js
 32 | 

Self Hosted.

33 |

To entirely self-host, you'll need to pull in the font files and let Video.js know where the swf is located. If you simply copy the dist folder or zip file contents into your project everything 34 | should Just Work™, but the paths can easily be changed by editing the LESS file and re-building, or by modifying the generated CSS file. Additionally include the videojs-vtt.js source, which adds the WebVTT object to the global scope.

35 |
<link href="//example.com/path/to/video-js.min.css" rel="stylesheet">
 36 | <script src="//example.com/path/to/videojs-vtt.js"></script>
 37 | <script src="//example.com/path/to/video.min.js"></script>
 38 | <script>
 39 |   videojs.options.flash.swf = "http://example.com/path/to/video-js.swf"
 40 | </script>
 41 | 
42 |

Step 2: Add an HTML5 video tag to your page.

43 |

With Video.js you just use an HTML5 video tag to embed a video. Video.js will then read the tag and make it work in all browsers, not just ones that support HTML5 video. Beyond the basic markup, Video.js needs a few extra pieces.

44 |
45 |

Note: The data-setup attribute described here should not be used if you use the alternative setup described in the next section.

46 |
47 |
    48 |
  1. The 'data-setup' Attribute tells Video.js to automatically set up the video when the page is ready, and read any options (in JSON format) from the attribute (see options). There are other methods for initializing the player, but this is the easiest.

    49 |
  2. 50 |
  3. The 'id' Attribute: Should be used and unique for every video on the same page.

    51 |
  4. 52 |
  5. The 'class' attribute contains two classes:

    53 |
      54 |
    • video-js applies styles that are required for Video.js functionality, like fullscreen and subtitles.
    • 55 |
    • vjs-default-skin applies the default skin to the HTML controls, and can be removed or overridden to create your own controls design.
    • 56 |
    57 |
  6. 58 |
59 |

Otherwise include/exclude attributes, settings, sources, and tracks exactly as you would for HTML5 video.*

60 |
<video id="example_video_1" class="video-js vjs-default-skin"
 61 |   controls preload="auto" width="640" height="264"
 62 |   poster="http://video-js.zencoder.com/oceans-clip.png"
 63 |   data-setup='{"example_option":true}'>
 64 |  <source src="http://video-js.zencoder.com/oceans-clip.mp4" type="video/mp4" />
 65 |  <source src="http://video-js.zencoder.com/oceans-clip.webm" type="video/webm" />
 66 |  <source src="http://video-js.zencoder.com/oceans-clip.ogv" type="video/ogg" />
 67 |  <p class="vjs-no-js">To view this video please enable JavaScript, and consider upgrading to a web browser that <a href="http://videojs.com/html5-video-support/" target="_blank">supports HTML5 video</a></p>
 68 | </video>
 69 | 
70 |

By default, the big play button is located in the upper left hand corner so it doesn't cover up the interesting parts of the poster. If you'd prefer to center the big play button, you can add an additional vjs-big-play-centered class to your video element. For example:

71 |
<video id="example_video_1" class="video-js vjs-default-skin vjs-big-play-centered"
 72 |   controls preload="auto" width="640" height="264"
 73 |   poster="http://video-js.zencoder.com/oceans-clip.png"
 74 |   data-setup='{"example_option":true}'>
 75 |   ...
 76 | </video>
 77 | 
78 |

Alternative Setup for Dynamically Loaded HTML

79 |

If your web page or application loads the video tag dynamically (ajax, appendChild, etc.), so that it may not exist when the page loads, you'll want to manually set up the player instead of relying on the data-setup attribute. To do this, first remove the data-setup attribute from the tag so there's no confusion around when the player is initialized. Next, run the following javascript some time after the Video.js javascript library has loaded, and after the video tag has been loaded into the DOM.

80 |
videojs("example_video_1", {}, function(){
 81 |   // Player (this) is initialized and ready.
 82 | });
 83 | 
84 |

The first argument in the videojs function is the ID of your video tag. Replace it with your own.

85 |

The second argument is an options object. It allows you to set additional options like you can with the data-setup attribute.

86 |

The third argument is a 'ready' callback. Once Video.js has initialized it will call this function.

87 |

Instead of using an element ID, you can also pass a reference to the element itself.

88 |
videojs(document.getElementById('example_video_1'), {}, function() {
 89 |   // This is functionally the same as the previous example.
 90 | });
 91 | 
92 |
videojs(document.getElementsByClassName('awesome_video_class')[0], {}, function() {
 93 |   // You can grab an element by class if you'd like, just make sure
 94 |   // if it's an array that you pick one (here we chose the first).
 95 | });
 96 | 
97 |

* If you have trouble playing back content you know is in the correct format, your HTTP server might not be delivering the content with the correct MIME type. Please double check your content's headers before opening an issue.

98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /docs/guides/skins.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |

Skins

14 |

Base Skin

15 |

The base Video.js skin is made using HTML and CSS (although we use the Sass preprocessor), 16 | and by default these styles are added to the DOM for you! 17 | That means you can build a custom skin by simply taking advantage of the cascading aspect of CSS and overriding 18 | the styles you'd like to change.

19 |

If you don't want Video.js to inject the base styles for you, you can disable it by setting window.VIDEOJS_NO_BASE_THEME = true before Video.js is loaded. 20 | Keep in mind that without these base styles enabled, you'll need to manually include them.

21 |

Video.js does not currently include the base skin automatically yet, so, this option isn't necessary.

22 |

Default style elements

23 |

Video.js uses a couple of style elements dynamically, specifically, there's a default styles element as well as a player dimensions style element. 24 | They are used to provide extra default flexiblity with styling the player. However, in some cases, like if a user has the HEAD tag managed by React, users do not want this. 25 | When window.VIDEOJS_NO_DYNAMIC_STYLE is set to true, video.js will not include these element in the page. 26 | This means that default dimensions and configured player dimensions will not be applied. 27 | For example, the following player will end up having a width and height of 0 when initialized if window.VIDEOJS_NO_DYNAMIC_STYLE === true:

28 |
<video width="600" height="300"></video>
29 | 
30 |

Player#width and Player#height

31 |

When VIDEOJS_NO_DYNAMIC_STYLE is set, Player#width and Player#height will apply any width and height 32 | that is set directly to the video element (or whatever element the current tech uses).

33 |

Icons

34 |

You can view all of the icons available in the base theme by renaming and viewing 35 | icons.html.example in the sandbox directory.

36 |

Customization

37 |

When you create a new skin, the easiest way to get started is to simply override the base Video.js theme. 38 | You should include a new class matching the name of your theme, then just start overriding!

39 |
.vjs-skin-hotdog-stand { color: #FF0000; }
40 | .vjs-skin-hotdog-stand .vjs-control-bar { background: #FFFF00; }
41 | .vjs-skin-hotdog-stand .vjs-play-progress { background: #FF0000; }
42 | 
43 |

This would take care of the major areas of the skin (play progress, the control bar background, and icon colors), 44 | but you can skin any other aspect. 45 | Our suggestion is to use a browser such as Firefox and Chrome, 46 | and use the developer tools to inspect the different elements and see what you'd like to change and what classes 47 | to target when you do so.

48 |

More custom skins will be available for download soon. 49 | If you have one you like you can share it by forking this example on CodePen.io, 50 | and adding a link on the Skins wiki page.

51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /docs/guides/tech.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |

Playback Technology ("Tech")

14 |

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.

15 |

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.

16 |

Building an API Wrapper

17 |

We'll write a more complete guide on writing a wrapper soon, but for now the best resource is the Video.js source where you can see how both the HTML5 and video-js.swf API wrappers were created.

18 |

Required Methods

19 |

canPlayType 20 | play 21 | pause 22 | currentTime 23 | volume 24 | duration 25 | buffered 26 | supportsFullScreen

27 |

Required Events

28 |

loadstart 29 | play 30 | pause 31 | playing 32 | ended 33 | volumechange 34 | durationchange 35 | error

36 |

Optional Events (include if supported)

37 |

timeupdate 38 | progress 39 | enterFullScreen 40 | exitFullScreen

41 |

Adding Playback Technology

42 |

When adding additional Tech to a video player, make sure to add the supported tech to the video object.

43 |

Tag Method:

44 |
<video data-setup='{"techOrder": ["html5", "flash", "other supported tech"]}'
45 | 

Object Method:

46 |
videojs("videoID", {
47 |   techOrder: ["html5", "flash", "other supported tech"]
48 | });
49 | 

Technology Ordering

50 |

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.

51 |

Tech-first ordering can present a problem if you have a sourceHandler that supports both Html5 and Flash techs such as videojs-contrib-hls.

52 |

For example, given the following video element:

53 | 57 | 58 |

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.

59 |

In "Tech-first" mode, the tests run something like this: 60 | Can video.m3u8 play with Html5? No... 61 | Can video.mp4 play with Html5? Yes! Use the second source.

62 |

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.

63 |

With a player setup as follows:

64 | 68 | 69 |

The Flash-based HLS support will be tried before falling back to the MP4 source.

70 |

In "Source-first" mode, the tests run something like this: 71 | Can video.m3u8 play with Html5? No... 72 | Can video.m3u8 play with Flash? Yes! Use the first source.

73 |

Flash Technology

74 |

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.

75 |

Enabling Streaming Playback

76 |

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:

77 |
<source src="rtmp://your.streaming.provider.net/cfx/st/&mp4:path/to/video.mp4" type="rtmp/mp4">
78 | <source src="http://your.static.provider.net/path/to/video.mp4" type="video/mp4">
79 | <source src="http://your.static.provider.net/path/to/video.webm" type="video/webm">
80 | 

You may optionally use the last / as the separator between connection and stream strings, for example:

81 |
<source src="rtmp://your.streaming.provider.net/cfx/st/mp4:video.mp4" type="rtmp/mp4">
82 | 

All four RTMP protocols are valid in the src (RTMP, RTMPT, RTMPE, and RTMPS).

83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /docs/guides/tracks.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |

Tracks

14 |

There are currently three types of tracks

15 |
    16 |
  • AudioTracks - allows the selection of alternative AudioTracks for a video
  • 17 |
  • VideoTracks - allows the selection of an alternative VideoTrack for a video
  • 18 |
  • TextTracks - Text Tracks are used to display subtitles and captions, and add a menu for navigating between chapters in a video.
  • 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /docs/guides/video-tracks.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |

Video Tracks

14 |

Video Tracks are a function of HTML5 video for providing a selection of alternative video tracks to the user, so that they can change type of video they want to watch. Video.js makes video tracks work across all browsers. There are currently six types of tracks:

15 |
    16 |
  • Alternative: an alternative video representation of the main video track
  • 17 |
  • Captions: The main video track with burned in captions
  • 18 |
  • Main: the main video track
  • 19 |
  • Sign: the main video track with added sign language overlay
  • 20 |
  • Subtitles: the main video track with burned in subtitles
  • 21 |
  • Commentary: the main video track with burned in commentary
  • 22 |
23 |

Missing Funtionality

24 |
    25 |
  • It is currently impossible to add VideoTracks in a non-programtic way
  • 26 |
  • Literal switching of VideoTracks for playback is not handled by video.js and must be handled by something else. video.js only stores the track representation
  • 27 |
  • There is currently no UI implementation of VideoTracks
  • 28 |
29 |

Adding to Video.js

30 |
31 |

Right now adding video tracks in the HTML is unsupported. Video Tracks must be added programatically.

32 |
33 |

You must add video tracks programatically for the time being.

34 |

Attributes

35 |

Video Track propertites and settings

36 |

kind

37 |

One of the five track types listed above. Kind defaults to empty string if no kind is included, or an invalid kind is used.

38 |

label

39 |

The label for the track that will be show to the user, for example in a menu that list the different languages available for video tracks.

40 |

language

41 |

The two-letter code (valid BCP 47 language tag) for the language of the video track, for example "en" for English. A list of language codes is available here.

42 |

selected

43 |

If this track should be playing or not. Trying to select more than one track will cause other tracks to be deselected.

44 |

Interacting with Video Tracks

45 |

Doing something when a track becomes enabled

46 |

When a new track is enabled (other than the main track) an event is fired on the VideoTrackList called change you can listen to that event and do something with it. 47 | Here's an example:

48 |
// get the current players VideoTrackList object
49 | let tracks = player.videoTracks();
50 | 
51 | // listen to the change event
52 | tracks.addEventListener('change', function() {
53 |   // get the currently selected track
54 |   let index = tracks.selectedIndex;
55 |   let track = tracks[index];
56 | 
57 |   // print the currently selected track
58 |   console.log(track.label);
59 | });
60 | 
61 |

API

62 |

player.videoTracks() -> VideoTrackList

63 |

This is the main interface into the video tracks of the player. 64 | It returns an VideoTrackList which is an array like object that contains all the VideoTrack on the player.

65 |

player.videoTracks().addTrack(VideoTrack)

66 |

Add an existing VideoTrack to the players internal list of VideoTracks.

67 |

player.videoTracks().removeTrack(VideoTrack)

68 |

Remove a track from the VideoTrackList currently on the player. if no track exists this will do nothing.

69 |

player.videoTracks().selectedIndex

70 |

The current index for the selected track

71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /docs/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/videojs/docs/2aab67b2e50948c8e89513c68dd000d7b41dbc65/docs/images/logo.png -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 17 | 18 | 19 |
20 |
21 |

Videojs Documentation

22 |
23 |

Guides

24 |

Setup

25 |

Options

26 |

Tracks

27 |

Components

28 |

API

29 |

Skins

30 |

Languages

31 |

Tech

32 |

Plugins

33 |

Glossary

34 |
35 |
36 |

Samples

37 |

Simple Embed

38 |

Shared

39 |
40 |
41 |

API Reference

42 |

Videojs API

43 |
44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /docs/js/guides.js: -------------------------------------------------------------------------------- 1 | var BCLS = ( function () { 2 | var heading = document.getElementsByTagName('h1')[0], 3 | title = document.getElementsByTagName('title')[0], 4 | sections = document.getElementsByTagName('h2'), 5 | links = document.getElementsByTagName('a'), 6 | sidenav = document.getElementById('sidenav'), 7 | navList, 8 | navA, 9 | navItem, 10 | navText, 11 | i, 12 | iMax, 13 | item; 14 | 15 | /** 16 | * tests for all the ways a variable might be undefined or not have a value 17 | * @param {*} x the variable to test 18 | * @return {Boolean} true if variable is defined and has a value 19 | */ 20 | function isDefined (x){ 21 | if ( x === "" || x === null || x === undefined || x === NaN) { 22 | return false; 23 | } 24 | return true; 25 | } 26 | 27 | function buildSideNav() { 28 | if (isDefined(sections)) { 29 | var homeHead = document.createElement('p'), 30 | homeLink = document.createElement('a'); 31 | homeLink.setAttribute('href', '../../index.html'); 32 | homeLink.setAttribute('style', 'font-size:1.4em;font-weight:bold;text-align:right;margin:0;padding-left:1em'); 33 | homeLink.textContent = 'Docs Index'; 34 | homeHead.appendChild(homeLink); 35 | navList = document.createElement('ul'); 36 | navList.setAttribute('class', 'sidenav-list'); 37 | navItem = document.createElement('li'); 38 | navA = document.createElement('a'); 39 | navA.setAttribute('href', '#toc0'); 40 | navText = document.createTextNode('Top'); 41 | navA.appendChild(navText); 42 | navItem.appendChild(navA); 43 | navList.appendChild(navItem); 44 | iMax = sections.length; 45 | for (i = 0; i < iMax; i++) { 46 | item = sections[i]; 47 | navItem = document.createElement('li'); 48 | navA = document.createElement('a'); 49 | navA.setAttribute('href', '#' + item.id ); 50 | navText = document.createTextNode(item.textContent); 51 | navA.appendChild(navText); 52 | navItem.appendChild(navA); 53 | navList.appendChild(navItem); 54 | } 55 | sidenav.appendChild(homeHead); 56 | sidenav.appendChild(navList); 57 | } 58 | } 59 | 60 | /** 61 | * fix link paths to point to html instead of md 62 | */ 63 | function fixLinks() { 64 | var i, 65 | iMax = links.length, 66 | link, 67 | url; 68 | for (i = 0; i < iMax; i += 1) { 69 | link = links[i]; 70 | url = link.getAttribute('href'); 71 | if (isDefined(url)) { 72 | // if CONTRIBUTING.md, don't change 73 | if (url.indexOf('CONTRIBUTING.md' === -1)) { 74 | url.replace('.md', '.html'); 75 | link.setAttribute('href', url); 76 | } 77 | } 78 | } 79 | } 80 | 81 | /** 82 | * set the doc title 83 | */ 84 | function setTitle() { 85 | title.textContent = 'Videojs ' + heading.textContent; 86 | } 87 | 88 | /** 89 | * add the page footer 90 | */ 91 | function addFooter() { 92 | var path = document.location.pathname, 93 | footer = document.createElement('div'), 94 | srcLink = document.createElement('a'), 95 | srcLink2 = document.createElement('a'), 96 | main = document.getElementById('main'), 97 | srcPath, 98 | srcPath2; 99 | // extract file name 100 | if (path.indexOf('#') > 0) { 101 | path = path.substring(0, path.indexOf('#')); 102 | } 103 | path = path.substring(path.lastIndexOf('/') + 1); 104 | srcPath = 'https://github.com/videojs/video.js/blob/master/docs/guides/' + path; 105 | srcPath2 = 'https://github.com/videojs/docs'; 106 | footer.setAttribute('class', 'footer'); 107 | srcLink.setAttribute('href', srcPath); 108 | srcLink.appendChild(document.createTextNode('content source')); 109 | srcLink2.setAttribute('href', srcPath2); 110 | srcLink2.appendChild(document.createTextNode('doc generator')); 111 | footer.innerHTML = 'Want to contribute? Go to the '; 112 | footer.appendChild(srcLink); 113 | footer.innerHTML += ' or the '; 114 | footer.appendChild(srcLink2); 115 | main.appendChild(footer); 116 | } 117 | 118 | setTitle(); 119 | buildSideNav(); 120 | fixLinks(); 121 | addFooter(); 122 | })(); 123 | -------------------------------------------------------------------------------- /docs/js/home.js: -------------------------------------------------------------------------------- 1 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 5 | */ 6 | 'use strict'; 7 | 8 | /*eslint spaced-line-comment: 0 */ 9 | 10 | exports.handlers = { 11 | /// 12 | /// Convert ///-style comments into jsdoc comments. 13 | /// @param e 14 | /// @param e.filename 15 | /// @param e.source 16 | /// 17 | beforeParse: function(e) { 18 | e.source = e.source.replace(/(\n[ \t]*\/\/\/[^\n]*)+/g, function($) { 19 | var replacement = '\n/**' + $.replace(/^[ \t]*\/\/\//mg, '').replace(/(\n$|$)/, '*/$1'); 20 | return replacement; 21 | }); 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /plugins/commentsOnly.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @overview Remove everything in a file except JSDoc-style comments. By enabling this plugin, you 3 | * can document source files that are not valid JavaScript (including source files for other 4 | * languages). 5 | * @module plugins/commentsOnly 6 | * @author Jeff Williams 7 | */ 8 | 'use strict'; 9 | exports.handlers = { 10 | beforeParse: function(e) { 11 | var code = "//" 12 | var withoutspaces = e.source.replace(/^ +/gm, ''); 13 | var regex = /\/\*[\s\S]*?\*\/|(^[\s\S]*?$)/gm; 14 | var replaced = withoutspaces.replace(regex, function(m, group1) { 15 | if (group1) return code; 16 | else return m; 17 | }); 18 | e.source = replaced.replace(/^[ \t]*$\r?\n/gm,code+'\n'); 19 | } 20 | }; -------------------------------------------------------------------------------- /plugins/escapeHtml.js: -------------------------------------------------------------------------------- 1 | /** 2 | @overview Escape HTML tags in descriptions. 3 | @module plugins/escapeHtml 4 | @author Michael Mathews 5 | */ 6 | 'use strict'; 7 | 8 | exports.handlers = { 9 | /** 10 | Translate HTML tags in descriptions into safe entities. 11 | Replaces <, & and newlines 12 | */ 13 | newDoclet: function(e) { 14 | if (e.doclet.description) { 15 | e.doclet.description = e.doclet.description 16 | .replace(/&/g, '&') 17 | .replace(/'); 19 | } 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /plugins/eventDumper.js: -------------------------------------------------------------------------------- 1 | /*global env: true */ 2 | /** 3 | * @overview Dump information about parser events to the console. 4 | * @module plugins/eventDumper 5 | * @author Jeff Williams 6 | */ 7 | 'use strict'; 8 | 9 | var _ = require('underscore'); 10 | var util = require('util'); 11 | 12 | var conf = env.conf.eventDumper || {}; 13 | var isRhino = require('jsdoc/util/runtime').isRhino(); 14 | 15 | // Dump the included parser events (defaults to all events) 16 | var events = conf.include || [ 17 | 'parseBegin', 18 | 'fileBegin', 19 | 'beforeParse', 20 | 'jsdocCommentFound', 21 | 'symbolFound', 22 | 'newDoclet', 23 | 'fileComplete', 24 | 'parseComplete', 25 | 'processingComplete' 26 | ]; 27 | // Don't dump the excluded parser events 28 | if (conf.exclude) { 29 | events = _.difference(events, conf.exclude); 30 | } 31 | 32 | /** 33 | * Check whether a variable appears to be a Java native object. 34 | * 35 | * @param {*} o - The variable to check. 36 | * @return {boolean} Set to `true` for Java native objects and `false` in all other cases. 37 | */ 38 | function isJavaNativeObject(o) { 39 | if (!isRhino) { 40 | return false; 41 | } 42 | 43 | return o && typeof o === 'object' && typeof o.getClass === 'function'; 44 | } 45 | 46 | /** 47 | * Replace AST node objects in events with a placeholder. 48 | * 49 | * @param {Object} o - An object whose properties may contain AST node objects. 50 | * @return {Object} The modified object. 51 | */ 52 | function replaceNodeObjects(o) { 53 | var doop = require('jsdoc/util/doop'); 54 | 55 | var OBJECT_PLACEHOLDER = ''; 56 | 57 | if (o.code && o.code.node) { 58 | // don't break the original object! 59 | o.code = doop(o.code); 60 | o.code.node = OBJECT_PLACEHOLDER; 61 | } 62 | 63 | if (o.doclet && o.doclet.meta && o.doclet.meta.code && o.doclet.meta.code.node) { 64 | // don't break the original object! 65 | o.doclet.meta.code = doop(o.doclet.meta.code); 66 | o.doclet.meta.code.node = OBJECT_PLACEHOLDER; 67 | } 68 | 69 | if (o.astnode) { 70 | o.astnode = OBJECT_PLACEHOLDER; 71 | } 72 | 73 | return o; 74 | } 75 | 76 | /** 77 | * Get rid of unwanted crud in an event object. 78 | * 79 | * @param {object} e The event object. 80 | * @return {object} The fixed-up object. 81 | */ 82 | function cleanse(e) { 83 | var result = {}; 84 | 85 | Object.keys(e).forEach(function(prop) { 86 | // by default, don't stringify properties that contain an array of functions 87 | if (!conf.includeFunctions && util.isArray(e[prop]) && e[prop][0] && 88 | String(typeof e[prop][0]) === 'function') { 89 | result[prop] = 'function[' + e[prop].length + ']'; 90 | } 91 | // never include functions that belong to the object 92 | else if (typeof e[prop] !== 'function') { 93 | // don't call JSON.stringify() on Java native objects--Rhino will throw an exception 94 | result[prop] = isJavaNativeObject(e[prop]) ? String(e[prop]) : e[prop]; 95 | } 96 | }); 97 | 98 | // allow users to omit node objects, which can be enormous 99 | if (conf.omitNodes) { 100 | result = replaceNodeObjects(result); 101 | } 102 | 103 | return result; 104 | } 105 | 106 | exports.handlers = {}; 107 | 108 | events.forEach(function(eventType) { 109 | exports.handlers[eventType] = function(e) { 110 | console.log( JSON.stringify({ 111 | type: eventType, 112 | content: cleanse(e) 113 | }, null, 4) ); 114 | }; 115 | }); 116 | -------------------------------------------------------------------------------- /plugins/markdown.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @overview Translate doclet descriptions from MarkDown into HTML. 3 | * @module plugins/markdown 4 | * @author Michael Mathews 5 | * @author Ben Blank 6 | */ 7 | 'use strict'; 8 | 9 | var config = global.env.conf.markdown || {}; 10 | var defaultTags = [ 11 | 'author', 12 | 'classdesc', 13 | 'description', 14 | 'exceptions', 15 | 'params', 16 | 'properties', 17 | 'returns', 18 | 'see' 19 | ]; 20 | var hasOwnProp = Object.prototype.hasOwnProperty; 21 | var parse = require('jsdoc/util/markdown').getParser(); 22 | var tags = []; 23 | var excludeTags = []; 24 | 25 | function shouldProcessString(tagName, text) { 26 | var shouldProcess = true; 27 | 28 | // we only want to process `@author` and `@see` tags that contain Markdown links 29 | if ( (tagName === 'author' || tagName === 'see') && text.indexOf('[') === -1 ) { 30 | shouldProcess = false; 31 | } 32 | 33 | return shouldProcess; 34 | } 35 | 36 | /** 37 | * Process the markdown source in a doclet. The properties that should be 38 | * processed are configurable, but always include "classdesc", "description", 39 | * "params", "properties", and "returns". Handled properties can be bare 40 | * strings, objects, or arrays of objects. 41 | */ 42 | function process(doclet) { 43 | tags.forEach(function(tag) { 44 | if ( !hasOwnProp.call(doclet, tag) ) { 45 | return; 46 | } 47 | 48 | if (typeof doclet[tag] === 'string' && shouldProcessString(tag, doclet[tag]) ) { 49 | doclet[tag] = parse(doclet[tag]); 50 | } 51 | else if ( Array.isArray(doclet[tag]) ) { 52 | doclet[tag].forEach(function(value, index, original) { 53 | var inner = {}; 54 | inner[tag] = value; 55 | process(inner); 56 | original[index] = inner[tag]; 57 | }); 58 | } 59 | else if (doclet[tag]) { 60 | process(doclet[tag]); 61 | } 62 | }); 63 | } 64 | 65 | // set up the list of "tags" (properties) to process 66 | if (config.tags) { 67 | tags = config.tags.slice(); 68 | } 69 | // set up the list of default tags to exclude from processing 70 | if (config.excludeTags) { 71 | excludeTags = config.excludeTags.slice(); 72 | } 73 | defaultTags.forEach(function(tag) { 74 | if (excludeTags.indexOf(tag) === -1 && tags.indexOf(tag) === -1) { 75 | tags.push(tag); 76 | } 77 | }); 78 | 79 | exports.handlers = { 80 | /** 81 | * Translate markdown syntax in a new doclet's description into HTML. Is run 82 | * by JSDoc 3 whenever a "newDoclet" event fires. 83 | */ 84 | newDoclet: function(e) { 85 | process(e.doclet); 86 | } 87 | }; 88 | -------------------------------------------------------------------------------- /plugins/overloadHelper.js: -------------------------------------------------------------------------------- 1 | /** 2 | * The Overload Helper plugin automatically adds a signature-like string to the longnames of 3 | * overloaded functions and methods. In JSDoc, this string is known as a _variation_. (The longnames 4 | * of overloaded constructor functions are _not_ updated, so that JSDoc can identify the class' 5 | * members correctly.) 6 | * 7 | * Using this plugin allows you to link to overloaded functions without manually adding `@variation` 8 | * tags to your documentation. 9 | * 10 | * For example, suppose your code includes a function named `foo` that you can call in the 11 | * following ways: 12 | * 13 | * + `foo()` 14 | * + `foo(bar)` 15 | * + `foo(bar, baz)` (where `baz` is repeatable) 16 | * 17 | * This plugin assigns the following variations and longnames to each version of `foo`: 18 | * 19 | * + `foo()` gets the variation `()` and the longname `foo()`. 20 | * + `foo(bar)` gets the variation `(bar)` and the longname `foo(bar)`. 21 | * + `foo(bar, baz)` (where `baz` is repeatable) gets the variation `(bar, ...baz)` and the longname 22 | * `foo(bar, ...baz)`. 23 | * 24 | * You can then link to these functions with `{@link foo()}`, `{@link foo(bar)}`, and 25 | * `{@link foo(bar, ...baz)`. Note that the variation is based on the names of the function 26 | * parameters, _not_ their types. 27 | * 28 | * If you prefer to manually assign variations to certain functions, you can still do so with the 29 | * `@variation` tag. This plugin will not change these variations or add more variations for that 30 | * function, as long as the variations you've defined result in unique longnames. 31 | * 32 | * If an overloaded function includes multiple signatures with the same parameter names, the plugin 33 | * will assign numeric variations instead, starting at `(1)` and counting upwards. 34 | * 35 | * @module plugins/overloadHelper 36 | * @author Jeff Williams 37 | * @license Apache License 2.0 38 | */ 39 | 'use strict'; 40 | 41 | // lookup table of function doclets by longname 42 | var functionDoclets; 43 | 44 | function hasUniqueValues(obj) { 45 | var isUnique = true; 46 | var seen = []; 47 | Object.keys(obj).forEach(function(key) { 48 | if (seen.indexOf(obj[key]) !== -1) { 49 | isUnique = false; 50 | } 51 | 52 | seen.push(obj[key]); 53 | }); 54 | 55 | return isUnique; 56 | } 57 | 58 | function getParamNames(params) { 59 | var names = []; 60 | 61 | params.forEach(function(param) { 62 | var name = param.name || ''; 63 | if (param.variable) { 64 | name = '...' + name; 65 | } 66 | if (name !== '') { 67 | names.push(name); 68 | } 69 | }); 70 | 71 | return names.length ? names.join(', ') : ''; 72 | } 73 | 74 | function getParamVariation(doclet) { 75 | return getParamNames(doclet.params || []); 76 | } 77 | 78 | function getUniqueVariations(doclets) { 79 | var counter = 0; 80 | var variations = {}; 81 | var docletKeys = Object.keys(doclets); 82 | 83 | function getUniqueNumbers() { 84 | var format = require('util').format; 85 | 86 | docletKeys.forEach(function(doclet) { 87 | var newLongname; 88 | 89 | while (true) { 90 | counter++; 91 | variations[doclet] = String(counter); 92 | 93 | // is this longname + variation unique? 94 | newLongname = format('%s(%s)', doclets[doclet].longname, variations[doclet]); 95 | if ( !functionDoclets[newLongname] ) { 96 | break; 97 | } 98 | } 99 | }); 100 | } 101 | 102 | function getUniqueNames() { 103 | // start by trying to preserve existing variations 104 | docletKeys.forEach(function(doclet) { 105 | variations[doclet] = doclets[doclet].variation || getParamVariation(doclets[doclet]); 106 | }); 107 | 108 | // if they're identical, try again, without preserving existing variations 109 | if ( !hasUniqueValues(variations) ) { 110 | docletKeys.forEach(function(doclet) { 111 | variations[doclet] = getParamVariation(doclets[doclet]); 112 | }); 113 | 114 | // if they're STILL identical, switch to numeric variations 115 | if ( !hasUniqueValues(variations) ) { 116 | getUniqueNumbers(); 117 | } 118 | } 119 | } 120 | 121 | // are we already using numeric variations? if so, keep doing that 122 | if (functionDoclets[doclets.newDoclet.longname + '(1)']) { 123 | getUniqueNumbers(); 124 | } 125 | else { 126 | getUniqueNames(); 127 | } 128 | 129 | return variations; 130 | } 131 | 132 | function ensureUniqueLongname(newDoclet) { 133 | var doclets = { 134 | oldDoclet: functionDoclets[newDoclet.longname], 135 | newDoclet: newDoclet 136 | }; 137 | var docletKeys = Object.keys(doclets); 138 | var oldDocletLongname; 139 | var variations = {}; 140 | 141 | if (doclets.oldDoclet) { 142 | oldDocletLongname = doclets.oldDoclet.longname; 143 | // if the shared longname has a variation, like MyClass#myLongname(variation), 144 | // remove the variation 145 | if (doclets.oldDoclet.variation || doclets.oldDoclet.variation === '') { 146 | docletKeys.forEach(function(doclet) { 147 | doclets[doclet].longname = doclets[doclet].longname.replace(/\([\s\S]*\)$/, ''); 148 | doclets[doclet].variation = null; 149 | }); 150 | } 151 | 152 | variations = getUniqueVariations(doclets); 153 | 154 | // update the longnames/variations 155 | docletKeys.forEach(function(doclet) { 156 | doclets[doclet].longname += '(' + variations[doclet] + ')'; 157 | doclets[doclet].variation = variations[doclet]; 158 | }); 159 | 160 | // update the old doclet in the lookup table 161 | functionDoclets[oldDocletLongname] = null; 162 | functionDoclets[doclets.oldDoclet.longname] = doclets.oldDoclet; 163 | } 164 | 165 | // always store the new doclet in the lookup table 166 | functionDoclets[doclets.newDoclet.longname] = doclets.newDoclet; 167 | 168 | return doclets.newDoclet; 169 | } 170 | 171 | exports.handlers = { 172 | parseBegin: function() { 173 | functionDoclets = {}; 174 | }, 175 | 176 | newDoclet: function(e) { 177 | if (e.doclet.kind === 'function') { 178 | e.doclet = ensureUniqueLongname(e.doclet); 179 | } 180 | }, 181 | 182 | parseComplete: function() { 183 | functionDoclets = null; 184 | } 185 | }; 186 | -------------------------------------------------------------------------------- /plugins/partial.js: -------------------------------------------------------------------------------- 1 | /** 2 | @overview Adds support for reusable partial jsdoc files. 3 | @module plugins/partial 4 | @author Ludo Antonov 5 | */ 6 | 'use strict'; 7 | 8 | var fs = require('jsdoc/fs'); 9 | var path = require('path'); 10 | 11 | exports.handlers = { 12 | /** 13 | * Include a partial jsdoc 14 | * 15 | * @param e 16 | * @param e.filename 17 | * @param e.source 18 | * @example 19 | * @partial "partial_doc.jsdoc" 20 | */ 21 | beforeParse: function(e) { 22 | e.source = e.source.replace(/(@partial \".*\")+/g, function($) { 23 | var pathArg = $.match(/\".*\"/)[0].replace(/"/g, ''); 24 | var fullPath = path.join(e.filename, '..', pathArg); 25 | 26 | var partialData = fs.readFileSync(fullPath, global.env.opts.encoding); 27 | 28 | return partialData; 29 | }); 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /plugins/railsTemplate.js: -------------------------------------------------------------------------------- 1 | /** 2 | @overview Strips the rails template tags from a js.erb file 3 | @module plugins/railsTemplate 4 | @author Jannon Frank 5 | */ 6 | 'use strict'; 7 | 8 | exports.handlers = { 9 | /** 10 | * Remove rails tags from the source input (e.g. <% foo bar %>) 11 | * @param e 12 | * @param e.filename 13 | * @param e.source 14 | */ 15 | beforeParse: function(e) { 16 | if (e.filename.match(/\.erb$/)) { 17 | e.source = e.source.replace(/<%.*%>/g, ''); 18 | } 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /plugins/shout.js: -------------------------------------------------------------------------------- 1 | /** 2 | @overview This is just an example. 3 | @module plugins/shout 4 | @author Michael Mathews 5 | */ 6 | 'use strict'; 7 | 8 | exports.handlers = { 9 | /** 10 | Make your descriptions more shoutier. 11 | */ 12 | newDoclet: function(e) { 13 | if (typeof e.doclet.description === 'string') { 14 | e.doclet.description = e.doclet.description.toUpperCase(); 15 | } 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /plugins/sourcetag.js: -------------------------------------------------------------------------------- 1 | /** 2 | @module plugins/sourcetag 3 | @author Michael Mathews 4 | */ 5 | 'use strict'; 6 | 7 | var logger = require('jsdoc/util/logger'); 8 | 9 | exports.handlers = { 10 | /** 11 | Support @source tag. Expected value like: 12 | { "filename": "myfile.js", "lineno": 123 } 13 | Modifies the corresponding meta values on the given doclet. 14 | 15 | WARNING: If you are using a JSDoc template that generates pretty-printed source files, 16 | such as JSDoc's default template, this plugin can cause JSDoc to crash. To fix this issue, 17 | update your template settings to disable pretty-printed source files. 18 | 19 | @source { "filename": "sourcetag.js", "lineno": 13 } 20 | */ 21 | newDoclet: function(e) { 22 | var tags = e.doclet.tags, 23 | tag, 24 | value; 25 | 26 | // any user-defined tags in this doclet? 27 | if (typeof tags !== 'undefined') { 28 | // only interested in the @source tags 29 | tags = tags.filter(function($) { 30 | return $.title === 'source'; 31 | }); 32 | 33 | if (tags.length) { 34 | // take the first one 35 | tag = tags[0]; 36 | 37 | try { 38 | value = JSON.parse(tag.value); 39 | } 40 | catch(e) { 41 | logger.error('@source tag expects a valid JSON value, like { "filename": "myfile.js", "lineno": 123 }.'); 42 | return; 43 | } 44 | 45 | e.doclet.meta = e.doclet.meta || {}; 46 | e.doclet.meta.filename = value.filename || ''; 47 | e.doclet.meta.lineno = value.lineno || ''; 48 | } 49 | } 50 | } 51 | }; 52 | -------------------------------------------------------------------------------- /plugins/summarize.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @overview This plugin creates a summary tag, if missing, from the first sentence in the 3 | * description. 4 | * @module plugins/summarize 5 | * @author Mads Bondo Dydensborg 6 | */ 7 | 'use strict'; 8 | 9 | exports.handlers = { 10 | /** 11 | * Autogenerate summaries, if missing, from the description, if present. 12 | */ 13 | newDoclet: function(e) { 14 | var endTag; 15 | var tags; 16 | var stack; 17 | 18 | // If the summary is missing, grab the first sentence from the description 19 | // and use that. 20 | if (e.doclet && !e.doclet.summary && e.doclet.description) { 21 | // The summary may end with `.$`, `. `, or `.<` (a period followed by an HTML tag). 22 | e.doclet.summary = e.doclet.description.split(/\.$|\.\s|\.]+>/g) || []; 29 | stack = []; 30 | 31 | tags.forEach(function(tag) { 32 | var idx = tag.indexOf('/'); 33 | 34 | if (idx === -1) { 35 | // start tag -- push onto the stack 36 | stack.push(tag); 37 | } else if (idx === 1) { 38 | // end tag -- pop off of the stack 39 | stack.pop(); 40 | } 41 | 42 | // otherwise, it's a self-closing tag; don't modify the stack 43 | }); 44 | 45 | // stack should now contain only the start tags that lack end tags, 46 | // with the most deeply nested start tag at the top 47 | while (stack.length > 0) { 48 | // pop the unmatched tag off the stack 49 | endTag = stack.pop(); 50 | // get just the tag name 51 | endTag = endTag.substring(1, endTag.search(/[ >]/)); 52 | // append the end tag 53 | e.doclet.summary += ''; 54 | } 55 | 56 | // and, finally, if the summary starts and ends with a

tag, remove it; let the 57 | // template decide whether to wrap the summary in a

tag 58 | e.doclet.summary = e.doclet.summary.replace(/^

(.*)<\/p>$/i, '$1'); 59 | } 60 | } 61 | }; 62 | -------------------------------------------------------------------------------- /plugins/test/fixtures/markdown.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * @see [Nowhere](http://nowhere.com) 5 | */ 6 | function foo() {} 7 | 8 | /** 9 | * @see AnObject#myProperty 10 | */ 11 | function bar() {} 12 | 13 | /** 14 | * @author [Mr. Macintosh](http://www.folklore.org/StoryView.py?story=Mister_Macintosh.txt) 15 | * @classdesc My class. 16 | * @description My class. 17 | * @exception {Error} Some error. 18 | * @param {string} myParam - My parameter. 19 | * @property {string} value - Value of myParam. 20 | * @return {MyClass} Class instance. 21 | * @see [Example Inc.](http://example.com) 22 | */ 23 | function MyClass(myParam) { 24 | this.value = myParam; 25 | } 26 | -------------------------------------------------------------------------------- /plugins/test/fixtures/overloadHelper.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A bowl of non-spicy soup. 3 | * @class 4 | *//** 5 | * A bowl of spicy soup. 6 | * @class 7 | * @param {number} spiciness - The spiciness of the soup, in Scoville heat units (SHU). 8 | */ 9 | function Soup(spiciness) {} 10 | 11 | /** 12 | * Slurp the soup. 13 | *//** 14 | * Slurp the soup loudly. 15 | * @param {number} dBA - The slurping volume, in A-weighted decibels. 16 | */ 17 | Soup.prototype.slurp = function(dBA) {}; 18 | 19 | /** 20 | * Salt the soup as needed, using a highly optimized soup-salting heuristic. 21 | *//** 22 | * Salt the soup, specifying the amount of salt to add. 23 | * @variation mg 24 | * @param {number} amount - The amount of salt to add, in milligrams. 25 | */ 26 | Soup.prototype.salt = function(amount) {}; 27 | 28 | /** 29 | * Heat the soup by the specified number of degrees. 30 | * @param {number} degrees - The number of degrees, in Fahrenheit, by which to heat the soup. 31 | *//** 32 | * Heat the soup by the specified number of degrees. 33 | * @variation 1 34 | * @param {string} degrees - The number of degrees, in Fahrenheit, by which to heat the soup, but 35 | * as a string for some reason. 36 | *//** 37 | * Heat the soup by the specified number of degrees. 38 | * @param {boolean} degrees - The number of degrees, as a boolean. Wait, what? 39 | */ 40 | Soup.prototype.heat = function(degrees) {}; 41 | 42 | /** 43 | * Discard the soup. 44 | * @variation discardSoup 45 | *//** 46 | * Discard the soup by pouring it into the specified container. 47 | * @variation discardSoup 48 | * @param {Object} container - The container in which to discard the soup. 49 | */ 50 | Soup.prototype.discard = function(container) {}; 51 | -------------------------------------------------------------------------------- /plugins/test/fixtures/railsTemplate.js.erb: -------------------------------------------------------------------------------- 1 | /** 2 | @overview Strips the rails template tags from a js.erb file 3 | @module plugins/railsTemplate 4 | @author Jannon Frank 5 | */ 6 | 7 | exports.handlers = { 8 | /** 9 | * Remove rails tags from the source input (e.g. <% foo bar %>) 10 | * @param e 11 | * @param e.filename 12 | * @param e.source 13 | */ 14 | beforeParse: function(e) { 15 | if (e.filename.match(/\.erb$/)) { 16 | e.source = e.source.replace(/<%.*%> /g, ""); 17 | } 18 | } 19 | }; -------------------------------------------------------------------------------- /plugins/test/fixtures/underscore.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** This doclet will be shown by default, just like normal. */ 4 | function normal() {} 5 | 6 | /** This doclet will be hidden by default because it begins with an underscore. */ 7 | function _hidden() {} 8 | 9 | /** 10 | * Klass class 11 | * @class 12 | */ 13 | function Klass() { 14 | /** This is a private property of the class, and should not. */ 15 | this._privateProp = null; 16 | 17 | /** 18 | * This is a property explicitly marked as private. 19 | * @private 20 | */ 21 | this.privateProp = null; 22 | } 23 | -------------------------------------------------------------------------------- /plugins/test/specs/commentConvert.js: -------------------------------------------------------------------------------- 1 | /*global describe: true, env: true, expect: true, it: true, jasmine: true */ 2 | describe("commentConvert plugin", function() { 3 | var parser = jasmine.createParser(); 4 | var path = require('jsdoc/path'); 5 | 6 | var docSet; 7 | 8 | var pluginPath = 'plugins/commentConvert'; 9 | var pluginPathResolved = path.join(env.dirname, pluginPath); 10 | var plugin = require(pluginPathResolved); 11 | 12 | require('jsdoc/plugins').installPlugins([pluginPathResolved], parser); 13 | docSet = jasmine.getDocSetFromFile(pluginPath + '.js', parser); 14 | 15 | it("should convert '///-style comments into jsdoc comments", function() { 16 | var doclet = docSet.getByLongname("module:plugins/commentConvert.handlers.beforeParse"); 17 | expect(doclet.length).toEqual(1); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /plugins/test/specs/escapeHtml.js: -------------------------------------------------------------------------------- 1 | /*global describe: true, env: true, expect: true, it: true, jasmine: true */ 2 | describe("escapeHtml plugin", function() { 3 | var parser = jasmine.createParser(); 4 | var path = require('jsdoc/path'); 5 | 6 | var docSet; 7 | 8 | var pluginPath = 'plugins/escapeHtml'; 9 | var pluginPathResolved = path.join(env.dirname,pluginPath); 10 | var plugin = require(pluginPathResolved); 11 | 12 | require('jsdoc/plugins').installPlugins([pluginPathResolved], parser); 13 | docSet = jasmine.getDocSetFromFile(pluginPath + '.js', parser); 14 | 15 | it("should escape '&', '<' and newlines in doclet descriptions", function() { 16 | var doclet = docSet.getByLongname("module:plugins/escapeHtml.handlers.newDoclet"); 17 | expect(doclet[0].description).toEqual("Translate HTML tags in descriptions into safe entities.
Replaces <, & and newlines"); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /plugins/test/specs/markdown.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('jsdoc/path'); 4 | 5 | describe('markdown plugin', function() { 6 | var pluginPath = 'plugins/markdown'; 7 | var pluginPathResolved = path.join(global.env.dirname, pluginPath); 8 | var plugin = require(pluginPathResolved); 9 | 10 | var docSet = jasmine.getDocSetFromFile('plugins/test/fixtures/markdown.js'); 11 | 12 | // TODO: more tests; refactor the plugin so multiple settings can be tested 13 | 14 | it('should process the correct tags by default', function() { 15 | var myClass = docSet.getByLongname('MyClass')[0]; 16 | 17 | plugin.handlers.newDoclet({ doclet: myClass }); 18 | [ 19 | myClass.author[0], 20 | myClass.classdesc, 21 | myClass.description, 22 | myClass.exceptions[0].description, 23 | myClass.params[0].description, 24 | myClass.properties[0].description, 25 | myClass.returns[0].description, 26 | myClass.see 27 | ].forEach(function(value) { 28 | // if we processed the value, it should be wrapped in a

tag 29 | expect( /^

(?:.+)<\/p>$/.test(value) ).toBe(true); 30 | }); 31 | }); 32 | 33 | describe('@see tag support', function() { 34 | var foo = docSet.getByLongname('foo')[0]; 35 | var bar = docSet.getByLongname('bar')[0]; 36 | 37 | it('should parse @see tags containing links', function() { 38 | plugin.handlers.newDoclet({ doclet: foo }); 39 | expect(typeof foo).toEqual('object'); 40 | expect(foo.see[0]).toEqual('

Nowhere

'); 41 | }); 42 | 43 | it('should not parse @see tags that do not contain links', function() { 44 | plugin.handlers.newDoclet({ doclet: bar }); 45 | expect(typeof bar).toEqual('object'); 46 | expect(bar.see[0]).toEqual('AnObject#myProperty'); 47 | }); 48 | }); 49 | }); 50 | -------------------------------------------------------------------------------- /plugins/test/specs/overloadHelper.js: -------------------------------------------------------------------------------- 1 | /*global describe: true, env: true, expect: true, it: true, jasmine: true, xit: true */ 2 | describe('plugins/overloadHelper', function() { 3 | var parser = jasmine.createParser(); 4 | var path = require('jsdoc/path'); 5 | 6 | var docSet; 7 | 8 | var pluginPath = 'plugins/overloadHelper'; 9 | var pluginPathResolved = path.resolve(env.dirname, pluginPath); 10 | var plugin = require(pluginPathResolved); 11 | 12 | require('jsdoc/plugins').installPlugins([pluginPathResolved], parser); 13 | docSet = jasmine.getDocSetFromFile('plugins/test/fixtures/overloadHelper.js', parser); 14 | 15 | it('should exist', function() { 16 | expect(plugin).toBeDefined(); 17 | expect(typeof plugin).toBe('object'); 18 | }); 19 | 20 | it('should export handlers', function() { 21 | expect(plugin.handlers).toBeDefined(); 22 | expect(typeof plugin.handlers).toBe('object'); 23 | }); 24 | 25 | it('should export a "newDoclet" handler', function() { 26 | expect(plugin.handlers.newDoclet).toBeDefined(); 27 | expect(typeof plugin.handlers.newDoclet).toBe('function'); 28 | }); 29 | 30 | it('should export a "parseComplete" handler', function() { 31 | expect(plugin.handlers.parseComplete).toBeDefined(); 32 | expect(typeof plugin.handlers.parseComplete).toBe('function'); 33 | }); 34 | 35 | describe('newDoclet handler', function() { 36 | it('should not add unique longnames to constructors', function() { 37 | var soup = docSet.getByLongname('Soup'); 38 | var soup1 = docSet.getByLongname('Soup()'); 39 | var soup2 = docSet.getByLongname('Soup(spiciness)'); 40 | 41 | expect(soup.length).toBe(2); 42 | expect(soup1.length).toBe(0); 43 | expect(soup2.length).toBe(0); 44 | }); 45 | 46 | it('should add unique longnames to methods', function() { 47 | var slurp = docSet.getByLongname('Soup#slurp'); 48 | var slurp1 = docSet.getByLongname('Soup#slurp()'); 49 | var slurp2 = docSet.getByLongname('Soup#slurp(dBA)'); 50 | 51 | expect(slurp.length).toBe(0); 52 | expect(slurp1.length).toBe(1); 53 | expect(slurp2.length).toBe(1); 54 | }); 55 | 56 | it('should update the "variation" property of the method', function() { 57 | var slurp1 = docSet.getByLongname('Soup#slurp()')[0]; 58 | var slurp2 = docSet.getByLongname('Soup#slurp(dBA)')[0]; 59 | 60 | expect(slurp1.variation).toBe(''); 61 | expect(slurp2.variation).toBe('dBA'); 62 | }); 63 | 64 | it('should not add to or change existing variations that are unique', function() { 65 | var salt1 = docSet.getByLongname('Soup#salt'); 66 | var salt2 = docSet.getByLongname('Soup#salt(mg)'); 67 | 68 | expect(salt1.length).toBe(1); 69 | expect(salt2.length).toBe(1); 70 | }); 71 | 72 | it('should not duplicate the names of existing numeric variations', function() { 73 | var heat1 = docSet.getByLongname('Soup#heat(1)'); 74 | var heat2 = docSet.getByLongname('Soup#heat(2)'); 75 | var heat3 = docSet.getByLongname('Soup#heat(3)'); 76 | 77 | expect(heat1.length).toBe(1); 78 | expect(heat2.length).toBe(1); 79 | expect(heat3.length).toBe(1); 80 | }); 81 | 82 | it('should replace identical variations with new, unique variations', function() { 83 | var discard1 = docSet.getByLongname('Soup#discard()'); 84 | var discard2 = docSet.getByLongname('Soup#discard(container)'); 85 | 86 | expect(discard1.length).toBe(1); 87 | expect(discard2.length).toBe(1); 88 | }); 89 | }); 90 | 91 | describe('parseComplete handler', function() { 92 | // disabled because on the second run, each comment is being parsed twice; who knows why... 93 | xit('should not retain parse results between parser runs', function() { 94 | parser.clear(); 95 | docSet = jasmine.getDocSetFromFile('plugins/test/fixtures/overloadHelper.js', parser); 96 | var heat = docSet.getByLongname('Soup#heat(4)'); 97 | 98 | expect(heat.length).toBe(0); 99 | }); 100 | }); 101 | }); 102 | -------------------------------------------------------------------------------- /plugins/test/specs/railsTemplate.js: -------------------------------------------------------------------------------- 1 | /*global describe: true, env: true, expect: true, it: true, jasmine: true */ 2 | describe("railsTemplate plugin", function() { 3 | var parser = jasmine.createParser(); 4 | var path = require('jsdoc/path'); 5 | 6 | var pluginPath = path.join(env.dirname, 'plugins/railsTemplate'); 7 | var plugin = require(pluginPath); 8 | 9 | require('jsdoc/plugins').installPlugins([pluginPath], parser); 10 | require('jsdoc/src/handlers').attachTo(parser); 11 | 12 | it("should remove <% %> rails template tags from the source of *.erb files", function() { 13 | var docSet = parser.parse([path.join(env.dirname, "plugins/test/fixtures/railsTemplate.js.erb")]); 14 | 15 | expect(docSet[2].description).toEqual("Remove rails tags from the source input (e.g. )"); 16 | }); 17 | }); -------------------------------------------------------------------------------- /plugins/test/specs/shout.js: -------------------------------------------------------------------------------- 1 | /*global describe: true, env: true, expect: true, it: true, jasmine: true */ 2 | describe("shout plugin", function() { 3 | var parser = jasmine.createParser(); 4 | var path = require('jsdoc/path'); 5 | 6 | var docSet; 7 | 8 | var pluginPath = 'plugins/shout'; 9 | var pluginPathResolved = path.join(env.dirname, pluginPath); 10 | var plugin = require(pluginPathResolved); 11 | 12 | require('jsdoc/plugins').installPlugins([pluginPathResolved], parser); 13 | docSet = jasmine.getDocSetFromFile(pluginPath + '.js', parser); 14 | 15 | it("should make the description uppercase", function() { 16 | var doclet = docSet.getByLongname("module:plugins/shout.handlers.newDoclet"); 17 | expect(doclet[0].description).toEqual("MAKE YOUR DESCRIPTIONS MORE SHOUTIER."); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /plugins/test/specs/sourcetag.js: -------------------------------------------------------------------------------- 1 | /*global describe, expect, it, jasmine */ 2 | 'use strict'; 3 | 4 | describe('sourcetag plugin', function() { 5 | var parser = jasmine.createParser(); 6 | var path = require('jsdoc/path'); 7 | 8 | var docSet; 9 | 10 | var pluginPath = 'plugins/sourcetag'; 11 | var pluginPathResolved = path.join(global.env.dirname, pluginPath); 12 | var plugin = require(pluginPathResolved); 13 | 14 | require('jsdoc/plugins').installPlugins([pluginPathResolved], parser); 15 | docSet = jasmine.getDocSetFromFile(pluginPath + '.js', parser); 16 | 17 | it("should set the lineno and filename of the doclet's meta property", function() { 18 | var doclet = docSet.getByLongname('module:plugins/sourcetag.handlers.newDoclet'); 19 | expect(doclet[0].meta).toBeDefined(); 20 | expect(doclet[0].meta.filename).toEqual('sourcetag.js'); 21 | expect(doclet[0].meta.lineno).toEqual(13); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /plugins/test/specs/summarize.js: -------------------------------------------------------------------------------- 1 | /*global describe, expect, it */ 2 | 'use strict'; 3 | 4 | var summarize = require('../../summarize'); 5 | 6 | describe('summarize', function() { 7 | it('should export handlers', function() { 8 | expect(summarize.handlers).toBeDefined(); 9 | expect(typeof summarize.handlers).toBe('object'); 10 | }); 11 | 12 | it('should export a newDoclet handler', function() { 13 | expect(summarize.handlers.newDoclet).toBeDefined(); 14 | expect(typeof summarize.handlers.newDoclet).toBe('function'); 15 | }); 16 | 17 | describe('newDoclet handler', function() { 18 | var handler = summarize.handlers.newDoclet; 19 | 20 | it('should not blow up if the doclet is missing', function() { 21 | function noDoclet() { 22 | return handler({}); 23 | } 24 | 25 | expect(noDoclet).not.toThrow(); 26 | }); 27 | 28 | it('should not change the summary if it is already defined', function() { 29 | var doclet = { 30 | summary: 'This is a summary.', 31 | description: 'Descriptions are good.' 32 | }; 33 | handler({ doclet: doclet }); 34 | 35 | expect(doclet.summary).not.toBe(doclet.description); 36 | }); 37 | 38 | it('should not do anything if the description is missing', function() { 39 | var doclet = {}; 40 | handler({ doclet: doclet }); 41 | 42 | expect(doclet.summary).not.toBeDefined(); 43 | }); 44 | 45 | it('should use the first sentence as the summary', function() { 46 | var doclet = { 47 | description: 'This sentence is the summary. This sentence is not.' 48 | }; 49 | handler({ doclet: doclet }); 50 | 51 | expect(doclet.summary).toBe('This sentence is the summary.'); 52 | }); 53 | 54 | it('should not add an extra period if there is only one sentence in the description', 55 | function() { 56 | var doclet = { 57 | description: 'This description has only one sentence.' 58 | }; 59 | handler({ doclet: doclet }); 60 | 61 | expect(doclet.summary).toBe('This description has only one sentence.'); 62 | }); 63 | 64 | it('should use the entire description, plus a period, as the summary if the description ' + 65 | 'does not contain a period', function() { 66 | var doclet = { 67 | description: 'This is a description' 68 | }; 69 | handler({ doclet: doclet }); 70 | 71 | expect(doclet.summary).toBe('This is a description.'); 72 | }); 73 | 74 | it('should use the entire description as the summary if the description contains only ' + 75 | 'one sentence', function() { 76 | var doclet = { 77 | description: 'This is a description.' 78 | }; 79 | handler({ doclet: doclet }); 80 | 81 | expect(doclet.description).toBe('This is a description.'); 82 | }); 83 | 84 | it('should work when an HTML tag immediately follows the first sentence', function() { 85 | var doclet = { 86 | description: 'This sentence is the summary.This sentence is small.' 87 | }; 88 | handler({ doclet: doclet }); 89 | 90 | expect(doclet.summary).toBe('This sentence is the summary.'); 91 | }); 92 | 93 | it('should generate valid HTML if a tag is opened, but not closed, in the summary', 94 | function() { 95 | var doclet = { 96 | description: 'This description has a tag. The tag straddles sentences.' 97 | }; 98 | handler({ doclet: doclet }); 99 | 100 | expect(doclet.summary).toBe('This description has a tag.'); 101 | }); 102 | 103 | it('should not include a

tag in the summary', function() { 104 | var doclet = { 105 | description: '

This description contains HTML.

And plenty of it!

' 106 | }; 107 | handler({ doclet: doclet }); 108 | 109 | expect(doclet.summary).toBe('This description contains HTML.'); 110 | }); 111 | }); 112 | }); 113 | -------------------------------------------------------------------------------- /plugins/test/specs/underscore.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('underscore plugin', function () { 4 | var parser = jasmine.createParser(); 5 | var path = require('jsdoc/path'); 6 | 7 | var docSet; 8 | 9 | var pluginPath = 'plugins/underscore'; 10 | var fixturePath = 'plugins/test/fixtures/underscore'; 11 | var pluginPathResolved = path.join(env.dirname, pluginPath); 12 | var plugin = require(pluginPathResolved); 13 | 14 | require('jsdoc/plugins').installPlugins([pluginPathResolved], parser); 15 | docSet = jasmine.getDocSetFromFile(fixturePath + '.js', parser); 16 | 17 | it('should not mark normal, public properties as private', function() { 18 | // Base line tests 19 | var normal = docSet.getByLongname('normal'); 20 | expect(normal[0].access).toBeUndefined(); 21 | 22 | var realPrivate = docSet.getByLongname('Klass#privateProp'); 23 | expect(realPrivate[0].access).toEqual('private'); 24 | }); 25 | 26 | it('should hide doclet for symbols beginning with an underscore under normal circumstances', function () { 27 | var hidden = docSet.getByLongname('_hidden'); 28 | expect(hidden[0].access).toEqual('private'); 29 | }); 30 | 31 | it('picks up "this"', function() { 32 | var privateUnderscore = docSet.getByLongname('Klass#_privateProp'); 33 | expect(privateUnderscore[0].access).toEqual('private'); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /plugins/underscore.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Removes all symbols that begin with an underscore from the doc output. If 5 | * you're using underscores to denote private variables in modules, this 6 | * automatically hides them. 7 | * 8 | * @module plugins/underscore 9 | * @author Daniel Ellis 10 | */ 11 | 12 | exports.handlers = { 13 | newDoclet: function(e) { 14 | var doclet = e.doclet; 15 | 16 | // Ignore comment blocks for all symbols that begin with underscore 17 | if (doclet.name.charAt(0) === '_' || doclet.name.substr(0, 6) === 'this._') { 18 | doclet.access = 'private'; 19 | } 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /semicolon.txt: -------------------------------------------------------------------------------- 1 | ; -------------------------------------------------------------------------------- /templates/guide-template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 | <%=content%> 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /var-name.txt: -------------------------------------------------------------------------------- 1 | var docData = --------------------------------------------------------------------------------