@instructure/studio-player 0.1.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.
Files changed (58) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +59 -0
  3. package/dist/StudioPlayer/StudioPlayer.d.ts +10 -0
  4. package/dist/StudioPlayer/StudioPlayerContext.d.ts +11 -0
  5. package/dist/StudioPlayer/components/BufferingIndicator/BufferingIndicator.d.ts +1 -0
  6. package/dist/StudioPlayer/components/CaptionsButton/CaptionsButton.d.ts +1 -0
  7. package/dist/StudioPlayer/components/CaptionsOverlay/CaptionsOverlay.d.ts +5 -0
  8. package/dist/StudioPlayer/components/ControlsLayout/ControlsLayout.d.ts +1 -0
  9. package/dist/StudioPlayer/components/CustomSettingsMenu/CustomSettingsMenu.d.ts +1 -0
  10. package/dist/StudioPlayer/components/CustomSettingsMenu/CustomSettingsMenuContext.d.ts +8 -0
  11. package/dist/StudioPlayer/components/CustomSettingsMenu/menus/CaptionsMenu/CaptionsFontSizeMenu.d.ts +1 -0
  12. package/dist/StudioPlayer/components/CustomSettingsMenu/menus/CaptionsMenu/CaptionsLanguageMenu.d.ts +1 -0
  13. package/dist/StudioPlayer/components/CustomSettingsMenu/menus/CaptionsMenu/CaptionsMenu.d.ts +1 -0
  14. package/dist/StudioPlayer/components/CustomSettingsMenu/menus/MainMenu/MainMenu.d.ts +1 -0
  15. package/dist/StudioPlayer/components/CustomSettingsMenu/menus/QualityMenu/QualityMenu.d.ts +1 -0
  16. package/dist/StudioPlayer/components/CustomSettingsMenu/menus/SpeedMenu/SpeedMenu.d.ts +1 -0
  17. package/dist/StudioPlayer/components/CustomSettingsMenu/menus/buttons/BaseButton.d.ts +8 -0
  18. package/dist/StudioPlayer/components/CustomSettingsMenu/menus/buttons/CaptionsButton.d.ts +1 -0
  19. package/dist/StudioPlayer/components/CustomSettingsMenu/menus/buttons/CaptionsFontSizeButton.d.ts +1 -0
  20. package/dist/StudioPlayer/components/CustomSettingsMenu/menus/buttons/CaptionsLanguageButton.d.ts +1 -0
  21. package/dist/StudioPlayer/components/CustomSettingsMenu/menus/buttons/QualityButton.d.ts +1 -0
  22. package/dist/StudioPlayer/components/CustomSettingsMenu/menus/buttons/SpeedButton.d.ts +1 -0
  23. package/dist/StudioPlayer/components/CustomSettingsMenu/useCallbackOnEsc.d.ts +1 -0
  24. package/dist/StudioPlayer/components/CustomSettingsMenu/useCustomSettingsMenu.d.ts +18 -0
  25. package/dist/StudioPlayer/components/FeedbackOverlay/FeedbackIcon.d.ts +1 -0
  26. package/dist/StudioPlayer/components/FeedbackOverlay/FeedbackMessage.d.ts +1 -0
  27. package/dist/StudioPlayer/components/FeedbackOverlay/FeedbackOverlay.d.ts +1 -0
  28. package/dist/StudioPlayer/components/FeedbackOverlay/createFeedbackComponent.d.ts +1 -0
  29. package/dist/StudioPlayer/components/FullscreenButton/FullscreenButton.d.ts +1 -0
  30. package/dist/StudioPlayer/components/GesturesContainer/GesturesContainer.d.ts +1 -0
  31. package/dist/StudioPlayer/components/PlayPauseButton/PlayPauseButton.d.ts +1 -0
  32. package/dist/StudioPlayer/components/PosterContainer/PosterContainer.d.ts +4 -0
  33. package/dist/StudioPlayer/components/SmallLayoutOverlay/SmallLayoutOverlay.d.ts +1 -0
  34. package/dist/StudioPlayer/components/TimeIndicator/TimeIndicator.d.ts +1 -0
  35. package/dist/StudioPlayer/components/TimeLine/TimeLine.d.ts +4 -0
  36. package/dist/StudioPlayer/components/VolumeMenu/VolumeMenu.d.ts +1 -0
  37. package/dist/StudioPlayer/components/index.d.ts +14 -0
  38. package/dist/StudioPlayer/shortcuts.d.ts +2 -0
  39. package/dist/constants.d.ts +5 -0
  40. package/dist/errors-DCJKAXTz.js +70 -0
  41. package/dist/index-BM9a_WKH.js +33480 -0
  42. package/dist/index.css +1 -0
  43. package/dist/index.d.ts +3 -0
  44. package/dist/prod-DTLJXtPo.js +994 -0
  45. package/dist/srt-parser-CWqahKwO.js +27 -0
  46. package/dist/ssa-parser-BqjjKy4M.js +209 -0
  47. package/dist/studio-player.es.js +6 -0
  48. package/dist/types.d.ts +6 -0
  49. package/dist/vidstack-B-YW57m0-DZMwUKSQ.js +140 -0
  50. package/dist/vidstack-BFbyAy5g-DqVWIlTG.js +378 -0
  51. package/dist/vidstack-BGEqnOoX-BiZsT73r.js +434 -0
  52. package/dist/vidstack-CC0Rsbn0-Cf76Gp3K.js +32 -0
  53. package/dist/vidstack-CbSFenOv-DX2VhxT6.js +60 -0
  54. package/dist/vidstack-D2cUZes0-BnrvKkrf.js +237 -0
  55. package/dist/vidstack-Xu8hy52p-DHV2kI-e.js +323 -0
  56. package/dist/vidstack-Zc3I7oOd-DDsBgkhs.js +31 -0
  57. package/dist/vidstack-krOAtKMi-B4IZWKdc.js +29 -0
  58. package/package.json +78 -0
