2c0250d29a
- Increased thresholds for funlen and lll linters to accommodate complex functions. - Added exclusions for dupl linter in specific files and directories to reduce false positives. - Updated CI workflow documentation to clarify triggers and requirements for SonarCloud analysis. - Removed unnecessary linter directives in several files for improved readability.
4096 lines
121 KiB
Go
4096 lines
121 KiB
Go
package onvif
|
|
|
|
import (
|
|
"context"
|
|
"encoding/xml"
|
|
"fmt"
|
|
|
|
"github.com/0x524a/onvif-go/internal/soap"
|
|
)
|
|
|
|
// Media service namespace.
|
|
const mediaNamespace = "http://www.onvif.org/ver10/media/wsdl"
|
|
|
|
// getMediaEndpoint returns the media endpoint, falling back to the default endpoint if not set.
|
|
func (c *Client) getMediaEndpoint() string {
|
|
if c.mediaEndpoint != "" {
|
|
return c.mediaEndpoint
|
|
}
|
|
|
|
return c.endpoint
|
|
}
|
|
|
|
// getMediaSoapClient creates a new SOAP client for media operations.
|
|
func (c *Client) getMediaSoapClient() *soap.Client {
|
|
username, password := c.GetCredentials()
|
|
|
|
return soap.NewClient(c.httpClient, username, password)
|
|
}
|
|
|
|
// GetProfiles retrieves all media profiles.
|
|
//
|
|
//nolint:funlen // GetProfiles has many statements due to parsing complex profile structures
|
|
func (c *Client) GetProfiles(ctx context.Context) ([]*Profile, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetProfiles struct {
|
|
XMLName xml.Name `xml:"trt:GetProfiles"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
}
|
|
|
|
type GetProfilesResponse struct {
|
|
XMLName xml.Name `xml:"GetProfilesResponse"`
|
|
Profiles []struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
VideoSourceConfiguration *struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
SourceToken string `xml:"SourceToken"`
|
|
Bounds *struct {
|
|
X int `xml:"x,attr"`
|
|
Y int `xml:"y,attr"`
|
|
Width int `xml:"width,attr"`
|
|
Height int `xml:"height,attr"`
|
|
} `xml:"Bounds"`
|
|
} `xml:"VideoSourceConfiguration"`
|
|
VideoEncoderConfiguration *struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
Encoding string `xml:"Encoding"`
|
|
Resolution *struct {
|
|
Width int `xml:"Width"`
|
|
Height int `xml:"Height"`
|
|
} `xml:"Resolution"`
|
|
Quality float64 `xml:"Quality"`
|
|
RateControl *struct {
|
|
FrameRateLimit int `xml:"FrameRateLimit"`
|
|
EncodingInterval int `xml:"EncodingInterval"`
|
|
BitrateLimit int `xml:"BitrateLimit"`
|
|
} `xml:"RateControl"`
|
|
} `xml:"VideoEncoderConfiguration"`
|
|
PTZConfiguration *struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
NodeToken string `xml:"NodeToken"`
|
|
} `xml:"PTZConfiguration"`
|
|
} `xml:"Profiles"`
|
|
}
|
|
|
|
req := GetProfiles{
|
|
Xmlns: mediaNamespace,
|
|
}
|
|
|
|
var resp GetProfilesResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetProfiles failed: %w", err)
|
|
}
|
|
|
|
profiles := make([]*Profile, len(resp.Profiles))
|
|
for i, p := range resp.Profiles {
|
|
profile := &Profile{
|
|
Token: p.Token,
|
|
Name: p.Name,
|
|
}
|
|
|
|
if p.VideoSourceConfiguration != nil {
|
|
profile.VideoSourceConfiguration = &VideoSourceConfiguration{
|
|
Token: p.VideoSourceConfiguration.Token,
|
|
Name: p.VideoSourceConfiguration.Name,
|
|
UseCount: p.VideoSourceConfiguration.UseCount,
|
|
SourceToken: p.VideoSourceConfiguration.SourceToken,
|
|
}
|
|
if p.VideoSourceConfiguration.Bounds != nil {
|
|
profile.VideoSourceConfiguration.Bounds = &IntRectangle{
|
|
X: p.VideoSourceConfiguration.Bounds.X,
|
|
Y: p.VideoSourceConfiguration.Bounds.Y,
|
|
Width: p.VideoSourceConfiguration.Bounds.Width,
|
|
Height: p.VideoSourceConfiguration.Bounds.Height,
|
|
}
|
|
}
|
|
}
|
|
|
|
if p.VideoEncoderConfiguration != nil {
|
|
profile.VideoEncoderConfiguration = &VideoEncoderConfiguration{
|
|
Token: p.VideoEncoderConfiguration.Token,
|
|
Name: p.VideoEncoderConfiguration.Name,
|
|
UseCount: p.VideoEncoderConfiguration.UseCount,
|
|
Encoding: p.VideoEncoderConfiguration.Encoding,
|
|
Quality: p.VideoEncoderConfiguration.Quality,
|
|
}
|
|
if p.VideoEncoderConfiguration.Resolution != nil {
|
|
profile.VideoEncoderConfiguration.Resolution = &VideoResolution{
|
|
Width: p.VideoEncoderConfiguration.Resolution.Width,
|
|
Height: p.VideoEncoderConfiguration.Resolution.Height,
|
|
}
|
|
}
|
|
if p.VideoEncoderConfiguration.RateControl != nil {
|
|
profile.VideoEncoderConfiguration.RateControl = &VideoRateControl{
|
|
FrameRateLimit: p.VideoEncoderConfiguration.RateControl.FrameRateLimit,
|
|
EncodingInterval: p.VideoEncoderConfiguration.RateControl.EncodingInterval,
|
|
BitrateLimit: p.VideoEncoderConfiguration.RateControl.BitrateLimit,
|
|
}
|
|
}
|
|
}
|
|
|
|
if p.PTZConfiguration != nil {
|
|
profile.PTZConfiguration = &PTZConfiguration{
|
|
Token: p.PTZConfiguration.Token,
|
|
Name: p.PTZConfiguration.Name,
|
|
UseCount: p.PTZConfiguration.UseCount,
|
|
NodeToken: p.PTZConfiguration.NodeToken,
|
|
}
|
|
}
|
|
|
|
profiles[i] = profile
|
|
}
|
|
|
|
return profiles, nil
|
|
}
|
|
|
|
// GetStreamURI retrieves the stream URI for a profile.
|
|
func (c *Client) GetStreamURI(ctx context.Context, profileToken string) (*MediaURI, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetStreamURI struct {
|
|
XMLName xml.Name `xml:"trt:GetStreamUri"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
Xmlnst string `xml:"xmlns:tt,attr"`
|
|
StreamSetup struct {
|
|
Stream string `xml:"tt:Stream"`
|
|
Transport struct {
|
|
Protocol string `xml:"tt:Protocol"`
|
|
} `xml:"tt:Transport"`
|
|
} `xml:"trt:StreamSetup"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
type GetStreamURIResponse struct {
|
|
XMLName xml.Name `xml:"GetStreamUriResponse"`
|
|
MediaURI struct {
|
|
URI string `xml:"Uri"`
|
|
InvalidAfterConnect bool `xml:"InvalidAfterConnect"`
|
|
InvalidAfterReboot bool `xml:"InvalidAfterReboot"`
|
|
Timeout string `xml:"Timeout"`
|
|
} `xml:"MediaUri"`
|
|
}
|
|
|
|
req := GetStreamURI{
|
|
Xmlns: mediaNamespace,
|
|
Xmlnst: "http://www.onvif.org/ver10/schema",
|
|
ProfileToken: profileToken,
|
|
}
|
|
req.StreamSetup.Stream = "RTP-Unicast"
|
|
req.StreamSetup.Transport.Protocol = "RTSP"
|
|
|
|
var resp GetStreamURIResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetStreamURI failed: %w", err)
|
|
}
|
|
|
|
return &MediaURI{
|
|
URI: resp.MediaURI.URI,
|
|
InvalidAfterConnect: resp.MediaURI.InvalidAfterConnect,
|
|
InvalidAfterReboot: resp.MediaURI.InvalidAfterReboot,
|
|
}, nil
|
|
}
|
|
|
|
// GetSnapshotURI retrieves the snapshot URI for a profile.
|
|
func (c *Client) GetSnapshotURI(ctx context.Context, profileToken string) (*MediaURI, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetSnapshotURI struct {
|
|
XMLName xml.Name `xml:"trt:GetSnapshotUri"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
type GetSnapshotURIResponse struct {
|
|
XMLName xml.Name `xml:"GetSnapshotUriResponse"`
|
|
MediaURI struct {
|
|
URI string `xml:"Uri"`
|
|
InvalidAfterConnect bool `xml:"InvalidAfterConnect"`
|
|
InvalidAfterReboot bool `xml:"InvalidAfterReboot"`
|
|
Timeout string `xml:"Timeout"`
|
|
} `xml:"MediaUri"`
|
|
}
|
|
|
|
req := GetSnapshotURI{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
var resp GetSnapshotURIResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetSnapshotURI failed: %w", err)
|
|
}
|
|
|
|
return &MediaURI{
|
|
URI: resp.MediaURI.URI,
|
|
InvalidAfterConnect: resp.MediaURI.InvalidAfterConnect,
|
|
InvalidAfterReboot: resp.MediaURI.InvalidAfterReboot,
|
|
}, nil
|
|
}
|
|
|
|
// GetVideoEncoderConfiguration retrieves video encoder configuration.
|
|
func (c *Client) GetVideoEncoderConfiguration(
|
|
ctx context.Context,
|
|
configurationToken string,
|
|
) (*VideoEncoderConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetVideoEncoderConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:GetVideoEncoderConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken"`
|
|
}
|
|
|
|
type GetVideoEncoderConfigurationResponse struct {
|
|
XMLName xml.Name `xml:"GetVideoEncoderConfigurationResponse"`
|
|
Configuration struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
Encoding string `xml:"Encoding"`
|
|
Resolution *struct {
|
|
Width int `xml:"Width"`
|
|
Height int `xml:"Height"`
|
|
} `xml:"Resolution"`
|
|
Quality float64 `xml:"Quality"`
|
|
RateControl *struct {
|
|
FrameRateLimit int `xml:"FrameRateLimit"`
|
|
EncodingInterval int `xml:"EncodingInterval"`
|
|
BitrateLimit int `xml:"BitrateLimit"`
|
|
} `xml:"RateControl"`
|
|
} `xml:"Configuration"`
|
|
}
|
|
|
|
req := GetVideoEncoderConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ConfigurationToken: configurationToken,
|
|
}
|
|
|
|
var resp GetVideoEncoderConfigurationResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetVideoEncoderConfiguration failed: %w", err)
|
|
}
|
|
|
|
config := &VideoEncoderConfiguration{
|
|
Token: resp.Configuration.Token,
|
|
Name: resp.Configuration.Name,
|
|
UseCount: resp.Configuration.UseCount,
|
|
Encoding: resp.Configuration.Encoding,
|
|
Quality: resp.Configuration.Quality,
|
|
}
|
|
|
|
if resp.Configuration.Resolution != nil {
|
|
config.Resolution = &VideoResolution{
|
|
Width: resp.Configuration.Resolution.Width,
|
|
Height: resp.Configuration.Resolution.Height,
|
|
}
|
|
}
|
|
|
|
if resp.Configuration.RateControl != nil {
|
|
config.RateControl = &VideoRateControl{
|
|
FrameRateLimit: resp.Configuration.RateControl.FrameRateLimit,
|
|
EncodingInterval: resp.Configuration.RateControl.EncodingInterval,
|
|
BitrateLimit: resp.Configuration.RateControl.BitrateLimit,
|
|
}
|
|
}
|
|
|
|
return config, nil
|
|
}
|
|
|
|
// GetVideoSources retrieves all video sources.
|
|
func (c *Client) GetVideoSources(ctx context.Context) ([]*VideoSource, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetVideoSources struct {
|
|
XMLName xml.Name `xml:"trt:GetVideoSources"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
}
|
|
|
|
type GetVideoSourcesResponse struct {
|
|
XMLName xml.Name `xml:"GetVideoSourcesResponse"`
|
|
VideoSources []struct {
|
|
Token string `xml:"token,attr"`
|
|
Framerate float64 `xml:"Framerate"`
|
|
Resolution struct {
|
|
Width int `xml:"Width"`
|
|
Height int `xml:"Height"`
|
|
} `xml:"Resolution"`
|
|
} `xml:"VideoSources"`
|
|
}
|
|
|
|
req := GetVideoSources{
|
|
Xmlns: mediaNamespace,
|
|
}
|
|
|
|
var resp GetVideoSourcesResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetVideoSources failed: %w", err)
|
|
}
|
|
|
|
sources := make([]*VideoSource, len(resp.VideoSources))
|
|
for i, s := range resp.VideoSources {
|
|
sources[i] = &VideoSource{
|
|
Token: s.Token,
|
|
Framerate: s.Framerate,
|
|
Resolution: &VideoResolution{
|
|
Width: s.Resolution.Width,
|
|
Height: s.Resolution.Height,
|
|
},
|
|
}
|
|
}
|
|
|
|
return sources, nil
|
|
}
|
|
|
|
// GetAudioSources retrieves all audio sources.
|
|
func (c *Client) GetAudioSources(ctx context.Context) ([]*AudioSource, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetAudioSources struct {
|
|
XMLName xml.Name `xml:"trt:GetAudioSources"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
}
|
|
|
|
type GetAudioSourcesResponse struct {
|
|
XMLName xml.Name `xml:"GetAudioSourcesResponse"`
|
|
AudioSources []struct {
|
|
Token string `xml:"token,attr"`
|
|
Channels int `xml:"Channels"`
|
|
} `xml:"AudioSources"`
|
|
}
|
|
|
|
req := GetAudioSources{
|
|
Xmlns: mediaNamespace,
|
|
}
|
|
|
|
var resp GetAudioSourcesResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetAudioSources failed: %w", err)
|
|
}
|
|
|
|
sources := make([]*AudioSource, len(resp.AudioSources))
|
|
for i, s := range resp.AudioSources {
|
|
sources[i] = &AudioSource{
|
|
Token: s.Token,
|
|
Channels: s.Channels,
|
|
}
|
|
}
|
|
|
|
return sources, nil
|
|
}
|
|
|
|
// GetAudioOutputs retrieves all audio outputs.
|
|
func (c *Client) GetAudioOutputs(ctx context.Context) ([]*AudioOutput, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetAudioOutputs struct {
|
|
XMLName xml.Name `xml:"trt:GetAudioOutputs"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
}
|
|
|
|
type GetAudioOutputsResponse struct {
|
|
XMLName xml.Name `xml:"GetAudioOutputsResponse"`
|
|
AudioOutputs []struct {
|
|
Token string `xml:"token,attr"`
|
|
} `xml:"AudioOutputs"`
|
|
}
|
|
|
|
req := GetAudioOutputs{
|
|
Xmlns: mediaNamespace,
|
|
}
|
|
|
|
var resp GetAudioOutputsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetAudioOutputs failed: %w", err)
|
|
}
|
|
|
|
outputs := make([]*AudioOutput, len(resp.AudioOutputs))
|
|
for i, o := range resp.AudioOutputs {
|
|
outputs[i] = &AudioOutput{
|
|
Token: o.Token,
|
|
}
|
|
}
|
|
|
|
return outputs, nil
|
|
}
|
|
|
|
// CreateProfile creates a new media profile.
|
|
func (c *Client) CreateProfile(ctx context.Context, name, token string) (*Profile, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type CreateProfile struct {
|
|
XMLName xml.Name `xml:"trt:CreateProfile"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
Name string `xml:"trt:Name"`
|
|
Token *string `xml:"trt:Token,omitempty"`
|
|
}
|
|
|
|
type CreateProfileResponse struct {
|
|
XMLName xml.Name `xml:"CreateProfileResponse"`
|
|
Profile struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
} `xml:"Profile"`
|
|
}
|
|
|
|
req := CreateProfile{
|
|
Xmlns: mediaNamespace,
|
|
Name: name,
|
|
}
|
|
if token != "" {
|
|
req.Token = &token
|
|
}
|
|
|
|
var resp CreateProfileResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("CreateProfile failed: %w", err)
|
|
}
|
|
|
|
return &Profile{
|
|
Token: resp.Profile.Token,
|
|
Name: resp.Profile.Name,
|
|
}, nil
|
|
}
|
|
|
|
// DeleteProfile deletes a media profile.
|
|
func (c *Client) DeleteProfile(ctx context.Context, profileToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type DeleteProfile struct {
|
|
XMLName xml.Name `xml:"trt:DeleteProfile"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
req := DeleteProfile{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("DeleteProfile failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// SetVideoEncoderConfiguration sets video encoder configuration.
|
|
func (c *Client) SetVideoEncoderConfiguration(
|
|
ctx context.Context,
|
|
config *VideoEncoderConfiguration,
|
|
forcePersistence bool,
|
|
) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type SetVideoEncoderConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:SetVideoEncoderConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
Xmlnst string `xml:"xmlns:tt,attr"`
|
|
Configuration struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"tt:Name"`
|
|
UseCount int `xml:"tt:UseCount"`
|
|
Encoding string `xml:"tt:Encoding"`
|
|
Resolution *struct {
|
|
Width int `xml:"tt:Width"`
|
|
Height int `xml:"tt:Height"`
|
|
} `xml:"tt:Resolution,omitempty"`
|
|
Quality *float64 `xml:"tt:Quality,omitempty"`
|
|
RateControl *struct {
|
|
FrameRateLimit int `xml:"tt:FrameRateLimit"`
|
|
EncodingInterval int `xml:"tt:EncodingInterval"`
|
|
BitrateLimit int `xml:"tt:BitrateLimit"`
|
|
} `xml:"tt:RateControl,omitempty"`
|
|
} `xml:"trt:Configuration"`
|
|
ForcePersistence bool `xml:"trt:ForcePersistence"`
|
|
}
|
|
|
|
req := SetVideoEncoderConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
Xmlnst: "http://www.onvif.org/ver10/schema",
|
|
ForcePersistence: forcePersistence,
|
|
}
|
|
|
|
req.Configuration.Token = config.Token
|
|
req.Configuration.Name = config.Name
|
|
req.Configuration.UseCount = config.UseCount
|
|
req.Configuration.Encoding = config.Encoding
|
|
|
|
if config.Resolution != nil {
|
|
req.Configuration.Resolution = &struct {
|
|
Width int `xml:"tt:Width"`
|
|
Height int `xml:"tt:Height"`
|
|
}{
|
|
Width: config.Resolution.Width,
|
|
Height: config.Resolution.Height,
|
|
}
|
|
}
|
|
|
|
if config.Quality > 0 {
|
|
req.Configuration.Quality = &config.Quality
|
|
}
|
|
|
|
if config.RateControl != nil {
|
|
req.Configuration.RateControl = &struct {
|
|
FrameRateLimit int `xml:"tt:FrameRateLimit"`
|
|
EncodingInterval int `xml:"tt:EncodingInterval"`
|
|
BitrateLimit int `xml:"tt:BitrateLimit"`
|
|
}{
|
|
FrameRateLimit: config.RateControl.FrameRateLimit,
|
|
EncodingInterval: config.RateControl.EncodingInterval,
|
|
BitrateLimit: config.RateControl.BitrateLimit,
|
|
}
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("SetVideoEncoderConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetMediaServiceCapabilities retrieves media service capabilities.
|
|
func (c *Client) GetMediaServiceCapabilities(ctx context.Context) (*MediaServiceCapabilities, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetServiceCapabilities struct {
|
|
XMLName xml.Name `xml:"trt:GetServiceCapabilities"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
}
|
|
|
|
type GetServiceCapabilitiesResponse struct {
|
|
XMLName xml.Name `xml:"GetServiceCapabilitiesResponse"`
|
|
Capabilities struct {
|
|
SnapshotURI bool `xml:"SnapshotUri,attr"`
|
|
Rotation bool `xml:"Rotation,attr"`
|
|
VideoSourceMode bool `xml:"VideoSourceMode,attr"`
|
|
OSD bool `xml:"OSD,attr"`
|
|
TemporaryOSDText bool `xml:"TemporaryOSDText,attr"`
|
|
EXICompression bool `xml:"EXICompression,attr"`
|
|
ProfileCapabilities *struct {
|
|
MaximumNumberOfProfiles int `xml:"MaximumNumberOfProfiles,attr"`
|
|
} `xml:"ProfileCapabilities"`
|
|
StreamingCapabilities *struct {
|
|
RTPMulticast bool `xml:"RTPMulticast,attr"`
|
|
RTPTCP bool `xml:"RTP_TCP,attr"`
|
|
RTPRTSPTCP bool `xml:"RTP_RTSP_TCP,attr"`
|
|
} `xml:"StreamingCapabilities"`
|
|
} `xml:"Capabilities"`
|
|
}
|
|
|
|
req := GetServiceCapabilities{
|
|
Xmlns: mediaNamespace,
|
|
}
|
|
|
|
var resp GetServiceCapabilitiesResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetMediaServiceCapabilities failed: %w", err)
|
|
}
|
|
|
|
caps := &MediaServiceCapabilities{
|
|
SnapshotURI: resp.Capabilities.SnapshotURI,
|
|
Rotation: resp.Capabilities.Rotation,
|
|
VideoSourceMode: resp.Capabilities.VideoSourceMode,
|
|
OSD: resp.Capabilities.OSD,
|
|
TemporaryOSDText: resp.Capabilities.TemporaryOSDText,
|
|
EXICompression: resp.Capabilities.EXICompression,
|
|
}
|
|
|
|
if resp.Capabilities.ProfileCapabilities != nil {
|
|
caps.MaximumNumberOfProfiles = resp.Capabilities.ProfileCapabilities.MaximumNumberOfProfiles
|
|
}
|
|
|
|
if resp.Capabilities.StreamingCapabilities != nil {
|
|
caps.RTPMulticast = resp.Capabilities.StreamingCapabilities.RTPMulticast
|
|
caps.RTPTCP = resp.Capabilities.StreamingCapabilities.RTPTCP
|
|
caps.RTPRTSPTCP = resp.Capabilities.StreamingCapabilities.RTPRTSPTCP
|
|
}
|
|
|
|
return caps, nil
|
|
}
|
|
|
|
// GetVideoEncoderConfigurationOptions retrieves available options for video encoder configuration.
|
|
//
|
|
//nolint:funlen // GetVideoEncoderConfigurationOptions has many statements due to parsing complex encoder options
|
|
func (c *Client) GetVideoEncoderConfigurationOptions(
|
|
ctx context.Context, configurationToken string,
|
|
) (*VideoEncoderConfigurationOptions, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetVideoEncoderConfigurationOptions struct {
|
|
XMLName xml.Name `xml:"trt:GetVideoEncoderConfigurationOptions"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken,omitempty"`
|
|
ProfileToken string `xml:"trt:ProfileToken,omitempty"`
|
|
}
|
|
|
|
type GetVideoEncoderConfigurationOptionsResponse struct {
|
|
XMLName xml.Name `xml:"GetVideoEncoderConfigurationOptionsResponse"`
|
|
Options struct {
|
|
QualityRange *struct {
|
|
Min float64 `xml:"Min"`
|
|
Max float64 `xml:"Max"`
|
|
} `xml:"QualityRange"`
|
|
JPEG *struct {
|
|
ResolutionsAvailable []struct {
|
|
Width int `xml:"Width"`
|
|
Height int `xml:"Height"`
|
|
} `xml:"ResolutionsAvailable"`
|
|
FrameRateRange *struct {
|
|
Min float64 `xml:"Min"`
|
|
Max float64 `xml:"Max"`
|
|
} `xml:"FrameRateRange"`
|
|
EncodingIntervalRange *struct {
|
|
Min int `xml:"Min"`
|
|
Max int `xml:"Max"`
|
|
} `xml:"EncodingIntervalRange"`
|
|
} `xml:"JPEG"`
|
|
H264 *struct {
|
|
ResolutionsAvailable []struct {
|
|
Width int `xml:"Width"`
|
|
Height int `xml:"Height"`
|
|
} `xml:"ResolutionsAvailable"`
|
|
GovLengthRange *struct {
|
|
Min int `xml:"Min"`
|
|
Max int `xml:"Max"`
|
|
} `xml:"GovLengthRange"`
|
|
FrameRateRange *struct {
|
|
Min float64 `xml:"Min"`
|
|
Max float64 `xml:"Max"`
|
|
} `xml:"FrameRateRange"`
|
|
EncodingIntervalRange *struct {
|
|
Min int `xml:"Min"`
|
|
Max int `xml:"Max"`
|
|
} `xml:"EncodingIntervalRange"`
|
|
H264ProfilesSupported []string `xml:"H264ProfilesSupported"`
|
|
} `xml:"H264"`
|
|
Extension struct{} `xml:"Extension"`
|
|
} `xml:"Options"`
|
|
}
|
|
|
|
req := GetVideoEncoderConfigurationOptions{
|
|
Xmlns: mediaNamespace,
|
|
}
|
|
if configurationToken != "" {
|
|
req.ConfigurationToken = configurationToken
|
|
}
|
|
|
|
var resp GetVideoEncoderConfigurationOptionsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetVideoEncoderConfigurationOptions failed: %w", err)
|
|
}
|
|
|
|
options := &VideoEncoderConfigurationOptions{}
|
|
|
|
if resp.Options.QualityRange != nil {
|
|
options.QualityRange = &FloatRange{
|
|
Min: resp.Options.QualityRange.Min,
|
|
Max: resp.Options.QualityRange.Max,
|
|
}
|
|
}
|
|
|
|
if resp.Options.JPEG != nil {
|
|
jpegOpts := &JPEGOptions{}
|
|
if resp.Options.JPEG.FrameRateRange != nil {
|
|
jpegOpts.FrameRateRange = &FloatRange{
|
|
Min: resp.Options.JPEG.FrameRateRange.Min,
|
|
Max: resp.Options.JPEG.FrameRateRange.Max,
|
|
}
|
|
}
|
|
if resp.Options.JPEG.EncodingIntervalRange != nil {
|
|
jpegOpts.EncodingIntervalRange = &IntRange{
|
|
Min: resp.Options.JPEG.EncodingIntervalRange.Min,
|
|
Max: resp.Options.JPEG.EncodingIntervalRange.Max,
|
|
}
|
|
}
|
|
for _, res := range resp.Options.JPEG.ResolutionsAvailable {
|
|
jpegOpts.ResolutionsAvailable = append(jpegOpts.ResolutionsAvailable, &VideoResolution{
|
|
Width: res.Width,
|
|
Height: res.Height,
|
|
})
|
|
}
|
|
options.JPEG = jpegOpts
|
|
}
|
|
|
|
if resp.Options.H264 != nil {
|
|
h264Opts := &H264Options{}
|
|
if resp.Options.H264.FrameRateRange != nil {
|
|
h264Opts.FrameRateRange = &FloatRange{
|
|
Min: resp.Options.H264.FrameRateRange.Min,
|
|
Max: resp.Options.H264.FrameRateRange.Max,
|
|
}
|
|
}
|
|
if resp.Options.H264.GovLengthRange != nil {
|
|
h264Opts.GovLengthRange = &IntRange{
|
|
Min: resp.Options.H264.GovLengthRange.Min,
|
|
Max: resp.Options.H264.GovLengthRange.Max,
|
|
}
|
|
}
|
|
if resp.Options.H264.EncodingIntervalRange != nil {
|
|
h264Opts.EncodingIntervalRange = &IntRange{
|
|
Min: resp.Options.H264.EncodingIntervalRange.Min,
|
|
Max: resp.Options.H264.EncodingIntervalRange.Max,
|
|
}
|
|
}
|
|
for _, res := range resp.Options.H264.ResolutionsAvailable {
|
|
h264Opts.ResolutionsAvailable = append(h264Opts.ResolutionsAvailable, &VideoResolution{
|
|
Width: res.Width,
|
|
Height: res.Height,
|
|
})
|
|
}
|
|
h264Opts.H264ProfilesSupported = resp.Options.H264.H264ProfilesSupported
|
|
options.H264 = h264Opts
|
|
}
|
|
|
|
return options, nil
|
|
}
|
|
|
|
// GetAudioEncoderConfiguration retrieves audio encoder configuration.
|
|
func (c *Client) GetAudioEncoderConfiguration(
|
|
ctx context.Context,
|
|
configurationToken string,
|
|
) (*AudioEncoderConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetAudioEncoderConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:GetAudioEncoderConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken"`
|
|
}
|
|
|
|
type GetAudioEncoderConfigurationResponse struct {
|
|
XMLName xml.Name `xml:"GetAudioEncoderConfigurationResponse"`
|
|
Configuration struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
Encoding string `xml:"Encoding"`
|
|
Bitrate int `xml:"Bitrate"`
|
|
SampleRate int `xml:"SampleRate"`
|
|
Multicast *struct {
|
|
Address *struct {
|
|
Type string `xml:"Type"`
|
|
IPv4Address string `xml:"IPv4Address"`
|
|
IPv6Address string `xml:"IPv6Address"`
|
|
} `xml:"Address"`
|
|
Port int `xml:"Port"`
|
|
TTL int `xml:"TTL"`
|
|
AutoStart bool `xml:"AutoStart"`
|
|
} `xml:"Multicast"`
|
|
SessionTimeout string `xml:"SessionTimeout"`
|
|
} `xml:"Configuration"`
|
|
}
|
|
|
|
req := GetAudioEncoderConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ConfigurationToken: configurationToken,
|
|
}
|
|
|
|
var resp GetAudioEncoderConfigurationResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetAudioEncoderConfiguration failed: %w", err)
|
|
}
|
|
|
|
config := &AudioEncoderConfiguration{
|
|
Token: resp.Configuration.Token,
|
|
Name: resp.Configuration.Name,
|
|
UseCount: resp.Configuration.UseCount,
|
|
Encoding: resp.Configuration.Encoding,
|
|
Bitrate: resp.Configuration.Bitrate,
|
|
SampleRate: resp.Configuration.SampleRate,
|
|
}
|
|
|
|
if resp.Configuration.Multicast != nil {
|
|
config.Multicast = &MulticastConfiguration{
|
|
Port: resp.Configuration.Multicast.Port,
|
|
TTL: resp.Configuration.Multicast.TTL,
|
|
AutoStart: resp.Configuration.Multicast.AutoStart,
|
|
}
|
|
if resp.Configuration.Multicast.Address != nil {
|
|
config.Multicast.Address = &IPAddress{
|
|
Type: resp.Configuration.Multicast.Address.Type,
|
|
IPv4Address: resp.Configuration.Multicast.Address.IPv4Address,
|
|
IPv6Address: resp.Configuration.Multicast.Address.IPv6Address,
|
|
}
|
|
}
|
|
}
|
|
|
|
return config, nil
|
|
}
|
|
|
|
// SetAudioEncoderConfiguration sets audio encoder configuration.
|
|
func (c *Client) SetAudioEncoderConfiguration(
|
|
ctx context.Context,
|
|
config *AudioEncoderConfiguration,
|
|
forcePersistence bool,
|
|
) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type SetAudioEncoderConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:SetAudioEncoderConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
Xmlnst string `xml:"xmlns:tt,attr"`
|
|
Configuration struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"tt:Name"`
|
|
UseCount int `xml:"tt:UseCount"`
|
|
Encoding string `xml:"tt:Encoding"`
|
|
Bitrate int `xml:"tt:Bitrate,omitempty"`
|
|
SampleRate int `xml:"tt:SampleRate,omitempty"`
|
|
Multicast *struct {
|
|
Address *struct {
|
|
Type string `xml:"tt:Type"`
|
|
IPv4Address string `xml:"tt:IPv4Address,omitempty"`
|
|
IPv6Address string `xml:"tt:IPv6Address,omitempty"`
|
|
} `xml:"tt:Address,omitempty"`
|
|
Port int `xml:"tt:Port,omitempty"`
|
|
TTL int `xml:"tt:TTL,omitempty"`
|
|
AutoStart bool `xml:"tt:AutoStart,omitempty"`
|
|
} `xml:"tt:Multicast,omitempty"`
|
|
SessionTimeout string `xml:"tt:SessionTimeout,omitempty"`
|
|
} `xml:"trt:Configuration"`
|
|
ForcePersistence bool `xml:"trt:ForcePersistence"`
|
|
}
|
|
|
|
req := SetAudioEncoderConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
Xmlnst: "http://www.onvif.org/ver10/schema",
|
|
ForcePersistence: forcePersistence,
|
|
}
|
|
|
|
req.Configuration.Token = config.Token
|
|
req.Configuration.Name = config.Name
|
|
req.Configuration.UseCount = config.UseCount
|
|
req.Configuration.Encoding = config.Encoding
|
|
if config.Bitrate > 0 {
|
|
req.Configuration.Bitrate = config.Bitrate
|
|
}
|
|
if config.SampleRate > 0 {
|
|
req.Configuration.SampleRate = config.SampleRate
|
|
}
|
|
|
|
if config.Multicast != nil {
|
|
req.Configuration.Multicast = &struct {
|
|
Address *struct {
|
|
Type string `xml:"tt:Type"`
|
|
IPv4Address string `xml:"tt:IPv4Address,omitempty"`
|
|
IPv6Address string `xml:"tt:IPv6Address,omitempty"`
|
|
} `xml:"tt:Address,omitempty"`
|
|
Port int `xml:"tt:Port,omitempty"`
|
|
TTL int `xml:"tt:TTL,omitempty"`
|
|
AutoStart bool `xml:"tt:AutoStart,omitempty"`
|
|
}{
|
|
Port: config.Multicast.Port,
|
|
TTL: config.Multicast.TTL,
|
|
AutoStart: config.Multicast.AutoStart,
|
|
}
|
|
if config.Multicast.Address != nil {
|
|
req.Configuration.Multicast.Address = &struct {
|
|
Type string `xml:"tt:Type"`
|
|
IPv4Address string `xml:"tt:IPv4Address,omitempty"`
|
|
IPv6Address string `xml:"tt:IPv6Address,omitempty"`
|
|
}{
|
|
Type: config.Multicast.Address.Type,
|
|
IPv4Address: config.Multicast.Address.IPv4Address,
|
|
IPv6Address: config.Multicast.Address.IPv6Address,
|
|
}
|
|
}
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("SetAudioEncoderConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetMetadataConfiguration retrieves metadata configuration.
|
|
func (c *Client) GetMetadataConfiguration(
|
|
ctx context.Context,
|
|
configurationToken string,
|
|
) (*MetadataConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetMetadataConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:GetMetadataConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken"`
|
|
}
|
|
|
|
type GetMetadataConfigurationResponse struct {
|
|
XMLName xml.Name `xml:"GetMetadataConfigurationResponse"`
|
|
Configuration struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
PTZStatus *struct {
|
|
Status bool `xml:"Status"`
|
|
Position bool `xml:"Position"`
|
|
} `xml:"PTZStatus"`
|
|
Events *struct{} `xml:"Events"`
|
|
Analytics bool `xml:"Analytics"`
|
|
Multicast *struct {
|
|
Address *struct {
|
|
Type string `xml:"Type"`
|
|
IPv4Address string `xml:"IPv4Address"`
|
|
IPv6Address string `xml:"IPv6Address"`
|
|
} `xml:"Address"`
|
|
Port int `xml:"Port"`
|
|
TTL int `xml:"TTL"`
|
|
AutoStart bool `xml:"AutoStart"`
|
|
} `xml:"Multicast"`
|
|
SessionTimeout string `xml:"SessionTimeout"`
|
|
} `xml:"Configuration"`
|
|
}
|
|
|
|
req := GetMetadataConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ConfigurationToken: configurationToken,
|
|
}
|
|
|
|
var resp GetMetadataConfigurationResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetMetadataConfiguration failed: %w", err)
|
|
}
|
|
|
|
config := &MetadataConfiguration{
|
|
Token: resp.Configuration.Token,
|
|
Name: resp.Configuration.Name,
|
|
UseCount: resp.Configuration.UseCount,
|
|
Analytics: resp.Configuration.Analytics,
|
|
}
|
|
|
|
if resp.Configuration.PTZStatus != nil {
|
|
config.PTZStatus = &PTZFilter{
|
|
Status: resp.Configuration.PTZStatus.Status,
|
|
Position: resp.Configuration.PTZStatus.Position,
|
|
}
|
|
}
|
|
|
|
if resp.Configuration.Events != nil {
|
|
config.Events = &EventSubscription{}
|
|
}
|
|
|
|
if resp.Configuration.Multicast != nil {
|
|
config.Multicast = &MulticastConfiguration{
|
|
Port: resp.Configuration.Multicast.Port,
|
|
TTL: resp.Configuration.Multicast.TTL,
|
|
AutoStart: resp.Configuration.Multicast.AutoStart,
|
|
}
|
|
if resp.Configuration.Multicast.Address != nil {
|
|
config.Multicast.Address = &IPAddress{
|
|
Type: resp.Configuration.Multicast.Address.Type,
|
|
IPv4Address: resp.Configuration.Multicast.Address.IPv4Address,
|
|
IPv6Address: resp.Configuration.Multicast.Address.IPv6Address,
|
|
}
|
|
}
|
|
}
|
|
|
|
return config, nil
|
|
}
|
|
|
|
// SetMetadataConfiguration sets metadata configuration.
|
|
func (c *Client) SetMetadataConfiguration(
|
|
ctx context.Context,
|
|
config *MetadataConfiguration,
|
|
forcePersistence bool,
|
|
) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type SetMetadataConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:SetMetadataConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
Xmlnst string `xml:"xmlns:tt,attr"`
|
|
Configuration struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"tt:Name"`
|
|
UseCount int `xml:"tt:UseCount"`
|
|
PTZStatus *struct {
|
|
Status bool `xml:"tt:Status"`
|
|
Position bool `xml:"tt:Position"`
|
|
} `xml:"tt:PTZStatus,omitempty"`
|
|
Events *struct{} `xml:"tt:Events,omitempty"`
|
|
Analytics bool `xml:"tt:Analytics,omitempty"`
|
|
Multicast *struct {
|
|
Address *struct {
|
|
Type string `xml:"tt:Type"`
|
|
IPv4Address string `xml:"tt:IPv4Address,omitempty"`
|
|
IPv6Address string `xml:"tt:IPv6Address,omitempty"`
|
|
} `xml:"tt:Address,omitempty"`
|
|
Port int `xml:"tt:Port,omitempty"`
|
|
TTL int `xml:"tt:TTL,omitempty"`
|
|
AutoStart bool `xml:"tt:AutoStart,omitempty"`
|
|
} `xml:"tt:Multicast,omitempty"`
|
|
SessionTimeout string `xml:"tt:SessionTimeout,omitempty"`
|
|
} `xml:"trt:Configuration"`
|
|
ForcePersistence bool `xml:"trt:ForcePersistence"`
|
|
}
|
|
|
|
req := SetMetadataConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
Xmlnst: "http://www.onvif.org/ver10/schema",
|
|
ForcePersistence: forcePersistence,
|
|
}
|
|
|
|
req.Configuration.Token = config.Token
|
|
req.Configuration.Name = config.Name
|
|
req.Configuration.UseCount = config.UseCount
|
|
req.Configuration.Analytics = config.Analytics
|
|
|
|
if config.PTZStatus != nil {
|
|
req.Configuration.PTZStatus = &struct {
|
|
Status bool `xml:"tt:Status"`
|
|
Position bool `xml:"tt:Position"`
|
|
}{
|
|
Status: config.PTZStatus.Status,
|
|
Position: config.PTZStatus.Position,
|
|
}
|
|
}
|
|
|
|
if config.Events != nil {
|
|
req.Configuration.Events = &struct{}{}
|
|
}
|
|
|
|
if config.Multicast != nil {
|
|
req.Configuration.Multicast = &struct {
|
|
Address *struct {
|
|
Type string `xml:"tt:Type"`
|
|
IPv4Address string `xml:"tt:IPv4Address,omitempty"`
|
|
IPv6Address string `xml:"tt:IPv6Address,omitempty"`
|
|
} `xml:"tt:Address,omitempty"`
|
|
Port int `xml:"tt:Port,omitempty"`
|
|
TTL int `xml:"tt:TTL,omitempty"`
|
|
AutoStart bool `xml:"tt:AutoStart,omitempty"`
|
|
}{
|
|
Port: config.Multicast.Port,
|
|
TTL: config.Multicast.TTL,
|
|
AutoStart: config.Multicast.AutoStart,
|
|
}
|
|
if config.Multicast.Address != nil {
|
|
req.Configuration.Multicast.Address = &struct {
|
|
Type string `xml:"tt:Type"`
|
|
IPv4Address string `xml:"tt:IPv4Address,omitempty"`
|
|
IPv6Address string `xml:"tt:IPv6Address,omitempty"`
|
|
}{
|
|
Type: config.Multicast.Address.Type,
|
|
IPv4Address: config.Multicast.Address.IPv4Address,
|
|
IPv6Address: config.Multicast.Address.IPv6Address,
|
|
}
|
|
}
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("SetMetadataConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetVideoSourceModes retrieves available video source modes.
|
|
func (c *Client) GetVideoSourceModes(ctx context.Context, videoSourceToken string) ([]*VideoSourceMode, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetVideoSourceModes struct {
|
|
XMLName xml.Name `xml:"trt:GetVideoSourceModes"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
VideoSourceToken string `xml:"trt:VideoSourceToken"`
|
|
}
|
|
|
|
type GetVideoSourceModesResponse struct {
|
|
XMLName xml.Name `xml:"GetVideoSourceModesResponse"`
|
|
VideoSourceModes []struct {
|
|
Token string `xml:"token,attr"`
|
|
Enabled bool `xml:"Enabled"`
|
|
Resolution struct {
|
|
Width int `xml:"Width"`
|
|
Height int `xml:"Height"`
|
|
} `xml:"Resolution"`
|
|
} `xml:"VideoSourceModes"`
|
|
}
|
|
|
|
req := GetVideoSourceModes{
|
|
Xmlns: mediaNamespace,
|
|
VideoSourceToken: videoSourceToken,
|
|
}
|
|
|
|
var resp GetVideoSourceModesResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetVideoSourceModes failed: %w", err)
|
|
}
|
|
|
|
modes := make([]*VideoSourceMode, len(resp.VideoSourceModes))
|
|
for i, m := range resp.VideoSourceModes {
|
|
modes[i] = &VideoSourceMode{
|
|
Token: m.Token,
|
|
Enabled: m.Enabled,
|
|
Resolution: &VideoResolution{
|
|
Width: m.Resolution.Width,
|
|
Height: m.Resolution.Height,
|
|
},
|
|
}
|
|
}
|
|
|
|
return modes, nil
|
|
}
|
|
|
|
// SetVideoSourceMode sets the video source mode.
|
|
func (c *Client) SetVideoSourceMode(ctx context.Context, videoSourceToken, modeToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type SetVideoSourceMode struct {
|
|
XMLName xml.Name `xml:"trt:SetVideoSourceMode"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
VideoSourceToken string `xml:"trt:VideoSourceToken"`
|
|
ModeToken string `xml:"trt:ModeToken"`
|
|
}
|
|
|
|
req := SetVideoSourceMode{
|
|
Xmlns: mediaNamespace,
|
|
VideoSourceToken: videoSourceToken,
|
|
ModeToken: modeToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("SetVideoSourceMode failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// SetSynchronizationPoint sets a synchronization point for the stream.
|
|
func (c *Client) SetSynchronizationPoint(ctx context.Context, profileToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type SetSynchronizationPoint struct {
|
|
XMLName xml.Name `xml:"trt:SetSynchronizationPoint"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
req := SetSynchronizationPoint{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("SetSynchronizationPoint failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetOSDs retrieves all OSD configurations.
|
|
func (c *Client) GetOSDs(ctx context.Context, configurationToken string) ([]*OSDConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetOSDs struct {
|
|
XMLName xml.Name `xml:"trt:GetOSDs"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken,omitempty"`
|
|
}
|
|
|
|
type GetOSDsResponse struct {
|
|
XMLName xml.Name `xml:"GetOSDsResponse"`
|
|
OSDs []struct {
|
|
Token string `xml:"token,attr"`
|
|
} `xml:"OSDs"`
|
|
}
|
|
|
|
req := GetOSDs{
|
|
Xmlns: mediaNamespace,
|
|
}
|
|
if configurationToken != "" {
|
|
req.ConfigurationToken = configurationToken
|
|
}
|
|
|
|
var resp GetOSDsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetOSDs failed: %w", err)
|
|
}
|
|
|
|
osds := make([]*OSDConfiguration, len(resp.OSDs))
|
|
for i, o := range resp.OSDs {
|
|
osds[i] = &OSDConfiguration{
|
|
Token: o.Token,
|
|
}
|
|
}
|
|
|
|
return osds, nil
|
|
}
|
|
|
|
// GetOSD retrieves a specific OSD configuration.
|
|
func (c *Client) GetOSD(ctx context.Context, osdToken string) (*OSDConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetOSD struct {
|
|
XMLName xml.Name `xml:"trt:GetOSD"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
OSDToken string `xml:"trt:OSDToken"`
|
|
}
|
|
|
|
type GetOSDResponse struct {
|
|
XMLName xml.Name `xml:"GetOSDResponse"`
|
|
OSD struct {
|
|
Token string `xml:"token,attr"`
|
|
} `xml:"OSD"`
|
|
}
|
|
|
|
req := GetOSD{
|
|
Xmlns: mediaNamespace,
|
|
OSDToken: osdToken,
|
|
}
|
|
|
|
var resp GetOSDResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetOSD failed: %w", err)
|
|
}
|
|
|
|
return &OSDConfiguration{
|
|
Token: resp.OSD.Token,
|
|
}, nil
|
|
}
|
|
|
|
// SetOSD sets OSD configuration.
|
|
func (c *Client) SetOSD(ctx context.Context, osd *OSDConfiguration) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type SetOSD struct {
|
|
XMLName xml.Name `xml:"trt:SetOSD"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
Xmlnst string `xml:"xmlns:tt,attr"`
|
|
OSD struct {
|
|
Token string `xml:"token,attr"`
|
|
} `xml:"trt:OSD"`
|
|
}
|
|
|
|
req := SetOSD{
|
|
Xmlns: mediaNamespace,
|
|
Xmlnst: "http://www.onvif.org/ver10/schema",
|
|
}
|
|
req.OSD.Token = osd.Token
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("SetOSD failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// CreateOSD creates a new OSD configuration.
|
|
func (c *Client) CreateOSD(
|
|
ctx context.Context,
|
|
videoSourceConfigurationToken string,
|
|
osd *OSDConfiguration,
|
|
) (*OSDConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type CreateOSD struct {
|
|
XMLName xml.Name `xml:"trt:CreateOSD"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
Xmlnst string `xml:"xmlns:tt,attr"`
|
|
VideoSourceConfigurationToken string `xml:"trt:VideoSourceConfigurationToken"`
|
|
OSD struct {
|
|
Token string `xml:"token,attr,omitempty"`
|
|
} `xml:"trt:OSD"`
|
|
}
|
|
|
|
type CreateOSDResponse struct {
|
|
XMLName xml.Name `xml:"CreateOSDResponse"`
|
|
OSD struct {
|
|
Token string `xml:"token,attr"`
|
|
} `xml:"OSD"`
|
|
}
|
|
|
|
req := CreateOSD{
|
|
Xmlns: mediaNamespace,
|
|
Xmlnst: "http://www.onvif.org/ver10/schema",
|
|
VideoSourceConfigurationToken: videoSourceConfigurationToken,
|
|
}
|
|
if osd != nil && osd.Token != "" {
|
|
req.OSD.Token = osd.Token
|
|
}
|
|
|
|
var resp CreateOSDResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("CreateOSD failed: %w", err)
|
|
}
|
|
|
|
return &OSDConfiguration{
|
|
Token: resp.OSD.Token,
|
|
}, nil
|
|
}
|
|
|
|
// DeleteOSD deletes an OSD configuration.
|
|
func (c *Client) DeleteOSD(ctx context.Context, osdToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type DeleteOSD struct {
|
|
XMLName xml.Name `xml:"trt:DeleteOSD"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
OSDToken string `xml:"trt:OSDToken"`
|
|
}
|
|
|
|
req := DeleteOSD{
|
|
Xmlns: mediaNamespace,
|
|
OSDToken: osdToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("DeleteOSD failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// StartMulticastStreaming starts multicast streaming.
|
|
func (c *Client) StartMulticastStreaming(ctx context.Context, profileToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type StartMulticastStreaming struct {
|
|
XMLName xml.Name `xml:"trt:StartMulticastStreaming"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
req := StartMulticastStreaming{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("StartMulticastStreaming failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// StopMulticastStreaming stops multicast streaming.
|
|
func (c *Client) StopMulticastStreaming(ctx context.Context, profileToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type StopMulticastStreaming struct {
|
|
XMLName xml.Name `xml:"trt:StopMulticastStreaming"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
req := StopMulticastStreaming{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("StopMulticastStreaming failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetProfile retrieves a specific media profile.
|
|
func (c *Client) GetProfile(ctx context.Context, profileToken string) (*Profile, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetProfile struct {
|
|
XMLName xml.Name `xml:"trt:GetProfile"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
type GetProfileResponse struct {
|
|
XMLName xml.Name `xml:"GetProfileResponse"`
|
|
Profile struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
} `xml:"Profile"`
|
|
}
|
|
|
|
req := GetProfile{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
var resp GetProfileResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetProfile failed: %w", err)
|
|
}
|
|
|
|
return &Profile{
|
|
Token: resp.Profile.Token,
|
|
Name: resp.Profile.Name,
|
|
}, nil
|
|
}
|
|
|
|
// SetProfile sets profile configuration.
|
|
func (c *Client) SetProfile(ctx context.Context, profile *Profile) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type SetProfile struct {
|
|
XMLName xml.Name `xml:"trt:SetProfile"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
Xmlnst string `xml:"xmlns:tt,attr"`
|
|
Profile struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"tt:Name"`
|
|
} `xml:"trt:Profile"`
|
|
}
|
|
|
|
req := SetProfile{
|
|
Xmlns: mediaNamespace,
|
|
Xmlnst: "http://www.onvif.org/ver10/schema",
|
|
}
|
|
req.Profile.Token = profile.Token
|
|
req.Profile.Name = profile.Name
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("SetProfile failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// AddVideoEncoderConfiguration adds video encoder configuration to a profile.
|
|
func (c *Client) AddVideoEncoderConfiguration(ctx context.Context, profileToken, configurationToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type AddVideoEncoderConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:AddVideoEncoderConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken"`
|
|
}
|
|
|
|
req := AddVideoEncoderConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
ConfigurationToken: configurationToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("AddVideoEncoderConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// RemoveVideoEncoderConfiguration removes video encoder configuration from a profile.
|
|
func (c *Client) RemoveVideoEncoderConfiguration(ctx context.Context, profileToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type RemoveVideoEncoderConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:RemoveVideoEncoderConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
req := RemoveVideoEncoderConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("RemoveVideoEncoderConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// AddAudioEncoderConfiguration adds audio encoder configuration to a profile.
|
|
func (c *Client) AddAudioEncoderConfiguration(ctx context.Context, profileToken, configurationToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type AddAudioEncoderConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:AddAudioEncoderConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken"`
|
|
}
|
|
|
|
req := AddAudioEncoderConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
ConfigurationToken: configurationToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("AddAudioEncoderConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// RemoveAudioEncoderConfiguration removes audio encoder configuration from a profile.
|
|
func (c *Client) RemoveAudioEncoderConfiguration(ctx context.Context, profileToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type RemoveAudioEncoderConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:RemoveAudioEncoderConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
req := RemoveAudioEncoderConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("RemoveAudioEncoderConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// AddAudioSourceConfiguration adds audio source configuration to a profile.
|
|
func (c *Client) AddAudioSourceConfiguration(ctx context.Context, profileToken, configurationToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type AddAudioSourceConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:AddAudioSourceConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken"`
|
|
}
|
|
|
|
req := AddAudioSourceConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
ConfigurationToken: configurationToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("AddAudioSourceConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// RemoveAudioSourceConfiguration removes audio source configuration from a profile.
|
|
func (c *Client) RemoveAudioSourceConfiguration(ctx context.Context, profileToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type RemoveAudioSourceConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:RemoveAudioSourceConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
req := RemoveAudioSourceConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("RemoveAudioSourceConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// AddVideoSourceConfiguration adds video source configuration to a profile.
|
|
func (c *Client) AddVideoSourceConfiguration(ctx context.Context, profileToken, configurationToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type AddVideoSourceConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:AddVideoSourceConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken"`
|
|
}
|
|
|
|
req := AddVideoSourceConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
ConfigurationToken: configurationToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("AddVideoSourceConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// RemoveVideoSourceConfiguration removes video source configuration from a profile.
|
|
func (c *Client) RemoveVideoSourceConfiguration(ctx context.Context, profileToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type RemoveVideoSourceConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:RemoveVideoSourceConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
req := RemoveVideoSourceConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("RemoveVideoSourceConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// AddPTZConfiguration adds PTZ configuration to a profile.
|
|
func (c *Client) AddPTZConfiguration(ctx context.Context, profileToken, configurationToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type AddPTZConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:AddPTZConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken"`
|
|
}
|
|
|
|
req := AddPTZConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
ConfigurationToken: configurationToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("AddPTZConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// RemovePTZConfiguration removes PTZ configuration from a profile.
|
|
func (c *Client) RemovePTZConfiguration(ctx context.Context, profileToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type RemovePTZConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:RemovePTZConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
req := RemovePTZConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("RemovePTZConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// AddMetadataConfiguration adds metadata configuration to a profile.
|
|
func (c *Client) AddMetadataConfiguration(ctx context.Context, profileToken, configurationToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type AddMetadataConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:AddMetadataConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken"`
|
|
}
|
|
|
|
req := AddMetadataConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
ConfigurationToken: configurationToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("AddMetadataConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// RemoveMetadataConfiguration removes metadata configuration from a profile.
|
|
func (c *Client) RemoveMetadataConfiguration(ctx context.Context, profileToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type RemoveMetadataConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:RemoveMetadataConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
req := RemoveMetadataConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("RemoveMetadataConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetAudioEncoderConfigurationOptions retrieves available options for audio encoder configuration.
|
|
func (c *Client) GetAudioEncoderConfigurationOptions(
|
|
ctx context.Context,
|
|
configurationToken, profileToken string,
|
|
) (*AudioEncoderConfigurationOptions, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetAudioEncoderConfigurationOptions struct {
|
|
XMLName xml.Name `xml:"trt:GetAudioEncoderConfigurationOptions"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken,omitempty"`
|
|
ProfileToken string `xml:"trt:ProfileToken,omitempty"`
|
|
}
|
|
|
|
type GetAudioEncoderConfigurationOptionsResponse struct {
|
|
XMLName xml.Name `xml:"GetAudioEncoderConfigurationOptionsResponse"`
|
|
Options struct {
|
|
EncodingOptions []string `xml:"EncodingOptions"`
|
|
BitrateList []int `xml:"BitrateList"`
|
|
SampleRateList []int `xml:"SampleRateList"`
|
|
} `xml:"Options"`
|
|
}
|
|
|
|
req := GetAudioEncoderConfigurationOptions{
|
|
Xmlns: mediaNamespace,
|
|
}
|
|
if configurationToken != "" {
|
|
req.ConfigurationToken = configurationToken
|
|
}
|
|
if profileToken != "" {
|
|
req.ProfileToken = profileToken
|
|
}
|
|
|
|
var resp GetAudioEncoderConfigurationOptionsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetAudioEncoderConfigurationOptions failed: %w", err)
|
|
}
|
|
|
|
return &AudioEncoderConfigurationOptions{
|
|
EncodingOptions: resp.Options.EncodingOptions,
|
|
BitrateList: resp.Options.BitrateList,
|
|
SampleRateList: resp.Options.SampleRateList,
|
|
}, nil
|
|
}
|
|
|
|
// GetMetadataConfigurationOptions retrieves available options for metadata configuration.
|
|
func (c *Client) GetMetadataConfigurationOptions(
|
|
ctx context.Context,
|
|
configurationToken, profileToken string,
|
|
) (*MetadataConfigurationOptions, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetMetadataConfigurationOptions struct {
|
|
XMLName xml.Name `xml:"trt:GetMetadataConfigurationOptions"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken,omitempty"`
|
|
ProfileToken string `xml:"trt:ProfileToken,omitempty"`
|
|
}
|
|
|
|
type GetMetadataConfigurationOptionsResponse struct {
|
|
XMLName xml.Name `xml:"GetMetadataConfigurationOptionsResponse"`
|
|
Options struct {
|
|
PTZStatusFilterOptions *struct {
|
|
Status bool `xml:"Status"`
|
|
Position bool `xml:"Position"`
|
|
} `xml:"PTZStatusFilterOptions"`
|
|
Extension struct{} `xml:"Extension"`
|
|
} `xml:"Options"`
|
|
}
|
|
|
|
req := GetMetadataConfigurationOptions{
|
|
Xmlns: mediaNamespace,
|
|
}
|
|
if configurationToken != "" {
|
|
req.ConfigurationToken = configurationToken
|
|
}
|
|
if profileToken != "" {
|
|
req.ProfileToken = profileToken
|
|
}
|
|
|
|
var resp GetMetadataConfigurationOptionsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetMetadataConfigurationOptions failed: %w", err)
|
|
}
|
|
|
|
options := &MetadataConfigurationOptions{}
|
|
if resp.Options.PTZStatusFilterOptions != nil {
|
|
options.PTZStatusFilterOptions = &PTZFilter{
|
|
Status: resp.Options.PTZStatusFilterOptions.Status,
|
|
Position: resp.Options.PTZStatusFilterOptions.Position,
|
|
}
|
|
}
|
|
|
|
return options, nil
|
|
}
|
|
|
|
// GetAudioOutputConfiguration retrieves audio output configuration.
|
|
func (c *Client) GetAudioOutputConfiguration(ctx context.Context, configurationToken string) (*AudioOutputConfiguration, error) {
|
|
endpoint := c.getMediaEndpoint()
|
|
|
|
type GetAudioOutputConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:GetAudioOutputConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken"`
|
|
}
|
|
|
|
type GetAudioOutputConfigurationResponse struct {
|
|
XMLName xml.Name `xml:"GetAudioOutputConfigurationResponse"`
|
|
Configuration struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
OutputToken string `xml:"OutputToken"`
|
|
} `xml:"Configuration"`
|
|
}
|
|
|
|
req := GetAudioOutputConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ConfigurationToken: configurationToken,
|
|
}
|
|
|
|
var resp GetAudioOutputConfigurationResponse
|
|
soapClient := c.getMediaSoapClient()
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetAudioOutputConfiguration failed: %w", err)
|
|
}
|
|
|
|
return &AudioOutputConfiguration{
|
|
Token: resp.Configuration.Token,
|
|
Name: resp.Configuration.Name,
|
|
UseCount: resp.Configuration.UseCount,
|
|
OutputToken: resp.Configuration.OutputToken,
|
|
}, nil
|
|
}
|
|
|
|
// SetAudioOutputConfiguration sets audio output configuration.
|
|
func (c *Client) SetAudioOutputConfiguration(ctx context.Context, config *AudioOutputConfiguration, forcePersistence bool) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type SetAudioOutputConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:SetAudioOutputConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
Xmlnst string `xml:"xmlns:tt,attr"`
|
|
Configuration struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"tt:Name"`
|
|
UseCount int `xml:"tt:UseCount"`
|
|
OutputToken string `xml:"tt:OutputToken"`
|
|
} `xml:"trt:Configuration"`
|
|
ForcePersistence bool `xml:"trt:ForcePersistence"`
|
|
}
|
|
|
|
req := SetAudioOutputConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
Xmlnst: "http://www.onvif.org/ver10/schema",
|
|
ForcePersistence: forcePersistence,
|
|
}
|
|
|
|
req.Configuration.Token = config.Token
|
|
req.Configuration.Name = config.Name
|
|
req.Configuration.UseCount = config.UseCount
|
|
req.Configuration.OutputToken = config.OutputToken
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("SetAudioOutputConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetAudioOutputConfigurationOptions retrieves available options for audio output configuration.
|
|
func (c *Client) GetAudioOutputConfigurationOptions(
|
|
ctx context.Context,
|
|
configurationToken string,
|
|
) (*AudioOutputConfigurationOptions, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetAudioOutputConfigurationOptions struct {
|
|
XMLName xml.Name `xml:"trt:GetAudioOutputConfigurationOptions"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken,omitempty"`
|
|
}
|
|
|
|
type GetAudioOutputConfigurationOptionsResponse struct {
|
|
XMLName xml.Name `xml:"GetAudioOutputConfigurationOptionsResponse"`
|
|
Options struct {
|
|
OutputTokensAvailable []string `xml:"OutputTokensAvailable"`
|
|
} `xml:"Options"`
|
|
}
|
|
|
|
req := GetAudioOutputConfigurationOptions{
|
|
Xmlns: mediaNamespace,
|
|
}
|
|
if configurationToken != "" {
|
|
req.ConfigurationToken = configurationToken
|
|
}
|
|
|
|
var resp GetAudioOutputConfigurationOptionsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetAudioOutputConfigurationOptions failed: %w", err)
|
|
}
|
|
|
|
return &AudioOutputConfigurationOptions{
|
|
OutputTokensAvailable: resp.Options.OutputTokensAvailable,
|
|
}, nil
|
|
}
|
|
|
|
// GetAudioDecoderConfigurationOptions retrieves available options for audio decoder configuration.
|
|
func (c *Client) GetAudioDecoderConfigurationOptions(
|
|
ctx context.Context,
|
|
configurationToken string,
|
|
) (*AudioDecoderConfigurationOptions, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetAudioDecoderConfigurationOptions struct {
|
|
XMLName xml.Name `xml:"trt:GetAudioDecoderConfigurationOptions"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken,omitempty"`
|
|
}
|
|
|
|
type GetAudioDecoderConfigurationOptionsResponse struct {
|
|
XMLName xml.Name `xml:"GetAudioDecoderConfigurationOptionsResponse"`
|
|
Options struct {
|
|
AACDecOptions *struct {
|
|
BitrateList []int `xml:"BitrateList"`
|
|
SampleRateList []int `xml:"SampleRateList"`
|
|
} `xml:"AACDecOptions"`
|
|
G711DecOptions *struct {
|
|
BitrateList []int `xml:"BitrateList"`
|
|
} `xml:"G711DecOptions"`
|
|
G726DecOptions *struct {
|
|
BitrateList []int `xml:"BitrateList"`
|
|
} `xml:"G726DecOptions"`
|
|
} `xml:"Options"`
|
|
}
|
|
|
|
req := GetAudioDecoderConfigurationOptions{
|
|
Xmlns: mediaNamespace,
|
|
}
|
|
if configurationToken != "" {
|
|
req.ConfigurationToken = configurationToken
|
|
}
|
|
|
|
var resp GetAudioDecoderConfigurationOptionsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetAudioDecoderConfigurationOptions failed: %w", err)
|
|
}
|
|
|
|
options := &AudioDecoderConfigurationOptions{}
|
|
if resp.Options.AACDecOptions != nil {
|
|
options.AACDecOptions = &AudioDecoderOptions{
|
|
BitrateList: resp.Options.AACDecOptions.BitrateList,
|
|
SampleRateList: resp.Options.AACDecOptions.SampleRateList,
|
|
}
|
|
}
|
|
if resp.Options.G711DecOptions != nil {
|
|
options.G711DecOptions = &AudioDecoderOptions{
|
|
BitrateList: resp.Options.G711DecOptions.BitrateList,
|
|
}
|
|
}
|
|
if resp.Options.G726DecOptions != nil {
|
|
options.G726DecOptions = &AudioDecoderOptions{
|
|
BitrateList: resp.Options.G726DecOptions.BitrateList,
|
|
}
|
|
}
|
|
|
|
return options, nil
|
|
}
|
|
|
|
// GetGuaranteedNumberOfVideoEncoderInstances retrieves the guaranteed number of video encoder instances.
|
|
func (c *Client) GetGuaranteedNumberOfVideoEncoderInstances(
|
|
ctx context.Context,
|
|
configurationToken string,
|
|
) (*GuaranteedNumberOfVideoEncoderInstances, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetGuaranteedNumberOfVideoEncoderInstances struct {
|
|
XMLName xml.Name `xml:"trt:GetGuaranteedNumberOfVideoEncoderInstances"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken"`
|
|
}
|
|
|
|
type GetGuaranteedNumberOfVideoEncoderInstancesResponse struct {
|
|
XMLName xml.Name `xml:"GetGuaranteedNumberOfVideoEncoderInstancesResponse"`
|
|
TotalNumber int `xml:"TotalNumber"`
|
|
JPEG int `xml:"JPEG"`
|
|
H264 int `xml:"H264"`
|
|
MPEG4 int `xml:"MPEG4"`
|
|
}
|
|
|
|
req := GetGuaranteedNumberOfVideoEncoderInstances{
|
|
Xmlns: mediaNamespace,
|
|
ConfigurationToken: configurationToken,
|
|
}
|
|
|
|
var resp GetGuaranteedNumberOfVideoEncoderInstancesResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetGuaranteedNumberOfVideoEncoderInstances failed: %w", err)
|
|
}
|
|
|
|
return &GuaranteedNumberOfVideoEncoderInstances{
|
|
TotalNumber: resp.TotalNumber,
|
|
JPEG: resp.JPEG,
|
|
H264: resp.H264,
|
|
MPEG4: resp.MPEG4,
|
|
}, nil
|
|
}
|
|
|
|
// GetOSDOptions retrieves available options for OSD configuration.
|
|
func (c *Client) GetOSDOptions(ctx context.Context, configurationToken string) (*OSDConfigurationOptions, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetOSDOptions struct {
|
|
XMLName xml.Name `xml:"trt:GetOSDOptions"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken,omitempty"`
|
|
}
|
|
|
|
type GetOSDOptionsResponse struct {
|
|
XMLName xml.Name `xml:"GetOSDOptionsResponse"`
|
|
Options struct {
|
|
MaximumNumberOfOSDs int `xml:"MaximumNumberOfOSDs"`
|
|
} `xml:"Options"`
|
|
}
|
|
|
|
req := GetOSDOptions{
|
|
Xmlns: mediaNamespace,
|
|
}
|
|
if configurationToken != "" {
|
|
req.ConfigurationToken = configurationToken
|
|
}
|
|
|
|
var resp GetOSDOptionsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetOSDOptions failed: %w", err)
|
|
}
|
|
|
|
return &OSDConfigurationOptions{
|
|
MaximumNumberOfOSDs: resp.Options.MaximumNumberOfOSDs,
|
|
}, nil
|
|
}
|
|
|
|
// GetVideoSourceConfigurations retrieves all video source configurations.
|
|
func (c *Client) GetVideoSourceConfigurations(ctx context.Context) ([]*VideoSourceConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetVideoSourceConfigurations struct {
|
|
XMLName xml.Name `xml:"trt:GetVideoSourceConfigurations"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
}
|
|
|
|
type GetVideoSourceConfigurationsResponse struct {
|
|
XMLName xml.Name `xml:"GetVideoSourceConfigurationsResponse"`
|
|
Configurations []struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
SourceToken string `xml:"SourceToken"`
|
|
Bounds *struct {
|
|
X int `xml:"x,attr"`
|
|
Y int `xml:"y,attr"`
|
|
Width int `xml:"width,attr"`
|
|
Height int `xml:"height,attr"`
|
|
} `xml:"Bounds"`
|
|
} `xml:"Configurations"`
|
|
}
|
|
|
|
req := GetVideoSourceConfigurations{
|
|
Xmlns: mediaNamespace,
|
|
}
|
|
|
|
var resp GetVideoSourceConfigurationsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetVideoSourceConfigurations failed: %w", err)
|
|
}
|
|
|
|
configs := make([]*VideoSourceConfiguration, len(resp.Configurations))
|
|
for i, cfg := range resp.Configurations {
|
|
config := &VideoSourceConfiguration{
|
|
Token: cfg.Token,
|
|
Name: cfg.Name,
|
|
UseCount: cfg.UseCount,
|
|
SourceToken: cfg.SourceToken,
|
|
}
|
|
if cfg.Bounds != nil {
|
|
config.Bounds = &IntRectangle{
|
|
X: cfg.Bounds.X,
|
|
Y: cfg.Bounds.Y,
|
|
Width: cfg.Bounds.Width,
|
|
Height: cfg.Bounds.Height,
|
|
}
|
|
}
|
|
configs[i] = config
|
|
}
|
|
|
|
return configs, nil
|
|
}
|
|
|
|
// GetAudioSourceConfigurations retrieves all audio source configurations.
|
|
func (c *Client) GetAudioSourceConfigurations(ctx context.Context) ([]*AudioSourceConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetAudioSourceConfigurations struct {
|
|
XMLName xml.Name `xml:"trt:GetAudioSourceConfigurations"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
}
|
|
|
|
type GetAudioSourceConfigurationsResponse struct {
|
|
XMLName xml.Name `xml:"GetAudioSourceConfigurationsResponse"`
|
|
Configurations []struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
SourceToken string `xml:"SourceToken"`
|
|
} `xml:"Configurations"`
|
|
}
|
|
|
|
req := GetAudioSourceConfigurations{
|
|
Xmlns: mediaNamespace,
|
|
}
|
|
|
|
var resp GetAudioSourceConfigurationsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetAudioSourceConfigurations failed: %w", err)
|
|
}
|
|
|
|
configs := make([]*AudioSourceConfiguration, len(resp.Configurations))
|
|
for i, cfg := range resp.Configurations {
|
|
configs[i] = &AudioSourceConfiguration{
|
|
Token: cfg.Token,
|
|
Name: cfg.Name,
|
|
UseCount: cfg.UseCount,
|
|
SourceToken: cfg.SourceToken,
|
|
}
|
|
}
|
|
|
|
return configs, nil
|
|
}
|
|
|
|
// GetVideoEncoderConfigurations retrieves all video encoder configurations.
|
|
func (c *Client) GetVideoEncoderConfigurations(ctx context.Context) ([]*VideoEncoderConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetVideoEncoderConfigurations struct {
|
|
XMLName xml.Name `xml:"trt:GetVideoEncoderConfigurations"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
}
|
|
|
|
type GetVideoEncoderConfigurationsResponse struct {
|
|
XMLName xml.Name `xml:"GetVideoEncoderConfigurationsResponse"`
|
|
Configurations []struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
Encoding string `xml:"Encoding"`
|
|
Resolution *struct {
|
|
Width int `xml:"Width"`
|
|
Height int `xml:"Height"`
|
|
} `xml:"Resolution"`
|
|
Quality float64 `xml:"Quality"`
|
|
RateControl *struct {
|
|
FrameRateLimit int `xml:"FrameRateLimit"`
|
|
EncodingInterval int `xml:"EncodingInterval"`
|
|
BitrateLimit int `xml:"BitrateLimit"`
|
|
} `xml:"RateControl"`
|
|
MPEG4 *struct {
|
|
GovLength int `xml:"GovLength"`
|
|
MPEG4Profile string `xml:"MPEG4Profile"`
|
|
} `xml:"MPEG4"`
|
|
H264 *struct {
|
|
GovLength int `xml:"GovLength"`
|
|
H264Profile string `xml:"H264Profile"`
|
|
} `xml:"H264"`
|
|
Multicast *struct {
|
|
Address *struct {
|
|
Type string `xml:"Type"`
|
|
IPv4Address string `xml:"IPv4Address"`
|
|
IPv6Address string `xml:"IPv6Address"`
|
|
} `xml:"Address"`
|
|
Port int `xml:"Port"`
|
|
TTL int `xml:"TTL"`
|
|
AutoStart bool `xml:"AutoStart"`
|
|
} `xml:"Multicast"`
|
|
SessionTimeout string `xml:"SessionTimeout"`
|
|
} `xml:"Configurations"`
|
|
}
|
|
|
|
req := GetVideoEncoderConfigurations{
|
|
Xmlns: mediaNamespace,
|
|
}
|
|
|
|
var resp GetVideoEncoderConfigurationsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetVideoEncoderConfigurations failed: %w", err)
|
|
}
|
|
|
|
configs := make([]*VideoEncoderConfiguration, len(resp.Configurations))
|
|
for i, cfg := range resp.Configurations {
|
|
config := &VideoEncoderConfiguration{
|
|
Token: cfg.Token,
|
|
Name: cfg.Name,
|
|
UseCount: cfg.UseCount,
|
|
Encoding: cfg.Encoding,
|
|
Quality: cfg.Quality,
|
|
}
|
|
|
|
if cfg.Resolution != nil {
|
|
config.Resolution = &VideoResolution{
|
|
Width: cfg.Resolution.Width,
|
|
Height: cfg.Resolution.Height,
|
|
}
|
|
}
|
|
|
|
if cfg.RateControl != nil {
|
|
config.RateControl = &VideoRateControl{
|
|
FrameRateLimit: cfg.RateControl.FrameRateLimit,
|
|
EncodingInterval: cfg.RateControl.EncodingInterval,
|
|
BitrateLimit: cfg.RateControl.BitrateLimit,
|
|
}
|
|
}
|
|
|
|
if cfg.MPEG4 != nil {
|
|
config.MPEG4 = &MPEG4Configuration{
|
|
GovLength: cfg.MPEG4.GovLength,
|
|
MPEG4Profile: cfg.MPEG4.MPEG4Profile,
|
|
}
|
|
}
|
|
|
|
if cfg.H264 != nil {
|
|
config.H264 = &H264Configuration{
|
|
GovLength: cfg.H264.GovLength,
|
|
H264Profile: cfg.H264.H264Profile,
|
|
}
|
|
}
|
|
|
|
if cfg.Multicast != nil {
|
|
config.Multicast = &MulticastConfiguration{
|
|
Port: cfg.Multicast.Port,
|
|
TTL: cfg.Multicast.TTL,
|
|
AutoStart: cfg.Multicast.AutoStart,
|
|
}
|
|
if cfg.Multicast.Address != nil {
|
|
config.Multicast.Address = &IPAddress{
|
|
Type: cfg.Multicast.Address.Type,
|
|
IPv4Address: cfg.Multicast.Address.IPv4Address,
|
|
IPv6Address: cfg.Multicast.Address.IPv6Address,
|
|
}
|
|
}
|
|
}
|
|
|
|
configs[i] = config
|
|
}
|
|
|
|
return configs, nil
|
|
}
|
|
|
|
// GetAudioEncoderConfigurations retrieves all audio encoder configurations.
|
|
func (c *Client) GetAudioEncoderConfigurations(ctx context.Context) ([]*AudioEncoderConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetAudioEncoderConfigurations struct {
|
|
XMLName xml.Name `xml:"trt:GetAudioEncoderConfigurations"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
}
|
|
|
|
type GetAudioEncoderConfigurationsResponse struct {
|
|
XMLName xml.Name `xml:"GetAudioEncoderConfigurationsResponse"`
|
|
Configurations []struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
Encoding string `xml:"Encoding"`
|
|
Bitrate int `xml:"Bitrate"`
|
|
SampleRate int `xml:"SampleRate"`
|
|
Multicast *struct {
|
|
Address *struct {
|
|
Type string `xml:"Type"`
|
|
IPv4Address string `xml:"IPv4Address"`
|
|
IPv6Address string `xml:"IPv6Address"`
|
|
} `xml:"Address"`
|
|
Port int `xml:"Port"`
|
|
TTL int `xml:"TTL"`
|
|
AutoStart bool `xml:"AutoStart"`
|
|
} `xml:"Multicast"`
|
|
SessionTimeout string `xml:"SessionTimeout"`
|
|
} `xml:"Configurations"`
|
|
}
|
|
|
|
req := GetAudioEncoderConfigurations{
|
|
Xmlns: mediaNamespace,
|
|
}
|
|
|
|
var resp GetAudioEncoderConfigurationsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetAudioEncoderConfigurations failed: %w", err)
|
|
}
|
|
|
|
configs := make([]*AudioEncoderConfiguration, len(resp.Configurations))
|
|
for i, cfg := range resp.Configurations {
|
|
config := &AudioEncoderConfiguration{
|
|
Token: cfg.Token,
|
|
Name: cfg.Name,
|
|
UseCount: cfg.UseCount,
|
|
Encoding: cfg.Encoding,
|
|
Bitrate: cfg.Bitrate,
|
|
SampleRate: cfg.SampleRate,
|
|
}
|
|
|
|
if cfg.Multicast != nil {
|
|
config.Multicast = &MulticastConfiguration{
|
|
Port: cfg.Multicast.Port,
|
|
TTL: cfg.Multicast.TTL,
|
|
AutoStart: cfg.Multicast.AutoStart,
|
|
}
|
|
if cfg.Multicast.Address != nil {
|
|
config.Multicast.Address = &IPAddress{
|
|
Type: cfg.Multicast.Address.Type,
|
|
IPv4Address: cfg.Multicast.Address.IPv4Address,
|
|
IPv6Address: cfg.Multicast.Address.IPv6Address,
|
|
}
|
|
}
|
|
}
|
|
|
|
configs[i] = config
|
|
}
|
|
|
|
return configs, nil
|
|
}
|
|
|
|
// GetVideoSourceConfiguration retrieves a specific video source configuration.
|
|
func (c *Client) GetVideoSourceConfiguration(
|
|
ctx context.Context,
|
|
configurationToken string,
|
|
) (*VideoSourceConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetVideoSourceConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:GetVideoSourceConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken"`
|
|
}
|
|
|
|
type GetVideoSourceConfigurationResponse struct {
|
|
XMLName xml.Name `xml:"GetVideoSourceConfigurationResponse"`
|
|
Configuration struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
SourceToken string `xml:"SourceToken"`
|
|
Bounds *struct {
|
|
X int `xml:"x,attr"`
|
|
Y int `xml:"y,attr"`
|
|
Width int `xml:"width,attr"`
|
|
Height int `xml:"height,attr"`
|
|
} `xml:"Bounds"`
|
|
} `xml:"Configuration"`
|
|
}
|
|
|
|
req := GetVideoSourceConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ConfigurationToken: configurationToken,
|
|
}
|
|
|
|
var resp GetVideoSourceConfigurationResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetVideoSourceConfiguration failed: %w", err)
|
|
}
|
|
|
|
config := &VideoSourceConfiguration{
|
|
Token: resp.Configuration.Token,
|
|
Name: resp.Configuration.Name,
|
|
UseCount: resp.Configuration.UseCount,
|
|
SourceToken: resp.Configuration.SourceToken,
|
|
}
|
|
|
|
if resp.Configuration.Bounds != nil {
|
|
config.Bounds = &IntRectangle{
|
|
X: resp.Configuration.Bounds.X,
|
|
Y: resp.Configuration.Bounds.Y,
|
|
Width: resp.Configuration.Bounds.Width,
|
|
Height: resp.Configuration.Bounds.Height,
|
|
}
|
|
}
|
|
|
|
return config, nil
|
|
}
|
|
|
|
// GetAudioSourceConfiguration retrieves a specific audio source configuration.
|
|
func (c *Client) GetAudioSourceConfiguration(ctx context.Context, configurationToken string) (*AudioSourceConfiguration, error) {
|
|
endpoint := c.getMediaEndpoint()
|
|
|
|
type GetAudioSourceConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:GetAudioSourceConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken"`
|
|
}
|
|
|
|
type GetAudioSourceConfigurationResponse struct {
|
|
XMLName xml.Name `xml:"GetAudioSourceConfigurationResponse"`
|
|
Configuration struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
SourceToken string `xml:"SourceToken"`
|
|
} `xml:"Configuration"`
|
|
}
|
|
|
|
req := GetAudioSourceConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ConfigurationToken: configurationToken,
|
|
}
|
|
|
|
var resp GetAudioSourceConfigurationResponse
|
|
soapClient := c.getMediaSoapClient()
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetAudioSourceConfiguration failed: %w", err)
|
|
}
|
|
|
|
return &AudioSourceConfiguration{
|
|
Token: resp.Configuration.Token,
|
|
Name: resp.Configuration.Name,
|
|
UseCount: resp.Configuration.UseCount,
|
|
SourceToken: resp.Configuration.SourceToken,
|
|
}, nil
|
|
}
|
|
|
|
// GetVideoSourceConfigurationOptions retrieves available options for video source configuration.
|
|
func (c *Client) GetVideoSourceConfigurationOptions(
|
|
ctx context.Context,
|
|
configurationToken, profileToken string,
|
|
) (*VideoSourceConfigurationOptions, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetVideoSourceConfigurationOptions struct {
|
|
XMLName xml.Name `xml:"trt:GetVideoSourceConfigurationOptions"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken,omitempty"`
|
|
ProfileToken string `xml:"trt:ProfileToken,omitempty"`
|
|
}
|
|
|
|
type GetVideoSourceConfigurationOptionsResponse struct {
|
|
XMLName xml.Name `xml:"GetVideoSourceConfigurationOptionsResponse"`
|
|
Options struct {
|
|
BoundsRange *struct {
|
|
X *IntRange `xml:"X"`
|
|
Y *IntRange `xml:"Y"`
|
|
Width *IntRange `xml:"Width"`
|
|
Height *IntRange `xml:"Height"`
|
|
} `xml:"BoundsRange"`
|
|
VideoSourceTokensAvailable []string `xml:"VideoSourceTokensAvailable"`
|
|
} `xml:"Options"`
|
|
}
|
|
|
|
req := GetVideoSourceConfigurationOptions{
|
|
Xmlns: mediaNamespace,
|
|
}
|
|
if configurationToken != "" {
|
|
req.ConfigurationToken = configurationToken
|
|
}
|
|
if profileToken != "" {
|
|
req.ProfileToken = profileToken
|
|
}
|
|
|
|
var resp GetVideoSourceConfigurationOptionsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetVideoSourceConfigurationOptions failed: %w", err)
|
|
}
|
|
|
|
options := &VideoSourceConfigurationOptions{}
|
|
if resp.Options.BoundsRange != nil {
|
|
options.BoundsRange = &BoundsRange{
|
|
X: resp.Options.BoundsRange.X,
|
|
Y: resp.Options.BoundsRange.Y,
|
|
Width: resp.Options.BoundsRange.Width,
|
|
Height: resp.Options.BoundsRange.Height,
|
|
}
|
|
}
|
|
options.VideoSourceTokensAvailable = resp.Options.VideoSourceTokensAvailable
|
|
|
|
return options, nil
|
|
}
|
|
|
|
// GetAudioSourceConfigurationOptions retrieves available options for audio source configuration.
|
|
func (c *Client) GetAudioSourceConfigurationOptions(
|
|
ctx context.Context,
|
|
configurationToken, profileToken string,
|
|
) (*AudioSourceConfigurationOptions, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetAudioSourceConfigurationOptions struct {
|
|
XMLName xml.Name `xml:"trt:GetAudioSourceConfigurationOptions"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken,omitempty"`
|
|
ProfileToken string `xml:"trt:ProfileToken,omitempty"`
|
|
}
|
|
|
|
type GetAudioSourceConfigurationOptionsResponse struct {
|
|
XMLName xml.Name `xml:"GetAudioSourceConfigurationOptionsResponse"`
|
|
Options struct {
|
|
InputTokensAvailable []string `xml:"InputTokensAvailable"`
|
|
} `xml:"Options"`
|
|
}
|
|
|
|
req := GetAudioSourceConfigurationOptions{
|
|
Xmlns: mediaNamespace,
|
|
}
|
|
if configurationToken != "" {
|
|
req.ConfigurationToken = configurationToken
|
|
}
|
|
if profileToken != "" {
|
|
req.ProfileToken = profileToken
|
|
}
|
|
|
|
var resp GetAudioSourceConfigurationOptionsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetAudioSourceConfigurationOptions failed: %w", err)
|
|
}
|
|
|
|
return &AudioSourceConfigurationOptions{
|
|
InputTokensAvailable: resp.Options.InputTokensAvailable,
|
|
}, nil
|
|
}
|
|
|
|
// SetVideoSourceConfiguration sets video source configuration.
|
|
func (c *Client) SetVideoSourceConfiguration(
|
|
ctx context.Context,
|
|
config *VideoSourceConfiguration,
|
|
forcePersistence bool,
|
|
) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type SetVideoSourceConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:SetVideoSourceConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
Xmlnst string `xml:"xmlns:tt,attr"`
|
|
Configuration struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"tt:Name"`
|
|
UseCount int `xml:"tt:UseCount"`
|
|
SourceToken string `xml:"tt:SourceToken"`
|
|
Bounds *struct {
|
|
X int `xml:"x,attr"`
|
|
Y int `xml:"y,attr"`
|
|
Width int `xml:"width,attr"`
|
|
Height int `xml:"height,attr"`
|
|
} `xml:"tt:Bounds,omitempty"`
|
|
} `xml:"trt:Configuration"`
|
|
ForcePersistence bool `xml:"trt:ForcePersistence"`
|
|
}
|
|
|
|
req := SetVideoSourceConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
Xmlnst: "http://www.onvif.org/ver10/schema",
|
|
ForcePersistence: forcePersistence,
|
|
}
|
|
|
|
req.Configuration.Token = config.Token
|
|
req.Configuration.Name = config.Name
|
|
req.Configuration.UseCount = config.UseCount
|
|
req.Configuration.SourceToken = config.SourceToken
|
|
|
|
if config.Bounds != nil {
|
|
req.Configuration.Bounds = &struct {
|
|
X int `xml:"x,attr"`
|
|
Y int `xml:"y,attr"`
|
|
Width int `xml:"width,attr"`
|
|
Height int `xml:"height,attr"`
|
|
}{
|
|
X: config.Bounds.X,
|
|
Y: config.Bounds.Y,
|
|
Width: config.Bounds.Width,
|
|
Height: config.Bounds.Height,
|
|
}
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("SetVideoSourceConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// SetAudioSourceConfiguration sets audio source configuration.
|
|
func (c *Client) SetAudioSourceConfiguration(ctx context.Context, config *AudioSourceConfiguration, forcePersistence bool) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type SetAudioSourceConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:SetAudioSourceConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
Xmlnst string `xml:"xmlns:tt,attr"`
|
|
Configuration struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"tt:Name"`
|
|
UseCount int `xml:"tt:UseCount"`
|
|
SourceToken string `xml:"tt:SourceToken"`
|
|
} `xml:"trt:Configuration"`
|
|
ForcePersistence bool `xml:"trt:ForcePersistence"`
|
|
}
|
|
|
|
req := SetAudioSourceConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
Xmlnst: "http://www.onvif.org/ver10/schema",
|
|
ForcePersistence: forcePersistence,
|
|
}
|
|
|
|
req.Configuration.Token = config.Token
|
|
req.Configuration.Name = config.Name
|
|
req.Configuration.UseCount = config.UseCount
|
|
req.Configuration.SourceToken = config.SourceToken
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("SetAudioSourceConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetCompatibleVideoEncoderConfigurations retrieves compatible video encoder configurations for a profile.
|
|
func (c *Client) GetCompatibleVideoEncoderConfigurations(
|
|
ctx context.Context,
|
|
profileToken string,
|
|
) ([]*VideoEncoderConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetCompatibleVideoEncoderConfigurations struct {
|
|
XMLName xml.Name `xml:"trt:GetCompatibleVideoEncoderConfigurations"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
type GetCompatibleVideoEncoderConfigurationsResponse struct {
|
|
XMLName xml.Name `xml:"GetCompatibleVideoEncoderConfigurationsResponse"`
|
|
Configurations []struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
Encoding string `xml:"Encoding"`
|
|
Resolution *struct {
|
|
Width int `xml:"Width"`
|
|
Height int `xml:"Height"`
|
|
} `xml:"Resolution"`
|
|
Quality float64 `xml:"Quality"`
|
|
RateControl *struct {
|
|
FrameRateLimit int `xml:"FrameRateLimit"`
|
|
EncodingInterval int `xml:"EncodingInterval"`
|
|
BitrateLimit int `xml:"BitrateLimit"`
|
|
} `xml:"RateControl"`
|
|
} `xml:"Configurations"`
|
|
}
|
|
|
|
req := GetCompatibleVideoEncoderConfigurations{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
var resp GetCompatibleVideoEncoderConfigurationsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetCompatibleVideoEncoderConfigurations failed: %w", err)
|
|
}
|
|
|
|
configs := make([]*VideoEncoderConfiguration, len(resp.Configurations))
|
|
for i, cfg := range resp.Configurations {
|
|
config := &VideoEncoderConfiguration{
|
|
Token: cfg.Token,
|
|
Name: cfg.Name,
|
|
UseCount: cfg.UseCount,
|
|
Encoding: cfg.Encoding,
|
|
Quality: cfg.Quality,
|
|
}
|
|
|
|
if cfg.Resolution != nil {
|
|
config.Resolution = &VideoResolution{
|
|
Width: cfg.Resolution.Width,
|
|
Height: cfg.Resolution.Height,
|
|
}
|
|
}
|
|
|
|
if cfg.RateControl != nil {
|
|
config.RateControl = &VideoRateControl{
|
|
FrameRateLimit: cfg.RateControl.FrameRateLimit,
|
|
EncodingInterval: cfg.RateControl.EncodingInterval,
|
|
BitrateLimit: cfg.RateControl.BitrateLimit,
|
|
}
|
|
}
|
|
|
|
configs[i] = config
|
|
}
|
|
|
|
return configs, nil
|
|
}
|
|
|
|
// GetCompatibleVideoSourceConfigurations retrieves compatible video source configurations for a profile.
|
|
func (c *Client) GetCompatibleVideoSourceConfigurations(
|
|
ctx context.Context,
|
|
profileToken string,
|
|
) ([]*VideoSourceConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetCompatibleVideoSourceConfigurations struct {
|
|
XMLName xml.Name `xml:"trt:GetCompatibleVideoSourceConfigurations"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
type GetCompatibleVideoSourceConfigurationsResponse struct {
|
|
XMLName xml.Name `xml:"GetCompatibleVideoSourceConfigurationsResponse"`
|
|
Configurations []struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
SourceToken string `xml:"SourceToken"`
|
|
Bounds *struct {
|
|
X int `xml:"x,attr"`
|
|
Y int `xml:"y,attr"`
|
|
Width int `xml:"width,attr"`
|
|
Height int `xml:"height,attr"`
|
|
} `xml:"Bounds"`
|
|
} `xml:"Configurations"`
|
|
}
|
|
|
|
req := GetCompatibleVideoSourceConfigurations{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
var resp GetCompatibleVideoSourceConfigurationsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetCompatibleVideoSourceConfigurations failed: %w", err)
|
|
}
|
|
|
|
configs := make([]*VideoSourceConfiguration, len(resp.Configurations))
|
|
for i, cfg := range resp.Configurations {
|
|
config := &VideoSourceConfiguration{
|
|
Token: cfg.Token,
|
|
Name: cfg.Name,
|
|
UseCount: cfg.UseCount,
|
|
SourceToken: cfg.SourceToken,
|
|
}
|
|
if cfg.Bounds != nil {
|
|
config.Bounds = &IntRectangle{
|
|
X: cfg.Bounds.X,
|
|
Y: cfg.Bounds.Y,
|
|
Width: cfg.Bounds.Width,
|
|
Height: cfg.Bounds.Height,
|
|
}
|
|
}
|
|
configs[i] = config
|
|
}
|
|
|
|
return configs, nil
|
|
}
|
|
|
|
// GetCompatibleAudioEncoderConfigurations retrieves compatible audio encoder configurations for a profile.
|
|
func (c *Client) GetCompatibleAudioEncoderConfigurations(
|
|
ctx context.Context,
|
|
profileToken string,
|
|
) ([]*AudioEncoderConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetCompatibleAudioEncoderConfigurations struct {
|
|
XMLName xml.Name `xml:"trt:GetCompatibleAudioEncoderConfigurations"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
type GetCompatibleAudioEncoderConfigurationsResponse struct {
|
|
XMLName xml.Name `xml:"GetCompatibleAudioEncoderConfigurationsResponse"`
|
|
Configurations []struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
Encoding string `xml:"Encoding"`
|
|
Bitrate int `xml:"Bitrate"`
|
|
SampleRate int `xml:"SampleRate"`
|
|
} `xml:"Configurations"`
|
|
}
|
|
|
|
req := GetCompatibleAudioEncoderConfigurations{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
var resp GetCompatibleAudioEncoderConfigurationsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetCompatibleAudioEncoderConfigurations failed: %w", err)
|
|
}
|
|
|
|
configs := make([]*AudioEncoderConfiguration, len(resp.Configurations))
|
|
for i, cfg := range resp.Configurations {
|
|
configs[i] = &AudioEncoderConfiguration{
|
|
Token: cfg.Token,
|
|
Name: cfg.Name,
|
|
UseCount: cfg.UseCount,
|
|
Encoding: cfg.Encoding,
|
|
Bitrate: cfg.Bitrate,
|
|
SampleRate: cfg.SampleRate,
|
|
}
|
|
}
|
|
|
|
return configs, nil
|
|
}
|
|
|
|
// GetCompatibleAudioSourceConfigurations retrieves compatible audio source configurations for a profile.
|
|
func (c *Client) GetCompatibleAudioSourceConfigurations(ctx context.Context, profileToken string) ([]*AudioSourceConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetCompatibleAudioSourceConfigurations struct {
|
|
XMLName xml.Name `xml:"trt:GetCompatibleAudioSourceConfigurations"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
type GetCompatibleAudioSourceConfigurationsResponse struct {
|
|
XMLName xml.Name `xml:"GetCompatibleAudioSourceConfigurationsResponse"`
|
|
Configurations []struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
SourceToken string `xml:"SourceToken"`
|
|
} `xml:"Configurations"`
|
|
}
|
|
|
|
req := GetCompatibleAudioSourceConfigurations{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
var resp GetCompatibleAudioSourceConfigurationsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetCompatibleAudioSourceConfigurations failed: %w", err)
|
|
}
|
|
|
|
configs := make([]*AudioSourceConfiguration, len(resp.Configurations))
|
|
for i, cfg := range resp.Configurations {
|
|
configs[i] = &AudioSourceConfiguration{
|
|
Token: cfg.Token,
|
|
Name: cfg.Name,
|
|
UseCount: cfg.UseCount,
|
|
SourceToken: cfg.SourceToken,
|
|
}
|
|
}
|
|
|
|
return configs, nil
|
|
}
|
|
|
|
// GetCompatiblePTZConfigurations retrieves compatible PTZ configurations for a profile.
|
|
func (c *Client) GetCompatiblePTZConfigurations(ctx context.Context, profileToken string) ([]*PTZConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetCompatiblePTZConfigurations struct {
|
|
XMLName xml.Name `xml:"trt:GetCompatiblePTZConfigurations"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
type GetCompatiblePTZConfigurationsResponse struct {
|
|
XMLName xml.Name `xml:"GetCompatiblePTZConfigurationsResponse"`
|
|
Configurations []struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
NodeToken string `xml:"NodeToken"`
|
|
} `xml:"Configurations"`
|
|
}
|
|
|
|
req := GetCompatiblePTZConfigurations{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
var resp GetCompatiblePTZConfigurationsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetCompatiblePTZConfigurations failed: %w", err)
|
|
}
|
|
|
|
configs := make([]*PTZConfiguration, len(resp.Configurations))
|
|
for i, cfg := range resp.Configurations {
|
|
configs[i] = &PTZConfiguration{
|
|
Token: cfg.Token,
|
|
Name: cfg.Name,
|
|
UseCount: cfg.UseCount,
|
|
NodeToken: cfg.NodeToken,
|
|
}
|
|
}
|
|
|
|
return configs, nil
|
|
}
|
|
|
|
// GetCompatibleMetadataConfigurations retrieves compatible metadata configurations for a profile.
|
|
func (c *Client) GetCompatibleMetadataConfigurations(ctx context.Context, profileToken string) ([]*MetadataConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetCompatibleMetadataConfigurations struct {
|
|
XMLName xml.Name `xml:"trt:GetCompatibleMetadataConfigurations"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
type GetCompatibleMetadataConfigurationsResponse struct {
|
|
XMLName xml.Name `xml:"GetCompatibleMetadataConfigurationsResponse"`
|
|
Configurations []struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
Analytics bool `xml:"Analytics"`
|
|
} `xml:"Configurations"`
|
|
}
|
|
|
|
req := GetCompatibleMetadataConfigurations{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
var resp GetCompatibleMetadataConfigurationsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetCompatibleMetadataConfigurations failed: %w", err)
|
|
}
|
|
|
|
configs := make([]*MetadataConfiguration, len(resp.Configurations))
|
|
for i, cfg := range resp.Configurations {
|
|
configs[i] = &MetadataConfiguration{
|
|
Token: cfg.Token,
|
|
Name: cfg.Name,
|
|
UseCount: cfg.UseCount,
|
|
Analytics: cfg.Analytics,
|
|
}
|
|
}
|
|
|
|
return configs, nil
|
|
}
|
|
|
|
// GetCompatibleAudioOutputConfigurations retrieves compatible audio output configurations for a profile.
|
|
func (c *Client) GetCompatibleAudioOutputConfigurations(ctx context.Context, profileToken string) ([]*AudioOutputConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetCompatibleAudioOutputConfigurations struct {
|
|
XMLName xml.Name `xml:"trt:GetCompatibleAudioOutputConfigurations"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
type GetCompatibleAudioOutputConfigurationsResponse struct {
|
|
XMLName xml.Name `xml:"GetCompatibleAudioOutputConfigurationsResponse"`
|
|
Configurations []struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
OutputToken string `xml:"OutputToken"`
|
|
} `xml:"Configurations"`
|
|
}
|
|
|
|
req := GetCompatibleAudioOutputConfigurations{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
var resp GetCompatibleAudioOutputConfigurationsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetCompatibleAudioOutputConfigurations failed: %w", err)
|
|
}
|
|
|
|
configs := make([]*AudioOutputConfiguration, len(resp.Configurations))
|
|
for i, cfg := range resp.Configurations {
|
|
configs[i] = &AudioOutputConfiguration{
|
|
Token: cfg.Token,
|
|
Name: cfg.Name,
|
|
UseCount: cfg.UseCount,
|
|
OutputToken: cfg.OutputToken,
|
|
}
|
|
}
|
|
|
|
return configs, nil
|
|
}
|
|
|
|
// GetCompatibleAudioDecoderConfigurations retrieves compatible audio decoder configurations for a profile.
|
|
func (c *Client) GetCompatibleAudioDecoderConfigurations(ctx context.Context, profileToken string) ([]*AudioDecoderConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetCompatibleAudioDecoderConfigurations struct {
|
|
XMLName xml.Name `xml:"trt:GetCompatibleAudioDecoderConfigurations"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
type GetCompatibleAudioDecoderConfigurationsResponse struct {
|
|
XMLName xml.Name `xml:"GetCompatibleAudioDecoderConfigurationsResponse"`
|
|
Configurations []struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
} `xml:"Configurations"`
|
|
}
|
|
|
|
req := GetCompatibleAudioDecoderConfigurations{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
var resp GetCompatibleAudioDecoderConfigurationsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetCompatibleAudioDecoderConfigurations failed: %w", err)
|
|
}
|
|
|
|
configs := make([]*AudioDecoderConfiguration, len(resp.Configurations))
|
|
for i, cfg := range resp.Configurations {
|
|
configs[i] = &AudioDecoderConfiguration{
|
|
Token: cfg.Token,
|
|
Name: cfg.Name,
|
|
UseCount: cfg.UseCount,
|
|
}
|
|
}
|
|
|
|
return configs, nil
|
|
}
|
|
|
|
// GetMetadataConfigurations retrieves all metadata configurations.
|
|
func (c *Client) GetMetadataConfigurations(ctx context.Context) ([]*MetadataConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetMetadataConfigurations struct {
|
|
XMLName xml.Name `xml:"trt:GetMetadataConfigurations"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
}
|
|
|
|
type GetMetadataConfigurationsResponse struct {
|
|
XMLName xml.Name `xml:"GetMetadataConfigurationsResponse"`
|
|
Configurations []struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
Analytics bool `xml:"Analytics"`
|
|
} `xml:"Configurations"`
|
|
}
|
|
|
|
req := GetMetadataConfigurations{
|
|
Xmlns: mediaNamespace,
|
|
}
|
|
|
|
var resp GetMetadataConfigurationsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetMetadataConfigurations failed: %w", err)
|
|
}
|
|
|
|
configs := make([]*MetadataConfiguration, len(resp.Configurations))
|
|
for i, cfg := range resp.Configurations {
|
|
configs[i] = &MetadataConfiguration{
|
|
Token: cfg.Token,
|
|
Name: cfg.Name,
|
|
UseCount: cfg.UseCount,
|
|
Analytics: cfg.Analytics,
|
|
}
|
|
}
|
|
|
|
return configs, nil
|
|
}
|
|
|
|
// GetAudioOutputConfigurations retrieves all audio output configurations.
|
|
func (c *Client) GetAudioOutputConfigurations(ctx context.Context) ([]*AudioOutputConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetAudioOutputConfigurations struct {
|
|
XMLName xml.Name `xml:"trt:GetAudioOutputConfigurations"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
}
|
|
|
|
type GetAudioOutputConfigurationsResponse struct {
|
|
XMLName xml.Name `xml:"GetAudioOutputConfigurationsResponse"`
|
|
Configurations []struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
OutputToken string `xml:"OutputToken"`
|
|
} `xml:"Configurations"`
|
|
}
|
|
|
|
req := GetAudioOutputConfigurations{
|
|
Xmlns: mediaNamespace,
|
|
}
|
|
|
|
var resp GetAudioOutputConfigurationsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetAudioOutputConfigurations failed: %w", err)
|
|
}
|
|
|
|
configs := make([]*AudioOutputConfiguration, len(resp.Configurations))
|
|
for i, cfg := range resp.Configurations {
|
|
configs[i] = &AudioOutputConfiguration{
|
|
Token: cfg.Token,
|
|
Name: cfg.Name,
|
|
UseCount: cfg.UseCount,
|
|
OutputToken: cfg.OutputToken,
|
|
}
|
|
}
|
|
|
|
return configs, nil
|
|
}
|
|
|
|
// GetAudioDecoderConfigurations retrieves all audio decoder configurations.
|
|
func (c *Client) GetAudioDecoderConfigurations(ctx context.Context) ([]*AudioDecoderConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetAudioDecoderConfigurations struct {
|
|
XMLName xml.Name `xml:"trt:GetAudioDecoderConfigurations"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
}
|
|
|
|
type GetAudioDecoderConfigurationsResponse struct {
|
|
XMLName xml.Name `xml:"GetAudioDecoderConfigurationsResponse"`
|
|
Configurations []struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
} `xml:"Configurations"`
|
|
}
|
|
|
|
req := GetAudioDecoderConfigurations{
|
|
Xmlns: mediaNamespace,
|
|
}
|
|
|
|
var resp GetAudioDecoderConfigurationsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetAudioDecoderConfigurations failed: %w", err)
|
|
}
|
|
|
|
configs := make([]*AudioDecoderConfiguration, len(resp.Configurations))
|
|
for i, cfg := range resp.Configurations {
|
|
configs[i] = &AudioDecoderConfiguration{
|
|
Token: cfg.Token,
|
|
Name: cfg.Name,
|
|
UseCount: cfg.UseCount,
|
|
}
|
|
}
|
|
|
|
return configs, nil
|
|
}
|
|
|
|
// GetAudioDecoderConfiguration retrieves a specific audio decoder configuration.
|
|
func (c *Client) GetAudioDecoderConfiguration(
|
|
ctx context.Context,
|
|
configurationToken string,
|
|
) (*AudioDecoderConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetAudioDecoderConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:GetAudioDecoderConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken"`
|
|
}
|
|
|
|
type GetAudioDecoderConfigurationResponse struct {
|
|
XMLName xml.Name `xml:"GetAudioDecoderConfigurationResponse"`
|
|
Configuration struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
} `xml:"Configuration"`
|
|
}
|
|
|
|
req := GetAudioDecoderConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ConfigurationToken: configurationToken,
|
|
}
|
|
|
|
var resp GetAudioDecoderConfigurationResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetAudioDecoderConfiguration failed: %w", err)
|
|
}
|
|
|
|
return &AudioDecoderConfiguration{
|
|
Token: resp.Configuration.Token,
|
|
Name: resp.Configuration.Name,
|
|
UseCount: resp.Configuration.UseCount,
|
|
}, nil
|
|
}
|
|
|
|
// SetAudioDecoderConfiguration sets audio decoder configuration.
|
|
func (c *Client) SetAudioDecoderConfiguration(ctx context.Context, config *AudioDecoderConfiguration, forcePersistence bool) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type SetAudioDecoderConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:SetAudioDecoderConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
Xmlnst string `xml:"xmlns:tt,attr"`
|
|
Configuration struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"tt:Name"`
|
|
UseCount int `xml:"tt:UseCount"`
|
|
} `xml:"trt:Configuration"`
|
|
ForcePersistence bool `xml:"trt:ForcePersistence"`
|
|
}
|
|
|
|
req := SetAudioDecoderConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
Xmlnst: "http://www.onvif.org/ver10/schema",
|
|
ForcePersistence: forcePersistence,
|
|
}
|
|
|
|
req.Configuration.Token = config.Token
|
|
req.Configuration.Name = config.Name
|
|
req.Configuration.UseCount = config.UseCount
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("SetAudioDecoderConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetVideoAnalyticsConfigurations retrieves all video analytics configurations.
|
|
func (c *Client) GetVideoAnalyticsConfigurations(ctx context.Context) ([]*VideoAnalyticsConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetVideoAnalyticsConfigurations struct {
|
|
XMLName xml.Name `xml:"trt:GetVideoAnalyticsConfigurations"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
}
|
|
|
|
type GetVideoAnalyticsConfigurationsResponse struct {
|
|
XMLName xml.Name `xml:"GetVideoAnalyticsConfigurationsResponse"`
|
|
Configurations []struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
} `xml:"Configurations"`
|
|
}
|
|
|
|
req := GetVideoAnalyticsConfigurations{
|
|
Xmlns: mediaNamespace,
|
|
}
|
|
|
|
var resp GetVideoAnalyticsConfigurationsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetVideoAnalyticsConfigurations failed: %w", err)
|
|
}
|
|
|
|
configs := make([]*VideoAnalyticsConfiguration, len(resp.Configurations))
|
|
for i, cfg := range resp.Configurations {
|
|
configs[i] = &VideoAnalyticsConfiguration{
|
|
Token: cfg.Token,
|
|
Name: cfg.Name,
|
|
UseCount: cfg.UseCount,
|
|
}
|
|
}
|
|
|
|
return configs, nil
|
|
}
|
|
|
|
// GetVideoAnalyticsConfiguration retrieves a specific video analytics configuration.
|
|
func (c *Client) GetVideoAnalyticsConfiguration(
|
|
ctx context.Context,
|
|
configurationToken string,
|
|
) (*VideoAnalyticsConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetVideoAnalyticsConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:GetVideoAnalyticsConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken"`
|
|
}
|
|
|
|
type GetVideoAnalyticsConfigurationResponse struct {
|
|
XMLName xml.Name `xml:"GetVideoAnalyticsConfigurationResponse"`
|
|
Configuration struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
} `xml:"Configuration"`
|
|
}
|
|
|
|
req := GetVideoAnalyticsConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ConfigurationToken: configurationToken,
|
|
}
|
|
|
|
var resp GetVideoAnalyticsConfigurationResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetVideoAnalyticsConfiguration failed: %w", err)
|
|
}
|
|
|
|
return &VideoAnalyticsConfiguration{
|
|
Token: resp.Configuration.Token,
|
|
Name: resp.Configuration.Name,
|
|
UseCount: resp.Configuration.UseCount,
|
|
}, nil
|
|
}
|
|
|
|
// GetCompatibleVideoAnalyticsConfigurations retrieves compatible video analytics configurations for a profile.
|
|
func (c *Client) GetCompatibleVideoAnalyticsConfigurations(ctx context.Context, profileToken string) ([]*VideoAnalyticsConfiguration, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetCompatibleVideoAnalyticsConfigurations struct {
|
|
XMLName xml.Name `xml:"trt:GetCompatibleVideoAnalyticsConfigurations"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
type GetCompatibleVideoAnalyticsConfigurationsResponse struct {
|
|
XMLName xml.Name `xml:"GetCompatibleVideoAnalyticsConfigurationsResponse"`
|
|
Configurations []struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"Name"`
|
|
UseCount int `xml:"UseCount"`
|
|
} `xml:"Configurations"`
|
|
}
|
|
|
|
req := GetCompatibleVideoAnalyticsConfigurations{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
var resp GetCompatibleVideoAnalyticsConfigurationsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetCompatibleVideoAnalyticsConfigurations failed: %w", err)
|
|
}
|
|
|
|
configs := make([]*VideoAnalyticsConfiguration, len(resp.Configurations))
|
|
for i, cfg := range resp.Configurations {
|
|
configs[i] = &VideoAnalyticsConfiguration{
|
|
Token: cfg.Token,
|
|
Name: cfg.Name,
|
|
UseCount: cfg.UseCount,
|
|
}
|
|
}
|
|
|
|
return configs, nil
|
|
}
|
|
|
|
// SetVideoAnalyticsConfiguration sets video analytics configuration.
|
|
func (c *Client) SetVideoAnalyticsConfiguration(ctx context.Context, config *VideoAnalyticsConfiguration, forcePersistence bool) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type SetVideoAnalyticsConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:SetVideoAnalyticsConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
Xmlnst string `xml:"xmlns:tt,attr"`
|
|
Configuration struct {
|
|
Token string `xml:"token,attr"`
|
|
Name string `xml:"tt:Name"`
|
|
UseCount int `xml:"tt:UseCount"`
|
|
} `xml:"trt:Configuration"`
|
|
ForcePersistence bool `xml:"trt:ForcePersistence"`
|
|
}
|
|
|
|
req := SetVideoAnalyticsConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
Xmlnst: "http://www.onvif.org/ver10/schema",
|
|
ForcePersistence: forcePersistence,
|
|
}
|
|
|
|
req.Configuration.Token = config.Token
|
|
req.Configuration.Name = config.Name
|
|
req.Configuration.UseCount = config.UseCount
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("SetVideoAnalyticsConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetVideoAnalyticsConfigurationOptions retrieves available options for video analytics configuration.
|
|
func (c *Client) GetVideoAnalyticsConfigurationOptions(
|
|
ctx context.Context,
|
|
configurationToken, profileToken string,
|
|
) (*VideoAnalyticsConfigurationOptions, error) {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type GetVideoAnalyticsConfigurationOptions struct {
|
|
XMLName xml.Name `xml:"trt:GetVideoAnalyticsConfigurationOptions"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken,omitempty"`
|
|
ProfileToken string `xml:"trt:ProfileToken,omitempty"`
|
|
}
|
|
|
|
type GetVideoAnalyticsConfigurationOptionsResponse struct {
|
|
XMLName xml.Name `xml:"GetVideoAnalyticsConfigurationOptionsResponse"`
|
|
Options struct{} `xml:"Options"`
|
|
}
|
|
|
|
req := GetVideoAnalyticsConfigurationOptions{
|
|
Xmlns: mediaNamespace,
|
|
}
|
|
if configurationToken != "" {
|
|
req.ConfigurationToken = configurationToken
|
|
}
|
|
if profileToken != "" {
|
|
req.ProfileToken = profileToken
|
|
}
|
|
|
|
var resp GetVideoAnalyticsConfigurationOptionsResponse
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, &resp); err != nil {
|
|
return nil, fmt.Errorf("GetVideoAnalyticsConfigurationOptions failed: %w", err)
|
|
}
|
|
|
|
return &VideoAnalyticsConfigurationOptions{}, nil
|
|
}
|
|
|
|
// AddVideoAnalyticsConfiguration adds a video analytics configuration to a profile.
|
|
func (c *Client) AddVideoAnalyticsConfiguration(ctx context.Context, profileToken, configurationToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type AddVideoAnalyticsConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:AddVideoAnalyticsConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken"`
|
|
}
|
|
|
|
req := AddVideoAnalyticsConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
ConfigurationToken: configurationToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("AddVideoAnalyticsConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// RemoveVideoAnalyticsConfiguration removes a video analytics configuration from a profile.
|
|
func (c *Client) RemoveVideoAnalyticsConfiguration(ctx context.Context, profileToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type RemoveVideoAnalyticsConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:RemoveVideoAnalyticsConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
req := RemoveVideoAnalyticsConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("RemoveVideoAnalyticsConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// AddAudioOutputConfiguration adds an audio output configuration to a profile.
|
|
func (c *Client) AddAudioOutputConfiguration(ctx context.Context, profileToken, configurationToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type AddAudioOutputConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:AddAudioOutputConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken"`
|
|
}
|
|
|
|
req := AddAudioOutputConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
ConfigurationToken: configurationToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("AddAudioOutputConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// RemoveAudioOutputConfiguration removes an audio output configuration from a profile.
|
|
func (c *Client) RemoveAudioOutputConfiguration(ctx context.Context, profileToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type RemoveAudioOutputConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:RemoveAudioOutputConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
req := RemoveAudioOutputConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("RemoveAudioOutputConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// AddAudioDecoderConfiguration adds an audio decoder configuration to a profile.
|
|
func (c *Client) AddAudioDecoderConfiguration(ctx context.Context, profileToken, configurationToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type AddAudioDecoderConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:AddAudioDecoderConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
ConfigurationToken string `xml:"trt:ConfigurationToken"`
|
|
}
|
|
|
|
req := AddAudioDecoderConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
ConfigurationToken: configurationToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("AddAudioDecoderConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// RemoveAudioDecoderConfiguration removes an audio decoder configuration from a profile.
|
|
func (c *Client) RemoveAudioDecoderConfiguration(ctx context.Context, profileToken string) error {
|
|
endpoint := c.mediaEndpoint
|
|
if endpoint == "" {
|
|
endpoint = c.endpoint
|
|
}
|
|
|
|
type RemoveAudioDecoderConfiguration struct {
|
|
XMLName xml.Name `xml:"trt:RemoveAudioDecoderConfiguration"`
|
|
Xmlns string `xml:"xmlns:trt,attr"`
|
|
ProfileToken string `xml:"trt:ProfileToken"`
|
|
}
|
|
|
|
req := RemoveAudioDecoderConfiguration{
|
|
Xmlns: mediaNamespace,
|
|
ProfileToken: profileToken,
|
|
}
|
|
|
|
username, password := c.GetCredentials()
|
|
soapClient := soap.NewClient(c.httpClient, username, password)
|
|
|
|
if err := soapClient.Call(ctx, endpoint, "", req, nil); err != nil {
|
|
return fmt.Errorf("RemoveAudioDecoderConfiguration failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|