diff --git a/docs/tutorials/architecture.md b/docs/tutorials/architecture.md
new file mode 100644
index 000000000..27be1a40e
--- /dev/null
+++ b/docs/tutorials/architecture.md
@@ -0,0 +1,12 @@
+# Architecture Diagrams
+
+
+
+
+
diff --git a/docs/tutorials/basic-usage.md b/docs/tutorials/basic-usage.md
index 0ac00ed29..42129bf9d 100644
--- a/docs/tutorials/basic-usage.md
+++ b/docs/tutorials/basic-usage.md
@@ -5,17 +5,12 @@ Basic usage of Shaka Player is very easy:
1. Start with {@tutorial welcome} and compile the library.
2. Create a simple HTML page with a video element.
3. In your application's JavaScript:
- 1. Install polyfills.
+ 1. Install Shaka's polyfills.
2. Check for browser support.
3. Create a Player object to wrap the video element.
4. Listen for errors.
5. Load a manifest.
-*NOTE: For simplicity, we will use `alert()` for errors in this tutorial.
-In a real application, you would want a more appropriate mechanism to display
-errors to your users.*
-
-
```html
@@ -44,13 +39,15 @@ function initApp() {
shaka.polyfill.installAll();
// Check to see if the browser supports the basic APIs Shaka needs.
+ // This is an asynchronous check.
shaka.Player.support().then(function(support) {
+ // This executes when the asynchronous check is complete.
if (support.supported) {
// Everything looks good!
initPlayer();
} else {
// This browser does not have the minimum set of APIs we need.
- alert('Browser not supported!');
+ console.error('Browser not supported!');
}
});
}
@@ -67,9 +64,11 @@ function initPlayer() {
player.addEventListener('error', onErrorEvent);
// Try to load a manifest.
+ // This is an asynchronous process.
player.load(manifestUri).then(function() {
- // The video has now been loaded!
- }).catch(onError);
+ // This runs if the asynchronous load is successful.
+ console.log('The video has now been loaded!');
+ }).catch(onError); // onError is executed if the asynchronous load fails.
}
function onErrorEvent(event) {
@@ -79,8 +78,7 @@ function onErrorEvent(event) {
function onError(error) {
// Log the error.
- console.error(error);
- alert('Error code ' + error.code);
+ console.error('Error code', error.code, 'object', error);
}
document.addEventListener('DOMContentLoaded', initApp);
diff --git a/docs/tutorials/debugging.md b/docs/tutorials/debugging.md
index 95da5c26a..a8729fc76 100644
--- a/docs/tutorials/debugging.md
+++ b/docs/tutorials/debugging.md
@@ -12,7 +12,7 @@ First, let's make `manifestUri` blank.
var manifestUri = '';
```
-This causes an alert that says "Error code 4000". What now?
+This causes an error in the console that says "Error code 4000". What now?
#### Use the JS console
@@ -49,13 +49,17 @@ need to load the uncompiled library.
Instead of the single-file compiled library, we need to load three scripts in
our HTML file:
-1. Closure's base library
-2. A dependency file which maps Shaka's class names to source files
-3. The uncompiled library's bootstrap file, "shaka-player.uncompiled.js"
+1. Closure's base library. (This is a small JavaScript library related to the
+ Closure compiler used when we build Shaka.) This is what loads Shaka without
+ requiring you to list all 50+ source files.
+2. A dependency file which maps Shaka's class names to source files. This is
+ how Closure's base library can locate all of Shaka's individual source files.
+3. The uncompiled Shaka library's bootstrap file, "shaka-player.uncompiled.js".
+ This uses Closure to load the top-level parts of the library. Each of those
+ files in turn load their internal dependencies.
-The uncompiled library's bootstrap file will use Closure to "require" each of
-the exported classes in the library. This causes the entire library to be
-loaded, one uncompiled source file at a time.
+Once we're using the uncompiled library, we will be able to see detailed logs
+and line numbers for errors. It is difficult to debug without this.
```html
@@ -77,7 +81,7 @@ Reload the page and look in the JavaScript console. Now we see:
Unable to guess manifest type by file extension or by MIME type.
undefined text/html player.js:297
-s…a.u…l.Error {category: 4, code: 4000, data: Array[1],
+Error {category: 4, code: 4000, data: Array[1],
message: "Shaka Error MANIFEST.UNABLE_TO_GUESS_MANIFEST_TYPE ()",
stack: "Error: Shaka Error… at http://localhost/shaka/lib/player.js:300:35"}
```
@@ -85,7 +89,10 @@ s…a.u…l.Error {category: 4, code: 4000, data: Array[1],
So much more information! The uncompiled library includes a log from Player
(player.js, line 297) right before the error was dispatched, and the error
includes a message that gives the full human-readable name of the error:
-`MANIFEST.UNABLE_TO_GUESS_MANIFEST_TYPE`.
+`MANIFEST.UNABLE_TO_GUESS_MANIFEST_TYPE`. The `MANIFEST` part is the textual
+name for category: 4, and `UNABLE_TO_GUESS_MANIFEST_TYPE` is the textual name
+for code: 4000. (A full list can be found in the docs for
+{@link shaka.util.Error}).
There's also a `stack` field showing the context in which it was generated:
@@ -125,7 +132,7 @@ To keep the API simple, Shaka tries to guess what type of manifest you want to
load. It does this first based on extension, and if that fails, it makes a HEAD
request and checks the MIME type.
-A request for "" is interpretted as a relative URL. What we actually requested
+A request for "" is interpreted as a relative URL. What we actually requested
was the index page for the folder the HTML is in.
Since the file extension of "" was `undefined`, and the MIME type was
diff --git a/docs/tutorials/drm-config.md b/docs/tutorials/drm-config.md
index 27fdc696e..de9d545d3 100644
--- a/docs/tutorials/drm-config.md
+++ b/docs/tutorials/drm-config.md
@@ -41,9 +41,9 @@ particular key system at all, but instead state that any CENC system will do:
```
If this is the only `` element in the manifest, Shaka will
-try {@link shaka.dash.ContentProtection.defaultKeySystems\_ all key systems
-it knows}. If the browser supports it and you configured a license server URL
-for it, we'll use it.
+try {@linksource shaka.dash.ContentProtection.defaultKeySystems\_ all key
+systems it knows}. If the browser supports it and you configured a license
+server URL for it, we'll use it.
#### Clear Key
diff --git a/docs/tutorials/index.json b/docs/tutorials/index.json
index 0e91951ea..e18beb4ff 100644
--- a/docs/tutorials/index.json
+++ b/docs/tutorials/index.json
@@ -12,5 +12,6 @@
{ "offline": { "title": "Offline Storage and Playback" } }
] } },
{ "plugins": { "title": "Plugins and Customizing the Build" } },
+ { "architecture": { "title": "Architecture Diagrams" } },
{ "upgrade": { "title": "Shaka v2 Upgrade Guide" } }
]
diff --git a/docs/tutorials/license-server-auth.md b/docs/tutorials/license-server-auth.md
index 2e3c3ec59..d73a36478 100644
--- a/docs/tutorials/license-server-auth.md
+++ b/docs/tutorials/license-server-auth.md
@@ -2,7 +2,7 @@
Your application's license server may require some form of authentication so
that it only delivers licenses to paying users. In this tutorial, we're going
-to use different license server endpoints that require different forms of
+to use various license server endpoints that require various forms of
authentication.
*Please note that the license server we are using in this tutorial is a
diff --git a/docs/tutorials/network-and-buffering-config.md b/docs/tutorials/network-and-buffering-config.md
index 70ee88907..3a385a0bb 100644
--- a/docs/tutorials/network-and-buffering-config.md
+++ b/docs/tutorials/network-and-buffering-config.md
@@ -9,9 +9,8 @@ segment request.
The three separate retry settings are found under `drm.retryParameters` (for
license requests), `manifest.retryParameters` (for manifest requests), and
-`streaming.retryParameters` (for segment requests).
-
-They all look the same, though:
+`streaming.retryParameters` (for segment requests). All three structures are
+identical:
```js
retryParameters: {
diff --git a/docs/tutorials/plugins.md b/docs/tutorials/plugins.md
index 381a03beb..e934ee1e3 100644
--- a/docs/tutorials/plugins.md
+++ b/docs/tutorials/plugins.md
@@ -1,18 +1,24 @@
# Plugins and Customizing the Build
Shaka has a plugin system to make it easier to extend and customize the
-library. Plugins can be written outside the library (in your application), or
+library. The plugin interfaces are here to allow you extend or customize Shaka
+Player in one of these areas: manifest parsing, subtitle and caption parsing,
+networking, ABR, and polyfills. Each of these parts of the system has its own
+plugin interface. Even our "built-in" parsers, such as DASH and WebVTT, are
+actually just plugins we build by default.
+
+Plugins can be written outside the library (in your application), or
they can be built into the library to take advantage of the [Closure compiler].
[Closure compiler]: https://github.com/google/closure-compiler
-Manifest parsing, subtitle and caption parsing, networking, ABR, and polyfills
-are all done through plugins. Even our "built-in" parsers, such as DASH and
-WebVTT, are actually just default plugins.
-
#### Plugins
+We will only cover plugin concepts at a high level here and will not go into
+detailed examples of plugin development. If you are interested in customizing
+or extending Shaka in one of these areas, please see the links below.
+
A plugin registers itself with a "core" component. These are the various
plugin interfaces and the default plugins that Shaka provides:
@@ -21,36 +27,38 @@ __Manifest parsers__
- Register with {@link shaka.media.ManifestParser.registerParserByExtension}
and {@link shaka.media.ManifestParser.registerParserByMime}
- Default manifest parser plugins:
- - DASH: {@link shaka.dash.DashParser}
+ - DASH: {@linksource shaka.dash.DashParser}
__Subtitle/caption parsers__
- Selected by MIME type
- Register with {@link shaka.media.TextEngine.registerParser}
- Default text parser plugins:
- - WebVTT: {@link shaka.media.VttTextParser}
+ - WebVTT: {@linksource shaka.media.VttTextParser}
__Networking plugins__
- Selected by URI scheme (http, https, etc.)
- Register with {@link shaka.net.NetworkingEngine.registerScheme}
- Default networking plugins:
- - HTTP(S): {@link shaka.net.HttpPlugin}
- - data URIs: {@link shaka.net.DataUriPlugin}
+ - HTTP(S): {@linksource shaka.net.HttpPlugin}
+ - data URIs: {@linksource shaka.net.DataUriPlugin}
__ABR plugins__
- Configured at runtime on a Player instance
- Use {@link player.configure} and set the `abr.manager` field
- Must implement the {@link shakaExtern.AbrManager} interface
- - Default AbrManager implementation: {@link shaka.abr.SimpleAbrManager}
+ - Default AbrManager implementation: {@linksource shaka.abr.SimpleAbrManager}
__Polyfills__
- All polyfills are installed by {@link shaka.polyfill.installAll}
- Register with {@link shaka.polyfill.register}
- Default polyfills:
- - prefixed fullscreen implementations: {@link shaka.polyfill.Fullscreen}
- - prefixed video QoE metrics: {@link shaka.polyfill.VideoPlaybackQuality}
+ - prefixed fullscreen implementations:
+ {@linksource shaka.polyfill.Fullscreen}
+ - prefixed video QoE metrics:
+ {@linksource shaka.polyfill.VideoPlaybackQuality}
- prefixed EME implementations for IE 11 and very old versions of embedded
- Chrome/Chromium: {@link shaka.polyfill.MediaKeys}
- - Promise implementation for IE 11: {@link shaka.polyfill.Promise}
+ Chrome/Chromium: {@linksource shaka.polyfill.MediaKeys}
+ - Promise implementation for IE 11: {@linksource shaka.polyfill.Promise}
#### Excluding Default Plugins
diff --git a/docs/tutorials/welcome.md b/docs/tutorials/welcome.md
index d3494559e..d232aca9d 100644
--- a/docs/tutorials/welcome.md
+++ b/docs/tutorials/welcome.md
@@ -8,7 +8,30 @@ It plays [DASH][] content without browser plugins using
[MediaSource Extensions]: http://w3c.github.io/media-source/
[Encrypted Media Extensions]: https://w3c.github.io/encrypted-media/
-## Getting Started
+#### Prerequisites
+
+You can build Shaka on Linux, Windows, or Mac.
+To get the sources and compile the library, you will need:
+ * Git 1.7.10+ {@link https://git-scm.com/downloads}
+ * Python 2.7.x {@link https://www.python.org/downloads/}
+ * Java Runtime Environment 7+ {@link https://java.com/en/download/}
+
+Additionally, to build the documentation and run the tests, you will need:
+ * npm v1.3.12+ {@link https://nodejs.org/en/download/}
+
+To quickly install these prerequisites on Ubuntu or Debian, run:
+
+```sh
+sudo apt-get install git python2.7 openjdk-7-jre-headless npm
+sudo npm install -g npm # Upgrade npm to the latest
+# Add a symlink missing on some systems:
+sudo ln -s /usr/bin/nodejs /usr/local/bin/node
+```
+
+Installation instructions for other operating systems are not provided here.
+(We can't possibly document them all.) You can follow the links above to
+download and install the prerequisites.
+
#### Get the source
@@ -25,12 +48,12 @@ python build/all.py
```
-#### Join the mailing list
+#### Join the community
-If you want to discuss Shaka Player developement or receive notifications when
-a new version is released, you should join our [mailing list].
+If you want to discuss Shaka Player development or receive notifications when
+a new version is released, you should join our [users group].
-[mailing list]: https://groups.google.com/forum/#!forum/shaka-player-users
+[users group]: https://groups.google.com/forum/#!forum/shaka-player-users
#### Continue the Tutorials
diff --git a/third_party/jsdoc/lib/jsdoc/util/templateHelper.js b/third_party/jsdoc/lib/jsdoc/util/templateHelper.js
index 2c2305277..f6151ba57 100644
--- a/third_party/jsdoc/lib/jsdoc/util/templateHelper.js
+++ b/third_party/jsdoc/lib/jsdoc/util/templateHelper.js
@@ -139,6 +139,7 @@ var getUniqueId = exports.getUniqueId = makeUniqueId;
// two-way lookup
var linkMap = {
longnameToUrl: {},
+ longnameToSource: {},
urlToLongname: {}
};
@@ -393,6 +394,15 @@ var toTutorial = exports.toTutorial = function(tutorial, content, missingOpts) {
exports.resolveLinks = function(str) {
var replaceInlineTags = require('jsdoc/tag/inline').replaceInlineTags;
+ var longnameToSourceUrl = {};
+ for (var name in linkMap.longnameToSource) {
+ var data = linkMap.longnameToSource[name];
+ var path = data[0];
+ var lineno = data[1];
+ var html = longnameToUrl[path];
+ longnameToSourceUrl[name] = html + '#line' + lineno;
+ }
+
function extractLeadingText(string, completeTag) {
var tagIndex = string.indexOf(completeTag);
var leadingText = null;
@@ -443,10 +453,30 @@ exports.resolveLinks = function(str) {
return string.replace( tagInfo.completeTag, toTutorial(tagInfo.text, leading.leadingText) );
}
+ function processSource(string, tagInfo) {
+ var leading = extractLeadingText(string, tagInfo.completeTag);
+ var linkText = leading.leadingText;
+ var split;
+ var target;
+ string = leading.string;
+
+ split = splitLinkText(tagInfo.text);
+ target = split.target;
+ linkText = linkText || split.linkText;
+
+ monospace = useMonospace(tagInfo.tag, tagInfo.text);
+
+ return string.replace( tagInfo.completeTag, buildLink(target, linkText, {
+ linkMap: longnameToSourceUrl,
+ monospace: monospace
+ }) );
+ }
+
var replacers = {
link: processLink,
linkcode: processLink,
linkplain: processLink,
+ linksource: processSource,
tutorial: processTutorial
};
@@ -775,6 +805,11 @@ var registerLink = exports.registerLink = function(longname, url) {
linkMap.urlToLongname[url] = longname;
};
+exports.registerSourceLink = function(longname, path, lineno) {
+ linkMap.longnameToSource[longname] = [path, lineno];
+};
+
+
/**
* Get a longname's filename if one has been registered; otherwise, generate a unique filename, then
* register the filename.
diff --git a/third_party/jsdoc/templates/default/publish.js b/third_party/jsdoc/templates/default/publish.js
index 77feb1a10..6e25d438a 100644
--- a/third_party/jsdoc/templates/default/publish.js
+++ b/third_party/jsdoc/templates/default/publish.js
@@ -560,6 +560,8 @@ exports.publish = function(taffyData, opts, tutorials) {
docletPath = sourceFiles[docletPath].shortened;
if (docletPath) {
doclet.meta.shortpath = docletPath;
+ helper.registerSourceLink(doclet.longname, docletPath,
+ doclet.meta.lineno);
}
}
});
diff --git a/third_party/jsdoc/templates/default/static/styles/jsdoc-default.css b/third_party/jsdoc/templates/default/static/styles/jsdoc-default.css
index 7d7016b5b..27744dc04 100644
--- a/third_party/jsdoc/templates/default/static/styles/jsdoc-default.css
+++ b/third_party/jsdoc/templates/default/static/styles/jsdoc-default.css
@@ -141,10 +141,6 @@ footer {
font-size: 90%;
}
-p {
- margin-bottom: 24px;
-}
-
h1, h2, h3, h4 {
font-weight: 200;
margin: 0;
@@ -155,7 +151,7 @@ h1
font-family: 'Open Sans Light', sans-serif;
font-size: 48px;
letter-spacing: -2px;
- margin: 12px 24px 20px;
+ margin-bottom: 20px;
}
h2, h3
@@ -170,7 +166,7 @@ h4
{
font-size: 18px;
letter-spacing: -0.33px;
- margin-bottom: 12px;
+ margin-top: 32px;
color: #4d4e53;
}
@@ -179,14 +175,14 @@ h5, .container-overview .subsection-title
font-size: 120%;
font-weight: bold;
letter-spacing: -0.01em;
- margin: 8px 0 3px -16px;
+ margin: 8px 0 3px;
}
h6
{
font-size: 100%;
letter-spacing: -0.01em;
- margin: 6px 0 3px 0;
+ margin: 6px 0 3px;
font-style: italic;
}