Skip to content

Commit

Permalink
Shaka Player release v1.1
Browse files Browse the repository at this point in the history
  • Loading branch information
joeyparrish committed Jan 15, 2015
1 parent b3d035b commit d4df698
Show file tree
Hide file tree
Showing 41 changed files with 1,237 additions and 521 deletions.
48 changes: 48 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,51 @@
## 1.1 (2015-01-14)

Maintenance release.

Bugfixes:
- The enabled flag for text tracks is now preserved when switching tracks.
Player.enableTextTrack() is no longer required after selectTextTrack().
- https://github.com/google/shaka-player/issues/1
- The documentation for Player methods enableTextTrack, setPreferredLanguage,
and getCurrentResolution has been corrected.
- https://github.com/google/shaka-player/issues/3
- https://github.com/google/shaka-player/issues/4
- https://github.com/google/shaka-player/issues/6
- The AbrManager class is now correctly destroyed.
- https://github.com/google/shaka-player/issues/5
- Clearkey support for Chrome 41+ has been fixed.
- https://github.com/google/shaka-player/issues/8
- A new polyfill has been added to compensate for Chrome 41+'s removal of
MediaKeys.isTypeSupported.
- https://github.com/google/shaka-player/issues/7
- Several unused internal methods have been removed from the codebase.
- Fixed a failing assertion in one of the MediaKeys polyfills.
- Fixed failing code coverage analysis and related parse errors in several
tests.
- Fixed support for MPDs with SegmentTemplate@duration and
MPD@mediaPresentationDuration, but no Period@duration attribute.
- https://github.com/google/shaka-player/issues/9

Features:
- Tests are now checked for style.
- Tests have been expanded to increase coverage and exercise more Player
features:
- playback rate
- stats
- language preference
- license restrictions
- WebM/VP9
- error events
- Integration tests now run much faster.
- MediaKeys polyfills have received minor updates to improve compatibility
with Chrome 41.
- New sample assets and code in app.js to demonstrate how to use a PSSH from
an MPD to override what's in the content itself.

Broken Compatibility:
- None!


## 1.0 (2014-12-19)

First public release.
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ sources, including the [Closure Compiler][], [gjslint][], [JSDoc][], and
[Jasmine]: http://jasmine.github.io/2.1/introduction.html


## Mailing list ##

We have a [public mailing list][] for discussion and announcements. To receive
notifications about new versions, please join the list. You can also use the
list to ask questions or discuss Shaka Player development.

[public mailing list]: https://groups.google.com/forum/#!forum/shaka-player-users


## Documentation ##

We have detailed documentation which is generated from the sources using JSDoc.
Expand Down
65 changes: 65 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,7 @@ app.interpretContentProtection_ = function(contentProtection) {
var key = StringUtils.fromHex(child.getAttribute('key'));
var keyObj = {
kty: 'oct',
alg: 'A128KW',
kid: StringUtils.toBase64(keyid, false),
k: StringUtils.toBase64(key, false)
};
Expand All @@ -527,6 +528,33 @@ app.interpretContentProtection_ = function(contentProtection) {
'org.w3.clearkey', false, licenseServerUrl, false, initData, null);
}

if (contentProtection.schemeIdUri == 'http://youtube.com/drm/2012/10/10') {
// This is another scheme used by YouTube.
var licenseServerUrl = null;
for (var i = 0; i < contentProtection.children.length; ++i) {
var child = contentProtection.children[i];
if (child.getAttribute('type') == 'widevine') {
licenseServerUrl = child.firstChild.nodeValue;
break;
}
}
if (licenseServerUrl) {
var initDataOverride = null;
if (contentProtection.pssh && contentProtection.pssh.psshBox) {
// Override the init data with the PSSH from the manifest.
initDataOverride = {
initData: contentProtection.pssh.psshBox,
initDataType: 'cenc'
};
console.info('Found overridden PSSH with system IDs:',
contentProtection.pssh.parsedPssh.systemIds);
}
return new shaka.player.DrmSchemeInfo(
'com.widevine.alpha', true, licenseServerUrl, false, initDataOverride,
app.postProcessYouTubeLicenseResponse_);
}
}

