Camera
#Overview
The Camera API provides access to the device's camera for taking photos, recording videos, and selecting media from the gallery.
use Native\Mobile\Facades\Camera;
import { camera, on, off, Events } from '#nativephp';
#Methods
#getPhoto()
Opens the camera interface to take a photo.
Camera::getPhoto();
// Basic usageawait camera.getPhoto(); // With identifier for trackingawait camera.getPhoto() .id('profile-pic');
#recordVideo()
Opens the camera interface to record a video with optional configuration.
Parameters:
array $options- Optional recording options (default:[])
Returns: PendingVideoRecorder - Fluent interface for configuring video recording
// Basic video recordingCamera::recordVideo(); // With maximum duration (30 seconds)Camera::recordVideo(['maxDuration' => 30]); // Using fluent APICamera::recordVideo() ->maxDuration(60) ->id('my-video-123') ->start();
// Basic video recordingawait camera.recordVideo(); // With maximum durationawait camera.recordVideo() .maxDuration(60); // With identifier for trackingawait camera.recordVideo() .maxDuration(30) .id('my-video-123');
#pickImages()
Opens the gallery/photo picker to select existing images.
Parameters:
string $media_type- Type of media to pick:'all','images','videos'(default:'all')bool $multiple- Allow multiple selection (default:false)
Returns: bool - true if picker opened successfully
// Pick a single imageCamera::pickImages('images', false); // Pick multiple imagesCamera::pickImages('images', true); // Pick any media typeCamera::pickImages('all', true);
// Pick images using fluent APIawait camera.pickImages() .images() .multiple() .maxItems(5); // Pick only videosawait camera.pickImages() .videos() .multiple(); // Pick any media typeawait camera.pickImages() .all() .multiple() .maxItems(10); // Single image selectionawait camera.pickImages() .images();
#PendingVideoRecorder
The fluent API returned by recordVideo() provides several methods for configuring video recording:
#maxDuration(int $seconds)
Set the maximum recording duration in seconds.
Camera::recordVideo() ->maxDuration(30) ->start();
#id(string $id)
Set a unique identifier for this recording to correlate with events.
Camera::recordVideo() ->id('user-upload-video') ->start();
#getId()
Get the recorder's unique identifier (auto-generates UUID if not set).
$recorder = Camera::recordVideo();$id = $recorder->getId(); // Returns UUID
#event(string $eventClass)
Set a custom event class to dispatch when recording completes.
Camera::recordVideo() ->event(MyCustomVideoEvent::class) ->start();
#remember()
Store the recorder's ID in the session for later retrieval.
Camera::recordVideo() ->remember() ->start(); // Later, in your event handler$recorderId = PendingVideoRecorder::lastId();
#start()
Explicitly start the video recording. If not called, recording starts automatically.
Camera::recordVideo() ->maxDuration(60) ->start();
#Events
#PhotoTaken
Fired when a photo is taken with the camera.
Payload: string $path - File path to the captured photo
use Native\Mobile\Attributes\OnNative;use Native\Mobile\Events\Camera\PhotoTaken; #[OnNative(PhotoTaken::class)]public function handlePhotoTaken(string $path){ // Process the captured photo $this->processPhoto($path);}
import { on, off, Events } from '#nativephp';import { ref, onMounted, onUnmounted } from 'vue'; const photoPath = ref(''); const handlePhotoTaken = (payload) => { photoPath.value = payload.path; processPhoto(payload.path);}; onMounted(() => { on(Events.Camera.PhotoTaken, handlePhotoTaken);}); onUnmounted(() => { off(Events.Camera.PhotoTaken, handlePhotoTaken);});
import { on, off, Events } from '#nativephp';import { useState, useEffect } from 'react'; const [photoPath, setPhotoPath] = useState(''); const handlePhotoTaken = (payload) => { setPhotoPath(payload.path); processPhoto(payload.path);}; useEffect(() => { on(Events.Camera.PhotoTaken, handlePhotoTaken); return () => { off(Events.Camera.PhotoTaken, handlePhotoTaken); };}, []);
#VideoRecorded
Fired when a video is successfully recorded.
Payload:
string $path- File path to the recorded videostring $mimeType- Video MIME type (default:'video/mp4')?string $id- Optional identifier if set viaid()method
use Native\Mobile\Attributes\OnNative;use Native\Mobile\Events\Camera\VideoRecorded; #[OnNative(VideoRecorded::class)]public function handleVideoRecorded(string $path, string $mimeType, ?string $id = null){ // Process the recorded video $this->processVideo($path); // Check if this is the video we're expecting if ($id === 'my-upload-video') { $this->uploadVideo($path); }}
import { on, off, Events } from '#nativephp';import { ref, onMounted, onUnmounted } from 'vue'; const videoPath = ref(''); const handleVideoRecorded = (payload) => { const { path, mimeType, id } = payload; videoPath.value = path; processVideo(path); if (id === 'my-upload-video') { uploadVideo(path); }}; onMounted(() => { on(Events.Camera.VideoRecorded, handleVideoRecorded);}); onUnmounted(() => { off(Events.Camera.VideoRecorded, handleVideoRecorded);});
import { on, off, Events } from '#nativephp';import { useState, useEffect } from 'react'; const [videoPath, setVideoPath] = useState(''); const handleVideoRecorded = (payload) => { const { path, mimeType, id } = payload; setVideoPath(path); processVideo(path); if (id === 'my-upload-video') { uploadVideo(path); }}; useEffect(() => { on(Events.Camera.VideoRecorded, handleVideoRecorded); return () => { off(Events.Camera.VideoRecorded, handleVideoRecorded); };}, []);
#VideoCancelled
Fired when video recording is cancelled by the user.
Payload:
bool $cancelled- Alwaystrue?string $id- Optional identifier if set viaid()method
use Native\Mobile\Attributes\OnNative;use Native\Mobile\Events\Camera\VideoCancelled; #[OnNative(VideoCancelled::class)]public function handleVideoCancelled(bool $cancelled, ?string $id = null){ // Handle cancellation $this->notifyUser('Video recording was cancelled');}
import { on, off, Events } from '#nativephp';import { onMounted, onUnmounted } from 'vue'; const handleVideoCancelled = (payload) => { notifyUser('Video recording was cancelled');}; onMounted(() => { on(Events.Camera.VideoCancelled, handleVideoCancelled);}); onUnmounted(() => { off(Events.Camera.VideoCancelled, handleVideoCancelled);});
import { on, off, Events } from '#nativephp';import { useEffect } from 'react'; const handleVideoCancelled = (payload) => { notifyUser('Video recording was cancelled');}; useEffect(() => { on(Events.Camera.VideoCancelled, handleVideoCancelled); return () => { off(Events.Camera.VideoCancelled, handleVideoCancelled); };}, []);
#MediaSelected
Fired when media is selected from the gallery.
Payload: array $media - Array of selected media items
use Native\Mobile\Attributes\OnNative;use Native\Mobile\Events\Gallery\MediaSelected; #[OnNative(MediaSelected::class)]public function handleMediaSelected($success, $files, $count){ foreach ($files as $file) { // Process each selected media item $this->processMedia($file); }}
import { on, off, Events } from '#nativephp';import { ref, onMounted, onUnmounted } from 'vue'; const selectedFiles = ref([]); const handleMediaSelected = (payload) => { const { success, files, count } = payload; if (success) { selectedFiles.value = files; files.forEach(file => processMedia(file)); }}; onMounted(() => { on(Events.Gallery.MediaSelected, handleMediaSelected);}); onUnmounted(() => { off(Events.Gallery.MediaSelected, handleMediaSelected);});
import { on, off, Events } from '#nativephp';import { useState, useEffect } from 'react'; const [selectedFiles, setSelectedFiles] = useState([]); const handleMediaSelected = (payload) => { const { success, files, count } = payload; if (success) { setSelectedFiles(files); files.forEach(file => processMedia(file)); }}; useEffect(() => { on(Events.Gallery.MediaSelected, handleMediaSelected); return () => { off(Events.Gallery.MediaSelected, handleMediaSelected); };}, []);
#Storage Locations
Media files are stored in different locations depending on the platform:
Photos:
- Android: App cache directory at
{cache}/captured.jpg - iOS: Application Support at
~/Library/Application Support/Photos/captured.jpg
Videos:
- Android: App cache directory at
{cache}/video_{timestamp}.mp4 - iOS: Application Support at
~/Library/Application Support/Videos/captured_video_{timestamp}.mp4
Important Notes:
- Android stores media in the cache directory (temporary, can be cleared by system)
- iOS stores media in Application Support (persistent, excluded from backups)
- iOS photo captures use a fixed filename
captured.jpg(overwrites previous) - iOS/Android videos use timestamped filenames (don't overwrite)
#Notes
- Permissions: You must enable the
camerapermission inconfig/nativephp.phpto use camera features. Once enabled, camera permissions are handled automatically on both platforms, and users will be prompted for permission the first time your app requests camera access. - If permission is denied, camera functions will fail silently
- Camera permission is required for photos, videos, AND QR/barcode scanning
- File formats: JPEG for photos, MP4 for videos (platform-dependent)
- Video quality and camera selection are controlled by the native camera app