@imgly/camera-react-native 1.40.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 (29) hide show
  1. package/IMGLYCameraModule.podspec +21 -0
  2. package/LICENSE.md +137 -0
  3. package/README.md +26 -0
  4. package/android/.gradle/8.9/checksums/checksums.lock +0 -0
  5. package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
  6. package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
  7. package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
  8. package/android/.gradle/8.9/gc.properties +0 -0
  9. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  10. package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
  11. package/android/.gradle/vcs-1/gc.properties +0 -0
  12. package/android/build.gradle +64 -0
  13. package/android/src/main/kotlin/ly/img/camera/reactnative/module/IMGLYCameraModule.kt +249 -0
  14. package/android/src/main/kotlin/ly/img/camera/reactnative/module/IMGLYCameraPackage.kt +35 -0
  15. package/android/src/main/kotlin/ly/img/camera/reactnative/module/model/CameraResult.kt +118 -0
  16. package/android/src/main/kotlin/ly/img/camera/reactnative/module/model/CameraSettings.kt +46 -0
  17. package/android/src/main/kotlin/ly/img/camera/reactnative/module/model/Recording.kt +83 -0
  18. package/android/src/newarch/IMGLYCameraModuleSpec.kt +7 -0
  19. package/android/src/oldarch/IMGLYEditorModuleSpec.kt +17 -0
  20. package/index.d.ts +3 -0
  21. package/index.js +3 -0
  22. package/ios/IMGLYCameraModule.h +11 -0
  23. package/ios/IMGLYCameraModule.mm +61 -0
  24. package/ios/IMGLYCameraModule.swift +70 -0
  25. package/ios/Model/CameraBuilder.swift +94 -0
  26. package/ios/Model/CameraResult.swift +181 -0
  27. package/ios/Model/CameraSettings.swift +24 -0
  28. package/package.json +46 -0
  29. package/src/NativeIMGLYCamera.ts +191 -0
