Use standard port for ssdp discovery. Also try to fix CLI issue on windows
This commit is contained in:
3
Makefile
3
Makefile
@@ -1,11 +1,10 @@
|
||||
LDFLAGS="-s -w"
|
||||
WINLDFLAGS="-H=windowsgui -s -w"
|
||||
|
||||
build: clean
|
||||
go build -trimpath -ldflags $(LDFLAGS) -o build/go2tv cmd/go2tv/go2tv.go
|
||||
|
||||
windows: clean
|
||||
env CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ GOOS=windows GOARCH=amd64 go build -trimpath -ldflags $(WINLDFLAGS) -o build/go2tv.exe cmd/go2tv/go2tv.go
|
||||
env CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ GOOS=windows GOARCH=amd64 go build -trimpath -ldflags $(LDFLAGS) -o build/go2tv.exe cmd/go2tv/go2tv.go
|
||||
|
||||
install: build
|
||||
mkdir -vp /usr/local/bin/
|
||||
|
@@ -106,7 +106,7 @@ func run() error {
|
||||
}
|
||||
|
||||
if flagRes.gui {
|
||||
scr := gui.InitFyneNewScreen(version)
|
||||
scr := gui.NewFyneScreen(version)
|
||||
gui.Start(exitCTX, scr)
|
||||
return nil
|
||||
}
|
||||
|
@@ -21,7 +21,7 @@ var (
|
||||
func LoadSSDPservices(delay int) (map[string]string, error) {
|
||||
// Reset device list every time we call this.
|
||||
urlList := make(map[string]string)
|
||||
list, err := ssdp.Search(ssdp.All, delay, "")
|
||||
list, err := ssdp.Search(ssdp.All, delay, "239.255.255.250:1900")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("LoadSSDPservices search error: %w", err)
|
||||
}
|
||||
|
12
go.mod
12
go.mod
@@ -3,7 +3,7 @@ module github.com/alexballas/go2tv
|
||||
go 1.23.3
|
||||
|
||||
require (
|
||||
fyne.io/fyne/v2 v2.5.2
|
||||
fyne.io/fyne/v2 v2.5.3
|
||||
github.com/alexballas/go-ssdp v0.0.3
|
||||
github.com/gdamore/tcell/v2 v2.7.4
|
||||
github.com/h2non/filetype v1.1.3
|
||||
@@ -14,6 +14,7 @@ require (
|
||||
github.com/rs/zerolog v1.33.0
|
||||
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d
|
||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
|
||||
golang.org/x/sys v0.28.0
|
||||
golang.org/x/time v0.8.0
|
||||
)
|
||||
|
||||
@@ -30,11 +31,11 @@ require (
|
||||
github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 // indirect
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a // indirect
|
||||
github.com/go-text/render v0.2.0 // indirect
|
||||
github.com/go-text/typesetting v0.2.0 // indirect
|
||||
github.com/go-text/typesetting v0.2.1 // indirect
|
||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||
github.com/gopherjs/gopherjs v1.17.2 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/jeandeaual/go-locale v0.0.0-20241204123234-32dda1c00a20 // indirect
|
||||
github.com/jeandeaual/go-locale v0.0.0-20241217141322-fcc2cadd6f08 // indirect
|
||||
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
@@ -48,9 +49,8 @@ require (
|
||||
github.com/stretchr/testify v1.10.0 // indirect
|
||||
github.com/yuin/goldmark v1.7.8 // indirect
|
||||
golang.org/x/image v0.23.0 // indirect
|
||||
golang.org/x/mobile v0.0.0-20241204233305-ce44b2716d33 // indirect
|
||||
golang.org/x/net v0.32.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
golang.org/x/mobile v0.0.0-20241213221354-a87c1cf6cf46 // indirect
|
||||
golang.org/x/net v0.33.0 // indirect
|
||||
golang.org/x/term v0.27.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
24
go.sum
24
go.sum
@@ -37,8 +37,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
fyne.io/fyne/v2 v2.5.2 h1:eSyGTmSkv10yAdAeHpDet6u2KkKxOGFc14kQu81We7Q=
|
||||
fyne.io/fyne/v2 v2.5.2/go.mod h1:26gqPDvtaxHeyct+C0BBjuGd2zwAJlPkUGSBrb+d7Ug=
|
||||
fyne.io/fyne/v2 v2.5.3 h1:k6LjZx6EzRZhClsuzy6vucLZBstdH2USDGHSGWq8ly8=
|
||||
fyne.io/fyne/v2 v2.5.3/go.mod h1:0GOXKqyvNwk3DLmsFu9v0oYM0ZcD1ysGnlHCerKoAmo=
|
||||
fyne.io/systray v1.11.0 h1:D9HISlxSkx+jHSniMBR6fCFOUjk1x/OOOJLa9lJYAKg=
|
||||
fyne.io/systray v1.11.0/go.mod h1:RVwqP9nYMo7h5zViCBHri2FgjXF7H2cub7MAq4NSoLs=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
@@ -107,10 +107,10 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a h1:vxnBhFDDT+
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-text/render v0.2.0 h1:LBYoTmp5jYiJ4NPqDc2pz17MLmA3wHw1dZSVGcOdeAc=
|
||||
github.com/go-text/render v0.2.0/go.mod h1:CkiqfukRGKJA5vZZISkjSYrcdtgKQWRa2HIzvwNN5SU=
|
||||
github.com/go-text/typesetting v0.2.0 h1:fbzsgbmk04KiWtE+c3ZD4W2nmCRzBqrqQOvYlwAOdho=
|
||||
github.com/go-text/typesetting v0.2.0/go.mod h1:2+owI/sxa73XA581LAzVuEBZ3WEEV2pXeDswCH/3i1I=
|
||||
github.com/go-text/typesetting-utils v0.0.0-20240317173224-1986cbe96c66 h1:GUrm65PQPlhFSKjLPGOZNPNxLCybjzjYBzjfoBGaDUY=
|
||||
github.com/go-text/typesetting-utils v0.0.0-20240317173224-1986cbe96c66/go.mod h1:DDxDdQEnB70R8owOx3LVpEFvpMK9eeH1o2r0yZhFI9o=
|
||||
github.com/go-text/typesetting v0.2.1 h1:x0jMOGyO3d1qFAPI0j4GSsh7M0Q3Ypjzr4+CEVg82V8=
|
||||
github.com/go-text/typesetting v0.2.1/go.mod h1:mTOxEwasOFpAMBjEQDhdWRckoLLeI/+qrQeBCTGEt6M=
|
||||
github.com/go-text/typesetting-utils v0.0.0-20241103174707-87a29e9e6066 h1:qCuYC+94v2xrb1PoS4NIDe7DGYtLnU2wWiQe9a1B1c0=
|
||||
github.com/go-text/typesetting-utils v0.0.0-20241103174707-87a29e9e6066/go.mod h1:DDxDdQEnB70R8owOx3LVpEFvpMK9eeH1o2r0yZhFI9o=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
@@ -216,8 +216,8 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jeandeaual/go-locale v0.0.0-20241204123234-32dda1c00a20 h1:S6sn9jRW3oq1k/Qiwa20F+E57ZVJ2+KB1Vp5xiJ1FlI=
|
||||
github.com/jeandeaual/go-locale v0.0.0-20241204123234-32dda1c00a20/go.mod h1:pYcXQtDPRThfL37oZEzUVo2Jb8ua0NEC7rZqrxXyuhA=
|
||||
github.com/jeandeaual/go-locale v0.0.0-20241217141322-fcc2cadd6f08 h1:wMeVzrPO3mfHIWLZtDcSaGAe2I4PW9B/P5nMkRSwCAc=
|
||||
github.com/jeandeaual/go-locale v0.0.0-20241217141322-fcc2cadd6f08/go.mod h1:ZDXo8KHryOWSIqnsb/CiDq7hQUYryCgdVnxbj8tDG7o=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
@@ -382,8 +382,8 @@ golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPI
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mobile v0.0.0-20211207041440-4e6c2922fdee/go.mod h1:pe2sM7Uk+2Su1y7u/6Z8KJ24D7lepUjFZbhFOrmDfuQ=
|
||||
golang.org/x/mobile v0.0.0-20241204233305-ce44b2716d33 h1:MeYjBsMjR6w9aXA3oHEJWCQ5bnD5fOjesYMOn52ovQY=
|
||||
golang.org/x/mobile v0.0.0-20241204233305-ce44b2716d33/go.mod h1:Sf9LBimL0mWKEdgAjRmJ6iu7Z34osHQTK/devqFbM2I=
|
||||
golang.org/x/mobile v0.0.0-20241213221354-a87c1cf6cf46 h1:E+R1qmJL8cmWTyWXBHVtmqRxr7FdiTwntffsba1F1Tg=
|
||||
golang.org/x/mobile v0.0.0-20241213221354-a87c1cf6cf46/go.mod h1:Sf9LBimL0mWKEdgAjRmJ6iu7Z34osHQTK/devqFbM2I=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
@@ -434,8 +434,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI=
|
||||
golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs=
|
||||
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
@@ -20,7 +20,7 @@ import (
|
||||
"fyne.io/fyne/v2/widget"
|
||||
)
|
||||
|
||||
func aboutWindow(s *NewScreen) fyne.CanvasObject {
|
||||
func aboutWindow(s *FyneScreen) fyne.CanvasObject {
|
||||
sr := fyne.NewStaticResource("Go2TV Icon", go2TVSmallIcon)
|
||||
go2tvImage := canvas.NewImageFromResource(sr)
|
||||
richhead := widget.NewRichTextFromMarkdown(`
|
||||
@@ -70,7 +70,7 @@ MIT
|
||||
return container.NewPadded(cont)
|
||||
}
|
||||
|
||||
func checkVersion(s *NewScreen) {
|
||||
func checkVersion(s *FyneScreen) {
|
||||
s.CheckVersion.Disable()
|
||||
defer s.CheckVersion.Enable()
|
||||
errRedirectChecker := errors.New("redirect")
|
||||
|
@@ -30,7 +30,7 @@ import (
|
||||
"github.com/skratchdot/open-golang/open"
|
||||
)
|
||||
|
||||
func muteAction(screen *NewScreen) {
|
||||
func muteAction(screen *FyneScreen) {
|
||||
if screen.renderingControlURL == "" {
|
||||
check(screen, errors.New(lang.L("please select a device")))
|
||||
return
|
||||
@@ -56,7 +56,7 @@ func muteAction(screen *NewScreen) {
|
||||
setMuteUnmuteView("Unmute", screen)
|
||||
}
|
||||
|
||||
func unmuteAction(screen *NewScreen) {
|
||||
func unmuteAction(screen *FyneScreen) {
|
||||
if screen.renderingControlURL == "" {
|
||||
check(screen, errors.New(lang.L("please select a device")))
|
||||
return
|
||||
@@ -78,7 +78,7 @@ func unmuteAction(screen *NewScreen) {
|
||||
setMuteUnmuteView("Mute", screen)
|
||||
}
|
||||
|
||||
func selectMediaFile(screen *NewScreen, f fyne.URI) {
|
||||
func selectMediaFile(screen *FyneScreen, f fyne.URI) {
|
||||
mfile := f.Path()
|
||||
absMediaFile, err := filepath.Abs(mfile)
|
||||
check(screen, err)
|
||||
@@ -116,7 +116,7 @@ func selectMediaFile(screen *NewScreen, f fyne.URI) {
|
||||
screen.SelectInternalSubs.Enable()
|
||||
}
|
||||
|
||||
func selectSubsFile(screen *NewScreen, f fyne.URI) {
|
||||
func selectSubsFile(screen *FyneScreen, f fyne.URI) {
|
||||
sfile := f.Path()
|
||||
absSubtitlesFile, err := filepath.Abs(sfile)
|
||||
check(screen, err)
|
||||
@@ -131,7 +131,7 @@ func selectSubsFile(screen *NewScreen, f fyne.URI) {
|
||||
screen.SubsText.Refresh()
|
||||
}
|
||||
|
||||
func mediaAction(screen *NewScreen) {
|
||||
func mediaAction(screen *FyneScreen) {
|
||||
w := screen.Current
|
||||
fd := dialog.NewFileOpen(func(reader fyne.URIReadCloser, err error) {
|
||||
check(screen, err)
|
||||
@@ -157,7 +157,7 @@ func mediaAction(screen *NewScreen) {
|
||||
fd.Show()
|
||||
}
|
||||
|
||||
func subsAction(screen *NewScreen) {
|
||||
func subsAction(screen *FyneScreen) {
|
||||
w := screen.Current
|
||||
fd := dialog.NewFileOpen(func(reader fyne.URIReadCloser, err error) {
|
||||
check(screen, err)
|
||||
@@ -185,7 +185,7 @@ func subsAction(screen *NewScreen) {
|
||||
fd.Show()
|
||||
}
|
||||
|
||||
func playAction(screen *NewScreen) {
|
||||
func playAction(screen *FyneScreen) {
|
||||
var mediaFile interface{}
|
||||
|
||||
screen.PlayPause.Disable()
|
||||
@@ -422,7 +422,7 @@ func playAction(screen *NewScreen) {
|
||||
|
||||
}
|
||||
|
||||
func startAfreshPlayButton(screen *NewScreen) {
|
||||
func startAfreshPlayButton(screen *FyneScreen) {
|
||||
if screen.cancelEnablePlay != nil {
|
||||
screen.cancelEnablePlay()
|
||||
}
|
||||
@@ -431,7 +431,7 @@ func startAfreshPlayButton(screen *NewScreen) {
|
||||
screen.updateScreenState("Stopped")
|
||||
}
|
||||
|
||||
func gaplessMediaWatcher(ctx context.Context, screen *NewScreen, payload *soapcalls.TVPayload) {
|
||||
func gaplessMediaWatcher(ctx context.Context, screen *FyneScreen, payload *soapcalls.TVPayload) {
|
||||
t := time.NewTicker(1 * time.Second)
|
||||
out:
|
||||
for {
|
||||
@@ -489,12 +489,12 @@ out:
|
||||
}
|
||||
}
|
||||
|
||||
func pauseAction(screen *NewScreen) {
|
||||
func pauseAction(screen *FyneScreen) {
|
||||
err := screen.tvdata.SendtoTV("Pause")
|
||||
check(screen, err)
|
||||
}
|
||||
|
||||
func clearmediaAction(screen *NewScreen) {
|
||||
func clearmediaAction(screen *FyneScreen) {
|
||||
screen.MediaText.Text = ""
|
||||
screen.mediafile = ""
|
||||
screen.MediaText.Refresh()
|
||||
@@ -504,14 +504,14 @@ func clearmediaAction(screen *NewScreen) {
|
||||
screen.SelectInternalSubs.Disable()
|
||||
}
|
||||
|
||||
func clearsubsAction(screen *NewScreen) {
|
||||
func clearsubsAction(screen *FyneScreen) {
|
||||
screen.SelectInternalSubs.ClearSelected()
|
||||
screen.SubsText.Text = ""
|
||||
screen.subsfile = ""
|
||||
screen.SubsText.Refresh()
|
||||
}
|
||||
|
||||
func skipNextAction(screen *NewScreen) {
|
||||
func skipNextAction(screen *FyneScreen) {
|
||||
if screen.controlURL == "" {
|
||||
check(screen, errors.New(lang.L("please select a device")))
|
||||
return
|
||||
@@ -536,7 +536,7 @@ func skipNextAction(screen *NewScreen) {
|
||||
playAction(screen)
|
||||
}
|
||||
|
||||
func previewmedia(screen *NewScreen) {
|
||||
func previewmedia(screen *FyneScreen) {
|
||||
if screen.mediafile == "" {
|
||||
check(screen, errors.New(lang.L("please select a media file")))
|
||||
return
|
||||
@@ -571,7 +571,7 @@ func previewmedia(screen *NewScreen) {
|
||||
}
|
||||
}
|
||||
|
||||
func stopAction(screen *NewScreen) {
|
||||
func stopAction(screen *FyneScreen) {
|
||||
screen.PlayPause.Enable()
|
||||
|
||||
if screen.tvdata == nil || screen.tvdata.ControlURL == "" {
|
||||
@@ -610,7 +610,7 @@ func getDevices(delay int) ([]devType, error) {
|
||||
return guiDeviceList, nil
|
||||
}
|
||||
|
||||
func volumeAction(screen *NewScreen, up bool) {
|
||||
func volumeAction(screen *FyneScreen, up bool) {
|
||||
if screen.renderingControlURL == "" {
|
||||
check(screen, errors.New(lang.L("please select a device")))
|
||||
return
|
||||
@@ -646,7 +646,7 @@ func volumeAction(screen *NewScreen, up bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func queueNext(screen *NewScreen, clear bool) (*soapcalls.TVPayload, error) {
|
||||
func queueNext(screen *FyneScreen, clear bool) (*soapcalls.TVPayload, error) {
|
||||
if screen.tvdata == nil {
|
||||
return nil, errors.New("queueNext, nil tvdata")
|
||||
}
|
||||
|
@@ -27,8 +27,8 @@ import (
|
||||
"github.com/alexballas/go2tv/soapcalls/utils"
|
||||
)
|
||||
|
||||
// NewScreen .
|
||||
type NewScreen struct {
|
||||
// FyneScreen .
|
||||
type FyneScreen struct {
|
||||
tempFiles []string
|
||||
SelectInternalSubs *widget.Select
|
||||
CurrentPos binding.String
|
||||
@@ -51,7 +51,7 @@ type NewScreen struct {
|
||||
httpserver *httphandlers.HTTPserver
|
||||
MediaText *widget.Entry
|
||||
ExternalMediaURL *widget.Check
|
||||
GaplessMediaWatcher func(context.Context, *NewScreen, *soapcalls.TVPayload)
|
||||
GaplessMediaWatcher func(context.Context, *FyneScreen, *soapcalls.TVPayload)
|
||||
SlideBar *tappedSlider
|
||||
MuteUnmute *widget.Button
|
||||
VolumeDown *widget.Button
|
||||
@@ -102,7 +102,7 @@ func (f *debugWriter) Write(b []byte) (int, error) {
|
||||
var translations embed.FS
|
||||
|
||||
// Start .
|
||||
func Start(ctx context.Context, s *NewScreen) {
|
||||
func Start(ctx context.Context, s *FyneScreen) {
|
||||
if s == nil {
|
||||
return
|
||||
}
|
||||
@@ -174,7 +174,7 @@ func Start(ctx context.Context, s *NewScreen) {
|
||||
|
||||
}
|
||||
|
||||
func onDropFiles(screen *NewScreen) func(p fyne.Position, u []fyne.URI) {
|
||||
func onDropFiles(screen *FyneScreen) func(p fyne.Position, u []fyne.URI) {
|
||||
return func(p fyne.Position, u []fyne.URI) {
|
||||
var mfiles, sfiles []fyne.URI
|
||||
|
||||
@@ -205,7 +205,7 @@ func onDropFiles(screen *NewScreen) func(p fyne.Position, u []fyne.URI) {
|
||||
}
|
||||
|
||||
// EmitMsg Method to implement the screen interface
|
||||
func (p *NewScreen) EmitMsg(a string) {
|
||||
func (p *FyneScreen) EmitMsg(a string) {
|
||||
switch a {
|
||||
case "Playing":
|
||||
setPlayPauseView("Pause", p)
|
||||
@@ -225,7 +225,7 @@ func (p *NewScreen) EmitMsg(a string) {
|
||||
// Fini Method to implement the screen interface.
|
||||
// Will only be executed when we receive a callback message,
|
||||
// not when we explicitly click the Stop button.
|
||||
func (p *NewScreen) Fini() {
|
||||
func (p *FyneScreen) Fini() {
|
||||
gaplessOption := fyne.CurrentApp().Preferences().StringWithFallback("Gapless", "Disabled")
|
||||
|
||||
if p.NextMediaCheck.Checked && gaplessOption == "Disabled" {
|
||||
@@ -244,8 +244,7 @@ func (p *NewScreen) Fini() {
|
||||
}
|
||||
}
|
||||
|
||||
// InitFyneNewScreen .
|
||||
func InitFyneNewScreen(version string) *NewScreen {
|
||||
func InitFyneNewScreen(version string) *FyneScreen {
|
||||
go2tv := app.NewWithID("app.go2tv.go2tv")
|
||||
|
||||
switch go2tv.Preferences().String("Language") {
|
||||
@@ -268,7 +267,7 @@ func InitFyneNewScreen(version string) *NewScreen {
|
||||
ring: ring.New(1000),
|
||||
}
|
||||
|
||||
return &NewScreen{
|
||||
return &FyneScreen{
|
||||
Current: w,
|
||||
currentmfolder: currentDir,
|
||||
mediaFormats: []string{".mp4", ".avi", ".mkv", ".mpeg", ".mov", ".webm", ".m4v", ".mpv", ".dv", ".mp3", ".flac", ".wav", ".m4a", ".jpg", ".jpeg", ".png"},
|
||||
@@ -277,7 +276,7 @@ func InitFyneNewScreen(version string) *NewScreen {
|
||||
}
|
||||
}
|
||||
|
||||
func check(s *NewScreen, err error) {
|
||||
func check(s *FyneScreen, err error) {
|
||||
s.muError.Lock()
|
||||
defer s.muError.Unlock()
|
||||
|
||||
@@ -292,7 +291,7 @@ func check(s *NewScreen, err error) {
|
||||
}
|
||||
}
|
||||
|
||||
func getNextMedia(screen *NewScreen) (string, string) {
|
||||
func getNextMedia(screen *FyneScreen) (string, string) {
|
||||
filedir := filepath.Dir(screen.mediafile)
|
||||
filelist, err := os.ReadDir(filedir)
|
||||
check(screen, err)
|
||||
@@ -358,7 +357,7 @@ func getNextMedia(screen *NewScreen) (string, string) {
|
||||
return resName, resPath
|
||||
}
|
||||
|
||||
func autoSelectNextSubs(v string, screen *NewScreen) {
|
||||
func autoSelectNextSubs(v string, screen *FyneScreen) {
|
||||
name, path := getNextPossibleSubs(v)
|
||||
screen.SubsText.Text = name
|
||||
screen.subsfile = path
|
||||
@@ -379,7 +378,7 @@ func getNextPossibleSubs(v string) (string, string) {
|
||||
return name, path
|
||||
}
|
||||
|
||||
func setPlayPauseView(s string, screen *NewScreen) {
|
||||
func setPlayPauseView(s string, screen *FyneScreen) {
|
||||
if screen.cancelEnablePlay != nil {
|
||||
screen.cancelEnablePlay()
|
||||
}
|
||||
@@ -397,7 +396,7 @@ func setPlayPauseView(s string, screen *NewScreen) {
|
||||
}
|
||||
}
|
||||
|
||||
func setMuteUnmuteView(s string, screen *NewScreen) {
|
||||
func setMuteUnmuteView(s string, screen *FyneScreen) {
|
||||
switch s {
|
||||
case "Mute":
|
||||
screen.MuteUnmute.Icon = theme.VolumeUpIcon()
|
||||
@@ -411,14 +410,14 @@ func setMuteUnmuteView(s string, screen *NewScreen) {
|
||||
// updateScreenState updates the screen state based on
|
||||
// the emitted messages. The State variable is used across
|
||||
// the GUI interface to control certain flows.
|
||||
func (p *NewScreen) updateScreenState(a string) {
|
||||
func (p *FyneScreen) updateScreenState(a string) {
|
||||
p.mu.Lock()
|
||||
p.State = a
|
||||
p.mu.Unlock()
|
||||
}
|
||||
|
||||
// getScreenState returns the current screen state
|
||||
func (p *NewScreen) getScreenState() string {
|
||||
func (p *FyneScreen) getScreenState() string {
|
||||
p.mu.RLock()
|
||||
defer p.mu.RUnlock()
|
||||
return p.State
|
||||
|
@@ -28,7 +28,7 @@ import (
|
||||
|
||||
type tappedSlider struct {
|
||||
*widget.Slider
|
||||
screen *NewScreen
|
||||
screen *FyneScreen
|
||||
end string
|
||||
mu sync.Mutex
|
||||
}
|
||||
@@ -59,7 +59,7 @@ func newDeviceList(dd *[]devType) *deviceList {
|
||||
return list
|
||||
}
|
||||
|
||||
func newTappableSlider(s *NewScreen) *tappedSlider {
|
||||
func newTappableSlider(s *FyneScreen) *tappedSlider {
|
||||
slider := &tappedSlider{
|
||||
Slider: &widget.Slider{
|
||||
Max: 100,
|
||||
@@ -207,7 +207,7 @@ func (t *tappedSlider) Tapped(p *fyne.PointEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
func mainWindow(s *NewScreen) fyne.CanvasObject {
|
||||
func mainWindow(s *FyneScreen) fyne.CanvasObject {
|
||||
w := s.Current
|
||||
var data []devType
|
||||
list := newDeviceList(&data)
|
||||
@@ -561,7 +561,7 @@ func mainWindow(s *NewScreen) fyne.CanvasObject {
|
||||
return content
|
||||
}
|
||||
|
||||
func refreshDevList(s *NewScreen, data *[]devType) {
|
||||
func refreshDevList(s *FyneScreen, data *[]devType) {
|
||||
refreshDevices := time.NewTicker(5 * time.Second)
|
||||
|
||||
_, err := getDevices(2)
|
||||
@@ -625,7 +625,7 @@ func refreshDevList(s *NewScreen, data *[]devType) {
|
||||
}
|
||||
}
|
||||
|
||||
func checkMutefunc(s *NewScreen) {
|
||||
func checkMutefunc(s *FyneScreen) {
|
||||
checkMute := time.NewTicker(2 * time.Second)
|
||||
|
||||
var checkMuteCounter int
|
||||
@@ -662,7 +662,7 @@ func checkMutefunc(s *NewScreen) {
|
||||
}
|
||||
}
|
||||
|
||||
func sliderUpdate(s *NewScreen) {
|
||||
func sliderUpdate(s *FyneScreen) {
|
||||
t := time.NewTicker(time.Second)
|
||||
for range t.C {
|
||||
if s.sliderActive {
|
||||
|
9
internal/gui/newGUI.go
Normal file
9
internal/gui/newGUI.go
Normal file
@@ -0,0 +1,9 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package gui
|
||||
|
||||
// NewFyneScreen .
|
||||
func NewFyneScreen(version string) *FyneScreen {
|
||||
return InitFyneNewScreen(version)
|
||||
}
|
23
internal/gui/newGUI_windows.go
Normal file
23
internal/gui/newGUI_windows.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package gui
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// NewFyneScreen .
|
||||
func NewFyneScreen(version string) *FyneScreen {
|
||||
hideConsole()
|
||||
return InitFyneNewScreen(version)
|
||||
}
|
||||
|
||||
func hideConsole() {
|
||||
kernel32 := windows.NewLazySystemDLL("kernel32.dll")
|
||||
getConsoleWindow := kernel32.NewProc("GetConsoleWindow")
|
||||
showWindow := windows.NewLazySystemDLL("user32.dll").NewProc("ShowWindow")
|
||||
|
||||
hwnd, _, _ := getConsoleWindow.Call()
|
||||
if hwnd != 0 {
|
||||
const SW_HIDE = 0
|
||||
showWindow.Call(hwnd, SW_HIDE)
|
||||
}
|
||||
}
|
@@ -16,7 +16,7 @@ import (
|
||||
"fyne.io/fyne/v2/widget"
|
||||
)
|
||||
|
||||
func settingsWindow(s *NewScreen) fyne.CanvasObject {
|
||||
func settingsWindow(s *FyneScreen) fyne.CanvasObject {
|
||||
w := s.Current
|
||||
|
||||
themeText := widget.NewLabel(lang.L("Theme"))
|
||||
@@ -147,7 +147,7 @@ func settingsWindow(s *NewScreen) fyne.CanvasObject {
|
||||
return container.New(layout.NewFormLayout(), themeText, dropdownTheme, languageText, dropdownLanguage, gaplessText, gaplessdropdown, ffmpegText, ffmpegTextEntry, debugText, debugExport)
|
||||
}
|
||||
|
||||
func saveDebugLogs(f fyne.URIWriteCloser, s *NewScreen) {
|
||||
func saveDebugLogs(f fyne.URIWriteCloser, s *FyneScreen) {
|
||||
w := s.Current
|
||||
defer f.Close()
|
||||
|
||||
@@ -176,7 +176,7 @@ func parseTheme(t string) {
|
||||
}()
|
||||
}
|
||||
|
||||
func parseLanguage(s *NewScreen) func(string) {
|
||||
func parseLanguage(s *FyneScreen) func(string) {
|
||||
w := s.Current
|
||||
return func(t string) {
|
||||
if t != fyne.CurrentApp().Preferences().StringWithFallback("Language", "System Default") {
|
||||
|
55
soapcalls/utils/ffprobe_test.go
Normal file
55
soapcalls/utils/ffprobe_test.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TestFormatDuration - test formatDuration
|
||||
func TestFormatDuration(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input time.Duration
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "Zero duration",
|
||||
input: 0,
|
||||
expected: "00:00:00.000",
|
||||
},
|
||||
{
|
||||
name: "Milliseconds only",
|
||||
input: 123 * time.Millisecond,
|
||||
expected: "00:00:00.123",
|
||||
},
|
||||
{
|
||||
name: "Seconds and milliseconds",
|
||||
input: 12*time.Second + 345*time.Millisecond,
|
||||
expected: "00:00:12.345",
|
||||
},
|
||||
{
|
||||
name: "Minutes, seconds, and milliseconds",
|
||||
input: 5*time.Minute + 23*time.Second + 789*time.Millisecond,
|
||||
expected: "00:05:23.789",
|
||||
},
|
||||
{
|
||||
name: "Hours, minutes, seconds, and milliseconds",
|
||||
input: 2*time.Hour + 15*time.Minute + 9*time.Second + 56*time.Millisecond,
|
||||
expected: "02:15:09.056",
|
||||
},
|
||||
{
|
||||
name: "More than a day",
|
||||
input: 26*time.Hour + 45*time.Minute + 33*time.Second + 1*time.Millisecond,
|
||||
expected: "26:45:33.001",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
result := formatDuration(test.input)
|
||||
if result != test.expected {
|
||||
t.Fatalf("for input %v, expected %q but got %q", test.input, test.expected, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@@ -29,8 +29,10 @@ type tags struct {
|
||||
Language string `mapstructure:"language"`
|
||||
}
|
||||
|
||||
// ErrNoSubs - No subs detected
|
||||
var ErrNoSubs = errors.New("no subs")
|
||||
|
||||
// GetSubs - List all subs in our video file.
|
||||
func GetSubs(ffmpeg string, f string) ([]string, error) {
|
||||
_, err := os.Stat(f)
|
||||
if err != nil {
|
||||
@@ -93,6 +95,8 @@ func GetSubs(ffmpeg string, f string) ([]string, error) {
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ExtractSub - Save the extracted sub into a temp file.
|
||||
// Return the path of that file.
|
||||
func ExtractSub(ffmpeg string, n int, f string) (string, error) {
|
||||
_, err := os.Stat(f)
|
||||
if err != nil {
|
||||
|
@@ -27,8 +27,10 @@ type tags struct {
|
||||
Language string `mapstructure:"language"`
|
||||
}
|
||||
|
||||
// ErrNoSubs - No subs detected
|
||||
var ErrNoSubs = errors.New("no subs")
|
||||
|
||||
// GetSubs - List all subs in our video file.
|
||||
func GetSubs(ffmpeg string, f string) ([]string, error) {
|
||||
_, err := os.Stat(f)
|
||||
if err != nil {
|
||||
@@ -90,6 +92,8 @@ func GetSubs(ffmpeg string, f string) ([]string, error) {
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ExtractSub - Save the extracted sub into a temp file.
|
||||
// Return the path of that file.
|
||||
func ExtractSub(ffmpeg string, n int, f string) (string, error) {
|
||||
_, err := os.Stat(f)
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user