diff --git a/bun.lock b/bun.lock index 19ce3b54..568e5f61 100644 --- a/bun.lock +++ b/bun.lock @@ -29,6 +29,7 @@ "name": "react-native-video-example", "version": "7.0.0-dev", "dependencies": { + "@react-native-community/slider": "^4.5.6", "react": "18.3.1", "react-native": "^0.77.0", "react-native-nitro-modules": "^0.25.0", @@ -487,6 +488,8 @@ "@react-native-community/cli-types": ["@react-native-community/cli-types@15.0.1", "", { "dependencies": { "joi": "^17.2.1" } }, "sha512-sWiJ62kkGu2mgYni2dsPxOMBzpwTjNsDH1ubY4mqcNEI9Zmzs0vRwwDUEhYqwNGys9+KpBKoZRrT2PAlhO84xA=="], + "@react-native-community/slider": ["@react-native-community/slider@4.5.6", "", {}, "sha512-UhLPFeqx0YfPLrEz8ffT3uqAyXWu6iqFjohNsbp4cOU7hnJwg2RXtDnYHoHMr7MOkZDVdlLMdrSrAuzY6KGqrg=="], + "@react-native/assets-registry": ["@react-native/assets-registry@0.77.2", "", {}, "sha512-AcEhFjndzBWVVhaHaASk36vhA83iDVkQbFYb0D0vATzjuJ67vhhHVLae0+JtHl5jhghotUFDg4Vj/1QbZNDyyQ=="], "@react-native/babel-plugin-codegen": ["@react-native/babel-plugin-codegen@0.77.2", "", { "dependencies": { "@babel/traverse": "^7.25.3", "@react-native/codegen": "0.77.2" } }, "sha512-2PShbsfsa4NZS+Zt0y2tl1AoWza5podKFmPE5qcYjJoN915VoH3BRkiTVlSpYNKmdvs31o1aQuXAMQDTh7DZ/g=="], diff --git a/example/android/gradle.properties b/example/android/gradle.properties index 5e24e3aa..dcfadd8d 100644 --- a/example/android/gradle.properties +++ b/example/android/gradle.properties @@ -34,6 +34,9 @@ reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 # are providing them. newArchEnabled=true +#useExoplayerHls=false +#useExoplayerDash=false + # Use this property to enable or disable the Hermes JS engine. # If set to false, you will be using JSC instead. hermesEnabled=true diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 8c588f07..c6b7a187 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1233,6 +1233,49 @@ PODS: - React-jsiexecutor - React-RCTFBReactNativeSpec - ReactCommon/turbomodule/core + - react-native-slider (4.5.6): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2024.11.18.00) + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - react-native-slider/common (= 4.5.6) + - React-NativeModulesApple + - React-RCTFabric + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - Yoga + - react-native-slider/common (4.5.6): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2024.11.18.00) + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-NativeModulesApple + - React-RCTFabric + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - Yoga - React-nativeconfig (0.77.2) - React-NativeModulesApple (0.77.2): - glog @@ -1587,6 +1630,7 @@ DEPENDENCIES: - React-logger (from `../../node_modules/react-native/ReactCommon/logger`) - React-Mapbuffer (from `../../node_modules/react-native/ReactCommon`) - React-microtasksnativemodule (from `../../node_modules/react-native/ReactCommon/react/nativemodule/microtasks`) + - "react-native-slider (from `../../node_modules/@react-native-community/slider`)" - React-nativeconfig (from `../../node_modules/react-native/ReactCommon`) - React-NativeModulesApple (from `../../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`) - React-perflogger (from `../../node_modules/react-native/ReactCommon/reactperflogger`) @@ -1699,6 +1743,8 @@ EXTERNAL SOURCES: :path: "../../node_modules/react-native/ReactCommon" React-microtasksnativemodule: :path: "../../node_modules/react-native/ReactCommon/react/nativemodule/microtasks" + react-native-slider: + :path: "../../node_modules/@react-native-community/slider" React-nativeconfig: :path: "../../node_modules/react-native/ReactCommon" React-NativeModulesApple: @@ -1800,6 +1846,7 @@ SPEC CHECKSUMS: React-logger: 592d84bed2e04db64c0b3725f9970b437473f3d3 React-Mapbuffer: 595c88852c1dcb1c4faafad88148de8690a70aae React-microtasksnativemodule: b56986b155ae82e9bcb1d1c0ca8726bac52dbb6e + react-native-slider: bb7eb4732940fab78217e1c096bb647d8b0d1cf3 React-nativeconfig: ecf4dc92c40b97e2b3f0c619938f78bfd6507b08 React-NativeModulesApple: f457bbfb30fb3bc41979b1a87b99d292d7340d39 React-perflogger: 1111b5feb064c4cc83df88fb403efda54b387951 diff --git a/example/package.json b/example/package.json index 0fb59f36..29467ba4 100644 --- a/example/package.json +++ b/example/package.json @@ -10,6 +10,7 @@ "start": "react-native start" }, "dependencies": { + "@react-native-community/slider": "^4.5.6", "react": "18.3.1", "react-native": "^0.77.0", "react-native-nitro-modules": "^0.25.0", diff --git a/example/src/App.tsx b/example/src/App.tsx index 9c878691..cbed03b2 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -1,108 +1,356 @@ +import Slider from '@react-native-community/slider'; import * as React from 'react'; import { - Button, - Dimensions, SafeAreaView, StyleSheet, + Switch, Text, + TouchableOpacity, View, } from 'react-native'; import { VideoView, createSource, useVideoPlayer } from 'react-native-video'; +const formatTime = (seconds: number) => { + if (isNaN(seconds)) return '--:--'; + const m = Math.floor(seconds / 60); + const s = Math.floor(seconds % 60); + return `${m}:${s < 10 ? '0' : ''}${s}`; +}; + const VideoDemo = () => { const [show, setShow] = React.useState(false); + const [volume, setVolume] = React.useState(1); + const [muted, setMuted] = React.useState(false); + const [rate, setRate] = React.useState(1); + const [loop, setLoop] = React.useState(false); const player = useVideoPlayer( 'https://www.w3schools.com/html/mov_bbb.mp4', (_player) => { - _player.loop = true; + //_player.loop = loop; } ); + // Sync volume, muted, rate with player + React.useEffect(() => { + if (!show) return; + player.volume = volume; + }, [volume, player, show]); + React.useEffect(() => { + if (!show) return; + player.muted = muted; + }, [muted, player, show]); + React.useEffect(() => { + if (!show) return; + player.rate = rate; + }, [rate, player, show]); + React.useEffect(() => { + if (!show) return; + player.loop = loop; + }, [loop, player, show]); + + // Progress state + const [progress, setProgress] = React.useState(0); + React.useEffect(() => { + const interval = setInterval(() => { + setProgress( + show ? (isNaN(player.currentTime) ? 0 : player.currentTime) : 0 + ); + }, 300); + return () => clearInterval(interval); + }, [player, show]); + + // Handlers + const handleSeek = (val: number) => { + player.seekTo(val); + setProgress(val); + }; + return ( - + {show ? ( - + ) : ( - VideoView is hidden! + Video Hidden )} -