diff --git a/android/src/main/java/com/brentvatne/common/react/VideoEventEmitter.kt b/android/src/main/java/com/brentvatne/common/react/VideoEventEmitter.kt
index 161b79be..acf21832 100644
--- a/android/src/main/java/com/brentvatne/common/react/VideoEventEmitter.kt
+++ b/android/src/main/java/com/brentvatne/common/react/VideoEventEmitter.kt
@@ -73,7 +73,7 @@ class VideoEventEmitter {
lateinit var onVideoBandwidthUpdate: (bitRateEstimate: Long, height: Int, width: Int, trackId: String?) -> Unit
lateinit var onVideoPlaybackStateChanged: (isPlaying: Boolean, isSeeking: Boolean) -> Unit
lateinit var onVideoSeek: (currentPosition: Long, seekTime: Long) -> Unit
- lateinit var onVideoSeekComplete: (currentPosition: Long) -> Unit
+ lateinit var onVideoSeekComplete: (currentPosition: Long, seekTime: Long) -> Unit
lateinit var onVideoEnd: () -> Unit
lateinit var onVideoFullscreenPlayerWillPresent: () -> Unit
lateinit var onVideoFullscreenPlayerDidPresent: () -> Unit
@@ -202,9 +202,11 @@ class VideoEventEmitter {
putDouble("seekTime", seekTime / 1000.0)
}
}
- onVideoSeekComplete = { currentPosition ->
+ onVideoSeekComplete = { currentPosition, seekTime ->
event.dispatch(EventTypes.EVENT_SEEK_COMPLETE) {
putDouble("currentTime", currentPosition / 1000.0)
+ putDouble("seekTime", seekTime / 1000.0)
+ putInt("target", view.id)
}
}
onVideoEnd = {
diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java
index cd7963e5..205b4d94 100644
--- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java
+++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java
@@ -319,7 +319,10 @@ public class ReactExoplayerView extends FrameLayout implements
private void handleSeekCompletion() {
if (player != null && player.getPlaybackState() == Player.STATE_READY && isSeekInProgress) {
Log.d("ReactExoplayerView", "handleSeekCompletion: currentPosition=" + player.getCurrentPosition());
- eventEmitter.onVideoSeekComplete.invoke(player.getCurrentPosition());
+ if (isSeeking) {
+ eventEmitter.onVideoSeek.invoke(player.getCurrentPosition(), seekPosition);
+ }
+ eventEmitter.onVideoSeekComplete.invoke(player.getCurrentPosition(), seekPosition);
isSeeking = false;
seekPosition = -1;
isSeekInProgress = false;
@@ -1847,6 +1850,7 @@ public class ReactExoplayerView extends FrameLayout implements
// We need to update the selected track to make sure that it still matches user selection if track list has changed in this period
setSelectedTrack(C.TRACK_TYPE_VIDEO, videoTrackType, videoTrackValue);
}
+ handleSeekCompletion();
}
if (playerNeedsSource) {
diff --git a/docs/pages/component/props.mdx b/docs/pages/component/props.mdx
index aac1b92e..e6f60d7e 100644
--- a/docs/pages/component/props.mdx
+++ b/docs/pages/component/props.mdx
@@ -801,8 +801,6 @@ The documentation for this prop is incomplete and will be updated as each option
-
-
Example:
Pass the asset directly (deprecated):
diff --git a/docs/pages/installation.md b/docs/pages/installation.md
index a0fb83f5..3873ec64 100644
--- a/docs/pages/installation.md
+++ b/docs/pages/installation.md
@@ -22,6 +22,7 @@ Then follow the instructions for your platform to link `react-native-video` into
## iOS
### Standard Method
+
Run `pod install` in the `ios` directory of your project.
⚠️ From version `6.0.0`, the minimum iOS version required is `13.0`. For more information, see the [updating section](updating.md).
@@ -100,6 +101,7 @@ You can enable or disable the following features by setting the corresponding va
Each enabled feature increases the APK size, so only enable what you need.
By default, the enabled features are:
+
- `useExoplayerSmoothStreaming`
- `useExoplayerDash`
- `useExoplayerHls`
@@ -222,17 +224,10 @@ Run `pod install` in the `visionos` directory of your project.
## Web
-No additional setup is required. Everything should work out of the box.
+No additional setup is required.
-However, only basic video support is available. HLS, Dash, ads, and DRM are not currently supported.
-
-
-
-
-web
-
-Nothing to do, everything should work out of the box.
-
-Note that only basic video support is present, no hls/dash or ads/drm for now.
+The Railbird fork uses Shaka Player for browser playback, including HLS and DASH
+sources. The native ads and DRM props are not currently integrated with the web
+player.
diff --git a/src/Video.web.tsx b/src/Video.web.tsx
index f7c6e90e..51512026 100644
--- a/src/Video.web.tsx
+++ b/src/Video.web.tsx
@@ -66,39 +66,25 @@ class ActionQueue {
}
}
-function shallowEqual(obj1: unknown, obj2: unknown): boolean {
- // If both are strictly equal (covers primitive types and identical object references)
- if (obj1 === obj2) {
+function isDeepEqual(first: T, second: T): boolean {
+ if (first === second) {
return true;
}
- // If one is not an object (meaning it's a primitive), they must be strictly equal
- if (
- typeof obj1 !== 'object' ||
- typeof obj2 !== 'object' ||
- obj1 === null ||
- obj2 === null
- ) {
+ const bothAreObjects =
+ first && second && typeof first === 'object' && typeof second === 'object';
+ if (!bothAreObjects) {
return false;
}
- const first = obj1 as Record;
- const second = obj2 as Record;
-
- // Get the keys of both objects
- const keys1 = Object.keys(first);
- const keys2 = Object.keys(second);
-
- // If the number of keys is different, the objects are not equal
- if (keys1.length !== keys2.length) {
- return false;
- }
-
- // Check that all keys and their corresponding values are the same
- return keys1.every((key) => {
- // If the value is an object, we fall back to reference equality (shallow comparison)
- return first[key] === second[key];
- });
+ const firstObject = first as Record;
+ const secondObject = second as Record;
+ return (
+ Object.keys(firstObject).length === Object.keys(secondObject).length &&
+ Object.entries(firstObject).every(([key, value]) =>
+ isDeepEqual(value, secondObject[key]),
+ )
+ );
}
const Video = forwardRef(
@@ -136,10 +122,17 @@ const Video = forwardRef(
const shakaPlayerRef = useRef(null);
const [activeSource, setActiveSource] = useState(source);
const sourceProp = useRef(source);
- const [loadedSource, setLoadedSource] = useState