@nikelroot/video-player 0.2.4 → 0.2.6

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 CHANGED
@@ -37,7 +37,30 @@ export function Example() {
37
37
  }
38
38
  ```
39
39
 
40
- When `active` is `true`, pressing `F` toggles fullscreen. When `active` is `false`, the player releases native media loading so inactive MP4 players do not keep network requests open.
40
+ When `active` is `true`, pressing `F` toggles fullscreen.
41
+
42
+ ## Multiple MP4 players
43
+
44
+ Use `active` when rendering several video players on the same page and only one of them should be ready for playback.
45
+
46
+ ```tsx
47
+ <VideoPlayer
48
+ videoSrc="https://cdn.example.com/video-a.mp4"
49
+ sourceType="native"
50
+ active={isSelected}
51
+ preload="metadata"
52
+ />
53
+ ```
54
+
55
+ This solves a switching problem where previous MP4 players can keep large browser media requests open after another player starts. In Chrome DevTools this often appears as new video requests staying in a long `Pending` state, even when CDN, disk, and network throughput are healthy.
56
+
57
+ For native MP4 sources:
58
+
59
+ - `active={true}` allows playback and fullscreen.
60
+ - `active={false}` releases playback loading so inactive players do not keep competing media requests open.
61
+ - `preload="metadata"` still loads metadata for inactive native videos, so duration and basic media information can be available without starting playback loading.
62
+
63
+ By default `exclusivePlayback` is enabled. When a player starts playback, the previous active native MP4 player is paused and its media source is released, freeing the browser media request before the next video loads.
41
64
 
42
65
  For public CDN-hosted videos, prefer non-credentialed requests unless the CDN is explicitly configured for cookies:
43
66
 
@@ -56,4 +79,3 @@ Build before publishing:
56
79
  ```bash
57
80
  npm run build
