@eluvio/elv-player-js 1.0.136 → 1.0.137

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/style.css ADDED
@@ -0,0 +1 @@
1
+ @keyframes fade-out{0%{opacity:1}to{opacity:0}}.eluvio-player{align-items:center;display:flex;height:100%;justify-content:center;max-height:100%;max-width:100%;object-fit:contain;position:relative;width:100%}.eluvio-player--error{background-color:#000}.eluvio-player--error .eluvio-player__big-play-button{display:none}.eluvio-player__error-message{align-items:center;display:flex;height:100%;justify-content:center;letter-spacing:.05em;padding:20px;position:absolute;-webkit-user-select:none;user-select:none;width:100%;z-index:1}.eluvio-player__error-message__text{color:#a32;font-size:20px;font-weight:300;max-width:600px;text-align:center}.eluvio-player--seek-left:after,.eluvio-player--seek-right:after{animation:fade-out .5s ease;content:"";height:100%;opacity:0;pointer-events:none;position:absolute;transition:background-color 1s ease;width:100%;z-index:100}.eluvio-player--seek-left:after{background:linear-gradient(90deg,rgba(100,100,100,.15),transparent 15%)}.eluvio-player--seek-right:after{background:linear-gradient(90deg,transparent 85%,rgba(100,100,100,.15))}.eluvio-player.eluvio-player-restarted .eluvio-player__big-play-button{display:none}.eluvio-player *{box-sizing:border-box;font-family:Helvetica Neue,Helvetica,sans-serif;overscroll-behavior-y:contain}.eluvio-player input[type=range],.eluvio-player button{background:transparent;border:0;cursor:pointer;justify-content:center}.eluvio-player input[type=range]:hover,.eluvio-player button:hover{opacity:1}.eluvio-player input[type=range]:disabled,.eluvio-player button:disabled{opacity:.5}.eluvio-player input[type=range]:focus,.eluvio-player button:focus{outline:0}.eluvio-player input[type=range].focus-visible,.eluvio-player button.focus-visible{box-shadow:0 0 2px #e1e1ffb3;outline:0}.eluvio-player input[type=range]{-webkit-tap-highlight-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border-radius:3px;height:3px;margin:0;padding:15px 0;z-index:100}.eluvio-player input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;-moz-appearance:none;appearance:none;height:15px;opacity:0;width:15px}.eluvio-player input[type=range]::-moz-range-thumb{-webkit-appearance:none;-moz-appearance:none;appearance:none;height:15px;opacity:0;width:15px}.eluvio-player input[type=range]::-webkit-slider-runnable-track{-webkit-tap-highlight-color:transparent;background:transparent;height:3px}.eluvio-player input[type=range]::-moz-range-track{-webkit-tap-highlight-color:transparent;background:transparent;height:3px}.eluvio-player progress{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border:0;border-radius:3px;height:3px}.eluvio-player ::-webkit-progress-value{background-color:#3784eb}.eluvio-player ::-webkit-progress-bar{background-color:transparent}.eluvio-player ::-moz-progress-bar{background-color:#3784eb}.eluvio-player__poster-image{cursor:pointer;height:100%;left:0;object-fit:contain;object-position:center;position:absolute;top:0;width:100%}.eluvio-player__video{background:#000;height:100%;margin:auto;object-fit:contain;object-position:center;width:100%;z-index:1}.eluvio-player__watermark{height:15px;pointer-events:none;position:absolute;right:15px;top:15px;width:auto;z-index:10}.eluvio-player__account-watermark{color:#fff;font-size:8px;opacity:.5;pointer-events:none;position:absolute;right:15px;top:15px;z-index:10}.eluvio-player__hidden-audio-controls{bottom:10px;height:max-content;left:10px;opacity:1;position:absolute;transition:opacity .25s linear;width:max-content;z-index:10}.eluvio-player__hidden-audio-controls button{background:#000c;border-radius:100%;padding:6px}.eluvio-player__title-container{background:linear-gradient(rgba(0,0,0,.5) 75%,transparent);color:#fff;display:grid;gap:5px;padding:10px 10px 20px;position:absolute;top:0;-webkit-user-select:none;user-select:none;width:100%;z-index:2}.eluvio-player__title{font-size:20px;padding-right:100px}.eluvio-player__description{font-size:12px;padding-right:100px}.eluvio-player__controls{align-items:center;background:#000c;bottom:0;display:flex;height:max-content;padding:5px;position:absolute;transition:opacity .25s linear;width:100%;z-index:10}.eluvio-player__controls__button{-webkit-tap-highlight-color:transparent;color:#fff;height:35px;max-height:35px;max-width:35px;min-height:35px;min-width:35px;overflow:visible;padding:6px;transition:opacity .25s linear,color .1s ease;width:35px}.eluvio-player__controls__button:not(:last-child){margin-right:2px}.eluvio-player__controls__button:disabled{opacity:.5}.eluvio-player__controls__button-volume{padding-right:0}.eluvio-player__controls__button--active{color:#3784eb}.eluvio-player__controls__button svg{height:100%;max-height:100%;max-width:100%;overflow:visible;width:100%}.eluvio-player__controls__button-multiview-spinning svg{animation:spin 1s ease-in-out infinite}.eluvio-player__controls__volume-container{flex:1 1 auto;max-width:75px;min-width:0}.eluvio-player__controls__volume{background-color:#71717180!important}.eluvio-player__controls__volume::-webkit-progress-value{background-color:#fff}.eluvio-player__controls__volume::-moz-progress-bar{background-color:#fff}.eluvio-player__controls__slider-container{align-items:center;display:flex;flex:1 1 auto;height:100%;justify-content:center;min-width:0;position:relative}.eluvio-player__controls__slider-container__input,.eluvio-player__controls__slider-container__progress{flex:1 1 auto;left:0;margin:0 5px;min-width:0;position:absolute;width:calc(100% - 10px)}.eluvio-player__controls__slider-container__input{width:100%;z-index:0}.eluvio-player__controls__slider-container__progress{pointer-events:none;z-index:2}.eluvio-player__controls__progress-buffer{background-color:#71717180!important;z-index:1}.eluvio-player__controls__progress-buffer::-webkit-progress-value{background-color:#71717180}.eluvio-player__controls__progress-buffer::-moz-progress-bar{background-color:#71717180}.eluvio-player__controls__time{color:#fff;font-size:11px;text-align:center;width:55px}.eluvio-player__controls__right-buttons{align-items:center;display:flex;flex-wrap:nowrap;height:100%}.eluvio-player__controls.eluvio-player__controls-no-progress .eluvio-player__controls__time,.eluvio-player__controls.eluvio-player__controls-no-progress .eluvio-player__controls__progress-slider{visibility:hidden}.eluvio-player__controls__tooltip{background:#000c;border-radius:3px;bottom:45px;color:#fff;font-size:14px;font-weight:300;max-height:calc(100% - 54px);max-width:225px;min-height:20px;opacity:1;padding:10px 5px;pointer-events:none;position:absolute;right:10px;text-align:center;transition:opacity .1s linear;-webkit-user-select:none;user-select:none;z-index:100}.eluvio-player__controls__tooltip *{line-height:1.2em}.eluvio-player__controls__tooltip:empty{display:none;opacity:0}.eluvio-player__controls__tooltip svg{height:20px;margin-bottom:5px;width:auto}.eluvio-player__controls__settings-menu{background:#000c;border-radius:3px 0 0;bottom:45px;color:#fff;max-height:min(90%,100% - (25px + 35px + 5px + 5px));min-height:20px;overflow-y:auto;position:absolute;right:0;width:250px;z-index:100}.eluvio-player__controls__settings-menu-hidden{display:none}.eluvio-player__controls__settings-menu button{border:1px solid transparent}.eluvio-player__controls__settings-menu__close{align-items:center;display:none;height:20px;justify-content:center;padding:0;position:absolute;right:20px;top:20px;width:20px}.eluvio-player__controls__settings-menu__close *{color:#fff}.eluvio-player__controls__settings-menu__title{font-size:16px;margin-bottom:5px;padding:9px 20px;-webkit-user-select:none;user-select:none}.eluvio-player__controls__settings-menu__option{border:1px solid transparent;color:#ffffffb3;cursor:pointer;display:block;font-size:14px;height:max-content;line-height:1.4;max-width:100%;overflow-x:hidden;padding:9px 20px;text-align:left;text-overflow:ellipsis;transition:background-color .05s linear;width:100%}.eluvio-player__controls__settings-menu__option-back{align-items:center;display:flex;position:relative;width:100%}.eluvio-player__controls__settings-menu__option-back__icon{align-items:center;display:flex;height:100%;left:20px;margin-right:5px;position:absolute;width:15px}.eluvio-player__controls__settings-menu__option-back__icon svg{height:100%;width:100%}.eluvio-player__controls__settings-menu__option-back__text{padding-inline:25px;width:100%}.eluvio-player__controls__settings-menu__option-selected{color:#fff;font-weight:500}.eluvio-player__controls__settings-menu__option:hover{background:#ffffff1a;color:#fff}.eluvio-player__controls__settings-menu__option.focus-visible{border:1px solid rgba(225,225,255,.7)}.eluvio-player__big-play-button{max-height:100px;max-width:100px;min-height:100px;min-width:100px;position:absolute;z-index:10}.eluvio-player__big-play-button svg{height:100%;opacity:.7;overflow:visible;padding:2px;transition:opacity .1s linear;width:100%;z-index:11}.eluvio-player__big-play-button:hover svg{opacity:1}.eluvio-player:fullscreen{margin:0;padding:0}.eluvio-player__hls-options-form-container{align-items:center;background-color:#00000080;bottom:0;display:flex;justify-content:center;left:0;position:absolute;right:0;top:0;z-index:100}.eluvio-player__hls-options-form{background-color:#000c;border-radius:5px;color:#fff;display:flex;flex-direction:column;height:400px;max-height:100%;max-width:100%;padding:30px 30px 20px;width:500px}.eluvio-player__hls-options-form__title{font-size:16px;margin-top:0}.eluvio-player__hls-options-form__input{background-color:#000c;border:1px solid #252525;color:#fff;flex:1 1 100%;font-size:14px;padding:.5rem;width:100%}.eluvio-player__hls-options-form__input:focus{outline:none}.eluvio-player__hls-options-form__input.focus-visible{outline:1px solid rgba(225,225,255,.7)}.eluvio-player__hls-options-form__input--invalid{border:1px solid #a32}.eluvio-player__hls-options-form__api-info{align-items:center;display:flex;font-size:10px;justify-content:space-between;padding:3px}.eluvio-player__hls-options-form__version{opacity:.5}.eluvio-player__hls-options-form__api-link{color:#fff}.eluvio-player__hls-options-form__actions{align-items:center;display:flex;justify-content:flex-end;margin-top:10px}.eluvio-player__hls-options-form button.eluvio-player__hls-options-form__action{align-items:center;background-color:#ddd;border-radius:3px;color:#000;cursor:pointer;display:flex;height:30px;justify-content:center;width:100px}.eluvio-player__hls-options-form button.eluvio-player__hls-options-form__action.focus-visible{border:1px solid rgba(225,225,255,.7);box-shadow:2px 2px 5px #e1e1ffb3}.eluvio-player__hls-options-form button.eluvio-player__hls-options-form__action:disabled{opacity:.5}.eluvio-player__hls-options-form button.eluvio-player__hls-options-form__action:not(:last-child){margin-right:10px}.eluvio-player__hls-options-form button.eluvio-player__hls-options-form__submit{background-color:#3784eb;color:#fff}.eluvio-player__ticket-modal{align-items:center;background:#000;display:flex;height:100%;justify-content:center;position:absolute;width:100%}.eluvio-player__ticket-modal__form{align-items:center;background:#121212;border:2px solid #252525;border-radius:3px;display:flex;flex-direction:column;justify-content:center;padding:20px 30px;width:300px}.eluvio-player__ticket-modal__form__text,.eluvio-player__ticket-modal__form__error-text,.eluvio-player__ticket-modal__form__input{margin-bottom:10px}.eluvio-player__ticket-modal__form__text{color:#fff;font-size:16px;font-weight:300;letter-spacing:.05em}.eluvio-player__ticket-modal__form__error-text{color:#a32;font-size:16px}.eluvio-player__ticket-modal__form__error-text:empty{display:none}.eluvio-player__ticket-modal__form__input{background:#fff;border:0;border-radius:3px;font-size:18px;font-weight:700;letter-spacing:.16em;margin:5px 0 15px;min-height:36px;padding:0 10px;text-align:center;width:100%}.eluvio-player__ticket-modal__form__submit{border-radius:3px;color:#fff;font-size:14px;font-weight:500;height:40px;letter-spacing:.1em;text-transform:uppercase;width:100%}.eluvio-player__ticket-modal__form__submit:disabled{color:#71717180}.eluvio-player__ticket-modal__form button.eluvio-player__ticket-modal__form__submit{background:#252525;margin:0}.eluvio-player__hotspot-overlay{bottom:0;left:0;position:absolute;right:0;top:0;z-index:5}.eluvio-player__hotspot-overlay__target{align-items:center;cursor:pointer;display:flex;justify-content:center;position:absolute;transition:background-color .3s}.eluvio-player__hotspot-overlay__target__title{color:#fff;display:none;font-size:24px;font-weight:300;letter-spacing:.08em;transition:letter-spacing 5s}.eluvio-player__hotspot-overlay__target:hover{background-color:#7171714d}.eluvio-player__hotspot-overlay__target:hover .eluvio-player__hotspot-overlay__target__title{display:block;text-shadow:1px 1px #717171}.eluvio-player__hotspot-overlay__target-switching{animation:hotspot-select 1s ease-out}.eluvio-player__hotspot-overlay-visible .eluvio-player__hotspot-overlay__target{background-color:#7171714d}.eluvio-player__hotspot-overlay-visible .eluvio-player__hotspot-overlay__target__title{display:block;text-shadow:1px 1px #717171}.eluvio-player.eluvio-player-xl .eluvio-player__title{font-size:28px}.eluvio-player.eluvio-player-xl .eluvio-player__description{font-size:16px}.eluvio-player.eluvio-player-xl .eluvio-player__controls{padding:7.5px}.eluvio-player.eluvio-player-xl .eluvio-player__controls__tooltip{bottom:65px}.eluvio-player.eluvio-player-xl .eluvio-player__controls__settings-menu{bottom:50px}.eluvio-player.eluvio-player-m .eluvio-player__error-message__text,.eluvio-player.eluvio-player-s .eluvio-player__error-message__text{font-size:18px}.eluvio-player.eluvio-player-m .eluvio-player__watermark,.eluvio-player.eluvio-player-s .eluvio-player__watermark{height:10px;top:10px}.eluvio-player.eluvio-player-m .eluvio-player__controls,.eluvio-player.eluvio-player-s .eluvio-player__controls{padding:2.5px}.eluvio-player.eluvio-player-m .eluvio-player__controls__button:not(.eluvio-player__big-play-button),.eluvio-player.eluvio-player-s .eluvio-player__controls__button:not(.eluvio-player__big-play-button){height:31.5px;max-height:31.5px;max-width:31.5px;min-height:31.5px;min-width:31.5px}.eluvio-player.eluvio-player-m .eluvio-player__controls__settings-menu,.eluvio-player.eluvio-player-s .eluvio-player__controls__settings-menu{bottom:36.5px;max-height:min(90%,100% - (25px + 31.5px + 5px));right:0}.eluvio-player.eluvio-player-m .eluvio-player__controls__volume-container,.eluvio-player.eluvio-player-s .eluvio-player__controls__volume-container{display:none}.eluvio-player.eluvio-player-m .eluvio-player__big-play-button,.eluvio-player.eluvio-player-s .eluvio-player__big-play-button{max-height:55px;max-width:55px;min-height:55px;min-width:55px}.eluvio-player.eluvio-player-m .eluvio-player__ticket-modal__form,.eluvio-player.eluvio-player-s .eluvio-player__ticket-modal__form{max-height:70%;max-width:70%}.eluvio-player.eluvio-player-m .eluvio-player__hotspot-overlay .eluvio-player__hotspot-overlay__target .eluvio-player__hotspot-overlay__target__title,.eluvio-player.eluvio-player-s .eluvio-player__hotspot-overlay .eluvio-player__hotspot-overlay__target .eluvio-player__hotspot-overlay__target__title{font-size:16px}.eluvio-player.eluvio-player-s .eluvio-player__error-message__text{font-size:14px}.eluvio-player.eluvio-player-s .eluvio-player__controls__time{display:none}.eluvio-player.eluvio-player-s .eluvio-player__controls__tooltip{font-size:10px;max-width:180px}.eluvio-player.eluvio-player-s .eluvio-player__controls__tooltip svg{height:15px;width:15px}.eluvio-player.eluvio-player-s .eluvio-player__controls__settings-menu{align-items:center;height:100%;max-height:100%;padding:80px 0 100px;right:0;top:0;width:100%}.eluvio-player.eluvio-player-s .eluvio-player__controls__settings-menu__title,.eluvio-player.eluvio-player-s .eluvio-player__controls__settings-menu__option{font-size:20px;margin-bottom:5px;text-align:center}.eluvio-player.eluvio-player-s .eluvio-player__controls__settings-menu__title-back,.eluvio-player.eluvio-player-s .eluvio-player__controls__settings-menu__option-back{margin-bottom:20px}.eluvio-player.eluvio-player-s .eluvio-player__controls__settings-menu__close{display:flex;z-index:100}.eluvio-player.eluvio-player-s.eluvio-player-landscape .eluvio-player__controls__settings-menu{padding:20px 0 50px}.eluvio-player.eluvio-player-s.eluvio-player-landscape .eluvio-player__controls__settings-menu__title,.eluvio-player.eluvio-player-s.eluvio-player-landscape .eluvio-player__controls__settings-menu__option{font-size:14px;margin-bottom:5px;text-align:center}.eluvio-player.eluvio-player-s.eluvio-player-landscape .eluvio-player__controls__settings-menu__title-back,.eluvio-player.eluvio-player-s.eluvio-player-landscape .eluvio-player__controls__settings-menu__option-back{margin-bottom:20px}.eluvio-player.eluvio-player-s.eluvio-player-landscape .eluvio-player__controls__settings-menu__close{display:flex}.eluvio-player.eluvio-player-s .eluvio-player__hls-options-form{padding:10px}.eluvio-player.eluvio-player-s .eluvio-player__hls-options-form__title{font-size:12px;margin-bottom:5px}.eluvio-player.eluvio-player-s .eluvio-player__hls-options-form__input{font-size:12px}.eluvio-player.eluvio-player-s .eluvio-player__hls-options-form__action{font-size:12px;height:20px;width:60px}.eluvio-player.eluvio-player-s .eluvio-player__hotspot-overlay .eluvio-player__hotspot-overlay__target .eluvio-player__hotspot-overlay__target__title{font-size:14px}.-elv-fade-in,.-elv-fade-out{transition:opacity .25s linear}.-elv-fade-out{opacity:0!important;pointer-events:none!important}.-elv-fade-in{opacity:1}.-elv-no-cursor,.-elv-no-cursor *{cursor:none!important}@keyframes hotspot-select{0%{background-color:#fff3;opacity:1}50%{background-color:#ffffffb3;opacity:.7}to{background-color:#fff0;opacity:0}}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eluvio/elv-player-js",
3
- "version": "1.0.136",
3
+ "version": "1.0.137",
4
4
  "description": "![Eluvio Logo](src/static/images/Logo.png \"Eluvio Logo\")",
5
5
  "main": "src/index.js",
6
6
  "license": "MIT",
@@ -9,7 +9,7 @@
9
9
  "bump-version": "npm --git-tag-version --no-commit-hooks version patch",
10
10
  "serve": "TEST_PAGE=true webpack-dev-server --hot --port 8089 --host=0.0.0.0",
11
11
  "serve-example": "EXAMPLE_PAGE=true webpack-dev-server --hot --port 8089 --host=0.0.0.0",
12
- "build": "node ./node_modules/webpack-cli/bin/cli.js --mode=production --devtool false",
12
+ "build": "BUILD_LIBRARY=true node ./node_modules/webpack-cli/bin/cli.js --mode=production --devtool false",
13
13
  "build-test": "TEST_PAGE=true node ./node_modules/webpack-cli/bin/cli.js --mode=production --devtool false",
14
14
  "build-example": "EXAMPLE_PAGE=true node ./node_modules/webpack-cli/bin/cli.js --mode=production --devtool false",
15
15
  "build-analyze": "ANALYZE_BUNDLE=true node ./node_modules/webpack-cli/bin/cli.js --mode=production --devtool false",
@@ -36,11 +36,12 @@
36
36
  "webpack.config.js"
37
37
  ],
