Skip to content

Commit

Permalink
Fix non-default namespace names in DASH.
Browse files Browse the repository at this point in the history
XML allows namespace names to be any string.  So instead of looking
for the literal name 'cenc:pssh', we should be looking for the 'pssh'
name in the correct namespace.

Closes #1438

Change-Id: I724db3b7f0e60b4233b0fc40b1ed57698c6ce9ce
  • Loading branch information
TheModMaker committed May 21, 2018
1 parent fc470e4 commit 866b0e1
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 10 deletions.
12 changes: 10 additions & 2 deletions lib/dash/content_protection.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,13 @@ shaka.dash.ContentProtection.MP4Protection_ =
'urn:mpeg:dash:mp4protection:2011';


/**
* @const {string}
* @private
*/
shaka.dash.ContentProtection.CencNamespaceUri = 'urn:mpeg:cenc:2013';


/**
* Parses info from the ContentProtection elements at the AdaptationSet level.
*
Expand Down Expand Up @@ -302,12 +309,13 @@ shaka.dash.ContentProtection.parseElements_ = function(elems) {
* @return {?shaka.dash.ContentProtection.Element}
*/
function(elem) {
const NS = shaka.dash.ContentProtection.CencNamespaceUri;
/** @type {?string} */
let schemeUri = elem.getAttribute('schemeIdUri');
/** @type {?string} */
let keyId = elem.getAttribute('cenc:default_KID');
let keyId = shaka.util.XmlUtils.getAttributeNS(elem, NS, 'default_KID');
/** @type {!Array.<string>} */
let psshs = shaka.util.XmlUtils.findChildren(elem, 'cenc:pssh')
let psshs = shaka.util.XmlUtils.findChildrenNS(elem, NS, 'pssh')
.map(shaka.util.XmlUtils.getContents);

if (!schemeUri) {
Expand Down
28 changes: 20 additions & 8 deletions lib/dash/mpd_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ shaka.dash.MpdUtils.TimeRange;
shaka.dash.MpdUtils.SegmentInfo;


/**
* @const {string}
* @private
*/
shaka.dash.MpdUtils.XlinkNamespaceUri = 'http://www.w3.org/1999/xlink';


/**
* Fills a SegmentTemplate URI template. This function does not validate the
* resulting URI.
Expand Down Expand Up @@ -474,18 +481,21 @@ shaka.dash.MpdUtils.handleXlinkInElement_ =
function(element, retryParameters, failGracefully, baseUri,
networkingEngine, linkDepth) {
const MpdUtils = shaka.dash.MpdUtils;
const XmlUtils = shaka.util.XmlUtils;
const Error = shaka.util.Error;
const ManifestParserUtils = shaka.util.ManifestParserUtils;
const NS = MpdUtils.XlinkNamespaceUri;

let xlinkHref = element.getAttribute('xlink:href');
let xlinkActuate = element.getAttribute('xlink:actuate') || 'onRequest';
let xlinkHref = XmlUtils.getAttributeNS(element, NS, 'href');
let xlinkActuate =
XmlUtils.getAttributeNS(element, NS, 'actuate') || 'onRequest';

// Remove the xlink properties, so it won't download again
// when re-processed.
for (let i = 0; i < element.attributes.length; i++) {
let attribute = element.attributes[i].nodeName;
if (attribute.indexOf('xlink:') != -1) {
element.removeAttribute(attribute);
let attribute = element.attributes[i];
if (attribute.namespaceURI == NS) {
element.removeAttributeNS(attribute.namespaceURI, attribute.localName);
i -= 1;
}
}
Expand Down Expand Up @@ -579,8 +589,10 @@ shaka.dash.MpdUtils.processXlinks =
function(element, retryParameters, failGracefully, baseUri,
networkingEngine, linkDepth = 0) {
const MpdUtils = shaka.dash.MpdUtils;
const XmlUtils = shaka.util.XmlUtils;
const NS = MpdUtils.XlinkNamespaceUri;

if (element.getAttribute('xlink:href')) {
if (XmlUtils.getAttributeNS(element, NS, 'href')) {
let handled = MpdUtils.handleXlinkInElement_(
element, retryParameters, failGracefully, baseUri,
networkingEngine, linkDepth);
Expand All @@ -602,8 +614,8 @@ shaka.dash.MpdUtils.processXlinks =
for (let i = 0; i < element.childNodes.length; i++) {
let child = element.childNodes[i];
if (child instanceof Element) {
let resolveToZeroString = 'urn:mpeg:dash:resolve-to-zero:2013';
if (child.getAttribute('xlink:href') == resolveToZeroString) {
const resolveToZeroString = 'urn:mpeg:dash:resolve-to-zero:2013';
if (XmlUtils.getAttributeNS(child, NS, 'href') == resolveToZeroString) {
// This is a 'resolve to zero' code; it means the element should
// be removed, as specified by the mpeg-dash rules for xlink.
element.removeChild(child);
Expand Down
29 changes: 29 additions & 0 deletions lib/util/xml_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,35 @@ shaka.util.XmlUtils.findChildren = function(elem, name) {
};


/**
* Finds namespace-qualified child XML elements.
* @param {!Node} elem The parent XML element.
* @param {string} ns The child XML element's namespace URI.
* @param {string} name The child XML element's local name.
* @return {!Array.<!Element>} The child XML elements.
*/
shaka.util.XmlUtils.findChildrenNS = function(elem, ns, name) {
return Array.prototype.filter.call(elem.childNodes, function(child) {
return child instanceof Element && child.localName == name &&
child.namespaceURI == ns;
});
};


/**
* Gets a namespace-qualified attribute.
* @param {!Element} elem The element to get from.
* @param {string} ns The namespace URI.
* @param {string} name The local name of the attribute.
* @return {?string} The attribute's value, or null if not present.
*/
shaka.util.XmlUtils.getAttributeNS = function(elem, ns, name) {
// Some browsers return the empty string when the attribute is missing,
// so check if it exists first. See: https://mzl.la/2L7F0UK
return elem.hasAttributeNS(ns, name) ? elem.getAttributeNS(ns, name) : null;
};


/**
* Gets the text contents of a node.
* @param {!Node} elem The XML element.
Expand Down
22 changes: 22 additions & 0 deletions test/dash/dash_parser_content_protection_unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,28 @@ describe('DashParser ContentProtection', function() {
testDashParser(done, source, expected);
});

it('handles non-default namespace names', function(done) {
let source = [
'<MPD xmlns="urn:mpeg:DASH:schema:MPD:2011"',
' xmlns:foo="urn:mpeg:cenc:2013">',
' <Period duration="PT30S">',
' <SegmentTemplate media="s.mp4" duration="2" />',
' <AdaptationSet mimeType="video/mp4" codecs="avc1.4d401f">',
' <ContentProtection',
' schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed">',
' <foo:pssh>b25lIGhlYWRlciB0byBydWxlIHRoZW0gYWxs</foo:pssh>',
' </ContentProtection>',
' <Representation bandwidth="50" width="576" height="432" />',
' <Representation bandwidth="100" width="576" height="432" />',
' </AdaptationSet>',
' </Period>',
'</MPD>'
].join('\n');
let expected = buildExpectedManifest([buildDrmInfo(
'com.widevine.alpha', [], ['b25lIGhlYWRlciB0byBydWxlIHRoZW0gYWxs'])]);
testDashParser(done, source, expected);
});

it('fails for no schemes common', function(done) {
let source = buildManifestText([
// AdaptationSet lines
Expand Down

0 comments on commit 866b0e1

Please sign in to comment.