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
132
133
134
135
136
137
138
139
140
|
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>(true);
// 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);
// Slight delay to play video since RNCamera can't record and play video here
// at the same time.
// see: https://github.com/react-native-camera/react-native-camera/issues/2592
useEffect(() => {
setTimeout(() => {
setPaused(false);
}, 1000);
}, []);
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;
|