@umituz/react-native-video-editor 1.0.9 → 1.0.11
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.11",
|
|
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",
|
|
@@ -11,16 +11,16 @@ declare const __DEV__: boolean;
|
|
|
11
11
|
* Safely play video with error handling
|
|
12
12
|
*/
|
|
13
13
|
export const safePlay = (player: VideoPlayer | null): boolean => {
|
|
14
|
+
console.log("[safePlay] called, player:", !!player);
|
|
14
15
|
if (!player) return false;
|
|
15
16
|
|
|
16
17
|
try {
|
|
18
|
+
console.log("[safePlay] calling player.play()");
|
|
17
19
|
player.play();
|
|
20
|
+
console.log("[safePlay] player.play() called successfully");
|
|
18
21
|
return true;
|
|
19
22
|
} catch (error) {
|
|
20
|
-
|
|
21
|
-
// eslint-disable-next-line no-console
|
|
22
|
-
console.log("[VideoPlayer] Play error ignored:", error);
|
|
23
|
-
}
|
|
23
|
+
console.log("[safePlay] Play error:", error);
|
|
24
24
|
return false;
|
|
25
25
|
}
|
|
26
26
|
};
|
|
@@ -8,17 +8,31 @@ import {
|
|
|
8
8
|
View,
|
|
9
9
|
TouchableOpacity,
|
|
10
10
|
StyleSheet,
|
|
11
|
-
|
|
11
|
+
type ViewStyle,
|
|
12
12
|
} from "react-native";
|
|
13
13
|
import { Image } from "expo-image";
|
|
14
14
|
import { VideoView } from "expo-video";
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
useAppDesignTokens,
|
|
17
|
+
AtomicIcon,
|
|
18
|
+
useResponsive,
|
|
19
|
+
} from "@umituz/react-native-design-system";
|
|
16
20
|
|
|
17
21
|
import type { VideoPlayerProps } from "../../types";
|
|
18
22
|
import { useVideoPlayerControl } from "../hooks/useVideoPlayerControl";
|
|
19
23
|
|
|
24
|
+
declare const __DEV__: boolean;
|
|
25
|
+
|
|
20
26
|
const ASPECT_RATIO = 16 / 9;
|
|
21
27
|
|
|
28
|
+
/** Extract numeric width from style prop */
|
|
29
|
+
const getWidthFromStyle = (style: ViewStyle | undefined): number | null => {
|
|
30
|
+
if (!style) return null;
|
|
31
|
+
const w = style.width;
|
|
32
|
+
if (typeof w === "number") return w;
|
|
33
|
+
return null;
|
|
34
|
+
};
|
|
35
|
+
|
|
22
36
|
export const VideoPlayer: React.FC<VideoPlayerProps> = ({
|
|
23
37
|
source,
|
|
24
38
|
thumbnailUrl,
|
|
@@ -30,57 +44,65 @@ export const VideoPlayer: React.FC<VideoPlayerProps> = ({
|
|
|
30
44
|
style,
|
|
31
45
|
}) => {
|
|
32
46
|
const tokens = useAppDesignTokens();
|
|
33
|
-
const { width } =
|
|
47
|
+
const { width: screenWidth, horizontalPadding } = useResponsive();
|
|
34
48
|
const [showVideo, setShowVideo] = useState(autoPlay);
|
|
35
49
|
|
|
36
50
|
const { player, state, controls } = useVideoPlayerControl({
|
|
37
|
-
source
|
|
51
|
+
source,
|
|
38
52
|
loop,
|
|
39
53
|
muted,
|
|
40
|
-
autoPlay:
|
|
54
|
+
autoPlay: false,
|
|
41
55
|
});
|
|
42
56
|
|
|
43
|
-
// Auto-play when video becomes visible
|
|
44
57
|
useEffect(() => {
|
|
45
58
|
if (showVideo && state.isPlayerValid && player) {
|
|
46
|
-
|
|
59
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
60
|
+
// eslint-disable-next-line no-console
|
|
61
|
+
console.log("[VideoPlayer] Starting playback...");
|
|
62
|
+
}
|
|
47
63
|
controls.play();
|
|
48
64
|
}
|
|
49
65
|
}, [showVideo, state.isPlayerValid, player, controls]);
|
|
50
66
|
|
|
51
67
|
const handlePlay = useCallback(() => {
|
|
52
|
-
|
|
68
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
69
|
+
// eslint-disable-next-line no-console
|
|
70
|
+
console.log("[VideoPlayer] handlePlay called, source:", source);
|
|
71
|
+
}
|
|
53
72
|
setShowVideo(true);
|
|
54
73
|
}, [source]);
|
|
55
74
|
|
|
75
|
+
// Calculate absolute dimensions for VideoView (expo-video requires pixel values)
|
|
76
|
+
const videoWidth = getWidthFromStyle(style as ViewStyle) ?? (screenWidth - horizontalPadding * 2);
|
|
77
|
+
const videoHeight = videoWidth / ASPECT_RATIO;
|
|
78
|
+
|
|
56
79
|
const containerStyle = useMemo(() => ({
|
|
57
|
-
width:
|
|
58
|
-
|
|
80
|
+
width: videoWidth,
|
|
81
|
+
height: videoHeight,
|
|
59
82
|
backgroundColor: tokens.colors.surface,
|
|
60
83
|
borderRadius: 16,
|
|
61
84
|
overflow: "hidden" as const,
|
|
62
|
-
}), [tokens.colors.surface]);
|
|
85
|
+
}), [tokens.colors.surface, videoWidth, videoHeight]);
|
|
63
86
|
|
|
64
87
|
const styles = useMemo(
|
|
65
88
|
() =>
|
|
66
89
|
StyleSheet.create({
|
|
67
90
|
video: {
|
|
68
|
-
width:
|
|
69
|
-
height:
|
|
91
|
+
width: videoWidth,
|
|
92
|
+
height: videoHeight,
|
|
70
93
|
},
|
|
71
94
|
thumbnailContainer: {
|
|
72
|
-
|
|
73
|
-
height: "100%",
|
|
95
|
+
flex: 1,
|
|
74
96
|
justifyContent: "center",
|
|
75
97
|
alignItems: "center",
|
|
76
98
|
},
|
|
77
99
|
thumbnail: {
|
|
78
|
-
width:
|
|
79
|
-
height:
|
|
100
|
+
width: videoWidth,
|
|
101
|
+
height: videoHeight,
|
|
80
102
|
},
|
|
81
103
|
placeholder: {
|
|
82
|
-
width:
|
|
83
|
-
height:
|
|
104
|
+
width: videoWidth,
|
|
105
|
+
height: videoHeight,
|
|
84
106
|
backgroundColor: tokens.colors.surfaceSecondary,
|
|
85
107
|
},
|
|
86
108
|
playButtonContainer: {
|
|
@@ -98,20 +120,24 @@ export const VideoPlayer: React.FC<VideoPlayerProps> = ({
|
|
|
98
120
|
paddingLeft: 4,
|
|
99
121
|
},
|
|
100
122
|
}),
|
|
101
|
-
[tokens]
|
|
123
|
+
[tokens, videoWidth, videoHeight]
|
|
102
124
|
);
|
|
103
125
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
126
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
127
|
+
// eslint-disable-next-line no-console
|
|
128
|
+
console.log("[VideoPlayer] state:", {
|
|
129
|
+
showVideo,
|
|
130
|
+
isPlayerValid: state.isPlayerValid,
|
|
131
|
+
hasPlayer: !!player,
|
|
132
|
+
source,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
111
135
|
|
|
112
|
-
// Show video player when playing
|
|
113
136
|
if (showVideo && state.isPlayerValid && player) {
|
|
114
|
-
|
|
137
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
138
|
+
// eslint-disable-next-line no-console
|
|
139
|
+
console.log("[VideoPlayer] Rendering VideoView");
|
|
140
|
+
}
|
|
115
141
|
return (
|
|
116
142
|
<View style={[containerStyle, style]}>
|
|
117
143
|
<VideoView
|
|
@@ -124,7 +150,6 @@ export const VideoPlayer: React.FC<VideoPlayerProps> = ({
|
|
|
124
150
|
);
|
|
125
151
|
}
|
|
126
152
|
|
|
127
|
-
// Show thumbnail with play button
|
|
128
153
|
return (
|
|
129
154
|
<TouchableOpacity
|
|
130
155
|
style={[containerStyle, style]}
|
|
@@ -31,7 +31,8 @@ export const useVideoPlayerControl = (
|
|
|
31
31
|
const [isPlaying, setIsPlaying] = useState(false);
|
|
32
32
|
const [isLoading, setIsLoading] = useState(true);
|
|
33
33
|
|
|
34
|
-
const player = useExpoVideoPlayer(source
|
|
34
|
+
const player = useExpoVideoPlayer(source || "", (p) => {
|
|
35
|
+
console.log("[useVideoPlayerControl] Player callback, source:", source, "player:", !!p);
|
|
35
36
|
if (source && p) {
|
|
36
37
|
configurePlayer(p, { loop, muted, autoPlay });
|
|
37
38
|
setIsLoading(false);
|