mirror of
https://github.com/xaionaro-go/streamctl.git
synced 2025-10-26 09:00:29 +08:00
Initial commit, pt. 59
This commit is contained in:
@@ -30,7 +30,7 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
if flags.SplitProcess {
|
||||
if flags.SplitProcess && flags.RemoteAddr == "" {
|
||||
runSplitProcesses(ctx, flags)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -37,7 +37,14 @@ type MPV struct {
|
||||
|
||||
var _ Player = (*MPV)(nil)
|
||||
|
||||
func NewMPV(title string, pathToMPV string) (*MPV, error) {
|
||||
func NewMPV(title string, pathToMPV string) (_ret *MPV, _err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
_err = fmt.Errorf("got panic: %v", r)
|
||||
_ret = nil
|
||||
return
|
||||
}
|
||||
}()
|
||||
if pathToMPV == "" {
|
||||
pathToMPV = "mpv"
|
||||
switch runtime.GOOS {
|
||||
|
||||
@@ -121,7 +121,7 @@ func (p *Panel) getImage(
|
||||
}
|
||||
|
||||
func imgFitTo(src image.Image, size image.Point) image.Image {
|
||||
sizeCur := src.Bounds().Max
|
||||
sizeCur := src.Bounds().Size()
|
||||
factor := math.MaxFloat64
|
||||
factor = math.Min(factor, float64(size.X)/float64(sizeCur.X))
|
||||
factor = math.Min(factor, float64(size.Y)/float64(sizeCur.Y))
|
||||
@@ -130,6 +130,85 @@ func imgFitTo(src image.Image, size image.Point) image.Image {
|
||||
return resize.Resize(newWidth, newHeight, src, resize.Lanczos3)
|
||||
}
|
||||
|
||||
type align int
|
||||
|
||||
const (
|
||||
alignCenter = align(iota)
|
||||
alignStart
|
||||
alignEnd
|
||||
)
|
||||
|
||||
func imgFillTo(
|
||||
ctx context.Context,
|
||||
src image.Image,
|
||||
size image.Point,
|
||||
alignX align,
|
||||
alignY align,
|
||||
) image.Image {
|
||||
sizeCur := src.Bounds().Size()
|
||||
ratioCur := float64(sizeCur.X) / float64(sizeCur.Y)
|
||||
ratioNew := float64(size.X) / float64(size.Y)
|
||||
|
||||
if ratioCur == ratioNew {
|
||||
return src
|
||||
}
|
||||
if math.IsNaN(ratioNew) {
|
||||
return src
|
||||
}
|
||||
|
||||
var sizeNew image.Point
|
||||
if ratioCur < ratioNew {
|
||||
sizeNew = image.Point{
|
||||
X: int(float64(sizeCur.Y) * ratioNew),
|
||||
Y: sizeCur.Y,
|
||||
}
|
||||
} else {
|
||||
sizeNew = image.Point{
|
||||
X: sizeCur.X,
|
||||
Y: int(float64(sizeCur.X) / ratioNew),
|
||||
}
|
||||
}
|
||||
|
||||
logger.Tracef(ctx, "ratio: %v -> %v; size: %#+v -> %#+v", ratioCur, ratioNew, sizeCur, sizeNew)
|
||||
img := image.NewRGBA(image.Rectangle{
|
||||
Max: sizeNew,
|
||||
})
|
||||
|
||||
var offsetX, offsetY int
|
||||
if ratioCur < ratioNew {
|
||||
offsetX = sizeNew.X - sizeCur.X
|
||||
switch alignX {
|
||||
case alignStart:
|
||||
offsetX *= 0
|
||||
case alignCenter:
|
||||
offsetX /= 2
|
||||
case alignEnd:
|
||||
offsetX /= 1
|
||||
}
|
||||
} else {
|
||||
offsetY = sizeNew.Y - sizeCur.Y
|
||||
switch alignY {
|
||||
case alignStart:
|
||||
offsetY *= 0
|
||||
case alignCenter:
|
||||
offsetY /= 2
|
||||
case alignEnd:
|
||||
offsetY /= 1
|
||||
}
|
||||
}
|
||||
|
||||
for x := 0; x < sizeCur.X; x++ {
|
||||
for y := 0; y < sizeCur.Y; y++ {
|
||||
xNew := x + offsetX
|
||||
yNew := y + offsetY
|
||||
|
||||
img.Set(xNew, yNew, src.At(x, y))
|
||||
}
|
||||
}
|
||||
|
||||
return img
|
||||
}
|
||||
|
||||
const (
|
||||
ScreenshotMaxWidth = 384
|
||||
ScreenshotMaxHeight = 216
|
||||
|
||||
@@ -2,14 +2,14 @@ package streampanel
|
||||
|
||||
import (
|
||||
"context"
|
||||
"runtime"
|
||||
"sync"
|
||||
|
||||
"image"
|
||||
"time"
|
||||
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/canvas"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/layout"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
"github.com/anthonynsimon/bild/adjust"
|
||||
"github.com/facebookincubator/go-belt/tool/logger"
|
||||
@@ -85,6 +85,18 @@ func (p *Panel) updateMonitorPageImages(
|
||||
logger.Tracef(ctx, "updateMonitorPageImages")
|
||||
defer logger.Tracef(ctx, "/updateMonitorPageImages")
|
||||
|
||||
var winSize fyne.Size
|
||||
switch runtime.GOOS {
|
||||
default:
|
||||
winSize = p.monitorPage.Size()
|
||||
}
|
||||
lastWinSize := p.monitorLastWinSize
|
||||
p.monitorLastWinSize = winSize
|
||||
|
||||
if lastWinSize != winSize {
|
||||
logger.Debugf(ctx, "window size changed %#+v -> %#+v", lastWinSize, winSize)
|
||||
}
|
||||
|
||||
p.monitorPageUpdaterLocker.Lock()
|
||||
defer p.monitorPageUpdaterLocker.Unlock()
|
||||
|
||||
@@ -98,16 +110,17 @@ func (p *Panel) updateMonitorPageImages(
|
||||
if err != nil {
|
||||
logger.Error(ctx, err)
|
||||
} else {
|
||||
if !changed {
|
||||
if !changed && lastWinSize == winSize {
|
||||
return
|
||||
}
|
||||
//s := p.mainWindow.Canvas().Size()
|
||||
//img = imgFitTo(img, image.Point{X: 1450, Y: 1450})
|
||||
logger.Tracef(ctx, "updating the screenshot image: %v %#+v %#+v", changed, lastWinSize, winSize)
|
||||
//img = imgFitTo(img, image.Point{X: int(winSize.Width), Y: int(winSize.Height)})
|
||||
img = imgFillTo(ctx, img, image.Point{X: int(winSize.Width), Y: int(winSize.Height)}, alignStart, alignStart)
|
||||
img = adjust.Brightness(img, -0.5)
|
||||
imgFyne := canvas.NewImageFromImage(img)
|
||||
imgFyne.FillMode = canvas.ImageFillOriginal
|
||||
imgFyne.FillMode = canvas.ImageFillContain
|
||||
logger.Tracef(ctx, "screenshot image size: %#+v", img.Bounds().Size())
|
||||
|
||||
p.screenshotContainer.Layout = layout.NewBorderLayout(imgFyne, nil, nil, nil)
|
||||
p.screenshotContainer.Objects = p.screenshotContainer.Objects[:0]
|
||||
p.screenshotContainer.Objects = append(p.screenshotContainer.Objects, imgFyne)
|
||||
p.screenshotContainer.Refresh()
|
||||
@@ -121,18 +134,18 @@ func (p *Panel) updateMonitorPageImages(
|
||||
if err != nil {
|
||||
logger.Error(ctx, err)
|
||||
} else {
|
||||
if !changed {
|
||||
if !changed && lastWinSize == winSize {
|
||||
return
|
||||
}
|
||||
//s := p.mainWindow.Canvas().Size()
|
||||
//img = imgFitTo(img, image.Point{X: int(s.Width), Y: int(s.Height)})
|
||||
img = imgFitTo(img, image.Point{X: 1450, Y: 1450})
|
||||
logger.Tracef(ctx, "updating the chat image: %v %#+v %#+v", changed, lastWinSize, winSize)
|
||||
//img = imgFitTo(img, image.Point{X: int(winSize.Width), Y: int(winSize.Height)})
|
||||
img = imgFillTo(ctx, img, image.Point{X: int(winSize.Width), Y: int(winSize.Height)}, alignStart, alignEnd)
|
||||
imgFyne := canvas.NewImageFromImage(img)
|
||||
imgFyne.FillMode = canvas.ImageFillOriginal
|
||||
imgFyne.FillMode = canvas.ImageFillContain
|
||||
logger.Tracef(ctx, "chat image size: %#+v", img.Bounds().Size())
|
||||
|
||||
p.chatContainer.Layout = layout.NewVBoxLayout()
|
||||
p.chatContainer.Objects = p.chatContainer.Objects[:0]
|
||||
p.chatContainer.Objects = append(p.chatContainer.Objects, layout.NewSpacer(), container.NewHBox(imgFyne, layout.NewSpacer()))
|
||||
p.chatContainer.Objects = append(p.chatContainer.Objects, imgFyne)
|
||||
p.chatContainer.Refresh()
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -88,8 +88,10 @@ type Panel struct {
|
||||
streamTitleField *widget.Entry
|
||||
streamDescriptionField *widget.Entry
|
||||
|
||||
monitorPage *fyne.Container
|
||||
monitorPageUpdaterLocker sync.Mutex
|
||||
monitorPageUpdaterCancel context.CancelFunc
|
||||
monitorLastWinSize fyne.Size
|
||||
screenshotContainer *fyne.Container
|
||||
chatContainer *fyne.Container
|
||||
|
||||
@@ -1394,6 +1396,7 @@ func (p *Panel) initMainWindow(
|
||||
startingPage consts.Page,
|
||||
) {
|
||||
w := p.app.NewWindow(appName)
|
||||
p.mainWindow = w
|
||||
w.SetMaster()
|
||||
resizeWindow(w, fyne.NewSize(400, 600))
|
||||
|
||||
@@ -1538,28 +1541,28 @@ func (p *Panel) initMainWindow(
|
||||
monitorBackgroundFyne := canvas.NewImageFromImage(monitorBackground)
|
||||
monitorBackgroundFyne.FillMode = canvas.ImageFillStretch
|
||||
|
||||
p.screenshotContainer = container.NewBorder(nil, nil, nil, nil)
|
||||
p.screenshotContainer = container.NewStack()
|
||||
obsLabel := widget.NewLabel("OBS:")
|
||||
obsLabel.Importance = widget.LowImportance
|
||||
obsLabel.Importance = widget.HighImportance
|
||||
p.streamStatus[obs.ID] = widget.NewLabel("")
|
||||
twLabel := widget.NewLabel("TW:")
|
||||
twLabel.Importance = widget.LowImportance
|
||||
twLabel.Importance = widget.HighImportance
|
||||
p.streamStatus[twitch.ID] = widget.NewLabel("")
|
||||
ytLabel := widget.NewLabel("YT:")
|
||||
ytLabel.Importance = widget.LowImportance
|
||||
ytLabel.Importance = widget.HighImportance
|
||||
p.streamStatus[youtube.ID] = widget.NewLabel("")
|
||||
streamInfoContainer := container.NewBorder(
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
container.NewVBox(
|
||||
container.NewHBox(obsLabel, p.streamStatus[obs.ID]),
|
||||
container.NewHBox(twLabel, p.streamStatus[twitch.ID]),
|
||||
container.NewHBox(ytLabel, p.streamStatus[youtube.ID]),
|
||||
container.NewHBox(layout.NewSpacer(), obsLabel, p.streamStatus[obs.ID]),
|
||||
container.NewHBox(layout.NewSpacer(), twLabel, p.streamStatus[twitch.ID]),
|
||||
container.NewHBox(layout.NewSpacer(), ytLabel, p.streamStatus[youtube.ID]),
|
||||
),
|
||||
)
|
||||
p.chatContainer = container.NewBorder(nil, nil, nil, nil)
|
||||
monitorPage := container.NewStack(
|
||||
p.chatContainer = container.NewStack()
|
||||
p.monitorPage = container.NewStack(
|
||||
monitorBackgroundFyne,
|
||||
p.screenshotContainer,
|
||||
streamInfoContainer,
|
||||
@@ -1660,7 +1663,7 @@ func (p *Panel) initMainWindow(
|
||||
|
||||
switch page {
|
||||
case consts.PageControl:
|
||||
monitorPage.Hide()
|
||||
p.monitorPage.Hide()
|
||||
obsPage.Hide()
|
||||
restreamPage.Hide()
|
||||
profileControl.Show()
|
||||
@@ -1670,18 +1673,18 @@ func (p *Panel) initMainWindow(
|
||||
profileControl.Hide()
|
||||
restreamPage.Hide()
|
||||
obsPage.Hide()
|
||||
monitorPage.Show()
|
||||
p.monitorPage.Show()
|
||||
p.startMonitorPage(ctx)
|
||||
case consts.PageOBS:
|
||||
controlPage.Hide()
|
||||
profileControl.Hide()
|
||||
monitorPage.Hide()
|
||||
p.monitorPage.Hide()
|
||||
restreamPage.Hide()
|
||||
obsPage.Show()
|
||||
case consts.PageRestream:
|
||||
controlPage.Hide()
|
||||
profileControl.Hide()
|
||||
monitorPage.Hide()
|
||||
p.monitorPage.Hide()
|
||||
obsPage.Hide()
|
||||
restreamPage.Show()
|
||||
p.startRestreamPage(ctx)
|
||||
@@ -1708,11 +1711,10 @@ func (p *Panel) initMainWindow(
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
container.NewStack(controlPage, monitorPage, obsPage, restreamPage),
|
||||
container.NewStack(controlPage, p.monitorPage, obsPage, restreamPage),
|
||||
))
|
||||
|
||||
w.Show()
|
||||
p.mainWindow = w
|
||||
p.profilesListWidget = profilesList
|
||||
|
||||
if _, ok := p.StreamD.(*client.Client); ok {
|
||||
|
||||
Reference in New Issue
Block a user