aboutsummaryrefslogtreecommitdiff
path: root/src/components/moments/TrimmerPlayer.tsx
blob: 8d1cd156c62870920caddf86d655ae5b2a6a9f4d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import React, {useEffect, useRef, useState} from 'react';
import {StyleSheet, View} from 'react-native';
import Video from 'react-native-video';
import {Trimmer} from 'react-native-video-processing';
import {SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';

interface TrimmerPlayerProps {
  source: string;
  videoStyles: Object;
  hideTrimmer: boolean;
  handleLoad: Function;
  onChangedEndpoints: Function;
  muted: boolean;
}

const TrimmerPlayer: React.FC<TrimmerPlayerProps> = ({
  source,
  videoStyles,
  hideTrimmer,
  handleLoad,
  onChangedEndpoints,
  muted,
}) => {
  // Stores the reference to player for seeking
  const playerRef = useRef<Video>();
  // Stores where the video is playing (seekTime)
  const [seekTime, setSeekTime] = useState<number>(0);
  const [paused, setPaused] = useState<boolean>(false);
  // Stores where the tracker is
  const [trackerTime, setTrackerTime] = useState<number>(0);
  // Stores start/end of desired trimmed video
  const [end, setEnd] = useState<number>(60);
  const [start, setStart] = useState<number>(0);

  useEffect(() => {
    playerRef.current?.seek(seekTime);
  }, [seekTime]);
  useEffect(() => {
    if (!paused && (trackerTime >= end || trackerTime < start)) {
      setTrackerTime(start);
      playerRef.current?.seek(start);
    }
  }, [trackerTime]);
  useEffect(() => {
    setSeekTime(start);
    setTrackerTime(start);
  }, [start]);
  useEffect(() => {
    setSeekTime(end);
    setTrackerTime(start);
  }, [end]);
  // Callback so parent knows where the trimming endpts are
  useEffect(() => onChangedEndpoints({end, start}), [end, start]);

  useEffect(() => {
    playerRef.current?.seek(0);
  }, [hideTrimmer]);

  return (
    <>
      <Video
        // link to descr and use of props of video player ->
        // https://github.com/react-native-video/react-native-video
        ref={(ref) => {
          playerRef.current = ref || undefined;
        }}
        source={{uri: source}}
        rate={1.0}
        volume={1.0}
        muted={muted}
        paused={paused}
        resizeMode={'contain'}
        repeat={true}
        onLoad={(payload) => {
          setEnd(payload.duration);
          const {width, height} = payload.naturalSize;
          if (payload.naturalSize.orientation === 'portrait') {
            handleLoad(height, width, payload.duration);
          } else {
            handleLoad(width, height, payload.duration);
          }
        }}
        onProgress={(e) => {
          if (!paused) {
            setTrackerTime(e.currentTime);
          }
        }} // Callback every ~250ms with currentTime
        style={videoStyles}
        onTouchEnd={() => {
          setPaused((state) => !state);
        }}
      />
      {!hideTrimmer && (
        <View style={styles.trimmerContainer}>
          <Trimmer
            // link to descr and use of props for trimmer ->
            // https://github.com/shahen94/react-native-video-processing
            source={source}
            height={75}
            width={SCREEN_WIDTH}
            onTrackerMove={(e: {currentTime: number}) => {
              setPaused(true);
              setSeekTime(e.currentTime);
            }}
            currentTime={trackerTime}
            themeColor={'white'}
            thumbWidth={10}
            trackerColor={'white'}
            onChange={(e: {endTime: number; startTime: number}) => {
              setPaused(true);
              setEnd(e.endTime);
              setStart(e.startTime);
            }}
          />
        </View>
      )}
    </>
  );
};

const styles = StyleSheet.create({
  trimmerContainer: {
    position: 'absolute',
    bottom: SCREEN_HEIGHT * 0.1,
    alignItems: 'center',
    borderWidth: 1,
    borderColor: 'red',
  },
});

export default TrimmerPlayer;