@gcorevideo/player 2.0.2 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +192 -1480
- package/lib/Player.d.ts +1 -0
- package/lib/Player.d.ts.map +1 -1
- package/lib/Player.js +18 -6
- package/lib/plugins/dash-playback/DashPlayback.d.ts.map +1 -1
- package/lib/plugins/dash-playback/DashPlayback.js +0 -3
- package/lib/trace/SentryTracer.d.ts +3 -2
- package/lib/trace/SentryTracer.d.ts.map +1 -1
- package/lib/trace/SentryTracer.js +4 -3
- package/lib/types.d.ts +1 -0
- package/lib/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/Player.ts +20 -7
- package/src/plugins/dash-playback/DashPlayback.ts +0 -3
- package/src/trace/SentryTracer.ts +3 -3
- package/src/types.ts +2 -1
- package/tsconfig.tsbuildinfo +1 -1
package/dist/index.js
CHANGED
|
@@ -11501,7 +11501,7 @@ function isUndefined(arg) {
|
|
|
11501
11501
|
}
|
|
11502
11502
|
|
|
11503
11503
|
function isRegExp(re) {
|
|
11504
|
-
return isObject(re) && objectToString
|
|
11504
|
+
return isObject(re) && objectToString(re) === '[object RegExp]';
|
|
11505
11505
|
}
|
|
11506
11506
|
|
|
11507
11507
|
function isObject(arg) {
|
|
@@ -11509,12 +11509,12 @@ function isObject(arg) {
|
|
|
11509
11509
|
}
|
|
11510
11510
|
|
|
11511
11511
|
function isDate(d) {
|
|
11512
|
-
return isObject(d) && objectToString
|
|
11512
|
+
return isObject(d) && objectToString(d) === '[object Date]';
|
|
11513
11513
|
}
|
|
11514
11514
|
|
|
11515
11515
|
function isError(e) {
|
|
11516
11516
|
return isObject(e) &&
|
|
11517
|
-
(objectToString
|
|
11517
|
+
(objectToString(e) === '[object Error]' || e instanceof Error);
|
|
11518
11518
|
}
|
|
11519
11519
|
|
|
11520
11520
|
function isFunction(arg) {
|
|
@@ -11530,7 +11530,7 @@ function isPrimitive(arg) {
|
|
|
11530
11530
|
typeof arg === 'undefined';
|
|
11531
11531
|
}
|
|
11532
11532
|
|
|
11533
|
-
function objectToString
|
|
11533
|
+
function objectToString(o) {
|
|
11534
11534
|
return Object.prototype.toString.call(o);
|
|
11535
11535
|
}
|
|
11536
11536
|
|
|
@@ -12362,7 +12362,6 @@ class DashPlayback extends HTML5Video {
|
|
|
12362
12362
|
if (!this._dash) {
|
|
12363
12363
|
return Infinity;
|
|
12364
12364
|
}
|
|
12365
|
-
// Log.debug(T, '_duration', this._dash.duration());
|
|
12366
12365
|
return this._dash.duration() ?? Infinity;
|
|
12367
12366
|
}
|
|
12368
12367
|
constructor(options, i18n, playerError) {
|
|
@@ -12712,7 +12711,6 @@ class DashPlayback extends HTML5Video {
|
|
|
12712
12711
|
}
|
|
12713
12712
|
stop() {
|
|
12714
12713
|
if (this._dash) {
|
|
12715
|
-
Log.debug(T$2, 'stop');
|
|
12716
12714
|
this._stopTimeUpdateTimer();
|
|
12717
12715
|
this._dash.reset();
|
|
12718
12716
|
super.stop();
|
|
@@ -12720,7 +12718,6 @@ class DashPlayback extends HTML5Video {
|
|
|
12720
12718
|
}
|
|
12721
12719
|
}
|
|
12722
12720
|
destroy() {
|
|
12723
|
-
Log.debug(T$2, 'destroy');
|
|
12724
12721
|
this._stopTimeUpdateTimer();
|
|
12725
12722
|
if (this._dash) {
|
|
12726
12723
|
this._dash.off(DASHJS.MediaPlayer.events.ERROR, this._onDASHJSSError);
|
|
@@ -13313,7 +13310,7 @@ function enableLogs(debugConfig, id) {
|
|
|
13313
13310
|
exportedLogger = fakeLogger;
|
|
13314
13311
|
}
|
|
13315
13312
|
}
|
|
13316
|
-
const logger
|
|
13313
|
+
const logger = exportedLogger;
|
|
13317
13314
|
|
|
13318
13315
|
const DECIMAL_RESOLUTION_REGEX = /^(\d+)x(\d+)$/;
|
|
13319
13316
|
const ATTR_LIST_REGEX = /(.+?)=(".*?"|.*?)(?:,|$)/g;
|
|
@@ -13414,7 +13411,7 @@ class DateRange {
|
|
|
13414
13411
|
const previousAttr = dateRangeWithSameId.attr;
|
|
13415
13412
|
for (const key in previousAttr) {
|
|
13416
13413
|
if (Object.prototype.hasOwnProperty.call(dateRangeAttr, key) && dateRangeAttr[key] !== previousAttr[key]) {
|
|
13417
|
-
logger
|
|
13414
|
+
logger.warn(`DATERANGE tag attribute: "${key}" does not match for tags with ID: "${dateRangeAttr.ID}"`);
|
|
13418
13415
|
this._badValueForSameId = key;
|
|
13419
13416
|
break;
|
|
13420
13417
|
}
|
|
@@ -14540,7 +14537,7 @@ function parseSegmentIndex(sidx) {
|
|
|
14540
14537
|
const referenceSize = referenceInfo & 0x7fffffff;
|
|
14541
14538
|
const referenceType = (referenceInfo & 0x80000000) >>> 31;
|
|
14542
14539
|
if (referenceType === 1) {
|
|
14543
|
-
logger
|
|
14540
|
+
logger.warn('SIDX has hierarchical references (not supported)');
|
|
14544
14541
|
return null;
|
|
14545
14542
|
}
|
|
14546
14543
|
const subsegmentDuration = readUint32(sidx, referenceIndex);
|
|
@@ -14832,7 +14829,7 @@ function patchEncyptionData(initSegment, decryptdata) {
|
|
|
14832
14829
|
// Look for default key id (keyID offset is always 8 within the tenc box):
|
|
14833
14830
|
const tencKeyId = tenc.subarray(8, 24);
|
|
14834
14831
|
if (!tencKeyId.some(b => b !== 0)) {
|
|
14835
|
-
logger
|
|
14832
|
+
logger.log(`[eme] Patching keyId in 'enc${isAudio ? 'a' : 'v'}>sinf>>tenc' box: ${Hex.hexDump(tencKeyId)} -> ${Hex.hexDump(keyId)}`);
|
|
14836
14833
|
tenc.set(keyId, 8);
|
|
14837
14834
|
}
|
|
14838
14835
|
}
|
|
@@ -14886,7 +14883,7 @@ function getStartDTS(initData, fmp4) {
|
|
|
14886
14883
|
// This prevents large values from being used for initPTS, which can cause playlist sync issues.
|
|
14887
14884
|
// https://github.com/video-dev/hls.js/issues/5303
|
|
14888
14885
|
if (baseTime === UINT32_MAX$1) {
|
|
14889
|
-
logger
|
|
14886
|
+
logger.warn(`[mp4-demuxer]: Ignoring assumed invalid signed 64-bit track fragment decode time`);
|
|
14890
14887
|
return result;
|
|
14891
14888
|
}
|
|
14892
14889
|
baseTime *= UINT32_MAX$1 + 1;
|
|
@@ -15293,7 +15290,7 @@ function parseSEIMessageFromNALu(unescapedData, headerSize, pts, samples) {
|
|
|
15293
15290
|
seiPtr += payloadSize;
|
|
15294
15291
|
} else if (payloadSize > leftOver) {
|
|
15295
15292
|
// Some type of corruption has happened?
|
|
15296
|
-
logger
|
|
15293
|
+
logger.error(`Malformed SEI payload. ${payloadSize} is too small, only ${leftOver} bytes left to parse.`);
|
|
15297
15294
|
// We might be able to parse some data, but let's be safe and ignore it.
|
|
15298
15295
|
break;
|
|
15299
15296
|
}
|
|
@@ -15436,7 +15433,7 @@ function parseEmsg(data) {
|
|
|
15436
15433
|
presentationTime = 2 ** 32 * leftPresentationTime + rightPresentationTime;
|
|
15437
15434
|
if (!isSafeInteger(presentationTime)) {
|
|
15438
15435
|
presentationTime = Number.MAX_SAFE_INTEGER;
|
|
15439
|
-
logger
|
|
15436
|
+
logger.warn('Presentation time exceeds safe integer limit and wrapped to max safe integer in parsing emsg box');
|
|
15440
15437
|
}
|
|
15441
15438
|
eventDuration = readUint32(data, offset);
|
|
15442
15439
|
offset += 4;
|
|
@@ -15642,7 +15639,7 @@ class LevelKey {
|
|
|
15642
15639
|
// If the segment was encrypted with AES-128
|
|
15643
15640
|
// It must have an IV defined. We cannot substitute the Segment Number in.
|
|
15644
15641
|
if (this.method === 'AES-128' && !this.iv) {
|
|
15645
|
-
logger
|
|
15642
|
+
logger.warn(`missing IV for initialization segment with method="${this.method}" - compliance issue`);
|
|
15646
15643
|
}
|
|
15647
15644
|
// Explicitly set sn to resulting value from implicit conversions 'initSegment' values for IV generation.
|
|
15648
15645
|
sn = 0;
|
|
@@ -16071,7 +16068,7 @@ class M3U8Parser {
|
|
|
16071
16068
|
}
|
|
16072
16069
|
parsed.sessionKeys.push(sessionKey);
|
|
16073
16070
|
} else {
|
|
16074
|
-
logger
|
|
16071
|
+
logger.warn(`[Keys] Ignoring invalid EXT-X-SESSION-KEY tag: "${attributes}"`);
|
|
16075
16072
|
}
|
|
16076
16073
|
break;
|
|
16077
16074
|
}
|
|
@@ -16272,7 +16269,7 @@ class M3U8Parser {
|
|
|
16272
16269
|
} else {
|
|
16273
16270
|
result = result[0].match(LEVEL_PLAYLIST_REGEX_SLOW);
|
|
16274
16271
|
if (!result) {
|
|
16275
|
-
logger
|
|
16272
|
+
logger.warn('No matches on slow regex match for level playlist!');
|
|
16276
16273
|
continue;
|
|
16277
16274
|
}
|
|
16278
16275
|
for (i = 1; i < result.length; i++) {
|
|
@@ -16352,7 +16349,7 @@ class M3U8Parser {
|
|
|
16352
16349
|
if (dateRange.isValid || level.skippedSegments) {
|
|
16353
16350
|
level.dateRanges[dateRange.id] = dateRange;
|
|
16354
16351
|
} else {
|
|
16355
|
-
logger
|
|
16352
|
+
logger.warn(`Ignoring invalid DATERANGE tag: "${value1}"`);
|
|
16356
16353
|
}
|
|
16357
16354
|
// Add to fragment tag list for backwards compatibility (< v1.2.0)
|
|
16358
16355
|
frag.tagList.push(['EXT-X-DATERANGE', value1]);
|
|
@@ -16390,7 +16387,7 @@ class M3U8Parser {
|
|
|
16390
16387
|
}
|
|
16391
16388
|
levelkeys[levelKey.keyFormat] = levelKey;
|
|
16392
16389
|
} else {
|
|
16393
|
-
logger
|
|
16390
|
+
logger.warn(`[Keys] Ignoring invalid EXT-X-KEY tag: "${value1}"`);
|
|
16394
16391
|
}
|
|
16395
16392
|
break;
|
|
16396
16393
|
}
|
|
@@ -16483,7 +16480,7 @@ class M3U8Parser {
|
|
|
16483
16480
|
break;
|
|
16484
16481
|
}
|
|
16485
16482
|
default:
|
|
16486
|
-
logger
|
|
16483
|
+
logger.warn(`line parsed but not handled: ${result}`);
|
|
16487
16484
|
break;
|
|
16488
16485
|
}
|
|
16489
16486
|
}
|
|
@@ -16555,7 +16552,7 @@ function parseKey(keyTagAttributes, baseurl, parsed) {
|
|
|
16555
16552
|
// From RFC: This attribute is OPTIONAL; its absence indicates an implicit value of "identity".
|
|
16556
16553
|
const decryptkeyformat = (_keyAttrs$KEYFORMAT = keyAttrs.KEYFORMAT) != null ? _keyAttrs$KEYFORMAT : 'identity';
|
|
16557
16554
|
if (decrypturi && keyAttrs.IV && !decryptiv) {
|
|
16558
|
-
logger
|
|
16555
|
+
logger.error(`Invalid IV: ${keyAttrs.IV}`);
|
|
16559
16556
|
}
|
|
16560
16557
|
// If decrypturi is a URI with a scheme, then baseurl will be ignored
|
|
16561
16558
|
// No uri is allowed when METHOD is NONE
|
|
@@ -16817,10 +16814,10 @@ class PlaylistLoader {
|
|
|
16817
16814
|
const loaderContext = loader.context;
|
|
16818
16815
|
if (loaderContext && loaderContext.url === context.url && loaderContext.level === context.level) {
|
|
16819
16816
|
// same URL can't overlap
|
|
16820
|
-
logger
|
|
16817
|
+
logger.trace('[playlist-loader]: playlist request ongoing');
|
|
16821
16818
|
return;
|
|
16822
16819
|
}
|
|
16823
|
-
logger
|
|
16820
|
+
logger.log(`[playlist-loader]: aborting previous loader for type: ${context.type}`);
|
|
16824
16821
|
loader.abort();
|
|
16825
16822
|
}
|
|
16826
16823
|
|
|
@@ -16930,7 +16927,7 @@ class PlaylistLoader {
|
|
|
16930
16927
|
// alt audio rendition in which quality levels (main)
|
|
16931
16928
|
// contains both audio+video. but with mixed audio track not signaled
|
|
16932
16929
|
if (!embeddedAudioFound && levels[0].audioCodec && !levels[0].attrs.AUDIO) {
|
|
16933
|
-
logger
|
|
16930
|
+
logger.log('[playlist-loader]: audio codec signaled in quality level, but no embedded audio track signaled, create one');
|
|
16934
16931
|
audioTracks.unshift({
|
|
16935
16932
|
type: 'main',
|
|
16936
16933
|
name: 'main',
|
|
@@ -17029,7 +17026,7 @@ class PlaylistLoader {
|
|
|
17029
17026
|
message += ` id: ${context.id} group-id: "${context.groupId}"`;
|
|
17030
17027
|
}
|
|
17031
17028
|
const error = new Error(message);
|
|
17032
|
-
logger
|
|
17029
|
+
logger.warn(`[playlist-loader]: ${message}`);
|
|
17033
17030
|
let details = ErrorDetails.UNKNOWN;
|
|
17034
17031
|
let fatal = false;
|
|
17035
17032
|
const loader = this.getInternalLoader(context);
|
|
@@ -17196,13 +17193,13 @@ function addCueToTrack(track, cue) {
|
|
|
17196
17193
|
throw new Error(`addCue is failed for: ${cue}`);
|
|
17197
17194
|
}
|
|
17198
17195
|
} catch (err) {
|
|
17199
|
-
logger
|
|
17196
|
+
logger.debug(`[texttrack-utils]: ${err}`);
|
|
17200
17197
|
try {
|
|
17201
17198
|
const textTrackCue = new self.TextTrackCue(cue.startTime, cue.endTime, cue.text);
|
|
17202
17199
|
textTrackCue.id = cue.id;
|
|
17203
17200
|
track.addCue(textTrackCue);
|
|
17204
17201
|
} catch (err2) {
|
|
17205
|
-
logger
|
|
17202
|
+
logger.debug(`[texttrack-utils]: Legacy TextTrackCue fallback failed: ${err2}`);
|
|
17206
17203
|
}
|
|
17207
17204
|
}
|
|
17208
17205
|
}
|
|
@@ -17775,7 +17772,7 @@ class LatencyController {
|
|
|
17775
17772
|
}
|
|
17776
17773
|
this.stallCount++;
|
|
17777
17774
|
if ((_this$levelDetails = this.levelDetails) != null && _this$levelDetails.live) {
|
|
17778
|
-
logger
|
|
17775
|
+
logger.warn('[playback-rate-controller]: Stall detected, adjusting target latency');
|
|
17779
17776
|
}
|
|
17780
17777
|
}
|
|
17781
17778
|
timeupdate() {
|
|
@@ -18055,7 +18052,7 @@ function updateFromToPTS(fragFrom, fragTo) {
|
|
|
18055
18052
|
function updateFragPTSDTS(details, frag, startPTS, endPTS, startDTS, endDTS) {
|
|
18056
18053
|
const parsedMediaDuration = endPTS - startPTS;
|
|
18057
18054
|
if (parsedMediaDuration <= 0) {
|
|
18058
|
-
logger
|
|
18055
|
+
logger.warn('Fragment should have a positive duration', frag);
|
|
18059
18056
|
endPTS = startPTS + frag.duration;
|
|
18060
18057
|
endDTS = startDTS + frag.duration;
|
|
18061
18058
|
}
|
|
@@ -18179,7 +18176,7 @@ function mergeDetails(oldDetails, newDetails) {
|
|
|
18179
18176
|
if (newDetails.skippedSegments) {
|
|
18180
18177
|
newDetails.deltaUpdateFailed = newDetails.fragments.some(frag => !frag);
|
|
18181
18178
|
if (newDetails.deltaUpdateFailed) {
|
|
18182
|
-
logger
|
|
18179
|
+
logger.warn('[level-helper] Previous playlist missing segments skipped in delta playlist');
|
|
18183
18180
|
for (let i = newDetails.skippedSegments; i--;) {
|
|
18184
18181
|
newDetails.fragments.shift();
|
|
18185
18182
|
}
|
|
@@ -18191,7 +18188,7 @@ function mergeDetails(oldDetails, newDetails) {
|
|
|
18191
18188
|
}
|
|
18192
18189
|
const newFragments = newDetails.fragments;
|
|
18193
18190
|
if (ccOffset) {
|
|
18194
|
-
logger
|
|
18191
|
+
logger.warn('discontinuity sliding from playlist, take drift into account');
|
|
18195
18192
|
for (let i = 0; i < newFragments.length; i++) {
|
|
18196
18193
|
newFragments[i].cc += ccOffset;
|
|
18197
18194
|
}
|
|
@@ -18247,7 +18244,7 @@ function mergeDateRanges(oldDateRanges, deltaDateRanges, recentlyRemovedDaterang
|
|
|
18247
18244
|
if (dateRange.isValid) {
|
|
18248
18245
|
dateRanges[id] = dateRange;
|
|
18249
18246
|
} else {
|
|
18250
|
-
logger
|
|
18247
|
+
logger.warn(`Ignoring invalid Playlist Delta Update DATERANGE tag: "${JSON.stringify(deltaDateRanges[id].attr)}"`);
|
|
18251
18248
|
}
|
|
18252
18249
|
});
|
|
18253
18250
|
return dateRanges;
|
|
@@ -18612,9 +18609,9 @@ class ErrorController {
|
|
|
18612
18609
|
this.warn = void 0;
|
|
18613
18610
|
this.error = void 0;
|
|
18614
18611
|
this.hls = hls;
|
|
18615
|
-
this.log = logger
|
|
18616
|
-
this.warn = logger
|
|
18617
|
-
this.error = logger
|
|
18612
|
+
this.log = logger.log.bind(logger, `[info]:`);
|
|
18613
|
+
this.warn = logger.warn.bind(logger, `[warning]:`);
|
|
18614
|
+
this.error = logger.error.bind(logger, `[error]:`);
|
|
18618
18615
|
this.registerListeners();
|
|
18619
18616
|
}
|
|
18620
18617
|
registerListeners() {
|
|
@@ -18971,8 +18968,8 @@ class BasePlaylistController {
|
|
|
18971
18968
|
this.canLoad = false;
|
|
18972
18969
|
this.log = void 0;
|
|
18973
18970
|
this.warn = void 0;
|
|
18974
|
-
this.log = logger
|
|
18975
|
-
this.warn = logger
|
|
18971
|
+
this.log = logger.log.bind(logger, `${logPrefix}:`);
|
|
18972
|
+
this.warn = logger.warn.bind(logger, `${logPrefix}:`);
|
|
18976
18973
|
this.hls = hls;
|
|
18977
18974
|
}
|
|
18978
18975
|
destroy() {
|
|
@@ -19005,7 +19002,7 @@ class BasePlaylistController {
|
|
|
19005
19002
|
try {
|
|
19006
19003
|
uri = new self.URL(attr.URI, previous.url).href;
|
|
19007
19004
|
} catch (error) {
|
|
19008
|
-
logger
|
|
19005
|
+
logger.warn(`Could not construct new URL for Rendition Report: ${error}`);
|
|
19009
19006
|
uri = attr.URI || '';
|
|
19010
19007
|
}
|
|
19011
19008
|
// Use exact match. Otherwise, the last partial match, if any, will be used
|
|
@@ -19597,7 +19594,7 @@ function getStartCodecTier(codecTiers, currentVideoRange, currentBw, audioPrefer
|
|
|
19597
19594
|
};
|
|
19598
19595
|
}
|
|
19599
19596
|
function logStartCodecCandidateIgnored(codeSet, reason) {
|
|
19600
|
-
logger
|
|
19597
|
+
logger.log(`[abr] start candidates with "${codeSet}" ignored because ${reason}`);
|
|
19601
19598
|
}
|
|
19602
19599
|
function getAudioTracksByGroup(allAudioTracks) {
|
|
19603
19600
|
return allAudioTracks.reduce((audioTracksByGroup, track) => {
|
|
@@ -19883,7 +19880,7 @@ class AbrController {
|
|
|
19883
19880
|
this.resetEstimator(nextLoadLevelBitrate);
|
|
19884
19881
|
}
|
|
19885
19882
|
this.clearTimer();
|
|
19886
|
-
logger
|
|
19883
|
+
logger.warn(`[abr] Fragment ${frag.sn}${part ? ' part ' + part.index : ''} of level ${frag.level} is loading too slowly;
|
|
19887
19884
|
Time to underbuffer: ${bufferStarvationDelay.toFixed(3)} s
|
|
19888
19885
|
Estimated load time for current fragment: ${fragLoadedDelay.toFixed(3)} s
|
|
19889
19886
|
Estimated load time for down switch fragment: ${fragLevelNextLoadedDelay.toFixed(3)} s
|
|
@@ -19903,7 +19900,7 @@ class AbrController {
|
|
|
19903
19900
|
}
|
|
19904
19901
|
resetEstimator(abrEwmaDefaultEstimate) {
|
|
19905
19902
|
if (abrEwmaDefaultEstimate) {
|
|
19906
|
-
logger
|
|
19903
|
+
logger.log(`setting initial bwe to ${abrEwmaDefaultEstimate}`);
|
|
19907
19904
|
this.hls.config.abrEwmaDefaultEstimate = abrEwmaDefaultEstimate;
|
|
19908
19905
|
}
|
|
19909
19906
|
this.firstSelection = -1;
|
|
@@ -20135,7 +20132,7 @@ class AbrController {
|
|
|
20135
20132
|
}
|
|
20136
20133
|
const firstLevel = this.hls.firstLevel;
|
|
20137
20134
|
const clamped = Math.min(Math.max(firstLevel, minAutoLevel), maxAutoLevel);
|
|
20138
|
-
logger
|
|
20135
|
+
logger.warn(`[abr] Could not find best starting auto level. Defaulting to first in playlist ${firstLevel} clamped to ${clamped}`);
|
|
20139
20136
|
return clamped;
|
|
20140
20137
|
}
|
|
20141
20138
|
get forcedAutoLevel() {
|
|
@@ -20213,13 +20210,13 @@ class AbrController {
|
|
|
20213
20210
|
// cap maxLoadingDelay and ensure it is not bigger 'than bitrate test' frag duration
|
|
20214
20211
|
const maxLoadingDelay = currentFragDuration ? Math.min(currentFragDuration, config.maxLoadingDelay) : config.maxLoadingDelay;
|
|
20215
20212
|
maxStarvationDelay = maxLoadingDelay - bitrateTestDelay;
|
|
20216
|
-
logger
|
|
20213
|
+
logger.info(`[abr] bitrate test took ${Math.round(1000 * bitrateTestDelay)}ms, set first fragment max fetchDuration to ${Math.round(1000 * maxStarvationDelay)} ms`);
|
|
20217
20214
|
// don't use conservative factor on bitrate test
|
|
20218
20215
|
bwFactor = bwUpFactor = 1;
|
|
20219
20216
|
}
|
|
20220
20217
|
}
|
|
20221
20218
|
const bestLevel = this.findBestLevel(avgbw, minAutoLevel, maxAutoLevel, bufferStarvationDelay, maxStarvationDelay, bwFactor, bwUpFactor);
|
|
20222
|
-
logger
|
|
20219
|
+
logger.info(`[abr] ${bufferStarvationDelay ? 'rebuffering expected' : 'buffer is empty'}, optimal quality level ${bestLevel}`);
|
|
20223
20220
|
if (bestLevel > -1) {
|
|
20224
20221
|
return bestLevel;
|
|
20225
20222
|
}
|
|
@@ -20293,7 +20290,7 @@ class AbrController {
|
|
|
20293
20290
|
currentVideoRange = preferHDR ? videoRanges[videoRanges.length - 1] : videoRanges[0];
|
|
20294
20291
|
currentFrameRate = minFramerate;
|
|
20295
20292
|
currentBw = Math.max(currentBw, minBitrate);
|
|
20296
|
-
logger
|
|
20293
|
+
logger.log(`[abr] picked start tier ${JSON.stringify(startTier)}`);
|
|
20297
20294
|
} else {
|
|
20298
20295
|
currentCodecSet = level == null ? void 0 : level.codecSet;
|
|
20299
20296
|
currentVideoRange = level == null ? void 0 : level.videoRange;
|
|
@@ -20320,11 +20317,11 @@ class AbrController {
|
|
|
20320
20317
|
const levels = this.hls.levels;
|
|
20321
20318
|
const index = levels.indexOf(levelInfo);
|
|
20322
20319
|
if (decodingInfo.error) {
|
|
20323
|
-
logger
|
|
20320
|
+
logger.warn(`[abr] MediaCapabilities decodingInfo error: "${decodingInfo.error}" for level ${index} ${JSON.stringify(decodingInfo)}`);
|
|
20324
20321
|
} else if (!decodingInfo.supported) {
|
|
20325
|
-
logger
|
|
20322
|
+
logger.warn(`[abr] Unsupported MediaCapabilities decodingInfo result for level ${index} ${JSON.stringify(decodingInfo)}`);
|
|
20326
20323
|
if (index > -1 && levels.length > 1) {
|
|
20327
|
-
logger
|
|
20324
|
+
logger.log(`[abr] Removing unsupported level ${index}`);
|
|
20328
20325
|
this.hls.removeLevel(index);
|
|
20329
20326
|
}
|
|
20330
20327
|
}
|
|
@@ -20371,9 +20368,9 @@ class AbrController {
|
|
|
20371
20368
|
const forcedAutoLevel = this.forcedAutoLevel;
|
|
20372
20369
|
if (i !== loadLevel && (forcedAutoLevel === -1 || forcedAutoLevel !== loadLevel)) {
|
|
20373
20370
|
if (levelsSkipped.length) {
|
|
20374
|
-
logger
|
|
20371
|
+
logger.trace(`[abr] Skipped level(s) ${levelsSkipped.join(',')} of ${maxAutoLevel} max with CODECS and VIDEO-RANGE:"${levels[levelsSkipped[0]].codecs}" ${levels[levelsSkipped[0]].videoRange}; not compatible with "${level.codecs}" ${currentVideoRange}`);
|
|
20375
20372
|
}
|
|
20376
|
-
logger
|
|
20373
|
+
logger.info(`[abr] switch candidate:${selectionBaseLevel}->${i} adjustedbw(${Math.round(adjustedbw)})-bitrate=${Math.round(adjustedbw - bitrate)} ttfb:${ttfbEstimateSec.toFixed(1)} avgDuration:${avgDuration.toFixed(1)} maxFetchDuration:${maxFetchDuration.toFixed(1)} fetchDuration:${fetchDuration.toFixed(1)} firstSelection:${firstSelection} codecSet:${currentCodecSet} videoRange:${currentVideoRange} hls.loadLevel:${loadLevel}`);
|
|
20377
20374
|
}
|
|
20378
20375
|
if (firstSelection) {
|
|
20379
20376
|
this.firstSelection = i;
|
|
@@ -21068,7 +21065,7 @@ class BufferHelper {
|
|
|
21068
21065
|
try {
|
|
21069
21066
|
return media.buffered;
|
|
21070
21067
|
} catch (e) {
|
|
21071
|
-
logger
|
|
21068
|
+
logger.log('failed to get media.buffered', e);
|
|
21072
21069
|
return noopBuffered;
|
|
21073
21070
|
}
|
|
21074
21071
|
}
|
|
@@ -21128,12 +21125,12 @@ function findDiscontinuousReferenceFrag(prevDetails, curDetails) {
|
|
|
21128
21125
|
const prevFrags = prevDetails.fragments;
|
|
21129
21126
|
const curFrags = curDetails.fragments;
|
|
21130
21127
|
if (!curFrags.length || !prevFrags.length) {
|
|
21131
|
-
logger
|
|
21128
|
+
logger.log('No fragments to align');
|
|
21132
21129
|
return;
|
|
21133
21130
|
}
|
|
21134
21131
|
const prevStartFrag = findFirstFragWithCC(prevFrags, curFrags[0].cc);
|
|
21135
21132
|
if (!prevStartFrag || prevStartFrag && !prevStartFrag.startPTS) {
|
|
21136
|
-
logger
|
|
21133
|
+
logger.log('No frag in previous level to align on');
|
|
21137
21134
|
return;
|
|
21138
21135
|
}
|
|
21139
21136
|
return prevStartFrag;
|
|
@@ -21198,7 +21195,7 @@ function alignDiscontinuities(lastFrag, details, switchDetails) {
|
|
|
21198
21195
|
if (shouldAlignOnDiscontinuities(lastFrag, switchDetails, details)) {
|
|
21199
21196
|
const referenceFrag = findDiscontinuousReferenceFrag(switchDetails, details);
|
|
21200
21197
|
if (referenceFrag && isFiniteNumber(referenceFrag.start)) {
|
|
21201
|
-
logger
|
|
21198
|
+
logger.log(`Adjusting PTS using last level due to CC increase within current level ${details.url}`);
|
|
21202
21199
|
adjustSlidingStart(referenceFrag.start, details);
|
|
21203
21200
|
}
|
|
21204
21201
|
}
|
|
@@ -21961,7 +21958,7 @@ class Decrypter {
|
|
|
21961
21958
|
const crypto = new AESCrypto(this.subtle, new Uint8Array(iv));
|
|
21962
21959
|
return crypto.decrypt(data.buffer, aesKey);
|
|
21963
21960
|
}).catch(err => {
|
|
21964
|
-
logger
|
|
21961
|
+
logger.warn(`[decrypter]: WebCrypto Error, disable WebCrypto API, ${err.name}: ${err.message}`);
|
|
21965
21962
|
return this.onWebCryptoError(data, key, iv);
|
|
21966
21963
|
});
|
|
21967
21964
|
}
|
|
@@ -21988,7 +21985,7 @@ class Decrypter {
|
|
|
21988
21985
|
if (!this.logEnabled) {
|
|
21989
21986
|
return;
|
|
21990
21987
|
}
|
|
21991
|
-
logger
|
|
21988
|
+
logger.log(`[decrypter]: ${msg}`);
|
|
21992
21989
|
this.logEnabled = false;
|
|
21993
21990
|
}
|
|
21994
21991
|
}
|
|
@@ -22056,8 +22053,8 @@ class BaseStreamController extends TaskLoop {
|
|
|
22056
22053
|
this.warn = void 0;
|
|
22057
22054
|
this.playlistType = playlistType;
|
|
22058
22055
|
this.logPrefix = logPrefix;
|
|
22059
|
-
this.log = logger
|
|
22060
|
-
this.warn = logger
|
|
22056
|
+
this.log = logger.log.bind(logger, `${logPrefix}:`);
|
|
22057
|
+
this.warn = logger.warn.bind(logger, `${logPrefix}:`);
|
|
22061
22058
|
this.hls = hls;
|
|
22062
22059
|
this.fragmentLoader = new FragmentLoader(hls.config);
|
|
22063
22060
|
this.keyLoader = keyLoader;
|
|
@@ -23104,7 +23101,7 @@ class BaseStreamController extends TaskLoop {
|
|
|
23104
23101
|
errorAction.resolved = true;
|
|
23105
23102
|
}
|
|
23106
23103
|
} else {
|
|
23107
|
-
logger
|
|
23104
|
+
logger.warn(`${data.details} reached or exceeded max retry (${retryCount})`);
|
|
23108
23105
|
return;
|
|
23109
23106
|
}
|
|
23110
23107
|
} else if ((errorAction == null ? void 0 : errorAction.action) === NetworkErrorAction.SendAlternateToPenaltyBox) {
|
|
@@ -23537,7 +23534,7 @@ function getAudioConfig(observer, data, offset, audioCodec) {
|
|
|
23537
23534
|
adtsChannelConfig = (data[offset + 2] & 0x01) << 2;
|
|
23538
23535
|
// byte 3
|
|
23539
23536
|
adtsChannelConfig |= (data[offset + 3] & 0xc0) >>> 6;
|
|
23540
|
-
logger
|
|
23537
|
+
logger.log(`manifest codec:${audioCodec}, ADTS type:${adtsObjectType}, samplingIndex:${adtsSamplingIndex}`);
|
|
23541
23538
|
// firefox: freq less than 24kHz = AAC SBR (HE-AAC)
|
|
23542
23539
|
if (/firefox/i.test(userAgent)) {
|
|
23543
23540
|
if (adtsSamplingIndex >= 6) {
|
|
@@ -23687,7 +23684,7 @@ function initTrackConfig(track, observer, data, offset, audioCodec) {
|
|
|
23687
23684
|
track.channelCount = config.channelCount;
|
|
23688
23685
|
track.codec = config.codec;
|
|
23689
23686
|
track.manifestCodec = config.manifestCodec;
|
|
23690
|
-
logger
|
|
23687
|
+
logger.log(`parsed codec:${track.codec}, rate:${config.samplerate}, channels:${config.channelCount}`);
|
|
23691
23688
|
}
|
|
23692
23689
|
}
|
|
23693
23690
|
function getFrameDuration(samplerate) {
|
|
@@ -23943,7 +23940,7 @@ class AACDemuxer extends BaseAudioDemuxer {
|
|
|
23943
23940
|
}
|
|
23944
23941
|
for (let length = data.length; offset < length; offset++) {
|
|
23945
23942
|
if (probe$1(data, offset)) {
|
|
23946
|
-
logger
|
|
23943
|
+
logger.log('ADTS sync word found !');
|
|
23947
23944
|
return true;
|
|
23948
23945
|
}
|
|
23949
23946
|
}
|
|
@@ -24275,7 +24272,7 @@ class BaseVideoParser {
|
|
|
24275
24272
|
videoTrack.samples.push(VideoSample);
|
|
24276
24273
|
}
|
|
24277
24274
|
if (VideoSample.debug.length) {
|
|
24278
|
-
logger
|
|
24275
|
+
logger.log(VideoSample.pts + '/' + VideoSample.dts + ':' + VideoSample.debug);
|
|
24279
24276
|
}
|
|
24280
24277
|
}
|
|
24281
24278
|
}
|
|
@@ -24339,7 +24336,7 @@ class ExpGolomb {
|
|
|
24339
24336
|
let bits = Math.min(this.bitsAvailable, size); // :uint
|
|
24340
24337
|
const valu = this.word >>> 32 - bits; // :uint
|
|
24341
24338
|
if (size > 32) {
|
|
24342
|
-
logger
|
|
24339
|
+
logger.error('Cannot read more than 32 bits at a time');
|
|
24343
24340
|
}
|
|
24344
24341
|
this.bitsAvailable -= bits;
|
|
24345
24342
|
if (this.bitsAvailable > 0) {
|
|
@@ -24982,7 +24979,7 @@ class TSDemuxer {
|
|
|
24982
24979
|
static probe(data) {
|
|
24983
24980
|
const syncOffset = TSDemuxer.syncOffset(data);
|
|
24984
24981
|
if (syncOffset > 0) {
|
|
24985
|
-
logger
|
|
24982
|
+
logger.warn(`MPEG2-TS detected but first sync word found @ offset ${syncOffset}`);
|
|
24986
24983
|
}
|
|
24987
24984
|
return syncOffset !== -1;
|
|
24988
24985
|
}
|
|
@@ -25231,7 +25228,7 @@ class TSDemuxer {
|
|
|
25231
25228
|
id3Track.pid = id3Pid;
|
|
25232
25229
|
}
|
|
25233
25230
|
if (unknownPID !== null && !pmtParsed) {
|
|
25234
|
-
logger
|
|
25231
|
+
logger.warn(`MPEG-TS PMT found at ${start} after unknown PID '${unknownPID}'. Backtracking to sync byte @${syncOffset} to parse all TS packets.`);
|
|
25235
25232
|
unknownPID = null;
|
|
25236
25233
|
// we set it to -188, the += 188 in the for loop will reset start to 0
|
|
25237
25234
|
start = syncOffset - 188;
|
|
@@ -25325,7 +25322,7 @@ class TSDemuxer {
|
|
|
25325
25322
|
audioTrack.pesData = null;
|
|
25326
25323
|
} else {
|
|
25327
25324
|
if (audioData != null && audioData.size) {
|
|
25328
|
-
logger
|
|
25325
|
+
logger.log('last AAC PES packet truncated,might overlap between fragments');
|
|
25329
25326
|
}
|
|
25330
25327
|
|
|
25331
25328
|
// either audioData null or PES truncated, keep it for next frag parsing
|
|
@@ -25420,7 +25417,7 @@ class TSDemuxer {
|
|
|
25420
25417
|
const frameDuration = getFrameDuration(track.samplerate);
|
|
25421
25418
|
pts = aacOverFlow.sample.pts + frameDuration;
|
|
25422
25419
|
} else {
|
|
25423
|
-
logger
|
|
25420
|
+
logger.warn('[tsdemuxer]: AAC PES unknown PTS');
|
|
25424
25421
|
return;
|
|
25425
25422
|
}
|
|
25426
25423
|
|
|
@@ -25450,7 +25447,7 @@ class TSDemuxer {
|
|
|
25450
25447
|
let offset = 0;
|
|
25451
25448
|
const pts = pes.pts;
|
|
25452
25449
|
if (pts === undefined) {
|
|
25453
|
-
logger
|
|
25450
|
+
logger.warn('[tsdemuxer]: MPEG PES unknown PTS');
|
|
25454
25451
|
return;
|
|
25455
25452
|
}
|
|
25456
25453
|
while (offset < length) {
|
|
@@ -25474,7 +25471,7 @@ class TSDemuxer {
|
|
|
25474
25471
|
const data = pes.data;
|
|
25475
25472
|
const pts = pes.pts;
|
|
25476
25473
|
if (pts === undefined) {
|
|
25477
|
-
logger
|
|
25474
|
+
logger.warn('[tsdemuxer]: AC3 PES unknown PTS');
|
|
25478
25475
|
return;
|
|
25479
25476
|
}
|
|
25480
25477
|
const length = data.length;
|
|
@@ -25488,7 +25485,7 @@ class TSDemuxer {
|
|
|
25488
25485
|
}
|
|
25489
25486
|
parseID3PES(id3Track, pes) {
|
|
25490
25487
|
if (pes.pts === undefined) {
|
|
25491
|
-
logger
|
|
25488
|
+
logger.warn('[tsdemuxer]: ID3 PES unknown PTS');
|
|
25492
25489
|
return;
|
|
25493
25490
|
}
|
|
25494
25491
|
const id3Sample = _extends({}, pes, {
|
|
@@ -25569,7 +25566,7 @@ function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
|
|
|
25569
25566
|
case 0x04:
|
|
25570
25567
|
// logger.log('MPEG PID:' + pid);
|
|
25571
25568
|
if (!typeSupported.mpeg && !typeSupported.mp3) {
|
|
25572
|
-
logger
|
|
25569
|
+
logger.log('MPEG audio found, not supported in this browser');
|
|
25573
25570
|
} else if (result.audioPid === -1) {
|
|
25574
25571
|
result.audioPid = pid;
|
|
25575
25572
|
result.segmentAudioCodec = 'mp3';
|
|
@@ -25585,7 +25582,7 @@ function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
|
|
|
25585
25582
|
case 0x81:
|
|
25586
25583
|
{
|
|
25587
25584
|
if (!typeSupported.ac3) {
|
|
25588
|
-
logger
|
|
25585
|
+
logger.log('AC-3 audio found, not supported in this browser');
|
|
25589
25586
|
} else if (result.audioPid === -1) {
|
|
25590
25587
|
result.audioPid = pid;
|
|
25591
25588
|
result.segmentAudioCodec = 'ac3';
|
|
@@ -25607,7 +25604,7 @@ function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
|
|
|
25607
25604
|
// DVB Descriptor for AC-3
|
|
25608
25605
|
{
|
|
25609
25606
|
if (typeSupported.ac3 !== true) {
|
|
25610
|
-
logger
|
|
25607
|
+
logger.log('AC-3 audio found, not supported in this browser for now');
|
|
25611
25608
|
} else {
|
|
25612
25609
|
result.audioPid = pid;
|
|
25613
25610
|
result.segmentAudioCodec = 'ac3';
|
|
@@ -25637,7 +25634,7 @@ function parsePMT(data, offset, typeSupported, isSampleAes, observer) {
|
|
|
25637
25634
|
return result;
|
|
25638
25635
|
}
|
|
25639
25636
|
function emitParsingError(observer, error, levelRetry) {
|
|
25640
|
-
logger
|
|
25637
|
+
logger.warn(`parsing error: ${error.message}`);
|
|
25641
25638
|
observer.emit(Events.ERROR, Events.ERROR, {
|
|
25642
25639
|
type: ErrorTypes.MEDIA_ERROR,
|
|
25643
25640
|
details: ErrorDetails.FRAG_PARSING_ERROR,
|
|
@@ -25648,7 +25645,7 @@ function emitParsingError(observer, error, levelRetry) {
|
|
|
25648
25645
|
});
|
|
25649
25646
|
}
|
|
25650
25647
|
function logEncryptedSamplesFoundInUnencryptedStream(type) {
|
|
25651
|
-
logger
|
|
25648
|
+
logger.log(`${type} with AES-128-CBC encryption found in unencrypted stream`);
|
|
25652
25649
|
}
|
|
25653
25650
|
function parsePES(stream) {
|
|
25654
25651
|
let i = 0;
|
|
@@ -25705,7 +25702,7 @@ function parsePES(stream) {
|
|
|
25705
25702
|
// 1 << 7
|
|
25706
25703
|
(frag[18] & 0xfe) / 2;
|
|
25707
25704
|
if (pesPts - pesDts > 60 * 90000) {
|
|
25708
|
-
logger
|
|
25705
|
+
logger.warn(`${Math.round((pesPts - pesDts) / 90000)}s delta between PTS and DTS, align them`);
|
|
25709
25706
|
pesPts = pesDts;
|
|
25710
25707
|
}
|
|
25711
25708
|
} else {
|
|
@@ -25793,7 +25790,7 @@ class MP3Demuxer extends BaseAudioDemuxer {
|
|
|
25793
25790
|
}
|
|
25794
25791
|
for (let length = data.length; offset < length; offset++) {
|
|
25795
25792
|
if (probe(data, offset)) {
|
|
25796
|
-
logger
|
|
25793
|
+
logger.log('MPEG Audio sync word found !');
|
|
25797
25794
|
return true;
|
|
25798
25795
|
}
|
|
25799
25796
|
}
|
|
@@ -26491,16 +26488,16 @@ class MP4Remuxer {
|
|
|
26491
26488
|
this.config = this.videoTrackConfig = this._initPTS = this._initDTS = null;
|
|
26492
26489
|
}
|
|
26493
26490
|
resetTimeStamp(defaultTimeStamp) {
|
|
26494
|
-
logger
|
|
26491
|
+
logger.log('[mp4-remuxer]: initPTS & initDTS reset');
|
|
26495
26492
|
this._initPTS = this._initDTS = defaultTimeStamp;
|
|
26496
26493
|
}
|
|
26497
26494
|
resetNextTimestamp() {
|
|
26498
|
-
logger
|
|
26495
|
+
logger.log('[mp4-remuxer]: reset next timestamp');
|
|
26499
26496
|
this.isVideoContiguous = false;
|
|
26500
26497
|
this.isAudioContiguous = false;
|
|
26501
26498
|
}
|
|
26502
26499
|
resetInitSegment() {
|
|
26503
|
-
logger
|
|
26500
|
+
logger.log('[mp4-remuxer]: ISGenerated flag reset');
|
|
26504
26501
|
this.ISGenerated = false;
|
|
26505
26502
|
this.videoTrackConfig = undefined;
|
|
26506
26503
|
}
|
|
@@ -26519,7 +26516,7 @@ class MP4Remuxer {
|
|
|
26519
26516
|
}
|
|
26520
26517
|
}, videoSamples[0].pts);
|
|
26521
26518
|
if (rolloverDetected) {
|
|
26522
|
-
logger
|
|
26519
|
+
logger.debug('PTS rollover detected');
|
|
26523
26520
|
}
|
|
26524
26521
|
return startPTS;
|
|
26525
26522
|
}
|
|
@@ -26562,14 +26559,14 @@ class MP4Remuxer {
|
|
|
26562
26559
|
if (!isVideoContiguous && this.config.forceKeyFrameOnDiscontinuity) {
|
|
26563
26560
|
independent = true;
|
|
26564
26561
|
if (firstKeyFrameIndex > 0) {
|
|
26565
|
-
logger
|
|
26562
|
+
logger.warn(`[mp4-remuxer]: Dropped ${firstKeyFrameIndex} out of ${length} video samples due to a missing keyframe`);
|
|
26566
26563
|
const startPTS = this.getVideoStartPts(videoTrack.samples);
|
|
26567
26564
|
videoTrack.samples = videoTrack.samples.slice(firstKeyFrameIndex);
|
|
26568
26565
|
videoTrack.dropped += firstKeyFrameIndex;
|
|
26569
26566
|
videoTimeOffset += (videoTrack.samples[0].pts - startPTS) / videoTrack.inputTimeScale;
|
|
26570
26567
|
firstKeyFramePTS = videoTimeOffset;
|
|
26571
26568
|
} else if (firstKeyFrameIndex === -1) {
|
|
26572
|
-
logger
|
|
26569
|
+
logger.warn(`[mp4-remuxer]: No keyframe found out of ${length} video samples`);
|
|
26573
26570
|
independent = false;
|
|
26574
26571
|
}
|
|
26575
26572
|
}
|
|
@@ -26591,7 +26588,7 @@ class MP4Remuxer {
|
|
|
26591
26588
|
if (enoughAudioSamples) {
|
|
26592
26589
|
// if initSegment was generated without audio samples, regenerate it again
|
|
26593
26590
|
if (!audioTrack.samplerate) {
|
|
26594
|
-
logger
|
|
26591
|
+
logger.warn('[mp4-remuxer]: regenerate InitSegment as audio detected');
|
|
26595
26592
|
initSegment = this.generateIS(audioTrack, videoTrack, timeOffset, accurateTimeOffset);
|
|
26596
26593
|
}
|
|
26597
26594
|
audio = this.remuxAudio(audioTrack, audioTimeOffset, this.isAudioContiguous, accurateTimeOffset, hasVideo || enoughVideoSamples || playlistType === PlaylistLevelType.AUDIO ? videoTimeOffset : undefined);
|
|
@@ -26599,7 +26596,7 @@ class MP4Remuxer {
|
|
|
26599
26596
|
const audioTrackLength = audio ? audio.endPTS - audio.startPTS : 0;
|
|
26600
26597
|
// if initSegment was generated without video samples, regenerate it again
|
|
26601
26598
|
if (!videoTrack.inputTimeScale) {
|
|
26602
|
-
logger
|
|
26599
|
+
logger.warn('[mp4-remuxer]: regenerate InitSegment as video detected');
|
|
26603
26600
|
initSegment = this.generateIS(audioTrack, videoTrack, timeOffset, accurateTimeOffset);
|
|
26604
26601
|
}
|
|
26605
26602
|
video = this.remuxVideo(videoTrack, videoTimeOffset, isVideoContiguous, audioTrackLength);
|
|
@@ -26805,9 +26802,9 @@ class MP4Remuxer {
|
|
|
26805
26802
|
const foundOverlap = delta < -1;
|
|
26806
26803
|
if (foundHole || foundOverlap) {
|
|
26807
26804
|
if (foundHole) {
|
|
26808
|
-
logger
|
|
26805
|
+
logger.warn(`AVC: ${toMsFromMpegTsClock(delta, true)} ms (${delta}dts) hole between fragments detected at ${timeOffset.toFixed(3)}`);
|
|
26809
26806
|
} else {
|
|
26810
|
-
logger
|
|
26807
|
+
logger.warn(`AVC: ${toMsFromMpegTsClock(-delta, true)} ms (${delta}dts) overlapping between fragments detected at ${timeOffset.toFixed(3)}`);
|
|
26811
26808
|
}
|
|
26812
26809
|
if (!foundOverlap || nextAvcDts >= inputSamples[0].pts || chromeVersion) {
|
|
26813
26810
|
firstDTS = nextAvcDts;
|
|
@@ -26824,7 +26821,7 @@ class MP4Remuxer {
|
|
|
26824
26821
|
inputSamples[i].pts -= delta;
|
|
26825
26822
|
}
|
|
26826
26823
|
}
|
|
26827
|
-
logger
|
|
26824
|
+
logger.log(`Video: Initial PTS/DTS adjusted: ${toMsFromMpegTsClock(firstPTS, true)}/${toMsFromMpegTsClock(firstDTS, true)}, delta: ${toMsFromMpegTsClock(delta, true)} ms`);
|
|
26828
26825
|
}
|
|
26829
26826
|
}
|
|
26830
26827
|
}
|
|
@@ -26924,7 +26921,7 @@ class MP4Remuxer {
|
|
|
26924
26921
|
} else {
|
|
26925
26922
|
stretchedLastFrame = true;
|
|
26926
26923
|
}
|
|
26927
|
-
logger
|
|
26924
|
+
logger.log(`[mp4-remuxer]: It is approximately ${deltaToFrameEnd / 90} ms to the next segment; using duration ${mp4SampleDuration / 90} ms for the last video frame.`);
|
|
26928
26925
|
} else {
|
|
26929
26926
|
mp4SampleDuration = lastFrameDuration;
|
|
26930
26927
|
}
|
|
@@ -26952,7 +26949,7 @@ class MP4Remuxer {
|
|
|
26952
26949
|
// Fix for "CNN special report, with CC" in test-streams (Safari browser only)
|
|
26953
26950
|
// Ignore DTS when frame durations are irregular. Safari MSE does not handle this leading to gaps.
|
|
26954
26951
|
if (maxPtsDelta - minPtsDelta < maxDtsDelta - minDtsDelta && averageSampleDuration / maxDtsDelta < 0.025 && outputSamples[0].cts === 0) {
|
|
26955
|
-
logger
|
|
26952
|
+
logger.warn('Found irregular gaps in sample duration. Using PTS instead of DTS to determine MP4 sample duration.');
|
|
26956
26953
|
let dts = firstDTS;
|
|
26957
26954
|
for (let i = 0, len = outputSamples.length; i < len; i++) {
|
|
26958
26955
|
const nextDts = dts + outputSamples[i].duration;
|
|
@@ -27077,7 +27074,7 @@ class MP4Remuxer {
|
|
|
27077
27074
|
// When remuxing with video, if we're overlapping by more than a duration, drop this sample to stay in sync
|
|
27078
27075
|
if (delta <= -maxAudioFramesDrift * inputSampleDuration && alignedWithVideo) {
|
|
27079
27076
|
if (i === 0) {
|
|
27080
|
-
logger
|
|
27077
|
+
logger.warn(`Audio frame @ ${(pts / inputTimeScale).toFixed(3)}s overlaps nextAudioPts by ${Math.round(1000 * delta / inputTimeScale)} ms.`);
|
|
27081
27078
|
this.nextAudioPts = nextAudioPts = nextPts = pts;
|
|
27082
27079
|
}
|
|
27083
27080
|
} // eslint-disable-line brace-style
|
|
@@ -27099,12 +27096,12 @@ class MP4Remuxer {
|
|
|
27099
27096
|
if (i === 0) {
|
|
27100
27097
|
this.nextAudioPts = nextAudioPts = nextPts;
|
|
27101
27098
|
}
|
|
27102
|
-
logger
|
|
27099
|
+
logger.warn(`[mp4-remuxer]: Injecting ${missing} audio frame @ ${(nextPts / inputTimeScale).toFixed(3)}s due to ${Math.round(1000 * delta / inputTimeScale)} ms gap.`);
|
|
27103
27100
|
for (let j = 0; j < missing; j++) {
|
|
27104
27101
|
const newStamp = Math.max(nextPts, 0);
|
|
27105
27102
|
let fillFrame = AAC.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
|
|
27106
27103
|
if (!fillFrame) {
|
|
27107
|
-
logger
|
|
27104
|
+
logger.log('[mp4-remuxer]: Unable to get silent frame for given audio codec; duplicating last frame instead.');
|
|
27108
27105
|
fillFrame = sample.unit.subarray();
|
|
27109
27106
|
}
|
|
27110
27107
|
inputSamples.splice(i, 0, {
|
|
@@ -27231,10 +27228,10 @@ class MP4Remuxer {
|
|
|
27231
27228
|
const nbSamples = Math.ceil((endDTS - startDTS) / frameDuration);
|
|
27232
27229
|
// silent frame
|
|
27233
27230
|
const silentFrame = AAC.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
|
|
27234
|
-
logger
|
|
27231
|
+
logger.warn('[mp4-remuxer]: remux empty Audio');
|
|
27235
27232
|
// Can't remux if we can't generate a silent frame...
|
|
27236
27233
|
if (!silentFrame) {
|
|
27237
|
-
logger
|
|
27234
|
+
logger.trace('[mp4-remuxer]: Unable to remuxEmptyAudio since we were unable to get a silent frame for given audio codec');
|
|
27238
27235
|
return;
|
|
27239
27236
|
}
|
|
27240
27237
|
const samples = [];
|
|
@@ -27402,7 +27399,7 @@ class PassThroughRemuxer {
|
|
|
27402
27399
|
id: 'main'
|
|
27403
27400
|
};
|
|
27404
27401
|
} else {
|
|
27405
|
-
logger
|
|
27402
|
+
logger.warn('[passthrough-remuxer.ts]: initSegment does not contain moov or trak boxes.');
|
|
27406
27403
|
}
|
|
27407
27404
|
this.initTracks = tracks;
|
|
27408
27405
|
}
|
|
@@ -27444,7 +27441,7 @@ class PassThroughRemuxer {
|
|
|
27444
27441
|
}
|
|
27445
27442
|
if (!((_initData2 = initData) != null && _initData2.length)) {
|
|
27446
27443
|
// We can't remux if the initSegment could not be generated
|
|
27447
|
-
logger
|
|
27444
|
+
logger.warn('[passthrough-remuxer.ts]: Failed to generate initSegment.');
|
|
27448
27445
|
return result;
|
|
27449
27446
|
}
|
|
27450
27447
|
if (this.emitInitSegment) {
|
|
@@ -27457,7 +27454,7 @@ class PassThroughRemuxer {
|
|
|
27457
27454
|
if (isInvalidInitPts(initPTS, decodeTime, timeOffset, duration) || initSegment.timescale !== initPTS.timescale && accurateTimeOffset) {
|
|
27458
27455
|
initSegment.initPTS = decodeTime - timeOffset;
|
|
27459
27456
|
if (initPTS && initPTS.timescale === 1) {
|
|
27460
|
-
logger
|
|
27457
|
+
logger.warn(`Adjusting initPTS by ${initSegment.initPTS - initPTS.baseTime}`);
|
|
27461
27458
|
}
|
|
27462
27459
|
this.initPTS = initPTS = {
|
|
27463
27460
|
baseTime: initSegment.initPTS,
|
|
@@ -27470,7 +27467,7 @@ class PassThroughRemuxer {
|
|
|
27470
27467
|
if (duration > 0) {
|
|
27471
27468
|
this.lastEndTime = endTime;
|
|
27472
27469
|
} else {
|
|
27473
|
-
logger
|
|
27470
|
+
logger.warn('Duration parsed from mp4 should be greater than zero');
|
|
27474
27471
|
this.resetNextTimestamp();
|
|
27475
27472
|
}
|
|
27476
27473
|
const hasAudio = !!initData.audio;
|
|
@@ -27528,12 +27525,12 @@ function getParsedTrackCodec(track, type) {
|
|
|
27528
27525
|
return getCodecCompatibleName(parsedCodec, preferManagedMediaSource);
|
|
27529
27526
|
}
|
|
27530
27527
|
const result = 'mp4a.40.5';
|
|
27531
|
-
logger
|
|
27528
|
+
logger.info(`Parsed audio codec "${parsedCodec}" or audio object type not handled. Using "${result}"`);
|
|
27532
27529
|
return result;
|
|
27533
27530
|
}
|
|
27534
27531
|
// Provide defaults based on codec type
|
|
27535
27532
|
// This allows for some playback of some fmp4 playlists without CODECS defined in manifest
|
|
27536
|
-
logger
|
|
27533
|
+
logger.warn(`Unhandled video codec "${parsedCodec}"`);
|
|
27537
27534
|
if (parsedCodec === 'hvc1' || parsedCodec === 'hev1') {
|
|
27538
27535
|
return 'hvc1.1.6.L120.90';
|
|
27539
27536
|
}
|
|
@@ -27548,7 +27545,7 @@ let now$1;
|
|
|
27548
27545
|
try {
|
|
27549
27546
|
now$1 = self.performance.now.bind(self.performance);
|
|
27550
27547
|
} catch (err) {
|
|
27551
|
-
logger
|
|
27548
|
+
logger.debug('Unable to use Performance API on this environment');
|
|
27552
27549
|
now$1 = optionalSelf == null ? void 0 : optionalSelf.Date.now;
|
|
27553
27550
|
}
|
|
27554
27551
|
const muxConfig = [{
|
|
@@ -27656,7 +27653,7 @@ class Transmuxer {
|
|
|
27656
27653
|
if (resetMuxers) {
|
|
27657
27654
|
const error = this.configureTransmuxer(uintData);
|
|
27658
27655
|
if (error) {
|
|
27659
|
-
logger
|
|
27656
|
+
logger.warn(`[transmuxer] ${error.message}`);
|
|
27660
27657
|
this.observer.emit(Events.ERROR, Events.ERROR, {
|
|
27661
27658
|
type: ErrorTypes.MEDIA_ERROR,
|
|
27662
27659
|
details: ErrorDetails.FRAG_PARSING_ERROR,
|
|
@@ -27747,7 +27744,7 @@ class Transmuxer {
|
|
|
27747
27744
|
accurateTimeOffset,
|
|
27748
27745
|
timeOffset
|
|
27749
27746
|
} = this.currentTransmuxState;
|
|
27750
|
-
logger
|
|
27747
|
+
logger.log(`[transmuxer.ts]: Flushed fragment ${chunkMeta.sn}${chunkMeta.part > -1 ? ' p: ' + chunkMeta.part : ''} of level ${chunkMeta.level}`);
|
|
27751
27748
|
const remuxResult = this.remuxer.remux(audioTrack, videoTrack, id3Track, textTrack, timeOffset, accurateTimeOffset, true, this.id);
|
|
27752
27749
|
transmuxResults.push({
|
|
27753
27750
|
remuxResult,
|
|
@@ -28309,10 +28306,10 @@ class TransmuxerInterface {
|
|
|
28309
28306
|
if (canCreateWorker) {
|
|
28310
28307
|
try {
|
|
28311
28308
|
if (config.workerPath) {
|
|
28312
|
-
logger
|
|
28309
|
+
logger.log(`loading Web Worker ${config.workerPath} for "${id}"`);
|
|
28313
28310
|
this.workerContext = loadWorker(config.workerPath);
|
|
28314
28311
|
} else {
|
|
28315
|
-
logger
|
|
28312
|
+
logger.log(`injecting Web Worker for "${id}"`);
|
|
28316
28313
|
this.workerContext = injectWorker();
|
|
28317
28314
|
}
|
|
28318
28315
|
this.onwmsg = event => this.onWorkerMessage(event);
|
|
@@ -28323,7 +28320,7 @@ class TransmuxerInterface {
|
|
|
28323
28320
|
worker.onerror = event => {
|
|
28324
28321
|
const error = new Error(`${event.message} (${event.filename}:${event.lineno})`);
|
|
28325
28322
|
config.enableWorker = false;
|
|
28326
|
-
logger
|
|
28323
|
+
logger.warn(`Error in "${id}" Web Worker, fallback to inline`);
|
|
28327
28324
|
this.hls.trigger(Events.ERROR, {
|
|
28328
28325
|
type: ErrorTypes.OTHER_ERROR,
|
|
28329
28326
|
details: ErrorDetails.INTERNAL_EXCEPTION,
|
|
@@ -28340,7 +28337,7 @@ class TransmuxerInterface {
|
|
|
28340
28337
|
config: JSON.stringify(config)
|
|
28341
28338
|
});
|
|
28342
28339
|
} catch (err) {
|
|
28343
|
-
logger
|
|
28340
|
+
logger.warn(`Error setting up "${id}" Web Worker, fallback to inline`, err);
|
|
28344
28341
|
this.resetWorker();
|
|
28345
28342
|
this.error = null;
|
|
28346
28343
|
this.transmuxer = new Transmuxer(this.observer, m2tsTypeSupported, config, '', id);
|
|
@@ -28413,7 +28410,7 @@ class TransmuxerInterface {
|
|
|
28413
28410
|
const initSegmentChange = !(lastFrag && ((_frag$initSegment = frag.initSegment) == null ? void 0 : _frag$initSegment.url) === ((_lastFrag$initSegment = lastFrag.initSegment) == null ? void 0 : _lastFrag$initSegment.url));
|
|
28414
28411
|
const state = new TransmuxState(discontinuity, contiguous, accurateTimeOffset, trackSwitch, timeOffset, initSegmentChange);
|
|
28415
28412
|
if (!contiguous || discontinuity || initSegmentChange) {
|
|
28416
|
-
logger
|
|
28413
|
+
logger.log(`[transmuxer-interface, ${frag.type}]: Starting new transmux session for sn: ${chunkMeta.sn} p: ${chunkMeta.part} level: ${chunkMeta.level} id: ${chunkMeta.id}
|
|
28417
28414
|
discontinuity: ${discontinuity}
|
|
28418
28415
|
trackSwitch: ${trackSwitch}
|
|
28419
28416
|
contiguous: ${contiguous}
|
|
@@ -28503,7 +28500,7 @@ class TransmuxerInterface {
|
|
|
28503
28500
|
onWorkerMessage(event) {
|
|
28504
28501
|
const data = event.data;
|
|
28505
28502
|
if (!(data != null && data.event)) {
|
|
28506
|
-
logger
|
|
28503
|
+
logger.warn(`worker message received with no ${data ? 'event name' : 'data'}`);
|
|
28507
28504
|
return;
|
|
28508
28505
|
}
|
|
28509
28506
|
const hls = this.hls;
|
|
@@ -28534,8 +28531,8 @@ class TransmuxerInterface {
|
|
|
28534
28531
|
|
|
28535
28532
|
// pass logs from the worker thread to the main logger
|
|
28536
28533
|
case 'workerLog':
|
|
28537
|
-
if (logger
|
|
28538
|
-
logger
|
|
28534
|
+
if (logger[data.data.logType]) {
|
|
28535
|
+
logger[data.data.logType](data.data.message);
|
|
28539
28536
|
}
|
|
28540
28537
|
break;
|
|
28541
28538
|
default:
|
|
@@ -30587,7 +30584,7 @@ class BufferOperationQueue {
|
|
|
30587
30584
|
// which do not end with this event must call _onSBUpdateEnd manually
|
|
30588
30585
|
operation.execute();
|
|
30589
30586
|
} catch (error) {
|
|
30590
|
-
logger
|
|
30587
|
+
logger.warn(`[buffer-operation-queue]: Exception executing "${type}" SourceBuffer operation: ${error}`);
|
|
30591
30588
|
operation.onError(error);
|
|
30592
30589
|
|
|
30593
30590
|
// Only shift the current operation off, otherwise the updateend handler will do this for us
|
|
@@ -30687,15 +30684,15 @@ class BufferController {
|
|
|
30687
30684
|
_objectUrl
|
|
30688
30685
|
} = this;
|
|
30689
30686
|
if (mediaSrc !== _objectUrl) {
|
|
30690
|
-
logger
|
|
30687
|
+
logger.error(`Media element src was set while attaching MediaSource (${_objectUrl} > ${mediaSrc})`);
|
|
30691
30688
|
}
|
|
30692
30689
|
};
|
|
30693
30690
|
this.hls = hls;
|
|
30694
30691
|
const logPrefix = '[buffer-controller]';
|
|
30695
30692
|
this.appendSource = isManagedMediaSource(getMediaSource(hls.config.preferManagedMediaSource));
|
|
30696
|
-
this.log = logger
|
|
30697
|
-
this.warn = logger
|
|
30698
|
-
this.error = logger
|
|
30693
|
+
this.log = logger.log.bind(logger, logPrefix);
|
|
30694
|
+
this.warn = logger.warn.bind(logger, logPrefix);
|
|
30695
|
+
this.error = logger.error.bind(logger, logPrefix);
|
|
30699
30696
|
this._initSourceBuffer();
|
|
30700
30697
|
this.registerListeners();
|
|
30701
30698
|
}
|
|
@@ -31886,7 +31883,7 @@ class CaptionsLogger {
|
|
|
31886
31883
|
log(severity, msg) {
|
|
31887
31884
|
if (this.verboseLevel >= severity) {
|
|
31888
31885
|
const m = typeof msg === 'function' ? msg() : msg;
|
|
31889
|
-
logger
|
|
31886
|
+
logger.log(`${this.time} [${severity}] ${m}`);
|
|
31890
31887
|
}
|
|
31891
31888
|
}
|
|
31892
31889
|
}
|
|
@@ -34211,7 +34208,7 @@ class TimelineController {
|
|
|
34211
34208
|
if (inUseTracks != null && inUseTracks.length) {
|
|
34212
34209
|
const unusedTextTracks = inUseTracks.filter(t => t !== null).map(t => t.label);
|
|
34213
34210
|
if (unusedTextTracks.length) {
|
|
34214
|
-
logger
|
|
34211
|
+
logger.warn(`Media element contains unused subtitle tracks: ${unusedTextTracks.join(', ')}. Replace media element for each source to clear TextTracks and captions menu.`);
|
|
34215
34212
|
}
|
|
34216
34213
|
}
|
|
34217
34214
|
} else if (this.tracks.length) {
|
|
@@ -34328,7 +34325,7 @@ class TimelineController {
|
|
|
34328
34325
|
frag: frag
|
|
34329
34326
|
});
|
|
34330
34327
|
}, error => {
|
|
34331
|
-
logger
|
|
34328
|
+
logger.log(`Failed to parse IMSC1: ${error}`);
|
|
34332
34329
|
hls.trigger(Events.SUBTITLE_FRAG_PROCESSED, {
|
|
34333
34330
|
success: false,
|
|
34334
34331
|
frag: frag,
|
|
@@ -34369,7 +34366,7 @@ class TimelineController {
|
|
|
34369
34366
|
this._fallbackToIMSC1(frag, payload);
|
|
34370
34367
|
}
|
|
34371
34368
|
// Something went wrong while parsing. Trigger event with success false.
|
|
34372
|
-
logger
|
|
34369
|
+
logger.log(`Failed to parse VTT cue: ${error}`);
|
|
34373
34370
|
if (missingInitPTS && maxAvCC > frag.cc) {
|
|
34374
34371
|
return;
|
|
34375
34372
|
}
|
|
@@ -34648,7 +34645,7 @@ class CapLevelController {
|
|
|
34648
34645
|
const hls = this.hls;
|
|
34649
34646
|
const maxLevel = this.getMaxLevel(levels.length - 1);
|
|
34650
34647
|
if (maxLevel !== this.autoLevelCapping) {
|
|
34651
|
-
logger
|
|
34648
|
+
logger.log(`Setting autoLevelCapping to ${maxLevel}: ${levels[maxLevel].height}p@${levels[maxLevel].bitrate} for media ${this.mediaWidth}x${this.mediaHeight}`);
|
|
34652
34649
|
}
|
|
34653
34650
|
hls.autoLevelCapping = maxLevel;
|
|
34654
34651
|
if (hls.autoLevelCapping > this.autoLevelCapping && this.streamController) {
|
|
@@ -34829,7 +34826,7 @@ class FPSController {
|
|
|
34829
34826
|
// logger.log('checkFPS : droppedFPS/decodedFPS:' + droppedFPS/(1000 * currentDecoded / currentPeriod));
|
|
34830
34827
|
if (currentDropped > hls.config.fpsDroppedMonitoringThreshold * currentDecoded) {
|
|
34831
34828
|
let currentLevel = hls.currentLevel;
|
|
34832
|
-
logger
|
|
34829
|
+
logger.warn('drop FPS ratio greater than max allowed value for currentLevel: ' + currentLevel);
|
|
34833
34830
|
if (currentLevel > 0 && (hls.autoLevelCapping === -1 || hls.autoLevelCapping >= currentLevel)) {
|
|
34834
34831
|
currentLevel = currentLevel - 1;
|
|
34835
34832
|
hls.trigger(Events.FPS_DROP_LEVEL_CAPPING, {
|
|
@@ -34882,10 +34879,10 @@ class EMEController {
|
|
|
34882
34879
|
this.setMediaKeysQueue = EMEController.CDMCleanupPromise ? [EMEController.CDMCleanupPromise] : [];
|
|
34883
34880
|
this.onMediaEncrypted = this._onMediaEncrypted.bind(this);
|
|
34884
34881
|
this.onWaitingForKey = this._onWaitingForKey.bind(this);
|
|
34885
|
-
this.debug = logger
|
|
34886
|
-
this.log = logger
|
|
34887
|
-
this.warn = logger
|
|
34888
|
-
this.error = logger
|
|
34882
|
+
this.debug = logger.debug.bind(logger, LOGGER_PREFIX);
|
|
34883
|
+
this.log = logger.log.bind(logger, LOGGER_PREFIX);
|
|
34884
|
+
this.warn = logger.warn.bind(logger, LOGGER_PREFIX);
|
|
34885
|
+
this.error = logger.error.bind(logger, LOGGER_PREFIX);
|
|
34889
34886
|
this.hls = hls;
|
|
34890
34887
|
this.config = hls.config;
|
|
34891
34888
|
this.registerListeners();
|
|
@@ -36742,7 +36739,7 @@ class CMCDController {
|
|
|
36742
36739
|
su: !this.initialized
|
|
36743
36740
|
});
|
|
36744
36741
|
} catch (error) {
|
|
36745
|
-
logger
|
|
36742
|
+
logger.warn('Could not generate manifest CMCD data.', error);
|
|
36746
36743
|
}
|
|
36747
36744
|
};
|
|
36748
36745
|
/**
|
|
@@ -36764,7 +36761,7 @@ class CMCDController {
|
|
|
36764
36761
|
}
|
|
36765
36762
|
this.apply(context, data);
|
|
36766
36763
|
} catch (error) {
|
|
36767
|
-
logger
|
|
36764
|
+
logger.warn('Could not generate segment CMCD data.', error);
|
|
36768
36765
|
}
|
|
36769
36766
|
};
|
|
36770
36767
|
this.hls = hls;
|
|
@@ -37020,7 +37017,7 @@ class ContentSteeringController {
|
|
|
37020
37017
|
this.subtitleTracks = null;
|
|
37021
37018
|
this.penalizedPathways = {};
|
|
37022
37019
|
this.hls = hls;
|
|
37023
|
-
this.log = logger
|
|
37020
|
+
this.log = logger.log.bind(logger, `[content-steering]:`);
|
|
37024
37021
|
this.registerListeners();
|
|
37025
37022
|
}
|
|
37026
37023
|
registerListeners() {
|
|
@@ -37144,7 +37141,7 @@ class ContentSteeringController {
|
|
|
37144
37141
|
errorAction.resolved = this.pathwayId !== errorPathway;
|
|
37145
37142
|
}
|
|
37146
37143
|
if (!errorAction.resolved) {
|
|
37147
|
-
logger
|
|
37144
|
+
logger.warn(`Could not resolve ${data.details} ("${data.error.message}") with content-steering for Pathway: ${errorPathway} levels: ${levels ? levels.length : levels} priorities: ${JSON.stringify(pathwayPriority)} penalized: ${JSON.stringify(this.penalizedPathways)}`);
|
|
37148
37145
|
}
|
|
37149
37146
|
}
|
|
37150
37147
|
}
|
|
@@ -37620,7 +37617,7 @@ class XhrLoader {
|
|
|
37620
37617
|
if (shouldRetry(retryConfig, retryCount, false, response)) {
|
|
37621
37618
|
this.retry(retryConfig);
|
|
37622
37619
|
} else {
|
|
37623
|
-
logger
|
|
37620
|
+
logger.error(`${status} while loading ${context.url}`);
|
|
37624
37621
|
this.callbacks.onError({
|
|
37625
37622
|
code: status,
|
|
37626
37623
|
text: xhr.statusText
|
|
@@ -37638,7 +37635,7 @@ class XhrLoader {
|
|
|
37638
37635
|
this.retry(retryConfig);
|
|
37639
37636
|
} else {
|
|
37640
37637
|
var _this$context;
|
|
37641
|
-
logger
|
|
37638
|
+
logger.warn(`timeout while loading ${(_this$context = this.context) == null ? void 0 : _this$context.url}`);
|
|
37642
37639
|
const callbacks = this.callbacks;
|
|
37643
37640
|
if (callbacks) {
|
|
37644
37641
|
this.abortInternal();
|
|
@@ -37653,7 +37650,7 @@ class XhrLoader {
|
|
|
37653
37650
|
} = this;
|
|
37654
37651
|
this.retryDelay = getRetryDelay(retryConfig, stats.retry);
|
|
37655
37652
|
stats.retry++;
|
|
37656
|
-
logger
|
|
37653
|
+
logger.warn(`${status ? 'HTTP Status ' + status : 'Timeout'} while loading ${context == null ? void 0 : context.url}, retrying ${stats.retry}/${retryConfig.maxNumRetry} in ${this.retryDelay}ms`);
|
|
37657
37654
|
// abort and reset internal state
|
|
37658
37655
|
this.abortInternal();
|
|
37659
37656
|
this.loader = null;
|
|
@@ -38332,7 +38329,7 @@ function mergeConfig(defaultConfig, userConfig) {
|
|
|
38332
38329
|
}
|
|
38333
38330
|
});
|
|
38334
38331
|
if (report.length) {
|
|
38335
|
-
logger
|
|
38332
|
+
logger.warn(`hls.js config: "${report.join('", "')}" setting(s) are deprecated, use "${policyName}": ${JSON.stringify(userConfig[policyName])}`);
|
|
38336
38333
|
}
|
|
38337
38334
|
});
|
|
38338
38335
|
return _objectSpread2(_objectSpread2({}, defaultsCopy), userConfig);
|
|
@@ -38357,7 +38354,7 @@ function enableStreamingMode(config) {
|
|
|
38357
38354
|
const currentLoader = config.loader;
|
|
38358
38355
|
if (currentLoader !== FetchLoader && currentLoader !== XhrLoader) {
|
|
38359
38356
|
// If a developer has configured their own loader, respect that choice
|
|
38360
|
-
logger
|
|
38357
|
+
logger.log('[config]: Custom loader detected, cannot enable progressive streaming');
|
|
38361
38358
|
config.progressive = false;
|
|
38362
38359
|
} else {
|
|
38363
38360
|
const canStreamProgressively = fetchSupported();
|
|
@@ -38365,7 +38362,7 @@ function enableStreamingMode(config) {
|
|
|
38365
38362
|
config.loader = FetchLoader;
|
|
38366
38363
|
config.progressive = true;
|
|
38367
38364
|
config.enableSoftwareAES = true;
|
|
38368
|
-
logger
|
|
38365
|
+
logger.log('[config]: Progressive streaming enabled, using FetchLoader');
|
|
38369
38366
|
}
|
|
38370
38367
|
}
|
|
38371
38368
|
}
|
|
@@ -39238,7 +39235,7 @@ class GapController {
|
|
|
39238
39235
|
// The playhead is now moving, but was previously stalled
|
|
39239
39236
|
if (this.stallReported) {
|
|
39240
39237
|
const _stalledDuration = self.performance.now() - stalled;
|
|
39241
|
-
logger
|
|
39238
|
+
logger.warn(`playback not stuck anymore @${currentTime}, after ${Math.round(_stalledDuration)}ms`);
|
|
39242
39239
|
this.stallReported = false;
|
|
39243
39240
|
}
|
|
39244
39241
|
this.stalled = null;
|
|
@@ -39349,7 +39346,7 @@ class GapController {
|
|
|
39349
39346
|
// needs to cross some sort of threshold covering all source-buffers content
|
|
39350
39347
|
// to start playing properly.
|
|
39351
39348
|
if ((bufferInfo.len > config.maxBufferHole || bufferInfo.nextStart && bufferInfo.nextStart - currentTime < config.maxBufferHole) && stalledDurationMs > config.highBufferWatchdogPeriod * 1000) {
|
|
39352
|
-
logger
|
|
39349
|
+
logger.warn('Trying to nudge playhead over buffer-hole');
|
|
39353
39350
|
// Try to nudge currentTime over a buffer hole if we've been stalling for the configured amount of seconds
|
|
39354
39351
|
// We only try to jump the hole if it's under the configured size
|
|
39355
39352
|
// Reset stalled so to rearm watchdog timer
|
|
@@ -39373,7 +39370,7 @@ class GapController {
|
|
|
39373
39370
|
// Report stalled error once
|
|
39374
39371
|
this.stallReported = true;
|
|
39375
39372
|
const error = new Error(`Playback stalling at @${media.currentTime} due to low buffer (${JSON.stringify(bufferInfo)})`);
|
|
39376
|
-
logger
|
|
39373
|
+
logger.warn(error.message);
|
|
39377
39374
|
hls.trigger(Events.ERROR, {
|
|
39378
39375
|
type: ErrorTypes.MEDIA_ERROR,
|
|
39379
39376
|
details: ErrorDetails.BUFFER_STALLED_ERROR,
|
|
@@ -39441,7 +39438,7 @@ class GapController {
|
|
|
39441
39438
|
}
|
|
39442
39439
|
}
|
|
39443
39440
|
const targetTime = Math.max(startTime + SKIP_BUFFER_RANGE_START, currentTime + SKIP_BUFFER_HOLE_STEP_SECONDS);
|
|
39444
|
-
logger
|
|
39441
|
+
logger.warn(`skipping hole, adjusting currentTime from ${currentTime} to ${targetTime}`);
|
|
39445
39442
|
this.moved = true;
|
|
39446
39443
|
this.stalled = null;
|
|
39447
39444
|
media.currentTime = targetTime;
|
|
@@ -39482,7 +39479,7 @@ class GapController {
|
|
|
39482
39479
|
const targetTime = currentTime + (nudgeRetry + 1) * config.nudgeOffset;
|
|
39483
39480
|
// playback stalled in buffered area ... let's nudge currentTime to try to overcome this
|
|
39484
39481
|
const error = new Error(`Nudging 'currentTime' from ${currentTime} to ${targetTime}`);
|
|
39485
|
-
logger
|
|
39482
|
+
logger.warn(error.message);
|
|
39486
39483
|
media.currentTime = targetTime;
|
|
39487
39484
|
hls.trigger(Events.ERROR, {
|
|
39488
39485
|
type: ErrorTypes.MEDIA_ERROR,
|
|
@@ -39492,7 +39489,7 @@ class GapController {
|
|
|
39492
39489
|
});
|
|
39493
39490
|
} else {
|
|
39494
39491
|
const error = new Error(`Playhead still not moving while enough data buffered @${currentTime} after ${config.nudgeMaxRetry} nudges`);
|
|
39495
|
-
logger
|
|
39492
|
+
logger.error(error.message);
|
|
39496
39493
|
hls.trigger(Events.ERROR, {
|
|
39497
39494
|
type: ErrorTypes.MEDIA_ERROR,
|
|
39498
39495
|
details: ErrorDetails.BUFFER_STALLED_ERROR,
|
|
@@ -40847,7 +40844,7 @@ class Hls {
|
|
|
40847
40844
|
try {
|
|
40848
40845
|
return this.emit(event, event, eventObject);
|
|
40849
40846
|
} catch (error) {
|
|
40850
|
-
logger
|
|
40847
|
+
logger.error('An internal error happened while handling event ' + event + '. Error message: "' + error.message + '". Here is a stacktrace:', error);
|
|
40851
40848
|
// Prevent recursion in error event handlers that throw #5497
|
|
40852
40849
|
if (!this.triggeringException) {
|
|
40853
40850
|
this.triggeringException = true;
|
|
@@ -40873,7 +40870,7 @@ class Hls {
|
|
|
40873
40870
|
* Dispose of the instance
|
|
40874
40871
|
*/
|
|
40875
40872
|
destroy() {
|
|
40876
|
-
logger
|
|
40873
|
+
logger.log('destroy');
|
|
40877
40874
|
this.trigger(Events.DESTROYING, undefined);
|
|
40878
40875
|
this.detachMedia();
|
|
40879
40876
|
this.removeAllListeners();
|
|
@@ -40894,7 +40891,7 @@ class Hls {
|
|
|
40894
40891
|
* Attaches Hls.js to a media element
|
|
40895
40892
|
*/
|
|
40896
40893
|
attachMedia(media) {
|
|
40897
|
-
logger
|
|
40894
|
+
logger.log('attachMedia');
|
|
40898
40895
|
this._media = media;
|
|
40899
40896
|
this.trigger(Events.MEDIA_ATTACHING, {
|
|
40900
40897
|
media: media
|
|
@@ -40905,7 +40902,7 @@ class Hls {
|
|
|
40905
40902
|
* Detach Hls.js from the media
|
|
40906
40903
|
*/
|
|
40907
40904
|
detachMedia() {
|
|
40908
|
-
logger
|
|
40905
|
+
logger.log('detachMedia');
|
|
40909
40906
|
this.trigger(Events.MEDIA_DETACHING, undefined);
|
|
40910
40907
|
this._media = null;
|
|
40911
40908
|
}
|
|
@@ -40922,7 +40919,7 @@ class Hls {
|
|
|
40922
40919
|
});
|
|
40923
40920
|
this._autoLevelCapping = -1;
|
|
40924
40921
|
this._maxHdcpLevel = null;
|
|
40925
|
-
logger
|
|
40922
|
+
logger.log(`loadSource:${loadingSource}`);
|
|
40926
40923
|
if (media && loadedSource && (loadedSource !== loadingSource || this.bufferController.hasSourceTypes())) {
|
|
40927
40924
|
this.detachMedia();
|
|
40928
40925
|
this.attachMedia(media);
|
|
@@ -40941,7 +40938,7 @@ class Hls {
|
|
|
40941
40938
|
* Defaults to -1 (None: starts from earliest point)
|
|
40942
40939
|
*/
|
|
40943
40940
|
startLoad(startPosition = -1) {
|
|
40944
|
-
logger
|
|
40941
|
+
logger.log(`startLoad(${startPosition})`);
|
|
40945
40942
|
this.started = true;
|
|
40946
40943
|
this.networkControllers.forEach(controller => {
|
|
40947
40944
|
controller.startLoad(startPosition);
|
|
@@ -40952,7 +40949,7 @@ class Hls {
|
|
|
40952
40949
|
* Stop loading of any stream data.
|
|
40953
40950
|
*/
|
|
40954
40951
|
stopLoad() {
|
|
40955
|
-
logger
|
|
40952
|
+
logger.log('stopLoad');
|
|
40956
40953
|
this.started = false;
|
|
40957
40954
|
this.networkControllers.forEach(controller => {
|
|
40958
40955
|
controller.stopLoad();
|
|
@@ -40988,7 +40985,7 @@ class Hls {
|
|
|
40988
40985
|
* Swap through possible audio codecs in the stream (for example to switch from stereo to 5.1)
|
|
40989
40986
|
*/
|
|
40990
40987
|
swapAudioCodec() {
|
|
40991
|
-
logger
|
|
40988
|
+
logger.log('swapAudioCodec');
|
|
40992
40989
|
this.streamController.swapAudioCodec();
|
|
40993
40990
|
}
|
|
40994
40991
|
|
|
@@ -40999,7 +40996,7 @@ class Hls {
|
|
|
40999
40996
|
* Automatic recovery of media-errors by this process is configurable.
|
|
41000
40997
|
*/
|
|
41001
40998
|
recoverMediaError() {
|
|
41002
|
-
logger
|
|
40999
|
+
logger.log('recoverMediaError');
|
|
41003
41000
|
const media = this._media;
|
|
41004
41001
|
this.detachMedia();
|
|
41005
41002
|
if (media) {
|
|
@@ -41029,7 +41026,7 @@ class Hls {
|
|
|
41029
41026
|
* Set quality level index immediately. This will flush the current buffer to replace the quality asap. That means playback will interrupt at least shortly to re-buffer and re-sync eventually. Set to -1 for automatic level selection.
|
|
41030
41027
|
*/
|
|
41031
41028
|
set currentLevel(newLevel) {
|
|
41032
|
-
logger
|
|
41029
|
+
logger.log(`set currentLevel:${newLevel}`);
|
|
41033
41030
|
this.levelController.manualLevel = newLevel;
|
|
41034
41031
|
this.streamController.immediateLevelSwitch();
|
|
41035
41032
|
}
|
|
@@ -41048,7 +41045,7 @@ class Hls {
|
|
|
41048
41045
|
* @param newLevel - Pass -1 for automatic level selection
|
|
41049
41046
|
*/
|
|
41050
41047
|
set nextLevel(newLevel) {
|
|
41051
|
-
logger
|
|
41048
|
+
logger.log(`set nextLevel:${newLevel}`);
|
|
41052
41049
|
this.levelController.manualLevel = newLevel;
|
|
41053
41050
|
this.streamController.nextLevelSwitch();
|
|
41054
41051
|
}
|
|
@@ -41067,7 +41064,7 @@ class Hls {
|
|
|
41067
41064
|
* @param newLevel - Pass -1 for automatic level selection
|
|
41068
41065
|
*/
|
|
41069
41066
|
set loadLevel(newLevel) {
|
|
41070
|
-
logger
|
|
41067
|
+
logger.log(`set loadLevel:${newLevel}`);
|
|
41071
41068
|
this.levelController.manualLevel = newLevel;
|
|
41072
41069
|
}
|
|
41073
41070
|
|
|
@@ -41098,7 +41095,7 @@ class Hls {
|
|
|
41098
41095
|
* Sets "first-level", see getter.
|
|
41099
41096
|
*/
|
|
41100
41097
|
set firstLevel(newLevel) {
|
|
41101
|
-
logger
|
|
41098
|
+
logger.log(`set firstLevel:${newLevel}`);
|
|
41102
41099
|
this.levelController.firstLevel = newLevel;
|
|
41103
41100
|
}
|
|
41104
41101
|
|
|
@@ -41123,7 +41120,7 @@ class Hls {
|
|
|
41123
41120
|
* (determined from download of first segment)
|
|
41124
41121
|
*/
|
|
41125
41122
|
set startLevel(newLevel) {
|
|
41126
|
-
logger
|
|
41123
|
+
logger.log(`set startLevel:${newLevel}`);
|
|
41127
41124
|
// if not in automatic start level detection, ensure startLevel is greater than minAutoLevel
|
|
41128
41125
|
if (newLevel !== -1) {
|
|
41129
41126
|
newLevel = Math.max(newLevel, this.minAutoLevel);
|
|
@@ -41198,7 +41195,7 @@ class Hls {
|
|
|
41198
41195
|
*/
|
|
41199
41196
|
set autoLevelCapping(newLevel) {
|
|
41200
41197
|
if (this._autoLevelCapping !== newLevel) {
|
|
41201
|
-
logger
|
|
41198
|
+
logger.log(`set autoLevelCapping:${newLevel}`);
|
|
41202
41199
|
this._autoLevelCapping = newLevel;
|
|
41203
41200
|
this.levelController.checkMaxAutoUpdated();
|
|
41204
41201
|
}
|
|
@@ -42227,13 +42224,20 @@ const DEFAULT_OPTIONS = {
|
|
|
42227
42224
|
autoPlay: false,
|
|
42228
42225
|
mute: false,
|
|
42229
42226
|
loop: false,
|
|
42227
|
+
multisources: [],
|
|
42228
|
+
playbackType: 'vod',
|
|
42229
|
+
priorityTransport: 'dash',
|
|
42230
|
+
debug: 'none',
|
|
42231
|
+
pluginSettings: {},
|
|
42232
|
+
strings: {},
|
|
42233
|
+
poster: '',
|
|
42230
42234
|
};
|
|
42231
42235
|
/**
|
|
42232
42236
|
* @beta
|
|
42233
42237
|
*/
|
|
42234
42238
|
class Player {
|
|
42235
42239
|
bitrateInfo = null;
|
|
42236
|
-
config;
|
|
42240
|
+
config = DEFAULT_OPTIONS;
|
|
42237
42241
|
emitter = new EventLite();
|
|
42238
42242
|
player = null;
|
|
42239
42243
|
ready = false;
|
|
@@ -42262,7 +42266,7 @@ class Player {
|
|
|
42262
42266
|
return this.player?.core.activePlayback?.getPlaybackType();
|
|
42263
42267
|
}
|
|
42264
42268
|
constructor(config) {
|
|
42265
|
-
this.
|
|
42269
|
+
this.setConfig(config);
|
|
42266
42270
|
}
|
|
42267
42271
|
on(event, handler) {
|
|
42268
42272
|
this.emitter.on(event, handler);
|
|
@@ -42271,7 +42275,10 @@ class Player {
|
|
|
42271
42275
|
this.emitter.off(event, handler);
|
|
42272
42276
|
}
|
|
42273
42277
|
configure(config) {
|
|
42274
|
-
|
|
42278
|
+
this.setConfig(config);
|
|
42279
|
+
}
|
|
42280
|
+
setConfig(config) {
|
|
42281
|
+
this.config = $.extend(true, this.config, config);
|
|
42275
42282
|
}
|
|
42276
42283
|
async init(playerElement) {
|
|
42277
42284
|
assert.ok(!this.player, 'Player already initialized');
|
|
@@ -42281,6 +42288,7 @@ class Player {
|
|
|
42281
42288
|
Log.setLevel(0);
|
|
42282
42289
|
}
|
|
42283
42290
|
Log.debug(T, 'Config', this.config);
|
|
42291
|
+
Log.debug(T, 'isiOS', Browser.isiOS);
|
|
42284
42292
|
this.configurePlaybacks();
|
|
42285
42293
|
const coreOpts = this.buildCoreOptions(playerElement);
|
|
42286
42294
|
const { core, container, } = Loader.registeredPlugins;
|
|
@@ -42373,7 +42381,7 @@ class Player {
|
|
|
42373
42381
|
}
|
|
42374
42382
|
});
|
|
42375
42383
|
}
|
|
42376
|
-
if (this.config.
|
|
42384
|
+
if (this.config.xAutoPlay) {
|
|
42377
42385
|
setTimeout(() => {
|
|
42378
42386
|
Log.debug(T, 'autoPlay');
|
|
42379
42387
|
assert(this.player);
|
|
@@ -42437,7 +42445,8 @@ class Player {
|
|
|
42437
42445
|
const poster = mainSource?.poster ?? this.config.poster;
|
|
42438
42446
|
const coreOptions = {
|
|
42439
42447
|
...this.config.pluginSettings,
|
|
42440
|
-
|
|
42448
|
+
allowUserInteraction: true,
|
|
42449
|
+
autoPlay: this.config.autoPlay ?? false,
|
|
42441
42450
|
debug: this.config.debug || 'none',
|
|
42442
42451
|
events: this.events,
|
|
42443
42452
|
height: playerElement.clientHeight,
|
|
@@ -42446,8 +42455,8 @@ class Player {
|
|
|
42446
42455
|
mute: this.config.mute,
|
|
42447
42456
|
playback: {
|
|
42448
42457
|
controls: false,
|
|
42449
|
-
preload: Browser.isiOS ? 'metadata' : 'none',
|
|
42450
42458
|
playInline: true,
|
|
42459
|
+
preload: Browser.isiOS ? 'metadata' : 'none',
|
|
42451
42460
|
mute: this.config.mute,
|
|
42452
42461
|
crossOrigin: 'anonymous', // TODO
|
|
42453
42462
|
hlsjsConfig: {
|
|
@@ -42613,1332 +42622,35 @@ class LogTracer {
|
|
|
42613
42622
|
}
|
|
42614
42623
|
}
|
|
42615
42624
|
|
|
42616
|
-
// This is a magic string replaced by rollup
|
|
42617
|
-
|
|
42618
|
-
const SDK_VERSION = "8.47.0" ;
|
|
42619
|
-
|
|
42620
|
-
/** Get's the global object for the current JavaScript runtime */
|
|
42621
|
-
const GLOBAL_OBJ = globalThis ;
|
|
42622
|
-
|
|
42623
|
-
/**
|
|
42624
|
-
* Returns a global singleton contained in the global `__SENTRY__[]` object.
|
|
42625
|
-
*
|
|
42626
|
-
* If the singleton doesn't already exist in `__SENTRY__`, it will be created using the given factory
|
|
42627
|
-
* function and added to the `__SENTRY__` object.
|
|
42628
|
-
*
|
|
42629
|
-
* @param name name of the global singleton on __SENTRY__
|
|
42630
|
-
* @param creator creator Factory function to create the singleton if it doesn't already exist on `__SENTRY__`
|
|
42631
|
-
* @param obj (Optional) The global object on which to look for `__SENTRY__`, if not `GLOBAL_OBJ`'s return value
|
|
42632
|
-
* @returns the singleton
|
|
42633
|
-
*/
|
|
42634
|
-
function getGlobalSingleton(name, creator, obj) {
|
|
42635
|
-
const gbl = (GLOBAL_OBJ) ;
|
|
42636
|
-
const __SENTRY__ = (gbl.__SENTRY__ = gbl.__SENTRY__ || {});
|
|
42637
|
-
const versionedCarrier = (__SENTRY__[SDK_VERSION] = __SENTRY__[SDK_VERSION] || {});
|
|
42638
|
-
return versionedCarrier[name] || (versionedCarrier[name] = creator());
|
|
42639
|
-
}
|
|
42640
|
-
|
|
42641
|
-
/**
|
|
42642
|
-
* This serves as a build time flag that will be true by default, but false in non-debug builds or if users replace `__SENTRY_DEBUG__` in their generated code.
|
|
42643
|
-
*
|
|
42644
|
-
* ATTENTION: This constant must never cross package boundaries (i.e. be exported) to guarantee that it can be used for tree shaking.
|
|
42645
|
-
*/
|
|
42646
|
-
const DEBUG_BUILD = (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__);
|
|
42647
|
-
|
|
42648
|
-
/** Prefix for logging strings */
|
|
42649
|
-
const PREFIX = 'Sentry Logger ';
|
|
42650
|
-
|
|
42651
|
-
const CONSOLE_LEVELS = [
|
|
42652
|
-
'debug',
|
|
42653
|
-
'info',
|
|
42654
|
-
'warn',
|
|
42655
|
-
'error',
|
|
42656
|
-
'log',
|
|
42657
|
-
'assert',
|
|
42658
|
-
'trace',
|
|
42659
|
-
] ;
|
|
42660
|
-
|
|
42661
|
-
/** This may be mutated by the console instrumentation. */
|
|
42662
|
-
const originalConsoleMethods
|
|
42663
|
-
|
|
42664
|
-
= {};
|
|
42665
|
-
|
|
42666
|
-
/** JSDoc */
|
|
42667
|
-
|
|
42668
|
-
/**
|
|
42669
|
-
* Temporarily disable sentry console instrumentations.
|
|
42670
|
-
*
|
|
42671
|
-
* @param callback The function to run against the original `console` messages
|
|
42672
|
-
* @returns The results of the callback
|
|
42673
|
-
*/
|
|
42674
|
-
function consoleSandbox(callback) {
|
|
42675
|
-
if (!('console' in GLOBAL_OBJ)) {
|
|
42676
|
-
return callback();
|
|
42677
|
-
}
|
|
42678
|
-
|
|
42679
|
-
const console = GLOBAL_OBJ.console ;
|
|
42680
|
-
const wrappedFuncs = {};
|
|
42681
|
-
|
|
42682
|
-
const wrappedLevels = Object.keys(originalConsoleMethods) ;
|
|
42683
|
-
|
|
42684
|
-
// Restore all wrapped console methods
|
|
42685
|
-
wrappedLevels.forEach(level => {
|
|
42686
|
-
const originalConsoleMethod = originalConsoleMethods[level] ;
|
|
42687
|
-
wrappedFuncs[level] = console[level] ;
|
|
42688
|
-
console[level] = originalConsoleMethod;
|
|
42689
|
-
});
|
|
42690
|
-
|
|
42691
|
-
try {
|
|
42692
|
-
return callback();
|
|
42693
|
-
} finally {
|
|
42694
|
-
// Revert restoration to wrapped state
|
|
42695
|
-
wrappedLevels.forEach(level => {
|
|
42696
|
-
console[level] = wrappedFuncs[level] ;
|
|
42697
|
-
});
|
|
42698
|
-
}
|
|
42699
|
-
}
|
|
42700
|
-
|
|
42701
|
-
function makeLogger() {
|
|
42702
|
-
let enabled = false;
|
|
42703
|
-
const logger = {
|
|
42704
|
-
enable: () => {
|
|
42705
|
-
enabled = true;
|
|
42706
|
-
},
|
|
42707
|
-
disable: () => {
|
|
42708
|
-
enabled = false;
|
|
42709
|
-
},
|
|
42710
|
-
isEnabled: () => enabled,
|
|
42711
|
-
};
|
|
42712
|
-
|
|
42713
|
-
if (DEBUG_BUILD) {
|
|
42714
|
-
CONSOLE_LEVELS.forEach(name => {
|
|
42715
|
-
logger[name] = (...args) => {
|
|
42716
|
-
if (enabled) {
|
|
42717
|
-
consoleSandbox(() => {
|
|
42718
|
-
GLOBAL_OBJ.console[name](`${PREFIX}[${name}]:`, ...args);
|
|
42719
|
-
});
|
|
42720
|
-
}
|
|
42721
|
-
};
|
|
42722
|
-
});
|
|
42723
|
-
} else {
|
|
42724
|
-
CONSOLE_LEVELS.forEach(name => {
|
|
42725
|
-
logger[name] = () => undefined;
|
|
42726
|
-
});
|
|
42727
|
-
}
|
|
42728
|
-
|
|
42729
|
-
return logger ;
|
|
42730
|
-
}
|
|
42731
|
-
|
|
42732
|
-
/**
|
|
42733
|
-
* This is a logger singleton which either logs things or no-ops if logging is not enabled.
|
|
42734
|
-
* The logger is a singleton on the carrier, to ensure that a consistent logger is used throughout the SDK.
|
|
42735
|
-
*/
|
|
42736
|
-
const logger = getGlobalSingleton('logger', makeLogger);
|
|
42737
|
-
|
|
42738
|
-
/**
|
|
42739
|
-
* An object that contains globally accessible properties and maintains a scope stack.
|
|
42740
|
-
* @hidden
|
|
42741
|
-
*/
|
|
42742
|
-
|
|
42743
|
-
/**
|
|
42744
|
-
* Returns the global shim registry.
|
|
42745
|
-
*
|
|
42746
|
-
* FIXME: This function is problematic, because despite always returning a valid Carrier,
|
|
42747
|
-
* it has an optional `__SENTRY__` property, which then in turn requires us to always perform an unnecessary check
|
|
42748
|
-
* at the call-site. We always access the carrier through this function, so we can guarantee that `__SENTRY__` is there.
|
|
42749
|
-
**/
|
|
42750
|
-
function getMainCarrier() {
|
|
42751
|
-
// This ensures a Sentry carrier exists
|
|
42752
|
-
getSentryCarrier(GLOBAL_OBJ);
|
|
42753
|
-
return GLOBAL_OBJ;
|
|
42754
|
-
}
|
|
42755
|
-
|
|
42756
|
-
/** Will either get the existing sentry carrier, or create a new one. */
|
|
42757
|
-
function getSentryCarrier(carrier) {
|
|
42758
|
-
const __SENTRY__ = (carrier.__SENTRY__ = carrier.__SENTRY__ || {});
|
|
42759
|
-
|
|
42760
|
-
// For now: First SDK that sets the .version property wins
|
|
42761
|
-
__SENTRY__.version = __SENTRY__.version || SDK_VERSION;
|
|
42762
|
-
|
|
42763
|
-
// Intentionally populating and returning the version of "this" SDK instance
|
|
42764
|
-
// rather than what's set in .version so that "this" SDK always gets its carrier
|
|
42765
|
-
return (__SENTRY__[SDK_VERSION] = __SENTRY__[SDK_VERSION] || {});
|
|
42766
|
-
}
|
|
42767
|
-
|
|
42768
|
-
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
42769
|
-
const objectToString = Object.prototype.toString;
|
|
42770
|
-
/**
|
|
42771
|
-
* Checks whether given value is an instance of the given built-in class.
|
|
42772
|
-
*
|
|
42773
|
-
* @param wat The value to be checked
|
|
42774
|
-
* @param className
|
|
42775
|
-
* @returns A boolean representing the result.
|
|
42776
|
-
*/
|
|
42777
|
-
function isBuiltin(wat, className) {
|
|
42778
|
-
return objectToString.call(wat) === `[object ${className}]`;
|
|
42779
|
-
}
|
|
42780
|
-
|
|
42781
|
-
/**
|
|
42782
|
-
* Checks whether given value's type is an object literal, or a class instance.
|
|
42783
|
-
* {@link isPlainObject}.
|
|
42784
|
-
*
|
|
42785
|
-
* @param wat A value to be checked.
|
|
42786
|
-
* @returns A boolean representing the result.
|
|
42787
|
-
*/
|
|
42788
|
-
function isPlainObject(wat) {
|
|
42789
|
-
return isBuiltin(wat, 'Object');
|
|
42790
|
-
}
|
|
42791
|
-
|
|
42792
|
-
/**
|
|
42793
|
-
* Checks whether given value has a then function.
|
|
42794
|
-
* @param wat A value to be checked.
|
|
42795
|
-
*/
|
|
42796
|
-
function isThenable(wat) {
|
|
42797
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
42798
|
-
return Boolean(wat && wat.then && typeof wat.then === 'function');
|
|
42799
|
-
}
|
|
42800
|
-
|
|
42801
|
-
/**
|
|
42802
|
-
* Defines a non-enumerable property on the given object.
|
|
42803
|
-
*
|
|
42804
|
-
* @param obj The object on which to set the property
|
|
42805
|
-
* @param name The name of the property to be set
|
|
42806
|
-
* @param value The value to which to set the property
|
|
42807
|
-
*/
|
|
42808
|
-
function addNonEnumerableProperty(obj, name, value) {
|
|
42809
|
-
try {
|
|
42810
|
-
Object.defineProperty(obj, name, {
|
|
42811
|
-
// enumerable: false, // the default, so we can save on bundle size by not explicitly setting it
|
|
42812
|
-
value: value,
|
|
42813
|
-
writable: true,
|
|
42814
|
-
configurable: true,
|
|
42815
|
-
});
|
|
42816
|
-
} catch (o_O) {
|
|
42817
|
-
DEBUG_BUILD && logger.log(`Failed to add non-enumerable property "${name}" to object`, obj);
|
|
42818
|
-
}
|
|
42819
|
-
}
|
|
42820
|
-
|
|
42821
|
-
const ONE_SECOND_IN_MS = 1000;
|
|
42822
|
-
|
|
42823
|
-
/**
|
|
42824
|
-
* A partial definition of the [Performance Web API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Performance}
|
|
42825
|
-
* for accessing a high-resolution monotonic clock.
|
|
42826
|
-
*/
|
|
42827
|
-
|
|
42828
|
-
/**
|
|
42829
|
-
* Returns a timestamp in seconds since the UNIX epoch using the Date API.
|
|
42830
|
-
*
|
|
42831
|
-
* TODO(v8): Return type should be rounded.
|
|
42832
|
-
*/
|
|
42833
|
-
function dateTimestampInSeconds() {
|
|
42834
|
-
return Date.now() / ONE_SECOND_IN_MS;
|
|
42835
|
-
}
|
|
42836
|
-
|
|
42837
|
-
/**
|
|
42838
|
-
* Returns a wrapper around the native Performance API browser implementation, or undefined for browsers that do not
|
|
42839
|
-
* support the API.
|
|
42840
|
-
*
|
|
42841
|
-
* Wrapping the native API works around differences in behavior from different browsers.
|
|
42842
|
-
*/
|
|
42843
|
-
function createUnixTimestampInSecondsFunc() {
|
|
42844
|
-
const { performance } = GLOBAL_OBJ ;
|
|
42845
|
-
if (!performance || !performance.now) {
|
|
42846
|
-
return dateTimestampInSeconds;
|
|
42847
|
-
}
|
|
42848
|
-
|
|
42849
|
-
// Some browser and environments don't have a timeOrigin, so we fallback to
|
|
42850
|
-
// using Date.now() to compute the starting time.
|
|
42851
|
-
const approxStartingTimeOrigin = Date.now() - performance.now();
|
|
42852
|
-
const timeOrigin = performance.timeOrigin == undefined ? approxStartingTimeOrigin : performance.timeOrigin;
|
|
42853
|
-
|
|
42854
|
-
// performance.now() is a monotonic clock, which means it starts at 0 when the process begins. To get the current
|
|
42855
|
-
// wall clock time (actual UNIX timestamp), we need to add the starting time origin and the current time elapsed.
|
|
42856
|
-
//
|
|
42857
|
-
// TODO: This does not account for the case where the monotonic clock that powers performance.now() drifts from the
|
|
42858
|
-
// wall clock time, which causes the returned timestamp to be inaccurate. We should investigate how to detect and
|
|
42859
|
-
// correct for this.
|
|
42860
|
-
// See: https://github.com/getsentry/sentry-javascript/issues/2590
|
|
42861
|
-
// See: https://github.com/mdn/content/issues/4713
|
|
42862
|
-
// See: https://dev.to/noamr/when-a-millisecond-is-not-a-millisecond-3h6
|
|
42863
|
-
return () => {
|
|
42864
|
-
return (timeOrigin + performance.now()) / ONE_SECOND_IN_MS;
|
|
42865
|
-
};
|
|
42866
|
-
}
|
|
42867
|
-
|
|
42868
|
-
/**
|
|
42869
|
-
* Returns a timestamp in seconds since the UNIX epoch using either the Performance or Date APIs, depending on the
|
|
42870
|
-
* availability of the Performance API.
|
|
42871
|
-
*
|
|
42872
|
-
* BUG: Note that because of how browsers implement the Performance API, the clock might stop when the computer is
|
|
42873
|
-
* asleep. This creates a skew between `dateTimestampInSeconds` and `timestampInSeconds`. The
|
|
42874
|
-
* skew can grow to arbitrary amounts like days, weeks or months.
|
|
42875
|
-
* See https://github.com/getsentry/sentry-javascript/issues/2590.
|
|
42876
|
-
*/
|
|
42877
|
-
const timestampInSeconds = createUnixTimestampInSecondsFunc();
|
|
42878
|
-
|
|
42879
|
-
/**
|
|
42880
|
-
* The number of milliseconds since the UNIX epoch. This value is only usable in a browser, and only when the
|
|
42881
|
-
* performance API is available.
|
|
42882
|
-
*/
|
|
42883
|
-
(() => {
|
|
42884
|
-
// Unfortunately browsers may report an inaccurate time origin data, through either performance.timeOrigin or
|
|
42885
|
-
// performance.timing.navigationStart, which results in poor results in performance data. We only treat time origin
|
|
42886
|
-
// data as reliable if they are within a reasonable threshold of the current time.
|
|
42887
|
-
|
|
42888
|
-
const { performance } = GLOBAL_OBJ ;
|
|
42889
|
-
if (!performance || !performance.now) {
|
|
42890
|
-
return undefined;
|
|
42891
|
-
}
|
|
42892
|
-
|
|
42893
|
-
const threshold = 3600 * 1000;
|
|
42894
|
-
const performanceNow = performance.now();
|
|
42895
|
-
const dateNow = Date.now();
|
|
42896
|
-
|
|
42897
|
-
// if timeOrigin isn't available set delta to threshold so it isn't used
|
|
42898
|
-
const timeOriginDelta = performance.timeOrigin
|
|
42899
|
-
? Math.abs(performance.timeOrigin + performanceNow - dateNow)
|
|
42900
|
-
: threshold;
|
|
42901
|
-
const timeOriginIsReliable = timeOriginDelta < threshold;
|
|
42902
|
-
|
|
42903
|
-
// While performance.timing.navigationStart is deprecated in favor of performance.timeOrigin, performance.timeOrigin
|
|
42904
|
-
// is not as widely supported. Namely, performance.timeOrigin is undefined in Safari as of writing.
|
|
42905
|
-
// Also as of writing, performance.timing is not available in Web Workers in mainstream browsers, so it is not always
|
|
42906
|
-
// a valid fallback. In the absence of an initial time provided by the browser, fallback to the current time from the
|
|
42907
|
-
// Date API.
|
|
42908
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
42909
|
-
const navigationStart = performance.timing && performance.timing.navigationStart;
|
|
42910
|
-
const hasNavigationStart = typeof navigationStart === 'number';
|
|
42911
|
-
// if navigationStart isn't available set delta to threshold so it isn't used
|
|
42912
|
-
const navigationStartDelta = hasNavigationStart ? Math.abs(navigationStart + performanceNow - dateNow) : threshold;
|
|
42913
|
-
const navigationStartIsReliable = navigationStartDelta < threshold;
|
|
42914
|
-
|
|
42915
|
-
if (timeOriginIsReliable || navigationStartIsReliable) {
|
|
42916
|
-
// Use the more reliable time origin
|
|
42917
|
-
if (timeOriginDelta <= navigationStartDelta) {
|
|
42918
|
-
return performance.timeOrigin;
|
|
42919
|
-
} else {
|
|
42920
|
-
return navigationStart;
|
|
42921
|
-
}
|
|
42922
|
-
}
|
|
42923
|
-
return dateNow;
|
|
42924
|
-
})();
|
|
42925
|
-
|
|
42926
|
-
/**
|
|
42927
|
-
* UUID4 generator
|
|
42928
|
-
*
|
|
42929
|
-
* @returns string Generated UUID4.
|
|
42930
|
-
*/
|
|
42931
|
-
function uuid4() {
|
|
42932
|
-
const gbl = GLOBAL_OBJ ;
|
|
42933
|
-
const crypto = gbl.crypto || gbl.msCrypto;
|
|
42934
|
-
|
|
42935
|
-
let getRandomByte = () => Math.random() * 16;
|
|
42936
|
-
try {
|
|
42937
|
-
if (crypto && crypto.randomUUID) {
|
|
42938
|
-
return crypto.randomUUID().replace(/-/g, '');
|
|
42939
|
-
}
|
|
42940
|
-
if (crypto && crypto.getRandomValues) {
|
|
42941
|
-
getRandomByte = () => {
|
|
42942
|
-
// crypto.getRandomValues might return undefined instead of the typed array
|
|
42943
|
-
// in old Chromium versions (e.g. 23.0.1235.0 (151422))
|
|
42944
|
-
// However, `typedArray` is still filled in-place.
|
|
42945
|
-
// @see https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#typedarray
|
|
42946
|
-
const typedArray = new Uint8Array(1);
|
|
42947
|
-
crypto.getRandomValues(typedArray);
|
|
42948
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
42949
|
-
return typedArray[0];
|
|
42950
|
-
};
|
|
42951
|
-
}
|
|
42952
|
-
} catch (_) {
|
|
42953
|
-
// some runtimes can crash invoking crypto
|
|
42954
|
-
// https://github.com/getsentry/sentry-javascript/issues/8935
|
|
42955
|
-
}
|
|
42956
|
-
|
|
42957
|
-
// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
|
|
42958
|
-
// Concatenating the following numbers as strings results in '10000000100040008000100000000000'
|
|
42959
|
-
return (([1e7] ) + 1e3 + 4e3 + 8e3 + 1e11).replace(/[018]/g, c =>
|
|
42960
|
-
// eslint-disable-next-line no-bitwise
|
|
42961
|
-
((c ) ^ ((getRandomByte() & 15) >> ((c ) / 4))).toString(16),
|
|
42962
|
-
);
|
|
42963
|
-
}
|
|
42964
|
-
|
|
42965
42625
|
/**
|
|
42966
|
-
*
|
|
42967
|
-
*
|
|
42968
|
-
* Note that this function mutates the passed object and returns void.
|
|
42969
|
-
* (Had to do this instead of returning a new and updated session because closing and sending a session
|
|
42970
|
-
* makes an update to the session after it was passed to the sending logic.
|
|
42971
|
-
* @see BaseClient.captureSession )
|
|
42972
|
-
*
|
|
42973
|
-
* @param session the `Session` to update
|
|
42974
|
-
* @param context the `SessionContext` holding the properties that should be updated in @param session
|
|
42626
|
+
* @beta
|
|
42975
42627
|
*/
|
|
42976
|
-
|
|
42977
|
-
|
|
42978
|
-
|
|
42979
|
-
|
|
42980
|
-
|
|
42628
|
+
class SentryTracer {
|
|
42629
|
+
client;
|
|
42630
|
+
scope;
|
|
42631
|
+
constructor(client, scope) {
|
|
42632
|
+
this.client = client;
|
|
42633
|
+
this.scope = scope;
|
|
42981
42634
|
}
|
|
42982
|
-
|
|
42983
|
-
|
|
42984
|
-
session.did = context.user.id || context.user.email || context.user.username;
|
|
42635
|
+
reportError(e) {
|
|
42636
|
+
this.client.captureException(e);
|
|
42985
42637
|
}
|
|
42986
|
-
|
|
42987
|
-
|
|
42988
|
-
|
|
42989
|
-
|
|
42990
|
-
|
|
42991
|
-
|
|
42992
|
-
|
|
42993
|
-
|
|
42994
|
-
if (context.ignoreDuration) {
|
|
42995
|
-
session.ignoreDuration = context.ignoreDuration;
|
|
42996
|
-
}
|
|
42997
|
-
if (context.sid) {
|
|
42998
|
-
// Good enough uuid validation. — Kamil
|
|
42999
|
-
session.sid = context.sid.length === 32 ? context.sid : uuid4();
|
|
43000
|
-
}
|
|
43001
|
-
if (context.init !== undefined) {
|
|
43002
|
-
session.init = context.init;
|
|
43003
|
-
}
|
|
43004
|
-
if (!session.did && context.did) {
|
|
43005
|
-
session.did = `${context.did}`;
|
|
43006
|
-
}
|
|
43007
|
-
if (typeof context.started === 'number') {
|
|
43008
|
-
session.started = context.started;
|
|
43009
|
-
}
|
|
43010
|
-
if (session.ignoreDuration) {
|
|
43011
|
-
session.duration = undefined;
|
|
43012
|
-
} else if (typeof context.duration === 'number') {
|
|
43013
|
-
session.duration = context.duration;
|
|
43014
|
-
} else {
|
|
43015
|
-
const duration = session.timestamp - session.started;
|
|
43016
|
-
session.duration = duration >= 0 ? duration : 0;
|
|
43017
|
-
}
|
|
43018
|
-
if (context.release) {
|
|
43019
|
-
session.release = context.release;
|
|
43020
|
-
}
|
|
43021
|
-
if (context.environment) {
|
|
43022
|
-
session.environment = context.environment;
|
|
43023
|
-
}
|
|
43024
|
-
if (!session.ipAddress && context.ipAddress) {
|
|
43025
|
-
session.ipAddress = context.ipAddress;
|
|
43026
|
-
}
|
|
43027
|
-
if (!session.userAgent && context.userAgent) {
|
|
43028
|
-
session.userAgent = context.userAgent;
|
|
43029
|
-
}
|
|
43030
|
-
if (typeof context.errors === 'number') {
|
|
43031
|
-
session.errors = context.errors;
|
|
43032
|
-
}
|
|
43033
|
-
if (context.status) {
|
|
43034
|
-
session.status = context.status;
|
|
43035
|
-
}
|
|
43036
|
-
}
|
|
43037
|
-
|
|
43038
|
-
/**
|
|
43039
|
-
* Generate a random, valid trace ID.
|
|
43040
|
-
*/
|
|
43041
|
-
function generateTraceId() {
|
|
43042
|
-
return uuid4();
|
|
43043
|
-
}
|
|
43044
|
-
|
|
43045
|
-
/**
|
|
43046
|
-
* Generate a random, valid span ID.
|
|
43047
|
-
*/
|
|
43048
|
-
function generateSpanId() {
|
|
43049
|
-
return uuid4().substring(16);
|
|
43050
|
-
}
|
|
43051
|
-
|
|
43052
|
-
/**
|
|
43053
|
-
* Shallow merge two objects.
|
|
43054
|
-
* Does not mutate the passed in objects.
|
|
43055
|
-
* Undefined/empty values in the merge object will overwrite existing values.
|
|
43056
|
-
*
|
|
43057
|
-
* By default, this merges 2 levels deep.
|
|
43058
|
-
*/
|
|
43059
|
-
function merge(initialObj, mergeObj, levels = 2) {
|
|
43060
|
-
// If the merge value is not an object, or we have no merge levels left,
|
|
43061
|
-
// we just set the value to the merge value
|
|
43062
|
-
if (!mergeObj || typeof mergeObj !== 'object' || levels <= 0) {
|
|
43063
|
-
return mergeObj;
|
|
43064
|
-
}
|
|
43065
|
-
|
|
43066
|
-
// If the merge object is an empty object, and the initial object is not undefined, we return the initial object
|
|
43067
|
-
if (initialObj && mergeObj && Object.keys(mergeObj).length === 0) {
|
|
43068
|
-
return initialObj;
|
|
43069
|
-
}
|
|
43070
|
-
|
|
43071
|
-
// Clone object
|
|
43072
|
-
const output = { ...initialObj };
|
|
43073
|
-
|
|
43074
|
-
// Merge values into output, resursively
|
|
43075
|
-
for (const key in mergeObj) {
|
|
43076
|
-
if (Object.prototype.hasOwnProperty.call(mergeObj, key)) {
|
|
43077
|
-
output[key] = merge(output[key], mergeObj[key], levels - 1);
|
|
42638
|
+
trace(message, data) {
|
|
42639
|
+
this.scope.addBreadcrumb({
|
|
42640
|
+
type: "default",
|
|
42641
|
+
level: "info",
|
|
42642
|
+
message,
|
|
42643
|
+
data,
|
|
42644
|
+
});
|
|
43078
42645
|
}
|
|
43079
|
-
}
|
|
43080
|
-
|
|
43081
|
-
return output;
|
|
43082
|
-
}
|
|
43083
|
-
|
|
43084
|
-
const SCOPE_SPAN_FIELD = '_sentrySpan';
|
|
43085
|
-
|
|
43086
|
-
/**
|
|
43087
|
-
* Set the active span for a given scope.
|
|
43088
|
-
* NOTE: This should NOT be used directly, but is only used internally by the trace methods.
|
|
43089
|
-
*/
|
|
43090
|
-
function _setSpanForScope(scope, span) {
|
|
43091
|
-
if (span) {
|
|
43092
|
-
addNonEnumerableProperty(scope , SCOPE_SPAN_FIELD, span);
|
|
43093
|
-
} else {
|
|
43094
|
-
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
43095
|
-
delete (scope )[SCOPE_SPAN_FIELD];
|
|
43096
|
-
}
|
|
43097
|
-
}
|
|
43098
|
-
|
|
43099
|
-
/**
|
|
43100
|
-
* Get the active span for a given scope.
|
|
43101
|
-
* NOTE: This should NOT be used directly, but is only used internally by the trace methods.
|
|
43102
|
-
*/
|
|
43103
|
-
function _getSpanForScope(scope) {
|
|
43104
|
-
return scope[SCOPE_SPAN_FIELD];
|
|
43105
42646
|
}
|
|
43106
42647
|
|
|
43107
|
-
|
|
43108
|
-
* Default value for maximum number of breadcrumbs added to an event.
|
|
43109
|
-
*/
|
|
43110
|
-
const DEFAULT_MAX_BREADCRUMBS = 100;
|
|
43111
|
-
|
|
43112
|
-
/**
|
|
43113
|
-
* Holds additional event information.
|
|
43114
|
-
*/
|
|
43115
|
-
class ScopeClass {
|
|
43116
|
-
/** Flag if notifying is happening. */
|
|
43117
|
-
|
|
43118
|
-
/** Callback for client to receive scope changes. */
|
|
43119
|
-
|
|
43120
|
-
/** Callback list that will be called during event processing. */
|
|
43121
|
-
|
|
43122
|
-
/** Array of breadcrumbs. */
|
|
43123
|
-
|
|
43124
|
-
/** User */
|
|
43125
|
-
|
|
43126
|
-
/** Tags */
|
|
43127
|
-
|
|
43128
|
-
/** Extra */
|
|
43129
|
-
|
|
43130
|
-
/** Contexts */
|
|
43131
|
-
|
|
43132
|
-
/** Attachments */
|
|
43133
|
-
|
|
43134
|
-
/** Propagation Context for distributed tracing */
|
|
43135
|
-
|
|
43136
|
-
/**
|
|
43137
|
-
* A place to stash data which is needed at some point in the SDK's event processing pipeline but which shouldn't get
|
|
43138
|
-
* sent to Sentry
|
|
43139
|
-
*/
|
|
43140
|
-
|
|
43141
|
-
/** Fingerprint */
|
|
43142
|
-
|
|
43143
|
-
/** Severity */
|
|
43144
|
-
|
|
43145
|
-
/**
|
|
43146
|
-
* Transaction Name
|
|
43147
|
-
*
|
|
43148
|
-
* IMPORTANT: The transaction name on the scope has nothing to do with root spans/transaction objects.
|
|
43149
|
-
* It's purpose is to assign a transaction to the scope that's added to non-transaction events.
|
|
43150
|
-
*/
|
|
43151
|
-
|
|
43152
|
-
/** Session */
|
|
43153
|
-
|
|
43154
|
-
/** Request Mode Session Status */
|
|
43155
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
43156
|
-
|
|
43157
|
-
/** The client on this scope */
|
|
43158
|
-
|
|
43159
|
-
/** Contains the last event id of a captured event. */
|
|
43160
|
-
|
|
43161
|
-
// NOTE: Any field which gets added here should get added not only to the constructor but also to the `clone` method.
|
|
43162
|
-
|
|
43163
|
-
constructor() {
|
|
43164
|
-
this._notifyingListeners = false;
|
|
43165
|
-
this._scopeListeners = [];
|
|
43166
|
-
this._eventProcessors = [];
|
|
43167
|
-
this._breadcrumbs = [];
|
|
43168
|
-
this._attachments = [];
|
|
43169
|
-
this._user = {};
|
|
43170
|
-
this._tags = {};
|
|
43171
|
-
this._extra = {};
|
|
43172
|
-
this._contexts = {};
|
|
43173
|
-
this._sdkProcessingMetadata = {};
|
|
43174
|
-
this._propagationContext = {
|
|
43175
|
-
traceId: generateTraceId(),
|
|
43176
|
-
spanId: generateSpanId(),
|
|
43177
|
-
};
|
|
43178
|
-
}
|
|
43179
|
-
|
|
43180
|
-
/**
|
|
43181
|
-
* @inheritDoc
|
|
43182
|
-
*/
|
|
43183
|
-
clone() {
|
|
43184
|
-
const newScope = new ScopeClass();
|
|
43185
|
-
newScope._breadcrumbs = [...this._breadcrumbs];
|
|
43186
|
-
newScope._tags = { ...this._tags };
|
|
43187
|
-
newScope._extra = { ...this._extra };
|
|
43188
|
-
newScope._contexts = { ...this._contexts };
|
|
43189
|
-
if (this._contexts.flags) {
|
|
43190
|
-
// We need to copy the `values` array so insertions on a cloned scope
|
|
43191
|
-
// won't affect the original array.
|
|
43192
|
-
newScope._contexts.flags = {
|
|
43193
|
-
values: [...this._contexts.flags.values],
|
|
43194
|
-
};
|
|
43195
|
-
}
|
|
43196
|
-
|
|
43197
|
-
newScope._user = this._user;
|
|
43198
|
-
newScope._level = this._level;
|
|
43199
|
-
newScope._session = this._session;
|
|
43200
|
-
newScope._transactionName = this._transactionName;
|
|
43201
|
-
newScope._fingerprint = this._fingerprint;
|
|
43202
|
-
newScope._eventProcessors = [...this._eventProcessors];
|
|
43203
|
-
newScope._requestSession = this._requestSession;
|
|
43204
|
-
newScope._attachments = [...this._attachments];
|
|
43205
|
-
newScope._sdkProcessingMetadata = { ...this._sdkProcessingMetadata };
|
|
43206
|
-
newScope._propagationContext = { ...this._propagationContext };
|
|
43207
|
-
newScope._client = this._client;
|
|
43208
|
-
newScope._lastEventId = this._lastEventId;
|
|
43209
|
-
|
|
43210
|
-
_setSpanForScope(newScope, _getSpanForScope(this));
|
|
43211
|
-
|
|
43212
|
-
return newScope;
|
|
43213
|
-
}
|
|
43214
|
-
|
|
43215
|
-
/**
|
|
43216
|
-
* @inheritDoc
|
|
43217
|
-
*/
|
|
43218
|
-
setClient(client) {
|
|
43219
|
-
this._client = client;
|
|
43220
|
-
}
|
|
43221
|
-
|
|
43222
|
-
/**
|
|
43223
|
-
* @inheritDoc
|
|
43224
|
-
*/
|
|
43225
|
-
setLastEventId(lastEventId) {
|
|
43226
|
-
this._lastEventId = lastEventId;
|
|
43227
|
-
}
|
|
43228
|
-
|
|
43229
|
-
/**
|
|
43230
|
-
* @inheritDoc
|
|
43231
|
-
*/
|
|
43232
|
-
getClient() {
|
|
43233
|
-
return this._client ;
|
|
43234
|
-
}
|
|
43235
|
-
|
|
43236
|
-
/**
|
|
43237
|
-
* @inheritDoc
|
|
43238
|
-
*/
|
|
43239
|
-
lastEventId() {
|
|
43240
|
-
return this._lastEventId;
|
|
43241
|
-
}
|
|
43242
|
-
|
|
43243
|
-
/**
|
|
43244
|
-
* @inheritDoc
|
|
43245
|
-
*/
|
|
43246
|
-
addScopeListener(callback) {
|
|
43247
|
-
this._scopeListeners.push(callback);
|
|
43248
|
-
}
|
|
43249
|
-
|
|
43250
|
-
/**
|
|
43251
|
-
* @inheritDoc
|
|
43252
|
-
*/
|
|
43253
|
-
addEventProcessor(callback) {
|
|
43254
|
-
this._eventProcessors.push(callback);
|
|
43255
|
-
return this;
|
|
43256
|
-
}
|
|
43257
|
-
|
|
43258
|
-
/**
|
|
43259
|
-
* @inheritDoc
|
|
43260
|
-
*/
|
|
43261
|
-
setUser(user) {
|
|
43262
|
-
// If null is passed we want to unset everything, but still define keys,
|
|
43263
|
-
// so that later down in the pipeline any existing values are cleared.
|
|
43264
|
-
this._user = user || {
|
|
43265
|
-
email: undefined,
|
|
43266
|
-
id: undefined,
|
|
43267
|
-
ip_address: undefined,
|
|
43268
|
-
username: undefined,
|
|
43269
|
-
};
|
|
43270
|
-
|
|
43271
|
-
if (this._session) {
|
|
43272
|
-
updateSession(this._session, { user });
|
|
43273
|
-
}
|
|
43274
|
-
|
|
43275
|
-
this._notifyScopeListeners();
|
|
43276
|
-
return this;
|
|
43277
|
-
}
|
|
43278
|
-
|
|
43279
|
-
/**
|
|
43280
|
-
* @inheritDoc
|
|
43281
|
-
*/
|
|
43282
|
-
getUser() {
|
|
43283
|
-
return this._user;
|
|
43284
|
-
}
|
|
43285
|
-
|
|
43286
|
-
/**
|
|
43287
|
-
* @inheritDoc
|
|
43288
|
-
*/
|
|
43289
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
43290
|
-
getRequestSession() {
|
|
43291
|
-
return this._requestSession;
|
|
43292
|
-
}
|
|
43293
|
-
|
|
43294
|
-
/**
|
|
43295
|
-
* @inheritDoc
|
|
43296
|
-
*/
|
|
43297
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
43298
|
-
setRequestSession(requestSession) {
|
|
43299
|
-
this._requestSession = requestSession;
|
|
43300
|
-
return this;
|
|
43301
|
-
}
|
|
43302
|
-
|
|
43303
|
-
/**
|
|
43304
|
-
* @inheritDoc
|
|
43305
|
-
*/
|
|
43306
|
-
setTags(tags) {
|
|
43307
|
-
this._tags = {
|
|
43308
|
-
...this._tags,
|
|
43309
|
-
...tags,
|
|
43310
|
-
};
|
|
43311
|
-
this._notifyScopeListeners();
|
|
43312
|
-
return this;
|
|
43313
|
-
}
|
|
43314
|
-
|
|
43315
|
-
/**
|
|
43316
|
-
* @inheritDoc
|
|
43317
|
-
*/
|
|
43318
|
-
setTag(key, value) {
|
|
43319
|
-
this._tags = { ...this._tags, [key]: value };
|
|
43320
|
-
this._notifyScopeListeners();
|
|
43321
|
-
return this;
|
|
43322
|
-
}
|
|
43323
|
-
|
|
43324
|
-
/**
|
|
43325
|
-
* @inheritDoc
|
|
43326
|
-
*/
|
|
43327
|
-
setExtras(extras) {
|
|
43328
|
-
this._extra = {
|
|
43329
|
-
...this._extra,
|
|
43330
|
-
...extras,
|
|
43331
|
-
};
|
|
43332
|
-
this._notifyScopeListeners();
|
|
43333
|
-
return this;
|
|
43334
|
-
}
|
|
43335
|
-
|
|
43336
|
-
/**
|
|
43337
|
-
* @inheritDoc
|
|
43338
|
-
*/
|
|
43339
|
-
setExtra(key, extra) {
|
|
43340
|
-
this._extra = { ...this._extra, [key]: extra };
|
|
43341
|
-
this._notifyScopeListeners();
|
|
43342
|
-
return this;
|
|
43343
|
-
}
|
|
43344
|
-
|
|
43345
|
-
/**
|
|
43346
|
-
* @inheritDoc
|
|
43347
|
-
*/
|
|
43348
|
-
setFingerprint(fingerprint) {
|
|
43349
|
-
this._fingerprint = fingerprint;
|
|
43350
|
-
this._notifyScopeListeners();
|
|
43351
|
-
return this;
|
|
43352
|
-
}
|
|
43353
|
-
|
|
43354
|
-
/**
|
|
43355
|
-
* @inheritDoc
|
|
43356
|
-
*/
|
|
43357
|
-
setLevel(level) {
|
|
43358
|
-
this._level = level;
|
|
43359
|
-
this._notifyScopeListeners();
|
|
43360
|
-
return this;
|
|
43361
|
-
}
|
|
43362
|
-
|
|
43363
|
-
/**
|
|
43364
|
-
* @inheritDoc
|
|
43365
|
-
*/
|
|
43366
|
-
setTransactionName(name) {
|
|
43367
|
-
this._transactionName = name;
|
|
43368
|
-
this._notifyScopeListeners();
|
|
43369
|
-
return this;
|
|
43370
|
-
}
|
|
43371
|
-
|
|
43372
|
-
/**
|
|
43373
|
-
* @inheritDoc
|
|
43374
|
-
*/
|
|
43375
|
-
setContext(key, context) {
|
|
43376
|
-
if (context === null) {
|
|
43377
|
-
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
43378
|
-
delete this._contexts[key];
|
|
43379
|
-
} else {
|
|
43380
|
-
this._contexts[key] = context;
|
|
43381
|
-
}
|
|
43382
|
-
|
|
43383
|
-
this._notifyScopeListeners();
|
|
43384
|
-
return this;
|
|
43385
|
-
}
|
|
43386
|
-
|
|
43387
|
-
/**
|
|
43388
|
-
* @inheritDoc
|
|
43389
|
-
*/
|
|
43390
|
-
setSession(session) {
|
|
43391
|
-
if (!session) {
|
|
43392
|
-
delete this._session;
|
|
43393
|
-
} else {
|
|
43394
|
-
this._session = session;
|
|
43395
|
-
}
|
|
43396
|
-
this._notifyScopeListeners();
|
|
43397
|
-
return this;
|
|
43398
|
-
}
|
|
43399
|
-
|
|
43400
|
-
/**
|
|
43401
|
-
* @inheritDoc
|
|
43402
|
-
*/
|
|
43403
|
-
getSession() {
|
|
43404
|
-
return this._session;
|
|
43405
|
-
}
|
|
43406
|
-
|
|
43407
|
-
/**
|
|
43408
|
-
* @inheritDoc
|
|
43409
|
-
*/
|
|
43410
|
-
update(captureContext) {
|
|
43411
|
-
if (!captureContext) {
|
|
43412
|
-
return this;
|
|
43413
|
-
}
|
|
43414
|
-
|
|
43415
|
-
const scopeToMerge = typeof captureContext === 'function' ? captureContext(this) : captureContext;
|
|
43416
|
-
|
|
43417
|
-
const [scopeInstance, requestSession] =
|
|
43418
|
-
scopeToMerge instanceof Scope
|
|
43419
|
-
? // eslint-disable-next-line deprecation/deprecation
|
|
43420
|
-
[scopeToMerge.getScopeData(), scopeToMerge.getRequestSession()]
|
|
43421
|
-
: isPlainObject(scopeToMerge)
|
|
43422
|
-
? [captureContext , (captureContext ).requestSession]
|
|
43423
|
-
: [];
|
|
43424
|
-
|
|
43425
|
-
const { tags, extra, user, contexts, level, fingerprint = [], propagationContext } = scopeInstance || {};
|
|
43426
|
-
|
|
43427
|
-
this._tags = { ...this._tags, ...tags };
|
|
43428
|
-
this._extra = { ...this._extra, ...extra };
|
|
43429
|
-
this._contexts = { ...this._contexts, ...contexts };
|
|
43430
|
-
|
|
43431
|
-
if (user && Object.keys(user).length) {
|
|
43432
|
-
this._user = user;
|
|
43433
|
-
}
|
|
43434
|
-
|
|
43435
|
-
if (level) {
|
|
43436
|
-
this._level = level;
|
|
43437
|
-
}
|
|
43438
|
-
|
|
43439
|
-
if (fingerprint.length) {
|
|
43440
|
-
this._fingerprint = fingerprint;
|
|
43441
|
-
}
|
|
43442
|
-
|
|
43443
|
-
if (propagationContext) {
|
|
43444
|
-
this._propagationContext = propagationContext;
|
|
43445
|
-
}
|
|
43446
|
-
|
|
43447
|
-
if (requestSession) {
|
|
43448
|
-
this._requestSession = requestSession;
|
|
43449
|
-
}
|
|
43450
|
-
|
|
43451
|
-
return this;
|
|
43452
|
-
}
|
|
43453
|
-
|
|
43454
|
-
/**
|
|
43455
|
-
* @inheritDoc
|
|
43456
|
-
*/
|
|
43457
|
-
clear() {
|
|
43458
|
-
// client is not cleared here on purpose!
|
|
43459
|
-
this._breadcrumbs = [];
|
|
43460
|
-
this._tags = {};
|
|
43461
|
-
this._extra = {};
|
|
43462
|
-
this._user = {};
|
|
43463
|
-
this._contexts = {};
|
|
43464
|
-
this._level = undefined;
|
|
43465
|
-
this._transactionName = undefined;
|
|
43466
|
-
this._fingerprint = undefined;
|
|
43467
|
-
this._requestSession = undefined;
|
|
43468
|
-
this._session = undefined;
|
|
43469
|
-
_setSpanForScope(this, undefined);
|
|
43470
|
-
this._attachments = [];
|
|
43471
|
-
this.setPropagationContext({ traceId: generateTraceId() });
|
|
43472
|
-
|
|
43473
|
-
this._notifyScopeListeners();
|
|
43474
|
-
return this;
|
|
43475
|
-
}
|
|
43476
|
-
|
|
43477
|
-
/**
|
|
43478
|
-
* @inheritDoc
|
|
43479
|
-
*/
|
|
43480
|
-
addBreadcrumb(breadcrumb, maxBreadcrumbs) {
|
|
43481
|
-
const maxCrumbs = typeof maxBreadcrumbs === 'number' ? maxBreadcrumbs : DEFAULT_MAX_BREADCRUMBS;
|
|
43482
|
-
|
|
43483
|
-
// No data has been changed, so don't notify scope listeners
|
|
43484
|
-
if (maxCrumbs <= 0) {
|
|
43485
|
-
return this;
|
|
43486
|
-
}
|
|
43487
|
-
|
|
43488
|
-
const mergedBreadcrumb = {
|
|
43489
|
-
timestamp: dateTimestampInSeconds(),
|
|
43490
|
-
...breadcrumb,
|
|
43491
|
-
};
|
|
43492
|
-
|
|
43493
|
-
const breadcrumbs = this._breadcrumbs;
|
|
43494
|
-
breadcrumbs.push(mergedBreadcrumb);
|
|
43495
|
-
this._breadcrumbs = breadcrumbs.length > maxCrumbs ? breadcrumbs.slice(-maxCrumbs) : breadcrumbs;
|
|
43496
|
-
|
|
43497
|
-
this._notifyScopeListeners();
|
|
43498
|
-
|
|
43499
|
-
return this;
|
|
43500
|
-
}
|
|
43501
|
-
|
|
43502
|
-
/**
|
|
43503
|
-
* @inheritDoc
|
|
43504
|
-
*/
|
|
43505
|
-
getLastBreadcrumb() {
|
|
43506
|
-
return this._breadcrumbs[this._breadcrumbs.length - 1];
|
|
43507
|
-
}
|
|
43508
|
-
|
|
43509
|
-
/**
|
|
43510
|
-
* @inheritDoc
|
|
43511
|
-
*/
|
|
43512
|
-
clearBreadcrumbs() {
|
|
43513
|
-
this._breadcrumbs = [];
|
|
43514
|
-
this._notifyScopeListeners();
|
|
43515
|
-
return this;
|
|
43516
|
-
}
|
|
43517
|
-
|
|
43518
|
-
/**
|
|
43519
|
-
* @inheritDoc
|
|
43520
|
-
*/
|
|
43521
|
-
addAttachment(attachment) {
|
|
43522
|
-
this._attachments.push(attachment);
|
|
43523
|
-
return this;
|
|
43524
|
-
}
|
|
43525
|
-
|
|
43526
|
-
/**
|
|
43527
|
-
* @inheritDoc
|
|
43528
|
-
*/
|
|
43529
|
-
clearAttachments() {
|
|
43530
|
-
this._attachments = [];
|
|
43531
|
-
return this;
|
|
43532
|
-
}
|
|
43533
|
-
|
|
43534
|
-
/** @inheritDoc */
|
|
43535
|
-
getScopeData() {
|
|
43536
|
-
return {
|
|
43537
|
-
breadcrumbs: this._breadcrumbs,
|
|
43538
|
-
attachments: this._attachments,
|
|
43539
|
-
contexts: this._contexts,
|
|
43540
|
-
tags: this._tags,
|
|
43541
|
-
extra: this._extra,
|
|
43542
|
-
user: this._user,
|
|
43543
|
-
level: this._level,
|
|
43544
|
-
fingerprint: this._fingerprint || [],
|
|
43545
|
-
eventProcessors: this._eventProcessors,
|
|
43546
|
-
propagationContext: this._propagationContext,
|
|
43547
|
-
sdkProcessingMetadata: this._sdkProcessingMetadata,
|
|
43548
|
-
transactionName: this._transactionName,
|
|
43549
|
-
span: _getSpanForScope(this),
|
|
43550
|
-
};
|
|
43551
|
-
}
|
|
43552
|
-
|
|
43553
|
-
/**
|
|
43554
|
-
* @inheritDoc
|
|
43555
|
-
*/
|
|
43556
|
-
setSDKProcessingMetadata(newData) {
|
|
43557
|
-
this._sdkProcessingMetadata = merge(this._sdkProcessingMetadata, newData, 2);
|
|
43558
|
-
return this;
|
|
43559
|
-
}
|
|
43560
|
-
|
|
43561
|
-
/**
|
|
43562
|
-
* @inheritDoc
|
|
43563
|
-
*/
|
|
43564
|
-
setPropagationContext(
|
|
43565
|
-
context,
|
|
43566
|
-
) {
|
|
43567
|
-
this._propagationContext = {
|
|
43568
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
43569
|
-
spanId: generateSpanId(),
|
|
43570
|
-
...context,
|
|
43571
|
-
};
|
|
43572
|
-
return this;
|
|
43573
|
-
}
|
|
43574
|
-
|
|
43575
|
-
/**
|
|
43576
|
-
* @inheritDoc
|
|
43577
|
-
*/
|
|
43578
|
-
getPropagationContext() {
|
|
43579
|
-
return this._propagationContext;
|
|
43580
|
-
}
|
|
43581
|
-
|
|
43582
|
-
/**
|
|
43583
|
-
* @inheritDoc
|
|
43584
|
-
*/
|
|
43585
|
-
captureException(exception, hint) {
|
|
43586
|
-
const eventId = hint && hint.event_id ? hint.event_id : uuid4();
|
|
43587
|
-
|
|
43588
|
-
if (!this._client) {
|
|
43589
|
-
logger.warn('No client configured on scope - will not capture exception!');
|
|
43590
|
-
return eventId;
|
|
43591
|
-
}
|
|
43592
|
-
|
|
43593
|
-
const syntheticException = new Error('Sentry syntheticException');
|
|
43594
|
-
|
|
43595
|
-
this._client.captureException(
|
|
43596
|
-
exception,
|
|
43597
|
-
{
|
|
43598
|
-
originalException: exception,
|
|
43599
|
-
syntheticException,
|
|
43600
|
-
...hint,
|
|
43601
|
-
event_id: eventId,
|
|
43602
|
-
},
|
|
43603
|
-
this,
|
|
43604
|
-
);
|
|
43605
|
-
|
|
43606
|
-
return eventId;
|
|
43607
|
-
}
|
|
43608
|
-
|
|
43609
|
-
/**
|
|
43610
|
-
* @inheritDoc
|
|
43611
|
-
*/
|
|
43612
|
-
captureMessage(message, level, hint) {
|
|
43613
|
-
const eventId = hint && hint.event_id ? hint.event_id : uuid4();
|
|
43614
|
-
|
|
43615
|
-
if (!this._client) {
|
|
43616
|
-
logger.warn('No client configured on scope - will not capture message!');
|
|
43617
|
-
return eventId;
|
|
43618
|
-
}
|
|
43619
|
-
|
|
43620
|
-
const syntheticException = new Error(message);
|
|
43621
|
-
|
|
43622
|
-
this._client.captureMessage(
|
|
43623
|
-
message,
|
|
43624
|
-
level,
|
|
43625
|
-
{
|
|
43626
|
-
originalException: message,
|
|
43627
|
-
syntheticException,
|
|
43628
|
-
...hint,
|
|
43629
|
-
event_id: eventId,
|
|
43630
|
-
},
|
|
43631
|
-
this,
|
|
43632
|
-
);
|
|
43633
|
-
|
|
43634
|
-
return eventId;
|
|
43635
|
-
}
|
|
43636
|
-
|
|
43637
|
-
/**
|
|
43638
|
-
* @inheritDoc
|
|
43639
|
-
*/
|
|
43640
|
-
captureEvent(event, hint) {
|
|
43641
|
-
const eventId = hint && hint.event_id ? hint.event_id : uuid4();
|
|
43642
|
-
|
|
43643
|
-
if (!this._client) {
|
|
43644
|
-
logger.warn('No client configured on scope - will not capture event!');
|
|
43645
|
-
return eventId;
|
|
43646
|
-
}
|
|
43647
|
-
|
|
43648
|
-
this._client.captureEvent(event, { ...hint, event_id: eventId }, this);
|
|
43649
|
-
|
|
43650
|
-
return eventId;
|
|
43651
|
-
}
|
|
43652
|
-
|
|
43653
|
-
/**
|
|
43654
|
-
* This will be called on every set call.
|
|
43655
|
-
*/
|
|
43656
|
-
_notifyScopeListeners() {
|
|
43657
|
-
// We need this check for this._notifyingListeners to be able to work on scope during updates
|
|
43658
|
-
// If this check is not here we'll produce endless recursion when something is done with the scope
|
|
43659
|
-
// during the callback.
|
|
43660
|
-
if (!this._notifyingListeners) {
|
|
43661
|
-
this._notifyingListeners = true;
|
|
43662
|
-
this._scopeListeners.forEach(callback => {
|
|
43663
|
-
callback(this);
|
|
43664
|
-
});
|
|
43665
|
-
this._notifyingListeners = false;
|
|
43666
|
-
}
|
|
43667
|
-
}
|
|
43668
|
-
}
|
|
43669
|
-
|
|
43670
|
-
/**
|
|
43671
|
-
* Holds additional event information.
|
|
43672
|
-
*/
|
|
43673
|
-
const Scope = ScopeClass;
|
|
43674
|
-
|
|
43675
|
-
/** Get the default current scope. */
|
|
43676
|
-
function getDefaultCurrentScope() {
|
|
43677
|
-
return getGlobalSingleton('defaultCurrentScope', () => new Scope());
|
|
43678
|
-
}
|
|
43679
|
-
|
|
43680
|
-
/** Get the default isolation scope. */
|
|
43681
|
-
function getDefaultIsolationScope() {
|
|
43682
|
-
return getGlobalSingleton('defaultIsolationScope', () => new Scope());
|
|
43683
|
-
}
|
|
43684
|
-
|
|
43685
|
-
/**
|
|
43686
|
-
* This is an object that holds a stack of scopes.
|
|
43687
|
-
*/
|
|
43688
|
-
class AsyncContextStack {
|
|
43689
|
-
|
|
43690
|
-
constructor(scope, isolationScope) {
|
|
43691
|
-
let assignedScope;
|
|
43692
|
-
if (!scope) {
|
|
43693
|
-
assignedScope = new Scope();
|
|
43694
|
-
} else {
|
|
43695
|
-
assignedScope = scope;
|
|
43696
|
-
}
|
|
43697
|
-
|
|
43698
|
-
let assignedIsolationScope;
|
|
43699
|
-
if (!isolationScope) {
|
|
43700
|
-
assignedIsolationScope = new Scope();
|
|
43701
|
-
} else {
|
|
43702
|
-
assignedIsolationScope = isolationScope;
|
|
43703
|
-
}
|
|
43704
|
-
|
|
43705
|
-
// scope stack for domains or the process
|
|
43706
|
-
this._stack = [{ scope: assignedScope }];
|
|
43707
|
-
this._isolationScope = assignedIsolationScope;
|
|
43708
|
-
}
|
|
43709
|
-
|
|
43710
|
-
/**
|
|
43711
|
-
* Fork a scope for the stack.
|
|
43712
|
-
*/
|
|
43713
|
-
withScope(callback) {
|
|
43714
|
-
const scope = this._pushScope();
|
|
43715
|
-
|
|
43716
|
-
let maybePromiseResult;
|
|
43717
|
-
try {
|
|
43718
|
-
maybePromiseResult = callback(scope);
|
|
43719
|
-
} catch (e) {
|
|
43720
|
-
this._popScope();
|
|
43721
|
-
throw e;
|
|
43722
|
-
}
|
|
43723
|
-
|
|
43724
|
-
if (isThenable(maybePromiseResult)) {
|
|
43725
|
-
// @ts-expect-error - isThenable returns the wrong type
|
|
43726
|
-
return maybePromiseResult.then(
|
|
43727
|
-
res => {
|
|
43728
|
-
this._popScope();
|
|
43729
|
-
return res;
|
|
43730
|
-
},
|
|
43731
|
-
e => {
|
|
43732
|
-
this._popScope();
|
|
43733
|
-
throw e;
|
|
43734
|
-
},
|
|
43735
|
-
);
|
|
43736
|
-
}
|
|
43737
|
-
|
|
43738
|
-
this._popScope();
|
|
43739
|
-
return maybePromiseResult;
|
|
43740
|
-
}
|
|
43741
|
-
|
|
43742
|
-
/**
|
|
43743
|
-
* Get the client of the stack.
|
|
43744
|
-
*/
|
|
43745
|
-
getClient() {
|
|
43746
|
-
return this.getStackTop().client ;
|
|
43747
|
-
}
|
|
43748
|
-
|
|
43749
|
-
/**
|
|
43750
|
-
* Returns the scope of the top stack.
|
|
43751
|
-
*/
|
|
43752
|
-
getScope() {
|
|
43753
|
-
return this.getStackTop().scope;
|
|
43754
|
-
}
|
|
43755
|
-
|
|
43756
|
-
/**
|
|
43757
|
-
* Get the isolation scope for the stack.
|
|
43758
|
-
*/
|
|
43759
|
-
getIsolationScope() {
|
|
43760
|
-
return this._isolationScope;
|
|
43761
|
-
}
|
|
43762
|
-
|
|
43763
|
-
/**
|
|
43764
|
-
* Returns the topmost scope layer in the order domain > local > process.
|
|
43765
|
-
*/
|
|
43766
|
-
getStackTop() {
|
|
43767
|
-
return this._stack[this._stack.length - 1] ;
|
|
43768
|
-
}
|
|
43769
|
-
|
|
43770
|
-
/**
|
|
43771
|
-
* Push a scope to the stack.
|
|
43772
|
-
*/
|
|
43773
|
-
_pushScope() {
|
|
43774
|
-
// We want to clone the content of prev scope
|
|
43775
|
-
const scope = this.getScope().clone();
|
|
43776
|
-
this._stack.push({
|
|
43777
|
-
client: this.getClient(),
|
|
43778
|
-
scope,
|
|
43779
|
-
});
|
|
43780
|
-
return scope;
|
|
43781
|
-
}
|
|
43782
|
-
|
|
43783
|
-
/**
|
|
43784
|
-
* Pop a scope from the stack.
|
|
43785
|
-
*/
|
|
43786
|
-
_popScope() {
|
|
43787
|
-
if (this._stack.length <= 1) return false;
|
|
43788
|
-
return !!this._stack.pop();
|
|
43789
|
-
}
|
|
43790
|
-
}
|
|
43791
|
-
|
|
43792
|
-
/**
|
|
43793
|
-
* Get the global async context stack.
|
|
43794
|
-
* This will be removed during the v8 cycle and is only here to make migration easier.
|
|
43795
|
-
*/
|
|
43796
|
-
function getAsyncContextStack() {
|
|
43797
|
-
const registry = getMainCarrier();
|
|
43798
|
-
const sentry = getSentryCarrier(registry);
|
|
43799
|
-
|
|
43800
|
-
return (sentry.stack = sentry.stack || new AsyncContextStack(getDefaultCurrentScope(), getDefaultIsolationScope()));
|
|
43801
|
-
}
|
|
43802
|
-
|
|
43803
|
-
function withScope(callback) {
|
|
43804
|
-
return getAsyncContextStack().withScope(callback);
|
|
43805
|
-
}
|
|
43806
|
-
|
|
43807
|
-
function withSetScope(scope, callback) {
|
|
43808
|
-
const stack = getAsyncContextStack() ;
|
|
43809
|
-
return stack.withScope(() => {
|
|
43810
|
-
stack.getStackTop().scope = scope;
|
|
43811
|
-
return callback(scope);
|
|
43812
|
-
});
|
|
43813
|
-
}
|
|
43814
|
-
|
|
43815
|
-
function withIsolationScope(callback) {
|
|
43816
|
-
return getAsyncContextStack().withScope(() => {
|
|
43817
|
-
return callback(getAsyncContextStack().getIsolationScope());
|
|
43818
|
-
});
|
|
43819
|
-
}
|
|
43820
|
-
|
|
43821
|
-
/**
|
|
43822
|
-
* Get the stack-based async context strategy.
|
|
43823
|
-
*/
|
|
43824
|
-
function getStackAsyncContextStrategy() {
|
|
43825
|
-
return {
|
|
43826
|
-
withIsolationScope,
|
|
43827
|
-
withScope,
|
|
43828
|
-
withSetScope,
|
|
43829
|
-
withSetIsolationScope: (_isolationScope, callback) => {
|
|
43830
|
-
return withIsolationScope(callback);
|
|
43831
|
-
},
|
|
43832
|
-
getCurrentScope: () => getAsyncContextStack().getScope(),
|
|
43833
|
-
getIsolationScope: () => getAsyncContextStack().getIsolationScope(),
|
|
43834
|
-
};
|
|
43835
|
-
}
|
|
43836
|
-
|
|
43837
|
-
/**
|
|
43838
|
-
* Get the current async context strategy.
|
|
43839
|
-
* If none has been setup, the default will be used.
|
|
43840
|
-
*/
|
|
43841
|
-
function getAsyncContextStrategy(carrier) {
|
|
43842
|
-
const sentry = getSentryCarrier(carrier);
|
|
43843
|
-
|
|
43844
|
-
if (sentry.acs) {
|
|
43845
|
-
return sentry.acs;
|
|
43846
|
-
}
|
|
43847
|
-
|
|
43848
|
-
// Otherwise, use the default one (stack)
|
|
43849
|
-
return getStackAsyncContextStrategy();
|
|
43850
|
-
}
|
|
43851
|
-
|
|
43852
|
-
/**
|
|
43853
|
-
* Get the currently active scope.
|
|
43854
|
-
*/
|
|
43855
|
-
function getCurrentScope() {
|
|
43856
|
-
const carrier = getMainCarrier();
|
|
43857
|
-
const acs = getAsyncContextStrategy(carrier);
|
|
43858
|
-
return acs.getCurrentScope();
|
|
43859
|
-
}
|
|
43860
|
-
|
|
43861
|
-
/**
|
|
43862
|
-
* Get the currently active isolation scope.
|
|
43863
|
-
* The isolation scope is active for the current execution context.
|
|
43864
|
-
*/
|
|
43865
|
-
function getIsolationScope() {
|
|
43866
|
-
const carrier = getMainCarrier();
|
|
43867
|
-
const acs = getAsyncContextStrategy(carrier);
|
|
43868
|
-
return acs.getIsolationScope();
|
|
43869
|
-
}
|
|
43870
|
-
|
|
43871
|
-
/**
|
|
43872
|
-
* Get the currently active client.
|
|
43873
|
-
*/
|
|
43874
|
-
function getClient() {
|
|
43875
|
-
return getCurrentScope().getClient();
|
|
43876
|
-
}
|
|
43877
|
-
|
|
43878
|
-
/**
|
|
43879
|
-
* Default maximum number of breadcrumbs added to an event. Can be overwritten
|
|
43880
|
-
* with {@link Options.maxBreadcrumbs}.
|
|
43881
|
-
*/
|
|
43882
|
-
const DEFAULT_BREADCRUMBS = 100;
|
|
43883
|
-
|
|
43884
|
-
/**
|
|
43885
|
-
* Records a new breadcrumb which will be attached to future events.
|
|
43886
|
-
*
|
|
43887
|
-
* Breadcrumbs will be added to subsequent events to provide more context on
|
|
43888
|
-
* user's actions prior to an error or crash.
|
|
43889
|
-
*/
|
|
43890
|
-
function addBreadcrumb(breadcrumb, hint) {
|
|
43891
|
-
const client = getClient();
|
|
43892
|
-
const isolationScope = getIsolationScope();
|
|
43893
|
-
|
|
43894
|
-
if (!client) return;
|
|
43895
|
-
|
|
43896
|
-
const { beforeBreadcrumb = null, maxBreadcrumbs = DEFAULT_BREADCRUMBS } = client.getOptions();
|
|
43897
|
-
|
|
43898
|
-
if (maxBreadcrumbs <= 0) return;
|
|
43899
|
-
|
|
43900
|
-
const timestamp = dateTimestampInSeconds();
|
|
43901
|
-
const mergedBreadcrumb = { timestamp, ...breadcrumb };
|
|
43902
|
-
const finalBreadcrumb = beforeBreadcrumb
|
|
43903
|
-
? (consoleSandbox(() => beforeBreadcrumb(mergedBreadcrumb, hint)) )
|
|
43904
|
-
: mergedBreadcrumb;
|
|
43905
|
-
|
|
43906
|
-
if (finalBreadcrumb === null) return;
|
|
43907
|
-
|
|
43908
|
-
if (client.emit) {
|
|
43909
|
-
client.emit('beforeAddBreadcrumb', finalBreadcrumb, hint);
|
|
43910
|
-
}
|
|
43911
|
-
|
|
43912
|
-
isolationScope.addBreadcrumb(finalBreadcrumb, maxBreadcrumbs);
|
|
43913
|
-
}
|
|
43914
|
-
|
|
43915
|
-
/**
|
|
43916
|
-
* @beta
|
|
43917
|
-
*/
|
|
43918
|
-
class SentryTracer {
|
|
43919
|
-
client;
|
|
43920
|
-
constructor(client) {
|
|
43921
|
-
this.client = client;
|
|
43922
|
-
}
|
|
43923
|
-
reportError(e) {
|
|
43924
|
-
this.client.captureException(e);
|
|
43925
|
-
}
|
|
43926
|
-
trace(message, data) {
|
|
43927
|
-
addBreadcrumb({
|
|
43928
|
-
type: "default",
|
|
43929
|
-
level: "info",
|
|
43930
|
-
message,
|
|
43931
|
-
data,
|
|
43932
|
-
});
|
|
43933
|
-
}
|
|
43934
|
-
}
|
|
43935
|
-
|
|
43936
|
-
var version$1 = "2.0.2";
|
|
42648
|
+
var version$1 = "2.1.1";
|
|
43937
42649
|
|
|
43938
42650
|
var packages = {
|
|
43939
42651
|
"": {
|
|
43940
42652
|
name: "@gcorevideo/player",
|
|
43941
|
-
version: "2.
|
|
42653
|
+
version: "2.1.1",
|
|
43942
42654
|
license: "Apache-2.0",
|
|
43943
42655
|
dependencies: {
|
|
43944
42656
|
"@clappr/core": "^0.11.3",
|