rx-player 3.30.1-dev.2023032300 → 3.30.1-dev.2023032800
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 +8 -2
- package/VERSION +1 -1
- package/dist/_esm5.processed/compat/eme/load_session.js +1 -1
- package/dist/_esm5.processed/config.d.ts +2 -0
- package/dist/_esm5.processed/core/adaptive/adaptive_representation_selector.js +4 -2
- package/dist/_esm5.processed/core/adaptive/buffer_based_chooser.js +4 -4
- package/dist/_esm5.processed/core/adaptive/network_analyzer.js +8 -5
- package/dist/_esm5.processed/core/api/playback_observer.js +1 -0
- package/dist/_esm5.processed/core/api/public_api.js +3 -2
- package/dist/_esm5.processed/core/decrypt/utils/clean_old_loaded_sessions.js +2 -0
- package/dist/_esm5.processed/core/decrypt/utils/loaded_sessions_store.js +5 -1
- package/dist/_esm5.processed/core/init/media_source_content_initializer.js +6 -5
- package/dist/_esm5.processed/core/init/utils/content_time_boundaries_observer.d.ts +28 -1
- package/dist/_esm5.processed/core/init/utils/content_time_boundaries_observer.js +22 -9
- package/dist/_esm5.processed/core/init/utils/media_source_duration_updater.d.ts +58 -0
- package/dist/_esm5.processed/core/init/utils/{media_duration_updater.js → media_source_duration_updater.js} +71 -85
- package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +3 -3
- package/dist/_esm5.processed/default_config.d.ts +25 -0
- package/dist/_esm5.processed/default_config.js +27 -2
- package/dist/_esm5.processed/utils/is_null_or_undefined.d.ts +1 -1
- package/dist/_esm5.processed/utils/is_null_or_undefined.js +1 -1
- package/dist/rx-player.js +168 -120
- package/dist/rx-player.min.js +1 -1
- package/package.json +1 -1
- package/sonar-project.properties +1 -1
- package/src/compat/eme/load_session.ts +1 -1
- package/src/core/adaptive/adaptive_representation_selector.ts +6 -2
- package/src/core/adaptive/buffer_based_chooser.ts +4 -4
- package/src/core/adaptive/network_analyzer.ts +9 -4
- package/src/core/api/playback_observer.ts +1 -0
- package/src/core/api/public_api.ts +3 -2
- package/src/core/decrypt/utils/clean_old_loaded_sessions.ts +2 -1
- package/src/core/decrypt/utils/loaded_sessions_store.ts +8 -1
- package/src/core/init/media_source_content_initializer.ts +7 -5
- package/src/core/init/utils/content_time_boundaries_observer.ts +46 -10
- package/src/core/init/utils/{media_duration_updater.ts → media_source_duration_updater.ts} +87 -111
- package/src/core/stream/orchestrator/stream_orchestrator.ts +4 -4
- package/src/default_config.ts +29 -2
- package/src/utils/is_null_or_undefined.ts +1 -1
- package/dist/_esm5.processed/core/init/utils/media_duration_updater.d.ts +0 -56
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## v3.30.1 (2023-03-
|
|
3
|
+
## v3.30.1-dev.2023032800 (2023-03-28)
|
|
4
4
|
|
|
5
5
|
### Bug fixes
|
|
6
6
|
|
|
7
|
-
- DASH: Fix issue which could lead to infinite rebuffering when switching between multiple Periods
|
|
7
|
+
- DASH: Fix issue which could lead to infinite rebuffering when switching between multiple Periods [#1232]
|
|
8
|
+
- Return actual ending duration through the `getVideoDuration` method when playing dynamic contents whose future end is already known [#1235]
|
|
9
|
+
|
|
10
|
+
### Other improvements
|
|
11
|
+
|
|
12
|
+
- adaptive: Perform various adaptive tweaks to avoid switching too much between qualities in some conditions
|
|
13
|
+
|
|
8
14
|
|
|
9
15
|
## v3.30.0 (2023-03-07)
|
|
10
16
|
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.30.1-dev.
|
|
1
|
+
3.30.1-dev.2023032800
|
|
@@ -70,7 +70,7 @@ export default function loadSession(session, sessionId) {
|
|
|
70
70
|
return __generator(this, function (_a) {
|
|
71
71
|
switch (_a.label) {
|
|
72
72
|
case 0:
|
|
73
|
-
log.info("
|
|
73
|
+
log.info("DRM: Load persisted session", sessionId);
|
|
74
74
|
return [4 /*yield*/, session.load(sessionId)];
|
|
75
75
|
case 1:
|
|
76
76
|
isLoaded = _a.sent();
|
|
@@ -77,6 +77,8 @@ declare class ConfigHandler {
|
|
|
77
77
|
SAMPLING_INTERVAL_MEDIASOURCE: number;
|
|
78
78
|
SAMPLING_INTERVAL_LOW_LATENCY: number;
|
|
79
79
|
SAMPLING_INTERVAL_NO_MEDIASOURCE: number;
|
|
80
|
+
ABR_ENTER_BUFFER_BASED_ALGO: number;
|
|
81
|
+
ABR_EXIT_BUFFER_BASED_ALGO: number;
|
|
80
82
|
ABR_MINIMUM_TOTAL_BYTES: number;
|
|
81
83
|
ABR_MINIMUM_CHUNK_SIZE: number;
|
|
82
84
|
ABR_STARVATION_FACTOR: {
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
+
import config from "../../config";
|
|
16
17
|
import log from "../../log";
|
|
17
18
|
import noop from "../../utils/noop";
|
|
18
19
|
import { getLeftSizeOfRange } from "../../utils/ranges";
|
|
@@ -242,12 +243,13 @@ function getEstimateReference(_a, stopAllEstimates) {
|
|
|
242
243
|
stableRepresentation.bitrate / (lastPlaybackObservation.speed > 0 ?
|
|
243
244
|
lastPlaybackObservation.speed :
|
|
244
245
|
1);
|
|
245
|
-
|
|
246
|
+
var _b = config.getCurrent(), ABR_ENTER_BUFFER_BASED_ALGO = _b.ABR_ENTER_BUFFER_BASED_ALGO, ABR_EXIT_BUFFER_BASED_ALGO = _b.ABR_EXIT_BUFFER_BASED_ALGO;
|
|
247
|
+
if (allowBufferBasedEstimates && bufferGap <= ABR_EXIT_BUFFER_BASED_ALGO) {
|
|
246
248
|
allowBufferBasedEstimates = false;
|
|
247
249
|
}
|
|
248
250
|
else if (!allowBufferBasedEstimates &&
|
|
249
251
|
isFinite(bufferGap) &&
|
|
250
|
-
bufferGap
|
|
252
|
+
bufferGap >= ABR_ENTER_BUFFER_BASED_ALGO) {
|
|
251
253
|
allowBufferBasedEstimates = true;
|
|
252
254
|
}
|
|
253
255
|
/**
|
|
@@ -56,10 +56,10 @@ var BufferBasedChooser = /** @class */ (function () {
|
|
|
56
56
|
return bitrates[0];
|
|
57
57
|
}
|
|
58
58
|
var scaledScore;
|
|
59
|
-
if (currentScore
|
|
59
|
+
if (currentScore !== undefined) {
|
|
60
60
|
scaledScore = speed === 0 ? currentScore : (currentScore / speed);
|
|
61
61
|
}
|
|
62
|
-
if (scaledScore
|
|
62
|
+
if (scaledScore !== undefined && scaledScore > 1) {
|
|
63
63
|
var currentBufferLevel_1 = bufferLevels[currentBitrateIndex];
|
|
64
64
|
var nextIndex = (function () {
|
|
65
65
|
for (var i = currentBitrateIndex + 1; i < bufferLevels.length; i++) {
|
|
@@ -68,14 +68,14 @@ var BufferBasedChooser = /** @class */ (function () {
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
})();
|
|
71
|
-
if (nextIndex
|
|
71
|
+
if (nextIndex !== undefined) {
|
|
72
72
|
var nextBufferLevel = bufferLevels[nextIndex];
|
|
73
73
|
if (bufferGap >= nextBufferLevel) {
|
|
74
74
|
return bitrates[nextIndex];
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
|
-
if (scaledScore
|
|
78
|
+
if (scaledScore === undefined || scaledScore < 1.15) {
|
|
79
79
|
var currentBufferLevel = bufferLevels[currentBitrateIndex];
|
|
80
80
|
if (bufferGap < currentBufferLevel) {
|
|
81
81
|
for (var i = currentBitrateIndex - 1; i >= 0; i--) {
|
|
@@ -126,6 +126,12 @@ function estimateStarvationModeBitrate(pendingRequests, playbackInfo, currentRep
|
|
|
126
126
|
}
|
|
127
127
|
var concernedRequest = concernedRequests[0];
|
|
128
128
|
var now = performance.now();
|
|
129
|
+
var minimumRequestTime = concernedRequest.content.segment.duration * 1.5;
|
|
130
|
+
minimumRequestTime = Math.min(minimumRequestTime, 3000);
|
|
131
|
+
minimumRequestTime = Math.max(minimumRequestTime, 12000);
|
|
132
|
+
if (now - concernedRequest.requestTimestamp < minimumRequestTime) {
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
129
135
|
var lastProgressEvent = concernedRequest.progress.length > 0 ?
|
|
130
136
|
concernedRequest.progress[concernedRequest.progress.length - 1] :
|
|
131
137
|
undefined;
|
|
@@ -138,7 +144,7 @@ function estimateStarvationModeBitrate(pendingRequests, playbackInfo, currentRep
|
|
|
138
144
|
// Calculate estimated time spent rebuffering if we continue doing that request.
|
|
139
145
|
var expectedRebufferingTime = remainingTime -
|
|
140
146
|
(realBufferGap / speed);
|
|
141
|
-
if (expectedRebufferingTime >
|
|
147
|
+
if (expectedRebufferingTime > 2500) {
|
|
142
148
|
return bandwidthEstimate;
|
|
143
149
|
}
|
|
144
150
|
}
|
|
@@ -320,12 +326,9 @@ var NetworkAnalyzer = /** @class */ (function () {
|
|
|
320
326
|
if (currentRepresentation === null) {
|
|
321
327
|
return true;
|
|
322
328
|
}
|
|
323
|
-
else if (bitrate
|
|
329
|
+
else if (bitrate >= currentRepresentation.bitrate) {
|
|
324
330
|
return false;
|
|
325
331
|
}
|
|
326
|
-
else if (bitrate > currentRepresentation.bitrate) {
|
|
327
|
-
return !this._inStarvationMode;
|
|
328
|
-
}
|
|
329
332
|
return shouldDirectlySwitchToLowBitrate(playbackInfo, currentRequests, this._lowLatencyMode);
|
|
330
333
|
};
|
|
331
334
|
return NetworkAnalyzer;
|
|
@@ -114,6 +114,7 @@ var PlaybackObserver = /** @class */ (function () {
|
|
|
114
114
|
*/
|
|
115
115
|
PlaybackObserver.prototype.setCurrentTime = function (time) {
|
|
116
116
|
this._internalSeeksIncoming.push(time);
|
|
117
|
+
log.info("API: Seeking internally", time);
|
|
117
118
|
this._mediaElement.currentTime = time;
|
|
118
119
|
};
|
|
119
120
|
/**
|
|
@@ -89,7 +89,7 @@ var Player = /** @class */ (function (_super) {
|
|
|
89
89
|
// Workaround to support Firefox autoplay on FF 42.
|
|
90
90
|
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1194624
|
|
91
91
|
videoElement.preload = "auto";
|
|
92
|
-
_this.version = /* PLAYER_VERSION */ "3.30.1-dev.
|
|
92
|
+
_this.version = /* PLAYER_VERSION */ "3.30.1-dev.2023032800";
|
|
93
93
|
_this.log = log;
|
|
94
94
|
_this.state = "STOPPED";
|
|
95
95
|
_this.videoElement = videoElement;
|
|
@@ -1165,6 +1165,7 @@ var Player = /** @class */ (function (_super) {
|
|
|
1165
1165
|
if (positionWanted === undefined) {
|
|
1166
1166
|
throw new Error("invalid time given");
|
|
1167
1167
|
}
|
|
1168
|
+
log.info("API: API Seek to", positionWanted);
|
|
1168
1169
|
this.videoElement.currentTime = positionWanted;
|
|
1169
1170
|
return positionWanted;
|
|
1170
1171
|
};
|
|
@@ -2339,5 +2340,5 @@ var Player = /** @class */ (function (_super) {
|
|
|
2339
2340
|
};
|
|
2340
2341
|
return Player;
|
|
2341
2342
|
}(EventEmitter));
|
|
2342
|
-
Player.version = /* PLAYER_VERSION */ "3.30.1-dev.
|
|
2343
|
+
Player.version = /* PLAYER_VERSION */ "3.30.1-dev.2023032800";
|
|
2343
2344
|
export default Player;
|
|
@@ -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 log from "../../../log";
|
|
52
53
|
/**
|
|
53
54
|
* Close sessions from the loadedSessionsStore to allow at maximum `limit`
|
|
54
55
|
* stored MediaKeySessions in it.
|
|
@@ -67,6 +68,7 @@ export default function cleanOldLoadedSessions(loadedSessionsStore, limit) {
|
|
|
67
68
|
if (limit < 0 || limit >= loadedSessionsStore.getLength()) {
|
|
68
69
|
return [2 /*return*/];
|
|
69
70
|
}
|
|
71
|
+
log.info("DRM: LSS cache limit exceeded", limit, loadedSessionsStore.getLength());
|
|
70
72
|
proms = [];
|
|
71
73
|
entries = loadedSessionsStore.getAll().slice();
|
|
72
74
|
toDelete = entries.length - limit;
|
|
@@ -92,6 +92,7 @@ var LoadedSessionsStore = /** @class */ (function () {
|
|
|
92
92
|
LoadedSessionsStore.prototype.createSession = function (initData, sessionType) {
|
|
93
93
|
var _this = this;
|
|
94
94
|
var keySessionRecord = new KeySessionRecord(initData);
|
|
95
|
+
log.debug("DRM-LSS: calling `createSession`", sessionType);
|
|
95
96
|
var mediaKeySession = this._mediaKeys.createSession(sessionType);
|
|
96
97
|
var entry = { mediaKeySession: mediaKeySession, sessionType: sessionType, keySessionRecord: keySessionRecord, isGeneratingRequest: false,
|
|
97
98
|
isLoadingPersistentSession: false,
|
|
@@ -99,6 +100,7 @@ var LoadedSessionsStore = /** @class */ (function () {
|
|
|
99
100
|
if (!isNullOrUndefined(mediaKeySession.closed)) {
|
|
100
101
|
mediaKeySession.closed
|
|
101
102
|
.then(function () {
|
|
103
|
+
log.info("DRM-LSS: session was closed, removing it.", mediaKeySession.sessionId);
|
|
102
104
|
var index = _this.getIndex(keySessionRecord);
|
|
103
105
|
if (index >= 0 &&
|
|
104
106
|
_this._storage[index].mediaKeySession === mediaKeySession) {
|
|
@@ -110,8 +112,8 @@ var LoadedSessionsStore = /** @class */ (function () {
|
|
|
110
112
|
log.warn("DRM-LSS: MediaKeySession.closed rejected: ".concat(e));
|
|
111
113
|
});
|
|
112
114
|
}
|
|
113
|
-
log.debug("DRM-LSS: Add MediaKeySession", entry.sessionType);
|
|
114
115
|
this._storage.push(__assign({}, entry));
|
|
116
|
+
log.debug("DRM-LSS: MediaKeySession added", entry.sessionType, this._storage.length);
|
|
115
117
|
return entry;
|
|
116
118
|
};
|
|
117
119
|
/**
|
|
@@ -132,6 +134,7 @@ var LoadedSessionsStore = /** @class */ (function () {
|
|
|
132
134
|
if (stored.keySessionRecord.isCompatibleWith(initializationData)) {
|
|
133
135
|
this._storage.splice(i, 1);
|
|
134
136
|
this._storage.push(stored);
|
|
137
|
+
log.debug("DRM-LSS: Reusing session:", stored.mediaKeySession.sessionId, stored.sessionType);
|
|
135
138
|
return __assign({}, stored);
|
|
136
139
|
}
|
|
137
140
|
}
|
|
@@ -365,6 +368,7 @@ var LoadedSessionsStore = /** @class */ (function () {
|
|
|
365
368
|
for (var i = this._storage.length - 1; i >= 0; i--) {
|
|
366
369
|
var stored = this._storage[i];
|
|
367
370
|
if (stored.mediaKeySession === mediaKeySession) {
|
|
371
|
+
log.debug("DRM-LSS: Removing session without closing it", mediaKeySession.sessionId);
|
|
368
372
|
this._storage.splice(i, 1);
|
|
369
373
|
return true;
|
|
370
374
|
}
|
|
@@ -87,7 +87,7 @@ import getInitialTime from "./utils/get_initial_time";
|
|
|
87
87
|
import getLoadedReference from "./utils/get_loaded_reference";
|
|
88
88
|
import performInitialSeekAndPlay from "./utils/initial_seek_and_play";
|
|
89
89
|
import initializeContentDecryption from "./utils/initialize_content_decryption";
|
|
90
|
-
import
|
|
90
|
+
import MediaSourceDurationUpdater from "./utils/media_source_duration_updater";
|
|
91
91
|
import RebufferingController from "./utils/rebuffering_controller";
|
|
92
92
|
import streamEventsEmitter from "./utils/stream_events_emitter";
|
|
93
93
|
import listenToMediaError from "./utils/throw_on_media_error";
|
|
@@ -501,9 +501,9 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
|
|
|
501
501
|
MediaSourceContentInitializer.prototype._createContentTimeBoundariesObserver = function (manifest, mediaSource, streamObserver, segmentBuffersStore, cancelSignal) {
|
|
502
502
|
var _this = this;
|
|
503
503
|
/** Maintains the MediaSource's duration up-to-date with the Manifest */
|
|
504
|
-
var
|
|
504
|
+
var mediaSourceDurationUpdater = new MediaSourceDurationUpdater(mediaSource);
|
|
505
505
|
cancelSignal.register(function () {
|
|
506
|
-
|
|
506
|
+
mediaSourceDurationUpdater.stopUpdating();
|
|
507
507
|
});
|
|
508
508
|
/** Allows to cancel a pending `end-of-stream` operation. */
|
|
509
509
|
var endOfStreamCanceller = null;
|
|
@@ -518,8 +518,7 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
|
|
|
518
518
|
_this.trigger("activePeriodChanged", { period: period });
|
|
519
519
|
});
|
|
520
520
|
contentTimeBoundariesObserver.addEventListener("durationUpdate", function (newDuration) {
|
|
521
|
-
|
|
522
|
-
mediaDurationUpdater.updateKnownDuration(newDuration);
|
|
521
|
+
mediaSourceDurationUpdater.updateDuration(newDuration.duration, !newDuration.isEnd);
|
|
523
522
|
});
|
|
524
523
|
contentTimeBoundariesObserver.addEventListener("endOfStream", function () {
|
|
525
524
|
if (endOfStreamCanceller === null) {
|
|
@@ -536,6 +535,8 @@ var MediaSourceContentInitializer = /** @class */ (function (_super) {
|
|
|
536
535
|
endOfStreamCanceller = null;
|
|
537
536
|
}
|
|
538
537
|
});
|
|
538
|
+
var currentDuration = contentTimeBoundariesObserver.getCurrentDuration();
|
|
539
|
+
mediaSourceDurationUpdater.updateDuration(currentDuration.duration, !currentDuration.isEnd);
|
|
539
540
|
return contentTimeBoundariesObserver;
|
|
540
541
|
};
|
|
541
542
|
/**
|
|
@@ -55,6 +55,11 @@ export default class ContentTimeBoundariesObserver extends EventEmitter<IContent
|
|
|
55
55
|
* @param {Object} playbackObserver
|
|
56
56
|
*/
|
|
57
57
|
constructor(manifest: Manifest, playbackObserver: IReadOnlyPlaybackObserver<IStreamOrchestratorPlaybackObservation>, bufferTypes: IBufferType[]);
|
|
58
|
+
/**
|
|
59
|
+
* Returns an estimate of the current duration of the content.
|
|
60
|
+
* @returns {Object}
|
|
61
|
+
*/
|
|
62
|
+
getCurrentDuration(): IDurationItem;
|
|
58
63
|
/**
|
|
59
64
|
* Method to call any time an Adaptation has been selected.
|
|
60
65
|
*
|
|
@@ -121,9 +126,31 @@ export default class ContentTimeBoundariesObserver extends EventEmitter<IContent
|
|
|
121
126
|
private _addActivelyLoadedPeriod;
|
|
122
127
|
private _removeActivelyLoadedPeriod;
|
|
123
128
|
private _checkCurrentPeriod;
|
|
129
|
+
private _getManifestDuration;
|
|
124
130
|
private _lazilyCreateActiveStreamInfo;
|
|
125
131
|
private _checkEndOfStream;
|
|
126
132
|
}
|
|
133
|
+
export interface IDurationItem {
|
|
134
|
+
/**
|
|
135
|
+
* The new maximum known position (note that this is the ending position
|
|
136
|
+
* currently known of the current content, it might be superior to the last
|
|
137
|
+
* position at which segments are available and it might also evolve over
|
|
138
|
+
* time), in seconds.
|
|
139
|
+
*/
|
|
140
|
+
duration: number;
|
|
141
|
+
/**
|
|
142
|
+
* If `true`, the communicated `duration` is the actual end of the content.
|
|
143
|
+
* It may still be updated due to a track change or to add precision, but it
|
|
144
|
+
* is still a (rough) estimate of the maximum position that content should
|
|
145
|
+
* have.
|
|
146
|
+
*
|
|
147
|
+
* If `false`, this is the currently known maximum position associated to
|
|
148
|
+
* the content, but the content is still evolving (typically, new media
|
|
149
|
+
* segments are still being generated) and as such it can still have a
|
|
150
|
+
* longer duration in the future.
|
|
151
|
+
*/
|
|
152
|
+
isEnd: boolean;
|
|
153
|
+
}
|
|
127
154
|
/**
|
|
128
155
|
* Events triggered by a `ContentTimeBoundariesObserver` where the keys are the
|
|
129
156
|
* event names and the value is the payload of those events.
|
|
@@ -137,7 +164,7 @@ export interface IContentTimeBoundariesObserverEvent {
|
|
|
137
164
|
* Triggered when the duration of the currently-playing content became known
|
|
138
165
|
* or changed.
|
|
139
166
|
*/
|
|
140
|
-
durationUpdate:
|
|
167
|
+
durationUpdate: IDurationItem;
|
|
141
168
|
/**
|
|
142
169
|
* Triggered when the last possible chronological segment for all types of
|
|
143
170
|
* buffers has either been pushed or is being pushed to the corresponding
|
|
@@ -82,19 +82,21 @@ var ContentTimeBoundariesObserver = /** @class */ (function (_super) {
|
|
|
82
82
|
}
|
|
83
83
|
}, { includeLastObservation: true, clearSignal: cancelSignal });
|
|
84
84
|
manifest.addEventListener("manifestUpdate", function () {
|
|
85
|
-
_this.trigger("durationUpdate",
|
|
85
|
+
_this.trigger("durationUpdate", _this._getManifestDuration());
|
|
86
86
|
if (cancelSignal.isCancelled()) {
|
|
87
87
|
return;
|
|
88
88
|
}
|
|
89
89
|
_this._checkEndOfStream();
|
|
90
90
|
}, cancelSignal);
|
|
91
|
-
function getManifestDuration() {
|
|
92
|
-
return manifest.isDynamic ?
|
|
93
|
-
maximumPositionCalculator.getMaximumAvailablePosition() :
|
|
94
|
-
maximumPositionCalculator.getEndingPosition();
|
|
95
|
-
}
|
|
96
91
|
return _this;
|
|
97
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Returns an estimate of the current duration of the content.
|
|
95
|
+
* @returns {Object}
|
|
96
|
+
*/
|
|
97
|
+
ContentTimeBoundariesObserver.prototype.getCurrentDuration = function () {
|
|
98
|
+
return this._getManifestDuration();
|
|
99
|
+
};
|
|
98
100
|
/**
|
|
99
101
|
* Method to call any time an Adaptation has been selected.
|
|
100
102
|
*
|
|
@@ -121,9 +123,12 @@ var ContentTimeBoundariesObserver = /** @class */ (function (_super) {
|
|
|
121
123
|
this._maximumPositionCalculator
|
|
122
124
|
.updateLastVideoAdaptation(adaptation);
|
|
123
125
|
}
|
|
124
|
-
var
|
|
125
|
-
|
|
126
|
-
|
|
126
|
+
var endingPosition = this._maximumPositionCalculator.getEndingPosition();
|
|
127
|
+
var newDuration = endingPosition !== undefined ?
|
|
128
|
+
{ isEnd: true,
|
|
129
|
+
duration: endingPosition } :
|
|
130
|
+
{ isEnd: false,
|
|
131
|
+
duration: this._maximumPositionCalculator.getMaximumAvailablePosition() };
|
|
127
132
|
this.trigger("durationUpdate", newDuration);
|
|
128
133
|
}
|
|
129
134
|
}
|
|
@@ -258,6 +263,14 @@ var ContentTimeBoundariesObserver = /** @class */ (function (_super) {
|
|
|
258
263
|
return state_1.value;
|
|
259
264
|
}
|
|
260
265
|
};
|
|
266
|
+
ContentTimeBoundariesObserver.prototype._getManifestDuration = function () {
|
|
267
|
+
var endingPosition = this._maximumPositionCalculator.getEndingPosition();
|
|
268
|
+
return endingPosition !== undefined ?
|
|
269
|
+
{ isEnd: true,
|
|
270
|
+
duration: endingPosition } :
|
|
271
|
+
{ isEnd: false,
|
|
272
|
+
duration: this._maximumPositionCalculator.getMaximumAvailablePosition() };
|
|
273
|
+
};
|
|
261
274
|
ContentTimeBoundariesObserver.prototype._lazilyCreateActiveStreamInfo = function (bufferType) {
|
|
262
275
|
var streamInfo = this._activeStreams.get(bufferType);
|
|
263
276
|
if (streamInfo === undefined) {
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2015 CANAL+ Group
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Keep the MediaSource's `duration` attribute up-to-date with the duration of
|
|
18
|
+
* the content played on it.
|
|
19
|
+
* @class MediaSourceDurationUpdater
|
|
20
|
+
*/
|
|
21
|
+
export default class MediaSourceDurationUpdater {
|
|
22
|
+
/**
|
|
23
|
+
* `MediaSource` on which we're going to update the `duration` attribute.
|
|
24
|
+
*/
|
|
25
|
+
private _mediaSource;
|
|
26
|
+
/**
|
|
27
|
+
* Abort the current duration-setting logic.
|
|
28
|
+
* `null` if no such logic is pending.
|
|
29
|
+
*/
|
|
30
|
+
private _currentMediaSourceDurationUpdateCanceller;
|
|
31
|
+
/**
|
|
32
|
+
* Create a new `MediaSourceDurationUpdater`,
|
|
33
|
+
* @param {MediaSource} mediaSource - The MediaSource on which the content is
|
|
34
|
+
* played.
|
|
35
|
+
*/
|
|
36
|
+
constructor(mediaSource: MediaSource);
|
|
37
|
+
/**
|
|
38
|
+
* Indicate to the `MediaSourceDurationUpdater` the currently known duration
|
|
39
|
+
* of the content.
|
|
40
|
+
*
|
|
41
|
+
* The `MediaSourceDurationUpdater` will then use that value to determine
|
|
42
|
+
* which `duration` attribute should be set on the `MediaSource` associated
|
|
43
|
+
*
|
|
44
|
+
* @param {number} newDuration
|
|
45
|
+
* @param {boolean} addTimeMargin - If set to `true`, the current content is
|
|
46
|
+
* a dynamic content (it might evolve in the future) and the `newDuration`
|
|
47
|
+
* communicated might be greater still. In effect the
|
|
48
|
+
* `MediaSourceDurationUpdater` will actually set a much higher value to the
|
|
49
|
+
* `MediaSource`'s duration to prevent being annoyed by the HTML-related
|
|
50
|
+
* side-effects of having a too low duration (such as the impossibility to
|
|
51
|
+
* seek over that value).
|
|
52
|
+
*/
|
|
53
|
+
updateDuration(newDuration: number, addTimeMargin: boolean): void;
|
|
54
|
+
/**
|
|
55
|
+
* Abort the last duration-setting operation and free its resources.
|
|
56
|
+
*/
|
|
57
|
+
stopUpdating(): void;
|
|
58
|
+
}
|