rx-player
Version:
Canal+ HTML5 Video Player
301 lines (300 loc) • 14.6 kB
JavaScript
;
/**
* Copyright 2015 CANAL+ Group
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = parseRepresentations;
var log_1 = require("../../../../log");
var array_find_1 = require("../../../../utils/array_find");
var object_assign_1 = require("../../../../utils/object_assign");
var convert_supplemental_codecs_1 = require("./convert_supplemental_codecs");
var get_hdr_information_1 = require("./get_hdr_information");
var parse_representation_index_1 = require("./parse_representation_index");
var resolve_base_urls_1 = require("./resolve_base_urls");
/**
* Combine inband event streams from representation and
* adaptation data.
* @param {Object} representation
* @param {Object} adaptation
* @returns {undefined | Array.<Object>}
*/
function combineInbandEventStreams(representation, adaptation) {
var newSchemeId = [];
if (representation.children.inbandEventStreams !== undefined) {
newSchemeId.push.apply(newSchemeId, __spreadArray([], __read(representation.children.inbandEventStreams), false));
}
if (adaptation.children.inbandEventStreams !== undefined) {
newSchemeId.push.apply(newSchemeId, __spreadArray([], __read(adaptation.children.inbandEventStreams), false));
}
if (newSchemeId.length === 0) {
return undefined;
}
return newSchemeId;
}
/**
* Extract HDR information from manifest and codecs.
* @param {Object}
* @returns {Object | undefined}
*/
function getHDRInformation(_a) {
var adaptationProfiles = _a.adaptationProfiles, essentialProperties = _a.essentialProperties, supplementalProperties = _a.supplementalProperties, manifestProfiles = _a.manifestProfiles, codecs = _a.codecs;
var profiles = (adaptationProfiles !== null && adaptationProfiles !== void 0 ? adaptationProfiles : "") + (manifestProfiles !== null && manifestProfiles !== void 0 ? manifestProfiles : "");
if (profiles.indexOf("http://dashif.org/guidelines/dash-if-uhd#hevc-hdr-pq10") !== -1) {
if (codecs === "hvc1.2.4.L153.B0" || codecs === "hev1.2.4.L153.B0") {
return { colorDepth: 10, eotf: "pq", colorSpace: "rec2020" };
}
}
var transferCharacteristicScheme = (0, array_find_1.default)(__spreadArray(__spreadArray([], __read((essentialProperties !== null && essentialProperties !== void 0 ? essentialProperties : [])), false), __read((supplementalProperties !== null && supplementalProperties !== void 0 ? supplementalProperties : [])), false), function (p) { return p.schemeIdUri === "urn:mpeg:mpegB:cicp:TransferCharacteristics"; });
if (transferCharacteristicScheme !== undefined) {
// 1: ITU-R BT.709
// 2: Unspecified
// 4: Gamma 2.2 curve
// 5: Gamma 2.8 curve
// 6: SMPTE 170M
// 7: SMPTE 240M
// 8: Linear
// 9: Logarithmic (100:1 range)
// 10: Logarithmic (100 * Sqrt(10) : 1 range)
// 11: IEC 61966-2-4
// 12: ITU-R BT.1361 Extended Colour Gamut
// 13: IEC 61966-2-1 (sRGB or sYCC)
// 14: ITU-R BT.2020 10-bit system
// 15: ITU-R BT.2020 12-bit system
// 16: SMPTE ST 2084, ITU-R BT.2100 PQ
// 17: SMPTE ST 428-1
// 18: ARIB STD-B67 (HLG)
switch (transferCharacteristicScheme.value) {
case "15":
return undefined; // SDR
case "16":
return { eotf: "pq" };
case "18":
return { eotf: "hlg" };
}
}
if (codecs !== undefined && /^vp(08|09|10)/.test(codecs)) {
return (0, get_hdr_information_1.getWEBMHDRInformation)(codecs);
}
}
/**
* Process intermediate representations to create final parsed representations.
* In the same order.
* @param {Array.<Object>} representationsIR
* @param {Object} context
* @returns {Array.<Object>}
*/
function parseRepresentations(representationsIR, adaptation, context) {
var e_1, _a;
var _b, _c, _d, _e, _f, _g, _h;
var parsedRepresentations = [];
var _loop_1 = function (representation) {
var e_2, _j;
// Compute Representation ID
var representationID = representation.attributes.id !== undefined
? representation.attributes.id
: String(representation.attributes.bitrate) +
(representation.attributes.height !== undefined
? "-".concat(representation.attributes.height)
: "") +
(representation.attributes.width !== undefined
? "-".concat(representation.attributes.width)
: "") +
(representation.attributes.mimeType !== undefined
? "-".concat(representation.attributes.mimeType)
: "") +
(representation.attributes.codecs !== undefined
? "-".concat(representation.attributes.codecs)
: "");
// Avoid duplicate IDs
while (parsedRepresentations.some(function (r) { return r.id === representationID; })) {
representationID += "-dup";
}
// Retrieve previous version of the Representation, if one.
var unsafelyBaseOnPreviousRepresentation = (_c = (_b = context.unsafelyBaseOnPreviousAdaptation) === null || _b === void 0 ? void 0 : _b.getRepresentation(representationID)) !== null && _c !== void 0 ? _c : null;
var inbandEventStreams = combineInbandEventStreams(representation, adaptation);
var availabilityTimeComplete = (_d = representation.attributes.availabilityTimeComplete) !== null && _d !== void 0 ? _d : context.availabilityTimeComplete;
var availabilityTimeOffset = void 0;
if (representation.attributes.availabilityTimeOffset !== undefined ||
context.availabilityTimeOffset !== undefined) {
availabilityTimeOffset =
((_e = representation.attributes.availabilityTimeOffset) !== null && _e !== void 0 ? _e : 0) +
((_f = context.availabilityTimeOffset) !== null && _f !== void 0 ? _f : 0);
}
var reprIndexCtxt = (0, object_assign_1.default)({}, context, {
availabilityTimeOffset: availabilityTimeOffset,
availabilityTimeComplete: availabilityTimeComplete,
unsafelyBaseOnPreviousRepresentation: unsafelyBaseOnPreviousRepresentation,
adaptation: adaptation,
inbandEventStreams: inbandEventStreams,
});
var representationIndex = (0, parse_representation_index_1.default)(representation, reprIndexCtxt);
// Find bitrate
var representationBitrate = void 0;
if (representation.attributes.bitrate === undefined) {
log_1.default.warn("DASH: No usable bitrate found in the Representation.");
representationBitrate = 0;
}
else {
representationBitrate = representation.attributes.bitrate;
}
var representationBaseURLs = (0, resolve_base_urls_1.default)(context.baseURLs, representation.children.baseURLs);
var cdnMetadata = representationBaseURLs.length === 0
? // No BaseURL seems to be associated to this Representation, nor to the MPD,
// but underlying segments might have one. To indicate that segments should
// still be available through a CDN without giving any root CDN URL here,
// we just communicate about an empty `baseUrl`, as documented.
[{ baseUrl: "", id: undefined }]
: representationBaseURLs.map(function (x) { return ({
baseUrl: x.url,
id: x.serviceLocation,
}); });
// Construct Representation Base
var parsedRepresentation = {
bitrate: representationBitrate,
cdnMetadata: cdnMetadata,
index: representationIndex,
id: representationID,
};
if (representation.children.supplementalProperties !== undefined &&
(0, array_find_1.default)(representation.children.supplementalProperties, function (r) {
return r.schemeIdUri === "tag:dolby.com,2018:dash:EC3_ExtensionType:2018" &&
r.value === "JOC";
}) !== undefined) {
parsedRepresentation.isSpatialAudio = true;
}
// Add optional attributes
var codecs = void 0;
if (representation.attributes.codecs !== undefined) {
codecs = representation.attributes.codecs;
}
else if (adaptation.attributes.codecs !== undefined) {
codecs = adaptation.attributes.codecs;
}
if (codecs !== undefined) {
codecs = codecs === "mp4a.40.02" ? "mp4a.40.2" : codecs;
parsedRepresentation.codecs = codecs;
}
var supplementalCodecs = void 0;
if (representation.attributes.supplementalCodecs !== undefined) {
supplementalCodecs = representation.attributes.supplementalCodecs;
}
else if (adaptation.attributes.supplementalCodecs !== undefined) {
supplementalCodecs = adaptation.attributes.supplementalCodecs;
}
if (supplementalCodecs !== undefined) {
parsedRepresentation.supplementalCodecs =
(0, convert_supplemental_codecs_1.convertSupplementalCodecsToRFC6381)(supplementalCodecs);
}
if (representation.attributes.frameRate !== undefined) {
parsedRepresentation.frameRate = representation.attributes.frameRate;
}
else if (adaptation.attributes.frameRate !== undefined) {
parsedRepresentation.frameRate = adaptation.attributes.frameRate;
}
if (representation.attributes.height !== undefined) {
parsedRepresentation.height = representation.attributes.height;
}
else if (adaptation.attributes.height !== undefined) {
parsedRepresentation.height = adaptation.attributes.height;
}
if (representation.attributes.mimeType !== undefined) {
parsedRepresentation.mimeType = representation.attributes.mimeType;
}
else if (adaptation.attributes.mimeType !== undefined) {
parsedRepresentation.mimeType = adaptation.attributes.mimeType;
}
if (representation.attributes.width !== undefined) {
parsedRepresentation.width = representation.attributes.width;
}
else if (adaptation.attributes.width !== undefined) {
parsedRepresentation.width = adaptation.attributes.width;
}
// Content Protection parsing
{
var contentProtIrArr = __spreadArray(__spreadArray([], __read(((_g = adaptation.children.contentProtections) !== null && _g !== void 0 ? _g : [])), false), __read(((_h = representation.children.contentProtections) !== null && _h !== void 0 ? _h : [])), false);
try {
for (var contentProtIrArr_1 = (e_2 = void 0, __values(contentProtIrArr)), contentProtIrArr_1_1 = contentProtIrArr_1.next(); !contentProtIrArr_1_1.done; contentProtIrArr_1_1 = contentProtIrArr_1.next()) {
var contentProtIr = contentProtIrArr_1_1.value;
context.contentProtectionParser.add(parsedRepresentation, contentProtIr);
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (contentProtIrArr_1_1 && !contentProtIrArr_1_1.done && (_j = contentProtIrArr_1.return)) _j.call(contentProtIrArr_1);
}
finally { if (e_2) throw e_2.error; }
}
}
parsedRepresentation.hdrInfo = getHDRInformation({
adaptationProfiles: adaptation.attributes.profiles,
supplementalProperties: adaptation.children.supplementalProperties,
essentialProperties: adaptation.children.essentialProperties,
manifestProfiles: context.manifestProfiles,
codecs: codecs,
});
parsedRepresentations.push(parsedRepresentation);
};
try {
for (var representationsIR_1 = __values(representationsIR), representationsIR_1_1 = representationsIR_1.next(); !representationsIR_1_1.done; representationsIR_1_1 = representationsIR_1.next()) {
var representation = representationsIR_1_1.value;
_loop_1(representation);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (representationsIR_1_1 && !representationsIR_1_1.done && (_a = representationsIR_1.return)) _a.call(representationsIR_1);
}
finally { if (e_1) throw e_1.error; }
}
return parsedRepresentations;
}