38
38
  "dependencies": {
39
- "@eluvio/elv-client-js": "^4.0.62",
39
+ "@eluvio/elv-client-js": "^4.0.76",
40
40
  "dashjs": "~4.7.0",
41
41
  "focus-visible": "^5.2.0",
42
42
  "hls.js": "~1.4.12",
43
43
  "lodash": "^4.17.21",
44
+ "mux-embed": "^4.30.0",
44
45
  "resize-observer-polyfill": "^1.5.1",
45
46
  "url-join": "^4.0.1"
46
47
  },
@@ -0,0 +1,114 @@
1
+ import Mux from "mux-embed";
2
+ const {version} = require("../package.json");
3
+
4
+ export const InitializeMuxMonitoring = async ({
5
+ appName="elv-player-js",
6
+ elvPlayer,
7
+ playoutUrl,
8
+ authorizationToken,
9
+ disableCookies
10
+ }) => {
11
+ playoutUrl = new URL(playoutUrl);
12
+
13
+ const client = await elvPlayer.Client();
14
+ const muxKey = (await client.NetworkInfo()).name === "main" ?
15
+ "aq4mdjn7qo5sbkf89pkvfv93j" :
16
+ "2i5480sms8vdgj0sv9bv6lpk5";
17
+
18
+ const versionHash = playoutUrl.pathname.split("/").find(token => token.startsWith("hq__"));
19
+ const objectId = client.utils.DecodeVersionHash(versionHash).objectId;
20
+ const offering = playoutUrl.toString().match(/\/rep\/playout\/([^/]+)/)[1] || "default";
21
+ const sessionId = playoutUrl.searchParams.get("sid");
22
+
23
+ let name = versionHash;
24
+ try {
25
+ const metadata = (await client.ContentObjectMetadata({
26
+ versionHash,
27
+ metadataSubtree: "/public",
28
+ select: [
29
+ "name",
30
+ "asset_metadata/display_title",
31
+ "asset_metadata/title"
32
+ ],
33
+ authorizationToken
34
+ })) || {};
35
+
36
+ name =
37
+ (metadata.asset_metadata || {}).display_title ||
38
+ (metadata.asset_metadata || {}).title ||
39
+ metadata.name || versionHash;
40
+ // eslint-disable-next-line no-empty
41
+ } catch (error) {}
42
+
43
+ let tenantId = undefined;
44
+ try {
45
+ tenantId = await client.ContentObjectTenantId({versionHash});
46
+ // eslint-disable-next-line no-empty
47
+ } catch (error) {}
48
+
49
+ let address = await client.CurrentAccountAddress();
50
+ if(authorizationToken || client.staticToken) {
51
+ try {
52
+ const {payload} = client.utils.DecodeSignedToken(authorizationToken);
53
+ address = payload.adr || address;
54
+ // eslint-disable-next-line no-empty
55
+ } catch (error) {}
56
+ }
57
+
58
+ let addressDigest = address;
59
+ if(typeof crypto !== "undefined") {
60
+ try {
61
+ const encoder = new TextEncoder();
62
+ addressDigest = Buffer.from(
63
+ await crypto.subtle.digest("SHA-256", encoder.encode(address))
64
+ ).toString("hex");
65
+ // eslint-disable-next-line no-empty
66
+ } catch (error) {}
67
+ }
68
+
69
+ const options = {
70
+ debug: false,
71
+ disableCookies,
72
+ data: {
73
+ env_key: muxKey,
74
+ video_id: objectId,
75
+ video_variant_id: versionHash,
76
+ video_variant_name: offering,
77
+ video_title: name,
78
+ video_cdn: playoutUrl.hostname,
79
+ viewer_user_id: addressDigest,
80
+ sub_property_id: tenantId,
81
+ player_name: appName,
82
+ player_version: version,
83
+ player_init_time: elvPlayer.initTime
84
+ }
85
+ };
86
+
87
+ if(sessionId) {
88
+ options.data.view_session_id = sessionId;
89
+ }
90
+
91
+ if(elvPlayer.player) {
92
+ if(elvPlayer.HLS) {
93
+ options.hlsjs = elvPlayer.player;
94
+ options.Hls = elvPlayer.HLS;
95
+ } else if(elvPlayer.Dash) {
96
+ options.dashjs = elvPlayer.player;
97
+ }
98
+ }
99
+ try {
100
+ Mux.monitor(elvPlayer.video, options);
101
+
102
+ // eslint-disable-next-line no-console
103
+ console.info("elv-player-js: Mux monitoring initialized");
104
+ // eslint-disable-next-line no-console
105
+ console.info(JSON.stringify({...options, hlsjs: {}}));
106
+ } catch (error) {
107
+ // eslint-disable-next-line no-console
108
+ console.warn("elv-player-js: Failed to initialize mux monitoring:");
109
+ // eslint-disable-next-line no-console
110
+ console.warn(JSON.stringify(options, null, 2));
111
+ // eslint-disable-next-line no-console
112
+ console.warn(error);
113
+ }
114
+ };
@@ -10,7 +10,10 @@ import {
10
10
  VolumeLowIcon,
11
11
  VolumeHighIcon,
12
12
  MultiViewIcon,
13
- LeftArrowIcon
13
+ LeftArrowIcon,
14
+ PreviousTrackIcon,
15
+ NextTrackIcon,
16
+ CollectionIcon
14
17
  } from "./static/icons/Icons";
