UNPKG

dashjs

Version:

A reference client implementation for the playback of MPEG DASH via Javascript and compliant browsers.

49 lines (48 loc) 7.84 kB
'use strict';Object.defineProperty(exports,"__esModule",{value:true});exports.unescapeDollarsInTemplate=unescapeDollarsInTemplate;exports.replaceIDForTemplate=replaceIDForTemplate;exports.replaceTokenForTemplate=replaceTokenForTemplate;exports.getIndexBasedSegment=getIndexBasedSegment;exports.getTimeBasedSegment=getTimeBasedSegment;var _Segment=require('./../vo/Segment');var _Segment2=_interopRequireDefault(_Segment);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}function zeroPadToLength(numStr,minStrLength){while(numStr.length<minStrLength){numStr='0'+numStr;}return numStr;}/** * The copyright in this software is being made available under the BSD License, * included below. This software may be subject to other third party and contributor * rights, including patent rights, and no such rights are granted under this license. * * Copyright (c) 2013, Dash Industry Forum. * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation and/or * other materials provided with the distribution. * * Neither the name of Dash Industry Forum nor the names of its * contributors may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */function getNumberForSegment(segment,segmentIndex){return segment.representation.startNumber+segmentIndex;}function unescapeDollarsInTemplate(url){return url?url.split('$$').join('$'):url;}function replaceIDForTemplate(url,value){if(!value||!url||url.indexOf('$RepresentationID$')===-1){return url;}var v=value.toString();return url.split('$RepresentationID$').join(v);}function replaceTokenForTemplate(url,token,value){var formatTag='%0';var startPos=void 0,endPos=void 0,formatTagPos=void 0,specifier=void 0,width=void 0,paddedValue=void 0;var tokenLen=token.length;var formatTagLen=formatTag.length;if(!url){return url;}// keep looping round until all instances of <token> have been // replaced. once that has happened, startPos below will be -1 // and the completed url will be returned. while(true){// check if there is a valid $<token>...$ identifier // if not, return the url as is. startPos=url.indexOf('$'+token);if(startPos<0){return url;}// the next '$' must be the end of the identifier // if there isn't one, return the url as is. endPos=url.indexOf('$',startPos+tokenLen);if(endPos<0){return url;}// now see if there is an additional format tag suffixed to // the identifier within the enclosing '$' characters formatTagPos=url.indexOf(formatTag,startPos+tokenLen);if(formatTagPos>startPos&&formatTagPos<endPos){specifier=url.charAt(endPos-1);width=parseInt(url.substring(formatTagPos+formatTagLen,endPos-1),10);// support the minimum specifiers required by IEEE 1003.1 // (d, i , o, u, x, and X) for completeness switch(specifier){// treat all int types as uint, // hence deliberate fallthrough case'd':case'i':case'u':paddedValue=zeroPadToLength(value.toString(),width);break;case'x':paddedValue=zeroPadToLength(value.toString(16),width);break;case'X':paddedValue=zeroPadToLength(value.toString(16),width).toUpperCase();break;case'o':paddedValue=zeroPadToLength(value.toString(8),width);break;default:return url;}}else{paddedValue=value;}url=url.substring(0,startPos)+paddedValue+url.substring(endPos+1);}}function getSegment(representation,duration,presentationStartTime,mediaStartTime,availabilityStartTime,timelineConverter,presentationEndTime,isDynamic,index){var seg=new _Segment2.default();seg.representation=representation;seg.duration=duration;seg.presentationStartTime=presentationStartTime;seg.mediaStartTime=mediaStartTime;seg.availabilityStartTime=availabilityStartTime;seg.availabilityEndTime=timelineConverter.calcAvailabilityEndTimeFromPresentationTime(presentationEndTime,representation.adaptation.period.mpd,isDynamic);seg.wallStartTime=timelineConverter.calcWallTimeForSegment(seg,isDynamic);seg.replacementNumber=getNumberForSegment(seg,index);seg.availabilityIdx=index;return seg;}function isSegmentAvailable(timelineConverter,representation,segment,isDynamic){var periodEnd=timelineConverter.getPeriodEnd(representation,isDynamic);var periodRelativeEnd=timelineConverter.calcPeriodRelativeTimeFromMpdRelativeTime(representation,periodEnd);var segmentTime=timelineConverter.calcPeriodRelativeTimeFromMpdRelativeTime(representation,segment.presentationStartTime);if(segmentTime>=periodRelativeEnd){return false;}return true;}function getIndexBasedSegment(timelineConverter,isDynamic,representation,index){var duration=void 0,presentationStartTime=void 0,presentationEndTime=void 0;duration=representation.segmentDuration;/* * From spec - If neither @duration attribute nor SegmentTimeline element is present, then the Representation * shall contain exactly one Media Segment. The MPD start time is 0 and the MPD duration is obtained * in the same way as for the last Media Segment in the Representation. */if(isNaN(duration)){duration=representation.adaptation.period.duration;}presentationStartTime=parseFloat((representation.adaptation.period.start+index*duration).toFixed(5));presentationEndTime=parseFloat((presentationStartTime+duration).toFixed(5));var segment=getSegment(representation,duration,presentationStartTime,timelineConverter.calcMediaTimeFromPresentationTime(presentationStartTime,representation),timelineConverter.calcAvailabilityStartTimeFromPresentationTime(presentationStartTime,representation.adaptation.period.mpd,isDynamic),timelineConverter,presentationEndTime,isDynamic,index);if(!isSegmentAvailable(timelineConverter,representation,segment,isDynamic)){return null;}return segment;}function getTimeBasedSegment(timelineConverter,isDynamic,representation,time,duration,fTimescale,url,range,index,tManifest){var scaledTime=time/fTimescale;var scaledDuration=Math.min(duration/fTimescale,representation.adaptation.period.mpd.maxSegmentDuration);var presentationStartTime=void 0,presentationEndTime=void 0,seg=void 0;presentationStartTime=timelineConverter.calcPresentationTimeFromMediaTime(scaledTime,representation);presentationEndTime=presentationStartTime+scaledDuration;seg=getSegment(representation,scaledDuration,presentationStartTime,scaledTime,representation.adaptation.period.mpd.manifest.loadedTime,timelineConverter,presentationEndTime,isDynamic,index);if(!isSegmentAvailable(timelineConverter,representation,seg,isDynamic)){return null;}seg.replacementTime=tManifest?tManifest:time;url=replaceTokenForTemplate(url,'Number',seg.replacementNumber);url=replaceTokenForTemplate(url,'Time',seg.replacementTime);seg.media=url;seg.mediaRange=range;return seg;} //# sourceMappingURL=SegmentsUtils.js.map