if (contentProtection.schemeIdUri ==
'urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed') {
// This is the UUID which represents Widevine in the edash-packager.
Expand All @@ -540,6 +568,43 @@ app.interpretContentProtection_ = function(contentProtection) {
};


/**
* Post-process the YouTube license server's response, which has headers before
* the actual license.
*
* @param {!Uint8Array} response
* @param {!shaka.player.DrmSchemeInfo.Restrictions} restrictions
* @return {!Uint8Array}
* @private
*/
app.postProcessYouTubeLicenseResponse_ = function(response, restrictions) {
var StringUtils = shaka.util.StringUtils;
var responseStr = StringUtils.fromUint8Array(response);
var index = responseStr.indexOf('\r\n\r\n');
if (index >= 0) {
// Strip off the headers.
var headers = responseStr.substr(0, index).split('\r\n');
responseStr = responseStr.substr(index + 4);
console.info('YT HEADERS:', headers);

// Check for restrictions on HD content.
for (var i = 0; i < headers.length; ++i) {
var k = headers[i].split(': ')[0];
var v = headers[i].split(': ')[1];
if (k == 'Authorized-Format-Types') {
var types = v.split(',');
if (types.indexOf('HD') == -1) {
// This license will not permit HD playback.
console.info('HD disabled.');
restrictions.maxHeight = 576;
}
}
}
}
return StringUtils.toUint8Array(responseStr);
};


if (document.readyState == 'complete' ||
document.readyState == 'interactive') {
app.init();
Expand Down
75 changes: 75 additions & 0 deletions assets/oops_cenc_pssh.mpd
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?xml version="1.0"?>
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mpeg:DASH:schema:MPD:2011" xmlns:yt="http://youtube.com/yt/2012/10/10" xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" type="static" minBufferTime="PT1.500S" mediaPresentationDuration="PT242.927S">
<BaseURL>http://yt-dash-mse-test.commondatastorage.googleapis.com/media/oops_cenc-20121114-signedlicenseurl-manifest.mpd</BaseURL>
<Period>
<AdaptationSet mimeType="audio/mp4" subsegmentAlignment="true">
<ContentProtection schemeIdUri="http://youtube.com/drm/2012/10/10">
<yt:SystemURL type="widevine">http://dash-mse-test.appspot.com/api/drm/widevine?drm_system=widevine&amp;source=YOUTUBE&amp;video_id=03681262dc412c06&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,source,video_id,drm_system&amp;signature=289105AFC9747471DB0D2A998544CC1DAF75B8F9.18DE89BB7C1CE9B68533315D0F84DF86387C6BB3&amp;key=test_key1</yt:SystemURL>
<cenc:pssh>AAAANHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABQIARIQexMo62G1VOKT91sePpTMOwAAAvRwc3NoAAAAAJoE8HmYQEKGq5LmW+CIX5UAAALU1AIAAAEAAQDKAjwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ANgB5AGcAVABlADcAVgBoADQAbABTAFQAOQAxAHMAZQBQAHAAVABNAE8AdwA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBwAG0AKwBTADAASQBHAG4AbwAwAHMAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APABMAEEAXwBVAFIATAA+AGgAdAB0AHAAcwA6AC8ALwB3AHcAdwAuAHkAbwB1AHQAdQBiAGUALgBjAG8AbQAvAGEAcABpAC8AZAByAG0ALwBwAGwAYQB5AHIAZQBhAGQAeQA/AHMAbwB1AHIAYwBlAD0AWQBPAFUAVABVAEIARQAmAGEAbQBwADsAdgBpAGQAZQBvAF8AaQBkAD0AMAAzADYAOAAxADIANgAyAGQAYwA0ADEAMgBjADAANgA8AC8ATABBAF8AVQBSAEwAPgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AAAAADBwc3NoAAAAAFgUfsgEI0ZZkub1LFzow8wAAAAQexMo62G1VOKT91sePpTMOw==</cenc:pssh>
</ContentProtection>
<Representation id="148" codecs="mp4a.40.2" audioSamplingRate="22050" startWithSAP="1" bandwidth="33107">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="1"/>
<BaseURL>oops_cenc-20121114-148.mp4</BaseURL>
<SegmentBase indexRange="1603-1934" indexRangeExact="true">
<Initialization range="0-1602"/>
</SegmentBase>
</Representation>
<Representation id="149" codecs="mp4a.40.2" audioSamplingRate="44100" startWithSAP="1" bandwidth="130111">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
<BaseURL>oops_cenc-20121114-149.mp4</BaseURL>
<SegmentBase indexRange="1603-1934" indexRangeExact="true">
<Initialization range="0-1602"/>
</SegmentBase>
</Representation>
<Representation id="150" codecs="mp4a.40.2" audioSamplingRate="44100" startWithSAP="1" bandwidth="258244">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
<BaseURL>oops_cenc-20121114-150.mp4</BaseURL>
<SegmentBase indexRange="1603-1934" indexRangeExact="true">
<Initialization range="0-1602"/>
</SegmentBase>
</Representation>
</AdaptationSet>
<AdaptationSet mimeType="video/mp4" subsegmentAlignment="true">
<ContentProtection schemeIdUri="http://youtube.com/drm/2012/10/10">
<yt:SystemURL type="widevine">http://dash-mse-test.appspot.com/api/drm/widevine?drm_system=widevine&amp;source=YOUTUBE&amp;video_id=03681262dc412c06&amp;ip=0.0.0.0&amp;ipbits=0&amp;expire=19000000000&amp;sparams=ip,ipbits,expire,source,video_id,drm_system&amp;signature=289105AFC9747471DB0D2A998544CC1DAF75B8F9.18DE89BB7C1CE9B68533315D0F84DF86387C6BB3&amp;key=test_key1</yt:SystemURL>
<cenc:pssh>AAAANHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABQIARIQk3iZIOjWUgCYV3348t1VRgAAAvRwc3NoAAAAAJoE8HmYQEKGq5LmW+CIX5UAAALU1AIAAAEAAQDKAjwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ASQBKAGwANABrADkAYgBvAEEARgBLAFkAVgAzADMANAA4AHQAMQBWAFIAZwA9AD0APAAvAEsASQBEAD4APABDAEgARQBDAEsAUwBVAE0APgBJAGUAcQA4AEwANgBIAHkASwBNAFkAPQA8AC8AQwBIAEUAQwBLAFMAVQBNAD4APABMAEEAXwBVAFIATAA+AGgAdAB0AHAAcwA6AC8ALwB3AHcAdwAuAHkAbwB1AHQAdQBiAGUALgBjAG8AbQAvAGEAcABpAC8AZAByAG0ALwBwAGwAYQB5AHIAZQBhAGQAeQA/AHMAbwB1AHIAYwBlAD0AWQBPAFUAVABVAEIARQAmAGEAbQBwADsAdgBpAGQAZQBvAF8AaQBkAD0AMAAzADYAOAAxADIANgAyAGQAYwA0ADEAMgBjADAANgA8AC8ATABBAF8AVQBSAEwAPgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AAAAADBwc3NoAAAAAFgUfsgEI0ZZkub1LFzow8wAAAAQk3iZIOjWUgCYV3348t1VRg==</cenc:pssh>
</ContentProtection>
<Representation id="142" codecs="avc1.4d4015" width="426" height="240" startWithSAP="1" bandwidth="282817">
<BaseURL>oops_cenc-20121114-142.mp4</BaseURL>
<SegmentBase indexRange="1739-2358" indexRangeExact="true">
<Initialization range="0-1738"/>
</SegmentBase>
</Representation>
<Representation id="143" codecs="avc1.4d401e" width="640" height="360" startWithSAP="1" bandwidth="972708">
<BaseURL>oops_cenc-20121114-143.mp4</BaseURL>
<SegmentBase indexRange="1775-2394" indexRangeExact="true">
<Initialization range="0-1774"/>
</SegmentBase>
</Representation>
<Representation id="144" codecs="avc1.4d401e" width="854" height="480" startWithSAP="1" bandwidth="1158302">
<BaseURL>oops_cenc-20121114-144.mp4</BaseURL>
<SegmentBase indexRange="1775-2394" indexRangeExact="true">
<Initialization range="0-1774"/>
</SegmentBase>
</Representation>
<Representation id="161" codecs="avc1.42c00b" width="256" height="144" startWithSAP="1" bandwidth="101416">
<BaseURL>oops_cenc-20121114-161.mp4</BaseURL>
<SegmentBase indexRange="1737-2356" indexRangeExact="true">
<Initialization range="0-1736"/>
</SegmentBase>
</Representation>
<Representation id="145" codecs="avc1.4d401f" width="1280" height="720" startWithSAP="1" bandwidth="3008632">
<BaseURL>oops_cenc-20121114-145.mp4</BaseURL>
<SegmentBase indexRange="1775-2394" indexRangeExact="true">
<Initialization range="0-1774"/>
</SegmentBase>
</Representation>
<Representation id="146" codecs="avc1.640028" width="1920" height="1080" startWithSAP="1" bandwidth="6021220">
<BaseURL>oops_cenc-20121114-146.mp4</BaseURL>
<SegmentBase indexRange="1779-2398" indexRangeExact="true">
<Initialization range="0-1778"/>
</SegmentBase>
</Representation>
</AdaptationSet>
</Period>
</MPD>
File renamed without changes.
6 changes: 6 additions & 0 deletions build/lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ function library_sources_0() {
-name '*.js' -print0
}

function test_sources_0() {
find \
"$dir"/spec \
-name '*.js' -print0
}

function closure_sources_0() {
find \
"$dir"/third_party/closure \
Expand Down
2 changes: 1 addition & 1 deletion build/lint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ dir=$(dirname $0)/..

set -e

library_sources_0 | lint_0 "$dir"/app.js
(library_sources_0; test_sources_0) | lint_0 "$dir"/app.js
9 changes: 9 additions & 0 deletions docs/mainpage.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,12 @@ sessions, so you should not have to keep setting it as you browse the docs.

If you're not sure where to go next, try the Tutorials on the right. Enjoy!


## Mailing List

We have a [public mailing list][] for discussion and announcements. To receive
notifications about new versions, please join the list. You can also use the
list to ask questions or discuss Shaka Player development.

[public mailing list]: https://groups.google.com/forum/#!forum/shaka-player-users

24 changes: 20 additions & 4 deletions externs/jwk_set.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,30 @@ function JWKSet() {
*/
function JWK() {
/**
* A key in hex.
* A key ID. Any ASCII string.
* @type {string}
*/
this.k = '';
this.kid = '';

/**
* A key ID in hex.
* The algorithm used with the key. Use "A128KW" for clearkey.
* @type {string}
*/
this.kid = '';
this.alg = '';

/**
* A key type. One of:
* "oct" (symmetric key octect sequence)
* "RSA" (RSA key)
* "EC" (elliptical curve key)
* Use "oct" for clearkey.
* @type {string}
*/
this.kty = '';

/**
* A key in base 64. Used with kty="oct".
* @type {string}
*/
this.k = '';
}
4 changes: 3 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,10 @@
<option value="assets/car_cenc-20120827-manifest.mpd">"Car/CENC" (YT DASH EME test) - MP4, ClearKey</option>
<option value="assets/feelings_vp9-20130806-manifest.mpd">"Feelings" (YT DASH test) - VP9</option>
<option value="assets/feelings_audio_only-20130806-manifest.mpd">"Feelings" (YT DASH test) - Audio only</option>
<option value="http://storage.googleapis.com/gtv-videos-bucket/dash/CarWidevine/car.mpd">"Car/SegmentTemplate" (Chromecast test) - MP4 (no SIDX), Widevine</option>
<option value="http://storage.googleapis.com/gtv-videos-bucket/dash/CarWidevine/car.mpd">"Car/SegmentTemplate" (Chromecast test) - MP4 (no SIDX, audio only), Widevine</option>
<option value="http://download.tsi.telecom-paristech.fr/gpac/DASH_CONFORMANCE/TelecomParisTech/mp4-main-multi/mp4-main-multi-mpd-AV-NBS.mpd">GPAC/SegmentList (conformance test)</option>
<option value="http://yt-dash-mse-test.commondatastorage.googleapis.com/media/oops_cenc-20121114-signedlicenseurl-manifest.mpd">"Oops" (YT DASH EME test) - MP4, multi-DRM</option>
<option value="assets/oops_cenc_pssh.mpd">"Oops" (modified YT DASH EME test) - MP4, Widevine, PSSH in MPD</option>
<option value="">(custom)</option>
</select>
</td>
Expand Down
7 changes: 6 additions & 1 deletion lib/dash/dash_text_stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ shaka.dash.DashTextStream.prototype.start = function(representation) {
this.representation_ = representation;
shaka.log.info('Starting stream for', this.representation_);

// Save the enabled flag so that changing the active text track does not
// change the visibility of the text track.
var enabled = this.getEnabled();

// NOTE: Simply changing the src attribute of an existing track may result
// in both the old and new subtitles appearing simultaneously. To be safe,
// remove the old track and create a new one.
Expand All @@ -102,7 +106,7 @@ shaka.dash.DashTextStream.prototype.start = function(representation) {
this.track_.src = url;

// NOTE: mode must be set after appending to the DOM.
this.setEnabled(false);
this.setEnabled(enabled);
};


Expand All @@ -127,6 +131,7 @@ shaka.dash.DashTextStream.prototype.setEnabled = function(enabled) {

/** @override */
shaka.dash.DashTextStream.prototype.getEnabled = function() {
if (!this.track_) return false;
return this.track_.track.mode == 'showing';
};

25 changes: 2 additions & 23 deletions lib/dash/mpd_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -883,8 +883,8 @@ shaka.dash.mpd.SegmentBase.prototype.parse = function(parent, elem) {
* @param {!shaka.dash.mpd.SegmentBase} parent The parent SegmentBase.
* @param {!Node} elem The RepresentationIndex XML element.
*/
shaka.dash.mpd.RepresentationIndex.prototype.parse = function(
parent, elem) {
shaka.dash.mpd.RepresentationIndex.prototype.parse =
function(parent, elem) {
var mpd = shaka.dash.mpd;

// Parse attributes.
Expand Down Expand Up @@ -1098,27 +1098,6 @@ shaka.dash.mpd.parseChildren_ = function(parent, elem, constructor) {
};


/**
* Gets an array of child XML elements by tag name, without parsing them.
* @param {!Node} elem The parent XML element.
* @param {string} tagName The tag name to filter by.
* @return {!Array.<!Node>} The child XML elements.
* @private
*/
shaka.dash.mpd.getChildren_ = function(elem, tagName) {
var children = [];

for (var i = 0; i < elem.children.length; i++) {
if (elem.children[i].tagName != tagName) {
continue;
}
children.push(elem.children[i]);
}

return children;
};


/**
* Gets the text contents of a node.
* @param {!Node} elem The XML element.
Expand Down
Loading

0 comments on commit d4df698

Please sign in to comment.