@@ -0,0 +1,181 @@
1
+ import IMGLYCamera
2
+
3
+ /// The result type for a camera recording session in standard or dual camera mode.
4
+ @objc @objcMembers public class CameraRecording: NSObject {
5
+ /// The recorded videos.
6
+ public let recordings: [Recording]
7
+
8
+ /// Creates a new `CameraResult` from the `IMGLYCamera` result types.
9
+ /// - Parameters:
10
+ /// - recordings: The recorded `IMGLYCamera.Recording` videos.
11
+ public convenience init(recordings: [IMGLYCamera.Recording]) {
12
+ self.init(
13
+ recordings: recordings.compactMap { Recording(recording: $0) }
14
+ )
15
+ }
16
+
17
+ /// Creates a new `CameraResult`.
18
+ /// - Parameters:
19
+ /// - recordings: The recorded videos.
20
+ public init(recordings: [Recording]) {
21
+ self.recordings = recordings
22
+ }
23
+
24
+ func toDictionary() -> [String: Any] {
25
+ [
26
+ "recordings": recordings.compactMap { $0.toDictionary() },
27
+ ]
28
+ }
29
+ }
30
+
31
+ /// The result type for a camera reaction session.
32
+ @objc @objcMembers public class CameraReaction: NSObject {
33
+ /// The video that was reacted to.
34
+ public let video: Recording
35
+
36
+ /// The recorded videos.
37
+ public let recordings: [Recording]
38
+
39
+ /// Creates a new `CameraReaction` from the `IMGLYCamera` result types.
40
+ /// - Parameters:
41
+ /// - video: The `IMGLYCamera.Recording` video that was reacted to.
42
+ /// - recordings: The recorded `IMGLYCamera.Recording` videos.
43
+ public convenience init(video: IMGLYCamera.Recording, recordings: [IMGLYCamera.Recording]) {
44
+ self.init(
45
+ video: Recording(recording: video),
46
+ recordings: recordings.compactMap { Recording(recording: $0) }
47
+ )
48
+ }
49
+
50
+ /// Creates a new `CameraReaction` instance..
51
+ /// - Parameters:
52
+ /// - video: The `Recording` video that was reacted to.
53
+ /// - recordings: The recorded `Recording` videos.
54
+ public init(video: Recording, recordings: [Recording]) {
55
+ self.video = video
56
+ self.recordings = recordings
57
+ }
58
+
59
+ func toDictionary() -> [String: Any] {
60
+ [
61
+ "video": video.toDictionary(),
62
+ "recordings": recordings.compactMap { $0.toDictionary() },
63
+ ]
64
+ }
65
+ }
66
+
67
+ /// The result of a camera session.
68
+ @objc @objcMembers public class CameraResult: NSObject {
69
+ /// The video that was reacted to.
70
+ public let recording: CameraRecording?
71
+
72
+ /// The recorded videos.
73
+ public let reaction: CameraReaction?
74
+
75
+ /// The associated metadata.
76
+ public let metadata: [String: Any]
77
+
78
+ /// Creates a new `CameraResult`.
79
+ /// - Parameters:
80
+ /// - video: The video that was reacted to.
81
+ /// - recordings: The recorded videos.
82
+ /// - metadata: The associated metadata.
83
+ public convenience init(recording: CameraRecording, metadata: [String: Any] = [:]) {
84
+ self.init(recording: recording, reaction: nil, metadata: metadata)
85
+ }
86
+
87
+ /// Creates a new `CameraResult` from the `IMGLYCamera` result types.
88
+ /// - Parameters:
89
+ /// - video: The `IMGLYCamera.Recording` video that was reacted to.
90
+ /// - recordings: The recorded `IMGLYCamera.Recording` videos.
91
+ /// - metadata: The associated metadata.
92
+ public convenience init(reaction: CameraReaction, metadata: [String: Any] = [:]) {
93
+ self.init(recording: nil, reaction: reaction, metadata: metadata)
94
+ }
95
+
96
+ private init(recording: CameraRecording?, reaction: CameraReaction?, metadata: [String: Any] = [:]) {
97
+ self.recording = recording
98
+ self.reaction = reaction
99
+ self.metadata = metadata
100
+ }
101
+
102
+ /// Converts the instance to a dictionary.
103
+ public func toDictionary() -> [String: Any] {
104
+ var dictionary: [String: Any] = ["metadata": metadata]
105
+ if let recording {
106
+ dictionary["recording"] = recording.toDictionary()
107
+ }
108
+ if let reaction {
109
+ dictionary["reaction"] = reaction.toDictionary()
110
+ }
111
+ return dictionary
112
+ }
113
+ }
114
+
115
+ /// A recording of the camera that can contain multiple video sections.
116
+ @objc @objcMembers public class Recording: NSObject {
117
+ /// The individual video sections.
118
+ public let videos: [Video]
119
+
120
+ /// The duration in milliseconds.
121
+ public let duration: Double
122
+
123
+ /// Creates a new `Recording` instance.
124
+ /// - Parameters:
125
+ /// - videos: The individual video sections.
126
+ /// - duration: The duration in milliseconds.
127
+ public init(videos: [Video], duration: Double) {
128
+ self.videos = videos
129
+ self.duration = duration
130
+ }
131
+
132
+ /// Creates a new `Recording` instance from a `IMGLYCamera.Recording`.
133
+ /// - Parameter recording: The `IMGLYCamera.Recording`.
134
+ public convenience init(recording: IMGLYCamera.Recording) {
135
+ self.init(videos: recording.videos.compactMap { Video(video: $0) }, duration: recording.duration.seconds)
136
+ }
137
+
138
+ func toDictionary() -> [String: Any] {
139
+ [
140
+ "videos": videos.compactMap { $0.toDictionary() },
141
+ "duration": duration,
142
+ ]
143
+ }
144
+ }
145
+
146
+ /// An individual video.
147
+ @objc @objcMembers public class Video: NSObject {
148
+ /// The `URL` to the source of the video.
149
+ public let url: URL
150
+
151
+ /// The height of the video.
152
+ public let rect: CGRect
153
+
154
+ /// Creates a new `Video`.
155
+ /// - Parameters:
156
+ /// - url: The `URL` to the source of the video.
157
+ /// - height: The height of the video.
158
+ /// - width: The width of the video.
159
+ public init(url: URL, rect: CGRect) {
160
+ self.url = url
161
+ self.rect = rect
162
+ }
163
+
164
+ /// Creates a new `Video` instance from a `IMGLYCamera.Recording.Video`.
165
+ /// - Parameter recording: The `IMGLYCamera.Recording.Video`.
166
+ public convenience init(video: IMGLYCamera.Recording.Video) {
167
+ self.init(url: video.url, rect: video.rect)
168
+ }
169
+
170
+ func toDictionary() -> [String: Any] {
171
+ [
172
+ "uri": url.absoluteString,
173
+ "rect": [
174
+ "x": rect.origin.x,
175
+ "y": rect.origin.y,
176
+ "width": Double(rect.width),
177
+ "height": Double(rect.height),
178
+ ],
179
+ ]
180
+ }
181
+ }
@@ -0,0 +1,24 @@
1
+ /// A struct containing all necessary settings to setup the camera.
2
+ @objc @objcMembers public class CameraSettings: NSObject, Codable {
3
+ /// The license key.
4
+ public let license: String
5
+
6
+ /// The id of the current user.
7
+ public let userId: String?
8
+
9
+ /// Creates a new instance from a given dictionary.
10
+ ///
11
+ /// - Parameters:
12
+ /// - dictionary: The dictionary to convert the instance from.
13
+ /// - Returns: The `CameraSettings` instance.
14
+ public static func fromDictionary(_ dictionary: [String: Any]) -> CameraSettings? {
15
+ do {
16
+ let data = try JSONSerialization.data(withJSONObject: dictionary, options: [])
17
+ let settings = try JSONDecoder().decode(CameraSettings.self, from: data)
18
+ return settings
19
+ } catch {
20
+ print("Error decoding dictionary: \(error)")
21
+ return nil
22
+ }
23
+ }
24
+ }
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@imgly/camera-react-native",
3
+ "version": "1.40.0",
4
+ "description": "Camera SDK for React Native - provide a versatile video camera to your users on iOS and Android.",
5
+ "react-native": "index.js",
6
+ "source": "index.js",
7
+ "types": "index.d.ts",
8
+ "files": [
9
+ "src",
10
+ "android",
11
+ "ios",
12
+ "IMGLYCameraModule.podspec",
13
+ "index.d.ts",
14
+ "index.js",
15
+ "README.md",
16
+ "LICENSE.md",
17
+ "!android/build",
18
+ "!ios/build",
19
+ "!**/__tests__",
20
+ "!**/__fixtures__",
21
+ "!**/__mocks__"
22
+ ],
23
+ "keywords": [
24
+ "react-native",
25
+ "ios",
26
+ "android",
27
+ "camera",
28
+ "imgly",
29
+ "cesdk"
30
+ ],
31
+ "author": "IMG.LY GmbH",
32
+ "license": "SEE LICENSE IN LICENSE.md",
33
+ "homepage": "https://img.ly",
34
+ "peerDependencies": {
35
+ "react": "*",
36
+ "react-native": "*"
37
+ },
38
+ "codegenConfig": {
39
+ "name": "IMGLYCameraModuleSpec",
40
+ "type": "modules",
41
+ "jsSrcsDir": "./",
42
+ "android": {
43
+ "javaPackageName": "ly.img.camera.reactnative.module"
44
+ }
45
+ }
46
+ }
@@ -0,0 +1,191 @@
1
+ import { TurboModule, TurboModuleRegistry } from 'react-native';
2
+
3
+ /**
4
+ * A recording of the camera that can
5
+ * contain multiple videos.
6
+ */
7
+ export interface Recording {
8
+ /** The individual videos of the recording. */
9
+ videos: Video[];
10
+
11
+ /** The overall duration in milliseconds. */
12
+ duration: number;
13
+ }
14
+
15
+ /** An individual video. */
16
+ export interface Video {
17
+ /**
18
+ * A url to the video file that is stored
19
+ * in a temporary location.
20
+ */
21
+ uri: string;
22
+
23
+ /**
24
+ * A rect that contains the position of
25
+ * each video as it was shown in the
26
+ * camera preview (iOS only).
27
+ */
28
+ rect: Rect;
29
+ }
30
+
31
+ /**
32
+ * A rect used to determine video
33
+ * dimensions on the canvas.
34
+ */
35
+ export interface Rect {
36
+ /** The x coordinate of the top-left corner. */
37
+ x: number;
38
+
39
+ /** The y coordinate of the top-left corner. */
40
+ y: number;
41
+
42
+ /** The width. */
43
+ width: number;
44
+
45
+ /** The height. */
46
+ height: number;
47
+ }
48
+
49
+ /** The result for a default camera recording session. */
50
+ interface CameraRecording {
51
+ /** The recorded videos. */
52
+ recordings: Recording[];
53
+ }
54
+
55
+ /** The result for a reaction camera recording session. */
56
+ interface CameraReaction {
57
+ /** The video that was reacted to (iOS only). */
58
+ video: Recording;
59
+
60
+ /** The recorded videos. */
61
+ recordings: Recording[];
62
+ }
63
+
64
+ /** The result of a camera session. */
65
+ interface CameraResult {
66
+ /** The video that was reacted to (iOS only). */
67
+ recording?: CameraRecording;
68
+
69
+ /** The recorded videos. */
70
+ reaction?: CameraReaction;
71
+
72
+ /** The associated metadata. */
73
+ metadata: { [key: string]: unknown };
74
+ }
75
+
76
+ /** A class containing all necessary settings to setup the camera. */
77
+ export interface CameraSettings {
78
+ /** The license of the editor. */
79
+ license: string;
80
+
81
+ /**
82
+ * Unique ID tied to your application's user.
83
+ * This helps us accurately calculate monthly
84
+ * active users (MAU).
85
+ */
86
+ userId?: string;
87
+ }
88
+
89
+ /** TurboModule Spec. */
90
+ interface Spec extends TurboModule {
91
+ /**
92
+ * Open the Camera.
93
+ * @param settings The `CameraSettings`.
94
+ * @param video The video to react to (iOS only).
95
+ * @param metadata The metadata to pass to the native module.
96
+ */
97
+ openCamera(
98
+ settings: CameraSettings,
99
+ video?: string,
100
+ metadata?: { [key: string]: unknown }
101
+ ): Promise<CameraResult | null>;
102
+ }
103
+
104
+ /** The native module. */
105
+ const NativeModule = TurboModuleRegistry.get<Spec>(
106
+ 'IMGLYCamera'
107
+ ) as Spec | null;
108
+
109
+ /** The result for a default camera recording session. */
110
+ export interface CameraRecordingResult {
111
+ /** The recorded videos. */
112
+ recordings: Recording[];
113
+
114
+ /** The associated metadata. */
115
+ metadata: { [key: string]: unknown };
116
+ }
117
+
118
+ /** The result for a reaction camera recording session. */
119
+ export interface CameraReactionResult {
120
+ /** The video that was reacted to (iOS only). */
121
+ video: Recording;
122
+
123
+ /** The recorded videos. */
124
+ recordings: Recording[];
125
+
126
+ /** The associated metadata. */
127
+ metadata: { [key: string]: unknown };
128
+ }
129
+
130
+ /** The IMG.LY Camera. */
131
+ class IMGLYCamera {
132
+ /**
133
+ * Opens the camera for reaction mode (iOS only).
134
+ * @param settings - Configuration settings for the camera.
135
+ * @param video - Optional video input to trigger reactions.
136
+ * @param metadata - Optional metadata to pass to the native module.
137
+ * @returns A promise that resolves to the reaction result, or null if cancelled.
138
+ */
139
+ static async openCamera(
140
+ settings: CameraSettings,
141
+ video: string,
142
+ metadata?: { [key: string]: unknown }
143
+ ): Promise<CameraReactionResult | null>;
144
+
145
+ /**
146
+ * Opens the standard camera.
147
+ * @param settings - Configuration settings for the camera.
148
+ * @param metadata - Optional metadata to pass to the native module.
149
+ * @returns A promise that resolves to the recording result, or null if cancelled.
150
+ */
151
+ static async openCamera(
152
+ settings: CameraSettings,
153
+ metadata?: { [key: string]: unknown }
154
+ ): Promise<CameraRecordingResult | null>;
155
+
156
+ /**
157
+ * Opens the camera with the specified settings and optional video or metadata.
158
+ * @param settings - Configuration settings for the camera.
159
+ * @param video - Optional video input to trigger reactions (iOS only) or metadata object.
160
+ * @param metadata - Optional metadata to pass to the native module.
161
+ * @returns A promise that resolves to either the recording result, reaction result, or null if unsuccessful.
162
+ */
163
+ static async openCamera(
164
+ settings: CameraSettings,
165
+ video?: string | { [key: string]: unknown },
166
+ metadata: { [key: string]: unknown } = {}
167
+ ): Promise<CameraRecordingResult | CameraReactionResult | null> {
168
+ if (!NativeModule) return null;
169
+ const videoInput = typeof video === 'string' ? video : undefined;
170
+ const metadataInput =
171
+ typeof video === 'object' && video !== null ? video : metadata;
172
+ const result = await NativeModule.openCamera(
173
+ settings,
174
+ videoInput,
175
+ metadataInput
176
+ );
177
+ if (result?.reaction) {
178
+ const { video, recordings } = result.reaction;
179
+ return { video, recordings, metadata: result.metadata };
180
+ }
181
+ if (result?.recording) {
182
+ return {
183
+ recordings: result.recording.recordings,
184
+ metadata: result.metadata
185
+ };
186
+ }
187
+ return null;
188
+ }
189
+ }
190
+
191
+ export default IMGLYCamera;