UNPKG

react-native-video-player

Version:
214 lines (212 loc) 7.75 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RenderVideo = void 0; var _react = require("react"); var _reactNativeVideo = _interopRequireDefault(require("react-native-video")); var _Controls = require("./controls/Controls.js"); var _reactNative = require("react-native"); var _jsxRuntime = require("react/jsx-runtime"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const RenderVideo = exports.RenderVideo = /*#__PURE__*/(0, _react.memo)(/*#__PURE__*/(0, _react.forwardRef)((props, ref) => { const { animationDuration = 100, autoplay = false, controlsTimeout = 2000, customStyles = {}, defaultMuted, disableControlsAutoHide, disableFullscreen, disableSeek, fullScreenOnLongPress, hideControlsOnStart = false, muted, onEnd, onHideControls, onLoad, onMutePress, onPlayPress, onPlaybackStateChanged, onProgress, onShowControls, pauseOnPress, paused, repeat = false, resizeMode = 'contain', showDuration = false, source, style, sizeStyle } = props; const [isPlaying, setIsPlaying] = (0, _react.useState)(autoplay); const [isMuted, setIsMuted] = (0, _react.useState)(defaultMuted ?? false); const [isControlsVisible, setIsControlsVisible] = (0, _react.useState)(false); const [duration, setDuration] = (0, _react.useState)(0); const videoRef = (0, _react.useRef)(null); // ref to keeps progress to avoid re-rendering const progressRef = (0, _react.useRef)(0); // ref to pass progress to controls (in ref to avoid re-rendering) and to pass when controls wrapper should animate const controlsRef = (0, _react.useRef)(null); // ref to keep timeout id to clear it on unmount const controlsTimeoutRef = (0, _react.useRef)(null); const setProgress = (0, _react.useCallback)(progress => { if (!isFinite(progress)) return; progressRef.current = progress; controlsRef.current?.onProgress(progress); }, []); (0, _react.useImperativeHandle)(ref, () => ({ ...videoRef.current, resume: () => { setIsPlaying(true); videoRef.current?.resume(); }, pause: () => { setIsPlaying(false); videoRef.current?.pause(); }, stop: () => { setProgress(0); videoRef.current?.dismissFullscreenPlayer(); }, onStart: () => { setIsPlaying(true); setProgress(progressRef.current >= 1 ? 0 : progressRef.current); hideControlsOnStart ? _hideControls() : _showControls(); } })); const _hideControls = (0, _react.useCallback)(() => { if (controlsTimeoutRef.current) clearTimeout(controlsTimeoutRef.current); controlsTimeoutRef.current = setTimeout(() => { if (onHideControls) onHideControls(); if (disableControlsAutoHide) return; controlsRef.current?.runControlsAnimation(0.1, () => { setIsControlsVisible(false); setProgress(progressRef.current); }); }, controlsTimeout); }, [controlsTimeout, onHideControls, disableControlsAutoHide, setProgress]); const _showControls = (0, _react.useCallback)(() => { if (onShowControls && !isControlsVisible) onShowControls(); setIsControlsVisible(true); _hideControls(); // force re-renders to make sure controls are mounted. ControlsRef is then available and setProgress is called correctly (It fixes the moment when controls are hidden during paused video. After clicking on the screen, controls are shown, but the current duration shows 00) setTimeout(() => { setProgress(progressRef.current); controlsRef.current?.runControlsAnimation(1); }, 0); }, [onShowControls, isControlsVisible, _hideControls, setProgress]); (0, _react.useEffect)(() => { if (autoplay) _hideControls(); return () => { if (controlsTimeoutRef.current) { clearTimeout(controlsTimeoutRef.current); controlsTimeoutRef.current = null; } }; }, [_hideControls, autoplay]); const _onProgress = (0, _react.useCallback)(event => { if (onProgress) onProgress(event); if (isNaN(props?.duration || 0) && isNaN(duration)) { throw new Error('Could not load video duration correctly, please add `duration` props'); } setProgress(event.currentTime / (props.duration || duration)); }, [onProgress, props.duration, duration, setProgress]); const _onEnd = (0, _react.useCallback)(() => { if (onEnd) onEnd(); setProgress(1); if (repeat) videoRef.current?.seek(0); setIsPlaying(repeat); }, [onEnd, setProgress, repeat]); const _onLoad = (0, _react.useCallback)(event => { if (onLoad) onLoad(event); setDuration(event.duration); }, [onLoad]); const _onPlayPress = (0, _react.useCallback)(() => { if (onPlayPress) onPlayPress(); setIsPlaying(prev => !prev); if (progressRef.current >= 1) { videoRef.current?.seek(0); } _showControls(); }, [_showControls, onPlayPress]); const _onMutePress = (0, _react.useCallback)(() => { const newMutedState = !isMuted; if (onMutePress) onMutePress(newMutedState); setIsMuted(newMutedState); _showControls(); }, [isMuted, onMutePress, _showControls]); const _onPlaybackStateChanged = (0, _react.useCallback)(data => { if (onPlaybackStateChanged) onPlaybackStateChanged(data); if (data.isPlaying !== isPlaying) setIsPlaying(data.isPlaying); }, [isPlaying, onPlaybackStateChanged]); const onToggleFullScreen = (0, _react.useCallback)(() => { videoRef.current?.presentFullscreenPlayer(); }, []); const seek = (0, _react.useCallback)(progress => { videoRef.current?.seek(progress); setProgress(progress / (props.duration || duration)); }, [duration, props.duration, setProgress]); return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, { style: [{ overflow: 'hidden' }, customStyles.videoWrapper], children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeVideo.default, { ...props, ref: videoRef, style: [styles.video, sizeStyle, style, customStyles.video], muted: muted || isMuted, paused: paused || !isPlaying, onProgress: _onProgress, onEnd: _onEnd, onLoad: _onLoad, source: source, resizeMode: resizeMode, onPlaybackStateChanged: _onPlaybackStateChanged }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, { style: styles.overlayButton, onPress: () => { _showControls(); if (pauseOnPress) _onPlayPress(); }, onLongPress: () => { if (fullScreenOnLongPress) onToggleFullScreen(); } }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Controls.Controls, { ref: controlsRef, customStyles: customStyles, showDuration: showDuration, disableFullscreen: disableFullscreen, duration: props.duration || duration, isPlaying: isPlaying, isMuted: isMuted, onPlayPress: _onPlayPress, onMutePress: _onMutePress, onToggleFullScreen: onToggleFullScreen, animationDuration: animationDuration, showControls: _showControls, autoplay: autoplay, disableSeek: disableSeek, setIsPlaying: setIsPlaying, onSeek: seek, controlsTimeoutId: controlsTimeoutRef.current, isControlsVisible: isControlsVisible })] }); })); const styles = _reactNative.StyleSheet.create({ video: +_reactNative.Platform.Version >= 24 ? {} : { backgroundColor: 'black' }, controls: { backgroundColor: 'rgba(0, 0, 0, 0.6)', height: 48, marginTop: -48, flexDirection: 'row', alignItems: 'center' }, overlayButton: { ..._reactNative.StyleSheet.absoluteFillObject } }); //# sourceMappingURL=Video.js.map