@gcorevideo/player 2.6.0 → 2.6.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 +25 -171
- package/lib/plugins/dash-playback/DashPlayback.d.ts +0 -2
- package/lib/plugins/dash-playback/DashPlayback.d.ts.map +1 -1
- package/lib/plugins/dash-playback/DashPlayback.js +25 -171
- package/package.json +1 -1
- package/src/plugins/dash-playback/DashPlayback.ts +26 -195
- package/tsconfig.tsbuildinfo +1 -1
package/dist/index.js
CHANGED
|
@@ -12222,22 +12222,39 @@ const T$2 = 'DashPlayback';
|
|
|
12222
12222
|
class DashPlayback extends HTML5Video {
|
|
12223
12223
|
_levels = null;
|
|
12224
12224
|
_currentLevel = null;
|
|
12225
|
+
// true when the actual duration is longer than hlsjs's live sync point
|
|
12226
|
+
// when this is false playableRegionDuration will be the actual duration
|
|
12227
|
+
// when this is true playableRegionDuration will exclude the time after the sync point
|
|
12225
12228
|
_durationExcludesAfterLiveSyncPoint = false;
|
|
12226
12229
|
_isReadyState = false;
|
|
12230
|
+
// if content is removed from the beginning then this empty area should
|
|
12231
|
+
// be ignored. "playableRegionDuration" excludes the empty area
|
|
12227
12232
|
_playableRegionDuration = 0;
|
|
12233
|
+
// for hls streams which have dvr with a sliding window,
|
|
12234
|
+
// the content at the start of the playlist is removed as new
|
|
12235
|
+
// content is appended at the end.
|
|
12236
|
+
// this means the actual playable start time will increase as the
|
|
12237
|
+
// start content is deleted
|
|
12238
|
+
// For streams with dvr where the entire recording is kept from the
|
|
12239
|
+
// beginning this should stay as 0
|
|
12228
12240
|
_playableRegionStartTime = 0;
|
|
12229
12241
|
_playbackType = Playback.VOD;
|
|
12242
|
+
// #EXT-X-PLAYLIST-TYPE
|
|
12230
12243
|
_playlistType = null;
|
|
12231
12244
|
// #EXT-X-PROGRAM-DATE-TIME
|
|
12232
12245
|
_programDateTime = 0;
|
|
12233
12246
|
_dash = null;
|
|
12234
12247
|
_extrapolatedWindowDuration = 0;
|
|
12235
|
-
_extrapolatedWindowNumSegments = 0
|
|
12248
|
+
// _extrapolatedWindowNumSegments: number = 0
|
|
12236
12249
|
_lastDuration = null;
|
|
12237
12250
|
_lastTimeUpdate = { current: 0, total: 0 };
|
|
12251
|
+
// {local, remote} remote is the time in the video element that should represent 0
|
|
12252
|
+
// local is the system time when the 'remote' measurment took place
|
|
12238
12253
|
_localStartTimeCorrelation = null;
|
|
12254
|
+
// {local, remote} remote is the time in the video element that should represents the end
|
|
12255
|
+
// local is the system time when the 'remote' measurment took place
|
|
12239
12256
|
_localEndTimeCorrelation = null;
|
|
12240
|
-
_recoverAttemptsRemaining = 0
|
|
12257
|
+
// _recoverAttemptsRemaining: number = 0
|
|
12241
12258
|
_recoveredAudioCodecError = false;
|
|
12242
12259
|
_recoveredDecodingError = false;
|
|
12243
12260
|
startChangeQuality = false;
|
|
@@ -12333,50 +12350,13 @@ class DashPlayback extends HTML5Video {
|
|
|
12333
12350
|
}
|
|
12334
12351
|
constructor(options, i18n, playerError) {
|
|
12335
12352
|
super(options, i18n, playerError);
|
|
12336
|
-
|
|
12337
|
-
// this.options.playback || (this.options.playback = this.options);
|
|
12338
|
-
// The size of the start time extrapolation window measured as a multiple of segments.
|
|
12339
|
-
// Should be 2 or higher, or 0 to disable. Should only need to be increased above 2 if more than one segment is
|
|
12340
|
-
// removed from the start of the playlist at a time. E.g if the playlist is cached for 10 seconds and new chunks are
|
|
12341
|
-
// added/removed every 5.
|
|
12342
|
-
this._extrapolatedWindowNumSegments =
|
|
12343
|
-
this.options.playback?.extrapolatedWindowNumSegments ?? 2;
|
|
12353
|
+
trace(`${T$2} constructor`, { options });
|
|
12344
12354
|
if (this.options.playbackType) {
|
|
12345
12355
|
this._playbackType = this.options.playbackType;
|
|
12346
12356
|
}
|
|
12347
|
-
// this.
|
|
12348
|
-
//
|
|
12349
|
-
//
|
|
12350
|
-
// the content at the start of the playlist is removed as new
|
|
12351
|
-
// content is appended at the end.
|
|
12352
|
-
// this means the actual playable start time will increase as the
|
|
12353
|
-
// start content is deleted
|
|
12354
|
-
// For streams with dvr where the entire recording is kept from the
|
|
12355
|
-
// beginning this should stay as 0
|
|
12356
|
-
// this._playableRegionStartTime = 0;
|
|
12357
|
-
// {local, remote} remote is the time in the video element that should represent 0
|
|
12358
|
-
// local is the system time when the 'remote' measurment took place
|
|
12359
|
-
// this._localStartTimeCorrelation = null;
|
|
12360
|
-
// {local, remote} remote is the time in the video element that should represents the end
|
|
12361
|
-
// local is the system time when the 'remote' measurment took place
|
|
12362
|
-
// this._localEndTimeCorrelation = null;
|
|
12363
|
-
// if content is removed from the beginning then this empty area should
|
|
12364
|
-
// be ignored. "playableRegionDuration" excludes the empty area
|
|
12365
|
-
// this._playableRegionDuration = 0;
|
|
12366
|
-
// #EXT-X-PROGRAM-DATE-TIME
|
|
12367
|
-
// this._programDateTime = 0;
|
|
12368
|
-
// this.manifestInfo = null;
|
|
12369
|
-
// true when the actual duration is longer than hlsjs's live sync point
|
|
12370
|
-
// when this is false playableRegionDuration will be the actual duration
|
|
12371
|
-
// when this is true playableRegionDuration will exclude the time after the sync point
|
|
12372
|
-
// this._durationExcludesAfterLiveSyncPoint = false;
|
|
12373
|
-
// // #EXT-X-TARGETDURATION
|
|
12374
|
-
// this._segmentTargetDuration = null;
|
|
12375
|
-
// #EXT-X-PLAYLIST-TYPE
|
|
12376
|
-
// this._playlistType = null;
|
|
12377
|
-
if (this.options.hlsRecoverAttempts) {
|
|
12378
|
-
this._recoverAttemptsRemaining = this.options.hlsRecoverAttempts;
|
|
12379
|
-
}
|
|
12357
|
+
// if (this.options.hlsRecoverAttempts) {
|
|
12358
|
+
// this._recoverAttemptsRemaining = this.options.hlsRecoverAttempts
|
|
12359
|
+
// }
|
|
12380
12360
|
}
|
|
12381
12361
|
_setup() {
|
|
12382
12362
|
const dash = DASHJS.MediaPlayer().create();
|
|
@@ -12712,131 +12692,6 @@ class DashPlayback extends HTML5Video {
|
|
|
12712
12692
|
});
|
|
12713
12693
|
this.trigger(Events$1.PLAYBACK_LEVELS_AVAILABLE, this._levels);
|
|
12714
12694
|
}
|
|
12715
|
-
// _onLevelUpdated(_: any, data) {
|
|
12716
|
-
// this._segmentTargetDuration = data.details.targetduration;
|
|
12717
|
-
// this._playlistType = data.details.type || null;
|
|
12718
|
-
// let startTimeChanged = false;
|
|
12719
|
-
// let durationChanged = false;
|
|
12720
|
-
// const fragments = data.details.fragments;
|
|
12721
|
-
// const previousPlayableRegionStartTime = this._playableRegionStartTime;
|
|
12722
|
-
// const previousPlayableRegionDuration = this._playableRegionDuration;
|
|
12723
|
-
// if (fragments.length === 0) {
|
|
12724
|
-
// return;
|
|
12725
|
-
// }
|
|
12726
|
-
// // #EXT-X-PROGRAM-DATE-TIME
|
|
12727
|
-
// if (fragments[0].rawProgramDateTime) {
|
|
12728
|
-
// this._programDateTime = fragments[0].rawProgramDateTime;
|
|
12729
|
-
// }
|
|
12730
|
-
// if (this._playableRegionStartTime !== fragments[0].start) {
|
|
12731
|
-
// startTimeChanged = true;
|
|
12732
|
-
// this._playableRegionStartTime = fragments[0].start;
|
|
12733
|
-
// }
|
|
12734
|
-
// if (startTimeChanged) {
|
|
12735
|
-
// if (!this._localStartTimeCorrelation) {
|
|
12736
|
-
// // set the correlation to map to middle of the extrapolation window
|
|
12737
|
-
// this._localStartTimeCorrelation = {
|
|
12738
|
-
// local: this._now,
|
|
12739
|
-
// remote: (fragments[0].start + (this._extrapolatedWindowDuration / 2)) * 1000
|
|
12740
|
-
// };
|
|
12741
|
-
// } else {
|
|
12742
|
-
// // check if the correlation still works
|
|
12743
|
-
// const corr = this._localStartTimeCorrelation;
|
|
12744
|
-
// const timePassed = this._now - corr.local;
|
|
12745
|
-
// // this should point to a time within the extrapolation window
|
|
12746
|
-
// const startTime = (corr.remote + timePassed) / 1000;
|
|
12747
|
-
// if (startTime < fragments[0].start) {
|
|
12748
|
-
// // our start time is now earlier than the first chunk
|
|
12749
|
-
// // (maybe the chunk was removed early)
|
|
12750
|
-
// // reset correlation so that it sits at the beginning of the first available chunk
|
|
12751
|
-
// this._localStartTimeCorrelation = {
|
|
12752
|
-
// local: this._now,
|
|
12753
|
-
// remote: fragments[0].start * 1000
|
|
12754
|
-
// };
|
|
12755
|
-
// } else if (startTime > previousPlayableRegionStartTime + this._extrapolatedWindowDuration) {
|
|
12756
|
-
// // start time was past the end of the old extrapolation window (so would have been capped)
|
|
12757
|
-
// // see if now that time would be inside the window, and if it would be set the correlation
|
|
12758
|
-
// // so that it resumes from the time it was at at the end of the old window
|
|
12759
|
-
// // update the correlation so that the time starts counting again from the value it's on now
|
|
12760
|
-
// this._localStartTimeCorrelation = {
|
|
12761
|
-
// local: this._now,
|
|
12762
|
-
// remote: Math.max(
|
|
12763
|
-
// fragments[0].start,
|
|
12764
|
-
// previousPlayableRegionStartTime + this._extrapolatedWindowDuration
|
|
12765
|
-
// ) * 1000
|
|
12766
|
-
// };
|
|
12767
|
-
// }
|
|
12768
|
-
// }
|
|
12769
|
-
// }
|
|
12770
|
-
// let newDuration = data.details.totalduration;
|
|
12771
|
-
// // if it's a live stream then shorten the duration to remove access
|
|
12772
|
-
// // to the area after hlsjs's live sync point
|
|
12773
|
-
// // seeks to areas after this point sometimes have issues
|
|
12774
|
-
// if (this._playbackType === Playback.LIVE) {
|
|
12775
|
-
// const fragmentTargetDuration = data.details.targetduration;
|
|
12776
|
-
// const hlsjsConfig = this.options.playback.hlsjsConfig || {};
|
|
12777
|
-
// // eslint-disable-next-line no-undef
|
|
12778
|
-
// const liveSyncDurationCount = hlsjsConfig.liveSyncDurationCount || HLSJS.DefaultConfig.liveSyncDurationCount;
|
|
12779
|
-
// const hiddenAreaDuration = fragmentTargetDuration * liveSyncDurationCount;
|
|
12780
|
-
// if (hiddenAreaDuration <= newDuration) {
|
|
12781
|
-
// newDuration -= hiddenAreaDuration;
|
|
12782
|
-
// this._durationExcludesAfterLiveSyncPoint = true;
|
|
12783
|
-
// } else {
|
|
12784
|
-
// this._durationExcludesAfterLiveSyncPoint = false;
|
|
12785
|
-
// }
|
|
12786
|
-
// }
|
|
12787
|
-
// if (newDuration !== this._playableRegionDuration) {
|
|
12788
|
-
// durationChanged = true;
|
|
12789
|
-
// this._playableRegionDuration = newDuration;
|
|
12790
|
-
// }
|
|
12791
|
-
// // Note the end time is not the playableRegionDuration
|
|
12792
|
-
// // The end time will always increase even if content is removed from the beginning
|
|
12793
|
-
// const endTime = fragments[0].start + newDuration;
|
|
12794
|
-
// const previousEndTime = previousPlayableRegionStartTime + previousPlayableRegionDuration;
|
|
12795
|
-
// const endTimeChanged = endTime !== previousEndTime;
|
|
12796
|
-
// if (endTimeChanged) {
|
|
12797
|
-
// if (!this._localEndTimeCorrelation) {
|
|
12798
|
-
// // set the correlation to map to the end
|
|
12799
|
-
// this._localEndTimeCorrelation = {
|
|
12800
|
-
// local: this._now,
|
|
12801
|
-
// remote: endTime * 1000
|
|
12802
|
-
// };
|
|
12803
|
-
// } else {
|
|
12804
|
-
// // check if the correlation still works
|
|
12805
|
-
// const corr = this._localEndTimeCorrelation;
|
|
12806
|
-
// const timePassed = this._now - corr.local;
|
|
12807
|
-
// // this should point to a time within the extrapolation window from the end
|
|
12808
|
-
// const extrapolatedEndTime = (corr.remote + timePassed) / 1000;
|
|
12809
|
-
// if (extrapolatedEndTime > endTime) {
|
|
12810
|
-
// this._localEndTimeCorrelation = {
|
|
12811
|
-
// local: this._now,
|
|
12812
|
-
// remote: endTime * 1000
|
|
12813
|
-
// };
|
|
12814
|
-
// } else if (extrapolatedEndTime < endTime - this._extrapolatedWindowDuration) {
|
|
12815
|
-
// // our extrapolated end time is now earlier than the extrapolation window from the actual end time
|
|
12816
|
-
// // (maybe a chunk became available early)
|
|
12817
|
-
// // reset correlation so that it sits at the beginning of the extrapolation window from the end time
|
|
12818
|
-
// this._localEndTimeCorrelation = {
|
|
12819
|
-
// local: this._now,
|
|
12820
|
-
// remote: (endTime - this._extrapolatedWindowDuration) * 1000
|
|
12821
|
-
// };
|
|
12822
|
-
// } else if (extrapolatedEndTime > previousEndTime) {
|
|
12823
|
-
// // end time was past the old end time (so would have been capped)
|
|
12824
|
-
// // set the correlation so that it resumes from the time it was at at the end of the old window
|
|
12825
|
-
// this._localEndTimeCorrelation = {
|
|
12826
|
-
// local: this._now,
|
|
12827
|
-
// remote: previousEndTime * 1000
|
|
12828
|
-
// };
|
|
12829
|
-
// }
|
|
12830
|
-
// }
|
|
12831
|
-
// }
|
|
12832
|
-
// // now that the values have been updated call any methods that use on them so they get the updated values
|
|
12833
|
-
// // immediately
|
|
12834
|
-
// durationChanged && this._onDurationChange();
|
|
12835
|
-
// startTimeChanged && this._onProgress();
|
|
12836
|
-
// }
|
|
12837
|
-
// _onFragmentLoaded(evt, data) {
|
|
12838
|
-
// this.trigger(Events.PLAYBACK_FRAGMENT_LOADED, data);
|
|
12839
|
-
// }
|
|
12840
12695
|
onLevelSwitch(currentLevel) {
|
|
12841
12696
|
this.trigger(Events$1.PLAYBACK_BITRATE, {
|
|
12842
12697
|
height: currentLevel.height,
|
|
@@ -12857,7 +12712,6 @@ DashPlayback.canPlay = function (resource, mimeType) {
|
|
|
12857
12712
|
const isDash = (resourceParts.length > 1 && resourceParts[1].toLowerCase() === 'mpd') ||
|
|
12858
12713
|
mimeType === 'application/dash+xml' ||
|
|
12859
12714
|
mimeType === 'video/mp4';
|
|
12860
|
-
// TODO check
|
|
12861
12715
|
const ms = window.MediaSource;
|
|
12862
12716
|
const mms = 'ManagedMediaSource' in window ? window.ManagedMediaSource : undefined;
|
|
12863
12717
|
const wms = 'WebKitMediaSource' in window ? window.WebKitMediaSource : undefined;
|
|
@@ -42738,12 +42592,12 @@ class SentryTracer {
|
|
|
42738
42592
|
}
|
|
42739
42593
|
}
|
|
42740
42594
|
|
|
42741
|
-
var version$1 = "2.6.
|
|
42595
|
+
var version$1 = "2.6.1";
|
|
42742
42596
|
|
|
42743
42597
|
var packages = {
|
|
42744
42598
|
"": {
|
|
42745
42599
|
name: "@gcorevideo/player",
|
|
42746
|
-
version: "2.6.
|
|
42600
|
+
version: "2.6.1",
|
|
42747
42601
|
license: "Apache-2.0",
|
|
42748
42602
|
dependencies: {
|
|
42749
42603
|
"@clappr/core": "^0.11.3",
|
|
@@ -23,12 +23,10 @@ export default class DashPlayback extends HTML5Video {
|
|
|
23
23
|
_programDateTime: TimeValue;
|
|
24
24
|
_dash: DASHJS.MediaPlayerClass | null;
|
|
25
25
|
_extrapolatedWindowDuration: number;
|
|
26
|
-
_extrapolatedWindowNumSegments: number;
|
|
27
26
|
_lastDuration: TimeValue | null;
|
|
28
27
|
_lastTimeUpdate: TimePosition;
|
|
29
28
|
_localStartTimeCorrelation: LocalTimeCorrelation | null;
|
|
30
29
|
_localEndTimeCorrelation: LocalTimeCorrelation | null;
|
|
31
|
-
_recoverAttemptsRemaining: number;
|
|
32
30
|
_recoveredAudioCodecError: boolean;
|
|
33
31
|
_recoveredDecodingError: boolean;
|
|
34
32
|
startChangeQuality: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DashPlayback.d.ts","sourceRoot":"","sources":["../../../src/plugins/dash-playback/DashPlayback.ts"],"names":[],"mappings":"AAIA,OAAO,
|
|
1
|
+
{"version":3,"file":"DashPlayback.d.ts","sourceRoot":"","sources":["../../../src/plugins/dash-playback/DashPlayback.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Copyright 2014 Globo.com Player authors. All rights reserved.
|
|
2
2
|
// Use of this source code is governed by a BSD-style
|
|
3
3
|
// license that can be found in the LICENSE file.
|
|
4
|
-
import { Events, HTML5Video, Log, Playback, Utils
|
|
5
|
-
import assert from 'assert';
|
|
4
|
+
import { Events, HTML5Video, Log, Playback, Utils } from '@clappr/core';
|
|
5
|
+
import assert from 'assert';
|
|
6
6
|
import DASHJS from 'dashjs';
|
|
7
7
|
import { trace } from '../../trace/index.js';
|
|
8
8
|
const AUTO = -1;
|
|
@@ -11,22 +11,39 @@ const T = 'DashPlayback';
|
|
|
11
11
|
export default class DashPlayback extends HTML5Video {
|
|
12
12
|
_levels = null;
|
|
13
13
|
_currentLevel = null;
|
|
14
|
+
// true when the actual duration is longer than hlsjs's live sync point
|
|
15
|
+
// when this is false playableRegionDuration will be the actual duration
|
|
16
|
+
// when this is true playableRegionDuration will exclude the time after the sync point
|
|
14
17
|
_durationExcludesAfterLiveSyncPoint = false;
|
|
15
18
|
_isReadyState = false;
|
|
19
|
+
// if content is removed from the beginning then this empty area should
|
|
20
|
+
// be ignored. "playableRegionDuration" excludes the empty area
|
|
16
21
|
_playableRegionDuration = 0;
|
|
22
|
+
// for hls streams which have dvr with a sliding window,
|
|
23
|
+
// the content at the start of the playlist is removed as new
|
|
24
|
+
// content is appended at the end.
|
|
25
|
+
// this means the actual playable start time will increase as the
|
|
26
|
+
// start content is deleted
|
|
27
|
+
// For streams with dvr where the entire recording is kept from the
|
|
28
|
+
// beginning this should stay as 0
|
|
17
29
|
_playableRegionStartTime = 0;
|
|
18
30
|
_playbackType = Playback.VOD;
|
|
31
|
+
// #EXT-X-PLAYLIST-TYPE
|
|
19
32
|
_playlistType = null;
|
|
20
33
|
// #EXT-X-PROGRAM-DATE-TIME
|
|
21
34
|
_programDateTime = 0;
|
|
22
35
|
_dash = null;
|
|
23
36
|
_extrapolatedWindowDuration = 0;
|
|
24
|
-
_extrapolatedWindowNumSegments = 0
|
|
37
|
+
// _extrapolatedWindowNumSegments: number = 0
|
|
25
38
|
_lastDuration = null;
|
|
26
39
|
_lastTimeUpdate = { current: 0, total: 0 };
|
|
40
|
+
// {local, remote} remote is the time in the video element that should represent 0
|
|
41
|
+
// local is the system time when the 'remote' measurment took place
|
|
27
42
|
_localStartTimeCorrelation = null;
|
|
43
|
+
// {local, remote} remote is the time in the video element that should represents the end
|
|
44
|
+
// local is the system time when the 'remote' measurment took place
|
|
28
45
|
_localEndTimeCorrelation = null;
|
|
29
|
-
_recoverAttemptsRemaining = 0
|
|
46
|
+
// _recoverAttemptsRemaining: number = 0
|
|
30
47
|
_recoveredAudioCodecError = false;
|
|
31
48
|
_recoveredDecodingError = false;
|
|
32
49
|
startChangeQuality = false;
|
|
@@ -122,50 +139,13 @@ export default class DashPlayback extends HTML5Video {
|
|
|
122
139
|
}
|
|
123
140
|
constructor(options, i18n, playerError) {
|
|
124
141
|
super(options, i18n, playerError);
|
|
125
|
-
|
|
126
|
-
// this.options.playback || (this.options.playback = this.options);
|
|
127
|
-
// The size of the start time extrapolation window measured as a multiple of segments.
|
|
128
|
-
// Should be 2 or higher, or 0 to disable. Should only need to be increased above 2 if more than one segment is
|
|
129
|
-
// removed from the start of the playlist at a time. E.g if the playlist is cached for 10 seconds and new chunks are
|
|
130
|
-
// added/removed every 5.
|
|
131
|
-
this._extrapolatedWindowNumSegments =
|
|
132
|
-
this.options.playback?.extrapolatedWindowNumSegments ?? 2;
|
|
142
|
+
trace(`${T} constructor`, { options });
|
|
133
143
|
if (this.options.playbackType) {
|
|
134
144
|
this._playbackType = this.options.playbackType;
|
|
135
145
|
}
|
|
136
|
-
// this.
|
|
137
|
-
//
|
|
138
|
-
//
|
|
139
|
-
// the content at the start of the playlist is removed as new
|
|
140
|
-
// content is appended at the end.
|
|
141
|
-
// this means the actual playable start time will increase as the
|
|
142
|
-
// start content is deleted
|
|
143
|
-
// For streams with dvr where the entire recording is kept from the
|
|
144
|
-
// beginning this should stay as 0
|
|
145
|
-
// this._playableRegionStartTime = 0;
|
|
146
|
-
// {local, remote} remote is the time in the video element that should represent 0
|
|
147
|
-
// local is the system time when the 'remote' measurment took place
|
|
148
|
-
// this._localStartTimeCorrelation = null;
|
|
149
|
-
// {local, remote} remote is the time in the video element that should represents the end
|
|
150
|
-
// local is the system time when the 'remote' measurment took place
|
|
151
|
-
// this._localEndTimeCorrelation = null;
|
|
152
|
-
// if content is removed from the beginning then this empty area should
|
|
153
|
-
// be ignored. "playableRegionDuration" excludes the empty area
|
|
154
|
-
// this._playableRegionDuration = 0;
|
|
155
|
-
// #EXT-X-PROGRAM-DATE-TIME
|
|
156
|
-
// this._programDateTime = 0;
|
|
157
|
-
// this.manifestInfo = null;
|
|
158
|
-
// true when the actual duration is longer than hlsjs's live sync point
|
|
159
|
-
// when this is false playableRegionDuration will be the actual duration
|
|
160
|
-
// when this is true playableRegionDuration will exclude the time after the sync point
|
|
161
|
-
// this._durationExcludesAfterLiveSyncPoint = false;
|
|
162
|
-
// // #EXT-X-TARGETDURATION
|
|
163
|
-
// this._segmentTargetDuration = null;
|
|
164
|
-
// #EXT-X-PLAYLIST-TYPE
|
|
165
|
-
// this._playlistType = null;
|
|
166
|
-
if (this.options.hlsRecoverAttempts) {
|
|
167
|
-
this._recoverAttemptsRemaining = this.options.hlsRecoverAttempts;
|
|
168
|
-
}
|
|
146
|
+
// if (this.options.hlsRecoverAttempts) {
|
|
147
|
+
// this._recoverAttemptsRemaining = this.options.hlsRecoverAttempts
|
|
148
|
+
// }
|
|
169
149
|
}
|
|
170
150
|
_setup() {
|
|
171
151
|
const dash = DASHJS.MediaPlayer().create();
|
|
@@ -501,131 +481,6 @@ export default class DashPlayback extends HTML5Video {
|
|
|
501
481
|
});
|
|
502
482
|
this.trigger(Events.PLAYBACK_LEVELS_AVAILABLE, this._levels);
|
|
503
483
|
}
|
|
504
|
-
// _onLevelUpdated(_: any, data) {
|
|
505
|
-
// this._segmentTargetDuration = data.details.targetduration;
|
|
506
|
-
// this._playlistType = data.details.type || null;
|
|
507
|
-
// let startTimeChanged = false;
|
|
508
|
-
// let durationChanged = false;
|
|
509
|
-
// const fragments = data.details.fragments;
|
|
510
|
-
// const previousPlayableRegionStartTime = this._playableRegionStartTime;
|
|
511
|
-
// const previousPlayableRegionDuration = this._playableRegionDuration;
|
|
512
|
-
// if (fragments.length === 0) {
|
|
513
|
-
// return;
|
|
514
|
-
// }
|
|
515
|
-
// // #EXT-X-PROGRAM-DATE-TIME
|
|
516
|
-
// if (fragments[0].rawProgramDateTime) {
|
|
517
|
-
// this._programDateTime = fragments[0].rawProgramDateTime;
|
|
518
|
-
// }
|
|
519
|
-
// if (this._playableRegionStartTime !== fragments[0].start) {
|
|
520
|
-
// startTimeChanged = true;
|
|
521
|
-
// this._playableRegionStartTime = fragments[0].start;
|
|
522
|
-
// }
|
|
523
|
-
// if (startTimeChanged) {
|
|
524
|
-
// if (!this._localStartTimeCorrelation) {
|
|
525
|
-
// // set the correlation to map to middle of the extrapolation window
|
|
526
|
-
// this._localStartTimeCorrelation = {
|
|
527
|
-
// local: this._now,
|
|
528
|
-
// remote: (fragments[0].start + (this._extrapolatedWindowDuration / 2)) * 1000
|
|
529
|
-
// };
|
|
530
|
-
// } else {
|
|
531
|
-
// // check if the correlation still works
|
|
532
|
-
// const corr = this._localStartTimeCorrelation;
|
|
533
|
-
// const timePassed = this._now - corr.local;
|
|
534
|
-
// // this should point to a time within the extrapolation window
|
|
535
|
-
// const startTime = (corr.remote + timePassed) / 1000;
|
|
536
|
-
// if (startTime < fragments[0].start) {
|
|
537
|
-
// // our start time is now earlier than the first chunk
|
|
538
|
-
// // (maybe the chunk was removed early)
|
|
539
|
-
// // reset correlation so that it sits at the beginning of the first available chunk
|
|
540
|
-
// this._localStartTimeCorrelation = {
|
|
541
|
-
// local: this._now,
|
|
542
|
-
// remote: fragments[0].start * 1000
|
|
543
|
-
// };
|
|
544
|
-
// } else if (startTime > previousPlayableRegionStartTime + this._extrapolatedWindowDuration) {
|
|
545
|
-
// // start time was past the end of the old extrapolation window (so would have been capped)
|
|
546
|
-
// // see if now that time would be inside the window, and if it would be set the correlation
|
|
547
|
-
// // so that it resumes from the time it was at at the end of the old window
|
|
548
|
-
// // update the correlation so that the time starts counting again from the value it's on now
|
|
549
|
-
// this._localStartTimeCorrelation = {
|
|
550
|
-
// local: this._now,
|
|
551
|
-
// remote: Math.max(
|
|
552
|
-
// fragments[0].start,
|
|
553
|
-
// previousPlayableRegionStartTime + this._extrapolatedWindowDuration
|
|
554
|
-
// ) * 1000
|
|
555
|
-
// };
|
|
556
|
-
// }
|
|
557
|
-
// }
|
|
558
|
-
// }
|
|
559
|
-
// let newDuration = data.details.totalduration;
|
|
560
|
-
// // if it's a live stream then shorten the duration to remove access
|
|
561
|
-
// // to the area after hlsjs's live sync point
|
|
562
|
-
// // seeks to areas after this point sometimes have issues
|
|
563
|
-
// if (this._playbackType === Playback.LIVE) {
|
|
564
|
-
// const fragmentTargetDuration = data.details.targetduration;
|
|
565
|
-
// const hlsjsConfig = this.options.playback.hlsjsConfig || {};
|
|
566
|
-
// // eslint-disable-next-line no-undef
|
|
567
|
-
// const liveSyncDurationCount = hlsjsConfig.liveSyncDurationCount || HLSJS.DefaultConfig.liveSyncDurationCount;
|
|
568
|
-
// const hiddenAreaDuration = fragmentTargetDuration * liveSyncDurationCount;
|
|
569
|
-
// if (hiddenAreaDuration <= newDuration) {
|
|
570
|
-
// newDuration -= hiddenAreaDuration;
|
|
571
|
-
// this._durationExcludesAfterLiveSyncPoint = true;
|
|
572
|
-
// } else {
|
|
573
|
-
// this._durationExcludesAfterLiveSyncPoint = false;
|
|
574
|
-
// }
|
|
575
|
-
// }
|
|
576
|
-
// if (newDuration !== this._playableRegionDuration) {
|
|
577
|
-
// durationChanged = true;
|
|
578
|
-
// this._playableRegionDuration = newDuration;
|
|
579
|
-
// }
|
|
580
|
-
// // Note the end time is not the playableRegionDuration
|
|
581
|
-
// // The end time will always increase even if content is removed from the beginning
|
|
582
|
-
// const endTime = fragments[0].start + newDuration;
|
|
583
|
-
// const previousEndTime = previousPlayableRegionStartTime + previousPlayableRegionDuration;
|
|
584
|
-
// const endTimeChanged = endTime !== previousEndTime;
|
|
585
|
-
// if (endTimeChanged) {
|
|
586
|
-
// if (!this._localEndTimeCorrelation) {
|
|
587
|
-
// // set the correlation to map to the end
|
|
588
|
-
// this._localEndTimeCorrelation = {
|
|
589
|
-
// local: this._now,
|
|
590
|
-
// remote: endTime * 1000
|
|
591
|
-
// };
|
|
592
|
-
// } else {
|
|
593
|
-
// // check if the correlation still works
|
|
594
|
-
// const corr = this._localEndTimeCorrelation;
|
|
595
|
-
// const timePassed = this._now - corr.local;
|
|
596
|
-
// // this should point to a time within the extrapolation window from the end
|
|
597
|
-
// const extrapolatedEndTime = (corr.remote + timePassed) / 1000;
|
|
598
|
-
// if (extrapolatedEndTime > endTime) {
|
|
599
|
-
// this._localEndTimeCorrelation = {
|
|
600
|
-
// local: this._now,
|
|
601
|
-
// remote: endTime * 1000
|
|
602
|
-
// };
|
|
603
|
-
// } else if (extrapolatedEndTime < endTime - this._extrapolatedWindowDuration) {
|
|
604
|
-
// // our extrapolated end time is now earlier than the extrapolation window from the actual end time
|
|
605
|
-
// // (maybe a chunk became available early)
|
|
606
|
-
// // reset correlation so that it sits at the beginning of the extrapolation window from the end time
|
|
607
|
-
// this._localEndTimeCorrelation = {
|
|
608
|
-
// local: this._now,
|
|
609
|
-
// remote: (endTime - this._extrapolatedWindowDuration) * 1000
|
|
610
|
-
// };
|
|
611
|
-
// } else if (extrapolatedEndTime > previousEndTime) {
|
|
612
|
-
// // end time was past the old end time (so would have been capped)
|
|
613
|
-
// // set the correlation so that it resumes from the time it was at at the end of the old window
|
|
614
|
-
// this._localEndTimeCorrelation = {
|
|
615
|
-
// local: this._now,
|
|
616
|
-
// remote: previousEndTime * 1000
|
|
617
|
-
// };
|
|
618
|
-
// }
|
|
619
|
-
// }
|
|
620
|
-
// }
|
|
621
|
-
// // now that the values have been updated call any methods that use on them so they get the updated values
|
|
622
|
-
// // immediately
|
|
623
|
-
// durationChanged && this._onDurationChange();
|
|
624
|
-
// startTimeChanged && this._onProgress();
|
|
625
|
-
// }
|
|
626
|
-
// _onFragmentLoaded(evt, data) {
|
|
627
|
-
// this.trigger(Events.PLAYBACK_FRAGMENT_LOADED, data);
|
|
628
|
-
// }
|
|
629
484
|
onLevelSwitch(currentLevel) {
|
|
630
485
|
this.trigger(Events.PLAYBACK_BITRATE, {
|
|
631
486
|
height: currentLevel.height,
|
|
@@ -646,7 +501,6 @@ DashPlayback.canPlay = function (resource, mimeType) {
|
|
|
646
501
|
const isDash = (resourceParts.length > 1 && resourceParts[1].toLowerCase() === 'mpd') ||
|
|
647
502
|
mimeType === 'application/dash+xml' ||
|
|
648
503
|
mimeType === 'video/mp4';
|
|
649
|
-
// TODO check
|
|
650
504
|
const ms = window.MediaSource;
|
|
651
505
|
const mms = 'ManagedMediaSource' in window ? window.ManagedMediaSource : undefined;
|
|
652
506
|
const wms = 'WebKitMediaSource' in window ? window.WebKitMediaSource : undefined;
|