@zezosoft/zezo-ott-react-native-video-player
Version:
Production-ready React Native OTT video player library for Android & iOS. Features: playlists, seasons, auto-next playback, subtitles (SRT/VTT), custom theming, analytics tracking, fullscreen mode, gesture controls, ads player (pre-roll/mid-roll/post-roll
124 lines (123 loc) • 3.78 kB
JavaScript
"use strict";
/* eslint-disable react-hooks/exhaustive-deps */
import React, { useEffect, useMemo, useCallback } from 'react';
import { View, StyleSheet } from 'react-native';
import { Slider } from 'react-native-awesome-slider';
import { useSharedValue, withTiming } from 'react-native-reanimated';
import { moderateScale } from 'react-native-size-matters';
import { useVideoPlayerConfig } from "../context/index.js";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const ProgressBar = /*#__PURE__*/React.memo(({
duration,
currentTime,
bufferedTime,
onSeek,
showThumb = true,
disabled = false,
adMarkers = [],
height
}) => {
const {
colors,
metrics
} = useVideoPlayerConfig();
const sliderHeight = height ?? metrics.sliderHeight;
const thumbSize = useMemo(() => {
return sliderHeight * 3;
}, [sliderHeight]);
const progress = useSharedValue(currentTime);
const cache = useSharedValue(bufferedTime);
const min = useSharedValue(0);
const max = useSharedValue(duration);
useEffect(() => {
progress.value = withTiming(currentTime, {
duration: 160
});
}, [currentTime]);
useEffect(() => {
cache.value = withTiming(bufferedTime, {
duration: 180
});
}, [bufferedTime]);
useEffect(() => {
max.value = duration;
}, [duration]);
const adPositions = useMemo(() => {
if (duration <= 0) return [];
return adMarkers.map(t => t / duration * 100);
}, [adMarkers, duration]);
const handleSeek = useCallback(value => {
if (!disabled) onSeek?.(value);
}, [onSeek, disabled]);
return /*#__PURE__*/_jsxs(View, {
style: [styles.container, {
height: thumbSize
}],
children: [/*#__PURE__*/_jsx(Slider, {
progress: progress,
minimumValue: min,
maximumValue: max,
cache: cache,
disable: disabled,
onValueChange: handleSeek,
containerStyle: [styles.sliderContainer, {
borderRadius: sliderHeight / 2,
height: sliderHeight
}],
renderThumb: showThumb ? () => /*#__PURE__*/_jsx(View, {
style: {
backgroundColor: colors.primary,
width: thumbSize,
height: thumbSize,
borderRadius: thumbSize / 2
}
}) : () => null,
renderBubble: () => null,
thumbWidth: showThumb ? thumbSize : 0,
theme: {
minimumTrackTintColor: colors.primary,
maximumTrackTintColor: colors.secondary,
cacheTrackTintColor: colors.buffer,
disableMinTrackTintColor: colors.primary,
bubbleBackgroundColor: colors.white
}
}), adPositions.length > 0 && /*#__PURE__*/_jsx(View, {
style: styles.adMarkersContainer,
pointerEvents: "none",
children: adPositions.map((pos, index) => /*#__PURE__*/_jsx(View, {
style: [styles.adMarker, {
left: `${pos}%`,
backgroundColor: colors.primary,
width: sliderHeight
}]
}, `ad-${index}`))
})]
});
}, (p, n) => p.currentTime === n.currentTime && p.bufferedTime === n.bufferedTime && p.duration === n.duration && p.disabled === n.disabled && p.showThumb === n.showThumb && p.height === n.height && JSON.stringify(p.adMarkers) === JSON.stringify(n.adMarkers));
export default ProgressBar;
const styles = StyleSheet.create({
container: {
position: 'relative',
width: '100%',
overflow: 'hidden',
justifyContent: 'center'
},
sliderContainer: {
overflow: 'hidden'
},
adMarkersContainer: {
position: 'absolute',
width: '100%',
height: '100%',
justifyContent: 'center'
},
adMarker: {
position: 'absolute',
aspectRatio: 1,
top: '50%',
transform: [{
translateY: -moderateScale(2.5)
}]
}
});
//# sourceMappingURL=ProgressBar.js.map