Files
go2tv/go2tv.go
2021-02-11 19:11:45 +02:00

137 lines
3.2 KiB
Go

package main
import (
"errors"
"flag"
"fmt"
"os"
"os/signal"
"path/filepath"
"sort"
"syscall"
"github.com/alexballas/go2tv/iptools"
"github.com/alexballas/go2tv/servfiles"
"github.com/alexballas/go2tv/soapcalls"
"github.com/koron/go-ssdp"
)
var (
dmrURL string
serverStarted = make(chan struct{})
devices = make(map[int][]string)
videoArg = flag.String("v", "", "Path to the video file.")
subsArg = flag.String("s", "", "Path to the subtitles file. (not supported yet)")
listPtr = flag.Bool("l", false, "List all available UPnP/DLNA MediaRenderer models and URLs.")
targetPtr = flag.String("t", "", "Cast to a specific UPnP/DLNA MediaRenderer URL.")
)
func main() {
flag.Parse()
exit, err := checkflags()
if err != nil {
fmt.Fprintf(os.Stderr, "Encountered error(s): %s\n", err)
os.Exit(1)
}
if exit == true {
os.Exit(0)
}
absVideoFile, err := filepath.Abs(*videoArg)
if err != nil {
fmt.Fprintf(os.Stderr, "Encountered error(s): %s\n", err)
os.Exit(1)
}
absSubtitlesFile := *subsArg
transportURL, err := soapcalls.AVTransportFromDMRextractor(dmrURL)
if err != nil {
fmt.Fprintf(os.Stderr, "Encountered error(s): %s\n", err)
os.Exit(1)
}
whereToListen, err := iptools.URLtoListenIPandPort(dmrURL)
if err != nil {
fmt.Fprintf(os.Stderr, "Encountered error(s): %s\n", err)
os.Exit(1)
}
tvdata := &soapcalls.TVPayload{
TransportURL: transportURL,
VideoURL: "http://" + whereToListen + "/" + filepath.Base(absVideoFile),
SubtitlesURL: "http://" + whereToListen + "/" + filepath.Base(absSubtitlesFile),
}
if err != nil {
fmt.Fprintf(os.Stderr, "Encountered error(s): %s\n", err)
os.Exit(1)
}
s := servfiles.NewServer(whereToListen)
go func() { s.ServeFiles(serverStarted, absVideoFile, absSubtitlesFile) }()
// Wait for HTTP server to properly initialize
<-serverStarted
if err := tvdata.SendtoTV("Play"); err != nil {
fmt.Fprintf(os.Stderr, "Encountered error(s): %s\n", err)
os.Exit(1)
}
initializeCloseHandler(*tvdata)
// Sleep forever
select {}
}
func loadSSDPservices() error {
list, err := ssdp.Search(ssdp.All, 1, "")
if err != nil {
return err
}
counter := 0
for _, srv := range list {
// We only care about the AVTransport services
if srv.Type == "urn:schemas-upnp-org:service:AVTransport:1" {
counter++
devices[counter] = []string{srv.Server, srv.Location}
}
}
if counter > 0 {
return nil
}
return errors.New("loadSSDPservices: No available Media Renderers")
}
func devicePicker(i int) (string, error) {
if i > len(devices) || len(devices) == 0 || i <= 0 {
return "", errors.New("devicePicker: Requested device not available")
}
keys := make([]int, 0)
for k := range devices {
keys = append(keys, k)
}
sort.Ints(keys)
for _, k := range keys {
if i == k {
return devices[k][1], nil
}
}
return "", errors.New("devicePicker: Something went terribly wrong")
}
func initializeCloseHandler(tvdata soapcalls.TVPayload) {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
<-c
fmt.Println(" Shutting down...")
if err := tvdata.SendtoTV("Stop"); err != nil {
fmt.Fprintf(os.Stderr, "Encountered error(s): %s\n", err)
os.Exit(1)
}
os.Exit(0)
}()
}