nvrclip exports exact MP4 clips from Dahua and Hikvision NVR recordings without SmartPSS, DSS Express, iVMS, browser plugins, vendor SDKs, or background services.
The basic idea:
.\nvrclip.exe grab "shop cashier" --from "2026-05-06 14:50" --to "2026-05-06 15:20"Output:
shop_cashier_2026-05-06_1450-1520.mp4
- Windows, macOS, or Linux
- Go, if building from source
ffmpegavailable onPATH
On Windows, install FFmpeg with winget:
winget install --id Gyan.FFmpeg -eThen reopen PowerShell and verify:
ffmpeg -versionIf that package is unavailable, try:
winget install --id BtbN.FFmpeg.GPL -eYou can also set NVRCLIP_FFMPEG to the full path of ffmpeg.exe.
Build a local binary:
go run ./tools/build --version 0.1.0The build command updates Windows Program Details metadata, regenerates cmd/nvrclip/resource.syso, and writes nvrclip.exe.
Create nvrclip.toml in the working directory.
base_url can be just an IP address or hostname. nvrclip tries HTTPS first, then HTTP. If your NVR uses a self-signed HTTPS certificate, set insecure_tls = true.
Channels are 1-based, matching the NVR UI.
[shop]
type = "dahua"
base_url = "172.20.32.8"
username = "admin"
password_env = "NVRCLIP_SHOP_PASSWORD"
frame_rate = 25
timeout = "5m"
[shop.channels]
1 = "front-door"
2 = "shop cashier"
[warehouse]
type = "hikvision"
base_url = "10.10.37.5"
username = "admin"
password_env = "NVRCLIP_WAREHOUSE_PASSWORD"
insecure_tls = true
frame_rate = 25
timeout = "30m"
[warehouse.channels]
1 = "loading bay"
2 = "office"Passwords can be stored directly:
password = "your-password"Or pulled from environment variables:
password_env = "NVRCLIP_SHOP_PASSWORD"Set env vars in PowerShell:
$env:NVRCLIP_SHOP_PASSWORD = "your-password"grab is the shorthand form. Use it when the channel alias is globally unique across all configured NVRs and you already know the exact start and end times:
.\nvrclip.exe grab "shop cashier" --from "2026-05-05 14:00" --to "2026-05-05 14:10"This is equivalent to resolving "shop cashier" to its configured NVR and channel, then running the same clip export pipeline as download.
For convenience, grab joins every argument before the first flag into the channel alias. These two commands are equivalent:
.\nvrclip.exe grab "shop cashier" --from "2026-05-05 14:00" --to "2026-05-05 14:10"
.\nvrclip.exe grab shop cashier --from "2026-05-05 14:00" --to "2026-05-05 14:10"download is the explicit form. Use it when you want to name the NVR directly, when the same channel alias exists on more than one NVR, or when you want to use a numeric channel:
.\nvrclip.exe download shop --channel front-door --around "2026-05-05 14:05" --minutes 10Both commands produce a final MP4 by default. Despite the command name, download does not only save raw NVR files unless you pass --download-only.
Use exact start and end times with either command:
.\nvrclip.exe grab "shop cashier" --from "2026-05-05 14:00" --to "2026-05-05 14:10"
.\nvrclip.exe download warehouse --channel office --from "2026-05-05 14:00" --to "2026-05-05 14:10"Use --around with --minutes on download when you want a clip centered on a timestamp:
.\nvrclip.exe download shop --channel front-door --around "2026-05-05 14:05" --minutes 10That example exports 10 minutes total: 5 minutes before and 5 minutes after 2026-05-05 14:05.
Use a channel alias with download:
.\nvrclip.exe download shop --channel front-door --around "2026-05-05 14:05" --minutes 10Use a channel number with download:
.\nvrclip.exe download warehouse --channel 1 --around "2026-05-05 14:05" --minutes 10Use exact H.264 re-encoding for precise cuts and safer joins across mixed NVR parts:
.\nvrclip.exe download shop --channel 1 --from "2026-05-03 22:50" --to "2026-05-03 23:15" --format exactKeep downloaded/intermediate files for debugging:
.\nvrclip.exe download shop --channel 1 --around "2026-05-05 14:05" --minutes 10 --keep-tempDownload only, without producing a final MP4:
.\nvrclip.exe download shop --channel 1 --around "2026-05-05 14:05" --minutes 10 --download-only --keep-tempDahua:
- Searches recording segments through raw CGI.
- Downloads bounded overlapping time ranges where supported.
- Trims/remuxes with FFmpeg.
Hikvision:
- Searches recording segments through ISAPI
ContentMgmt/search. - Downloads matching segment files over HTTP(S).
- Trims each downloaded segment locally by timestamp offset.
- Concatenates the trimmed parts into one MP4.
If one requested clip crosses multiple recording files, nvrclip downloads each matching part and shows progress like:
part 1/2 downloading 2026-05-05 10:59:54 - 2026-05-05 11:00:00
part 1/2 done (3.0 MB)
part 2/2 downloading 2026-05-05 11:00:00 - 2026-05-05 11:00:06
part 2/2 done (4.5 MB)
Default mode:
--format copyThis remuxes without re-encoding where possible.
Exact mode:
--format exactThis re-encodes with H.264 for more precise cuts when stream-copy cutting is not enough. When a clip spans multiple recording files, exact mode normalizes the parts to matching video dimensions before joining them.
--mode copy and --mode exact are also accepted.