Camera and video creation in the Genuin SDK
Record, import, edit, and post video from inside your app with the Genuin camera modules, and control who can create from Brand Control Center.
Members create posts without leaving your app. They record clips with the device camera or import a video from the gallery, trim and decorate it, and post it to a group in your community. Creation ships as a separate module on Android and iOS, so an app that only shows feeds doesn't carry the video toolchain. The Web SDK has no camera; on the web, members create posts on your community site by uploading a file.
Creation needs a signed-in member. A guest who taps a create action is asked to sign in first. See Choose how members sign in to the Genuin SDK.
Modules
| Platform | Module | Install | Adds | Requires |
|---|---|---|---|---|
| Android | Camera | com.begenuin:camera:2.1.5 (48 MB AAR) | Recording, gallery import, trimmer, editor, post screen, and the background upload service | core, ui |
| iOS | GenuinCamera | pod "GenuinCamera" from https://bitbucket.org/genuindev/genuin_sdk_ios.git, tag 2.1.5 | Recording, gallery import, editor, post screen, and the upload manager | GenuinCore, GenuinUI |
| Web | None | — | The Web SDK renders feeds only. Your community site's Create page accepts an uploaded MP4 or WebM file. | — |
On Android, Core finds the Camera module at runtime. Without it, a tap on a create action shows your brand's unsupported-feature message as a toast. On iOS, register the module once at launch, after the core SDK:
import GenuinCore
import GenuinCamera
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
GenuinSDK.shared.initialize(apiKey: "{{API_KEY}}")
GenuinCamera.shared.initialize() // registers the camera with Core
return true
}Without GenuinCamera.shared.initialize(), the create actions on iOS return without opening anything.
The camera opens from the create button in feeds and from the reply and video-comment actions. iOS also exposes a direct entry point that signs the member in with your token and presents the camera full screen:
GenuinSDK.shared.initiateCreatePost(
fromVC: self,
ssoToken: "{{SSO_TOKEN}}",
params: ["name": "John Doe", "email": "john.doe@example.com"] // optional
)Permissions
The modules don't declare the camera, microphone, or media permissions themselves. Your app declares them, and the SDK checks for the declaration before it opens a camera or gallery screen, then requests access from the member at runtime.
Android
Add the permissions to your AndroidManifest.xml. The Camera module's own manifest declares none of them, and Core declares only INTERNET, ACCESS_NETWORK_STATE, VIBRATE, and WAKE_LOCK.
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />| Permission | Needed for | Without the declaration |
|---|---|---|
| android.permission.CAMERA | Recording clips, profile and community photos, link thumbnails | Create actions show the unsupported-feature toast and log a camera-access-denied event |
| android.permission.RECORD_AUDIO | Audio on recordings, voice comments, on-device transcripts | Same as above; the SDK checks CAMERA and RECORD_AUDIO together before opening the camera |
| android.permission.READ_MEDIA_VIDEO | Gallery import on Android 13 (API 33) and later | The gallery button shows the toast and logs a gallery-access-denied event |
| android.permission.READ_EXTERNAL_STORAGE with android:maxSdkVersion="32" | Gallery import on Android 12 and lower | Same as above on those versions |
| android.permission.WRITE_EXTERNAL_STORAGE | Optional. Saving the finished video to the device from the preview screen on Android 9 and lower | The save button asks for the permission and skips the save if it's denied |
At runtime the SDK requests CAMERA and RECORD_AUDIO together when the camera opens, and the media permission when the member taps the gallery. A member who denies them sees the SDK's permission screen with a Settings button; your app doesn't need its own prompt.
iOS
Add the usage descriptions to your app's Info.plist. Before opening a picker or camera, the SDK checks Bundle.main for the key and, when it's missing, shows your brand's unsupported-feature alert instead of crashing. iOS itself terminates an app that accesses the camera or microphone without the key.
<key>NSCameraUsageDescription</key>
<string>Genuin needs permissions to open your camera and microphone. This allows Genuin to record videos that can be shared with other people.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Genuin needs permissions to open your camera and microphone. This allows Genuin to record videos that can be shared with other people.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Genuin needs permissions to access your photo library. This allows Genuin to download videos to your phone and save it to your library.</string>
<key>NSSpeechRecognitionUsageDescription</key>
<string>The transcript of your recording will be displayed to you in the end for you to overlay it on the audio message.</string>| Info.plist key | Needed for | Requested with |
|---|---|---|
| NSCameraUsageDescription | Recording clips and video comments | AVCaptureDevice.requestAccess(for: .video) when the camera opens |
| NSMicrophoneUsageDescription | Audio on recordings and voice comments | AVCaptureDevice.requestAccess(for: .audio) when the camera opens |
| NSPhotoLibraryUsageDescription | Gallery import, cover images from Photos, saving videos | PHPhotoLibrary.requestAuthorization when the member opens the camera roll; limited access is accepted |
| NSSpeechRecognitionUsageDescription | The transcript shown after an audio recording | SFSpeechRecognizer authorization when the member records audio |
Replace the strings with your own wording; the ones above are Genuin's defaults. NSContactsUsageDescription, NSLocationWhenInUseUsageDescription, and NSUserTrackingUsageDescription belong to other features and are covered in the iOS SDK guide.
Web
No browser permission is involved. The community site's Create page takes an existing file through a drop zone and never opens the camera or microphone, so there's no getUserMedia prompt.
Recording and upload limits
| Limit | Android | iOS | Web (community site) |
|---|---|---|---|
| Post length, maximum | 300 seconds across all clips | 300 seconds across all clips | 300 seconds |
| Post length, minimum | 4 seconds | Not enforced; the record button re-enables 1 second after it starts | 4 seconds |
| Clips per post | No fixed count; the clips add up to the 300-second cap | Same | One file |
| Gallery import | Trimmed to 300 seconds in the import editor | Same | Rejected over 300 seconds |
| Video comment | 120 seconds | 120 seconds | — |
| Audio comment | — | 120 seconds | — |
| Recording speed | 1x, 2x, 4x | 1x, 2x | — |
| Countdown | 3 or 10 seconds, with a stop-recording-after timer | 3 seconds, with a stop-recording-after timer in 0.05-second steps | — |
| Capture | 1280x720 when the camera offers it, otherwise the first 1920-wide size; H.264 video and AAC audio at the device's QUALITY_HIGH bit rate and frame rate | AVCaptureSession preset 1280x720; export preset 1280x720 | — |
| Output | Portrait MP4 merged with FFmpeg to the size that matches the screen ratio: 640x960, 688x1220 (16:9), 720x1354 (17:9), 736x1472 (18:9), 760x1604 (19:9), or 800x1776 (20:9) | Portrait MP4 | Uploaded as-is |
| File size | No client-side cap; the upload reports the size as video_size | No client-side cap | 2 GB, MP4 or WebM, 9:16 aspect ratio |
| Description | 2,000 characters | Not verified | Not verified |
The merge step scales each clip to the output size and pads it rather than cropping, so a landscape import keeps its full frame with bars above and below.
Editing tools
| Tool | Android | iOS |
|---|---|---|
| Trim, reorder, retake, and delete clips | Trimmer with a frame strip, edit-clips and delete-clip actions on the camera | Gallery video editor and clip editor with an add-clip cell while the total is under 300 seconds |
| Text overlay | Eight fonts, colours, a transparent, white, or black background, and left, centre, or right alignment | Same eight fonts: Inter (two styles), Bebas Neue, Courier Prime, Scope One, Lora, Varela Round, Nunito |
| Stickers | GIPHY picker with Recents, Stickers, Text, and Emoji tabs | Same picker, draggable |
| Question overlay | For Q&A posts: pick, shuffle, add, or edit a question | Question editor and draggable question view |
| Link card | Preview of a shared link on the video | Draggable link view |
| Cover image | Pick a frame as the thumbnail, or change it later | Cover image selection |
| Transcript | On-device speech-to-text shown under audio-only posts | Apple speech recognition shown after an audio recording |
| Post screen | Description with @mentions, cover, add link, Post to group picker, privacy | Same fields |
Background music, transitions, and AI-generated captions aren't in version 2.1.5 of either module. Edit videos in the Genuin SDK describes each tool in detail.
Who can create
Three levels decide whether a member sees a create button and where the post can go.
Brand. Three flags on your brand record gate creation everywhere: camera_enabled (default on) shows or hides camera entry points, post_enabled (default on) shows or hides the create button in SDK feeds, and create_post_enabled (default off) shows the Create button on your community site. The Genuin team sets them; there's no screen for them in Brand Control Center.
Community. In Brand Control Center, go to Manage > Communities, open the community, and under Who can create Groups choose All community members or Admins. The same choice appears when you create a community.
Group. Posts always belong to a group. Go to Manage > Groups, open the group, and set its two access options. The choices depend on the community's privacy:
| Community | Who can see this Group | Who can post in this Group |
|---|---|---|
| Public | Everyone (including people without an account) or Group Members only | All community members or Group Members only |
| Private | All community members or Group Members only | All community members or Invite-only (members you invite or approve) |
The SDK's post screen offers the member only the groups they're allowed to post in.
Limitations
- Portrait only: The camera records and exports portrait video; landscape imports are padded, not rotated.
- Module size: The Android Camera module adds about 48 MB before compression because it bundles the FFmpeg toolchain and the on-device speech model.
- No camera on the web: The Web SDK can't record or upload. Creation on the web is the community site's Create page, which takes one MP4 or WebM file of 4 to 300 seconds and up to 2 GB.
- Permissions are yours to declare: The SDK checks your manifest or
Info.plistand shows the unsupported-feature message when a declaration is missing; it never adds permissions. - Brand flags aren't self-serve:
camera_enabled,post_enabled, andcreate_post_enabledchange through the Genuin team. - No music, transitions, or AI captions in the 2.1.5 camera modules.
- Signed-in members only: Guests are asked to sign in before the camera opens.