58
81
  ```
59
- # video-player
package/dist/index.cjs CHANGED
@@ -781,6 +781,9 @@ var isLikelyHlsSource = (src) => {
781
781
  return /\.m3u8($|[?#])/i.test(src);
782
782
  }
783
783
  };
784
+ var getSourceLoadMode = (sourceType, type, src) => {
785
+ return sourceType === "hls" || sourceType !== "native" && type !== "video" && isLikelyHlsSource(src) ? "hls" : "native";
786
+ };
784
787
  var assignRef = (ref, value) => {
785
788
  if (!ref) return;
786
789
  if (typeof ref === "function") {
@@ -1275,15 +1278,20 @@ var VideoPlayerBase = (props, ref) => {
1275
1278
  videoSrc
1276
1279
  ]
1277
1280
  );
1278
- const loadVideoNative = (0, import_react3.useCallback)((loadId = sourceLoadId.current) => {
1279
- if (loadId !== sourceLoadId.current) return;
1280
- const video = videoRef.current;
1281
- if (!video) return;
1282
- sourceLoadMode.current = "native";
1283
- video.src = videoSrc;
1284
- video.currentTime = initialTime;
1285
- if (autoPlay) void playAction();
1286
- }, [autoPlay, initialTime, playAction, videoSrc]);
1281
+ const loadVideoNative = (0, import_react3.useCallback)(
1282
+ (loadId = sourceLoadId.current, options) => {
1283
+ if (loadId !== sourceLoadId.current) return;
1284
+ const video = videoRef.current;
1285
+ if (!video) return;
1286
+ sourceLoadMode.current = "native";
1287
+ video.src = videoSrc;
1288
+ if (!(options == null ? void 0 : options.metadataOnly)) {
1289
+ video.currentTime = initialTime;
1290
+ if (autoPlay) void playAction();
1291
+ }
1292
+ },
1293
+ [autoPlay, initialTime, playAction, videoSrc]
1294
+ );
1287
1295
  const loadVideoHls = (0, import_react3.useCallback)(async (loadId = sourceLoadId.current) => {
1288
1296
  const video = videoRef.current;
1289
1297
  const canNativeHls = !!(video == null ? void 0 : video.canPlayType) && video.canPlayType("application/vnd.apple.mpegurl") !== "";
@@ -1438,9 +1446,14 @@ var VideoPlayerBase = (props, ref) => {
1438
1446
  liveStabilityMode.current = false;
1439
1447
  liveStallEvents.current = [];
1440
1448
  resetMediaForSourceChange();
1441
- if (active === false) return;
1442
- const nextSourceLoadMode = sourceType === "hls" || sourceType !== "native" && type !== "video" && isLikelyHlsSource(videoSrc) ? "hls" : "native";
1449
+ const nextSourceLoadMode = getSourceLoadMode(sourceType, type, videoSrc);
1443
1450
  sourceLoadMode.current = nextSourceLoadMode;
1451
+ if (active === false) {
1452
+ if (nextSourceLoadMode === "native" && preload === "metadata") {
1453
+ loadVideoNative(loadId, { metadataOnly: true });
1454
+ }
1455
+ return;
1456
+ }
1444
1457
  if (nextSourceLoadMode === "hls") {
1445
1458
  if (sourceType === "hls") void loadVideo(initialTime, loadId);
1446
1459
  else void loadVideoHls(loadId);
package/dist/index.js CHANGED
@@ -752,6 +752,9 @@ var isLikelyHlsSource = (src) => {
752
752
  return /\.m3u8($|[?#])/i.test(src);
753
753
  }
754
754
  };
755
+ var getSourceLoadMode = (sourceType, type, src) => {
756
+ return sourceType === "hls" || sourceType !== "native" && type !== "video" && isLikelyHlsSource(src) ? "hls" : "native";
757
+ };
755
758
  var assignRef = (ref, value) => {
756
759
  if (!ref) return;
757
760
  if (typeof ref === "function") {
@@ -1246,15 +1249,20 @@ var VideoPlayerBase = (props, ref) => {
1246
1249
  videoSrc
1247
1250
  ]
1248
1251
  );
1249
- const loadVideoNative = useCallback((loadId = sourceLoadId.current) => {
1250
- if (loadId !== sourceLoadId.current) return;
1251
- const video = videoRef.current;
1252
- if (!video) return;
1253
- sourceLoadMode.current = "native";
1254
- video.src = videoSrc;
1255
- video.currentTime = initialTime;
1256
- if (autoPlay) void playAction();
1257
- }, [autoPlay, initialTime, playAction, videoSrc]);
1252
+ const loadVideoNative = useCallback(
1253
+ (loadId = sourceLoadId.current, options) => {
1254
+ if (loadId !== sourceLoadId.current) return;
1255
+ const video = videoRef.current;
1256
+ if (!video) return;
1257
+ sourceLoadMode.current = "native";
1258
+ video.src = videoSrc;
1259
+ if (!(options == null ? void 0 : options.metadataOnly)) {
1260
+ video.currentTime = initialTime;
1261
+ if (autoPlay) void playAction();
1262
+ }
1263
+ },
1264
+ [autoPlay, initialTime, playAction, videoSrc]
1265
+ );
1258
1266
  const loadVideoHls = useCallback(async (loadId = sourceLoadId.current) => {
1259
1267
  const video = videoRef.current;
1260
1268
  const canNativeHls = !!(video == null ? void 0 : video.canPlayType) && video.canPlayType("application/vnd.apple.mpegurl") !== "";
@@ -1409,9 +1417,14 @@ var VideoPlayerBase = (props, ref) => {
1409
1417
  liveStabilityMode.current = false;
1410
1418
  liveStallEvents.current = [];
1411
1419
  resetMediaForSourceChange();
1412
- if (active === false) return;
1413
- const nextSourceLoadMode = sourceType === "hls" || sourceType !== "native" && type !== "video" && isLikelyHlsSource(videoSrc) ? "hls" : "native";
1420
+ const nextSourceLoadMode = getSourceLoadMode(sourceType, type, videoSrc);
1414
1421
  sourceLoadMode.current = nextSourceLoadMode;
1422
+ if (active === false) {
1423
+ if (nextSourceLoadMode === "native" && preload === "metadata") {
1424
+ loadVideoNative(loadId, { metadataOnly: true });
1425
+ }
1426
+ return;
1427
+ }
1415
1428
  if (nextSourceLoadMode === "hls") {
1416
1429
  if (sourceType === "hls") void loadVideo(initialTime, loadId);
1417
1430
  else void loadVideoHls(loadId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nikelroot/video-player",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "Standalone React video player with HLS support.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",