App-MHFS
view release on metacpan or search on metacpan
share/public_html/static/hls.js view on Meta::CPAN
*/
var sample_aes_SampleAesDecrypter = function () {
function SampleAesDecrypter(observer, config, decryptdata, discardEPB) {
sample_aes__classCallCheck(this, SampleAesDecrypter);
this.decryptdata = decryptdata;
this.discardEPB = discardEPB;
this.decrypter = new crypt_decrypter["a" /* default */](observer, config, { removePKCS7Padding: false });
}
SampleAesDecrypter.prototype.decryptBuffer = function decryptBuffer(encryptedData, callback) {
this.decrypter.decrypt(encryptedData, this.decryptdata.key.buffer, this.decryptdata.iv.buffer, callback);
};
// AAC - encrypt all full 16 bytes blocks starting from offset 16
SampleAesDecrypter.prototype.decryptAacSample = function decryptAacSample(samples, sampleIndex, callback, sync) {
var curUnit = samples[sampleIndex].unit;
var encryptedData = curUnit.subarray(16, curUnit.length - curUnit.length % 16);
var encryptedBuffer = encryptedData.buffer.slice(encryptedData.byteOffset, encryptedData.byteOffset + encryptedData.length);
var localthis = this;
this.decryptBuffer(encryptedBuffer, function (decryptedData) {
decryptedData = new Uint8Array(decryptedData);
curUnit.set(decryptedData, 16);
if (!sync) {
localthis.decryptAacSamples(samples, sampleIndex + 1, callback);
}
});
};
SampleAesDecrypter.prototype.decryptAacSamples = function decryptAacSamples(samples, sampleIndex, callback) {
for (;; sampleIndex++) {
if (sampleIndex >= samples.length) {
callback();
return;
}
if (samples[sampleIndex].unit.length < 32) {
continue;
}
var sync = this.decrypter.isSync();
this.decryptAacSample(samples, sampleIndex, callback, sync);
if (!sync) {
return;
}
}
};
// AVC - encrypt one 16 bytes block out of ten, starting from offset 32
SampleAesDecrypter.prototype.getAvcEncryptedData = function getAvcEncryptedData(decodedData) {
var encryptedDataLen = Math.floor((decodedData.length - 48) / 160) * 16 + 16;
var encryptedData = new Int8Array(encryptedDataLen);
var outputPos = 0;
for (var inputPos = 32; inputPos <= decodedData.length - 16; inputPos += 160, outputPos += 16) {
encryptedData.set(decodedData.subarray(inputPos, inputPos + 16), outputPos);
}
return encryptedData;
};
SampleAesDecrypter.prototype.getAvcDecryptedUnit = function getAvcDecryptedUnit(decodedData, decryptedData) {
decryptedData = new Uint8Array(decryptedData);
var inputPos = 0;
for (var outputPos = 32; outputPos <= decodedData.length - 16; outputPos += 160, inputPos += 16) {
decodedData.set(decryptedData.subarray(inputPos, inputPos + 16), outputPos);
}
return decodedData;
};
SampleAesDecrypter.prototype.decryptAvcSample = function decryptAvcSample(samples, sampleIndex, unitIndex, callback, curUnit, sync) {
var decodedData = this.discardEPB(curUnit.data);
var encryptedData = this.getAvcEncryptedData(decodedData);
var localthis = this;
this.decryptBuffer(encryptedData.buffer, function (decryptedData) {
curUnit.data = localthis.getAvcDecryptedUnit(decodedData, decryptedData);
if (!sync) {
localthis.decryptAvcSamples(samples, sampleIndex, unitIndex + 1, callback);
}
});
};
SampleAesDecrypter.prototype.decryptAvcSamples = function decryptAvcSamples(samples, sampleIndex, unitIndex, callback) {
for (;; sampleIndex++, unitIndex = 0) {
if (sampleIndex >= samples.length) {
callback();
return;
}
var curUnits = samples[sampleIndex].units;
for (;; unitIndex++) {
if (unitIndex >= curUnits.length) {
break;
}
var curUnit = curUnits[unitIndex];
if (curUnit.length <= 48 || curUnit.type !== 1 && curUnit.type !== 5) {
continue;
}
var sync = this.decrypter.isSync();
this.decryptAvcSample(samples, sampleIndex, unitIndex, callback, curUnit, sync);
if (!sync) {
return;
}
}
}
};
return SampleAesDecrypter;
}();
/* harmony default export */ var sample_aes = (sample_aes_SampleAesDecrypter);
// CONCATENATED MODULE: ./src/demux/tsdemuxer.js
function tsdemuxer__classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/**
* highly optimized TS demuxer:
* parse PAT, PMT
* extract PES packet from audio and video PIDs
* extract AVC/H264 NAL units and AAC/ADTS samples from PES packet
* trigger the remuxer upon parsing completion
* it also tries to workaround as best as it can audio codec switch (HE-AAC to AAC and vice versa), without having to restart the MediaSource.
* it also controls the remuxing process :
* upon discontinuity or level switch detection, it will also notifies the remuxer so that it can reset its state.
*/
// import Hex from '../utils/hex';
share/public_html/static/hls.js view on Meta::CPAN
if (!this.config.forceKeyFrameOnDiscontinuity || avcSample.key === true || avcTrack.sps && (nbSamples || this.contiguous)) {
avcSample.id = nbSamples;
samples.push(avcSample);
} else {
// dropped samples, track it
avcTrack.dropped++;
}
}
if (avcSample.debug.length) {
logger["b" /* logger */].log(avcSample.pts + '/' + avcSample.dts + ':' + avcSample.debug);
}
};
TSDemuxer.prototype._parseAVCPES = function _parseAVCPES(pes, last) {
var _this = this;
// logger.log('parse new PES');
var track = this._avcTrack,
units = this._parseAVCNALu(pes.data),
debug = false,
expGolombDecoder = void 0,
avcSample = this.avcSample,
push = void 0,
spsfound = false,
i = void 0,
pushAccesUnit = this.pushAccesUnit.bind(this),
createAVCSample = function createAVCSample(key, pts, dts, debug) {
return { key: key, pts: pts, dts: dts, units: [], debug: debug };
};
// free pes.data to save up some memory
pes.data = null;
// if new NAL units found and last sample still there, let's push ...
// this helps parsing streams with missing AUD (only do this if AUD never found)
if (avcSample && units.length && !track.audFound) {
pushAccesUnit(avcSample, track);
avcSample = this.avcSample = createAVCSample(false, pes.pts, pes.dts, '');
}
units.forEach(function (unit) {
switch (unit.type) {
// NDR
case 1:
push = true;
if (!avcSample) {
avcSample = _this.avcSample = createAVCSample(true, pes.pts, pes.dts, '');
}
if (debug) {
avcSample.debug += 'NDR ';
}
avcSample.frame = true;
var data = unit.data;
// only check slice type to detect KF in case SPS found in same packet (any keyframe is preceded by SPS ...)
if (spsfound && data.length > 4) {
// retrieve slice type by parsing beginning of NAL unit (follow H264 spec, slice_header definition) to detect keyframe embedded in NDR
var sliceType = new exp_golomb(data).readSliceType();
// 2 : I slice, 4 : SI slice, 7 : I slice, 9: SI slice
// SI slice : A slice that is coded using intra prediction only and using quantisation of the prediction samples.
// An SI slice can be coded such that its decoded samples can be constructed identically to an SP slice.
// I slice: A slice that is not an SI slice that is decoded using intra prediction only.
// if (sliceType === 2 || sliceType === 7) {
if (sliceType === 2 || sliceType === 4 || sliceType === 7 || sliceType === 9) {
avcSample.key = true;
}
}
break;
// IDR
case 5:
push = true;
// handle PES not starting with AUD
if (!avcSample) {
avcSample = _this.avcSample = createAVCSample(true, pes.pts, pes.dts, '');
}
if (debug) {
avcSample.debug += 'IDR ';
}
avcSample.key = true;
avcSample.frame = true;
break;
// SEI
case 6:
push = true;
if (debug && avcSample) {
avcSample.debug += 'SEI ';
}
expGolombDecoder = new exp_golomb(_this.discardEPB(unit.data));
// skip frameType
expGolombDecoder.readUByte();
var payloadType = 0;
var payloadSize = 0;
var endOfCaptions = false;
var b = 0;
while (!endOfCaptions && expGolombDecoder.bytesAvailable > 1) {
payloadType = 0;
do {
b = expGolombDecoder.readUByte();
payloadType += b;
} while (b === 0xFF);
// Parse payload size.
payloadSize = 0;
do {
b = expGolombDecoder.readUByte();
payloadSize += b;
} while (b === 0xFF);
// TODO: there can be more than one payload in an SEI packet...
// TODO: need to read type and size in a while loop to get them all
if (payloadType === 4 && expGolombDecoder.bytesAvailable !== 0) {
endOfCaptions = true;
var countryCode = expGolombDecoder.readUByte();
if (countryCode === 181) {
share/public_html/static/hls.js view on Meta::CPAN
var id3_track_controller_ID3TrackController = function (_EventHandler) {
id3_track_controller__inherits(ID3TrackController, _EventHandler);
function ID3TrackController(hls) {
id3_track_controller__classCallCheck(this, ID3TrackController);
var _this = id3_track_controller__possibleConstructorReturn(this, _EventHandler.call(this, hls, events["a" /* default */].MEDIA_ATTACHED, events["a" /* default */].MEDIA_DETACHING, events["a" /* default */].FRAG_PARSING_METADATA));
_this.id3Track = undefined;
_this.media = undefined;
return _this;
}
ID3TrackController.prototype.destroy = function destroy() {
event_handler.prototype.destroy.call(this);
};
// Add ID3 metatadata text track.
ID3TrackController.prototype.onMediaAttached = function onMediaAttached(data) {
this.media = data.media;
if (!this.media) {}
};
ID3TrackController.prototype.onMediaDetaching = function onMediaDetaching() {
clearCurrentCues(this.id3Track);
this.id3Track = undefined;
this.media = undefined;
};
ID3TrackController.prototype.getID3Track = function getID3Track(textTracks) {
for (var i = 0; i < textTracks.length; i++) {
var textTrack = textTracks[i];
if (textTrack.kind === 'metadata' && textTrack.label === 'id3') {
// send 'addtrack' when reusing the textTrack for metadata,
// same as what we do for captions
sendAddTrackEvent(textTrack, this.media);
return textTrack;
}
}
return this.media.addTextTrack('metadata', 'id3');
};
ID3TrackController.prototype.onFragParsingMetadata = function onFragParsingMetadata(data) {
var fragment = data.frag;
var samples = data.samples;
// create track dynamically
if (!this.id3Track) {
this.id3Track = this.getID3Track(this.media.textTracks);
this.id3Track.mode = 'hidden';
}
// Attempt to recreate Safari functionality by creating
// WebKitDataCue objects when available and store the decoded
// ID3 data in the value property of the cue
var Cue = window.WebKitDataCue || window.VTTCue || window.TextTrackCue;
for (var i = 0; i < samples.length; i++) {
var frames = id3["a" /* default */].getID3Frames(samples[i].data);
if (frames) {
var startTime = samples[i].pts;
var endTime = i < samples.length - 1 ? samples[i + 1].pts : fragment.endPTS;
// Give a slight bump to the endTime if it's equal to startTime to avoid a SyntaxError in IE
if (startTime === endTime) {
endTime += 0.0001;
}
for (var j = 0; j < frames.length; j++) {
var frame = frames[j];
// Safari doesn't put the timestamp frame in the TextTrack
if (!id3["a" /* default */].isTimeStampFrame(frame)) {
var cue = new Cue(startTime, endTime, '');
cue.value = frame;
this.id3Track.addCue(cue);
}
}
}
}
};
return ID3TrackController;
}(event_handler);
/* harmony default export */ var id3_track_controller = (id3_track_controller_ID3TrackController);
// CONCATENATED MODULE: ./src/is-supported.js
function is_supported_isSupported() {
var mediaSource = getMediaSource();
var sourceBuffer = window.SourceBuffer || window.WebKitSourceBuffer;
var isTypeSupported = mediaSource && typeof mediaSource.isTypeSupported === 'function' && mediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E,mp4a.40.2"');
// if SourceBuffer is exposed ensure its API is valid
// safari and old version of Chrome doe not expose SourceBuffer globally so checking SourceBuffer.prototype is impossible
var sourceBufferValidAPI = !sourceBuffer || sourceBuffer.prototype && typeof sourceBuffer.prototype.appendBuffer === 'function' && typeof sourceBuffer.prototype.remove === 'function';
return !!isTypeSupported && !!sourceBufferValidAPI;
}
// CONCATENATED MODULE: ./src/utils/ewma.js
function ewma__classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/*
* compute an Exponential Weighted moving average
* - https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
* - heavily inspired from shaka-player
*/
var EWMA = function () {
// About half of the estimated value will be from the last |halfLife| samples by weight.
function EWMA(halfLife) {
ewma__classCallCheck(this, EWMA);
// Larger values of alpha expire historical data more slowly.
this.alpha_ = halfLife ? Math.exp(Math.log(0.5) / halfLife) : 0;
share/public_html/static/hls.js view on Meta::CPAN
var pixelRatio = 1;
try {
pixelRatio = window.devicePixelRatio;
} catch (e) {}
return pixelRatio;
}
}]);
return CapLevelController;
}(event_handler);
/* harmony default export */ var cap_level_controller = (cap_level_controller_CapLevelController);
// CONCATENATED MODULE: ./src/controller/fps-controller.js
function fps_controller__classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function fps_controller__possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : se...
function fps_controller__inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Objec...
/*
* FPS Controller
*/
var fps_controller__window = window,
fps_controller_performance = fps_controller__window.performance;
var fps_controller_FPSController = function (_EventHandler) {
fps_controller__inherits(FPSController, _EventHandler);
function FPSController(hls) {
fps_controller__classCallCheck(this, FPSController);
return fps_controller__possibleConstructorReturn(this, _EventHandler.call(this, hls, events["a" /* default */].MEDIA_ATTACHING));
}
FPSController.prototype.destroy = function destroy() {
if (this.timer) {
clearInterval(this.timer);
}
this.isVideoPlaybackQualityAvailable = false;
};
FPSController.prototype.onMediaAttaching = function onMediaAttaching(data) {
var config = this.hls.config;
if (config.capLevelOnFPSDrop) {
var video = this.video = data.media instanceof window.HTMLVideoElement ? data.media : null;
if (typeof video.getVideoPlaybackQuality === 'function') {
this.isVideoPlaybackQualityAvailable = true;
}
clearInterval(this.timer);
this.timer = setInterval(this.checkFPSInterval.bind(this), config.fpsDroppedMonitoringPeriod);
}
};
FPSController.prototype.checkFPS = function checkFPS(video, decodedFrames, droppedFrames) {
var currentTime = fps_controller_performance.now();
if (decodedFrames) {
if (this.lastTime) {
var currentPeriod = currentTime - this.lastTime,
currentDropped = droppedFrames - this.lastDroppedFrames,
currentDecoded = decodedFrames - this.lastDecodedFrames,
droppedFPS = 1000 * currentDropped / currentPeriod,
hls = this.hls;
hls.trigger(events["a" /* default */].FPS_DROP, { currentDropped: currentDropped, currentDecoded: currentDecoded, totalDroppedFrames: droppedFrames });
if (droppedFPS > 0) {
// logger.log('checkFPS : droppedFPS/decodedFPS:' + droppedFPS/(1000 * currentDecoded / currentPeriod));
if (currentDropped > hls.config.fpsDroppedMonitoringThreshold * currentDecoded) {
var currentLevel = hls.currentLevel;
logger["b" /* logger */].warn('drop FPS ratio greater than max allowed value for currentLevel: ' + currentLevel);
if (currentLevel > 0 && (hls.autoLevelCapping === -1 || hls.autoLevelCapping >= currentLevel)) {
currentLevel = currentLevel - 1;
hls.trigger(events["a" /* default */].FPS_DROP_LEVEL_CAPPING, { level: currentLevel, droppedLevel: hls.currentLevel });
hls.autoLevelCapping = currentLevel;
hls.streamController.nextLevelSwitch();
}
}
}
}
this.lastTime = currentTime;
this.lastDroppedFrames = droppedFrames;
this.lastDecodedFrames = decodedFrames;
}
};
FPSController.prototype.checkFPSInterval = function checkFPSInterval() {
var video = this.video;
if (video) {
if (this.isVideoPlaybackQualityAvailable) {
var videoPlaybackQuality = video.getVideoPlaybackQuality();
this.checkFPS(video, videoPlaybackQuality.totalVideoFrames, videoPlaybackQuality.droppedVideoFrames);
} else {
this.checkFPS(video, video.webkitDecodedFrameCount, video.webkitDroppedFrameCount);
}
}
};
return FPSController;
}(event_handler);
/* harmony default export */ var fps_controller = (fps_controller_FPSController);
// CONCATENATED MODULE: ./src/utils/xhr-loader.js
function xhr_loader__classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/**
* XHR based logger
*/
var xhr_loader__window = window,
xhr_loader_performance = xhr_loader__window.performance,
XMLHttpRequest = xhr_loader__window.XMLHttpRequest;
var xhr_loader_XhrLoader = function () {
function XhrLoader(config) {
xhr_loader__classCallCheck(this, XhrLoader);
if (config && config.xhrSetup) {
this.xhrSetup = config.xhrSetup;
}
}
XhrLoader.prototype.destroy = function destroy() {
this.abort();
this.loader = null;
};
XhrLoader.prototype.abort = function abort() {
var loader = this.loader;
if (loader && loader.readyState !== 4) {
this.stats.aborted = true;
loader.abort();
}
window.clearTimeout(this.requestTimeout);
this.requestTimeout = null;
window.clearTimeout(this.retryTimeout);
this.retryTimeout = null;
};
XhrLoader.prototype.load = function load(context, config, callbacks) {
( run in 1.071 second using v1.01-cache-2.11-cpan-d7f47b0818f )