Compare commits

...

1 commit
1 ... master

Author SHA1 Message Date
6745dba616 feature: prefs, search, LF-ification 2025-12-13 00:58:52 -08:00

View file

@ -1,123 +1,145 @@
package threenis
import (
"log"
"os/exec"
"strings"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/widget"
"layeh.com/gumble/gumble"
"layeh.com/gumble/gumbleffmpeg"
"layeh.com/gumble/gumbleutil"
_ "layeh.com/gumble/opus"
)
type Threenis struct {
stream *gumbleffmpeg.Stream
process *exec.Cmd
}
type SourceStream string
func ThreenisSource(filename string) gumbleffmpeg.Source {
return SourceStream(filename)
}
func (s SourceStream) Arguments() []string {
return []string{"-fflags", "nobuffer", "-flags", "low_delay", "-f", "s16le", "-ac", "2", "-i", "udp://127.0.0.1:2888"}
}
func (SourceStream) Start(*exec.Cmd) error {
return nil
}
func (SourceStream) Done() {
}
func (t *Threenis) Mumble(server string, username string, password string, channel string) {
MumbleClient(server, username, password, gumbleutil.AutoBitrate, gumbleutil.Listener{
Connect: func(e *gumble.ConnectEvent) {
c := e.Client.Channels.Find(channel)
if c != nil {
e.Client.Self.Move(c)
}
t.stream = gumbleffmpeg.New(e.Client, ThreenisSource(""))
if err := t.stream.Play(); err != nil {
log.Println(err)
}
},
})
}
func Ui() {
myApp := app.New()
myWindow := myApp.NewWindow("Threenis")
myWindow.Resize(fyne.NewSize(800, 400))
myWindow.SetFixedSize(true)
processes := GetProcessStrings()
threenis := Threenis{}
defer func() {
threenis.stream.Stop()
if threenis.process != nil && threenis.process.Process != nil {
threenis.process.Process.Kill()
}
}()
list := widget.NewList(
func() int {
return len(processes)
},
func() fyne.CanvasObject {
return widget.NewLabel("template")
},
func(i widget.ListItemID, o fyne.CanvasObject) {
o.(*widget.Label).SetText(processes[i])
})
list.OnSelected = func(id widget.ListItemID) {
if threenis.process != nil && threenis.process.Process != nil {
threenis.process.Process.Kill()
}
threenis.process = exec.Command("./ApplicationLoopback.exe", strings.Split(processes[id], " - ")[0], "includetree")
log.Println(strings.Split(processes[id], " - ")[0])
err := threenis.process.Start()
if err != nil {
log.Println(err)
}
}
serverLabel := widget.NewLabel("Server")
server := widget.NewEntry()
usernameLabel := widget.NewLabel("Username")
username := widget.NewEntry()
passwordLabel := widget.NewLabel("Password")
password := widget.NewEntry()
channelLabel := widget.NewLabel("Channel")
channel := widget.NewEntry()
refresh := widget.NewButton("Refresh", func() {
processes = GetProcessStrings()
list.Refresh()
})
connect := widget.NewButton("Connect", func() {
go threenis.Mumble(server.Text, username.Text, password.Text, channel.Text)
})
form := container.New(layout.NewFormLayout(), serverLabel, server, usernameLabel, username, passwordLabel, password, channelLabel, channel, refresh, connect)
grid := container.New(layout.NewGridLayout(2), list, form)
myWindow.SetContent(grid)
myWindow.ShowAndRun()
}
package threenis
import (
"log"
"os/exec"
"strings"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/widget"
"layeh.com/gumble/gumble"
"layeh.com/gumble/gumbleffmpeg"
"layeh.com/gumble/gumbleutil"
_ "layeh.com/gumble/opus"
)
type Threenis struct {
stream *gumbleffmpeg.Stream
process *exec.Cmd
}
type SourceStream string
func ThreenisSource(filename string) gumbleffmpeg.Source {
return SourceStream(filename)
}
func (s SourceStream) Arguments() []string {
return []string{"-fflags", "nobuffer", "-flags", "low_delay", "-f", "s16le", "-ac", "2", "-i", "udp://127.0.0.1:2888"}
}
func (SourceStream) Start(*exec.Cmd) error {
return nil
}
func (SourceStream) Done() {
}
func (t *Threenis) Mumble(server string, username string, password string, channel string) {
MumbleClient(server, username, password, gumbleutil.AutoBitrate, gumbleutil.Listener{
Connect: func(e *gumble.ConnectEvent) {
c := e.Client.Channels.Find(channel)
if c != nil {
e.Client.Self.Move(c)
}
t.stream = gumbleffmpeg.New(e.Client, ThreenisSource(""))
if err := t.stream.Play(); err != nil {
log.Println(err)
}
},
})
}
func Ui() {
threenisApp := app.NewWithID("threenis")
window := threenisApp.NewWindow("Threenis")
window.Resize(fyne.NewSize(800, 400))
processes := GetProcessStrings()
threenis := Threenis{}
defer func() {
threenis.stream.Stop()
if threenis.process != nil && threenis.process.Process != nil {
threenis.process.Process.Kill()
}
}()
list := widget.NewList(
func() int {
return len(processes)
},
func() fyne.CanvasObject {
return widget.NewLabel("template")
},
func(i widget.ListItemID, o fyne.CanvasObject) {
o.(*widget.Label).SetText(processes[i])
})
list.OnSelected = func(id widget.ListItemID) {
if threenis.process != nil && threenis.process.Process != nil {
threenis.process.Process.Kill()
}
threenis.process = exec.Command("./ApplicationLoopback.exe", strings.Split(processes[id], " - ")[0], "includetree")
log.Println(strings.Split(processes[id], " - ")[0])
err := threenis.process.Start()
if err != nil {
log.Println(err)
}
}
serverLabel := widget.NewLabel("Server")
server := widget.NewEntry()
server.SetText(threenisApp.Preferences().StringWithFallback("server", ""))
usernameLabel := widget.NewLabel("Username")
username := widget.NewEntry()
username.SetText(threenisApp.Preferences().StringWithFallback("username", ""))
passwordLabel := widget.NewLabel("Password")
password := widget.NewEntry()
password.SetText(threenisApp.Preferences().StringWithFallback("password", ""))
channelLabel := widget.NewLabel("Channel")
channel := widget.NewEntry()
channel.SetText(threenisApp.Preferences().StringWithFallback("channel", ""))
refresh := widget.NewButton("Refresh", func() {
processes = GetProcessStrings()
list.Refresh()
})
connect := widget.NewButton("Connect", func() {
threenisApp.Preferences().SetString("server", server.Text)
threenisApp.Preferences().SetString("username", username.Text)
threenisApp.Preferences().SetString("password", password.Text)
threenisApp.Preferences().SetString("channel", channel.Text)
go threenis.Mumble(server.Text, username.Text, password.Text, channel.Text)
})
search := widget.NewEntry()
search.OnChanged = func(s string) {
procs := GetProcessStrings()
processes = make([]string, 0)
for _, proc := range procs {
if strings.Contains(strings.ToLower(proc), strings.ToLower(s)) {
processes = append(processes, proc)
}
}
list.Refresh()
}
content := container.NewBorder(nil, search, nil, nil, list)
form := container.New(layout.NewFormLayout(), serverLabel, server, usernameLabel, username, passwordLabel, password, channelLabel, channel, refresh, connect)
grid := container.New(layout.NewGridLayout(2), content, form)
window.SetContent(grid)
window.ShowAndRun()
}