@igorpache/expo-video-editor 0.1.0

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.
Files changed (58) hide show
  1. package/.prettierrc +8 -0
  2. package/LICENSE +21 -0
  3. package/README.md +117 -0
  4. package/android/build.gradle +27 -0
  5. package/android/src/main/AndroidManifest.xml +2 -0
  6. package/android/src/main/java/expo/modules/videoeditor/ColorMatrixEffect.kt +25 -0
  7. package/android/src/main/java/expo/modules/videoeditor/ExpoVideoEditorModule.kt +61 -0
  8. package/android/src/main/java/expo/modules/videoeditor/ExpoVideoEditorView.kt +109 -0
  9. package/android/src/main/java/expo/modules/videoeditor/ExportRunner.kt +302 -0
  10. package/android/src/main/java/expo/modules/videoeditor/GifOverlay.kt +27 -0
  11. package/android/src/main/java/expo/modules/videoeditor/Records.kt +44 -0
  12. package/eslint.config.cjs +16 -0
  13. package/expo-module.config.json +9 -0
  14. package/ios/AudioMixBuilder.swift +66 -0
  15. package/ios/ColorMatrixFilter.swift +24 -0
  16. package/ios/ExpoVideoEditor.podspec +23 -0
  17. package/ios/ExpoVideoEditorModule.swift +55 -0
  18. package/ios/ExpoVideoEditorView.swift +144 -0
  19. package/ios/ExportRunner.swift +135 -0
  20. package/ios/FrameComposer.swift +94 -0
  21. package/ios/ImageVideoWriter.swift +144 -0
  22. package/ios/Records.swift +41 -0
  23. package/package.json +36 -0
  24. package/src/components/EditorRoot.tsx +180 -0
  25. package/src/components/ExportOverlay.tsx +44 -0
  26. package/src/components/PreviewSurface.tsx +49 -0
  27. package/src/components/VideoEditor.tsx +51 -0
  28. package/src/components/audio/AudioPanel.tsx +69 -0
  29. package/src/components/audio/AudioScrubber.tsx +177 -0
  30. package/src/components/audio/Slider.tsx +60 -0
  31. package/src/components/filters/FilterCarousel.tsx +44 -0
  32. package/src/components/giphy/GiphyGrid.tsx +48 -0
  33. package/src/components/giphy/GiphyPicker.tsx +112 -0
  34. package/src/components/overlays/GifOverlayView.tsx +53 -0
  35. package/src/components/overlays/OverlayLayer.tsx +24 -0
  36. package/src/components/overlays/TextEditorSheet.tsx +135 -0
  37. package/src/components/overlays/TextOverlayView.tsx +61 -0
  38. package/src/components/timeline/ThumbnailStrip.tsx +63 -0
  39. package/src/components/timeline/TrimTimeline.tsx +152 -0
  40. package/src/errors.ts +33 -0
  41. package/src/filters/presets.ts +84 -0
  42. package/src/hooks/useAudioPreview.ts +94 -0
  43. package/src/hooks/useExport.ts +41 -0
  44. package/src/hooks/useOverlayGestures.ts +90 -0
  45. package/src/index.ts +29 -0
  46. package/src/native/EditorVideoView.tsx +27 -0
  47. package/src/native/VideoEditorModule.ts +51 -0
  48. package/src/overlays/captureRegistry.ts +12 -0
  49. package/src/services/demoCatalog.ts +30 -0
  50. package/src/services/exportService.ts +199 -0
  51. package/src/services/feedfmCatalog.ts +44 -0
  52. package/src/services/giphyClient.ts +69 -0
  53. package/src/services/mediaCache.ts +18 -0
  54. package/src/services/musicCatalog.ts +23 -0
  55. package/src/state/store.ts +200 -0
  56. package/src/theme.ts +26 -0
  57. package/src/types.ts +104 -0
  58. package/tsconfig.json +28 -0