15
18
  // Icons are generated from .svg files to an importable JS file. To add a new icon, modify and run src/BuildIcons.js
16
19
 
@@ -123,7 +126,23 @@ const Time = (time, total) => {
123
126
  return string;
124
127
  };
125
128
 
126
- export const InitializeTicketPrompt = (target, callback) => {
129
+ export const InitializeTicketPrompt = async (target, initialCode, callback) => {
130
+ // If initial code is provided, attempt to automatically redeem it before rendering the form
131
+ let initialError = "";
132
+ if(initialCode) {
133
+ try {
134
+ await callback(initialCode);
135
+ return;
136
+ } catch (error) {
137
+ // eslint-disable-next-line no-console
138
+ console.error("ELUVIO PLAYER: Invalid Code");
139
+ // eslint-disable-next-line no-console
140
+ console.error(error);
141
+
142
+ initialError = "Invalid Code";
143
+ }
144
+ }
145
+
127
146
  const ticketModal = CreateElement({
128
147
  parent: target,
129
148
  type: "div",
@@ -144,6 +163,8 @@ export const InitializeTicketPrompt = (target, callback) => {
144
163
  classes: ["eluvio-player__ticket-modal__form__error-text", "eluvio-player__ticket-modal__form__text"]
145
164
  });
146
165
 
166
+ errorMessage.innerHTML = initialError;
167
+
147
168
  const text = CreateElement({
148
169
  parent: form,
149
170
  type: "div",
@@ -158,6 +179,8 @@ export const InitializeTicketPrompt = (target, callback) => {
158
179
  classes: ["eluvio-player__ticket-modal__form__input"]
159
180
  });
160
181
 
182
+ input.value = initialCode;
183
+
161
184
  const submit = CreateElement({
162
185
  parent: form,
163
186
  type: "button",
@@ -188,7 +211,8 @@ export const InitializeTicketPrompt = (target, callback) => {
188
211
  };
189
212
 
190
213
  class PlayerControls {
191
- constructor({target, video, playerOptions, posterUrl, className}) {
214
+ constructor({player, target, video, playerOptions, posterUrl, className}) {
215
+ this.player = player;
192
216
  this.target = target;
193
217
  this.video = video;
194
218
  this.playerOptions = playerOptions;
@@ -200,6 +224,8 @@ class PlayerControls {
200
224
  this.SetPosterUrl(posterUrl);
201
225
  }
202
226
 
227
+ this.HandleClickOutsideMenu = this.HandleClickOutsideMenu.bind(this);
228
+
203
229
  this.InitializeControls(className);
204
230
  }
205
231
 
@@ -267,7 +293,7 @@ class PlayerControls {
267
293
  }
268
294
  }
269
295
 
270
- AutohideControls(controls) {
296
+ AutohideControls({controls, titleOnly=false}) {
271
297
  this.video.addEventListener("play", () => {
272
298
  this.played = true;
273
299
  });
@@ -289,14 +315,14 @@ class PlayerControls {
289
315
  const PlayerMove = () => {
290
316
  this.FadeIn({
291
317
  key: "controls",
292
- elements: [controls, this.settingsMenu, this.toolTip],
318
+ elements: titleOnly ? [this.titleContainer] : [controls, this.settingsMenu, this.toolTip, this.titleContainer],
293
319
  callback: () => {
294
320
  this.target.classList.remove("-elv-no-cursor");
295
321
  }
296
322
  });
297
323
  this.FadeOut({
298
324
  key: "controls",
299
- elements: [controls, this.settingsMenu, this.toolTip],
325
+ elements: titleOnly ? [this.titleContainer] : [controls, this.settingsMenu, this.toolTip, this.titleContainer],
300
326
  delay: 3000,
301
327
  unless: () => ControlsShouldShow(),
302
328
  callback: () => {
@@ -350,7 +376,40 @@ class PlayerControls {
350
376
  this.accountWatermark.innerText = address;
351
377
  }
352
378
 
379
+ InitializeContentTitle({title, description}) {
380
+ if(!title && !description) { return; }
381
+
382
+ this.titleContainer = CreateElement({
383
+ parent: this.target,
384
+ type: "div",
385
+ classes: ["eluvio-player__title-container"],
386
+ prepend: true
387
+ });
388
+
389
+ if(title) {
390
+ const titleElement = CreateElement({
391
+ parent: this.titleContainer,
392
+ type: "div",
393
+ classes: ["eluvio-player__title"]
394
+ });
395
+
396
+ titleElement.innerHTML = title;
397
+ }
398
+
399
+ if(description) {
400
+ const descriptionElement = CreateElement({
401
+ parent: this.titleContainer,
402
+ type: "div",
403
+ classes: ["eluvio-player__description"]
404
+ });
405
+
406
+ descriptionElement.innerHTML = description;
407
+ }
408
+ }
409
+
353
410
  InitializeControls(className="") {
411
+ const collectionInfo = this.player.collectionInfo;
412
+
354
413
  this.target.setAttribute("tabindex", "0");
355
414
 
356
415
  if(this.playerOptions.watermark) {
@@ -434,7 +493,7 @@ class PlayerControls {
434
493
  volumeButton.innerHTML = this.video.muted || this.video.volume === 0 ? MutedIcon : (this.video.volume < 0.5 ? VolumeLowIcon : VolumeHighIcon);
435
494
  });
436
495
 
437
- this.AutohideControls(controls);
496
+ this.AutohideControls({controls, titleOnly: false});
438
497
  };
439
498
 
440
499
  const HasAudio = () => (this.video.mozHasAudio || Boolean(this.video.webkitAudioDecodedByteCount) || Boolean(this.video.audioTracks && this.video.audioTracks.length));
@@ -559,6 +618,21 @@ class PlayerControls {
559
618
  volumeBar.value = volumeSlider.value;
560
619
  });
561
620
 
621
+ // Collection previous track
622
+ if(collectionInfo && collectionInfo.isPlaylist) {
623
+ const collectionPreviousButton = CreateImageButton({
624
+ parent: controls,
625
+ svg: PreviousTrackIcon,
626
+ classes: ["eluvio-player__controls__previous-track"],
627
+ label: "Previous Track",
628
+ options: {
629
+ disabled: collectionInfo.mediaIndex === 0
630
+ }
631
+ });
632
+
633
+ collectionPreviousButton.addEventListener("click", () => this.player.CollectionPlayPrevious());
634
+ }
635
+
562
636
  const progressTime = CreateElement({
563
637
  parent: controls,
564
638
  type: "div",
@@ -644,6 +718,36 @@ class PlayerControls {
644
718
 
645
719
  totalTime.innerHTML = "00:00";
646
720
 
721
+ // Collection previous track
722
+ if(collectionInfo && collectionInfo.isPlaylist) {
723
+ const collectionNextButton = CreateImageButton({
724
+ parent: controls,
725
+ svg: NextTrackIcon,
726
+ classes: ["eluvio-player__controls__next-track"],
727
+ label: "Next Track",
728
+ options: {
729
+ disabled: collectionInfo.mediaIndex >= collectionInfo.mediaLength - 1
730
+ }
731
+ });
732
+
733
+ collectionNextButton.addEventListener("click", () => this.player.CollectionPlayNext());
734
+ }
735
+
736
+ if(collectionInfo) {
737
+ this.collectionButton = CreateImageButton({
738
+ parent: controls,
739
+ svg: CollectionIcon,
740
+ classes: ["eluvio-player__controls__collection"],
741
+ label: "Collection Info"
742
+ });
743
+
744
+ this.collectionButton.addEventListener("click", () => {
745
+ this.settingsMenu.dataset.mode === "collection" ?
746
+ this.HideSettingsMenu() :
747
+ this.ShowCollectionMenu();
748
+ });
749
+ }
750
+
647
751
  // Right buttons container
648
752
  this.rightButtonsContainer = CreateElement({
649
753
  parent: controls,
@@ -651,6 +755,20 @@ class PlayerControls {
651
755
  classes: ["eluvio-player__controls__right-buttons"]
652
756
  });
653
757
 
758
+ this.settingsButton = CreateImageButton({
759
+ parent: this.rightButtonsContainer,
760
+ svg: SettingsIcon,
761
+ classes: ["eluvio-player__controls__button-settings"],
762
+ prepend: true,
763
+ label: "Settings"
764
+ });
765
+
766
+ this.settingsButton.addEventListener("click", () => {
767
+ this.settingsMenu.dataset.mode.startsWith("settings") ?
768
+ this.HideSettingsMenu() :
769
+ this.ShowSettingsMenu();
770
+ });
771
+
654
772
  // Fullscreen
655
773
  const fullscreenButton = CreateImageButton({
656
774
  parent: this.rightButtonsContainer,
@@ -805,9 +923,7 @@ class PlayerControls {
805
923
  }
806
924
  });
807
925
 
808
- if(this.playerOptions.controls === EluvioPlayerParameters.controls.AUTO_HIDE) {
809
- this.AutohideControls(controls);
810
- }
926
+ this.AutohideControls({controls, titleOnly: this.playerOptions.controls !== EluvioPlayerParameters.controls.AUTO_HIDE});
811
927
  }
812
928
 
813
929
  ShowHLSOptionsForm({hlsOptions={}, SetPlayerProfile, hlsVersion}) {
@@ -935,7 +1051,14 @@ class PlayerControls {
935
1051
  this.hlsOptionsFormContainer && this.hlsOptionsFormContainer.remove();
936
1052
  }
937
1053
 
1054
+ HandleClickOutsideMenu(event) {
1055
+ if(!this.settingsMenu.contains(event.target)) {
1056
+ this.HideSettingsMenu();
1057
+ }
1058
+ }
1059
+
938
1060
  InitializeMenu(mode) {
1061
+ this.HideSettingsMenu();
939
1062
  this.settingsMenu.innerHTML = "";
940
1063
  this.settingsMenu.classList.remove("eluvio-player__controls__settings-menu-hidden");
941
1064
  this.settingsMenu.setAttribute("data-mode", mode);
@@ -949,6 +1072,16 @@ class PlayerControls {
949
1072
  });
950
1073
 
951
1074
  closeButton.addEventListener("click", () => this.HideSettingsMenu());
1075
+
1076
+ setTimeout(() => {
1077
+ document.addEventListener("click", this.HandleClickOutsideMenu);
1078
+ }, 100);
1079
+
1080
+ if(mode === "collection") {
1081
+ this.collectionButton.classList.add("eluvio-player__controls__button--active");
1082
+ } else if(mode.includes("setting")) {
1083
+ this.settingsButton.classList.add("eluvio-player__controls__button--active");
1084
+ }
952
1085
  }
953
1086
 
954
1087
  AddSetting({Retrieve, Set}) {
@@ -1044,37 +1177,73 @@ class PlayerControls {
1044
1177
  }
1045
1178
 
1046
1179
  HideSettingsMenu() {
1180
+ document.removeEventListener("click", this.HandleClickOutsideMenu);
1181
+
1047
1182
  const mode = this.settingsMenu.dataset.mode;
1048
1183
  if(mode === "settings") {
1049
1184
  this.settingsButton.focus();
1050
1185
  } else if(mode === "multiview") {
1051
1186
  this.multiviewButton.focus();
1187
+ } else if(mode === "collection") {
1188
+ this.collectionButton.focus();
1052
1189
  }
1053
1190
 
1054
1191
  this.settingsMenu.innerHTML = "";
1055
1192
  this.settingsMenu.classList.add("eluvio-player__controls__settings-menu-hidden");
1056
1193
  this.settingsMenu.setAttribute("data-mode", "hidden");
1194
+
1195
+ this.settingsButton.classList.remove("eluvio-player__controls__button--active");
1196
+ this.collectionButton && this.collectionButton.classList.remove("eluvio-player__controls__button--active");
1197
+ this.multiviewButton && this.multiviewButton.classList.remove("eluvio-player__controls__button--active");
1057
1198
  }
1058
1199
 
1200
+ // Settings were updated - if the menu is already open, force it to refresh
1059
1201
  UpdateSettings() {
1060
- if(!this.settingsButton) {
1061
- this.settingsButton = CreateImageButton({
1062
- parent: this.rightButtonsContainer,
1063
- svg: SettingsIcon,
1064
- classes: ["eluvio-player__controls__button-settings"],
1065
- prepend: true,
1066
- label: "Settings"
1067
- });
1202
+ if(this.settingsMenu.dataset.mode === "settings") {
1203
+ this.ShowSettingsMenu();
1204
+ }
1205
+ }
1068
1206
 
1069
- this.settingsButton.addEventListener("click", () => {
1070
- this.settingsMenu.dataset.mode === "hidden" ?
1071
- this.ShowSettingsMenu() :
1207
+ ShowCollectionMenu() {
1208
+ if(
1209
+ !this.player.collectionInfo ||
1210
+ !this.player.collectionInfo.content ||
1211
+ this.player.collectionInfo.content.length <= 1
1212
+ ) {
1213
+ return;
1214
+ }
1215
+
1216
+ this.InitializeMenu("collection");
1217
+
1218
+ const collectionTitle = CreateElement({
1219
+ parent: this.settingsMenu,
1220
+ type: "div",
1221
+ classes: ["eluvio-player__controls__settings-menu__title"]
1222
+ });
1223
+
1224
+ collectionTitle.innerHTML = this.player.collectionInfo.title;
1225
+
1226
+ this.player.collectionInfo.content
1227
+ .forEach((option, index) => {
1228
+ const active = this.player.collectionInfo.mediaIndex === index;
1229
+ const optionButton = CreateElement({
1230
+ parent: this.settingsMenu,
1231
+ type: "button",
1232
+ classes: ["eluvio-player__controls__settings-menu__option", active ? "eluvio-player__controls__settings-menu__option-selected" : ""]
1233
+ });
1234
+
1235
+ optionButton.innerHTML = option.title || option.mediaHash;
1236
+
1237
+ optionButton.addEventListener("click", () => {
1238
+ this.player.CollectionPlay({mediaIndex: index});
1072
1239
  this.HideSettingsMenu();
1240
+ });
1073
1241
  });
1074
- }
1075
1242
 
1076
- if(this.settingsMenu.dataset.mode === "settings") {
1077
- this.ShowSettingsMenu();
1243
+ // Focus on first element in list when menu opened
1244
+ const firstItem = this.settingsMenu.querySelector("button");
1245
+ if(firstItem) {
1246
+ firstItem.focus();
1078
1247
  }
1079
1248
  }
1080
1249
 
@@ -1174,6 +1343,8 @@ class PlayerControls {
1174
1343
  return;
1175
1344
  }
1176
1345
 
1346
+ this.multiviewButton.classList.add("eluvio-player__controls__button--active");
1347
+
1177
1348
  this.settingsMenu.setAttribute("data-mode", "multiview");
1178
1349
  this.settingsMenu.classList.remove("eluvio-player__controls__settings-menu-hidden");
1179
1350