Introduce NewTVPayload function
This commit is contained in:
@@ -15,9 +15,7 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/alexballas/go2tv/devices"
|
"github.com/alexballas/go2tv/devices"
|
||||||
"github.com/alexballas/go2tv/httphandlers"
|
"github.com/alexballas/go2tv/httphandlers"
|
||||||
@@ -66,7 +64,6 @@ func run() error {
|
|||||||
var mediaType string
|
var mediaType string
|
||||||
var mediaFile interface{}
|
var mediaFile interface{}
|
||||||
var isSeek bool
|
var isSeek bool
|
||||||
var tvdata *soapcalls.TVPayload
|
|
||||||
var s *httphandlers.HTTPserver
|
var s *httphandlers.HTTPserver
|
||||||
|
|
||||||
keyboardExitCTX, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
keyboardExitCTX, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||||
@@ -151,42 +148,21 @@ func run() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
upnpServicesURLs, err := soapcalls.DMRextractor(flagRes.dmrURL)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
whereToListen, err := utils.URLtoListenIPandPort(flagRes.dmrURL)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
scr := &dummyScreen{ctxCancel: cancel2}
|
scr := &dummyScreen{ctxCancel: cancel2}
|
||||||
|
|
||||||
callbackPath, err := utils.RandomString()
|
tvdata, err := soapcalls.NewTVPayload(soapcalls.Options{
|
||||||
|
DMR: flagRes.dmrURL,
|
||||||
|
Media: absMediaFile,
|
||||||
|
Subs: absSubtitlesFile,
|
||||||
|
Mtype: mediaType,
|
||||||
|
Transcode: *transcodePtr,
|
||||||
|
Seek: isSeek,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
tvdata = &soapcalls.TVPayload{
|
s = httphandlers.NewServer(tvdata.ListenAddress())
|
||||||
ControlURL: upnpServicesURLs.AvtransportControlURL,
|
|
||||||
EventURL: upnpServicesURLs.AvtransportEventSubURL,
|
|
||||||
RenderingControlURL: upnpServicesURLs.RenderingControlURL,
|
|
||||||
ConnectionManagerURL: upnpServicesURLs.ConnectionManagerURL,
|
|
||||||
CallbackURL: "http://" + whereToListen + "/" + callbackPath,
|
|
||||||
MediaURL: "http://" + whereToListen + "/" + utils.ConvertFilename(absMediaFile),
|
|
||||||
SubtitlesURL: "http://" + whereToListen + "/" + utils.ConvertFilename(absSubtitlesFile),
|
|
||||||
MediaType: mediaType,
|
|
||||||
CurrentTimers: make(map[string]*time.Timer),
|
|
||||||
MediaRenderersStates: make(map[string]*soapcalls.States),
|
|
||||||
InitialMediaRenderersStates: make(map[string]bool),
|
|
||||||
RWMutex: &sync.RWMutex{},
|
|
||||||
Transcode: *transcodePtr,
|
|
||||||
Seekable: isSeek,
|
|
||||||
Logging: os.Stderr,
|
|
||||||
}
|
|
||||||
|
|
||||||
s = httphandlers.NewServer(whereToListen)
|
|
||||||
serverStarted := make(chan error)
|
serverStarted := make(chan error)
|
||||||
|
|
||||||
// We pass the tvdata here as we need the callback handlers to be able to react
|
// We pass the tvdata here as we need the callback handlers to be able to react
|
||||||
|
@@ -14,9 +14,7 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
|
||||||
|
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
@@ -144,44 +142,24 @@ func run() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
upnpServicesURLs, err := soapcalls.DMRextractor(flagRes.dmrURL)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
whereToListen, err := utils.URLtoListenIPandPort(flagRes.dmrURL)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
scr, err := interactive.InitTcellNewScreen(cancel2)
|
scr, err := interactive.InitTcellNewScreen(cancel2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
callbackPath, err := utils.RandomString()
|
tvdata, err := soapcalls.NewTVPayload(soapcalls.Options{
|
||||||
|
DMR: flagRes.dmrURL,
|
||||||
|
Media: absMediaFile,
|
||||||
|
Subs: absSubtitlesFile,
|
||||||
|
Mtype: mediaType,
|
||||||
|
Transcode: *transcodePtr,
|
||||||
|
Seek: isSeek,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
tvdata := &soapcalls.TVPayload{
|
s := httphandlers.NewServer(tvdata.ListenAddress())
|
||||||
ControlURL: upnpServicesURLs.AvtransportControlURL,
|
|
||||||
EventURL: upnpServicesURLs.AvtransportEventSubURL,
|
|
||||||
RenderingControlURL: upnpServicesURLs.RenderingControlURL,
|
|
||||||
ConnectionManagerURL: upnpServicesURLs.ConnectionManagerURL,
|
|
||||||
CallbackURL: "http://" + whereToListen + "/" + callbackPath,
|
|
||||||
MediaURL: "http://" + whereToListen + "/" + utils.ConvertFilename(absMediaFile),
|
|
||||||
SubtitlesURL: "http://" + whereToListen + "/" + utils.ConvertFilename(absSubtitlesFile),
|
|
||||||
MediaType: mediaType,
|
|
||||||
CurrentTimers: make(map[string]*time.Timer),
|
|
||||||
MediaRenderersStates: make(map[string]*soapcalls.States),
|
|
||||||
InitialMediaRenderersStates: make(map[string]bool),
|
|
||||||
RWMutex: &sync.RWMutex{},
|
|
||||||
Transcode: *transcodePtr,
|
|
||||||
Seekable: isSeek,
|
|
||||||
}
|
|
||||||
|
|
||||||
s := httphandlers.NewServer(whereToListen)
|
|
||||||
serverStarted := make(chan error)
|
serverStarted := make(chan error)
|
||||||
|
|
||||||
// We pass the tvdata here as we need the callback handlers to be able to react
|
// We pass the tvdata here as we need the callback handlers to be able to react
|
||||||
|
@@ -12,7 +12,6 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"fyne.io/fyne/v2"
|
"fyne.io/fyne/v2"
|
||||||
@@ -289,7 +288,6 @@ func playAction(screen *NewScreen) {
|
|||||||
CurrentTimers: make(map[string]*time.Timer),
|
CurrentTimers: make(map[string]*time.Timer),
|
||||||
MediaRenderersStates: make(map[string]*soapcalls.States),
|
MediaRenderersStates: make(map[string]*soapcalls.States),
|
||||||
InitialMediaRenderersStates: make(map[string]bool),
|
InitialMediaRenderersStates: make(map[string]bool),
|
||||||
RWMutex: &sync.RWMutex{},
|
|
||||||
Transcode: screen.Transcode,
|
Transcode: screen.Transcode,
|
||||||
Seekable: isSeek,
|
Seekable: isSeek,
|
||||||
Logging: screen.Debug,
|
Logging: screen.Debug,
|
||||||
|
@@ -10,7 +10,6 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"fyne.io/fyne/v2"
|
"fyne.io/fyne/v2"
|
||||||
@@ -273,7 +272,6 @@ func playAction(screen *NewScreen) {
|
|||||||
CurrentTimers: make(map[string]*time.Timer),
|
CurrentTimers: make(map[string]*time.Timer),
|
||||||
MediaRenderersStates: make(map[string]*soapcalls.States),
|
MediaRenderersStates: make(map[string]*soapcalls.States),
|
||||||
InitialMediaRenderersStates: make(map[string]bool),
|
InitialMediaRenderersStates: make(map[string]bool),
|
||||||
RWMutex: &sync.RWMutex{},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
screen.httpserver = httphandlers.NewServer(whereToListen)
|
screen.httpserver = httphandlers.NewServer(whereToListen)
|
||||||
|
@@ -34,7 +34,7 @@ type TVPayload struct {
|
|||||||
Logging io.Writer
|
Logging io.Writer
|
||||||
CurrentTimers map[string]*time.Timer
|
CurrentTimers map[string]*time.Timer
|
||||||
InitialMediaRenderersStates map[string]bool
|
InitialMediaRenderersStates map[string]bool
|
||||||
*sync.RWMutex
|
mu sync.RWMutex
|
||||||
MediaRenderersStates map[string]*States
|
MediaRenderersStates map[string]*States
|
||||||
RenderingControlURL string
|
RenderingControlURL string
|
||||||
ConnectionManagerURL string
|
ConnectionManagerURL string
|
||||||
@@ -46,7 +46,7 @@ type TVPayload struct {
|
|||||||
CallbackURL string
|
CallbackURL string
|
||||||
Transcode bool
|
Transcode bool
|
||||||
Seekable bool
|
Seekable bool
|
||||||
InitLogOnce sync.Once
|
initLogOnce sync.Once
|
||||||
}
|
}
|
||||||
|
|
||||||
type getMuteRespBody struct {
|
type getMuteRespBody struct {
|
||||||
@@ -816,12 +816,12 @@ func (p *TVPayload) SendtoTV(action string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if action == "Stop" {
|
if action == "Stop" {
|
||||||
p.RLock()
|
p.mu.RLock()
|
||||||
localStates := make(map[string]*States)
|
localStates := make(map[string]*States)
|
||||||
for key, value := range p.MediaRenderersStates {
|
for key, value := range p.MediaRenderersStates {
|
||||||
localStates[key] = value
|
localStates[key] = value
|
||||||
}
|
}
|
||||||
p.RUnlock()
|
p.mu.RUnlock()
|
||||||
|
|
||||||
// Cleaning up all uuids on force stop.
|
// Cleaning up all uuids on force stop.
|
||||||
for uuids := range localStates {
|
for uuids := range localStates {
|
||||||
@@ -853,8 +853,8 @@ func (p *TVPayload) UpdateMRstate(previous, new, uuid string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Lock()
|
p.mu.Lock()
|
||||||
defer p.Unlock()
|
defer p.mu.Unlock()
|
||||||
// If the UUID is not available in p.InitialMediaRenderersStates,
|
// If the UUID is not available in p.InitialMediaRenderersStates,
|
||||||
// it probably expired and there is not much we can do with it.
|
// it probably expired and there is not much we can do with it.
|
||||||
// Trying to send an UNSUBSCRIBE call for that UUID will result
|
// Trying to send an UNSUBSCRIBE call for that UUID will result
|
||||||
@@ -872,31 +872,31 @@ func (p *TVPayload) UpdateMRstate(previous, new, uuid string) bool {
|
|||||||
|
|
||||||
// CreateMRstate .
|
// CreateMRstate .
|
||||||
func (p *TVPayload) CreateMRstate(uuid string) {
|
func (p *TVPayload) CreateMRstate(uuid string) {
|
||||||
p.Lock()
|
p.mu.Lock()
|
||||||
defer p.Unlock()
|
defer p.mu.Unlock()
|
||||||
p.InitialMediaRenderersStates[uuid] = true
|
p.InitialMediaRenderersStates[uuid] = true
|
||||||
p.MediaRenderersStates[uuid] = &States{}
|
p.MediaRenderersStates[uuid] = &States{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteMRstate deletes the state entries for the specific UUID.
|
// DeleteMRstate deletes the state entries for the specific UUID.
|
||||||
func (p *TVPayload) DeleteMRstate(uuid string) {
|
func (p *TVPayload) DeleteMRstate(uuid string) {
|
||||||
p.Lock()
|
p.mu.Lock()
|
||||||
defer p.Unlock()
|
defer p.mu.Unlock()
|
||||||
delete(p.InitialMediaRenderersStates, uuid)
|
delete(p.InitialMediaRenderersStates, uuid)
|
||||||
delete(p.MediaRenderersStates, uuid)
|
delete(p.MediaRenderersStates, uuid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetProcessStopTrue set the stop process to true
|
// SetProcessStopTrue set the stop process to true
|
||||||
func (p *TVPayload) SetProcessStopTrue(uuid string) {
|
func (p *TVPayload) SetProcessStopTrue(uuid string) {
|
||||||
p.Lock()
|
p.mu.Lock()
|
||||||
defer p.Unlock()
|
defer p.mu.Unlock()
|
||||||
p.MediaRenderersStates[uuid].ProcessStop = true
|
p.MediaRenderersStates[uuid].ProcessStop = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetProcessStop returns the processStop value of the specific UUID.
|
// GetProcessStop returns the processStop value of the specific UUID.
|
||||||
func (p *TVPayload) GetProcessStop(uuid string) (bool, error) {
|
func (p *TVPayload) GetProcessStop(uuid string) (bool, error) {
|
||||||
p.RLock()
|
p.mu.RLock()
|
||||||
defer p.RUnlock()
|
defer p.mu.RUnlock()
|
||||||
if p.InitialMediaRenderersStates[uuid] {
|
if p.InitialMediaRenderersStates[uuid] {
|
||||||
return p.MediaRenderersStates[uuid].ProcessStop, nil
|
return p.MediaRenderersStates[uuid].ProcessStop, nil
|
||||||
}
|
}
|
||||||
@@ -906,7 +906,7 @@ func (p *TVPayload) GetProcessStop(uuid string) (bool, error) {
|
|||||||
|
|
||||||
func (p *TVPayload) Log() *zerolog.Logger {
|
func (p *TVPayload) Log() *zerolog.Logger {
|
||||||
if p.Logging != nil {
|
if p.Logging != nil {
|
||||||
p.InitLogOnce.Do(func() {
|
p.initLogOnce.Do(func() {
|
||||||
log = zerolog.New(p.Logging).With().Timestamp().Logger()
|
log = zerolog.New(p.Logging).With().Timestamp().Logger()
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
51
soapcalls/soapcalls.go
Normal file
51
soapcalls/soapcalls.go
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package soapcalls
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/alexballas/go2tv/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Options struct {
|
||||||
|
DMR, Media, Subs, Mtype, ListenAddr string
|
||||||
|
Transcode, Seek bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var listenAddress string
|
||||||
|
|
||||||
|
func NewTVPayload(o Options) (*TVPayload, error) {
|
||||||
|
upnpServicesURLs, err := DMRextractor(o.DMR)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
callbackPath, err := utils.RandomString()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ListenAddr, err := utils.URLtoListenIPandPort(o.DMR)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &TVPayload{
|
||||||
|
ControlURL: upnpServicesURLs.AvtransportControlURL,
|
||||||
|
EventURL: upnpServicesURLs.AvtransportEventSubURL,
|
||||||
|
RenderingControlURL: upnpServicesURLs.RenderingControlURL,
|
||||||
|
ConnectionManagerURL: upnpServicesURLs.ConnectionManagerURL,
|
||||||
|
CallbackURL: "http://" + ListenAddr + "/" + callbackPath,
|
||||||
|
MediaURL: "http://" + ListenAddr + "/" + utils.ConvertFilename(o.Media),
|
||||||
|
SubtitlesURL: "http://" + ListenAddr + "/" + utils.ConvertFilename(o.Subs),
|
||||||
|
MediaType: o.Mtype,
|
||||||
|
CurrentTimers: make(map[string]*time.Timer),
|
||||||
|
MediaRenderersStates: make(map[string]*States),
|
||||||
|
InitialMediaRenderersStates: make(map[string]bool),
|
||||||
|
Transcode: o.Transcode,
|
||||||
|
Seekable: o.Seek,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tv *TVPayload) ListenAddress() string {
|
||||||
|
return listenAddress
|
||||||
|
}
|
Reference in New Issue
Block a user