@umituz/react-native-video-editor 1.0.10 → 1.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-video-editor",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.12",
|
|
4
4
|
"description": "Professional video editor with layer-based timeline, text/image/shape/audio/animation layers, and export functionality",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -4,21 +4,30 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import React, { useState, useCallback, useMemo, useEffect } from "react";
|
|
7
|
-
import {
|
|
8
|
-
View,
|
|
9
|
-
TouchableOpacity,
|
|
10
|
-
StyleSheet,
|
|
11
|
-
useWindowDimensions,
|
|
12
|
-
} from "react-native";
|
|
7
|
+
import { View, TouchableOpacity, StyleSheet, type ViewStyle } from "react-native";
|
|
13
8
|
import { Image } from "expo-image";
|
|
14
9
|
import { VideoView } from "expo-video";
|
|
15
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
useResponsive,
|
|
12
|
+
useAppDesignTokens,
|
|
13
|
+
AtomicIcon,
|
|
14
|
+
} from "@umituz/react-native-design-system";
|
|
16
15
|
|
|
17
16
|
import type { VideoPlayerProps } from "../../types";
|
|
18
17
|
import { useVideoPlayerControl } from "../hooks/useVideoPlayerControl";
|
|
19
18
|
|
|
19
|
+
declare const __DEV__: boolean;
|
|
20
|
+
|
|
20
21
|
const ASPECT_RATIO = 16 / 9;
|
|
21
22
|
|
|
23
|
+
/** Extract numeric width from style prop */
|
|
24
|
+
const getWidthFromStyle = (style: ViewStyle | undefined): number | null => {
|
|
25
|
+
if (!style) return null;
|
|
26
|
+
const w = style.width;
|
|
27
|
+
if (typeof w === "number") return w;
|
|
28
|
+
return null;
|
|
29
|
+
};
|
|
30
|
+
|
|
22
31
|
export const VideoPlayer: React.FC<VideoPlayerProps> = ({
|
|
23
32
|
source,
|
|
24
33
|
thumbnailUrl,
|
|
@@ -29,11 +38,12 @@ export const VideoPlayer: React.FC<VideoPlayerProps> = ({
|
|
|
29
38
|
contentFit = "cover",
|
|
30
39
|
style,
|
|
31
40
|
}) => {
|
|
41
|
+
// IMPORTANT: Call useResponsive BEFORE useAppDesignTokens to maintain consistent hook order
|
|
42
|
+
// useAppDesignTokens internally calls useResponsive, so order matters
|
|
43
|
+
const { width: screenWidth, horizontalPadding } = useResponsive();
|
|
32
44
|
const tokens = useAppDesignTokens();
|
|
33
|
-
const { width } = useWindowDimensions();
|
|
34
45
|
const [showVideo, setShowVideo] = useState(autoPlay);
|
|
35
46
|
|
|
36
|
-
// Always pass source to player - control visibility separately
|
|
37
47
|
const { player, state, controls } = useVideoPlayerControl({
|
|
38
48
|
source,
|
|
39
49
|
loop,
|
|
@@ -41,47 +51,55 @@ export const VideoPlayer: React.FC<VideoPlayerProps> = ({
|
|
|
41
51
|
autoPlay: false,
|
|
42
52
|
});
|
|
43
53
|
|
|
44
|
-
// Auto-play when user clicks play button
|
|
45
54
|
useEffect(() => {
|
|
46
55
|
if (showVideo && state.isPlayerValid && player) {
|
|
47
|
-
|
|
56
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
57
|
+
// eslint-disable-next-line no-console
|
|
58
|
+
console.log("[VideoPlayer] Starting playback...");
|
|
59
|
+
}
|
|
48
60
|
controls.play();
|
|
49
61
|
}
|
|
50
62
|
}, [showVideo, state.isPlayerValid, player, controls]);
|
|
51
63
|
|
|
52
64
|
const handlePlay = useCallback(() => {
|
|
53
|
-
|
|
65
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
66
|
+
// eslint-disable-next-line no-console
|
|
67
|
+
console.log("[VideoPlayer] handlePlay called, source:", source);
|
|
68
|
+
}
|
|
54
69
|
setShowVideo(true);
|
|
55
70
|
}, [source]);
|
|
56
71
|
|
|
72
|
+
// Calculate absolute dimensions for VideoView (expo-video requires pixel values)
|
|
73
|
+
const videoWidth = getWidthFromStyle(style as ViewStyle) ?? (screenWidth - horizontalPadding * 2);
|
|
74
|
+
const videoHeight = videoWidth / ASPECT_RATIO;
|
|
75
|
+
|
|
57
76
|
const containerStyle = useMemo(() => ({
|
|
58
|
-
width:
|
|
59
|
-
|
|
77
|
+
width: videoWidth,
|
|
78
|
+
height: videoHeight,
|
|
60
79
|
backgroundColor: tokens.colors.surface,
|
|
61
80
|
borderRadius: 16,
|
|
62
81
|
overflow: "hidden" as const,
|
|
63
|
-
}), [tokens.colors.surface]);
|
|
82
|
+
}), [tokens.colors.surface, videoWidth, videoHeight]);
|
|
64
83
|
|
|
65
84
|
const styles = useMemo(
|
|
66
85
|
() =>
|
|
67
86
|
StyleSheet.create({
|
|
68
87
|
video: {
|
|
69
|
-
width:
|
|
70
|
-
height:
|
|
88
|
+
width: videoWidth,
|
|
89
|
+
height: videoHeight,
|
|
71
90
|
},
|
|
72
91
|
thumbnailContainer: {
|
|
73
|
-
|
|
74
|
-
height: "100%",
|
|
92
|
+
flex: 1,
|
|
75
93
|
justifyContent: "center",
|
|
76
94
|
alignItems: "center",
|
|
77
95
|
},
|
|
78
96
|
thumbnail: {
|
|
79
|
-
width:
|
|
80
|
-
height:
|
|
97
|
+
width: videoWidth,
|
|
98
|
+
height: videoHeight,
|
|
81
99
|
},
|
|
82
100
|
placeholder: {
|
|
83
|
-
width:
|
|
84
|
-
height:
|
|
101
|
+
width: videoWidth,
|
|
102
|
+
height: videoHeight,
|
|
85
103
|
backgroundColor: tokens.colors.surfaceSecondary,
|
|
86
104
|
},
|
|
87
105
|
playButtonContainer: {
|
|
@@ -99,20 +117,24 @@ export const VideoPlayer: React.FC<VideoPlayerProps> = ({
|
|
|
99
117
|
paddingLeft: 4,
|
|
100
118
|
},
|
|
101
119
|
}),
|
|
102
|
-
[tokens]
|
|
120
|
+
[tokens, videoWidth, videoHeight]
|
|
103
121
|
);
|
|
104
122
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
123
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
124
|
+
// eslint-disable-next-line no-console
|
|
125
|
+
console.log("[VideoPlayer] state:", {
|
|
126
|
+
showVideo,
|
|
127
|
+
isPlayerValid: state.isPlayerValid,
|
|
128
|
+
hasPlayer: !!player,
|
|
129
|
+
source,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
112
132
|
|
|
113
|
-
// Show video player when playing
|
|
114
133
|
if (showVideo && state.isPlayerValid && player) {
|
|
115
|
-
|
|
134
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
135
|
+
// eslint-disable-next-line no-console
|
|
136
|
+
console.log("[VideoPlayer] Rendering VideoView");
|
|
137
|
+
}
|
|
116
138
|
return (
|
|
117
139
|
<View style={[containerStyle, style]}>
|
|
118
140
|
<VideoView
|
|
@@ -125,7 +147,6 @@ export const VideoPlayer: React.FC<VideoPlayerProps> = ({
|
|
|
125
147
|
);
|
|
126
148
|
}
|
|
127
149
|
|
|
128
|
-
// Show thumbnail with play button
|
|
129
150
|
return (
|
|
130
151
|
<TouchableOpacity
|
|
131
152
|
style={[containerStyle, style]}
|