@@ -0,0 +1,237 @@
1
+ var N = Object.defineProperty;
2
+ var D = (n) => {
3
+ throw TypeError(n);
4
+ };
5
+ var z = (n, r, e) => r in n ? N(n, r, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[r] = e;
6
+ var T = (n, r, e) => z(n, typeof r != "symbol" ? r + "" : r, e), C = (n, r, e) => r.has(n) || D("Cannot " + e);
7
+ var s = (n, r, e) => (C(n, r, "read from private field"), e ? e.call(n) : r.get(n)), p = (n, r, e) => r.has(n) ? D("Cannot add the same private member more than once") : r instanceof WeakSet ? r.add(n) : r.set(n, e), l = (n, r, e, t) => (C(n, r, "write to private field"), t ? t.call(n, e) : r.set(n, e), e), o = (n, r, e) => (C(n, r, "access private method"), e);
8
+ import { m as A, n as G, p as H, e as J, b as K, q as Q, t as W, u as $, o as M, v as X } from "./index-BM9a_WKH.js";
9
+ import { E as Z } from "./vidstack-CbSFenOv-DX2VhxT6.js";
10
+ import { resolveYouTubeVideoId as ee } from "./vidstack-Zc3I7oOd-DDsBgkhs.js";
11
+ import "react";
12
+ const b = {
13
+ Unstarted: -1,
14
+ Ended: 0,
15
+ Playing: 1,
16
+ Paused: 2,
17
+ Buffering: 3,
18
+ Cued: 5
19
+ };
20
+ var a, v, k, S, P, f, y, i, te, se, O, m, j, Y, F, I, R, U, x, _, V, L;
21
+ class de extends Z {
22
+ constructor(e, t) {
23
+ super(e);
24
+ p(this, i);
25
+ T(this, "$$PROVIDER_TYPE", "YOUTUBE");
26
+ T(this, "scope", A());
27
+ p(this, a);
28
+ p(this, v, G(""));
29
+ p(this, k, -1);
30
+ p(this, S, null);
31
+ p(this, P, -1);
32
+ p(this, f, !1);
33
+ p(this, y, /* @__PURE__ */ new Map());
34
+ /**
35
+ * Sets the player's interface language. The parameter value is an ISO 639-1 two-letter
36
+ * language code or a fully specified locale. For example, fr and fr-ca are both valid values.
37
+ * Other language input codes, such as IETF language tags (BCP 47) might also be handled properly.
38
+ *
39
+ * The interface language is used for tooltips in the player and also affects the default caption
40
+ * track. Note that YouTube might select a different caption track language for a particular
41
+ * user based on the user's individual language preferences and the availability of caption tracks.
42
+ *
43
+ * @defaultValue 'en'
44
+ */
45
+ T(this, "language", "en");
46
+ T(this, "color", "red");
47
+ /**
48
+ * Whether cookies should be enabled on the embed. This is turned off by default to be
49
+ * GDPR-compliant.
50
+ *
51
+ * @defaultValue `false`
52
+ */
53
+ T(this, "cookies", !1);
54
+ l(this, a, t);
55
+ }
56
+ get currentSrc() {
57
+ return s(this, S);
58
+ }
59
+ get type() {
60
+ return "youtube";
61
+ }
62
+ get videoId() {
63
+ return s(this, v).call(this);
64
+ }
65
+ preconnect() {
66
+ H(this.getOrigin());
67
+ }
68
+ setup() {
69
+ super.setup(), J(o(this, i, O).bind(this)), s(this, a).notify("provider-setup", this);
70
+ }
71
+ destroy() {
72
+ o(this, i, _).call(this);
73
+ const e = "provider destroyed";
74
+ for (const t of s(this, y).values())
75
+ for (const { reject: d } of t) d(e);
76
+ s(this, y).clear();
77
+ }
78
+ async play() {
79
+ return o(this, i, m).call(this, "playVideo");
80
+ }
81
+ async pause() {
82
+ return o(this, i, m).call(this, "pauseVideo");
83
+ }
84
+ setMuted(e) {
85
+ e ? o(this, i, m).call(this, "mute") : o(this, i, m).call(this, "unMute");
86
+ }
87
+ setCurrentTime(e) {
88
+ o(this, i, m).call(this, "seekTo", e), s(this, a).notify("seeking", e);
89
+ }
90
+ setVolume(e) {
91
+ o(this, i, m).call(this, "setVolume", e * 100);
92
+ }
93
+ setPlaybackRate(e) {
94
+ o(this, i, m).call(this, "setPlaybackRate", e);
95
+ }
96
+ async loadSource(e) {
97
+ if (!K(e.src)) {
98
+ l(this, S, null), s(this, v).set("");
99
+ return;
100
+ }
101
+ const t = ee(e.src);
102
+ s(this, v).set(t ?? ""), l(this, S, e);
103
+ }
104
+ getOrigin() {
105
+ return this.cookies ? "https://www.youtube.com" : "https://www.youtube-nocookie.com";
106
+ }
107
+ buildParams() {
108
+ const { keyDisabled: e } = s(this, a).$props, { muted: t, playsInline: d, nativeControls: u } = s(this, a).$state, h = u();
109
+ return {
110
+ autoplay: 0,
111
+ cc_lang_pref: this.language,
112
+ cc_load_policy: h ? 1 : void 0,
113
+ color: this.color,
114
+ controls: h ? 1 : 0,
115
+ disablekb: !h || e() ? 1 : 0,
116
+ enablejsapi: 1,
117
+ fs: 1,
118
+ hl: this.language,
119
+ iv_load_policy: h ? 1 : 3,
120
+ mute: t() ? 1 : 0,
121
+ playsinline: d() ? 1 : 0
122
+ };
123
+ }
124
+ onLoad() {
125
+ window.setTimeout(() => this.postMessage({ event: "listening" }), 100);
126
+ }
127
+ onMessage({ info: e }, t) {
128
+ var c;
129
+ if (!e) return;
130
+ const { title: d, intrinsicDuration: u, playbackRate: h } = s(this, a).$state;
131
+ if (W(e.videoData) && e.videoData.title !== d() && s(this, a).notify("title-change", e.videoData.title, t), $(e.duration) && e.duration !== u()) {
132
+ if ($(e.videoLoadedFraction)) {
133
+ const g = ((c = e.progressState) == null ? void 0 : c.loaded) ?? e.videoLoadedFraction * e.duration, w = new M(0, e.duration);
134
+ o(this, i, I).call(this, g, w, t);
135
+ }
136
+ s(this, a).notify("duration-change", e.duration, t);
137
+ }
138
+ if ($(e.playbackRate) && e.playbackRate !== h() && s(this, a).notify("rate-change", e.playbackRate, t), e.progressState) {
139
+ const { current: g, seekableStart: w, seekableEnd: E, loaded: q, duration: B } = e.progressState;
140
+ o(this, i, F).call(this, g, t), o(this, i, I).call(this, q, new M(w, E), t), B !== u() && s(this, a).notify("duration-change", B, t);
141
+ }
142
+ if ($(e.volume) && X(e.muted) && !s(this, f)) {
143
+ const g = {
144
+ muted: e.muted,
145
+ volume: e.volume / 100
146
+ };
147
+ s(this, a).notify("volume-change", g, t);
148
+ }
149
+ $(e.playerState) && e.playerState !== s(this, k) && o(this, i, x).call(this, e.playerState, t);
150
+ }
151
+ }
152
+ a = new WeakMap(), v = new WeakMap(), k = new WeakMap(), S = new WeakMap(), P = new WeakMap(), f = new WeakMap(), y = new WeakMap(), i = new WeakSet(), te = function(e) {
153
+ var t;
154
+ (t = o(this, i, V).call(this, "playVideo")) == null || t.reject(e);
155
+ }, se = function(e) {
156
+ var t;
157
+ (t = o(this, i, V).call(this, "pauseVideo")) == null || t.reject(e);
158
+ }, O = function() {
159
+ o(this, i, _).call(this);
160
+ const e = s(this, v).call(this);
161
+ if (!e) {
162
+ this.src.set("");
163
+ return;
164
+ }
165
+ this.src.set(`${this.getOrigin()}/embed/${e}`), s(this, a).notify("load-start");
166
+ }, m = function(e, t) {
167
+ let d = Q(), u = s(this, y).get(e);
168
+ return u || s(this, y).set(e, u = []), u.push(d), this.postMessage({
169
+ event: "command",
170
+ func: e,
171
+ args: t ? [t] : void 0
172
+ }), d.promise;
173
+ }, j = function(e) {
174
+ s(this, a).notify("loaded-metadata"), s(this, a).notify("loaded-data"), s(this, a).delegate.ready(void 0, e);
175
+ }, Y = function(e) {
176
+ var t;
177
+ (t = o(this, i, V).call(this, "pauseVideo")) == null || t.resolve(), s(this, a).notify("pause", void 0, e);
178
+ }, F = function(e, t) {
179
+ const { duration: d, realCurrentTime: u } = s(this, a).$state, h = s(this, k) === b.Ended, c = h ? d() : e;
180
+ s(this, a).notify("time-change", c, t), !h && Math.abs(c - u()) > 1 && s(this, a).notify("seeking", c, t);
181
+ }, I = function(e, t, d) {
182
+ const u = {
183
+ buffered: new M(0, e),
184
+ seekable: t
185
+ };
186
+ s(this, a).notify("progress", u, d);
187
+ const { seeking: h, realCurrentTime: c } = s(this, a).$state;
188
+ h() && e > c() && o(this, i, R).call(this, d);
189
+ }, R = function(e) {
190
+ const { paused: t, realCurrentTime: d } = s(this, a).$state;
191
+ window.clearTimeout(s(this, P)), l(this, P, window.setTimeout(
192
+ () => {
193
+ s(this, a).notify("seeked", d(), e), l(this, P, -1);
194
+ },
195
+ t() ? 100 : 0
196
+ ));
197
+ }, U = function(e) {
198
+ const { seeking: t } = s(this, a).$state;
199
+ t() && o(this, i, R).call(this, e), s(this, a).notify("pause", void 0, e), s(this, a).notify("end", void 0, e);
200
+ }, x = function(e, t) {
201
+ var E;
202
+ const { paused: d, seeking: u } = s(this, a).$state, h = e === b.Playing, c = e === b.Buffering, g = o(this, i, L).call(this, "playVideo"), w = d() && (c || h);
203
+ if (c && s(this, a).notify("waiting", void 0, t), u() && h && o(this, i, R).call(this, t), s(this, f) && h) {
204
+ this.pause(), l(this, f, !1), this.setMuted(s(this, a).$state.muted());
205
+ return;
206
+ }
207
+ if (!g && w) {
208
+ l(this, f, !0), this.setMuted(!0);
209
+ return;
210
+ }
211
+ switch (w && ((E = o(this, i, V).call(this, "playVideo")) == null || E.resolve(), s(this, a).notify("play", void 0, t)), e) {
212
+ case b.Cued:
213
+ o(this, i, j).call(this, t);
214
+ break;
215
+ case b.Playing:
216
+ s(this, a).notify("playing", void 0, t);
217
+ break;
218
+ case b.Paused:
219
+ o(this, i, Y).call(this, t);
220
+ break;
221
+ case b.Ended:
222
+ o(this, i, U).call(this, t);
223
+ break;
224
+ }
225
+ l(this, k, e);
226
+ }, _ = function() {
227
+ l(this, k, -1), l(this, P, -1), l(this, f, !1);
228
+ }, V = function(e) {
229
+ var t;
230
+ return (t = s(this, y).get(e)) == null ? void 0 : t.shift();
231
+ }, L = function(e) {
232
+ var t;
233
+ return !!((t = s(this, y).get(e)) != null && t.length);
234
+ };
235
+ export {
236
+ de as YouTubeProvider
237
+ };
@@ -0,0 +1,323 @@
1
+ var rt = Object.defineProperty;
2
+ var V = (n) => {
3
+ throw TypeError(n);
4
+ };
5
+ var ot = (n, t, i) => t in n ? rt(n, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : n[t] = i;
6
+ var _ = (n, t, i) => ot(n, typeof t != "symbol" ? t + "" : t, i), R = (n, t, i) => t.has(n) || V("Cannot " + i);
7
+ var e = (n, t, i) => (R(n, t, "read from private field"), i ? i.call(n) : t.get(n)), p = (n, t, i) => t.has(n) ? V("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(n) : t.set(n, i), f = (n, t, i, s) => (R(n, t, "write to private field"), s ? s.call(n, i) : t.set(n, i), i), a = (n, t, i) => (R(n, t, "access private method"), i);
8
+ import { V as ht, i as at, b as C, p as dt, c as O, Q as N, l as j, e as ut, D as x, R as ct, T as lt, d as k, L as $, I as pt, f as q, g as ft, h as vt, j as yt, k as gt } from "./index-BM9a_WKH.js";
9
+ import "react";
10
+ const Lt = (n) => gt(n);
11
+ var T, h, o, D, b, r, E, M, U, F, Q, K, W, B, J, X, Y, z, G, Z, tt;
12
+ class St {
13
+ constructor(t, i) {
14
+ p(this, r);
15
+ p(this, T);
16
+ p(this, h);
17
+ p(this, o, null);
18
+ p(this, D, null);
19
+ _(this, "config", {});
20
+ p(this, b, /* @__PURE__ */ new Set());
21
+ f(this, T, t), f(this, h, i);
22
+ }
23
+ get instance() {
24
+ return e(this, o);
25
+ }
26
+ setup(t) {
27
+ const { streamType: i } = e(this, h).$state, s = O(i).includes("live"), c = O(i).includes("ll-");
28
+ f(this, o, new t({
29
+ lowLatencyMode: c,
30
+ backBufferLength: c ? 4 : s ? 8 : void 0,
31
+ renderTextTracksNatively: !1,
32
+ ...this.config
33
+ }));
34
+ const u = a(this, r, F).bind(this);
35
+ for (const l of Object.values(t.Events)) e(this, o).on(l, u);
36
+ e(this, o).on(t.Events.ERROR, a(this, r, Y).bind(this));
37
+ for (const l of e(this, b)) l(e(this, o));
38
+ e(this, h).player.dispatch("hls-instance", {
39
+ detail: e(this, o)
40
+ }), e(this, o).attachMedia(e(this, T)), e(this, o).on(t.Events.AUDIO_TRACK_SWITCHED, a(this, r, W).bind(this)), e(this, o).on(t.Events.LEVEL_SWITCHED, a(this, r, B).bind(this)), e(this, o).on(t.Events.LEVEL_LOADED, a(this, r, X).bind(this)), e(this, o).on(t.Events.LEVEL_UPDATED, a(this, r, J).bind(this)), e(this, o).on(t.Events.NON_NATIVE_TEXT_TRACKS_FOUND, a(this, r, Q).bind(this)), e(this, o).on(t.Events.CUES_PARSED, a(this, r, K).bind(this)), e(this, h).qualities[N.enableAuto] = a(this, r, G).bind(this), j(e(this, h).qualities, "change", a(this, r, Z).bind(this)), j(e(this, h).audioTracks, "change", a(this, r, tt).bind(this)), f(this, D, ut(a(this, r, M).bind(this)));
41
+ }
42
+ onInstance(t) {
43
+ return e(this, b).add(t), () => e(this, b).delete(t);
44
+ }
45
+ loadSource(t) {
46
+ var i;
47
+ C(t.src) && ((i = e(this, o)) == null || i.loadSource(t.src));
48
+ }
49
+ destroy() {
50
+ var t, i;
51
+ (t = e(this, o)) == null || t.destroy(), f(this, o, null), (i = e(this, D)) == null || i.call(this), f(this, D, null);
52
+ }
53
+ }
54
+ T = new WeakMap(), h = new WeakMap(), o = new WeakMap(), D = new WeakMap(), b = new WeakMap(), r = new WeakSet(), E = function(t, i) {
55
+ return new x(Lt(t), { detail: i });
56
+ }, M = function() {
57
+ if (!e(this, h).$state.live()) return;
58
+ const t = new ct(a(this, r, U).bind(this));
59
+ return t.start(), t.stop.bind(t);
60
+ }, U = function() {
61
+ var t;
62
+ e(this, h).$state.liveSyncPosition.set(((t = e(this, o)) == null ? void 0 : t.liveSyncPosition) ?? 1 / 0);
63
+ }, F = function(t, i) {
64
+ var s;
65
+ (s = e(this, h).player) == null || s.dispatch(a(this, r, E).call(this, t, i));
66
+ }, Q = function(t, i) {
67
+ const s = a(this, r, E).call(this, t, i);
68
+ let c = -1;
69
+ for (let u = 0; u < i.tracks.length; u++) {
70
+ const l = i.tracks[u], d = l.subtitleTrack ?? l.closedCaptions, w = new lt({
71
+ id: `hls-${l.kind}-${u}`,
72
+ src: d == null ? void 0 : d.url,
73
+ label: l.label,
74
+ language: d == null ? void 0 : d.lang,
75
+ kind: l.kind,
76
+ default: l.default
77
+ });
78
+ w[k.readyState] = 2, w[k.onModeChange] = () => {
79
+ w.mode === "showing" ? (e(this, o).subtitleTrack = u, c = u) : c === u && (e(this, o).subtitleTrack = -1, c = -1);
80
+ }, e(this, h).textTracks.add(w, s);
81
+ }
82
+ }, K = function(t, i) {
83
+ var l;
84
+ const s = (l = e(this, o)) == null ? void 0 : l.subtitleTrack, c = e(this, h).textTracks.getById(`hls-${i.type}-${s}`);
85
+ if (!c) return;
86
+ const u = a(this, r, E).call(this, t, i);
87
+ for (const d of i.cues)
88
+ d.positionAlign = "auto", c.addCue(d, u);
89
+ }, W = function(t, i) {
90
+ const s = e(this, h).audioTracks[i.id];
91
+ if (s) {
92
+ const c = a(this, r, E).call(this, t, i);
93
+ e(this, h).audioTracks[$.select](s, !0, c);
94
+ }
95
+ }, B = function(t, i) {
96
+ const s = e(this, h).qualities[i.level];
97
+ if (s) {
98
+ const c = a(this, r, E).call(this, t, i);
99
+ e(this, h).qualities[$.select](s, !0, c);
100
+ }
101
+ }, J = function(t, i) {
102
+ i.details.totalduration > 0 && e(this, h).$state.inferredLiveDVRWindow.set(i.details.totalduration);
103
+ }, X = function(t, i) {
104
+ var P;
105
+ if (e(this, h).$state.canPlay()) return;
106
+ const { type: s, live: c, totalduration: u, targetduration: l } = i.details, d = a(this, r, E).call(this, t, i);
107
+ e(this, h).notify(
108
+ "stream-type-change",
109
+ c ? s === "EVENT" && Number.isFinite(u) && l >= 10 ? "live:dvr" : "live" : "on-demand",
110
+ d
111
+ ), e(this, h).notify("duration-change", u, d);
112
+ const w = e(this, o).media;
113
+ e(this, o).currentLevel === -1 && e(this, h).qualities[N.setAuto](!0, d);
114
+ for (const y of e(this, o).audioTracks) {
115
+ const H = {
116
+ id: y.id.toString(),
117
+ label: y.name,
118
+ language: y.lang || "",
119
+ kind: "main"
120
+ };
121
+ e(this, h).audioTracks[$.add](H, d);
122
+ }
123
+ for (const y of e(this, o).levels) {
124
+ const H = {
125
+ id: ((P = y.id) == null ? void 0 : P.toString()) ?? y.height + "p",
126
+ width: y.width,
127
+ height: y.height,
128
+ codec: y.codecSet,
129
+ bitrate: y.bitrate
130
+ };
131
+ e(this, h).qualities[$.add](H, d);
132
+ }
133
+ w.dispatchEvent(new x("canplay", { trigger: d }));
134
+ }, Y = function(t, i) {
135
+ var s;
136
+ if (i.fatal)
137
+ switch (i.type) {
138
+ case "mediaError":
139
+ (s = e(this, o)) == null || s.recoverMediaError();
140
+ break;
141
+ default:
142
+ a(this, r, z).call(this, i.error);
143
+ break;
144
+ }
145
+ }, z = function(t) {
146
+ e(this, h).notify("error", {
147
+ message: t.message,
148
+ code: 1,
149
+ error: t
150
+ });
151
+ }, G = function() {
152
+ e(this, o) && (e(this, o).currentLevel = -1);
153
+ }, Z = function() {
154
+ const { qualities: t } = e(this, h);
155
+ !e(this, o) || t.auto || (e(this, o)[t.switch + "Level"] = t.selectedIndex, pt && (e(this, T).currentTime = e(this, T).currentTime));
156
+ }, tt = function() {
157
+ const { audioTracks: t } = e(this, h);
158
+ e(this, o) && e(this, o).audioTrack !== t.selectedIndex && (e(this, o).audioTrack = t.selectedIndex);
159
+ };
160
+ var m, g, I, L, it, et, st, nt;
161
+ class Et {
162
+ constructor(t, i, s) {
163
+ p(this, L);
164
+ p(this, m);
165
+ p(this, g);
166
+ p(this, I);
167
+ f(this, m, t), f(this, g, i), f(this, I, s), a(this, L, it).call(this);
168
+ }
169
+ }
170
+ m = new WeakMap(), g = new WeakMap(), I = new WeakMap(), L = new WeakSet(), it = async function() {
171
+ const t = {
172
+ onLoadStart: a(this, L, et).bind(this),
173
+ onLoaded: a(this, L, st).bind(this),
174
+ onLoadError: a(this, L, nt).bind(this)
175
+ };
176
+ let i = await mt(e(this, m), t);
177
+ if (q(i) && !C(e(this, m)) && (i = await Tt(e(this, m), t)), !i) return null;
178
+ if (!i.isSupported()) {
179
+ const s = "[vidstack] `hls.js` is not supported in this environment";
180
+ return e(this, g).player.dispatch(new x("hls-unsupported")), e(this, g).notify("error", { message: s, code: 4 }), null;
181
+ }
182
+ return i;
183
+ }, et = function() {
184
+ e(this, g).player.dispatch(new x("hls-lib-load-start"));
185
+ }, st = function(t) {
186
+ e(this, g).player.dispatch(
187
+ new x("hls-lib-loaded", {
188
+ detail: t
189
+ })
190
+ ), e(this, I).call(this, t);
191
+ }, nt = function(t) {
192
+ const i = ft(t);
193
+ e(this, g).player.dispatch(
194
+ new x("hls-lib-load-error", {
195
+ detail: i
196
+ })
197
+ ), e(this, g).notify("error", {
198
+ message: i.message,
199
+ code: 4,
200
+ error: i
201
+ });
202
+ };
203
+ async function Tt(n, t = {}) {
204
+ var i, s, c, u, l;
205
+ if (!q(n)) {
206
+ if ((i = t.onLoadStart) == null || i.call(t), n.prototype && n.prototype !== Function)
207
+ return (s = t.onLoaded) == null || s.call(t, n), n;
208
+ try {
209
+ const d = (c = await n()) == null ? void 0 : c.default;
210
+ if (d && d.isSupported)
211
+ (u = t.onLoaded) == null || u.call(t, d);
212
+ else
213
+ throw Error(
214
+ ""
215
+ );
216
+ return d;
217
+ } catch (d) {
218
+ (l = t.onLoadError) == null || l.call(t, d);
219
+ }
220
+ }
221
+ }
222
+ async function mt(n, t = {}) {
223
+ var i, s, c;
224
+ if (C(n)) {
225
+ (i = t.onLoadStart) == null || i.call(t);
226
+ try {
227
+ if (await vt(n), !yt(window.Hls))
228
+ throw Error(
229
+ ""
230
+ );
231
+ const u = window.Hls;
232
+ return (s = t.onLoaded) == null || s.call(t, u), u;
233
+ } catch (u) {
234
+ (c = t.onLoadError) == null || c.call(t, u);
235
+ }
236
+ }
237
+ }
238
+ const wt = "https://cdn.jsdelivr.net";
239
+ var A, v, S;
240
+ class xt extends ht {
241
+ constructor() {
242
+ super(...arguments);
243
+ _(this, "$$PROVIDER_TYPE", "HLS");
244
+ p(this, A, null);
245
+ p(this, v, new St(this.video, this.ctx));
246
+ p(this, S, `${wt}/npm/hls.js@^1.5.0/dist/hls.min.js`);
247
+ }
248
+ /**
249
+ * The `hls.js` constructor.
250
+ */
251
+ get ctor() {
252
+ return e(this, A);
253
+ }
254
+ /**
255
+ * The current `hls.js` instance.
256
+ */
257
+ get instance() {
258
+ return e(this, v).instance;
259
+ }
260
+ get type() {
261
+ return "hls";
262
+ }
263
+ get canLiveSync() {
264
+ return !0;
265
+ }
266
+ /**
267
+ * The `hls.js` configuration object.
268
+ *
269
+ * @see {@link https://github.com/video-dev/hls.js/blob/master/docs/API.md#fine-tuning}
270
+ */
271
+ get config() {
272
+ return e(this, v).config;
273
+ }
274
+ set config(i) {
275
+ e(this, v).config = i;
276
+ }
277
+ /**
278
+ * The `hls.js` constructor (supports dynamic imports) or a URL of where it can be found.
279
+ *
280
+ * @defaultValue `https://cdn.jsdelivr.net/npm/hls.js@^1.0.0/dist/hls.min.js`
281
+ */
282
+ get library() {
283
+ return e(this, S);
284
+ }
285
+ set library(i) {
286
+ f(this, S, i);
287
+ }
288
+ preconnect() {
289
+ C(e(this, S)) && dt(e(this, S));
290
+ }
291
+ setup() {
292
+ super.setup(), new Et(e(this, S), this.ctx, (i) => {
293
+ f(this, A, i), e(this, v).setup(i), this.ctx.notify("provider-setup", this);
294
+ const s = O(this.ctx.$state.source);
295
+ s && this.loadSource(s);
296
+ });
297
+ }
298
+ async loadSource(i, s) {
299
+ if (!C(i.src)) {
300
+ this.removeSource();
301
+ return;
302
+ }
303
+ this.media.preload = s || "", this.appendSource(i, "application/x-mpegurl"), e(this, v).loadSource(i), this.currentSrc = i;
304
+ }
305
+ /**
306
+ * The given callback is invoked when a new `hls.js` instance is created and right before it's
307
+ * attached to media.
308
+ */
309
+ onInstance(i) {
310
+ const s = e(this, v).instance;
311
+ return s && i(s), e(this, v).onInstance(i);
312
+ }
313
+ destroy() {
314
+ e(this, v).destroy();
315
+ }
316
+ }
317
+ A = new WeakMap(), v = new WeakMap(), S = new WeakMap(), /**
318
+ * Whether `hls.js` is supported in this environment.
319
+ */
320
+ _(xt, "supported", at());
321
+ export {
322
+ xt as HLSProvider
323
+ };
@@ -0,0 +1,31 @@
1
+ const i = /(?:youtu\.be|youtube|youtube\.com|youtube-nocookie\.com)\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=|)((?:\w|-){11})/, u = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map();
2
+ function h(e) {
3
+ var t;
4
+ return (t = e.match(i)) == null ? void 0 : t[1];
5
+ }
6
+ async function b(e, t) {
7
+ if (u.has(e)) return u.get(e);
8
+ if (s.has(e)) return s.get(e);
9
+ const n = new Promise(async (c) => {
10
+ const r = ["maxresdefault", "sddefault", "hqdefault"];
11
+ for (const a of r)
12
+ for (const f of [!0, !1]) {
13
+ const o = p(e, a, f);
14
+ if ((await fetch(o, {
15
+ mode: "no-cors",
16
+ signal: t.signal
17
+ })).status < 400) {
18
+ u.set(e, o), c(o);
19
+ return;
20
+ }
21
+ }
22
+ }).catch(() => "").finally(() => s.delete(e));
23
+ return s.set(e, n), n;
24
+ }
25
+ function p(e, t, n) {
26
+ return `https://i.ytimg.com/${n ? "vi_webp" : "vi"}/${e}/${t}.${n ? "webp" : "jpg"}`;
27
+ }
28
+ export {
29
+ b as findYouTubePoster,
30
+ h as resolveYouTubeVideoId
31
+ };
@@ -0,0 +1,29 @@
1
+ const g = /(?:https:\/\/)?(?:player\.)?vimeo(?:\.com)?\/(?:video\/)?(\d+)(?:(?:\?hash=|\?h=|\/)(.*))?/, c = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map();
2
+ function b(n) {
3
+ const o = n.match(g);
4
+ return { videoId: o == null ? void 0 : o[1], hash: o == null ? void 0 : o[2] };
5
+ }
6
+ async function w(n, o, r) {
7
+ if (c.has(n)) return c.get(n);
8
+ if (i.has(n)) return i.get(n);
9
+ let t = `https://vimeo.com/api/oembed.json?url=https://player.vimeo.com/video/${n}`;
10
+ r && (t = t.concat(`?h=${r}`));
11
+ const s = window.fetch(t, {
12
+ mode: "cors",
13
+ signal: o.signal
14
+ }).then((e) => e.json()).then((e) => {
15
+ var l, p;
16
+ const u = /vimeocdn.com\/video\/(.*)?_/, h = (p = (l = e == null ? void 0 : e.thumbnail_url) == null ? void 0 : l.match(u)) == null ? void 0 : p[1], f = h ? `https://i.vimeocdn.com/video/${h}_1920x1080.webp` : "", m = {
17
+ title: (e == null ? void 0 : e.title) ?? "",
18
+ duration: (e == null ? void 0 : e.duration) ?? 0,
19
+ poster: f,
20
+ pro: e.account_type !== "basic"
21
+ };
22
+ return c.set(n, m), m;
23
+ }).finally(() => i.delete(n));
24
+ return i.set(n, s), s;
25
+ }
26
+ export {
27
+ w as getVimeoVideoInfo,
28
+ b as resolveVimeoVideoId
29
+ };
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "@instructure/studio-player",
3
+ "version": "0.1.1",
4
+ "private": false,
5
+ "description": "Next generation media player for Instructure",
6
+ "module": "./dist/studio-player.es.js",
7
+ "types": "./dist/index.d.ts",
8
+ "type": "module",
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "exports": {
13
+ ".": {
14
+ "import": "./dist/studio-player.es.js"
15
+ }
16
+ },
17
+ "lint-staged": {
18
+ "*.css": "pnpm stylelint"
19
+ },
20
+ "license": "MIT",
21
+ "devDependencies": {
22
+ "@eslint/js": "^9.10.0",
23
+ "@storybook/addon-actions": "^8.3.0",
24
+ "@storybook/addon-essentials": "^8.3.0",
25
+ "@storybook/addon-interactions": "^8.3.0",
26
+ "@storybook/addon-links": "^8.3.0",
27
+ "@storybook/blocks": "^8.3.0",
28
+ "@storybook/react": "^8.3.0",
29
+ "@storybook/react-vite": "^8.3.0",
30
+ "@svgr/core": "^8.1.0",
31
+ "@svgr/plugin-jsx": "^8.1.0",
32
+ "@testing-library/dom": "^10.4.0",
33
+ "@testing-library/jest-dom": "^6.5.0",
34
+ "@testing-library/react": "^16.0.1",
35
+ "@testing-library/user-event": "^14.5.2",
36
+ "@types/react": "^18.3.5",
37
+ "@types/react-dom": "^18.3.0",
38
+ "@vitejs/plugin-react-swc": "^3.7.0",
39
+ "@vitest/expect": "^2.1.1",
40
+ "eslint": "^9.10.0",
41
+ "eslint-plugin-import": "^2.30.0",
42
+ "eslint-plugin-react": "^7.36.1",
43
+ "globals": "^15.9.0",
44
+ "happy-dom": "^15.7.4",
45
+ "husky": "^9.1.6",
46
+ "lint-staged": "^15.2.10",
47
+ "postcss-nesting": "^13.0.0",
48
+ "storybook": "^8.3.0",
49
+ "stylelint": "^16.9.0",
50
+ "stylelint-config-css-modules": "^4.4.0",
51
+ "stylelint-config-standard": "^36.0.1",
52
+ "typescript": "^5.6.2",
53
+ "typescript-eslint": "^8.5.0",
54
+ "unplugin-icons": "^0.19.3",
55
+ "vite": "^5.4.5",
56
+ "vite-plugin-dts": "^4.2.1",
57
+ "vite-plugin-lib-inject-css": "^2.1.1",
58
+ "vite-tsconfig-paths": "^5.0.1",
59
+ "vitest": "^2.1.1"
60
+ },
61
+ "dependencies": {
62
+ "@floating-ui/react": "^0.26.24",
63
+ "@vidstack/react": "^1.12.11",
64
+ "react": "^18.3.1",
65
+ "react-dom": "^18.3.1"
66
+ },
67
+ "scripts": {
68
+ "build": "vite build",
69
+ "build-storybook": "storybook build",
70
+ "check:types": "tsc --noEmit",
71
+ "lint": "pnpm check:types && eslint",
72
+ "storybook": "storybook dev -p 6006",
73
+ "test": "vitest",
74
+ "test:ci": "vitest --reporter=basic --disable-console-intercept --no-watch",
75
+ "stylelint": "stylelint 'src/**/*.css'",
76
+ "stylelint:fix": "stylelint 'src/**/*.css' --fix"
77
+ }
78
+ }