Documentation ¶
Overview ¶
Package gondi provides a wrapper for the NDI SDK for Linux, macOS, using purego.
The NDI SDK is available at https://www.ndi.tv/sdk/
The NDI SDK is licensed under the NewTek SDK EULA, which can be found at https://www.ndi.tv/sdk/
NDI® is a registered trademark of Vizrt Group.
Index ¶
- Constants
- Variables
- func ClearPreview(streamName string)
- func ConvertAudioFromInterleaved(pSrc *AudioFrameV2, pDst *AudioFrameV2)
- func ConvertAudioToInterleaved(pSrc *AudioFrameV2, pDst *AudioFrameV2)
- func ExtractSourceName(fullName string) string
- func GenerateAlpha() *image.RGBA
- func GetPreview(streamName string) (*image.RGBA, error)
- func GetPreviewIndex(streamName string) (int, error)
- func GetVersion() string
- func InitLibrary(libraryPath string) error
- func SendAlphaFrame(sender *SendInstance)
- func SetPreviewFrame(streamName string, frame []byte, width, height int)
- type AudioFrameV2
- type AudioFrameV3
- type FindInstance
- type FourCCType
- type FrameFormat
- type FrameType
- type MetadataFrame
- type NewRecvInstanceSettings
- type Preview
- type RecvBandwidth
- type RecvColorFormat
- type RecvInstance
- func (p *RecvInstance) AddConnectionMetadata(metadata *MetadataFrame)
- func (p *RecvInstance) CaptureV2(vf *VideoFrameV2, af *AudioFrameV2, mf *MetadataFrame, timeoutMs uint32) FrameType
- func (p *RecvInstance) CaptureV3(vf *VideoFrameV2, af *AudioFrameV3, mf *MetadataFrame, timeoutMs uint32) FrameType
- func (p *RecvInstance) ClearConnectionMetadata()
- func (p *RecvInstance) Connect(source *Source)
- func (p *RecvInstance) Destroy()
- func (p *RecvInstance) FreeAudioV2(af *AudioFrameV2)
- func (p *RecvInstance) FreeMetadata(metadata *MetadataFrame)
- func (p *RecvInstance) FreeVideoV2(vf *VideoFrameV2)
- func (p *RecvInstance) GetPerformance() (total *RecvPerformance, dropped *RecvPerformance)
- func (p *RecvInstance) SendMetadata(metadata *MetadataFrame) bool
- func (p *RecvInstance) SetTally(program bool, preview bool) bool
- type RecvPerformance
- type RoutingInstance
- type SendInstance
- func (p *SendInstance) AddConnectionMetadata(metadata *MetadataFrame)
- func (p *SendInstance) Capture(metadata *MetadataFrame, timeoutMs uint32) FrameType
- func (p *SendInstance) ClearConnectionMetadata()
- func (p *SendInstance) Destroy() error
- func (p *SendInstance) GetNumberOfConnections(timeoutMs uint32) int32
- func (p *SendInstance) GetTally(timeoutMs uint32) (*Tally, bool)
- func (p *SendInstance) SendAudioFrame(frame *AudioFrameV2)
- func (p *SendInstance) SendAudioFrame16s(frame *AudioFrameV3)
- func (p *SendInstance) SendAudioFrame32f(frame *AudioFrameV3)
- func (p *SendInstance) SendAudioFrameV3(frame *AudioFrameV3)
- func (p *SendInstance) SendMetadataFrame(frame *MetadataFrame)
- func (p *SendInstance) SendVideoFrame(frame *VideoFrameV2)
- func (p *SendInstance) SendVideoFrameAsync(frame *VideoFrameV2)
- func (p *SendInstance) SetFailover(source *Source)
- type Source
- type Tally
- type VideoFrameV2
Constants ¶
const ( SendTimecodeSynthesize int64 = math.MaxInt64 SendTimecodeEmpty int64 = 0 )
const EMPTY_X = 1920
const EMPTY_Y = 1080
Variables ¶
var Previews []Preview
Functions ¶
func ClearPreview ¶
func ClearPreview(streamName string)
func ConvertAudioFromInterleaved ¶
func ConvertAudioFromInterleaved(pSrc *AudioFrameV2, pDst *AudioFrameV2)
If your audio frames are interleaved, you can use this function to convert them to planar format. You can also use the frame.SetFromInterleavedArray(data) function to automatically convert an array of float32s in interleaved format to planar format as NDI likes it.
func ConvertAudioToInterleaved ¶
func ConvertAudioToInterleaved(pSrc *AudioFrameV2, pDst *AudioFrameV2)
If your want your audio frames to be interleaved, you can use this function to convert them from planar format. You can also use the frame.GetInterleavedArray() function to get a coverted array of float32s in interleaved format.
func ExtractSourceName ¶
func GenerateAlpha ¶
func GetPreviewIndex ¶
func InitLibrary ¶
Initialize the NDI Library, the libraryPath argument is optional and will be automatically set to the default library path for the current platform if empty. This function will panic if it does not find the library, or if it is unable to initialize NDI with the given library. But return error if NDI reports an error initializing.
func SetPreviewFrame ¶
Types ¶
type AudioFrameV2 ¶
type AudioFrameV2 struct { //The sample-rate of this buffer. SampleRate int32 //The number of audio channels. NumChannels int32 //The number of audio samples per channel. NumSamples int32 // The timecode of this frame in 100-nanosecond intervals. Timecode int64 // The audio data as float32 samples Data *float32 // The inter channel stride of the audio channels, in bytes. ChannelStride int32 // Per frame metadata for this frame. This is a NULL terminated UTF8 string that should be in XML format. // If you do not want any metadata then you may specify NULL here. Metadata *byte // This is only valid when receiving a frame and is specified as a 100-nanosecond time that was the exact // moment that the frame was submitted by the sending side and is generated by the SDK. If this value is // NDIlib_recv_timestamp_undefined then this value is not available and is NDIlib_recv_timestamp_undefined. Timestamp int64 }
func NewAudioFrameV2Preallocated ¶
func NewAudioFrameV2Preallocated(numChannels int32, numSamples int32) *AudioFrameV2
Allocate a new NDI audio frame object with preallocated data for holding numChannels * numSamples samples.
func (*AudioFrameV2) GetArray ¶
func (p *AudioFrameV2) GetArray() []float32
Get the audio frames as an array of float32 This is usually stored as planar audio, so the first NumSamples values are the first channel, the next NumSamples values are the second channel, etc. If you need to work with interleaved audio, you can use the GetInterleavedArray() function instead.
func (*AudioFrameV2) GetInterleavedArray ¶
func (p *AudioFrameV2) GetInterleavedArray() []float32
Get the audio frames as an array of float32 This function converts the audio to interleaved audio, so each sample is stored as a single value, and the channels are interleaved.
func (*AudioFrameV2) SetArray ¶
func (p *AudioFrameV2) SetArray(audio []float32)
Set the audio frames from an array of float32 The Data field of the frame needs to be preallocated.
func (*AudioFrameV2) SetFromInterleavedArray ¶
func (p *AudioFrameV2) SetFromInterleavedArray(audio []float32)
This function converts the interleaved audio from the parameter, to planar audio, and stores it in the Data field of the AudioFrameV2. The Data field of the frame needs to be preallocated.
type AudioFrameV3 ¶
type AudioFrameV3 struct { //The sample-rate of this buffer. SampleRate int32 //The number of audio channels. NumChannels int32 //The number of audio samples per channel. NumSamples int32 // The timecode of this frame in 100-nanosecond intervals. Timecode int64 // The audio data as int16 samples Data *byte // The inter channel stride of the audio channels, in bytes. ChannelStride int32 // Per frame metadata for this frame. This is a NULL terminated UTF8 string that should be in XML format. // If you do not want any metadata then you may specify NULL here. Metadata *byte // This is only valid when receiving a frame and is specified as a 100-nanosecond time that was the exact // moment that the frame was submitted by the sending side and is generated by the SDK. If this value is // NDIlib_recv_timestamp_undefined then this value is not available and is NDIlib_recv_timestamp_undefined. Timestamp int64 }
type FindInstance ¶
type FindInstance struct {
// contains filtered or unexported fields
}
Finder instance struct
func NewFindInstance ¶
func NewFindInstance(showLocalSources bool, groups string, extraIPs string) (*FindInstance, error)
Setup a finder instance, initialized groups and extraIPs. ShowLocalSources will control whether local sources are shown or not. The groups property may be empty, and it will use the default from NDI access manager. The extraIPs is only used to manually find sources from known ips on different subnets and is comma separated.
func (*FindInstance) GetCurrentSources ¶
func (p *FindInstance) GetCurrentSources() []*Source
Get the current sources from this finder instance. It is recomended to call WaitForSources before this. If you have a UI element to change the source, you should call this function before showing the user the list of sources, to always have the latest list of sources.
func (*FindInstance) WaitForSources ¶
func (p *FindInstance) WaitForSources(timeoutMs uint32) bool
This allows you to wait until the sources on the network have changed. It will return true if the list of sourcess has changed within the timeout, false otherwise. You are not required to call this function, but it is helpful for getting an initial list of sources, and to detect when the list of sources has changed.
type FourCCType ¶
type FourCCType [4]byte
var ( FourCCTypeRGBA = [4]byte{'R', 'G', 'B', 'A'} FourCCTypeRGBX = [4]byte{'R', 'G', 'B', 'X'} // YCbCr color space using 4:2:2. FourCCTypeUYVY FourCCType = [4]byte{'U', 'Y', 'V', 'Y'} // Planar 8bit, 4:4:4:4 video format. // Color ordering in memory is blue, green, red, alpha FourCCTypeBGRA FourCCType = [4]byte{'B', 'G', 'R', 'A'} // Planar 8bit, 4:4:4 video format, packed into 32bit pixels. // Color ordering in memory is blue, green, red, 255 FourCCTypeBGRX FourCCType = [4]byte{'B', 'G', 'R', 'X'} // YCbCr + Alpha color space, using 4:2:2:4. // In memory there are two separate planes. The first is a regular // UYVY 4:2:2 buffer. Immediately following this in memory is a // alpha channel buffer. FourCCTypeUYVA FourCCType = [4]byte{'U', 'Y', 'V', 'A'} )
type FrameFormat ¶
type FrameFormat int32
Video frame format
const ( FrameFormatInterleaved FrameFormat = iota //A fielded frame with the field 0 being on the even lines and field 1 being on the odd lines. FrameFormatProgressive //A progressive frame. //Individual fields. FrameFormatField0 FrameFormatField1 )
type FrameType ¶
type FrameType int32
An enumeration to specify the type of a packet returned by the capture functions
const ( FrameTypeNone FrameType = iota FrameTypeVideo FrameTypeAudio FrameTypeMetadata FrameTypeError //This indicates that the settings on this input have changed. //For instamce, this value will be returned from NDIlib_recv_capture_v2 and NDIlib_recv_capture //when the device is known to have new settings, for instance the web-url has changed ot the device //is now known to be a PTZ camera. FrameTypeStatusChange FrameType = 100 )
type MetadataFrame ¶
type MetadataFrame struct { // The length of the string in UTF8 characters. This includes the NULL terminating character. // If this is 0, then the length is assume to be the length of a null terminated string. Length int32 // The timecode of this frame in 100ns intervals. Timecode int64 // The metadata as a UTF8 XML string. This is a NULL terminated string. Data *byte }
func NewMetadataFrame ¶
func NewMetadataFrame(data string) *MetadataFrame
Allocate a new NDIMetadataFrame and initialize it with the specified utf-8 data string.
func (*MetadataFrame) GetData ¶
func (p *MetadataFrame) GetData() string
Get the data of the metadata frame as a utf8-string
type NewRecvInstanceSettings ¶
type NewRecvInstanceSettings struct { // Source to connect to SourceToConnectTo *Source // Your preferred colorspace, default is gondi.RecvColorFormatUYVYBGRA ColorFormat RecvColorFormat // The bandwidth setting that you wish to use for this video source. Bandwidth // controlled by changing both the compression level and the resolution of the source. // Default value, and for full quality and all frame types: gondi.RecvBandwidthHighest Bandwidth RecvBandwidth // When this flag is FALSE, all video that you receive will be progressive. For sources // that provide fields, this is de-interlaced on the receiving side (because we cannot change // what the up-stream source was actually rendering. This is provided as a convenience to // down-stream sources that do not wish to understand fielded video. There is almost no // performance impact of using this function. // Default is true AllowVideoFields bool // The name of the ndi receiver to create. This should be named the same way that you // would like the source on the network to be named. If this is empty then it will use the filename of your application // indexed with the number of the instance number of this receiver. Name string }
type RecvBandwidth ¶
type RecvBandwidth int32
Borrowed from ndi-go/ndi.go
const ( RecvBandwidthMetadataOnly RecvBandwidth = -10 //Receive metadata. RecvBandwidthAudioOnly RecvBandwidth = 10 //Receive metadata, audio. RecvBandwidthLowest RecvBandwidth = 0 //Receive metadata, audio, video at a lower bandwidth and resolution. RecvBandwidthHighest RecvBandwidth = 100 //Receive metadata, audio, video at full resolution. )
type RecvColorFormat ¶
type RecvColorFormat int32
Borrowed from ndi-go/ndi.go
const ( RecvColorFormatBGRXBGRA RecvColorFormat = 0 //No alpha channel: BGRX, Alpha channel: BGRA RecvColorFormatUYVYBGRA RecvColorFormat = 1 //No alpha channel: UYVY, Alpha channel: BGRA RecvColorFormatRGBXRGBA RecvColorFormat = 2 //No alpha channel: RGBX, Alpha channel: RGBA RecvColorFormatUYVYRGBA RecvColorFormat = 3 //No alpha channel: UYVY, Alpha channel: RGBA //Read the SDK documentation to understand the pros and cons of this format. RecvColorFormatFastest RecvColorFormat = 100 )
type RecvInstance ¶
type RecvInstance struct {
// contains filtered or unexported fields
}
Receiver instance struct
func NewRecvInstance ¶
func NewRecvInstance(settings *NewRecvInstanceSettings) (*RecvInstance, error)
Allocate a new Receiver, using a NewRecvInstanceSetting struct as parameters
func (*RecvInstance) AddConnectionMetadata ¶
func (p *RecvInstance) AddConnectionMetadata(metadata *MetadataFrame)
Add a connection metadata string to the list of what is sent on each new connection. If someone is already connected then this frame will be sent to them immediately.
func (*RecvInstance) CaptureV2 ¶
func (p *RecvInstance) CaptureV2(vf *VideoFrameV2, af *AudioFrameV2, mf *MetadataFrame, timeoutMs uint32) FrameType
This will allow you to receive video, audio and metadata frames from the source you are connected to. Any of the frame pointers can be nil, in which case that type of frame will not be captured. This call can be called on separate threads, so it is possible to have a separate thread for each of video, audio and metadata. This function will return the type of frame that was received, or gondi.FrameTypeNone if no frame was received within the specified timeout.
func (*RecvInstance) CaptureV3 ¶
func (p *RecvInstance) CaptureV3(vf *VideoFrameV2, af *AudioFrameV3, mf *MetadataFrame, timeoutMs uint32) FrameType
This will allow you to receive video, audio and metadata frames from the source you are connected to. Any of the frame pointers can be nil, in which case that type of frame will not be captured. This call can be called on separate threads, so it is possible to have a separate thread for each of video, audio and metadata. This function will return the type of frame that was received, or gondi.FrameTypeNone if no frame was received within the specified timeout.
func (*RecvInstance) ClearConnectionMetadata ¶
func (p *RecvInstance) ClearConnectionMetadata()
Connection based metadata is data that is sent automatically each time a new connection is received. You queue all of these up and they are sent on each connection. To reset them you need to clear them all and set them up again.
func (*RecvInstance) FreeAudioV2 ¶
func (p *RecvInstance) FreeAudioV2(af *AudioFrameV2)
Free the buffers returned by capture for audio
func (*RecvInstance) FreeMetadata ¶
func (p *RecvInstance) FreeMetadata(metadata *MetadataFrame)
Free the buffers returned by capture for metadata
func (*RecvInstance) FreeVideoV2 ¶
func (p *RecvInstance) FreeVideoV2(vf *VideoFrameV2)
Free the buffers returned by capture for video
func (*RecvInstance) GetPerformance ¶
func (p *RecvInstance) GetPerformance() (total *RecvPerformance, dropped *RecvPerformance)
Get the current amount of total and dropped video, audio and metadata frames. This can be used to determine if you have been calling instace.CaptureV2() fast enough to keep up with the incoming stream.
func (*RecvInstance) SendMetadata ¶
func (p *RecvInstance) SendMetadata(metadata *MetadataFrame) bool
This function will send a meta frame to the source that we are connected too. This returns FALSE if we are not currently connected to anything.
func (*RecvInstance) SetTally ¶
func (p *RecvInstance) SetTally(program bool, preview bool) bool
Set the up-stream tally notifications. This returns FALSE if we are not currently connected to anything. That said, the moment that we do connect to something it will automatically be sent the tally state.
type RecvPerformance ¶
type RoutingInstance ¶
type RoutingInstance struct {
// contains filtered or unexported fields
}
ROuting instance struct
func NewRoutingInstance ¶
func NewRoutingInstance(name string, groups string) (*RoutingInstance, error)
Setup a routed destination, specified by name and groups. The groups property may be empty, and it will use the default from NDI access manager.
func (*RoutingInstance) Change ¶
func (p *RoutingInstance) Change(source *Source)
Change the source this routing instance is connected to.
func (*RoutingInstance) Clear ¶
func (p *RoutingInstance) Clear()
Clear the current source this routing instance is connected to. Should return black to watchers.
func (*RoutingInstance) Destroy ¶
func (p *RoutingInstance) Destroy()
Destroy this routing instance.
func (*RoutingInstance) Groups ¶
func (p *RoutingInstance) Groups() string
Get the set groups for this instance, to change it, destroy this routing instance and create a new with the correct settings.
func (*RoutingInstance) Name ¶
func (p *RoutingInstance) Name() string
Get the set name of this instance. To change it, destroy this routing instance and create a new with the correct settings.
type SendInstance ¶
type SendInstance struct {
// contains filtered or unexported fields
}
Sender instance struct
func NewSendInstance ¶
func NewSendInstance(name string, groups string, clockVideo bool, clockAudio bool) (*SendInstance, error)
Set up a sender instance using the specified name and string. Syncronous calls will block on either audio or video frames, or both, depending on the clockVideo and clockAudio parameters, to make sure that the frames are sent at the correct time.
func (*SendInstance) AddConnectionMetadata ¶
func (p *SendInstance) AddConnectionMetadata(metadata *MetadataFrame)
Add a connection metadata string to the list of what is sent on each new connection. If someone is already connected then this string will be sent to them immediately.
func (*SendInstance) Capture ¶
func (p *SendInstance) Capture(metadata *MetadataFrame, timeoutMs uint32) FrameType
This method lets you receive metadata from the other end of the connection. Remember that there might be multiple connections to your sender instance.
func (*SendInstance) ClearConnectionMetadata ¶
func (p *SendInstance) ClearConnectionMetadata()
Connection based metadata is data that is sent automatically each time a new connection is received. You queue all of these up and they are sent on each connection. To reset them you need to clear them all and set them up again.
func (*SendInstance) Destroy ¶
func (p *SendInstance) Destroy() error
Remember to call Destroy() on the instance when you are done with it. This will free up resources and unregister the sender.
func (*SendInstance) GetNumberOfConnections ¶
func (p *SendInstance) GetNumberOfConnections(timeoutMs uint32) int32
Get the current number of receivers connected to this source. This can be used to avoid even rendering when nothing is connected to the video source. which can significantly improve the efficiency if you want to make a lot of sources available on the network. If you specify a timeout that is not 0 then it will wait until there are connections for this amount of time.
func (*SendInstance) GetTally ¶
func (p *SendInstance) GetTally(timeoutMs uint32) (*Tally, bool)
Determine the current tally sate. If you specify a timeout then it will wait until it has changed, otherwise it will simply poll it and return the current tally immediately. The boolean return value is whether anything has actually changed (true) or whether it timed out (false)
func (*SendInstance) SendAudioFrame ¶
func (p *SendInstance) SendAudioFrame(frame *AudioFrameV2)
Send an audio frame. This call is syncronous and will block until the frame has been sent, if you specified clockAudio=true in NewNDISendInstance().
func (*SendInstance) SendAudioFrame16s ¶
func (p *SendInstance) SendAudioFrame16s(frame *AudioFrameV3)
Send an audio frame. This call is syncronous and will block until the frame has been sent, if you specified clockAudio=true in NewNDISendInstance().
func (*SendInstance) SendAudioFrame32f ¶
func (p *SendInstance) SendAudioFrame32f(frame *AudioFrameV3)
Send an audio frame. This call is syncronous and will block until the frame has been sent, if you specified clockAudio=true in NewNDISendInstance().
func (*SendInstance) SendAudioFrameV3 ¶
func (p *SendInstance) SendAudioFrameV3(frame *AudioFrameV3)
Send an audio frame. This call is syncronous and will block until the frame has been sent, if you specified clockAudio=true in NewNDISendInstance().
func (*SendInstance) SendMetadataFrame ¶
func (p *SendInstance) SendMetadataFrame(frame *MetadataFrame)
Send a metadata frame
func (*SendInstance) SendVideoFrame ¶
func (p *SendInstance) SendVideoFrame(frame *VideoFrameV2)
Send a video frame. This call is syncronous and will block until the frame has been sent if you specified clockVideo=true in NewNDISendInstance().
func (*SendInstance) SendVideoFrameAsync ¶
func (p *SendInstance) SendVideoFrameAsync(frame *VideoFrameV2)
Send video asynchronously, this call will return immediately, and you need to keep the video frame memory resident until a synchronizing event has been received. Syncronizing events are: - A call to frame.SendVideoFrame() - A call to frame.SendVideoFrameAsync() with a different video frame - A call to frame.SendVideoFrame(nil) - A call to frame.Destroy()
func (*SendInstance) SetFailover ¶
func (p *SendInstance) SetFailover(source *Source)
This will assign a new fail-over source for this video source. What this means is that if this video source was to fail any receivers would automatically switch over to use this source, unless this source then came back online. You can specify nil to clear the source.
type VideoFrameV2 ¶
type VideoFrameV2 struct {
// The resolution of this frame.
Xres, Yres int32
// What FourCC describing the type of data for this frame.
FourCC FourCCType
// What is the frame rate of this frame.
// For instance NTSC is 30000,1001 = 30000/1001 = 29.97 fps.
FrameRateN, FrameRateD int32
// What is the picture aspect ratio of this frame.
// For instance 16.0/9.0 = 1.778 is 16:9 video
// 0 means square pixels.
PictureAspectRatio float32
// Is this a fielded frame, or is it progressive.
FrameFormatType FrameFormat
// The timecode of this frame in 100ns intervals.
Timecode int64
// The video data itself.
Data *byte
// The inter line stride of the video data, in bytes.
LineStride int32
//Per frame metadata for this frame. This is a NULL terminated UTF8 string that should be
//in XML format. If you do not want any metadata then you may specify NULL here.
Metadata *byte
//This is only valid when receiving a frame and is specified as a 100ns time that was the exact
//moment that the frame was submitted by the sending side and is generated by the SDK. If this
//value is NDIlib_recv_timestamp_undefined then this value is not available and is NDIlib_recv_timestamp_undefined.
Timestamp int64
}
func NewVideoFrameV2 ¶
func NewVideoFrameV2() *VideoFrameV2
Allocate a new NDI video frame with defaults