rx-player 3.30.1-dev.2023032800 → 3.31.0-dev.2023052200
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/CHANGELOG.md +14 -2
- package/CONTRIBUTING.md +48 -168
- package/FILES.md +40 -92
- package/VERSION +1 -1
- package/dist/_esm5.processed/compat/browser_detection.d.ts +3 -1
- package/dist/_esm5.processed/compat/browser_detection.js +7 -2
- package/dist/_esm5.processed/compat/has_issues_with_high_media_source_duration.d.ts +21 -0
- package/dist/_esm5.processed/compat/has_issues_with_high_media_source_duration.js +26 -0
- package/dist/_esm5.processed/core/adaptive/adaptive_representation_selector.js +1 -2
- package/dist/_esm5.processed/core/adaptive/buffer_based_chooser.d.ts +18 -1
- package/dist/_esm5.processed/core/adaptive/buffer_based_chooser.js +105 -24
- package/dist/_esm5.processed/core/adaptive/guess_based_chooser.js +6 -6
- package/dist/_esm5.processed/core/adaptive/utils/representation_score_calculator.d.ts +19 -1
- package/dist/_esm5.processed/core/adaptive/utils/representation_score_calculator.js +1 -1
- package/dist/_esm5.processed/core/api/debug/render.js +1 -1
- package/dist/_esm5.processed/core/api/public_api.js +2 -2
- package/dist/_esm5.processed/core/api/tracks_management/media_element_track_choice_manager.js +10 -1
- package/dist/_esm5.processed/core/api/tracks_management/track_choice_manager.js +20 -117
- package/dist/_esm5.processed/core/init/media_source_content_initializer.js +28 -3
- package/dist/_esm5.processed/core/init/utils/media_source_duration_updater.d.ts +2 -2
- package/dist/_esm5.processed/core/init/utils/media_source_duration_updater.js +29 -18
- package/dist/_esm5.processed/core/segment_buffers/index.d.ts +2 -2
- package/dist/_esm5.processed/core/stream/adaptation/utils/create_representation_estimator.js +1 -1
- package/dist/_esm5.processed/core/stream/period/period_stream.js +1 -1
- package/dist/_esm5.processed/core/stream/representation/utils/append_segment_to_buffer.d.ts +4 -2
- package/dist/_esm5.processed/core/stream/representation/utils/append_segment_to_buffer.js +2 -2
- package/dist/_esm5.processed/core/stream/representation/utils/push_init_segment.js +6 -2
- package/dist/_esm5.processed/errors/index.d.ts +2 -2
- package/dist/_esm5.processed/errors/media_error.d.ts +23 -1
- package/dist/_esm5.processed/errors/media_error.js +18 -5
- package/dist/_esm5.processed/manifest/adaptation.d.ts +17 -2
- package/dist/_esm5.processed/manifest/adaptation.js +67 -1
- package/dist/_esm5.processed/manifest/manifest.d.ts +1 -1
- package/dist/_esm5.processed/manifest/manifest.js +3 -3
- package/dist/_esm5.processed/manifest/period.js +1 -1
- package/dist/_esm5.processed/manifest/representation.d.ts +11 -1
- package/dist/_esm5.processed/manifest/representation.js +16 -0
- package/dist/_esm5.processed/parsers/manifest/dash/js-parser/parse_from_document.d.ts +1 -1
- package/dist/_esm5.processed/parsers/manifest/dash/js-parser/parse_from_document.js +1 -1
- package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/dash-wasm-parser.js +1 -0
- package/dist/_esm5.processed/public_types.d.ts +6 -5
- package/dist/_esm5.processed/transports/smooth/isobmff/create_boxes.d.ts +4 -6
- package/dist/_esm5.processed/transports/smooth/isobmff/create_boxes.js +4 -6
- package/dist/rx-player.js +3086 -3024
- package/dist/rx-player.min.js +1 -1
- package/package.json +25 -26
- package/sonar-project.properties +1 -1
- package/src/compat/browser_detection.ts +7 -1
- package/src/compat/has_issues_with_high_media_source_duration.ts +27 -0
- package/src/core/adaptive/__tests__/buffer_based_chooser.test.ts +147 -48
- package/src/core/adaptive/adaptive_representation_selector.ts +1 -2
- package/src/core/adaptive/buffer_based_chooser.ts +143 -25
- package/src/core/adaptive/guess_based_chooser.ts +9 -8
- package/src/core/adaptive/utils/representation_score_calculator.ts +22 -2
- package/src/core/api/debug/render.ts +1 -1
- package/src/core/api/public_api.ts +2 -2
- package/src/core/api/tracks_management/media_element_track_choice_manager.ts +17 -8
- package/src/core/api/tracks_management/track_choice_manager.ts +20 -132
- package/src/core/init/media_source_content_initializer.ts +32 -4
- package/src/core/init/utils/media_source_duration_updater.ts +31 -19
- package/src/core/segment_buffers/index.ts +2 -0
- package/src/core/stream/adaptation/utils/create_representation_estimator.ts +2 -1
- package/src/core/stream/period/period_stream.ts +2 -1
- package/src/core/stream/representation/utils/append_segment_to_buffer.ts +8 -3
- package/src/core/stream/representation/utils/push_init_segment.ts +7 -1
- package/src/errors/__tests__/media_error.test.ts +6 -6
- package/src/errors/index.ts +4 -1
- package/src/errors/media_error.ts +67 -1
- package/src/manifest/__tests__/period.test.ts +90 -45
- package/src/manifest/adaptation.ts +77 -2
- package/src/manifest/manifest.ts +5 -3
- package/src/manifest/period.ts +2 -1
- package/src/manifest/representation.ts +23 -1
- package/src/parsers/manifest/dash/js-parser/parse_from_document.ts +1 -1
- package/src/parsers/manifest/dash/wasm-parser/ts/dash-wasm-parser.ts +1 -0
- package/src/parsers/texttracks/ttml/parse_ttml.ts +1 -1
- package/src/public_types.ts +8 -3
- package/src/transports/smooth/isobmff/create_boxes.ts +4 -6
- package/src/typings/globals.d.ts +21 -21
- package/scripts/doc-generator/construct_table_of_contents.js +0 -76
- package/scripts/doc-generator/convert_MD_to_HMTL.js +0 -26
- package/scripts/doc-generator/create_documentation.js +0 -331
- package/scripts/doc-generator/create_documentation_page.js +0 -209
- package/scripts/doc-generator/create_page.js +0 -210
- package/scripts/doc-generator/generate_header_html.js +0 -147
- package/scripts/doc-generator/generate_page_html.js +0 -115
- package/scripts/doc-generator/generate_page_list_html.js +0 -92
- package/scripts/doc-generator/generate_sidebar_html.js +0 -85
- package/scripts/doc-generator/get_search_data_for_content.js +0 -137
- package/scripts/doc-generator/index.js +0 -34
- package/scripts/doc-generator/parse_doc_configs.js +0 -327
- package/scripts/doc-generator/scripts/lunr.js +0 -10
- package/scripts/doc-generator/scripts/script.js +0 -451
- package/scripts/doc-generator/styles/code.css +0 -99
- package/scripts/doc-generator/styles/style.css +0 -835
- package/scripts/doc-generator/utils.js +0 -74
|
@@ -379,7 +379,32 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
|
|
|
379
379
|
function handleStreamOrchestratorCallbacks() {
|
|
380
380
|
return {
|
|
381
381
|
needsBufferFlush: function () {
|
|
382
|
-
|
|
382
|
+
var seekedTime = mediaElement.currentTime + 0.001;
|
|
383
|
+
playbackObserver.setCurrentTime(seekedTime);
|
|
384
|
+
// Seek again once data begins to be buffered.
|
|
385
|
+
// This is sadly necessary on some browsers to avoid decoding
|
|
386
|
+
// issues after a flush.
|
|
387
|
+
//
|
|
388
|
+
// NOTE: there's in theory a potential race condition in the following
|
|
389
|
+
// logic as the callback could be called when media data is still
|
|
390
|
+
// being removed by the browser - which is an asynchronous process.
|
|
391
|
+
// The following condition checking for buffered data could thus lead
|
|
392
|
+
// to a false positive where we're actually checking previous data.
|
|
393
|
+
// For now, such scenario is avoided by setting the
|
|
394
|
+
// `includeLastObservation` option to `false` and calling
|
|
395
|
+
// `needsBufferFlush` once MSE media removal operations have been
|
|
396
|
+
// explicitely validated by the browser, but that's a complex and easy
|
|
397
|
+
// to break system.
|
|
398
|
+
playbackObserver.listen(function (obs, stopListening) {
|
|
399
|
+
if (
|
|
400
|
+
// Data is buffered around the current position
|
|
401
|
+
obs.currentRange !== null ||
|
|
402
|
+
// Or, for whatever reason, playback is already advancing
|
|
403
|
+
obs.position > seekedTime + 0.1) {
|
|
404
|
+
stopListening();
|
|
405
|
+
playbackObserver.setCurrentTime(obs.position + 0.001);
|
|
406
|
+
}
|
|
407
|
+
}, { includeLastObservation: false, clearSignal: cancelSignal });
|
|
383
408
|
},
|
|
384
409
|
streamStatusUpdate: function (value) {
|
|
385
410
|
// Announce discontinuities if found
|
|
@@ -518,7 +543,7 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
|
|
|
518
543
|
_this.trigger("activePeriodChanged", { period: period });
|
|
519
544
|
});
|
|
520
545
|
contentTimeBoundariesObserver.addEventListener("durationUpdate", function (newDuration) {
|
|
521
|
-
mediaSourceDurationUpdater.updateDuration(newDuration.duration,
|
|
546
|
+
mediaSourceDurationUpdater.updateDuration(newDuration.duration, newDuration.isEnd);
|
|
522
547
|
});
|
|
523
548
|
contentTimeBoundariesObserver.addEventListener("endOfStream", function () {
|
|
524
549
|
if (endOfStreamCanceller === null) {
|
|
@@ -536,7 +561,7 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
|
|
|
536
561
|
}
|
|
537
562
|
});
|
|
538
563
|
var currentDuration = contentTimeBoundariesObserver.getCurrentDuration();
|
|
539
|
-
mediaSourceDurationUpdater.updateDuration(currentDuration.duration,
|
|
564
|
+
mediaSourceDurationUpdater.updateDuration(currentDuration.duration, currentDuration.isEnd);
|
|
540
565
|
return contentTimeBoundariesObserver;
|
|
541
566
|
};
|
|
542
567
|
/**
|
|
@@ -42,7 +42,7 @@ export default class MediaSourceDurationUpdater {
|
|
|
42
42
|
* which `duration` attribute should be set on the `MediaSource` associated
|
|
43
43
|
*
|
|
44
44
|
* @param {number} newDuration
|
|
45
|
-
* @param {boolean}
|
|
45
|
+
* @param {boolean} isRealEndKnown - If set to `false`, the current content is
|
|
46
46
|
* a dynamic content (it might evolve in the future) and the `newDuration`
|
|
47
47
|
* communicated might be greater still. In effect the
|
|
48
48
|
* `MediaSourceDurationUpdater` will actually set a much higher value to the
|
|
@@ -50,7 +50,7 @@ export default class MediaSourceDurationUpdater {
|
|
|
50
50
|
* side-effects of having a too low duration (such as the impossibility to
|
|
51
51
|
* seek over that value).
|
|
52
52
|
*/
|
|
53
|
-
updateDuration(newDuration: number,
|
|
53
|
+
updateDuration(newDuration: number, isRealEndKnown: boolean): void;
|
|
54
54
|
/**
|
|
55
55
|
* Abort the last duration-setting operation and free its resources.
|
|
56
56
|
*/
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
import { onSourceOpen, onSourceEnded, onSourceClose, } from "../../../compat/event_listeners";
|
|
17
|
+
/* eslint-disable-next-line max-len */
|
|
18
|
+
import hasIssuesWithHighMediaSourceDuration from "../../../compat/has_issues_with_high_media_source_duration";
|
|
17
19
|
import log from "../../../log";
|
|
18
20
|
import createSharedReference from "../../../utils/reference";
|
|
19
21
|
import TaskCanceller from "../../../utils/task_canceller";
|
|
@@ -42,7 +44,7 @@ var MediaSourceDurationUpdater = /** @class */ (function () {
|
|
|
42
44
|
* which `duration` attribute should be set on the `MediaSource` associated
|
|
43
45
|
*
|
|
44
46
|
* @param {number} newDuration
|
|
45
|
-
* @param {boolean}
|
|
47
|
+
* @param {boolean} isRealEndKnown - If set to `false`, the current content is
|
|
46
48
|
* a dynamic content (it might evolve in the future) and the `newDuration`
|
|
47
49
|
* communicated might be greater still. In effect the
|
|
48
50
|
* `MediaSourceDurationUpdater` will actually set a much higher value to the
|
|
@@ -50,7 +52,7 @@ var MediaSourceDurationUpdater = /** @class */ (function () {
|
|
|
50
52
|
* side-effects of having a too low duration (such as the impossibility to
|
|
51
53
|
* seek over that value).
|
|
52
54
|
*/
|
|
53
|
-
MediaSourceDurationUpdater.prototype.updateDuration = function (newDuration,
|
|
55
|
+
MediaSourceDurationUpdater.prototype.updateDuration = function (newDuration, isRealEndKnown) {
|
|
54
56
|
if (this._currentMediaSourceDurationUpdateCanceller !== null) {
|
|
55
57
|
this._currentMediaSourceDurationUpdateCanceller.cancel();
|
|
56
58
|
}
|
|
@@ -81,7 +83,7 @@ var MediaSourceDurationUpdater = /** @class */ (function () {
|
|
|
81
83
|
if (areUpdating) {
|
|
82
84
|
return;
|
|
83
85
|
}
|
|
84
|
-
recursivelyForceDurationUpdate(mediaSource, newDuration,
|
|
86
|
+
recursivelyForceDurationUpdate(mediaSource, newDuration, isRealEndKnown, sourceBuffersUpdatingCanceller.signal);
|
|
85
87
|
}, { clearSignal: msOpenStatusCanceller.signal, emitCurrentValue: true });
|
|
86
88
|
}
|
|
87
89
|
};
|
|
@@ -107,20 +109,15 @@ export default MediaSourceDurationUpdater;
|
|
|
107
109
|
*
|
|
108
110
|
* @param {MediaSource} mediaSource
|
|
109
111
|
* @param {number} duration
|
|
110
|
-
* @param {boolean}
|
|
112
|
+
* @param {boolean} isRealEndKnown
|
|
111
113
|
* @returns {string}
|
|
112
114
|
*/
|
|
113
|
-
function setMediaSourceDuration(mediaSource, duration,
|
|
115
|
+
function setMediaSourceDuration(mediaSource, duration, isRealEndKnown) {
|
|
114
116
|
var newDuration = duration;
|
|
115
|
-
if (
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
// seek anywhere we want to (even ahead of the Manifest if we want to).
|
|
120
|
-
// As such, we put it at a safe default value of 2^32 excepted when the
|
|
121
|
-
// maximum position is already relatively close to that value, where we
|
|
122
|
-
// authorize exceptionally going over it.
|
|
123
|
-
newDuration = Math.max(Math.pow(2, 32), newDuration + YEAR_IN_SECONDS);
|
|
117
|
+
if (!isRealEndKnown) {
|
|
118
|
+
newDuration = hasIssuesWithHighMediaSourceDuration() ?
|
|
119
|
+
Infinity :
|
|
120
|
+
getMaximumLiveSeekablePosition(duration);
|
|
124
121
|
}
|
|
125
122
|
var maxBufferedEnd = 0;
|
|
126
123
|
for (var i = 0; i < mediaSource.sourceBuffers.length; i++) {
|
|
@@ -153,6 +150,9 @@ function setMediaSourceDuration(mediaSource, duration, addTimeMargin) {
|
|
|
153
150
|
try {
|
|
154
151
|
log.info("Init: Updating duration", newDuration);
|
|
155
152
|
mediaSource.duration = newDuration;
|
|
153
|
+
if (mediaSource.readyState === "open" && !isFinite(newDuration)) {
|
|
154
|
+
mediaSource.setLiveSeekableRange(0, getMaximumLiveSeekablePosition(duration));
|
|
155
|
+
}
|
|
156
156
|
}
|
|
157
157
|
catch (err) {
|
|
158
158
|
log.warn("Duration Updater: Can't update duration on the MediaSource.", err instanceof Error ? err : "");
|
|
@@ -234,19 +234,30 @@ function createMediaSourceOpenReference(mediaSource, cancelSignal) {
|
|
|
234
234
|
*
|
|
235
235
|
* @param {MediaSource} mediaSource
|
|
236
236
|
* @param {number} duration
|
|
237
|
-
* @param {boolean}
|
|
237
|
+
* @param {boolean} isRealEndKnown
|
|
238
238
|
* @param {Object} cancelSignal
|
|
239
239
|
*/
|
|
240
|
-
function recursivelyForceDurationUpdate(mediaSource, duration,
|
|
241
|
-
var res = setMediaSourceDuration(mediaSource, duration,
|
|
240
|
+
function recursivelyForceDurationUpdate(mediaSource, duration, isRealEndKnown, cancelSignal) {
|
|
241
|
+
var res = setMediaSourceDuration(mediaSource, duration, isRealEndKnown);
|
|
242
242
|
if (res === "success" /* MediaSourceDurationUpdateStatus.Success */) {
|
|
243
243
|
return;
|
|
244
244
|
}
|
|
245
245
|
var timeoutId = setTimeout(function () {
|
|
246
246
|
unregisterClear();
|
|
247
|
-
recursivelyForceDurationUpdate(mediaSource, duration,
|
|
247
|
+
recursivelyForceDurationUpdate(mediaSource, duration, isRealEndKnown, cancelSignal);
|
|
248
248
|
}, 2000);
|
|
249
249
|
var unregisterClear = cancelSignal.register(function () {
|
|
250
250
|
clearTimeout(timeoutId);
|
|
251
251
|
});
|
|
252
252
|
}
|
|
253
|
+
function getMaximumLiveSeekablePosition(contentLastPosition) {
|
|
254
|
+
// Some targets poorly support setting a very high number for seekable
|
|
255
|
+
// ranges.
|
|
256
|
+
// Yet, in contents whose end is not yet known (e.g. live contents), we
|
|
257
|
+
// would prefer setting a value as high as possible to still be able to
|
|
258
|
+
// seek anywhere we want to (even ahead of the Manifest if we want to).
|
|
259
|
+
// As such, we put it at a safe default value of 2^32 excepted when the
|
|
260
|
+
// maximum position is already relatively close to that value, where we
|
|
261
|
+
// authorize exceptionally going over it.
|
|
262
|
+
return Math.max(Math.pow(2, 32), contentLastPosition + YEAR_IN_SECONDS);
|
|
263
|
+
}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import BufferGarbageCollector from "./garbage_collector";
|
|
17
17
|
import { IBufferType, IEndOfSegmentInfos, IEndOfSegmentOperation, IPushChunkInfos, IPushedChunkData, IPushOperation, IRemoveOperation, ISBOperation, SegmentBuffer, SegmentBufferOperation } from "./implementations";
|
|
18
|
-
import { IBufferedChunk, IChunkContext } from "./inventory";
|
|
18
|
+
import { IBufferedChunk, IChunkContext, IInsertedChunkInfos } from "./inventory";
|
|
19
19
|
import SegmentBuffersStore, { ISegmentBufferOptions, ITextTrackSegmentBufferOptions } from "./segment_buffers_store";
|
|
20
20
|
export default SegmentBuffersStore;
|
|
21
|
-
export { BufferGarbageCollector, ISegmentBufferOptions, ITextTrackSegmentBufferOptions, SegmentBuffer, IBufferType, IBufferedChunk, IChunkContext, IPushChunkInfos, IPushedChunkData, IEndOfSegmentInfos, SegmentBufferOperation, ISBOperation, IEndOfSegmentOperation, IPushOperation, IRemoveOperation, };
|
|
21
|
+
export { BufferGarbageCollector, ISegmentBufferOptions, ITextTrackSegmentBufferOptions, SegmentBuffer, IBufferType, IBufferedChunk, IChunkContext, IInsertedChunkInfos, IPushChunkInfos, IPushedChunkData, IEndOfSegmentInfos, SegmentBufferOperation, ISBOperation, IEndOfSegmentOperation, IPushOperation, IRemoveOperation, };
|
package/dist/_esm5.processed/core/stream/adaptation/utils/create_representation_estimator.js
CHANGED
|
@@ -46,7 +46,7 @@ export default function getRepresentationEstimate(content, representationEstimat
|
|
|
46
46
|
var newRepr = adaptation.getPlayableRepresentations();
|
|
47
47
|
if (newRepr.length === 0) {
|
|
48
48
|
var noRepErr = new MediaError("NO_PLAYABLE_REPRESENTATION", "No Representation in the chosen " +
|
|
49
|
-
adaptation.type + " Adaptation can be played");
|
|
49
|
+
adaptation.type + " Adaptation can be played", { adaptation: adaptation });
|
|
50
50
|
cleanUp();
|
|
51
51
|
onFatalError(noRepErr);
|
|
52
52
|
return;
|
|
@@ -329,7 +329,7 @@ function getFirstDeclaredMimeType(adaptation) {
|
|
|
329
329
|
var representations = adaptation.getPlayableRepresentations();
|
|
330
330
|
if (representations.length === 0) {
|
|
331
331
|
var noRepErr = new MediaError("NO_PLAYABLE_REPRESENTATION", "No Representation in the chosen " +
|
|
332
|
-
adaptation.type + " Adaptation can be played");
|
|
332
|
+
adaptation.type + " Adaptation can be played", { adaptation: adaptation });
|
|
333
333
|
throw noRepErr;
|
|
334
334
|
}
|
|
335
335
|
return representations[0].getMimeTypeString();
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { CancellationSignal } from "../../../../utils/task_canceller";
|
|
17
17
|
import { IReadOnlyPlaybackObserver } from "../../../api";
|
|
18
|
-
import { IPushChunkInfos, SegmentBuffer } from "../../../segment_buffers";
|
|
18
|
+
import { IInsertedChunkInfos, IPushChunkInfos, SegmentBuffer } from "../../../segment_buffers";
|
|
19
19
|
import { IRepresentationStreamPlaybackObservation } from "../types";
|
|
20
20
|
/**
|
|
21
21
|
* Append a segment to the given segmentBuffer.
|
|
@@ -27,4 +27,6 @@ import { IRepresentationStreamPlaybackObservation } from "../types";
|
|
|
27
27
|
* @param {Object} cancellationSignal
|
|
28
28
|
* @returns {Promise}
|
|
29
29
|
*/
|
|
30
|
-
export default function appendSegmentToBuffer<T>(playbackObserver: IReadOnlyPlaybackObserver<IRepresentationStreamPlaybackObservation>, segmentBuffer: SegmentBuffer, dataInfos: IPushChunkInfos<T
|
|
30
|
+
export default function appendSegmentToBuffer<T>(playbackObserver: IReadOnlyPlaybackObserver<IRepresentationStreamPlaybackObservation>, segmentBuffer: SegmentBuffer, dataInfos: IPushChunkInfos<T> & {
|
|
31
|
+
inventoryInfos: IInsertedChunkInfos;
|
|
32
|
+
}, cancellationSignal: CancellationSignal): Promise<void>;
|
|
@@ -87,7 +87,7 @@ export default function appendSegmentToBuffer(playbackObserver, segmentBuffer, d
|
|
|
87
87
|
reason = appendError_1 instanceof Error ?
|
|
88
88
|
appendError_1.toString() :
|
|
89
89
|
"An unknown error happened when pushing content";
|
|
90
|
-
throw new MediaError("BUFFER_APPEND_ERROR", reason);
|
|
90
|
+
throw new MediaError("BUFFER_APPEND_ERROR", reason, { adaptation: dataInfos.inventoryInfos.adaptation });
|
|
91
91
|
}
|
|
92
92
|
position = playbackObserver.getReference().getValue().position;
|
|
93
93
|
currentPos = (_a = position.pending) !== null && _a !== void 0 ? _a : position.last;
|
|
@@ -105,7 +105,7 @@ export default function appendSegmentToBuffer(playbackObserver, segmentBuffer, d
|
|
|
105
105
|
err2_1 = _b.sent();
|
|
106
106
|
reason = err2_1 instanceof Error ? err2_1.toString() :
|
|
107
107
|
"Could not clean the buffer";
|
|
108
|
-
throw new MediaError("BUFFER_FULL_ERROR", reason);
|
|
108
|
+
throw new MediaError("BUFFER_FULL_ERROR", reason, { adaptation: dataInfos.inventoryInfos.adaptation });
|
|
109
109
|
case 7: return [3 /*break*/, 8];
|
|
110
110
|
case 8: return [2 /*return*/];
|
|
111
111
|
}
|
|
@@ -49,6 +49,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
49
49
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
50
50
|
}
|
|
51
51
|
};
|
|
52
|
+
import objectAssign from "../../../../utils/object_assign";
|
|
52
53
|
import appendSegmentToBuffer from "./append_segment_to_buffer";
|
|
53
54
|
/**
|
|
54
55
|
* Push the initialization segment to the SegmentBuffer.
|
|
@@ -59,7 +60,7 @@ import appendSegmentToBuffer from "./append_segment_to_buffer";
|
|
|
59
60
|
export default function pushInitSegment(_a, cancelSignal) {
|
|
60
61
|
var playbackObserver = _a.playbackObserver, content = _a.content, segment = _a.segment, segmentData = _a.segmentData, segmentBuffer = _a.segmentBuffer;
|
|
61
62
|
return __awaiter(this, void 0, void 0, function () {
|
|
62
|
-
var codec, data, buffered;
|
|
63
|
+
var codec, data, inventoryInfos, buffered;
|
|
63
64
|
return __generator(this, function (_b) {
|
|
64
65
|
switch (_b.label) {
|
|
65
66
|
case 0:
|
|
@@ -74,7 +75,10 @@ export default function pushInitSegment(_a, cancelSignal) {
|
|
|
74
75
|
chunk: null,
|
|
75
76
|
timestampOffset: 0,
|
|
76
77
|
appendWindow: [undefined, undefined], codec: codec };
|
|
77
|
-
|
|
78
|
+
inventoryInfos = objectAssign({ segment: segment, chunkSize: undefined,
|
|
79
|
+
start: 0,
|
|
80
|
+
end: 0 }, content);
|
|
81
|
+
return [4 /*yield*/, appendSegmentToBuffer(playbackObserver, segmentBuffer, { data: data, inventoryInfos: inventoryInfos }, cancelSignal)];
|
|
78
82
|
case 1:
|
|
79
83
|
_b.sent();
|
|
80
84
|
buffered = segmentBuffer.getBufferedRanges();
|
|
@@ -19,8 +19,8 @@ import EncryptedMediaError from "./encrypted_media_error";
|
|
|
19
19
|
import { ErrorCodes, ErrorTypes, IErrorCode, IErrorType, NetworkErrorTypes } from "./error_codes";
|
|
20
20
|
import formatError from "./format_error";
|
|
21
21
|
import isKnownError from "./is_known_error";
|
|
22
|
-
import MediaError from "./media_error";
|
|
22
|
+
import MediaError, { IMediaErrorTrackContext } from "./media_error";
|
|
23
23
|
import NetworkError from "./network_error";
|
|
24
24
|
import OtherError from "./other_error";
|
|
25
25
|
import RequestError from "./request_error";
|
|
26
|
-
export { AssertionError, CustomLoaderError, EncryptedMediaError, ErrorCodes, ErrorTypes, IErrorCode, IErrorType, formatError, MediaError as MediaError, NetworkError, OtherError, RequestError, NetworkErrorTypes, isKnownError, };
|
|
26
|
+
export { AssertionError, CustomLoaderError, EncryptedMediaError, ErrorCodes, ErrorTypes, IErrorCode, IErrorType, IMediaErrorTrackContext, formatError, MediaError as MediaError, NetworkError, OtherError, RequestError, NetworkErrorTypes, isKnownError, };
|
|
@@ -13,7 +13,23 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
+
import { Adaptation } from "../manifest";
|
|
17
|
+
import { IAudioTrack, ITextTrack, IVideoTrack } from "../public_types";
|
|
16
18
|
import { IMediaErrorCode } from "./error_codes";
|
|
19
|
+
interface IAudioTrackMediaErrorContext {
|
|
20
|
+
type: "audio";
|
|
21
|
+
track: IAudioTrack;
|
|
22
|
+
}
|
|
23
|
+
interface IVideoTrackMediaErrorContext {
|
|
24
|
+
type: "video";
|
|
25
|
+
track: IVideoTrack;
|
|
26
|
+
}
|
|
27
|
+
interface ITextTrackMediaErrorContext {
|
|
28
|
+
type: "text";
|
|
29
|
+
track: ITextTrack;
|
|
30
|
+
}
|
|
31
|
+
export type IMediaErrorTrackContext = IAudioTrackMediaErrorContext | IVideoTrackMediaErrorContext | ITextTrackMediaErrorContext;
|
|
32
|
+
type ICodeWithAdaptationType = "BUFFER_APPEND_ERROR" | "BUFFER_FULL_ERROR" | "NO_PLAYABLE_REPRESENTATION" | "MANIFEST_INCOMPATIBLE_CODECS_ERROR";
|
|
17
33
|
/**
|
|
18
34
|
* Error linked to the media Playback.
|
|
19
35
|
*
|
|
@@ -25,10 +41,16 @@ export default class MediaError extends Error {
|
|
|
25
41
|
readonly type: "MEDIA_ERROR";
|
|
26
42
|
readonly message: string;
|
|
27
43
|
readonly code: IMediaErrorCode;
|
|
44
|
+
readonly trackInfo: IMediaErrorTrackContext | undefined;
|
|
28
45
|
fatal: boolean;
|
|
29
46
|
/**
|
|
30
47
|
* @param {string} code
|
|
31
48
|
* @param {string} reason
|
|
49
|
+
* @param {Object|undefined} [context]
|
|
32
50
|
*/
|
|
33
|
-
constructor(code:
|
|
51
|
+
constructor(code: ICodeWithAdaptationType, reason: string, context: {
|
|
52
|
+
adaptation: Adaptation;
|
|
53
|
+
});
|
|
54
|
+
constructor(code: Exclude<IMediaErrorCode, ICodeWithAdaptationType>, reason: string);
|
|
34
55
|
}
|
|
56
|
+
export {};
|
|
@@ -38,11 +38,7 @@ import errorMessage from "./error_message";
|
|
|
38
38
|
*/
|
|
39
39
|
var MediaError = /** @class */ (function (_super) {
|
|
40
40
|
__extends(MediaError, _super);
|
|
41
|
-
|
|
42
|
-
* @param {string} code
|
|
43
|
-
* @param {string} reason
|
|
44
|
-
*/
|
|
45
|
-
function MediaError(code, reason) {
|
|
41
|
+
function MediaError(code, reason, context) {
|
|
46
42
|
var _this = _super.call(this) || this;
|
|
47
43
|
// @see https://stackoverflow.com/questions/41102060/typescript-extending-error-class
|
|
48
44
|
Object.setPrototypeOf(_this, MediaError.prototype);
|
|
@@ -51,6 +47,23 @@ var MediaError = /** @class */ (function (_super) {
|
|
|
51
47
|
_this.code = code;
|
|
52
48
|
_this.message = errorMessage(_this.name, _this.code, reason);
|
|
53
49
|
_this.fatal = false;
|
|
50
|
+
var adaptation = context === null || context === void 0 ? void 0 : context.adaptation;
|
|
51
|
+
if (adaptation !== undefined) {
|
|
52
|
+
switch (adaptation.type) {
|
|
53
|
+
case "audio":
|
|
54
|
+
_this.trackInfo = { type: "audio",
|
|
55
|
+
track: adaptation.toAudioTrack() };
|
|
56
|
+
break;
|
|
57
|
+
case "video":
|
|
58
|
+
_this.trackInfo = { type: "video",
|
|
59
|
+
track: adaptation.toVideoTrack() };
|
|
60
|
+
break;
|
|
61
|
+
case "text":
|
|
62
|
+
_this.trackInfo = { type: "text",
|
|
63
|
+
track: adaptation.toTextTrack() };
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
54
67
|
return _this;
|
|
55
68
|
}
|
|
56
69
|
return MediaError;
|
|
@@ -14,14 +14,14 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
import { IParsedAdaptation } from "../parsers/manifest";
|
|
17
|
-
import { IRepresentationFilter } from "../public_types";
|
|
17
|
+
import { IAudioTrack, IRepresentationFilter, ITextTrack, IVideoTrack } from "../public_types";
|
|
18
18
|
import Representation from "./representation";
|
|
19
19
|
import { IAdaptationType } from "./types";
|
|
20
20
|
/** List in an array every possible value for the Adaptation's `type` property. */
|
|
21
21
|
export declare const SUPPORTED_ADAPTATIONS_TYPE: IAdaptationType[];
|
|
22
22
|
/**
|
|
23
23
|
* Normalized Adaptation structure.
|
|
24
|
-
* An Adaptation describes a single `Track`. For example a specific audio
|
|
24
|
+
* An `Adaptation` describes a single `Track`. For example a specific audio
|
|
25
25
|
* track (in a given language) or a specific video track.
|
|
26
26
|
* It istelf can be represented in different qualities, which we call here
|
|
27
27
|
* `Representation`.
|
|
@@ -97,4 +97,19 @@ export default class Adaptation {
|
|
|
97
97
|
* @returns {Object|undefined}
|
|
98
98
|
*/
|
|
99
99
|
getRepresentation(wantedId: number | string): Representation | undefined;
|
|
100
|
+
/**
|
|
101
|
+
* Format an `Adaptation`, generally of type `"audio"`, as an `IAudioTrack`.
|
|
102
|
+
* @returns {Object}
|
|
103
|
+
*/
|
|
104
|
+
toAudioTrack(): IAudioTrack;
|
|
105
|
+
/**
|
|
106
|
+
* Format an `Adaptation`, generally of type `"audio"`, as an `IAudioTrack`.
|
|
107
|
+
* @returns {Object}
|
|
108
|
+
*/
|
|
109
|
+
toTextTrack(): ITextTrack;
|
|
110
|
+
/**
|
|
111
|
+
* Format an `Adaptation`, generally of type `"video"`, as an `IAudioTrack`.
|
|
112
|
+
* @returns {Object}
|
|
113
|
+
*/
|
|
114
|
+
toVideoTrack(): IVideoTrack;
|
|
100
115
|
}
|
|
@@ -26,7 +26,7 @@ export var SUPPORTED_ADAPTATIONS_TYPE = ["audio",
|
|
|
26
26
|
"image"];
|
|
27
27
|
/**
|
|
28
28
|
* Normalized Adaptation structure.
|
|
29
|
-
* An Adaptation describes a single `Track`. For example a specific audio
|
|
29
|
+
* An `Adaptation` describes a single `Track`. For example a specific audio
|
|
30
30
|
* track (in a given language) or a specific video track.
|
|
31
31
|
* It istelf can be represented in different qualities, which we call here
|
|
32
32
|
* `Representation`.
|
|
@@ -137,6 +137,72 @@ var Adaptation = /** @class */ (function () {
|
|
|
137
137
|
return wantedId === id;
|
|
138
138
|
});
|
|
139
139
|
};
|
|
140
|
+
/**
|
|
141
|
+
* Format an `Adaptation`, generally of type `"audio"`, as an `IAudioTrack`.
|
|
142
|
+
* @returns {Object}
|
|
143
|
+
*/
|
|
144
|
+
Adaptation.prototype.toAudioTrack = function () {
|
|
145
|
+
var _a, _b;
|
|
146
|
+
var formatted = {
|
|
147
|
+
language: (_a = this.language) !== null && _a !== void 0 ? _a : "",
|
|
148
|
+
normalized: (_b = this.normalizedLanguage) !== null && _b !== void 0 ? _b : "",
|
|
149
|
+
audioDescription: this.isAudioDescription === true,
|
|
150
|
+
id: this.id,
|
|
151
|
+
representations: this.representations.map(function (r) { return r.toAudioRepresentation(); }),
|
|
152
|
+
label: this.label,
|
|
153
|
+
};
|
|
154
|
+
if (this.isDub === true) {
|
|
155
|
+
formatted.dub = true;
|
|
156
|
+
}
|
|
157
|
+
return formatted;
|
|
158
|
+
};
|
|
159
|
+
/**
|
|
160
|
+
* Format an `Adaptation`, generally of type `"audio"`, as an `IAudioTrack`.
|
|
161
|
+
* @returns {Object}
|
|
162
|
+
*/
|
|
163
|
+
Adaptation.prototype.toTextTrack = function () {
|
|
164
|
+
var _a, _b;
|
|
165
|
+
return {
|
|
166
|
+
language: (_a = this.language) !== null && _a !== void 0 ? _a : "",
|
|
167
|
+
normalized: (_b = this.normalizedLanguage) !== null && _b !== void 0 ? _b : "",
|
|
168
|
+
closedCaption: this.isClosedCaption === true,
|
|
169
|
+
id: this.id,
|
|
170
|
+
label: this.label,
|
|
171
|
+
forced: this.isForcedSubtitles,
|
|
172
|
+
};
|
|
173
|
+
};
|
|
174
|
+
/**
|
|
175
|
+
* Format an `Adaptation`, generally of type `"video"`, as an `IAudioTrack`.
|
|
176
|
+
* @returns {Object}
|
|
177
|
+
*/
|
|
178
|
+
Adaptation.prototype.toVideoTrack = function () {
|
|
179
|
+
var trickModeTracks = this.trickModeTracks !== undefined ?
|
|
180
|
+
this.trickModeTracks.map(function (trickModeAdaptation) {
|
|
181
|
+
var representations = trickModeAdaptation.representations
|
|
182
|
+
.map(function (r) { return r.toVideoRepresentation(); });
|
|
183
|
+
var trickMode = { id: trickModeAdaptation.id, representations: representations, isTrickModeTrack: true };
|
|
184
|
+
if (trickModeAdaptation.isSignInterpreted === true) {
|
|
185
|
+
trickMode.signInterpreted = true;
|
|
186
|
+
}
|
|
187
|
+
return trickMode;
|
|
188
|
+
}) :
|
|
189
|
+
undefined;
|
|
190
|
+
var videoTrack = {
|
|
191
|
+
id: this.id,
|
|
192
|
+
representations: this.representations.map(function (r) { return r.toVideoRepresentation(); }),
|
|
193
|
+
label: this.label,
|
|
194
|
+
};
|
|
195
|
+
if (this.isSignInterpreted === true) {
|
|
196
|
+
videoTrack.signInterpreted = true;
|
|
197
|
+
}
|
|
198
|
+
if (this.isTrickModeTrack === true) {
|
|
199
|
+
videoTrack.isTrickModeTrack = true;
|
|
200
|
+
}
|
|
201
|
+
if (trickModeTracks !== undefined) {
|
|
202
|
+
videoTrack.trickModeTracks = trickModeTracks;
|
|
203
|
+
}
|
|
204
|
+
return videoTrack;
|
|
205
|
+
};
|
|
140
206
|
return Adaptation;
|
|
141
207
|
}());
|
|
142
208
|
export default Adaptation;
|
|
@@ -310,7 +310,7 @@ export default class Manifest extends EventEmitter<IManifestEvents> {
|
|
|
310
310
|
private _addSupplementaryTextAdaptations;
|
|
311
311
|
/**
|
|
312
312
|
* @param {Object} newManifest
|
|
313
|
-
* @param {number}
|
|
313
|
+
* @param {number} updateType
|
|
314
314
|
*/
|
|
315
315
|
private _performUpdate;
|
|
316
316
|
}
|
|
@@ -340,7 +340,7 @@ var Manifest = /** @class */ (function (_super) {
|
|
|
340
340
|
})
|
|
341
341
|
}] }, { isManuallyAdded: true });
|
|
342
342
|
if (newAdaptation.representations.length > 0 && !newAdaptation.isSupported) {
|
|
343
|
-
var error = new MediaError("MANIFEST_INCOMPATIBLE_CODECS_ERROR", "An Adaptation contains only incompatible codecs.");
|
|
343
|
+
var error = new MediaError("MANIFEST_INCOMPATIBLE_CODECS_ERROR", "An Adaptation contains only incompatible codecs.", { adaptation: newAdaptation });
|
|
344
344
|
_this.contentWarnings.push(error);
|
|
345
345
|
}
|
|
346
346
|
return newAdaptation;
|
|
@@ -392,7 +392,7 @@ var Manifest = /** @class */ (function (_super) {
|
|
|
392
392
|
})
|
|
393
393
|
}] }, { isManuallyAdded: true });
|
|
394
394
|
if (newAdaptation.representations.length > 0 && !newAdaptation.isSupported) {
|
|
395
|
-
var error = new MediaError("MANIFEST_INCOMPATIBLE_CODECS_ERROR", "An Adaptation contains only incompatible codecs.");
|
|
395
|
+
var error = new MediaError("MANIFEST_INCOMPATIBLE_CODECS_ERROR", "An Adaptation contains only incompatible codecs.", { adaptation: newAdaptation });
|
|
396
396
|
_this.contentWarnings.push(error);
|
|
397
397
|
}
|
|
398
398
|
return newAdaptation;
|
|
@@ -407,7 +407,7 @@ var Manifest = /** @class */ (function (_super) {
|
|
|
407
407
|
};
|
|
408
408
|
/**
|
|
409
409
|
* @param {Object} newManifest
|
|
410
|
-
* @param {number}
|
|
410
|
+
* @param {number} updateType
|
|
411
411
|
*/
|
|
412
412
|
Manifest.prototype._performUpdate = function (newManifest, updateType) {
|
|
413
413
|
this.availabilityStartTime = newManifest.availabilityStartTime;
|
|
@@ -42,7 +42,7 @@ var Period = /** @class */ (function () {
|
|
|
42
42
|
.map(function (adaptation) {
|
|
43
43
|
var newAdaptation = new Adaptation(adaptation, { representationFilter: representationFilter });
|
|
44
44
|
if (newAdaptation.representations.length > 0 && !newAdaptation.isSupported) {
|
|
45
|
-
var error = new MediaError("MANIFEST_INCOMPATIBLE_CODECS_ERROR", "An Adaptation contains only incompatible codecs.");
|
|
45
|
+
var error = new MediaError("MANIFEST_INCOMPATIBLE_CODECS_ERROR", "An Adaptation contains only incompatible codecs.", { adaptation: newAdaptation });
|
|
46
46
|
_this.contentWarnings.push(error);
|
|
47
47
|
}
|
|
48
48
|
return newAdaptation;
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
import { ICdnMetadata, IContentProtections, IParsedRepresentation } from "../parsers/manifest";
|
|
17
|
-
import { IHDRInformation } from "../public_types";
|
|
17
|
+
import { IAudioRepresentation, IHDRInformation, IVideoRepresentation } from "../public_types";
|
|
18
18
|
import { IRepresentationIndex } from "./representation_index";
|
|
19
19
|
import { IAdaptationType } from "./types";
|
|
20
20
|
/**
|
|
@@ -166,6 +166,16 @@ declare class Representation {
|
|
|
166
166
|
systemId: string;
|
|
167
167
|
data: Uint8Array;
|
|
168
168
|
}>): boolean;
|
|
169
|
+
/**
|
|
170
|
+
* Format Representation as an `IAudioRepresentation`.
|
|
171
|
+
* @returns {Object}
|
|
172
|
+
*/
|
|
173
|
+
toAudioRepresentation(): IAudioRepresentation;
|
|
174
|
+
/**
|
|
175
|
+
* Format Representation as an `IVideoRepresentation`.
|
|
176
|
+
* @returns {Object}
|
|
177
|
+
*/
|
|
178
|
+
toVideoRepresentation(): IVideoRepresentation;
|
|
169
179
|
}
|
|
170
180
|
/** Protection data as returned by a Representation. */
|
|
171
181
|
export interface IRepresentationProtectionData {
|
|
@@ -225,6 +225,22 @@ var Representation = /** @class */ (function () {
|
|
|
225
225
|
values: data });
|
|
226
226
|
return true;
|
|
227
227
|
};
|
|
228
|
+
/**
|
|
229
|
+
* Format Representation as an `IAudioRepresentation`.
|
|
230
|
+
* @returns {Object}
|
|
231
|
+
*/
|
|
232
|
+
Representation.prototype.toAudioRepresentation = function () {
|
|
233
|
+
var _a = this, id = _a.id, bitrate = _a.bitrate, codec = _a.codec;
|
|
234
|
+
return { id: id, bitrate: bitrate, codec: codec };
|
|
235
|
+
};
|
|
236
|
+
/**
|
|
237
|
+
* Format Representation as an `IVideoRepresentation`.
|
|
238
|
+
* @returns {Object}
|
|
239
|
+
*/
|
|
240
|
+
Representation.prototype.toVideoRepresentation = function () {
|
|
241
|
+
var _a = this, id = _a.id, bitrate = _a.bitrate, frameRate = _a.frameRate, width = _a.width, height = _a.height, codec = _a.codec, hdrInfo = _a.hdrInfo;
|
|
242
|
+
return { id: id, bitrate: bitrate, frameRate: frameRate, width: width, height: height, codec: codec, hdrInfo: hdrInfo };
|
|
243
|
+
};
|
|
228
244
|
return Representation;
|
|
229
245
|
}());
|
|
230
246
|
export default Representation;
|
|
@@ -17,7 +17,7 @@ import { IMPDParserArguments } from "../common";
|
|
|
17
17
|
import { IDashParserResponse } from "../parsers_types";
|
|
18
18
|
/**
|
|
19
19
|
* Parse MPD through the JS parser, on a `Document` instance.
|
|
20
|
-
* @param {Document}
|
|
20
|
+
* @param {Document} document - Original manifest as returned by the server
|
|
21
21
|
* @param {Object} args - Various parsing options and information.
|
|
22
22
|
* @returns {Object} - Response returned by the DASH-JS parser.
|
|
23
23
|
*/
|
|
@@ -20,7 +20,7 @@ import { createMPDIntermediateRepresentation, } from "./node_parsers/MPD";
|
|
|
20
20
|
import { createPeriodIntermediateRepresentation, } from "./node_parsers/Period";
|
|
21
21
|
/**
|
|
22
22
|
* Parse MPD through the JS parser, on a `Document` instance.
|
|
23
|
-
* @param {Document}
|
|
23
|
+
* @param {Document} document - Original manifest as returned by the server
|
|
24
24
|
* @param {Object} args - Various parsing options and information.
|
|
25
25
|
* @returns {Object} - Response returned by the DASH-JS parser.
|
|
26
26
|
*/
|