@nikelroot/video-player 0.1.10 → 0.1.12

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/index.cjs CHANGED
@@ -854,6 +854,7 @@ var VideoPlayerBase = (props, ref) => {
854
854
  const liveStabilityMode = (0, import_react3.useRef)(false);
855
855
  const liveStallEvents = (0, import_react3.useRef)([]);
856
856
  const controlTime = (0, import_react3.useRef)(null);
857
+ const sourceLoadId = (0, import_react3.useRef)(0);
857
858
  const [playingState, setPlayingState] = (0, import_react3.useState)(!!defaultPlaying);
858
859
  const [mutedState, setMutedState] = (0, import_react3.useState)(!!defaultMuted);
859
860
  const [durationState, setDurationState] = (0, import_react3.useState)(0);
@@ -871,6 +872,8 @@ var VideoPlayerBase = (props, ref) => {
871
872
  const fullscreenAllowed = active != null ? active : true;
872
873
  const onTimeChangeRef = (0, import_react3.useRef)(onTimeChange);
873
874
  const onDurationChangeRef = (0, import_react3.useRef)(onDurationChange);
875
+ onTimeChangeRef.current = onTimeChange;
876
+ onDurationChangeRef.current = onDurationChange;
874
877
  const setTimeD = (0, import_react3.useRef)(
875
878
  createThrottledNumberFn((value) => {
876
879
  const v = videoRef.current;
@@ -892,6 +895,18 @@ var VideoPlayerBase = (props, ref) => {
892
895
  controlTime.current = null;
893
896
  }
894
897
  }, []);
898
+ const resetMediaForSourceChange = (0, import_react3.useCallback)(() => {
899
+ clearTimers();
900
+ if (hlsRef.current) {
901
+ hlsRef.current.destroy();
902
+ hlsRef.current = null;
903
+ }
904
+ const video = videoRef.current;
905
+ if (!video) return;
906
+ video.pause();
907
+ video.removeAttribute("src");
908
+ video.load();
909
+ }, [clearTimers]);
895
910
  const setNextPlaying = (0, import_react3.useCallback)(
896
911
  (value) => {
897
912
  if (playingProp === void 0) setPlayingState(value);
@@ -934,12 +949,6 @@ var VideoPlayerBase = (props, ref) => {
934
949
  },
935
950
  [onActiveChange]
936
951
  );
937
- (0, import_react3.useEffect)(() => {
938
- onTimeChangeRef.current = onTimeChange;
939
- }, [onTimeChange]);
940
- (0, import_react3.useEffect)(() => {
941
- onDurationChangeRef.current = onDurationChange;
942
- }, [onDurationChange]);
943
952
  const onTime = (0, import_react3.useCallback)(() => {
944
953
  var _a;
945
954
  const el = videoRef.current;
@@ -1088,7 +1097,7 @@ var VideoPlayerBase = (props, ref) => {
1088
1097
  );
1089
1098
  }, [hlsConfig, hlsCredentials, live, liveHlsConfig, vodHlsConfig]);
1090
1099
  const loadVideo = (0, import_react3.useCallback)(
1091
- async (startAt = initialTime) => {
1100
+ async (startAt = initialTime, loadId = sourceLoadId.current) => {
1092
1101
  const startVideoRef = videoRef.current;
1093
1102
  if (!startVideoRef) return;
1094
1103
  let HlsCtor;
@@ -1098,13 +1107,16 @@ var VideoPlayerBase = (props, ref) => {
1098
1107
  reportError(error, { type: "hls-loader", src: videoSrc }, messages.streamLoadFailed);
1099
1108
  return;
1100
1109
  }
1110
+ if (loadId !== sourceLoadId.current) return;
1101
1111
  if (!videoRef.current || videoRef.current !== startVideoRef) return;
1102
1112
  const video = videoRef.current;
1103
1113
  if (!video) return;
1104
1114
  const h = new HlsCtor(resolvedHlsConfig());
1105
1115
  hlsRef.current = h;
1116
+ const isStaleLoad = () => loadId !== sourceLoadId.current || hlsRef.current !== h || videoRef.current !== video;
1106
1117
  h.on(HlsCtor.Events.ERROR, (_evt, data) => {
1107
1118
  var _a, _b;
1119
+ if (isStaleLoad()) return;
1108
1120
  const { type: errorType, details, fatal } = data;
1109
1121
  if (details === HlsCtor.ErrorDetails.BUFFER_APPEND_ERROR || details === "bufferAppendingError") return;
1110
1122
  if (!fatal) {
@@ -1125,7 +1137,7 @@ var VideoPlayerBase = (props, ref) => {
1125
1137
  hlsRef.current.destroy();
1126
1138
  hlsRef.current = null;
1127
1139
  }
1128
- void loadVideo(resumeTime2);
1140
+ void loadVideo(resumeTime2, loadId);
1129
1141
  }, 250);
1130
1142
  }
1131
1143
  return;
@@ -1145,7 +1157,7 @@ var VideoPlayerBase = (props, ref) => {
1145
1157
  hlsRef.current.destroy();
1146
1158
  hlsRef.current = null;
1147
1159
  }
1148
- void loadVideo(resumeTime);
1160
+ void loadVideo(resumeTime, loadId);
1149
1161
  }, backoffMs);
1150
1162
  return;
1151
1163
  }
@@ -1189,12 +1201,14 @@ var VideoPlayerBase = (props, ref) => {
1189
1201
  hlsRef.current.destroy();
1190
1202
  hlsRef.current = null;
1191
1203
  }
1192
- void loadVideo(resumeTime);
1204
+ void loadVideo(resumeTime, loadId);
1193
1205
  });
1194
1206
  h.on(HlsCtor.Events.MEDIA_ATTACHED, () => {
1207
+ if (isStaleLoad()) return;
1195
1208
  h.loadSource(videoSrc);
1196
1209
  });
1197
1210
  h.on(HlsCtor.Events.MANIFEST_PARSED, () => {
1211
+ if (isStaleLoad()) return;
1198
1212
  fatalReloadCount.current = 0;
1199
1213
  netRetryCount.current = 0;
1200
1214
  mediaRecoverCount.current = 0;
@@ -1224,14 +1238,15 @@ var VideoPlayerBase = (props, ref) => {
1224
1238
  videoSrc
1225
1239
  ]
1226
1240
  );
1227
- const loadVideoNative = (0, import_react3.useCallback)(() => {
1241
+ const loadVideoNative = (0, import_react3.useCallback)((loadId = sourceLoadId.current) => {
1242
+ if (loadId !== sourceLoadId.current) return;
1228
1243
  const video = videoRef.current;
1229
1244
  if (!video) return;
1230
1245
  video.src = videoSrc;
1231
1246
  video.currentTime = initialTime;
1232
1247
  if (autoPlay) void playAction();
1233
1248
  }, [autoPlay, initialTime, playAction, videoSrc]);
1234
- const loadVideoHls = (0, import_react3.useCallback)(async () => {
1249
+ const loadVideoHls = (0, import_react3.useCallback)(async (loadId = sourceLoadId.current) => {
1235
1250
  const video = videoRef.current;
1236
1251
  const canNativeHls = !!(video == null ? void 0 : video.canPlayType) && video.canPlayType("application/vnd.apple.mpegurl") !== "";
1237
1252
  let HlsCtor;
@@ -1241,13 +1256,14 @@ var VideoPlayerBase = (props, ref) => {
1241
1256
  reportError(error, { type: "hls-loader", src: videoSrc }, messages.streamLoadFailed);
1242
1257
  return;
1243
1258
  }
1259
+ if (loadId !== sourceLoadId.current) return;
1244
1260
  if (!videoRef.current || videoRef.current !== video) return;
1245
1261
  if (HlsCtor.isSupported()) {
1246
- void loadVideo(initialTime);
1262
+ void loadVideo(initialTime, loadId);
1247
1263
  return;
1248
1264
  }
1249
1265
  if (canNativeHls) {
1250
- loadVideoNative();
1266
+ loadVideoNative(loadId);
1251
1267
  return;
1252
1268
  }
1253
1269
  reportError(null, { type: "hls", src: videoSrc, reason: "HLS is not supported in this browser" }, messages.unsupported);
@@ -1372,34 +1388,30 @@ var VideoPlayerBase = (props, ref) => {
1372
1388
  }, [currentTimeProp, duration]);
1373
1389
  (0, import_react3.useEffect)(() => {
1374
1390
  if (!videoRef.current) return;
1391
+ const loadId = sourceLoadId.current + 1;
1392
+ sourceLoadId.current = loadId;
1375
1393
  clearErrorState();
1376
1394
  fatalReloadCount.current = 0;
1377
1395
  netRetryCount.current = 0;
1378
1396
  mediaRecoverCount.current = 0;
1379
1397
  liveStabilityMode.current = false;
1380
1398
  liveStallEvents.current = [];
1381
- if (hlsRef.current) {
1382
- hlsRef.current.destroy();
1383
- hlsRef.current = null;
1384
- }
1385
- if (sourceType === "native" || type === "video") loadVideoNative();
1386
- else if (sourceType === "hls") void loadVideo(initialTime);
1387
- else if (isLikelyHlsSource(videoSrc)) void loadVideoHls();
1388
- else loadVideoNative();
1399
+ resetMediaForSourceChange();
1400
+ if (sourceType === "native" || type === "video") loadVideoNative(loadId);
1401
+ else if (sourceType === "hls") void loadVideo(initialTime, loadId);
1402
+ else if (isLikelyHlsSource(videoSrc)) void loadVideoHls(loadId);
1403
+ else loadVideoNative(loadId);
1389
1404
  return () => {
1390
- clearTimers();
1391
- if (hlsRef.current) {
1392
- hlsRef.current.destroy();
1393
- hlsRef.current = null;
1394
- }
1405
+ sourceLoadId.current += 1;
1406
+ resetMediaForSourceChange();
1395
1407
  };
1396
1408
  }, [
1397
1409
  clearErrorState,
1398
- clearTimers,
1399
1410
  loadVideo,
1400
1411
  loadVideoHls,
1401
1412
  loadVideoNative,
1402
1413
  initialTime,
1414
+ resetMediaForSourceChange,
1403
1415
  reloadKey,
1404
1416
  reloadToken,
1405
1417
  sourceType,
package/dist/index.js CHANGED
@@ -825,6 +825,7 @@ var VideoPlayerBase = (props, ref) => {
825
825
  const liveStabilityMode = useRef2(false);
826
826
  const liveStallEvents = useRef2([]);
827
827
  const controlTime = useRef2(null);
828
+ const sourceLoadId = useRef2(0);
828
829
  const [playingState, setPlayingState] = useState(!!defaultPlaying);
829
830
  const [mutedState, setMutedState] = useState(!!defaultMuted);
830
831
  const [durationState, setDurationState] = useState(0);
@@ -842,6 +843,8 @@ var VideoPlayerBase = (props, ref) => {
842
843
  const fullscreenAllowed = active != null ? active : true;
843
844
  const onTimeChangeRef = useRef2(onTimeChange);
844
845
  const onDurationChangeRef = useRef2(onDurationChange);
846
+ onTimeChangeRef.current = onTimeChange;
847
+ onDurationChangeRef.current = onDurationChange;
845
848
  const setTimeD = useRef2(
846
849
  createThrottledNumberFn((value) => {
847
850
  const v = videoRef.current;
@@ -863,6 +866,18 @@ var VideoPlayerBase = (props, ref) => {
863
866
  controlTime.current = null;
864
867
  }
865
868
  }, []);
869
+ const resetMediaForSourceChange = useCallback(() => {
870
+ clearTimers();
871
+ if (hlsRef.current) {
872
+ hlsRef.current.destroy();
873
+ hlsRef.current = null;
874
+ }
875
+ const video = videoRef.current;
876
+ if (!video) return;
877
+ video.pause();
878
+ video.removeAttribute("src");
879
+ video.load();
880
+ }, [clearTimers]);
866
881
  const setNextPlaying = useCallback(
867
882
  (value) => {
868
883
  if (playingProp === void 0) setPlayingState(value);
@@ -905,12 +920,6 @@ var VideoPlayerBase = (props, ref) => {
905
920
  },
906
921
  [onActiveChange]
907
922
  );
908
- useEffect(() => {
909
- onTimeChangeRef.current = onTimeChange;
910
- }, [onTimeChange]);
911
- useEffect(() => {
912
- onDurationChangeRef.current = onDurationChange;
913
- }, [onDurationChange]);
914
923
  const onTime = useCallback(() => {
915
924
  var _a;
916
925
  const el = videoRef.current;
@@ -1059,7 +1068,7 @@ var VideoPlayerBase = (props, ref) => {
1059
1068
  );
1060
1069
  }, [hlsConfig, hlsCredentials, live, liveHlsConfig, vodHlsConfig]);
1061
1070
  const loadVideo = useCallback(
1062
- async (startAt = initialTime) => {
1071
+ async (startAt = initialTime, loadId = sourceLoadId.current) => {
1063
1072
  const startVideoRef = videoRef.current;
1064
1073
  if (!startVideoRef) return;
1065
1074
  let HlsCtor;
@@ -1069,13 +1078,16 @@ var VideoPlayerBase = (props, ref) => {
1069
1078
  reportError(error, { type: "hls-loader", src: videoSrc }, messages.streamLoadFailed);
1070
1079
  return;
1071
1080
  }
1081
+ if (loadId !== sourceLoadId.current) return;
1072
1082
  if (!videoRef.current || videoRef.current !== startVideoRef) return;
1073
1083
  const video = videoRef.current;
1074
1084
  if (!video) return;
1075
1085
  const h = new HlsCtor(resolvedHlsConfig());
1076
1086
  hlsRef.current = h;
1087
+ const isStaleLoad = () => loadId !== sourceLoadId.current || hlsRef.current !== h || videoRef.current !== video;
1077
1088
  h.on(HlsCtor.Events.ERROR, (_evt, data) => {
1078
1089
  var _a, _b;
1090
+ if (isStaleLoad()) return;
1079
1091
  const { type: errorType, details, fatal } = data;
1080
1092
  if (details === HlsCtor.ErrorDetails.BUFFER_APPEND_ERROR || details === "bufferAppendingError") return;
1081
1093
  if (!fatal) {
@@ -1096,7 +1108,7 @@ var VideoPlayerBase = (props, ref) => {
1096
1108
  hlsRef.current.destroy();
1097
1109
  hlsRef.current = null;
1098
1110
  }
1099
- void loadVideo(resumeTime2);
1111
+ void loadVideo(resumeTime2, loadId);
1100
1112
  }, 250);
1101
1113
  }
1102
1114
  return;
@@ -1116,7 +1128,7 @@ var VideoPlayerBase = (props, ref) => {
1116
1128
  hlsRef.current.destroy();
1117
1129
  hlsRef.current = null;
1118
1130
  }
1119
- void loadVideo(resumeTime);
1131
+ void loadVideo(resumeTime, loadId);
1120
1132
  }, backoffMs);
1121
1133
  return;
1122
1134
  }
@@ -1160,12 +1172,14 @@ var VideoPlayerBase = (props, ref) => {
1160
1172
  hlsRef.current.destroy();
1161
1173
  hlsRef.current = null;
1162
1174
  }
1163
- void loadVideo(resumeTime);
1175
+ void loadVideo(resumeTime, loadId);
1164
1176
  });
1165
1177
  h.on(HlsCtor.Events.MEDIA_ATTACHED, () => {
1178
+ if (isStaleLoad()) return;
1166
1179
  h.loadSource(videoSrc);
1167
1180
  });
1168
1181
  h.on(HlsCtor.Events.MANIFEST_PARSED, () => {
1182
+ if (isStaleLoad()) return;
1169
1183
  fatalReloadCount.current = 0;
1170
1184
  netRetryCount.current = 0;
1171
1185
  mediaRecoverCount.current = 0;
@@ -1195,14 +1209,15 @@ var VideoPlayerBase = (props, ref) => {
1195
1209
  videoSrc
1196
1210
  ]
1197
1211
  );
1198
- const loadVideoNative = useCallback(() => {
1212
+ const loadVideoNative = useCallback((loadId = sourceLoadId.current) => {
1213
+ if (loadId !== sourceLoadId.current) return;
1199
1214
  const video = videoRef.current;
1200
1215
  if (!video) return;
1201
1216
  video.src = videoSrc;
1202
1217
  video.currentTime = initialTime;
1203
1218
  if (autoPlay) void playAction();
1204
1219
  }, [autoPlay, initialTime, playAction, videoSrc]);
1205
- const loadVideoHls = useCallback(async () => {
1220
+ const loadVideoHls = useCallback(async (loadId = sourceLoadId.current) => {
1206
1221
  const video = videoRef.current;
1207
1222
  const canNativeHls = !!(video == null ? void 0 : video.canPlayType) && video.canPlayType("application/vnd.apple.mpegurl") !== "";
1208
1223
  let HlsCtor;
@@ -1212,13 +1227,14 @@ var VideoPlayerBase = (props, ref) => {
1212
1227
  reportError(error, { type: "hls-loader", src: videoSrc }, messages.streamLoadFailed);
1213
1228
  return;
1214
1229
  }
1230
+ if (loadId !== sourceLoadId.current) return;
1215
1231
  if (!videoRef.current || videoRef.current !== video) return;
1216
1232
  if (HlsCtor.isSupported()) {
1217
- void loadVideo(initialTime);
1233
+ void loadVideo(initialTime, loadId);
1218
1234
  return;
1219
1235
  }
1220
1236
  if (canNativeHls) {
1221
- loadVideoNative();
1237
+ loadVideoNative(loadId);
1222
1238
  return;
1223
1239
  }
1224
1240
  reportError(null, { type: "hls", src: videoSrc, reason: "HLS is not supported in this browser" }, messages.unsupported);
@@ -1343,34 +1359,30 @@ var VideoPlayerBase = (props, ref) => {
1343
1359
  }, [currentTimeProp, duration]);
1344
1360
  useEffect(() => {
1345
1361
  if (!videoRef.current) return;
1362
+ const loadId = sourceLoadId.current + 1;
1363
+ sourceLoadId.current = loadId;
1346
1364
  clearErrorState();
1347
1365
  fatalReloadCount.current = 0;
1348
1366
  netRetryCount.current = 0;
1349
1367
  mediaRecoverCount.current = 0;
1350
1368
  liveStabilityMode.current = false;
1351
1369
  liveStallEvents.current = [];
1352
- if (hlsRef.current) {
1353
- hlsRef.current.destroy();
1354
- hlsRef.current = null;
1355
- }
1356
- if (sourceType === "native" || type === "video") loadVideoNative();
1357
- else if (sourceType === "hls") void loadVideo(initialTime);
1358
- else if (isLikelyHlsSource(videoSrc)) void loadVideoHls();
1359
- else loadVideoNative();
1370
+ resetMediaForSourceChange();
1371
+ if (sourceType === "native" || type === "video") loadVideoNative(loadId);
1372
+ else if (sourceType === "hls") void loadVideo(initialTime, loadId);
1373
+ else if (isLikelyHlsSource(videoSrc)) void loadVideoHls(loadId);
1374
+ else loadVideoNative(loadId);
1360
1375
  return () => {
1361
- clearTimers();
1362
- if (hlsRef.current) {
1363
- hlsRef.current.destroy();
1364
- hlsRef.current = null;
1365
- }
1376
+ sourceLoadId.current += 1;
1377
+ resetMediaForSourceChange();
1366
1378
  };
1367
1379
  }, [
1368
1380
  clearErrorState,
1369
- clearTimers,
1370
1381
  loadVideo,
1371
1382
  loadVideoHls,
1372
1383
  loadVideoNative,
1373
1384
  initialTime,
1385
+ resetMediaForSourceChange,
1374
1386
  reloadKey,
1375
1387
  reloadToken,
1376
1388
  sourceType,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nikelroot/video-player",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "Standalone React video player with HLS support.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",