Video ingest in Python
With recent advancements in machine learning, robotics, and autonomy, video is now an essential test artifact for modern hardware development teams.
Nominal has 1st class support for video ingestion, analysis, time sychronization across sensor channels, and automated checks that signal when a video feature is out-of-spec.
This guide demonstrates how to upload a video file to Nominal in Python. Other guides in the Video section demonstrate basic Python video analysis and computer vision for video pre-processing prior to Nominal upload.
Connect to Nominal
When using the Nominal client library, there are two primary ways of authenticating:
Storing credentials to disk
First, run the following in your terminal and follow on-screen prompts to insert the base_url and API key:
This will store your API key in a config file ~/.nominal.yml
.
The API key will automatically be used when using the client again.
Directly using credentials in your scripts
NOTE: you should never share your Nominal API key with anyone. We therefore recommend that you not save it in your code and/or scripts.
Download sample video
For convenience, Nominal hosts sample test data on Hugging Face. To download the sample data for this guide, copy-paste the snippet below.
(Make sure to first install huggingface_hub with pip3 install huggingface_hub
).
Since our dataset is a video file, we’ll rename dataset_path
:
Correct video format
For a video file to be successfully ingested into Nominal, it needs to satisfy the following conditions:
- be H264 or H265 encoded,
- use YUV420p color space, and
- contain an audio track.
It is also recommended that the video has reasonably-spaced key-frames (at most ~10s between key-frames) for optimal playback performance.
These constraints do not apply for MCAP-based Videos.
To help customers ingest a wide variety of video formats, the Python client provides the following utility function:
To use this functionality, you must have ffmpeg
installed.
You can find pre-built binaries on their website, or install it via your operating system package manager.
If you intend to distribute the ‘ffmpeg’ binary, e.g. along with your scripts, you should also include its source code, as per the terms of FFMPEG’s GPLv3 license.
Need help determining what video encoding settings you are using? Off the shelf tools such as VLC can be used to inspect the codec information of a video file.
Here are some examples of the VLC “Media Information” window showing codec details of common situations with videos
Video that would successfully ingest into Nominal
Video that has an unsupported color space
Video that has an unsupported video codec
Video that is missing an audio track
Upload video to Nominal
Once uploaded to Nominal, video test artifacts can be analyzed collaboratively in no-code workflows and integrated with checks to signal off-nominal video features.
Nominal requires a video start time for video file upload. If the absolute time that the video was
captured is not important, you can use an arbitrary datetime like datetime.now()
or
2011-11-11 11:11:11
.
Video start times are used to align playback with other time-domain data in your run. Whichever absolute start time that you choose for your video (for example, 2011-11-11 11:11:11), make sure that it aligns with the other start times in your run’s data sources.
Add a Video to a Run
Once you’ve saved a Video to the Nominal platform, it’s easy to add the Video to a Run - Nominal’s container for multi-modal datasets that belong to the same test run and time domain.
In Nominal, Runs are containers of multimodal test data - including Datasets, Videos, Logs, and database connections.
To see your organization’s latest Runs, head over to the Runs page
Create an empty Run
The below code will create an empty Run container. Any type of data that Nominal supports (Video, CSV files, database connections, etc) and has an overlapping time domain can be attached to this Run container.
First, we’ll use OpenCV to get the video length in seconds.
Nominal Runs expect both a start and end timestamp.
In the example above, we’ve used 2011-11-11 11:11:11
as an arbitrary start time.
To get the Run end time, we’ll simply add the video duration (in seconds) to this start time.
If you haven’t make sure to install OpenCV for Python with pip install opencv-python
.
Now that we have the Run start and end times as variables, we create our empty Run container:
Attach Nominal Video to Run
We’ll use add_datset()
to add the video file to the Run:
Ref names (reference names) are a namespace for data sources that share common channels, but do not necessarily belong to the same Run. They allow data sources with similar schema to be referenced as a group. For example, data sources with the same ref name can share Workbook templates and Checklists.
Retrieve a video
Retrieve a video with its RID (resource ID), which can be copy pasted for any video on the Videos page.
Archive a video
Archiving a video prevents it from displaying on the Videos page.
To unarchive a video:
Now the video will display again on the Videos page.
Appendix
Display video inline
If you’re working in Jupyter notebook, here’s a shortcut to display the video inline in your notebook.
Inspect video metadata with OpenCV
The free OpenCV Python library is invaluable for video inspection and low-level video editing.
Below is a simple script that demonstrates how to capture basic video file properties such as video duration, frames per second, frame size, and total frame count.
You can install OpenCV for Python with pip install opencv-python
.
If interested in more advanced video processing in Python, check out the object identification guide.