Snapshots and recording
Install ScreenCapture, choose an upload provider, and configure snapshots, clips, and the saved video library.
GapCam takes snapshots through Discord and records clips through Discord, FiveManage, or Qbox CDN. ScreenCapture supplies the capture service through 402studio_bridge.
Install ScreenCapture
- Download the packaged resource from the ScreenCapture v0.17.2 release or a newer stable release.
- Extract it into your server's resources folder as
screencapture. Keep itsfxmanifest.luadirectly inside that folder. - Use ScreenCapture v0.17.2 or newer for video recording. GapCam requires the server exports
remoteUploadfor snapshots andstartVideoCaptureUploadfor clips. Both appear in the v0.17.2 export source. - Configure the bridge's capture adapter in its
config.lua:
Capture = { adapter = 'screencapture', resource = 'screencapture' },Keep that entry inside the bridge's existing Config table. If you rename ScreenCapture's resource folder, update resource to match.
Start your configured framework, inventory, target, and other bridge dependencies first. Then start the capture service, bridge, and GapCam in this order:
ensure oxmysql
ensure screencapture
ensure 402studio_bridge
ensure 402studio_gapcamGapCam also requires OneSync. Follow installation for the remaining dependencies and items.
Bridge resource access
The supplied 402studio_gapcam resource passes the bridge's first-party access check through its resource name and manifest author. A renamed resource needs an explicit allowlist entry:
set 402studio_bridge:allowedResources "your_gapcam_resource"Set this before starting the bridge. Preserve any existing allowed resources in the same value, separated by spaces or commas. See bridge resource access.
Choose a clip provider
Set Config.Video.Provider in GapCam's config.lua:
| Value | Destination | Required server setting |
|---|---|---|
discord | Discord webhook | gapcam_webhook and Config.Discord.Enabled = true |
fivemanage | FiveManage CDN | 402studio_bridge:fivemanageKey |
qbox | Qbox CDN | 402studio_bridge:qboxKey |
The supplied default is qbox. Set its CDN key or choose another provider before recording clips. Selecting the Qbox framework in the bridge and selecting Qbox CDN are separate settings.
Config.Video.Enabled controls clips. Config.Discord.Enabled controls snapshots and permits the Discord clip destination. For CDN clips, Config.Video.Enabled = true is sufficient alongside the matching CDN key and capture service.
Discord snapshots and clips
Create a webhook for the destination channel in Discord's channel settings under Integrations, then copy its webhook URL. The account creating the webhook needs permission to manage webhooks for that channel.
Store the URL in your private server configuration before the resource start lines:
set gapcam_webhook "https://discord.com/api/webhooks/WEBHOOK_ID/WEBHOOK_TOKEN"Use set for secrets so they stay server-only. Keep webhook URLs and API keys in private configuration, including when sharing logs or asking for support.
For snapshots, enable:
Config.Discord.Enabled = trueFor clips sent to the same webhook, also set:
Config.Video.Enabled = true
Config.Video.Provider = 'discord'GapCam accepts HTTPS Discord webhook URLs on discord.com, discordapp.com, or their supported subdomains. It adds wait=true when needed to read the uploaded attachment response.
Snapshots upload the image, then post an embed with the recorder, plate, recording time, vehicle position, and other vehicle occupants. Discord clips upload the file, then post the recorder, plate, duration, position, and other occupants. Config.Discord.Username sets the message name. Mentions are disabled.
FiveManage and Qbox CDN clips
Use Bridge 1.2.1 or newer with its included CDN adapters. Create a key in FiveManage or the Qbox dashboard. Enable video uploads and grant access to the intended storage folder, where the provider offers folder permissions. Check the account's upload and storage limits.
Set the matching key before starting the bridge:
set 402studio_bridge:fivemanageKey "YOUR_FIVEMANAGE_KEY"Or, for Qbox:
set 402studio_bridge:qboxKey "YOUR_QBOX_CDN_KEY"Choose that provider in GapCam:
Config.Video.Enabled = true
Config.Video.Provider = 'fivemanage'
Config.Video.LibraryEnabled = trueUse 'qbox' for Qbox CDN. The bridge uses the key in a server request to obtain a temporary upload URL. Presigned requests time out after 10 seconds. The FiveManage adapter requests an upload URL that expires after five minutes. See CDN uploads for the bridge's provider settings and error codes.
Record a snapshot or clip
Install a camera, select it in the vehicle menu, and open its live view with the menu action or B. Wait for the camera view to appear, then press N for a snapshot or M for a clip.
The live view starts the camera session and its timer. Press M to start an actual video capture and upload.
| Action | Command | Default key |
|---|---|---|
| Open the vehicle camera menu | /gapcam | Use the configured target interaction |
| Toggle camera view | /gapcamview | B |
| Take a snapshot | /gapcamsnap | N |
| Record a clip | /gapcamclip | M |
| Toggle horizon lock | /gapcamhorizon | H |
| Open saved CDN clips | /gapcamvideos | Choose Saved clips in the menu |
Keys come from Config.Recording.ViewKey, Config.Recording.HorizonKey, Config.Discord.SnapKey, and Config.Video.ClipKey. Players can change registered bindings in FiveM's key binding settings.
Capture uses the selected camera view. If the view is closed, GapCam opens it for the capture, then closes it afterward. If it is already open, GapCam keeps that view open. Keep the camera and vehicle available until capture finishes.
Config.Cameraman.PassengerOnly = false allows the driver to operate captures. Set it to true to require a passenger when operating from the vehicle. Config.Cameraman.NotifyDriver controls driver notifications.
Capture output and limits
Snapshots upload an image to Discord. Clips use ScreenCapture's VP9 WebM encoder. The v0.17.2 capture implementation uses 30 FPS and its medium quality preset. Clip size varies with scene movement and detail. Change duration and capture bounds to reduce upload size.
ScreenCapture reads the game framebuffer. GapCam's viewfinder labels, recording indicator, speed, and other browser overlays are shown through NUI, separately from the captured game image. The video encoder records a video track. Use the resulting game footage as the capture output.
HideHud = true hides GTA's HUD and radar during the capture. Config.Recording.Overlay controls the viewfinder shown to the player. Keep these settings separate when checking the player view and the uploaded file.
| Setting | Default | Accepted value |
|---|---|---|
Config.Discord.Width | 1280 | Clamped to 320 through 1920 pixels |
Config.Discord.Height | 720 | Clamped to 240 through 1080 pixels |
Config.Discord.Quality | 0.85 | Clamped to 0.1 through 1.0 |
Config.Discord.Cooldown | 10 | Seconds, minimum 1 |
Config.Discord.SnapshotTimeout | 45000 | Milliseconds, minimum 5000 |
Config.Discord.HideHud | true | Boolean |
Config.Video.Seconds | 10 | Whole seconds, clamped to 1 through 60 |
Config.Video.Width | 1280 | Whole pixels, clamped to 320 through 1920 |
Config.Video.Height | 720 | Whole pixels, clamped to 240 through 1080 |
Config.Video.Cooldown | 10 | Seconds, minimum 1 |
Config.Video.HideHud | true | Boolean |
Width and height are maximum bounds. ScreenCapture preserves the player's aspect ratio and scales down to fit. Actual output can be smaller. The library records the requested bounds with each clip.
Snapshots and clips share the player's capture cooldown. Each uses its own active-operation lock. A video request also has a server timeout of the configured clip duration plus 60 seconds. After recording, the client waits up to 60 seconds for the upload result.
Saved clips
Enable Config.Video.Enabled and Config.Video.LibraryEnabled, with fivemanage or qbox selected. /gapcamvideos and Saved clips open a compact panel with playback, copy link, refresh, and older clips. Press Escape to close it.
The server creates 402studio_gapcam_videos through oxmysql when the CDN library is enabled. The database account needs permission to create the table, insert clips, and read them. Each player's records use their server-verified license identifier, with license2 as a fallback. Saved records survive reconnects and resource restarts. Records from both included CDN providers appear together for that player.
Clips load newest first, 24 per page. The panel must be closed before capture starts. Close camera view, placement, and any active capture before opening the panel.
With LibraryEnabled = false, CDN uploads still complete and the provider stores the file. Enable the library to keep new clip records available through the player panel. Discord clips remain available in their destination channel. Hosted file availability follows the provider's storage and retention settings.
Troubleshooting
| Message or error | Check and fix |
|---|---|
| Snapshot or clip command does nothing | Check the relevant Enabled flag and allow the current capture to finish. Check the player's FiveM key bindings. |
snap_not_rec | Select an installed camera and open its live view before taking a snapshot or clip. |
snap_no_res | Start the configured capture resource. Check Config.Capture.resource, the screencapture adapter, the server's remoteUpload export, and bridge resource access. |
clip_no_video | Use ScreenCapture v0.17.2 or newer with startVideoCaptureUpload. Check resource state, bridge capture configuration, and resource access. |
snap_no_hook | Set a valid HTTPS Discord webhook with set gapcam_webhook, then restart GapCam after configuration changes. |
clip_cdn_unavailable | Check the provider name, matching key convar, Bridge 1.2.1 or newer, key permissions, provider account limits, and outbound HTTPS access. The default provider is qbox. |
snap_cooldown | Wait for the configured snapshot or clip cooldown. Both actions share one player cooldown. |
clip_busy | Wait for the active video capture and upload to finish. |
clip_passenger | Use a passenger to operate the camera, or set Config.Cameraman.PassengerOnly = false. |
too_far | Return to the camera's vehicle and the same routing bucket. |
snap_failed | Check ScreenCapture logs, the webhook, upload limits, and SnapshotTimeout. Keep the vehicle and installed camera available during the upload. |
clip_failed | Check ScreenCapture's server and client logs, encoder support, upload limits, and destination settings. Keep the vehicle and camera available until completion. |
clip_library_failed | The clip uploaded, but its library record failed. Check oxmysql, database availability, and permissions for 402studio_gapcam_videos. The hosted upload may already exist. |
library.unavailable | Enable video and the library, then select a CDN provider. |
library.busy | Close the saved clips panel before capturing. Close camera view, placement, or the current capture before opening the panel. |
library.load_failed | Check database logs and the player's license identifier. Wait briefly before retrying; library requests have a 750 ms limit. |
Video library database is unavailable. | Restore database connectivity and table permissions, then restart GapCam to retry table setup. |
snapshot embed rejected: HTTP ... | Check the webhook's channel, HTTP status, and Discord limits. Image upload and embed posting are separate requests. |
| Clip appears in the library but playback fails | Check the hosted URL, provider retention, file availability, and browser support for VP9 WebM. |
ScreenCapture describes video recording as experimental. Its encoder depends on WebCodecs support in FiveM's Chromium build. Test a short clip on your server build. A tiny or empty file can indicate an encoder failure; check the player's F8 console as well as server logs.
For a support report, include GapCam, bridge, and ScreenCapture versions; the FiveM server build; chosen provider; exact error text; redacted server and F8 logs; capture dimensions and duration; and whether snapshots, clips, or library playback fail. Include the time of the test and steps to reproduce it. Remove webhook tokens, API keys, temporary upload URLs, and player identifiers before sharing.