aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/comments/ZoomInCropper.tsx56
-rw-r--r--src/components/moments/trimmer.tsx95
-rw-r--r--src/screens/profile/CaptionScreen.tsx2
-rw-r--r--src/utils/camera.ts15
4 files changed, 147 insertions, 21 deletions
diff --git a/src/components/comments/ZoomInCropper.tsx b/src/components/comments/ZoomInCropper.tsx
index 6f8ff97c..8563288e 100644
--- a/src/components/comments/ZoomInCropper.tsx
+++ b/src/components/comments/ZoomInCropper.tsx
@@ -9,13 +9,14 @@ import CloseIcon from '../../assets/ionicons/close-outline.svg';
import {MainStackParams} from '../../routes';
import {
cropVideo,
+ trimVideo,
HeaderHeight,
SCREEN_HEIGHT,
SCREEN_WIDTH,
} from '../../utils';
import {TaggSquareButton} from '../common';
import ReactNativeZoomableView from '@dudigital/react-native-zoomable-view/src/ReactNativeZoomableView';
-import Video from 'react-native-video';
+import {TrimmerPlayer} from '../moments/trimmer';
type ZoomInCropperRouteProps = RouteProp<MainStackParams, 'ZoomInCropper'>;
type ZoomInCropperNavigationProps = StackNavigationProp<
@@ -51,6 +52,15 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({
cropOffsetY?: number;
}>({});
+ // Stores the current trim endpoints
+ const [trimEnds, setTrimEnds] = useState<{
+ end: number;
+ start: number;
+ }>({
+ end: 60,
+ start: 0,
+ });
+
const checkIfUriImage = (uri: string) => {
return (
uri.endsWith('jpg') ||
@@ -136,19 +146,24 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({
cropHeight: origDimensions[1],
}));
}
- cropVideo(
+ trimVideo(
media.uri,
- (croppedURL: string) => {
- navigation.navigate('CaptionScreen', {
- screenType,
- media: {
- uri: croppedURL,
- isVideo: true,
+ (trimmedURL: string) =>
+ cropVideo(
+ trimmedURL,
+ (croppedURL: string) => {
+ navigation.navigate('CaptionScreen', {
+ screenType,
+ media: {
+ uri: croppedURL,
+ isVideo: true,
+ },
+ selectedCategory,
+ });
},
- selectedCategory,
- });
- },
- videoCrop,
+ videoCrop,
+ ),
+ trimEnds,
);
}
};
@@ -304,22 +319,23 @@ export const ZoomInCropper: React.FC<ZoomInCropperProps> = ({
}}
style={styles.zoomView}>
<View style={styles.videoParent} ref={vidRef}>
- <Video
- source={{uri: media.uri}}
- volume={1}
- style={[
+ <TrimmerPlayer
+ hideTrimmer={false}
+ source={media.uri}
+ videoStyles={[
styles.media,
{
height: SCREEN_WIDTH / aspectRatio,
},
]}
- repeat={true}
- resizeMode={'contain'}
- onLoad={(response) => {
- const {width, height} = response.naturalSize;
+ handleLoad={(response: {width: number; height: number}) => {
+ const {width, height} = response;
setOrigDimensions([width, height]);
setAspectRatio(width / height);
}}
+ onChangedEndpoints={(response: {start: number; end: number}) =>
+ setTrimEnds(response)
+ }
/>
</View>
</ReactNativeZoomableView>
diff --git a/src/components/moments/trimmer.tsx b/src/components/moments/trimmer.tsx
new file mode 100644
index 00000000..c9e8a6c5
--- /dev/null
+++ b/src/components/moments/trimmer.tsx
@@ -0,0 +1,95 @@
+import React, {useEffect, useState} from 'react';
+import Video from 'react-native-video';
+import {Trimmer} from 'react-native-video-processing';
+import {useRef} from 'react';
+import {SCREEN_WIDTH} from '../../utils';
+
+export const TrimmerPlayer: React.FC<{
+ source: string;
+ videoStyles: Object;
+ hideTrimmer: boolean;
+ handleLoad: Function;
+ onChangedEndpoints: Function;
+}> = ({source, videoStyles, hideTrimmer, handleLoad, onChangedEndpoints}) => {
+ const playerRef = useRef<Video>();
+
+ const [seekTime, setSeekTime] = useState<number>(0);
+ const [paused, setPaused] = useState<boolean>(false);
+ useEffect(() => {
+ playerRef.current?.seek(seekTime);
+ }, [seekTime]);
+
+ const [trackerTime, setTrackerTime] = useState<number>(0);
+ useEffect(() => {
+ if (!paused && (trackerTime >= end || trackerTime < start)) {
+ setTrackerTime(start);
+ playerRef.current?.seek(start);
+ }
+ }, [trackerTime]);
+
+ const [end, setEnd] = useState<number>(60);
+ const [start, setStart] = useState<number>(0);
+ useEffect(() => {
+ setSeekTime(start);
+ setTrackerTime(start);
+ }, [start]);
+ useEffect(() => {
+ setSeekTime(end);
+ setTrackerTime(start);
+ }, [end]);
+
+ useEffect(() => onChangedEndpoints({end, start}), [end, start]);
+
+ return (
+ <>
+ <Video
+ ref={(ref) => {
+ playerRef.current = ref || undefined;
+ }}
+ source={{uri: source}} // Looks for .mp4 file (background.mp4) in the given expansion version.
+ rate={1.0} // 0 is paused, 1 is normal.
+ volume={1.0} // 0 is muted, 1 is normal.
+ muted={false} // Mutes the audio entirely.
+ paused={paused} // Pauses playback entirely.
+ resizeMode={'contain'}
+ repeat={true} // Repeat forever.
+ onLoad={(payload) => {
+ console.log(payload, source);
+ setEnd(payload.duration);
+ handleLoad(payload.naturalSize);
+ }}
+ onProgress={(e) => {
+ if (!paused) {
+ setTrackerTime(e.currentTime);
+ }
+ }} // Callback every ~250ms with currentTime
+ //onEnd={() => console.log('end')} // Callback when playback finishes
+ //onError={this.videoError} // Callback when video cannot be loaded
+ style={videoStyles}
+ onTouchEnd={() => {
+ setPaused((state) => !state);
+ }}
+ />
+ <Trimmer
+ source={source}
+ height={hideTrimmer ? 0 : 75}
+ width={hideTrimmer ? 0 : SCREEN_WIDTH}
+ borderWidth={hideTrimmer ? 0 : 100}
+ onTrackerMove={(e: {currentTime: number}) => {
+ setPaused(true);
+ setSeekTime(e.currentTime);
+ }} // iOS only
+ currentTime={trackerTime} // added .25 bc tracker is inaccurate
+ themeColor={'white'} // iOS only
+ // showTrackerHandle={true}
+ thumbWidth={10} // iOS only
+ trackerColor={'white'} // iOS only
+ onChange={(e: {endTime: number; startTime: number}) => {
+ setPaused(true);
+ setEnd(e.endTime);
+ setStart(e.startTime);
+ }}
+ />
+ </>
+ );
+};
diff --git a/src/screens/profile/CaptionScreen.tsx b/src/screens/profile/CaptionScreen.tsx
index 6bcf0e24..eba3e4bf 100644
--- a/src/screens/profile/CaptionScreen.tsx
+++ b/src/screens/profile/CaptionScreen.tsx
@@ -49,7 +49,6 @@ import {RootState} from '../../store/rootReducer';
import {MomentTagType} from '../../types';
import {isIPhoneX, normalize, SCREEN_WIDTH, StatusBarHeight} from '../../utils';
import {mentionPartTypes} from '../../utils/comments';
-
/**
* Upload Screen to allow users to upload posts to Tagg
*/
@@ -362,6 +361,7 @@ const CaptionScreen: React.FC<CaptionScreenProps> = ({route, navigation}) => {
</SearchBackground>
);
};
+
const styles = StyleSheet.create({
contentContainer: {
paddingTop: StatusBarHeight,
diff --git a/src/utils/camera.ts b/src/utils/camera.ts
index 9e37d62e..5c7f5ee0 100644
--- a/src/utils/camera.ts
+++ b/src/utils/camera.ts
@@ -118,6 +118,21 @@ export const showGIFFailureAlert = (onSuccess: () => void) =>
},
);
+export const trimVideo = (
+ sourceUri: string,
+ handleData: (data: any) => any,
+ ends: {
+ start: number;
+ end: number;
+ },
+) => {
+ ProcessingManager.trim(sourceUri, {
+ startTime: ends.start / 2, //needed divide by 2 for bug in module
+ endTime: ends.end,
+ quality: 'passthrough',
+ }).then((data: any) => handleData(data));
+};
+
export const cropVideo = (
sourceUri: string,
handleData: (data: any) => any,