Files
go2tv/soapcalls/soapbuilders.go

905 lines
25 KiB
Go

package soapcalls
import (
"bytes"
"encoding/xml"
"fmt"
"net/url"
"regexp"
"strings"
"github.com/alexballas/go2tv/soapcalls/utils"
"github.com/pkg/errors"
)
var (
ErrSetMuteInput = errors.New("setMuteSoapBuild input error. Was expecting 0 or 1.")
)
type playEnvelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Schema string `xml:"xmlns:s,attr"`
Encoding string `xml:"s:encodingStyle,attr"`
PlayBody playBody `xml:"s:Body"`
}
type playBody struct {
XMLName xml.Name `xml:"s:Body"`
PlayAction playAction `xml:"u:Play"`
}
type playAction struct {
XMLName xml.Name `xml:"u:Play"`
AVTransport string `xml:"xmlns:u,attr"`
InstanceID string
Speed string
}
type pauseEnvelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Schema string `xml:"xmlns:s,attr"`
Encoding string `xml:"s:encodingStyle,attr"`
PauseBody pauseBody `xml:"s:Body"`
}
type pauseBody struct {
XMLName xml.Name `xml:"s:Body"`
PauseAction pauseAction `xml:"u:Pause"`
}
type pauseAction struct {
XMLName xml.Name `xml:"u:Pause"`
AVTransport string `xml:"xmlns:u,attr"`
InstanceID string
Speed string
}
type stopEnvelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Schema string `xml:"xmlns:s,attr"`
Encoding string `xml:"s:encodingStyle,attr"`
StopBody stopBody `xml:"s:Body"`
}
type stopBody struct {
XMLName xml.Name `xml:"s:Body"`
StopAction stopAction `xml:"u:Stop"`
}
type stopAction struct {
XMLName xml.Name `xml:"u:Stop"`
AVTransport string `xml:"xmlns:u,attr"`
InstanceID string
Speed string
}
type seekEnvelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Schema string `xml:"xmlns:s,attr"`
Encoding string `xml:"s:encodingStyle,attr"`
SeekBody seekBody `xml:"s:Body"`
}
type seekBody struct {
XMLName xml.Name `xml:"s:Body"`
SeekAction seekAction `xml:"u:Seek"`
}
type seekAction struct {
XMLName xml.Name `xml:"u:Seek"`
AVTransport string `xml:"xmlns:u,attr"`
InstanceID string
Unit string
Target string
}
type setAVTransportEnvelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Schema string `xml:"xmlns:s,attr"`
Encoding string `xml:"s:encodingStyle,attr"`
Body setAVTransportBody `xml:"s:Body"`
}
type setAVTransportBody struct {
XMLName xml.Name `xml:"s:Body"`
SetAVTransportURI setAVTransportURI `xml:"u:SetAVTransportURI"`
}
type setAVTransportURI struct {
XMLName xml.Name `xml:"u:SetAVTransportURI"`
AVTransport string `xml:"xmlns:u,attr"`
InstanceID string
CurrentURI string
CurrentURIMetaData currentURIMetaData `xml:"CurrentURIMetaData"`
}
type currentURIMetaData struct {
XMLName xml.Name `xml:"CurrentURIMetaData"`
Value []byte `xml:",chardata"`
}
type setNextAVTransportEnvelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Schema string `xml:"xmlns:s,attr"`
Encoding string `xml:"s:encodingStyle,attr"`
Body setNextAVTransportBody `xml:"s:Body"`
}
type setNextAVTransportBody struct {
XMLName xml.Name `xml:"s:Body"`
SetNextAVTransportURI setNextAVTransportURI `xml:"u:SetNextAVTransportURI"`
}
type setNextAVTransportURI struct {
XMLName xml.Name `xml:"u:SetNextAVTransportURI"`
AVTransport string `xml:"xmlns:u,attr"`
InstanceID string
NextURI string
NextURIMetaData nextURIMetaData `xml:"NextURIMetaData"`
}
type nextURIMetaData struct {
XMLName xml.Name `xml:"NextURIMetaData"`
Value []byte `xml:",chardata"`
}
type didLLite struct {
XMLName xml.Name `xml:"DIDL-Lite"`
SchemaDIDL string `xml:"xmlns,attr"`
DC string `xml:"xmlns:dc,attr"`
Sec string `xml:"xmlns:sec,attr"`
SchemaUPNP string `xml:"xmlns:upnp,attr"`
DIDLLiteItem didLLiteItem `xml:"item"`
}
type didLLiteItem struct {
SecCaptionInfo *secCaptionInfo `xml:"sec:CaptionInfo,omitempty"`
SecCaptionInfoEx *secCaptionInfoEx `xml:"sec:CaptionInfoEx,omitempty"`
XMLName xml.Name `xml:"item"`
DCtitle string `xml:"dc:title"`
UPNPClass string `xml:"upnp:class"`
ID string `xml:"id,attr"`
ParentID string `xml:"parentID,attr"`
Restricted string `xml:"restricted,attr"`
ResNode []resNode `xml:"res"`
}
type resNode struct {
XMLName xml.Name `xml:"res"`
Duration string `xml:"duration,attr,omitempty"`
ProtocolInfo string `xml:"protocolInfo,attr"`
Value string `xml:",chardata"`
}
type secCaptionInfo struct {
XMLName xml.Name `xml:"sec:CaptionInfo"`
Type string `xml:"sec:type,attr"`
Value string `xml:",chardata"`
}
type secCaptionInfoEx struct {
XMLName xml.Name `xml:"sec:CaptionInfoEx"`
Type string `xml:"sec:type,attr"`
Value string `xml:",chardata"`
}
type setMuteEnvelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Schema string `xml:"xmlns:s,attr"`
Encoding string `xml:"s:encodingStyle,attr"`
SetMuteBody setMuteBody `xml:"s:Body"`
}
type setMuteBody struct {
XMLName xml.Name `xml:"s:Body"`
SetMuteAction setMuteAction `xml:"u:SetMute"`
}
type setMuteAction struct {
XMLName xml.Name `xml:"u:SetMute"`
RenderingControl string `xml:"xmlns:u,attr"`
InstanceID string
Channel string
DesiredMute string
}
type getMuteEnvelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Schema string `xml:"xmlns:s,attr"`
Encoding string `xml:"s:encodingStyle,attr"`
GetMuteBody getMuteBody `xml:"s:Body"`
}
type getMuteBody struct {
XMLName xml.Name `xml:"s:Body"`
GetMuteAction getMuteAction `xml:"u:GetMute"`
}
type getMuteAction struct {
XMLName xml.Name `xml:"u:GetMute"`
RenderingControl string `xml:"xmlns:u,attr"`
InstanceID string
Channel string
}
type getVolumeEnvelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Schema string `xml:"xmlns:s,attr"`
Encoding string `xml:"s:encodingStyle,attr"`
GetVolumeBody getVolumeBody `xml:"s:Body"`
}
type getVolumeBody struct {
XMLName xml.Name `xml:"s:Body"`
GetVolumeAction getVolumeAction `xml:"u:GetVolume"`
}
type getVolumeAction struct {
XMLName xml.Name `xml:"u:GetVolume"`
RenderingControl string `xml:"xmlns:u,attr"`
InstanceID string
Channel string
}
type setVolumeEnvelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Schema string `xml:"xmlns:s,attr"`
Encoding string `xml:"s:encodingStyle,attr"`
SetVolumeBody setVolumeBody `xml:"s:Body"`
}
type setVolumeBody struct {
XMLName xml.Name `xml:"s:Body"`
SetVolumeAction setVolumeAction `xml:"u:SetVolume"`
}
type setVolumeAction struct {
XMLName xml.Name `xml:"u:SetVolume"`
RenderingControl string `xml:"xmlns:u,attr"`
InstanceID string
Channel string
DesiredVolume string
}
type getProtocolInfoEnvelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Schema string `xml:"xmlns:s,attr"`
Encoding string `xml:"s:encodingStyle,attr"`
GetProtocolInfoBody getProtocolInfoBody `xml:"s:Body"`
}
type getProtocolInfoBody struct {
XMLName xml.Name `xml:"s:Body"`
GetProtocolInfoAction getProtocolInfoAction `xml:"u:GetProtocolInfo"`
}
type getProtocolInfoAction struct {
XMLName xml.Name `xml:"u:GetProtocolInfo"`
ConnectionManager string `xml:"xmlns:u,attr"`
}
type getMediaInfoEnvelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Schema string `xml:"xmlns:s,attr"`
Encoding string `xml:"s:encodingStyle,attr"`
GetMediaInfoBody getMediaInfoBody `xml:"s:Body"`
}
type getMediaInfoBody struct {
XMLName xml.Name `xml:"s:Body"`
GetMediaInfoAction getMediaInfoAction `xml:"u:GetMediaInfo"`
}
type getMediaInfoAction struct {
XMLName xml.Name `xml:"u:GetMediaInfo"`
AVTransport string `xml:"xmlns:u,attr"`
InstanceID string
}
type getTransportInfoEnvelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Schema string `xml:"xmlns:s,attr"`
Encoding string `xml:"s:encodingStyle,attr"`
GetTransportInfoBody getTransportInfoBody `xml:"s:Body"`
}
type getTransportInfoBody struct {
XMLName xml.Name `xml:"s:Body"`
GetTransportInfoAction getTransportInfoAction `xml:"u:GetTransportInfo"`
}
type getTransportInfoAction struct {
XMLName xml.Name `xml:"u:GetTransportInfo"`
AVTransport string `xml:"xmlns:u,attr"`
InstanceID string
}
type getPositionInfoEnvelope struct {
XMLName xml.Name `xml:"s:Envelope"`
Schema string `xml:"xmlns:s,attr"`
Encoding string `xml:"s:encodingStyle,attr"`
GetPositionInfoBody getPositionInfoBody `xml:"s:Body"`
}
type getPositionInfoBody struct {
XMLName xml.Name `xml:"s:Body"`
GetPositionInfoAction getPositionInfoAction `xml:"u:GetPositionInfo"`
}
type getPositionInfoAction struct {
XMLName xml.Name `xml:"u:GetPositionInfo"`
AVTransport string `xml:"xmlns:u,attr"`
InstanceID string
}
func setAVTransportSoapBuild(tvdata *TVPayload) ([]byte, error) {
mediaTypeSlice := strings.Split(tvdata.MediaType, "/")
seekflag := "00"
if tvdata.Seekable {
seekflag = "01"
}
contentFeatures, err := utils.BuildContentFeatures(tvdata.MediaType, seekflag, tvdata.Transcode)
if err != nil {
return nil, fmt.Errorf("setAVTransportSoapBuild failed to build contentFeatures: %w", err)
}
var class string
switch mediaTypeSlice[0] {
case "audio":
class = "object.item.audioItem.musicTrack"
case "image":
class = "object.item.imageItem.photo"
default:
class = "object.item.videoItem.movie"
}
mediaTitlefromURL, err := url.Parse(tvdata.MediaURL)
if err != nil {
return nil, fmt.Errorf("setAVTransportSoapBuild url parse error: %w", err)
}
mediaTitle := strings.TrimLeft(mediaTitlefromURL.Path, "/")
re, err := regexp.Compile(`[&<>\\]+`)
if err != nil {
return nil, fmt.Errorf("setAVTransportSoapBuild regex compile error: %w", err)
}
mediaTitle = re.ReplaceAllString(mediaTitle, "")
var didl didLLiteItem
resNodeData := []resNode{}
duration, _ := utils.DurationForMedia(tvdata.FFmpegPath, tvdata.MediaPath)
switch duration {
case "":
resNodeData = append(resNodeData, resNode{
XMLName: xml.Name{},
ProtocolInfo: fmt.Sprintf("http-get:*:%s:%s", tvdata.MediaType, contentFeatures),
Value: tvdata.MediaURL,
})
default:
resNodeData = append(resNodeData, resNode{
XMLName: xml.Name{},
Duration: duration,
ProtocolInfo: fmt.Sprintf("http-get:*:%s:%s", tvdata.MediaType, contentFeatures),
Value: tvdata.MediaURL,
})
}
didl = didLLiteItem{
XMLName: xml.Name{},
ID: "1",
ParentID: "0",
Restricted: "1",
UPNPClass: class,
DCtitle: mediaTitle,
ResNode: resNodeData,
}
if strings.Contains(tvdata.SubtitlesURL, "srt") {
resNodeData = append(resNodeData, resNode{
XMLName: xml.Name{},
ProtocolInfo: "http-get:*:text/srt:*",
Value: tvdata.SubtitlesURL,
})
didl = didLLiteItem{
XMLName: xml.Name{},
ID: "1",
ParentID: "0",
Restricted: "1",
DCtitle: mediaTitle,
UPNPClass: class,
ResNode: resNodeData,
SecCaptionInfo: &secCaptionInfo{
XMLName: xml.Name{},
Type: "srt",
Value: tvdata.SubtitlesURL,
},
SecCaptionInfoEx: &secCaptionInfoEx{
XMLName: xml.Name{},
Type: "srt",
Value: tvdata.SubtitlesURL,
},
}
}
l := didLLite{
XMLName: xml.Name{},
SchemaDIDL: "urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/",
DC: "http://purl.org/dc/elements/1.1/",
Sec: "http://www.sec.co.kr/",
SchemaUPNP: "urn:schemas-upnp-org:metadata-1-0/upnp/",
DIDLLiteItem: didl,
}
a, err := xml.Marshal(l)
if err != nil {
return nil, fmt.Errorf("setAVTransportSoapBuild #1 Marshal error: %w", err)
}
d := setAVTransportEnvelope{
XMLName: xml.Name{},
Schema: "http://schemas.xmlsoap.org/soap/envelope/",
Encoding: "http://schemas.xmlsoap.org/soap/encoding/",
Body: setAVTransportBody{
XMLName: xml.Name{},
SetAVTransportURI: setAVTransportURI{
XMLName: xml.Name{},
AVTransport: "urn:schemas-upnp-org:service:AVTransport:1",
InstanceID: "0",
CurrentURI: tvdata.MediaURL,
CurrentURIMetaData: currentURIMetaData{
XMLName: xml.Name{},
Value: a,
},
},
},
}
xmlStart := []byte(`<?xml version="1.0" encoding="utf-8"?>`)
b, err := xml.Marshal(d)
if err != nil {
return nil, fmt.Errorf("setAVTransportSoapBuild #2 Marshal error: %w", err)
}
// Samsung TV hack.
b = bytes.ReplaceAll(b, []byte("&#34;"), []byte(`"`))
b = bytes.ReplaceAll(b, []byte("&amp;"), []byte("&"))
return append(xmlStart, b...), nil
}
func setNextAVTransportSoapBuild(tvdata *TVPayload, clear bool) ([]byte, error) {
mediaTypeSlice := strings.Split(tvdata.MediaType, "/")
seekflag := "00"
if tvdata.Seekable {
seekflag = "01"
}
contentFeatures, err := utils.BuildContentFeatures(tvdata.MediaType, seekflag, tvdata.Transcode)
if err != nil {
return nil, fmt.Errorf("setNextAVTransportSoapBuild failed to build contentFeatures: %w", err)
}
var class string
switch mediaTypeSlice[0] {
case "audio":
class = "object.item.audioItem.musicTrack"
case "image":
class = "object.item.imageItem.photo"
default:
class = "object.item.videoItem.movie"
}
murl := tvdata.MediaURL
if clear {
murl = ""
}
mediaTitlefromURL, err := url.Parse(murl)
if err != nil {
return nil, fmt.Errorf("setNextAVTransportSoapBuild url parse error: %w", err)
}
mediaTitle := strings.TrimLeft(mediaTitlefromURL.Path, "/")
re, err := regexp.Compile(`[&<>\\]+`)
if err != nil {
return nil, fmt.Errorf("setNextAVTransportSoapBuild regex compile error: %w", err)
}
mediaTitle = re.ReplaceAllString(mediaTitle, "")
var didl didLLiteItem
resNodeData := []resNode{}
duration, _ := utils.DurationForMedia(tvdata.FFmpegPath, tvdata.MediaPath)
switch duration {
case "":
resNodeData = append(resNodeData, resNode{
XMLName: xml.Name{},
ProtocolInfo: fmt.Sprintf("http-get:*:%s:%s", tvdata.MediaType, contentFeatures),
Value: murl,
})
default:
resNodeData = append(resNodeData, resNode{
XMLName: xml.Name{},
Duration: duration,
ProtocolInfo: fmt.Sprintf("http-get:*:%s:%s", tvdata.MediaType, contentFeatures),
Value: murl,
})
}
didl = didLLiteItem{
XMLName: xml.Name{},
ID: "1",
ParentID: "0",
Restricted: "1",
UPNPClass: class,
DCtitle: mediaTitle,
ResNode: resNodeData,
}
if strings.Contains(tvdata.SubtitlesURL, "srt") {
resNodeData = append(resNodeData, resNode{
XMLName: xml.Name{},
ProtocolInfo: "http-get:*:text/srt:*",
Value: tvdata.SubtitlesURL,
})
didl = didLLiteItem{
XMLName: xml.Name{},
ID: "1",
ParentID: "0",
Restricted: "1",
DCtitle: mediaTitle,
UPNPClass: class,
ResNode: resNodeData,
SecCaptionInfo: &secCaptionInfo{
XMLName: xml.Name{},
Type: "srt",
Value: tvdata.SubtitlesURL,
},
SecCaptionInfoEx: &secCaptionInfoEx{
XMLName: xml.Name{},
Type: "srt",
Value: tvdata.SubtitlesURL,
},
}
}
l := didLLite{
XMLName: xml.Name{},
SchemaDIDL: "urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/",
DC: "http://purl.org/dc/elements/1.1/",
Sec: "http://www.sec.co.kr/",
SchemaUPNP: "urn:schemas-upnp-org:metadata-1-0/upnp/",
DIDLLiteItem: didl,
}
a, err := xml.Marshal(l)
if err != nil {
return nil, fmt.Errorf("setNextAVTransportSoapBuild #1 Marshal error: %w", err)
}
d := setNextAVTransportEnvelope{
XMLName: xml.Name{},
Schema: "http://schemas.xmlsoap.org/soap/envelope/",
Encoding: "http://schemas.xmlsoap.org/soap/encoding/",
Body: setNextAVTransportBody{
XMLName: xml.Name{},
SetNextAVTransportURI: setNextAVTransportURI{
XMLName: xml.Name{},
AVTransport: "urn:schemas-upnp-org:service:AVTransport:1",
InstanceID: "0",
NextURI: murl,
NextURIMetaData: nextURIMetaData{
XMLName: xml.Name{},
Value: a,
},
},
},
}
xmlStart := []byte(`<?xml version="1.0" encoding="utf-8"?>`)
b, err := xml.Marshal(d)
if err != nil {
return nil, fmt.Errorf("setNextAVTransportSoapBuild #2 Marshal error: %w", err)
}
// Samsung TV hack.
b = bytes.ReplaceAll(b, []byte("&#34;"), []byte(`"`))
b = bytes.ReplaceAll(b, []byte("&amp;"), []byte("&"))
return append(xmlStart, b...), nil
}
func playSoapBuild() ([]byte, error) {
d := playEnvelope{
XMLName: xml.Name{},
Schema: "http://schemas.xmlsoap.org/soap/envelope/",
Encoding: "http://schemas.xmlsoap.org/soap/encoding/",
PlayBody: playBody{
XMLName: xml.Name{},
PlayAction: playAction{
XMLName: xml.Name{},
AVTransport: "urn:schemas-upnp-org:service:AVTransport:1",
InstanceID: "0",
Speed: "1",
},
},
}
xmlStart := []byte(`<?xml version="1.0" encoding="utf-8"?>`)
b, err := xml.Marshal(d)
if err != nil {
return nil, fmt.Errorf("playSoapBuild Marshal error: %w", err)
}
return append(xmlStart, b...), nil
}
func stopSoapBuild() ([]byte, error) {
d := stopEnvelope{
XMLName: xml.Name{},
Schema: "http://schemas.xmlsoap.org/soap/envelope/",
Encoding: "http://schemas.xmlsoap.org/soap/encoding/",
StopBody: stopBody{
XMLName: xml.Name{},
StopAction: stopAction{
XMLName: xml.Name{},
AVTransport: "urn:schemas-upnp-org:service:AVTransport:1",
InstanceID: "0",
Speed: "1",
},
},
}
xmlStart := []byte(`<?xml version="1.0" encoding="utf-8"?>`)
b, err := xml.Marshal(d)
if err != nil {
return nil, fmt.Errorf("stopSoapBuild Marshal error: %w", err)
}
return append(xmlStart, b...), nil
}
func pauseSoapBuild() ([]byte, error) {
d := pauseEnvelope{
XMLName: xml.Name{},
Schema: "http://schemas.xmlsoap.org/soap/envelope/",
Encoding: "http://schemas.xmlsoap.org/soap/encoding/",
PauseBody: pauseBody{
XMLName: xml.Name{},
PauseAction: pauseAction{
XMLName: xml.Name{},
AVTransport: "urn:schemas-upnp-org:service:AVTransport:1",
InstanceID: "0",
Speed: "1",
},
},
}
xmlStart := []byte(`<?xml version="1.0" encoding="utf-8"?>`)
b, err := xml.Marshal(d)
if err != nil {
return nil, fmt.Errorf("pauseSoapBuild Marshal error: %w", err)
}
return append(xmlStart, b...), nil
}
func setMuteSoapBuild(m string) ([]byte, error) {
if m != "0" && m != "1" {
return nil, ErrSetMuteInput
}
d := setMuteEnvelope{
XMLName: xml.Name{},
Schema: "http://schemas.xmlsoap.org/soap/envelope/",
Encoding: "http://schemas.xmlsoap.org/soap/encoding/",
SetMuteBody: setMuteBody{
XMLName: xml.Name{},
SetMuteAction: setMuteAction{
XMLName: xml.Name{},
RenderingControl: "urn:schemas-upnp-org:service:RenderingControl:1",
InstanceID: "0",
Channel: "Master",
DesiredMute: m,
},
},
}
xmlStart := []byte(`<?xml version="1.0" encoding="utf-8"?>`)
b, err := xml.Marshal(d)
if err != nil {
return nil, fmt.Errorf("setMuteSoapBuild Marshal error: %w", err)
}
return append(xmlStart, b...), nil
}
func getMuteSoapBuild() ([]byte, error) {
d := getMuteEnvelope{
XMLName: xml.Name{},
Schema: "http://schemas.xmlsoap.org/soap/envelope/",
Encoding: "http://schemas.xmlsoap.org/soap/encoding/",
GetMuteBody: getMuteBody{
XMLName: xml.Name{},
GetMuteAction: getMuteAction{
XMLName: xml.Name{},
RenderingControl: "urn:schemas-upnp-org:service:RenderingControl:1",
InstanceID: "0",
Channel: "Master",
},
},
}
xmlStart := []byte(`<?xml version="1.0" encoding="utf-8"?>`)
b, err := xml.Marshal(d)
if err != nil {
return nil, fmt.Errorf("getMuteSoapBuild Marshal error: %w", err)
}
return append(xmlStart, b...), nil
}
func getVolumeSoapBuild() ([]byte, error) {
d := getVolumeEnvelope{
XMLName: xml.Name{},
Schema: "http://schemas.xmlsoap.org/soap/envelope/",
Encoding: "http://schemas.xmlsoap.org/soap/encoding/",
GetVolumeBody: getVolumeBody{
XMLName: xml.Name{},
GetVolumeAction: getVolumeAction{
XMLName: xml.Name{},
RenderingControl: "urn:schemas-upnp-org:service:RenderingControl:1",
InstanceID: "0",
Channel: "Master",
},
},
}
xmlStart := []byte(`<?xml version="1.0" encoding="utf-8"?>`)
b, err := xml.Marshal(d)
if err != nil {
return nil, fmt.Errorf("getVolumeSoapBuild Marshal error: %w", err)
}
return append(xmlStart, b...), nil
}
func setVolumeSoapBuild(v string) ([]byte, error) {
d := setVolumeEnvelope{
XMLName: xml.Name{},
Schema: "http://schemas.xmlsoap.org/soap/envelope/",
Encoding: "http://schemas.xmlsoap.org/soap/encoding/",
SetVolumeBody: setVolumeBody{
XMLName: xml.Name{},
SetVolumeAction: setVolumeAction{
XMLName: xml.Name{},
RenderingControl: "urn:schemas-upnp-org:service:RenderingControl:1",
InstanceID: "0",
Channel: "Master",
DesiredVolume: v,
},
},
}
xmlStart := []byte(`<?xml version="1.0" encoding="utf-8"?>`)
b, err := xml.Marshal(d)
if err != nil {
return nil, fmt.Errorf("setVolumeSoapBuild Marshal error: %w", err)
}
return append(xmlStart, b...), nil
}
func getProtocolInfoSoapBuild() ([]byte, error) {
d := getProtocolInfoEnvelope{
XMLName: xml.Name{},
Schema: "http://schemas.xmlsoap.org/soap/envelope/",
Encoding: "http://schemas.xmlsoap.org/soap/encoding/",
GetProtocolInfoBody: getProtocolInfoBody{
XMLName: xml.Name{},
GetProtocolInfoAction: getProtocolInfoAction{
XMLName: xml.Name{},
ConnectionManager: "urn:schemas-upnp-org:service:ConnectionManager:1",
},
},
}
xmlStart := []byte(`<?xml version="1.0" encoding="utf-8"?>`)
b, err := xml.Marshal(d)
if err != nil {
return nil, fmt.Errorf("getProtocolInfoSoapBuild Marshal error: %w", err)
}
return append(xmlStart, b...), nil
}
func getMediaInfoSoapBuild() ([]byte, error) {
d := getMediaInfoEnvelope{
XMLName: xml.Name{},
Schema: "http://schemas.xmlsoap.org/soap/envelope/",
Encoding: "http://schemas.xmlsoap.org/soap/encoding/",
GetMediaInfoBody: getMediaInfoBody{
XMLName: xml.Name{},
GetMediaInfoAction: getMediaInfoAction{
XMLName: xml.Name{},
AVTransport: "urn:schemas-upnp-org:service:AVTransport:1",
InstanceID: "0",
},
},
}
xmlStart := []byte(`<?xml version="1.0" encoding="utf-8"?>`)
b, err := xml.Marshal(d)
if err != nil {
return nil, fmt.Errorf("getMediaInfoSoapBuild Marshal error: %w", err)
}
return append(xmlStart, b...), nil
}
func getTransportInfoSoapBuild() ([]byte, error) {
d := getTransportInfoEnvelope{
XMLName: xml.Name{},
Schema: "http://schemas.xmlsoap.org/soap/envelope/",
Encoding: "http://schemas.xmlsoap.org/soap/encoding/",
GetTransportInfoBody: getTransportInfoBody{
XMLName: xml.Name{},
GetTransportInfoAction: getTransportInfoAction{
XMLName: xml.Name{},
AVTransport: "urn:schemas-upnp-org:service:AVTransport:1",
InstanceID: "0",
},
},
}
xmlStart := []byte(`<?xml version="1.0" encoding="utf-8"?>`)
b, err := xml.Marshal(d)
if err != nil {
return nil, fmt.Errorf("getTransportInfoSoapBuild Marshal error: %w", err)
}
return append(xmlStart, b...), nil
}
func getPositionInfoSoapBuild() ([]byte, error) {
d := getPositionInfoEnvelope{
XMLName: xml.Name{},
Schema: "http://schemas.xmlsoap.org/soap/envelope/",
Encoding: "http://schemas.xmlsoap.org/soap/encoding/",
GetPositionInfoBody: getPositionInfoBody{
XMLName: xml.Name{},
GetPositionInfoAction: getPositionInfoAction{
XMLName: xml.Name{},
AVTransport: "urn:schemas-upnp-org:service:AVTransport:1",
InstanceID: "0",
},
},
}
xmlStart := []byte(`<?xml version="1.0" encoding="utf-8"?>`)
b, err := xml.Marshal(d)
if err != nil {
return nil, fmt.Errorf("getPositionInfoSoapBuild Marshal error: %w", err)
}
return append(xmlStart, b...), nil
}
func seekSoapBuild(reltime string) ([]byte, error) {
d := seekEnvelope{
XMLName: xml.Name{},
Schema: "http://schemas.xmlsoap.org/soap/envelope/",
Encoding: "http://schemas.xmlsoap.org/soap/encoding/",
SeekBody: seekBody{
XMLName: xml.Name{},
SeekAction: seekAction{
XMLName: xml.Name{},
AVTransport: "urn:schemas-upnp-org:service:AVTransport:1",
InstanceID: "0",
Unit: "REL_TIME",
Target: reltime,
},
},
}
xmlStart := []byte(`<?xml version="1.0" encoding="utf-8"?>`)
b, err := xml.Marshal(d)
if err != nil {
return nil, fmt.Errorf("seekSoapBuild Marshal error: %w", err)
}
return append(xmlStart, b...), nil
}