RenatoMaynard/Smart-Video-Record-Deepstream-For-USB-in-Python
Guide to set up DeepStream pyds and run an USB pipeline in Python. Note: NVIDIA Smart Recording isn’t in official Python bindings and is supported only in C++. This repo includes a compatible wheel and tweaks so you can install it easily and enable Smart Recording from Python.
Smart-Video-Record-DeepStream-For-USB-in-Python
A practical guide + minimal code to:
- set up DeepStream Python (
pyds) - run a single USB camera pipeline in Python
- do YOLO inference with
nvinfer - record smart clips (pre/post event) from a USB source using NvDsSR
What this demo does
- Uses one USB camera (
/dev/videoX) and displays it full screen (no layout switching, no logo). - Runs inference with
nvinferusing a config file (example included). - Draws ONLY
persondetections and their confidence. - Supports Smart Recording for USB (manual NvDsSR via DeepStream smartrecord library).
- Hotkeys:
- R → record a clip
- ESC → exit
Repository files
-
usb_cam.py
Main app: USB camera → decode → streammux → nvinfer → OSD → fullscreen sink → Smart Record triggers. -
usb_smartrec.py
Smart Recording helper (manual NvDsSR wiring for USB). -
pt_to_onnx.py
Transform .pt to .onnx. -
dstest1_pgie_config.txt
Examplenvinferconfiguration for YOLO.
Key fields includeonnx-file,model-engine-file,parse-bbox-func-name,custom-lib-path, andengine-create-func-name. -
labels.txt
Example label file (COCO-style list).
Background: how it works (high level)
DeepStream apps are usually GStreamer pipelines using NVIDIA-accelerated elements.
1) USB capture + decode
Typical USB webcams output MJPEG. The pipeline requests MJPEG from /dev/videoX and decodes it using NVIDIA decode:
v4l2src→ reads/dev/videoXcapsfilter→ requestsimage/jpegwith a chosen resolution/FPSnvv4l2decoder→ hardware MJPEG decode into NVMM memorynvvidconv/nvvideoconvert→ color/format conversion for DeepStream elements
2) Inference with nvinfer
Inference is handled by nvinfer, which reads a config file.
Your sample config uses:
onnx-file=yolov11.pt.onnxmodel-engine-file=/home/nvidia/Desktop/Engine/b1_gpu0_fp16.engineparse-bbox-func-name=NvDsInferParseYolocustom-lib-path=.../libnvdsinfer_custom_impl_Yolo.soengine-create-func-name=NvDsInferYoloCudaEngineGet
3) OSD (drawing)
nvdsosd draws boxes/text.
This demo filters metadata so it only draws:
person- confidence text like:
person 87.3%
4) Smart Recording for USB (NvDsSR)
DeepStream has two Smart Record modes:
nvurisrcbinbuilt-in Smart Record (great for RTSP)- Manual NvDsSR (needed for USB / v4l2)
This repo uses manual NvDsSR so USB works:
- A
teesplits the stream - One branch goes to inference + display
- The other branch goes through encoder + parser into the NvDsSR recordbin (so the recorder gets encoded H264/H265)
Smart Record keeps a small “cache” (ring buffer), so each clip can include:
SR_BACK_SECseconds before the triggerSR_FRONT_SECseconds after the trigger
Setup / Configuration Guide (Important)
A) Install DeepStream
Install NVIDIA DeepStream on your Jetson (via JetPack + DeepStream SDK installer, or NVIDIA packages).
After install, you should have:
/opt/nvidia/deepstream/deepstream/
B) Install DeepStream Python (pyds)
You must be able to run:
import pydsIf import pyds fails, fix DeepStream Python first (this repo assumes it already works).
C) Enable YOLO in DeepStream (the critical part)
DeepStream does not natively know how to post-process YOLO outputs.
You need a YOLO custom parser and (often) an engine creation helper. The most common solution is:
- marcoslucianops / DeepStream-Yolo
1) Build the YOLO custom parser .so
In the DeepStream-Yolo repo, compile the library:
make -C nvdsinfer_custom_impl_Yolo clean && make -C nvdsinfer_custom_impl_YoloThat produces libnvdsinfer_custom_impl_Yolo.so.
2) Point your nvinfer config to the .so
Your dstest1_pgie_config.txt already does this via:
custom-lib-path=/home/nvidia/DeepStream-Yolo/nvdsinfer_custom_impl_Yolo/libnvdsinfer_custom_impl_Yolo.so
3) Use the YOLO parser function
Your config sets:
parse-bbox-func-name=NvDsInferParseYolo
4) (Optional) Engine creation helper
Your config sets:
engine-create-func-name=NvDsInferYoloCudaEngineGet
This allows DeepStream-Yolo to help generate the TensorRT engine in some workflows.
D) Model files (ONNX + TensorRT engine)
Your config expects:
onnx-file=yolov11.pt.onnxmodel-engine-file=/home/nvidia/Desktop/Engine/b1_gpu0_fp16.engine
You must ensure:
- the ONNX file exists at the path given (You can use the provided pt_to_onnx.py file)
- the engine file exists at the path given
(or DeepStream is allowed to generate it depending on your setup)
Tip: If you move files, update the config paths.
E) Labels + class count (very important)
Your config currently has:
num-detected-classes=1
But your labels.txt contains many labels (COCO list).
You should make these consistent:
- If your model is person-only, keep
num-detected-classes=1and use a single-line labels file:person
- If your model is COCO (80 classes), set:
num-detected-classes=80- and keep the COCO labels file
Running the demo
- Open this repo folder in Visual Studio Code on the Jetson.
- Open
usb_cam.py. - Edit the config block at the top:
USB_DEVICE = "/dev/video0"PGIE_CONFIG = "<absolute path>/dstest1_pgie_config.txt"
- Click Run.
No command-line args required.
Controls
- R → record a Smart Record clip
- ESC → exit
Output clips
Clips are written to:
SmartRecDir/(default)
Troubleshooting
NVDSINFER_CONFIG_FAILED
Usually one of:
- bad config file path
- missing ONNX/engine file
- wrong
custom-lib-path(YOLO parser.sonot found) - mismatch between model output and parser settings
YOLO runs but no detections
Common causes:
- wrong
num-detected-classes - wrong thresholds (
pre-cluster-threshold, NMS settings) - wrong input dims / preprocessing settings for your exported ONNX
License
MIT