package/src/types.ts ADDED
@@ -0,0 +1,104 @@
1
+ import type { StyleProp, ViewStyle } from 'react-native';
2
+
3
+ export type Transform = {
4
+ x: number;
5
+ y: number;
6
+ scale: number;
7
+ rotation: number;
8
+ };
9
+
10
+ export const IDENTITY_TRANSFORM: Transform = { x: 0.5, y: 0.5, scale: 1, rotation: 0 };
11
+
12
+ export type OverlayBaseSize = { baseWidth?: number; baseHeight?: number };
13
+
14
+ export type TextOverlay = OverlayBaseSize & {
15
+ id: string;
16
+ type: 'text';
17
+ text: string;
18
+ fontFamily?: string;
19
+ fontSize: number;
20
+ color: string;
21
+ backgroundColor?: string;
22
+ align: 'left' | 'center' | 'right';
23
+ transform: Transform;
24
+ timeRange?: [number, number];
25
+ };
26
+
27
+ export type StickerOverlay = OverlayBaseSize & {
28
+ id: string;
29
+ type: 'gif' | 'sticker';
30
+ previewUri: string;
31
+ exportUri: string;
32
+ aspectRatio: number;
33
+ transform: Transform;
34
+ timeRange?: [number, number];
35
+ };
36
+
37
+ export type Overlay = TextOverlay | StickerOverlay;
38
+
39
+ export type AudioTrack = {
40
+ uri: string;
41
+ title?: string;
42
+ duration: number;
43
+ trimStart: number;
44
+ trimEnd: number;
45
+ volume: number;
46
+ loop: boolean;
47
+ };
48
+
49
+ export type AudioSource = { uri: string; title?: string; duration?: number };
50
+
51
+ export type VideoSource = { uri: string };
52
+
53
+ export type VideoMeta = {
54
+ duration: number;
55
+ width: number;
56
+ height: number;
57
+ rotation: number;
58
+ };
59
+
60
+ export type ColorMatrix = number[];
61
+
62
+ export type EditorState = {
63
+ source: VideoSource;
64
+ meta: VideoMeta | null;
65
+ trim: { start: number; end: number };
66
+ filter: string;
67
+ overlays: Overlay[];
68
+ audio: AudioTrack | null;
69
+ originalVolume: number;
70
+ };
71
+
72
+ export type ExportResolution = 720 | 1080 | 'source';
73
+
74
+ export type ExportOptions = {
75
+ resolution?: ExportResolution;
76
+ bitrate?: number;
77
+ };
78
+
79
+ export type ExportResult = {
80
+ uri: string;
81
+ width: number;
82
+ height: number;
83
+ duration: number;
84
+ };
85
+
86
+ export type GiphyConfig = { apiKey: string };
87
+ export type AudioConfig = { onPickAudio?: () => Promise<AudioSource | null> };
88
+
89
+ export type VideoEditorProps = {
90
+ source: VideoSource;
91
+ giphy?: GiphyConfig;
92
+ audio?: AudioConfig;
93
+ export?: ExportOptions;
94
+ theme?: Partial<import('./theme').EditorTheme>;
95
+ style?: StyleProp<ViewStyle>;
96
+ onExportStart?: () => void;
97
+ onExportProgress?: (progress: number) => void;
98
+ onExportComplete?: (result: ExportResult) => void;
99
+ onExportError?: (error: unknown) => void;
100
+ /** Se fornecido, o botão de exportar NÃO roda o encode bloqueante — apenas
101
+ entrega o estado do editor para o host exportar em background. */
102
+ onRequestExport?: (state: EditorState, options: ExportOptions) => void;
103
+ onCancel?: () => void;
104
+ };
package/tsconfig.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "compilerOptions": {
3
+ "lib": ["dom", "DOM.Iterable", "esnext"],
4
+ "types": ["jest"],
5
+ "typeRoots": ["./ts-declarations", "./node_modules/@types", "../../node_modules/@types"],
6
+ "jsx": "react-native",
7
+ "target": "esnext",
8
+ "moduleResolution": "bundler",
9
+ "module": "esnext",
10
+ "moduleDetection": "force",
11
+ "esModuleInterop": true,
12
+ "sourceMap": true,
13
+ "declaration": true,
14
+ "declarationMap": true,
15
+ "inlineSources": true,
16
+ "skipLibCheck": true,
17
+ "strict": true,
18
+ "noFallthroughCasesInSwitch": true,
19
+ "noPropertyAccessFromIndexSignature": false,
20
+ "noImplicitReturns": true,
21
+ "noUnusedLocals": true,
22
+ "noUnusedParameters": false,
23
+ "rootDir": "./src",
24
+ "outDir": "./build"
25
+ },
26
+ "include": ["./src"],
27
+ "exclude": ["**/__mocks__/*", "**/__tests__/*"]
28
+ }