feat(module): arcast integration
Some checks are pending
arcad/edge/pipeline/head Build started...
arcad/edge/pipeline/pr-master Build started...

This commit is contained in:
2024-01-12 14:02:53 +01:00
parent 335b34625b
commit 7633ae0419
13 changed files with 283 additions and 37 deletions

View File

@ -0,0 +1,49 @@
package arcast
import (
"context"
"forge.cadoles.com/arcad/arcast/pkg/client"
"forge.cadoles.com/arcad/edge/pkg/module/cast"
"github.com/pkg/errors"
)
type Client struct {
client *client.Client
addr string
}
// Close implements cast.Client.
func (c *Client) Close() error {
return nil
}
// Load implements cast.Client.
func (c *Client) Load(ctx context.Context, url string) error {
if _, err := c.client.Cast(ctx, c.addr, url); err != nil {
return errors.WithStack(err)
}
return nil
}
// Status implements cast.Client.
func (c *Client) Status(ctx context.Context) (cast.DeviceStatus, error) {
status, err := c.client.Status(ctx, c.addr)
if err != nil {
return nil, errors.WithStack(err)
}
return &DeviceStatus{status}, nil
}
// Unload implements cast.Client.
func (c *Client) Unload(ctx context.Context) error {
if _, err := c.client.Reset(ctx, c.addr); err != nil {
return errors.WithStack(err)
}
return nil
}
var _ cast.Client = &Client{}

View File

@ -0,0 +1,57 @@
package arcast
import (
"context"
"net"
"forge.cadoles.com/arcad/arcast/pkg/client"
"forge.cadoles.com/arcad/arcast/pkg/server"
"forge.cadoles.com/arcad/edge/pkg/module/cast"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
)
const DeviceTypeArcast cast.DeviceType = "arcast"
type Device struct {
player *client.Player
}
// DeviceHost implements cast.Device.
func (d *Device) DeviceHost() net.IP {
rawPreferredIP, err := server.FindPreferredLocalAddress(d.player.IPs...)
if err != nil {
logger.Error(context.Background(), "could not find preferred local address", logger.CapturedE(errors.WithStack(err)))
return d.player.IPs[0]
}
preferredIP := net.ParseIP(rawPreferredIP)
if preferredIP == nil {
logger.Error(context.Background(), "could not parse device preferred ip", logger.F("rawPreferredIP", rawPreferredIP))
return d.player.IPs[0]
}
return preferredIP
}
// DeviceID implements cast.Device.
func (d *Device) DeviceID() string {
return d.player.ID
}
// DeviceName implements cast.Device.
func (d *Device) DeviceName() string {
return d.player.ID
}
// DevicePort implements cast.Device.
func (d *Device) DevicePort() int {
return d.player.Port
}
// DeviceType implements cast.Device.
func (d *Device) DeviceType() cast.DeviceType {
return DeviceTypeArcast
}
var _ cast.Device = &Device{}

View File

@ -0,0 +1,60 @@
package arcast
import (
"context"
"fmt"
"forge.cadoles.com/arcad/arcast/pkg/client"
"forge.cadoles.com/arcad/edge/pkg/module/cast"
"github.com/pkg/errors"
)
func init() {
cast.Register(DeviceTypeArcast, &Service{
client: client.New(),
})
}
type Service struct {
client *client.Client
}
// Find implements cast.Service.
func (s *Service) Find(ctx context.Context, deviceID string) (cast.Device, error) {
players, err := s.client.Scan(ctx, client.WithPlayerIDs(deviceID))
if err != nil && !errors.Is(err, context.DeadlineExceeded) {
return nil, errors.WithStack(err)
}
if len(players) == 0 {
return nil, errors.WithStack(cast.ErrDeviceNotFound)
}
return &Device{players[0]}, nil
}
// NewClient implements cast.Service.
func (s *Service) NewClient(ctx context.Context, device cast.Device) (cast.Client, error) {
return &Client{
client: s.client,
addr: fmt.Sprintf("%s:%d", device.DeviceHost(), device.DevicePort()),
}, nil
}
// Scan implements cast.Service.
func (s *Service) Scan(ctx context.Context) ([]cast.Device, error) {
players, err := s.client.Scan(ctx)
if err != nil && !errors.Is(err, context.DeadlineExceeded) {
return nil, errors.WithStack(err)
}
devices := make([]cast.Device, len(players))
for i, p := range players {
devices[i] = &Device{p}
}
return devices, nil
}
var _ cast.Service = &Service{}

View File

@ -0,0 +1,22 @@
package arcast
import (
"forge.cadoles.com/arcad/arcast/pkg/server"
"forge.cadoles.com/arcad/edge/pkg/module/cast"
)
type DeviceStatus struct {
status *server.StatusResponse
}
// State implements cast.DeviceStatus.
func (s *DeviceStatus) State() string {
return s.status.Status
}
// Title implements cast.DeviceStatus.
func (s *DeviceStatus) Title() string {
return s.status.Title
}
var _ cast.DeviceStatus = &DeviceStatus{}