@mdcrtrs/player 0.3.0 → 0.4.0
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/README.md +6 -0
- package/dist/index.cjs +153 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -3
- package/dist/index.d.ts +15 -3
- package/dist/index.js +153 -41
- package/dist/index.js.map +1 -1
- package/package.json +12 -12
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { FC } from 'react';
|
|
2
2
|
|
|
3
|
+
/** Platform environment. `preview` targets the preview Workers; defaults to `production`. */
|
|
4
|
+
type PlayerEnv = "production" | "preview";
|
|
3
5
|
interface PlayerAsset {
|
|
4
6
|
assetId: string;
|
|
5
7
|
playbackId: string;
|
|
@@ -23,6 +25,8 @@ interface PlayerError {
|
|
|
23
25
|
code: string;
|
|
24
26
|
message: string;
|
|
25
27
|
}
|
|
28
|
+
/** Code the playback service answers a refused token request with (HTTP 403 `error`). */
|
|
29
|
+
type PlayerAccessState = "access_denied" | "not_available";
|
|
26
30
|
interface PlayerEvents {
|
|
27
31
|
onTimeUpdate?: (currentTime: number, duration: number, pct: number) => void;
|
|
28
32
|
onQuartile?: (quartile: 25 | 50 | 75 | 100) => void;
|
|
@@ -59,6 +63,8 @@ interface PlayerConfig {
|
|
|
59
63
|
interface MediaCreatorsPlayerProps extends PlayerEvents {
|
|
60
64
|
creatorId: string;
|
|
61
65
|
asset: PlayerAsset;
|
|
66
|
+
/** Override the platform environment (e.g. `"preview"` on preview deploys). Defaults to `"production"`. */
|
|
67
|
+
env?: PlayerEnv;
|
|
62
68
|
auth?: PlayerAuth;
|
|
63
69
|
theme?: PlayerTheme;
|
|
64
70
|
/** Custom branding override. Omit to show the default MediaCreators logo. */
|
|
@@ -70,6 +76,10 @@ interface MediaCreatorsPlayerProps extends PlayerEvents {
|
|
|
70
76
|
metadata?: PlayerMetadata;
|
|
71
77
|
autoResume?: boolean;
|
|
72
78
|
className?: string;
|
|
79
|
+
/** Host-minted playback session (sc-one). When set, the SDK never calls POST /playback-session. */
|
|
80
|
+
getSession?: () => Promise<SessionToken>;
|
|
81
|
+
/** Called when the token endpoint answers 403 with code access_denied / not_available. */
|
|
82
|
+
onAccessDenied?: (state: PlayerAccessState) => void;
|
|
73
83
|
}
|
|
74
84
|
interface PlaybackTokens {
|
|
75
85
|
video: string;
|
|
@@ -98,14 +108,16 @@ interface UsePlaybackSessionResult {
|
|
|
98
108
|
tokens: PlaybackTokens | null;
|
|
99
109
|
isLoading: boolean;
|
|
100
110
|
error: Error | null;
|
|
111
|
+
/** Set when the playback service refused the viewer (403). Not an `error`: render a lock. */
|
|
112
|
+
accessDenied: PlayerAccessState | null;
|
|
101
113
|
}
|
|
102
|
-
declare function usePlaybackSession(creatorId: string, playbackId: string, duration: number, fanToken?: string): UsePlaybackSessionResult;
|
|
114
|
+
declare function usePlaybackSession(creatorId: string, playbackId: string, duration: number, fanToken?: string, env?: PlayerEnv, getSession?: () => Promise<SessionToken>): UsePlaybackSessionResult;
|
|
103
115
|
|
|
104
116
|
interface UseWatchProgressResult {
|
|
105
117
|
resumePosition: number | null;
|
|
106
118
|
saveProgress: (position: number, duration: number) => void;
|
|
107
119
|
authExpired: boolean;
|
|
108
120
|
}
|
|
109
|
-
declare function useWatchProgress(creatorId: string, assetId: string, fanToken: string | undefined, autoResume: boolean | undefined, onResume?: (position: number) => void): UseWatchProgressResult;
|
|
121
|
+
declare function useWatchProgress(creatorId: string, assetId: string, fanToken: string | undefined, autoResume: boolean | undefined, onResume?: (position: number) => void, env?: PlayerEnv): UseWatchProgressResult;
|
|
110
122
|
|
|
111
|
-
export { MediaCreatorsPlayer, type MediaCreatorsPlayerProps, type PlaybackTokens, type PlayerAsset, type PlayerAuth, type PlayerBrandingConfig, type PlayerConfig, type PlayerControlsConfig, type PlayerError, type PlayerEvents, type PlayerMetadata, type PlayerTheme, type SessionToken, type WatchProgressRecord, usePlaybackSession, useWatchProgress };
|
|
123
|
+
export { MediaCreatorsPlayer, type MediaCreatorsPlayerProps, type PlaybackTokens, type PlayerAccessState, type PlayerAsset, type PlayerAuth, type PlayerBrandingConfig, type PlayerConfig, type PlayerControlsConfig, type PlayerEnv, type PlayerError, type PlayerEvents, type PlayerMetadata, type PlayerTheme, type SessionToken, type WatchProgressRecord, usePlaybackSession, useWatchProgress };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
2
4
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
3
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
4
6
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
@@ -14,6 +16,7 @@ var __spreadValues = (a, b) => {
|
|
|
14
16
|
}
|
|
15
17
|
return a;
|
|
16
18
|
};
|
|
19
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
17
20
|
|
|
18
21
|
// src/components/player.tsx
|
|
19
22
|
import { memo, useCallback as useCallback3, useEffect as useEffect4, useMemo, useRef as useRef5 } from "react";
|
|
@@ -1081,11 +1084,19 @@ if (globalThis.customElements && !globalThis.customElements.get("media-theme-med
|
|
|
1081
1084
|
import { useEffect, useRef, useState } from "react";
|
|
1082
1085
|
|
|
1083
1086
|
// src/types.ts
|
|
1084
|
-
var
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1087
|
+
var PLATFORM_ENDPOINTS = {
|
|
1088
|
+
production: {
|
|
1089
|
+
apiBase: "https://api.mediacreators.io",
|
|
1090
|
+
playbackBase: "https://playback.mediacreators.io"
|
|
1091
|
+
},
|
|
1092
|
+
preview: {
|
|
1093
|
+
apiBase: "https://preview-api.mediacreators.io",
|
|
1094
|
+
playbackBase: "https://preview-playback.mediacreators.io"
|
|
1095
|
+
}
|
|
1088
1096
|
};
|
|
1097
|
+
var PLATFORM = __spreadProps(__spreadValues({}, PLATFORM_ENDPOINTS.production), {
|
|
1098
|
+
dataEnvKey: "fhri2484lqcn6gk89r013ckmb"
|
|
1099
|
+
});
|
|
1089
1100
|
|
|
1090
1101
|
// src/lib/api.ts
|
|
1091
1102
|
var ApiError = class extends Error {
|
|
@@ -1095,6 +1106,22 @@ var ApiError = class extends Error {
|
|
|
1095
1106
|
this.name = "ApiError";
|
|
1096
1107
|
}
|
|
1097
1108
|
};
|
|
1109
|
+
var AccessDeniedError = class extends ApiError {
|
|
1110
|
+
constructor(state) {
|
|
1111
|
+
super(state === "not_available" ? "Content is not available" : "Access denied", 403);
|
|
1112
|
+
this.state = state;
|
|
1113
|
+
this.name = "AccessDeniedError";
|
|
1114
|
+
}
|
|
1115
|
+
};
|
|
1116
|
+
async function readAccessState(res) {
|
|
1117
|
+
try {
|
|
1118
|
+
const body = await res.json();
|
|
1119
|
+
const code = body == null ? void 0 : body.error;
|
|
1120
|
+
return code === "access_denied" || code === "not_available" ? code : null;
|
|
1121
|
+
} catch (e) {
|
|
1122
|
+
return null;
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1098
1125
|
async function fetchWithRetry(url, init, maxRetries = 3) {
|
|
1099
1126
|
let lastError = new Error("Unknown fetch error");
|
|
1100
1127
|
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
@@ -1113,12 +1140,12 @@ async function fetchWithRetry(url, init, maxRetries = 3) {
|
|
|
1113
1140
|
}
|
|
1114
1141
|
throw lastError;
|
|
1115
1142
|
}
|
|
1116
|
-
async function fetchSessionToken(creatorId, fanToken) {
|
|
1143
|
+
async function fetchSessionToken(creatorId, fanToken, env = "production") {
|
|
1117
1144
|
const headers = {};
|
|
1118
1145
|
if (fanToken) {
|
|
1119
1146
|
headers["X-Fan-Token"] = fanToken;
|
|
1120
1147
|
}
|
|
1121
|
-
const url = `${
|
|
1148
|
+
const url = `${PLATFORM_ENDPOINTS[env].apiBase}/v1/mos/${encodeURIComponent(creatorId)}/playback-session`;
|
|
1122
1149
|
const res = await fetchWithRetry(url, { method: "POST", headers });
|
|
1123
1150
|
if (!res.ok) {
|
|
1124
1151
|
throw new ApiError(`Failed to fetch session token: ${res.status}`, res.status);
|
|
@@ -1126,12 +1153,16 @@ async function fetchSessionToken(creatorId, fanToken) {
|
|
|
1126
1153
|
const json = await res.json();
|
|
1127
1154
|
return { token: json.token, expiresAt: json.expires_at };
|
|
1128
1155
|
}
|
|
1129
|
-
async function fetchPlaybackTokens(creatorId, playbackId, duration, sessionToken) {
|
|
1156
|
+
async function fetchPlaybackTokens(creatorId, playbackId, duration, sessionToken, env = "production") {
|
|
1130
1157
|
const params = new URLSearchParams({ duration: String(duration) });
|
|
1131
|
-
const url = `${
|
|
1158
|
+
const url = `${PLATFORM_ENDPOINTS[env].playbackBase}/v1/${encodeURIComponent(creatorId)}/tokens/${encodeURIComponent(playbackId)}?${params}`;
|
|
1132
1159
|
const res = await fetchWithRetry(url, {
|
|
1133
1160
|
headers: { Authorization: `Bearer ${sessionToken}` }
|
|
1134
1161
|
});
|
|
1162
|
+
if (res.status === 403) {
|
|
1163
|
+
const state = await readAccessState(res);
|
|
1164
|
+
if (state) throw new AccessDeniedError(state);
|
|
1165
|
+
}
|
|
1135
1166
|
if (res.status === 401 || res.status === 403) {
|
|
1136
1167
|
throw new ApiError("Session token invalid or expired", res.status);
|
|
1137
1168
|
}
|
|
@@ -1146,8 +1177,8 @@ async function fetchPlaybackTokens(creatorId, playbackId, duration, sessionToken
|
|
|
1146
1177
|
expiresIn: json.expires_in
|
|
1147
1178
|
};
|
|
1148
1179
|
}
|
|
1149
|
-
async function saveWatchProgress(creatorId, assetId, position, duration, fanToken, completed) {
|
|
1150
|
-
const url = `${
|
|
1180
|
+
async function saveWatchProgress(creatorId, assetId, position, duration, fanToken, completed, env = "production") {
|
|
1181
|
+
const url = `${PLATFORM_ENDPOINTS[env].apiBase}/v1/mos/${encodeURIComponent(creatorId)}/watch-progress/${encodeURIComponent(assetId)}`;
|
|
1151
1182
|
try {
|
|
1152
1183
|
const res = await fetch(url, {
|
|
1153
1184
|
method: "PUT",
|
|
@@ -1164,8 +1195,8 @@ async function saveWatchProgress(creatorId, assetId, position, duration, fanToke
|
|
|
1164
1195
|
return { ok: false, status: 0 };
|
|
1165
1196
|
}
|
|
1166
1197
|
}
|
|
1167
|
-
async function getWatchProgress(creatorId, assetId, fanToken) {
|
|
1168
|
-
const url = `${
|
|
1198
|
+
async function getWatchProgress(creatorId, assetId, fanToken, env = "production") {
|
|
1199
|
+
const url = `${PLATFORM_ENDPOINTS[env].apiBase}/v1/mos/${encodeURIComponent(creatorId)}/watch-progress/${encodeURIComponent(assetId)}`;
|
|
1169
1200
|
try {
|
|
1170
1201
|
const res = await fetch(url, {
|
|
1171
1202
|
headers: { "X-Fan-Token": fanToken }
|
|
@@ -1199,10 +1230,13 @@ function cancelRefresh(timerRef) {
|
|
|
1199
1230
|
timerRef.current = null;
|
|
1200
1231
|
}
|
|
1201
1232
|
}
|
|
1202
|
-
function usePlaybackSession(creatorId, playbackId, duration, fanToken) {
|
|
1233
|
+
function usePlaybackSession(creatorId, playbackId, duration, fanToken, env = "production", getSession) {
|
|
1203
1234
|
const [tokens, setTokens] = useState(null);
|
|
1204
1235
|
const [isLoading, setIsLoading] = useState(true);
|
|
1205
1236
|
const [error, setError] = useState(null);
|
|
1237
|
+
const [accessDenied, setAccessDenied] = useState(null);
|
|
1238
|
+
const getSessionRef = useRef(getSession);
|
|
1239
|
+
getSessionRef.current = getSession;
|
|
1206
1240
|
const sessionTokenRef = useRef(null);
|
|
1207
1241
|
const sessionExpiresAtRef = useRef(null);
|
|
1208
1242
|
const tokensRef = useRef(null);
|
|
@@ -1214,30 +1248,48 @@ function usePlaybackSession(creatorId, playbackId, duration, fanToken) {
|
|
|
1214
1248
|
setTokens(null);
|
|
1215
1249
|
setIsLoading(true);
|
|
1216
1250
|
setError(null);
|
|
1251
|
+
setAccessDenied(null);
|
|
1252
|
+
function mintSession() {
|
|
1253
|
+
const hostSession = getSessionRef.current;
|
|
1254
|
+
return hostSession ? hostSession() : fetchSessionToken(creatorId, fanToken, env);
|
|
1255
|
+
}
|
|
1256
|
+
function deny(err) {
|
|
1257
|
+
if (cancelled) return;
|
|
1258
|
+
cancelRefresh(timerRef);
|
|
1259
|
+
tokensRef.current = null;
|
|
1260
|
+
setTokens(null);
|
|
1261
|
+
setError(null);
|
|
1262
|
+
setAccessDenied(err.state);
|
|
1263
|
+
}
|
|
1217
1264
|
async function refresh() {
|
|
1218
1265
|
if (!sessionTokenRef.current || !sessionExpiresAtRef.current) return;
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1266
|
+
try {
|
|
1267
|
+
const now = Date.now();
|
|
1268
|
+
const sessionExpiry = sessionExpiresAtRef.current.getTime();
|
|
1269
|
+
let sessionToken = sessionTokenRef.current;
|
|
1270
|
+
if (sessionExpiry - now < 6e4) {
|
|
1271
|
+
const newSession = await mintSession();
|
|
1272
|
+
sessionToken = newSession.token;
|
|
1273
|
+
sessionTokenRef.current = newSession.token;
|
|
1274
|
+
sessionExpiresAtRef.current = new Date(newSession.expiresAt);
|
|
1275
|
+
}
|
|
1276
|
+
const nextTokens = await fetchPlaybackTokens(creatorId, playbackId, duration, sessionToken, env);
|
|
1277
|
+
if (cancelled) return;
|
|
1278
|
+
tokensRef.current = nextTokens;
|
|
1279
|
+
setTokens(nextTokens);
|
|
1280
|
+
scheduleRefresh(nextTokens.expiresIn, refresh, timerRef);
|
|
1281
|
+
} catch (err) {
|
|
1282
|
+
if (!(err instanceof AccessDeniedError)) throw err;
|
|
1283
|
+
deny(err);
|
|
1227
1284
|
}
|
|
1228
|
-
const nextTokens = await fetchPlaybackTokens(creatorId, playbackId, duration, sessionToken);
|
|
1229
|
-
if (cancelled) return;
|
|
1230
|
-
tokensRef.current = nextTokens;
|
|
1231
|
-
setTokens(nextTokens);
|
|
1232
|
-
scheduleRefresh(nextTokens.expiresIn, refresh, timerRef);
|
|
1233
1285
|
}
|
|
1234
1286
|
async function initialize() {
|
|
1235
1287
|
try {
|
|
1236
|
-
const session = await
|
|
1288
|
+
const session = await mintSession();
|
|
1237
1289
|
if (cancelled) return;
|
|
1238
1290
|
sessionTokenRef.current = session.token;
|
|
1239
1291
|
sessionExpiresAtRef.current = new Date(session.expiresAt);
|
|
1240
|
-
const initialTokens = await fetchPlaybackTokens(creatorId, playbackId, duration, session.token);
|
|
1292
|
+
const initialTokens = await fetchPlaybackTokens(creatorId, playbackId, duration, session.token, env);
|
|
1241
1293
|
if (cancelled) return;
|
|
1242
1294
|
tokensRef.current = initialTokens;
|
|
1243
1295
|
setTokens(initialTokens);
|
|
@@ -1260,7 +1312,9 @@ function usePlaybackSession(creatorId, playbackId, duration, fanToken) {
|
|
|
1260
1312
|
};
|
|
1261
1313
|
document.addEventListener("visibilitychange", visibilityHandlerRef.current);
|
|
1262
1314
|
} catch (err) {
|
|
1263
|
-
if (
|
|
1315
|
+
if (err instanceof AccessDeniedError) {
|
|
1316
|
+
deny(err);
|
|
1317
|
+
} else if (!cancelled) {
|
|
1264
1318
|
setError(err instanceof Error ? err : new Error(String(err)));
|
|
1265
1319
|
setTokens(null);
|
|
1266
1320
|
}
|
|
@@ -1279,8 +1333,8 @@ function usePlaybackSession(creatorId, playbackId, duration, fanToken) {
|
|
|
1279
1333
|
sessionTokenRef.current = null;
|
|
1280
1334
|
sessionExpiresAtRef.current = null;
|
|
1281
1335
|
};
|
|
1282
|
-
}, [creatorId, playbackId, duration, fanToken]);
|
|
1283
|
-
return { tokens, isLoading, error };
|
|
1336
|
+
}, [creatorId, playbackId, duration, fanToken, env]);
|
|
1337
|
+
return { tokens, isLoading, error, accessDenied };
|
|
1284
1338
|
}
|
|
1285
1339
|
|
|
1286
1340
|
// src/hooks/use-player-events.ts
|
|
@@ -1373,7 +1427,7 @@ function useVolume() {
|
|
|
1373
1427
|
// src/hooks/use-watch-progress.ts
|
|
1374
1428
|
import { useCallback as useCallback2, useEffect as useEffect3, useRef as useRef4, useState as useState2 } from "react";
|
|
1375
1429
|
var SAVE_DEBOUNCE_MS = 1e4;
|
|
1376
|
-
function useWatchProgress(creatorId, assetId, fanToken, autoResume, onResume) {
|
|
1430
|
+
function useWatchProgress(creatorId, assetId, fanToken, autoResume, onResume, env = "production") {
|
|
1377
1431
|
const [resumePosition, setResumePosition] = useState2(null);
|
|
1378
1432
|
const [authExpired, setAuthExpired] = useState2(false);
|
|
1379
1433
|
const debounceTimer = useRef4(null);
|
|
@@ -1386,7 +1440,7 @@ function useWatchProgress(creatorId, assetId, fanToken, autoResume, onResume) {
|
|
|
1386
1440
|
setResumePosition(null);
|
|
1387
1441
|
if (!fanToken || !autoResume) return;
|
|
1388
1442
|
let cancelled = false;
|
|
1389
|
-
void getWatchProgress(creatorId, assetId, fanToken).then((record) => {
|
|
1443
|
+
void getWatchProgress(creatorId, assetId, fanToken, env).then((record) => {
|
|
1390
1444
|
var _a2;
|
|
1391
1445
|
if (cancelled || !record || record.completed) return;
|
|
1392
1446
|
if (record.position > 5) {
|
|
@@ -1401,14 +1455,14 @@ function useWatchProgress(creatorId, assetId, fanToken, autoResume, onResume) {
|
|
|
1401
1455
|
debounceTimer.current = null;
|
|
1402
1456
|
}
|
|
1403
1457
|
};
|
|
1404
|
-
}, [creatorId, assetId, fanToken, autoResume]);
|
|
1458
|
+
}, [creatorId, assetId, fanToken, autoResume, env]);
|
|
1405
1459
|
const saveProgress = useCallback2(
|
|
1406
1460
|
(position, duration) => {
|
|
1407
1461
|
if (!fanToken || stoppedRef.current) return;
|
|
1408
1462
|
if (debounceTimer.current !== null) clearTimeout(debounceTimer.current);
|
|
1409
1463
|
debounceTimer.current = setTimeout(() => {
|
|
1410
1464
|
const completed = duration > 0 && position / duration >= 0.95;
|
|
1411
|
-
void saveWatchProgress(creatorId, assetId, position, duration, fanToken, completed).then((result) => {
|
|
1465
|
+
void saveWatchProgress(creatorId, assetId, position, duration, fanToken, completed, env).then((result) => {
|
|
1412
1466
|
if (!result.ok && result.status === 401) {
|
|
1413
1467
|
stoppedRef.current = true;
|
|
1414
1468
|
setAuthExpired(true);
|
|
@@ -1416,11 +1470,49 @@ function useWatchProgress(creatorId, assetId, fanToken, autoResume, onResume) {
|
|
|
1416
1470
|
});
|
|
1417
1471
|
}, SAVE_DEBOUNCE_MS);
|
|
1418
1472
|
},
|
|
1419
|
-
[creatorId, assetId, fanToken]
|
|
1473
|
+
[creatorId, assetId, fanToken, env]
|
|
1420
1474
|
);
|
|
1421
1475
|
return { resumePosition, saveProgress, authExpired };
|
|
1422
1476
|
}
|
|
1423
1477
|
|
|
1478
|
+
// src/components/access-lock.tsx
|
|
1479
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
1480
|
+
var LABELS = {
|
|
1481
|
+
access_denied: "Locked",
|
|
1482
|
+
not_available: "Not available"
|
|
1483
|
+
};
|
|
1484
|
+
var AccessLock = ({ state, poster, className }) => /* @__PURE__ */ jsxs(
|
|
1485
|
+
"div",
|
|
1486
|
+
{
|
|
1487
|
+
className,
|
|
1488
|
+
role: "img",
|
|
1489
|
+
"aria-label": LABELS[state],
|
|
1490
|
+
"data-mc-player-state": state,
|
|
1491
|
+
style: {
|
|
1492
|
+
position: "relative",
|
|
1493
|
+
display: "flex",
|
|
1494
|
+
alignItems: "center",
|
|
1495
|
+
justifyContent: "center",
|
|
1496
|
+
width: "100%",
|
|
1497
|
+
aspectRatio: "16 / 9",
|
|
1498
|
+
overflow: "hidden",
|
|
1499
|
+
background: "#111"
|
|
1500
|
+
},
|
|
1501
|
+
children: [
|
|
1502
|
+
poster ? /* @__PURE__ */ jsx(
|
|
1503
|
+
"img",
|
|
1504
|
+
{
|
|
1505
|
+
src: poster,
|
|
1506
|
+
alt: "",
|
|
1507
|
+
"aria-hidden": "true",
|
|
1508
|
+
style: { position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover", opacity: 0.3 }
|
|
1509
|
+
}
|
|
1510
|
+
) : null,
|
|
1511
|
+
/* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", width: "48", height: "48", fill: "#fff", "aria-hidden": "true", style: { position: "relative" }, children: /* @__PURE__ */ jsx("path", { d: "M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z" }) })
|
|
1512
|
+
]
|
|
1513
|
+
}
|
|
1514
|
+
);
|
|
1515
|
+
|
|
1424
1516
|
// src/components/player-branding.tsx
|
|
1425
1517
|
function applyBranding(player, videoId, creatorId, config) {
|
|
1426
1518
|
var _a2, _b2, _c, _d;
|
|
@@ -1601,7 +1693,7 @@ function deriveTheme(primaryColor) {
|
|
|
1601
1693
|
}
|
|
1602
1694
|
|
|
1603
1695
|
// src/components/player.tsx
|
|
1604
|
-
import { jsx } from "react/jsx-runtime";
|
|
1696
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
1605
1697
|
function decodeJwtSub(token) {
|
|
1606
1698
|
try {
|
|
1607
1699
|
const payloadPart = token.split(".")[1];
|
|
@@ -1617,6 +1709,7 @@ function decodeJwtSub(token) {
|
|
|
1617
1709
|
var MediaCreatorsPlayer = memo(function MediaCreatorsPlayer2({
|
|
1618
1710
|
creatorId,
|
|
1619
1711
|
asset,
|
|
1712
|
+
env = "production",
|
|
1620
1713
|
auth,
|
|
1621
1714
|
theme,
|
|
1622
1715
|
branding,
|
|
@@ -1625,6 +1718,8 @@ var MediaCreatorsPlayer = memo(function MediaCreatorsPlayer2({
|
|
|
1625
1718
|
metadata,
|
|
1626
1719
|
autoResume,
|
|
1627
1720
|
className,
|
|
1721
|
+
getSession,
|
|
1722
|
+
onAccessDenied,
|
|
1628
1723
|
onTimeUpdate,
|
|
1629
1724
|
onQuartile,
|
|
1630
1725
|
onPause,
|
|
@@ -1637,7 +1732,14 @@ var MediaCreatorsPlayer = memo(function MediaCreatorsPlayer2({
|
|
|
1637
1732
|
}) {
|
|
1638
1733
|
var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
1639
1734
|
const durationHint = (_a2 = asset.duration) != null ? _a2 : 3600;
|
|
1640
|
-
const { tokens, isLoading, error } = usePlaybackSession(
|
|
1735
|
+
const { tokens, isLoading, error, accessDenied } = usePlaybackSession(
|
|
1736
|
+
creatorId,
|
|
1737
|
+
asset.playbackId,
|
|
1738
|
+
durationHint,
|
|
1739
|
+
auth == null ? void 0 : auth.fanToken,
|
|
1740
|
+
env,
|
|
1741
|
+
getSession
|
|
1742
|
+
);
|
|
1641
1743
|
const accentSource = (_c = (_b2 = config == null ? void 0 : config.accentColor) != null ? _b2 : theme == null ? void 0 : theme.primaryColor) != null ? _c : "#4ae9ab";
|
|
1642
1744
|
const colors = useMemo(() => deriveTheme(accentSource), [accentSource]);
|
|
1643
1745
|
const { initialVolume, handleVolumeChange } = useVolume();
|
|
@@ -1673,7 +1775,8 @@ var MediaCreatorsPlayer = memo(function MediaCreatorsPlayer2({
|
|
|
1673
1775
|
asset.assetId,
|
|
1674
1776
|
auth == null ? void 0 : auth.fanToken,
|
|
1675
1777
|
autoResume,
|
|
1676
|
-
onResume
|
|
1778
|
+
onResume,
|
|
1779
|
+
env
|
|
1677
1780
|
);
|
|
1678
1781
|
useEffect4(() => {
|
|
1679
1782
|
import("media-chrome/dist/utils/i18n.js").then(({ setLanguage }) => {
|
|
@@ -1686,6 +1789,12 @@ var MediaCreatorsPlayer = memo(function MediaCreatorsPlayer2({
|
|
|
1686
1789
|
onError == null ? void 0 : onError({ code: "SESSION_ERROR", message: error.message });
|
|
1687
1790
|
}
|
|
1688
1791
|
}, [error, onError]);
|
|
1792
|
+
const onAccessDeniedRef = useRef5(onAccessDenied);
|
|
1793
|
+
onAccessDeniedRef.current = onAccessDenied;
|
|
1794
|
+
useEffect4(() => {
|
|
1795
|
+
var _a3;
|
|
1796
|
+
if (accessDenied) (_a3 = onAccessDeniedRef.current) == null ? void 0 : _a3.call(onAccessDeniedRef, accessDenied);
|
|
1797
|
+
}, [accessDenied]);
|
|
1689
1798
|
useEffect4(() => {
|
|
1690
1799
|
seekDoneRef.current = false;
|
|
1691
1800
|
}, [asset.assetId]);
|
|
@@ -1722,10 +1831,13 @@ var MediaCreatorsPlayer = memo(function MediaCreatorsPlayer2({
|
|
|
1722
1831
|
[initialVolume]
|
|
1723
1832
|
);
|
|
1724
1833
|
const viewerUserId = (_g = (_f = (_e = metadata == null ? void 0 : metadata.viewerUserId) != null ? _e : (auth == null ? void 0 : auth.fanToken) ? decodeJwtSub(auth.fanToken) : null) != null ? _f : getSessionId()) != null ? _g : void 0;
|
|
1834
|
+
if (accessDenied) {
|
|
1835
|
+
return /* @__PURE__ */ jsx2(AccessLock, { state: accessDenied, poster, className });
|
|
1836
|
+
}
|
|
1725
1837
|
if (isLoading || !tokens) {
|
|
1726
|
-
return /* @__PURE__ */
|
|
1838
|
+
return /* @__PURE__ */ jsx2("div", { className, style: { width: "100%", aspectRatio: "16 / 9", background: "#111" } });
|
|
1727
1839
|
}
|
|
1728
|
-
return /* @__PURE__ */
|
|
1840
|
+
return /* @__PURE__ */ jsx2(
|
|
1729
1841
|
MuxPlayer,
|
|
1730
1842
|
{
|
|
1731
1843
|
ref: handlePlayerRef,
|