@eluvio/elv-player-js 2.0.13 → 2.0.15

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.
@@ -118,6 +118,10 @@ export class EluvioPlayer {
118
118
  options.ignore_trimming = playoutParameters.ignoreTrimming;
119
119
  options.resolve = playoutParameters.resolve;
120
120
 
121
+ if(this.dvrEnabled) {
122
+ options.dvr = 1;
123
+ }
124
+
121
125
  if(playoutParameters.offering || playoutParameters.directLink || (playoutParameters.offerings || []).length > 0) {
122
126
  let availableOfferings = (await client.AvailableOfferings({
123
127
  objectId: playoutParameters.objectId,
@@ -289,6 +293,7 @@ export class EluvioPlayer {
289
293
  }
290
294
 
291
295
  this.isLive = parameters.sourceOptions.contentInfo.type === EluvioPlayerParameters.type.LIVE;
296
+ this.dvrEnabled = parameters.sourceOptions.contentInfo.liveDVR === EluvioPlayerParameters.liveDVR.ON;
292
297
 
293
298
  this.errors = 0;
294
299
 
@@ -538,6 +543,11 @@ export class EluvioPlayer {
538
543
  ...customProfileSettings
539
544
  };
540
545
 
546
+ if(this.dvrEnabled) {
547
+ delete this.hlsOptions.liveMaxLatencyDuration;
548
+ delete this.hlsOptions.liveMaxLatencyDurationCount;
549
+ }
550
+
541
551
  const hlsPlayer = new this.HLS(this.hlsOptions);
542
552
 
543
553
  // Limit playback to maximum bitrate, if specified
@@ -602,7 +612,13 @@ export class EluvioPlayer {
602
612
  const playing = !this.video.paused;
603
613
  const currentTime = this.video.currentTime;
604
614
 
605
- this.hlsPlayer.destroy();
615
+ try {
616
+ this.hlsPlayer.destroy();
617
+ } catch(error) {
618
+ this.Log("Failed to destroy HLS player", true);
619
+ this.Log(error, true);
620
+ }
621
+
606
622
  await this.__InitializeHLS({
607
623
  playoutUrl,
608
624
  authorizationToken,
@@ -934,10 +950,15 @@ export class EluvioPlayer {
934
950
  this.video.pause();
935
951
  }
936
952
 
937
- if(this.hlsPlayer) {
938
- this.hlsPlayer.destroy();
939
- } else if(this.dashPlayer) {
940
- this.dashPlayer.destroy();
953
+ try {
954
+ if(this.hlsPlayer) {
955
+ this.hlsPlayer.destroy();
956
+ } else if(this.dashPlayer) {
957
+ this.dashPlayer.destroy();
958
+ }
959
+ } catch(error) {
960
+ this.Log("Failed to destroy abr player", true);
961
+ this.Log(error, true);
941
962
  }
942
963
 
943
964
  this.__listenerDisposers.forEach(Disposer => {
@@ -945,7 +966,7 @@ export class EluvioPlayer {
945
966
  Disposer();
946
967
  } catch (error) {
947
968
  this.Log("Failed to dispose of video event listener", true);
948
- this.Log(error);
969
+ this.Log(error, true);
949
970
  }
950
971
  });
951
972
 
@@ -968,6 +989,8 @@ export class EluvioPlayer {
968
989
  this.player = undefined;
969
990
  this.initTimeLogged = false;
970
991
  this.canPlay = false;
992
+ this.isLive = false;
993
+ this.dvrEnabled = false;
971
994
  }
972
995
 
973
996
  async __HardReload(error, delay=6000) {
@@ -88,6 +88,10 @@ export const PlayerParameters = {
88
88
  verifyContent: {
89
89
  OFF: false,
90
90
  ON: true
91
+ },
92
+ liveDVR: {
93
+ OFF: false,
94
+ ON: true
91
95
  }
92
96
  };
93
97
 
@@ -124,6 +128,7 @@ export const DefaultParameters = {
124
128
  image: undefined,
125
129
  posterImage: undefined,
126
130
  type: PlayerParameters.type.VOD,
131
+ liveDVR: PlayerParameters.liveDVR.OFF,
127
132
  headers: []
128
133
  },
129
134
  mediaCollectionOptions: {
@@ -65,9 +65,9 @@
65
65
  align-items: center;
66
66
  color: var(--color-button);
67
67
  display: flex;
68
+ height: 30px;
68
69
  padding: 4px;
69
70
  transition: color 0.15s ease;
70
- height: 30px;
71
71
  width: 30px;
72
72
 
73
73
  svg {
@@ -167,8 +167,8 @@
167
167
 
168
168
  .center-play-button {
169
169
  height: 100px;
170
- transition: opacity 0.5s ease;
171
170
  margin-bottom: 30px;
171
+ transition: opacity 0.5s ease;
172
172
  width: 100px;
173
173
  z-index: var(--layer-center-button);
174
174
 
@@ -233,6 +233,7 @@
233
233
  align-items: center;
234
234
  display: flex;
235
235
  font-size: 14px;
236
+ gap: 10px;
236
237
  min-width: 100px;
237
238
  user-select: none;
238
239
  white-space: nowrap;
@@ -334,12 +335,12 @@
334
335
 
335
336
  .icon-button {
336
337
  border: 1px solid transparent;
337
- transition: background-color 0.25s ease, color 0.25s ease;
338
338
  padding: 0;
339
+ transition: background-color 0.25s ease, color 0.25s ease;
339
340
 
340
341
  &-active,
341
342
  &:focus-visible {
342
- filter: drop-shadow(0 0 3px rgba(255, 255, 255, 0.5));
343
+ filter: drop-shadow(0 0 3px rgba(255, 255, 255, 50%));
343
344
  }
344
345
  }
345
346
  }
@@ -385,8 +386,8 @@
385
386
 
386
387
  .icon-button {
387
388
  height: 25px;
388
- width: 25px;
389
389
  min-width: 25px;
390
+ width: 25px;
390
391
  }
391
392
 
392
393
  .controls {
@@ -397,8 +398,8 @@
397
398
 
398
399
  .center-play-button {
399
400
  height: 50px;
400
- width: 50px;
401
401
  margin-bottom: 15px;
402
+ width: 50px;
402
403
  }
403
404
 
404
405
  /* Position menus relative to whole player */
@@ -77,7 +77,7 @@ export const SeekBar = ({player, videoState, setRecentUserAction, className=""})
77
77
  };
78
78
  }, []);
79
79
 
80
- if(player.isLive) {
80
+ if(player.isLive && !player.dvrEnabled) {
81
81
  return null;
82
82
  }
83
83
 
@@ -25,7 +25,7 @@ const PlayerProfileForm = ({player, Close}) => {
25
25
 
26
26
  try {
27
27
  setSubmitting(true);
28
- await player.controls.SetPlayerProfile({profile: "custom", customHLSOptions: JSON.parse(playerOptions)});
28
+ await player.controls.SetPlayerProfile({profile: "custom", customOptions: JSON.parse(playerOptions)});
29
29
 
30
30
  Close();
31
31
  } catch(error) {
@@ -26,7 +26,7 @@ const TimeIndicator = ({player, videoState}) => {
26
26
  return () => disposeVideoTimeObserver && disposeVideoTimeObserver();
27
27
  }, []);
28
28
 
29
- if(player.isLive) {
29
+ if(player.isLive && !player.dvrEnabled) {
30
30
  return null;
31
31
  }
32
32
 
@@ -306,9 +306,13 @@ const TVControls = ({player, playbackStarted, canPlay, recentlyInteracted, setRe
306
306
  <div className={ControlStyles["spacer"]}/>
307
307
  {
308
308
  !player.isLive ? null :
309
- <div className={ControlStyles["live-indicator"]}>
310
- Live
311
- </div>
309
+ player.dvrEnabled ?
310
+ <button onClick={() => player.controls.Seek({time: player.controls.GetDuration() - 2})} className={ControlStyles["live-indicator"]}>
311
+ Live
312
+ </button> :
313
+ <div className={ControlStyles["live-indicator"]}>
314
+ Live
315
+ </div>
312
316
  }
313
317
  {
314
318
  !collectionInfo ? null :
@@ -26,7 +26,7 @@ const TimeIndicator = ({player, videoState}) => {
26
26
  return () => disposeVideoTimeObserver && disposeVideoTimeObserver();
27
27
  }, []);
28
28
 
29
- if(player.isLive) {
29
+ if(player.isLive && !player.dvrEnabled) {
30
30
  return (
31
31
  <div className={ControlStyles["live-indicator"]}>
32
32
  Live
@@ -36,6 +36,12 @@ const TimeIndicator = ({player, videoState}) => {
36
36
 
37
37
  return (
38
38
  <div className={ControlStyles["time"]}>
39
+ {
40
+ !player.isLive ? null :
41
+ <button onClick={() => player.controls.Seek({time: player.controls.GetDuration() - 2})} className={ControlStyles["live-indicator"]}>
42
+ Live
43
+ </button>
44
+ }
39
45
  { Time(currentTime, videoState.duration) } / { Time(videoState.duration, videoState.duration) }
40
46
  </div>
41
47
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eluvio/elv-player-js",
3
- "version": "2.0.13",
3
+ "version": "2.0.15",
4
4
  "description": "![Eluvio Logo](lib/static/images/Logo.png \"Eluvio Logo\")",
5
5
  "main": "dist/elv-player-js.es.js",
6
6
  "license": "MIT",