Expand description
High-performance Rust bindings for the NDI® 6 SDK (Network Device Interface).
This crate provides safe, idiomatic Rust bindings for the NDI SDK, enabling real-time, low-latency video/audio streaming over IP networks. NDI is widely used in broadcast, live production, and video conferencing applications.
§Quick Start
use grafton_ndi::{NDI, FinderOptions, Finder};
use std::time::Duration;
// Initialize the NDI runtime
let ndi = NDI::new()?;
// Find sources on the network
let options = FinderOptions::builder().show_local_sources(true).build();
let finder = Finder::new(&ndi, &options)?;
// Discover sources
let sources = finder.find_sources(Duration::from_secs(5))?;
for source in sources {
println!("Found: {}", source);
}§Core Concepts
§Runtime Management
The NDI struct manages the NDI runtime lifecycle. It must be created before
any other NDI operations and should be kept alive for the duration of your
application’s NDI usage.
§Source Discovery
Use Finder to discover NDI sources on the network. Sources can be filtered
by groups and additional IP addresses can be specified for discovery.
§Receiving
The Receiver type handles receiving video, audio, and metadata from NDI
sources. It supports various color formats and bandwidth modes.
§Sending
Use Sender to transmit video, audio, and metadata as an NDI source.
Senders can be configured with clock settings and group assignments.
§Thread Safety
All primary types (Finder, Receiver, Sender) implement Send + Sync
as the underlying NDI SDK is thread-safe. However, for optimal performance,
minimize cross-thread operations and maintain thread affinity where possible.
§Zero-Copy Async Sending
The library provides zero-copy async video sending using NDIlib_send_send_video_async_v2.
The completion callback notifies when the buffer can be reused:
// Register callback to know when buffer is released
sender.on_async_video_done(|len| println!("Buffer released: {} bytes", len));
let buffer = vec![0u8; 1920 * 1080 * 4];
let frame = BorrowedVideoFrame::try_from_uncompressed(&buffer, 1920, 1080, PixelFormat::BGRA, 30, 1)?;
let token = sender.send_video_async(&frame);
// Buffer is now owned by NDI - cannot be modified until callback fires
// The AsyncVideoToken must be kept alive to track the operationNote: Only video supports async sending in the NDI SDK. Audio and metadata are always synchronous.
§Performance
- Zero-copy: Frame data directly references NDI’s buffers when possible
- Lock-free async: Atomic operations for minimal overhead in hot paths
- Bandwidth control: Multiple quality levels for different use cases
- Hardware acceleration: Automatically uses GPU acceleration when available
§Platform Support
Windows, Linux, and macOS are all exercised in CI (build, test, lint, and semver checks) against the NDI SDK.
- Windows: Links the NDI SDK import library at build time; requires the NDI runtime DLLs at runtime.
- Linux: Supports both standard and Advanced SDK install directories; the runtime libraries must be discoverable by the dynamic linker.
- macOS: Supports current NDI SDK package layouts used by the CI setup action and common local install paths.
Re-exports§
pub use finder::Finder;pub use finder::FinderOptions;pub use finder::FinderOptionsBuilder;pub use finder::Source;pub use finder::SourceAddress;pub use finder::SourceCache;pub use frames::AudioFormat;pub use frames::AudioFrame;pub use frames::AudioFrameBuilder;pub use frames::AudioFrameRef;pub use frames::AudioLayout;pub use frames::AudioRef;pub use frames::FormatCategory;pub use frames::LineStrideOrSize;pub use frames::MetadataFrame;pub use frames::MetadataFrameRef;pub use frames::PixelFormat;pub use frames::PixelFormatInfo;pub use frames::ScanType;pub use frames::VideoFrame;pub use frames::VideoFrameBuilder;pub use frames::VideoFrameRef;pub use frames::VideoRef;pub use framesync::FrameSync;pub use framesync::FrameSyncAudioRef;pub use framesync::FrameSyncAudioRequest;pub use framesync::FrameSyncVideoRef;pub use receiver::Capture;pub use receiver::ConnectionStats;pub use receiver::Receiver;pub use receiver::ReceiverBandwidth;pub use receiver::ReceiverColorFormat;pub use receiver::ReceiverOptions;pub use receiver::ReceiverOptionsBuilder;pub use receiver::ReceiverStatus;pub use receiver::Tally;pub use runtime::NDI;pub use sender::AsyncVideoToken;pub use sender::BorrowedVideoFrame;pub use sender::Sender;pub use sender::SenderOptions;pub use sender::SenderOptionsBuilder;pub use frames::ImageFormat;
Modules§
- async_
std - async-std runtime integration.
- finder
- NDI source discovery and network browsing.
- frames
- Frame types for video, audio, and metadata.
- framesync
- Frame synchronization for clock-corrected video/audio capture.
- receiver
- NDI receiving functionality for video, audio, and metadata.
- runtime
- NDI runtime management and initialization.
- sender
- NDI sending functionality for video, audio, and metadata.
- tokio
- Tokio async runtime integration.
- waitable_
completion - Zero-overhead completion signal for async operations.
Structs§
- Audio
Kind - Marker type for audio frame capture operations.
- Frame
Sync Audio Free - Free strategy for audio frames captured through
FrameSync. - Frame
Sync Video Free - Free strategy for video frames captured through
FrameSync. - Metadata
Kind - Marker type for metadata frame capture operations.
- Video
Kind - Marker type for video frame capture operations.
Enums§
- Error
- The main error type for NDI operations.
Constants§
- MAX_
TIMEOUT - Maximum timeout duration supported by the NDI SDK (~49.7 days).
Traits§
- Capture
Kind - Single source of truth describing one NDI frame kind (video, audio, or metadata).
- Frame
Free - The free strategy for one captured-frame family: the SDK instance handle type plus the SDK call that releases a single frame.
Type Aliases§
- Result
- Alias for Result with our Error type