Skip to content

Commit

Permalink
Added googlecast service
Browse files Browse the repository at this point in the history
  • Loading branch information
djthorpe committed Dec 31, 2020
1 parent 05fb696 commit 742e8da
Show file tree
Hide file tree
Showing 31 changed files with 1,193 additions and 104 deletions.
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ GOFLAGS = -ldflags "-s -w $(GOLDFLAGS)"
BUILDDIR = build
PACKAGECLOUD_REPO = djthorpe/gopi/raspbian/buster

all: hw httpserver helloworld argonone douglas dnsregister rpcping mediakit
all: hw httpserver helloworld argonone douglas dnsregister rpcping googlecast mediakit
@echo Use "make debian" to release to packaging
@echo Use "make clean" to clear build cache
@echo Use "make test" to run tests
Expand Down Expand Up @@ -177,6 +177,9 @@ dnsregister: builddir
rpcping: builddir protogen
PKG_CONFIG_PATH="$(PKG_CONFIG_PATH)" $(GO) build -o ${BUILDDIR}/rpcping -tags "$(TAGS)" ${GOFLAGS} ./cmd/rpcping

googlecast: builddir protogen
PKG_CONFIG_PATH="$(PKG_CONFIG_PATH)" $(GO) build -o ${BUILDDIR}/googlecast -tags "$(TAGS)" ${GOFLAGS} ./cmd/googlecast

mediakit: builddir ffmpeg chromaprint
PKG_CONFIG_PATH="$(PKG_CONFIG_PATH)" $(GO) build -o ${BUILDDIR}/mediakit -tags "$(TAGS)" ${GOFLAGS} ./cmd/mediakit

Expand Down
30 changes: 30 additions & 0 deletions cmd/googlecast/app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package main

import (
"context"
"fmt"

"github.com/djthorpe/gopi/v3"
)

////////////////////////////////////////////////////////////////////////////////
// TYPES

type app struct {
gopi.Unit
gopi.Logger
gopi.CastService
gopi.PingService
}

////////////////////////////////////////////////////////////////////////////////
// LIFECYCLE

func (this *app) Run(ctx context.Context) error {

// Wait for interrupt
fmt.Println("Press CTRL+C to end")
<-ctx.Done()

return ctx.Err()
}
11 changes: 11 additions & 0 deletions cmd/googlecast/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package main

import (
"os"

tool "github.com/djthorpe/gopi/v3/pkg/tool"
)

func main() {
os.Exit(tool.Server("googlecast", os.Args[1:], new(app)))
}
10 changes: 10 additions & 0 deletions cmd/googlecast/units.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package main

import (
_ "github.com/djthorpe/gopi/v3/pkg/dev/googlecast"
_ "github.com/djthorpe/gopi/v3/pkg/event"
_ "github.com/djthorpe/gopi/v3/pkg/mdns"
_ "github.com/djthorpe/gopi/v3/pkg/rpc/googlecast"
_ "github.com/djthorpe/gopi/v3/pkg/rpc/ping"
_ "github.com/djthorpe/gopi/v3/pkg/rpc/server"
)
7 changes: 4 additions & 3 deletions cmd/hw/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ func (h header) Format() (string, table.Alignment, table.Color) {
func (this *app) Define(cfg gopi.Config) error {
// Define flags
this.i2cbus = cfg.FlagUint("bus", 0, "I2C Bus", "i2c")
this.timeout = cfg.FlagDuration("timeout", time.Second, "Discovery timeout", "mdns", "cast", "cast app", "cast vol", "cast mute", "cast unmute", "cast load", "cast play", "cast pause", "cast stop")
this.watch = cfg.FlagBool("watch", false, "Watch for events", "cast app", "cast vol", "cast mute", "cast unmute", "cast load", "cast play", "cast pause", "cast stop")
this.name = cfg.FlagString("name", "", "Service or Chromecast Name", "mdns serve", "cast app", "cast vol", "cast mute", "cast unmute", "cast load", "cast play", "cast pause", "cast stop")
this.timeout = cfg.FlagDuration("timeout", time.Second, "Discovery timeout", "mdns", "cast", "cast app", "cast vol", "cast mute", "cast unmute", "cast load", "cast play", "cast pause", "cast stop", "cast seek")
this.watch = cfg.FlagBool("watch", false, "Watch for events", "cast app", "cast vol", "cast mute", "cast unmute", "cast load", "cast play", "cast pause", "cast stop", "cast seek")
this.name = cfg.FlagString("name", "", "Service or Chromecast Name", "mdns serve", "cast app", "cast vol", "cast mute", "cast unmute", "cast load", "cast play", "cast pause", "cast stop", "cast seek")
this.port = cfg.FlagUint("port", 0, "Service Port", "mdns serve")

// Define commands
Expand All @@ -70,6 +70,7 @@ func (this *app) Define(cfg gopi.Config) error {
cfg.Command("cast play", "Set play state on Chromecast", this.RunCastPlay)
cfg.Command("cast pause", "Set pause state on Chromecast", this.RunCastPause)
cfg.Command("cast stop", "Set stop state on Chromecast", this.RunCastStop)
cfg.Command("cast seek", "Seek media to position", this.RunCastSeek)

// Return success
return nil
Expand Down
69 changes: 44 additions & 25 deletions cmd/hw/cast.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,16 @@ func (this *app) RunCastApp(ctx context.Context) error {
}

if args := this.Args(); len(args) != 1 {
return gopi.ErrBadParameter.WithPrefix("AppId required")
} else if err := this.CastManager.LaunchAppWithId(devices[0], args[0]); err != nil {
return err
return gopi.ErrBadParameter.WithPrefix("AppId required, use 'default'")
} else {
appid := args[0]
if appid == "" || appid == "default" {
appid = gopi.CAST_APPID_DEFAULT
}
this.Debugf("Launching App %q", appid)
if err := this.CastManager.LaunchAppWithId(devices[0], appid); err != nil {
return err
}
}

// Wait for watching to end
Expand Down Expand Up @@ -90,7 +97,7 @@ func (this *app) RunCastVol(ctx context.Context) error {
return nil
}

func (this *app) RunCastLoad(ctx context.Context) error {
func (this *app) RunCastSeek(ctx context.Context) error {
devices, err := this.GetCastDevices(ctx)
if err != nil {
return err
Expand All @@ -104,14 +111,36 @@ func (this *app) RunCastLoad(ctx context.Context) error {
go this.RunCastWatch(ctx)
}

// Connect and wait
if err := this.CastManager.Connect(devices[0]); err != nil {
if args := this.Args(); len(args) != 1 {
return gopi.ErrBadParameter.WithPrefix("Volume required between 0.0 and 1.0")
} else if value, err := time.ParseDuration(args[0]); err != nil {
return err
} else if err := this.CastManager.Seek(devices[0], value); err != nil {
return err
}

// Wait for watching to end
this.WaitGroup.Wait()

// Return success
return nil
}

func (this *app) RunCastLoad(ctx context.Context) error {
devices, err := this.GetCastDevices(ctx)
if err != nil {
return err
} else if len(devices) != 1 {
return gopi.ErrNotFound.WithPrefix("Cast")
}

// Wait for app
time.Sleep(time.Second)
// Watch in background
if *this.watch {
this.WaitGroup.Add(1)
go this.RunCastWatch(ctx)
}

// Load URL
if args := this.Args(); len(args) != 1 {
return gopi.ErrBadParameter.WithPrefix("Missing URL")
} else if url, err := url.Parse(args[0]); err != nil {
Expand Down Expand Up @@ -183,14 +212,6 @@ func (this *app) RunCastPause(ctx context.Context) error {
go this.RunCastWatch(ctx)
}

// Connect and wait for App Transport Id
if err := this.CastManager.Connect(devices[0]); err != nil {
return err
} else {
// HACK!!!!
time.Sleep(time.Second)
}

if err := this.CastManager.SetPause(devices[0], true); err != nil {
return err
}
Expand All @@ -216,16 +237,14 @@ func (this *app) RunCastPlayEx(ctx context.Context, value bool) error {
go this.RunCastWatch(ctx)
}

// Connect and wait for App Transport Id
if err := this.CastManager.Connect(devices[0]); err != nil {
return err
if value {
if err := this.CastManager.SetPlay(devices[0], true); err != nil {
return err
}
} else {
// HACK!!!!
time.Sleep(time.Second)
}

if err := this.CastManager.SetPlay(devices[0], value); err != nil {
return err
if err := this.CastManager.Stop(devices[0]); err != nil {
return err
}
}

// Wait for watching to end
Expand Down
43 changes: 43 additions & 0 deletions cmd/rpcping/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ type app struct {
gopi.Server
gopi.ServiceDiscovery
gopi.Unit

castId *string
}

func (this *app) Define(cfg gopi.Config) error {
Expand Down Expand Up @@ -48,6 +50,30 @@ func (this *app) Define(cfg gopi.Config) error {
return this.RunMetrics(ctx, stub)
}
})
cfg.Command("cast", "List Google Chromecasts", func(ctx context.Context) error {
if stub, err := this.GetGoogleCastStub(); err != nil {
return err
} else {
return this.RunCast(ctx, stub)
}
})
cfg.Command("cast app", "Start Chromecast Application", func(ctx context.Context) error {
if stub, err := this.GetGoogleCastStub(); err != nil {
return err
} else {
return this.RunCastApp(ctx, stub)
}
})
cfg.Command("cast load", "Load media from URL", func(ctx context.Context) error {
if stub, err := this.GetGoogleCastStub(); err != nil {
return err
} else {
return this.RunCastLoad(ctx, stub)
}
})

// Set flags for cast functions
this.castId = cfg.FlagString("id", "", "Chromecast Id", "cast app", "cast load")

// Return success
return nil
Expand Down Expand Up @@ -104,6 +130,23 @@ func (this *app) GetMetricsStub() (gopi.MetricsStub, error) {
}
}

func (this *app) GetGoogleCastStub() (gopi.CastStub, error) {
args := this.Args()
addr := "grpc"
if len(args) == 1 {
addr = args[0]
}
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
defer cancel()
if conn, err := this.ConnPool.ConnectService(ctx, "tcp", addr, 0); err != nil {
return nil, err
} else if stub, _ := conn.NewStub("gopi.googlecast.Manager").(gopi.CastStub); stub == nil {
return nil, gopi.ErrInternalAppError.WithPrefix("Cannot create stub: ", "gopi.googlecast.Manager")
} else {
return stub, nil
}
}

func (this *app) GetServeAddress() (string, string, error) {
var network, addr string

Expand Down
51 changes: 51 additions & 0 deletions cmd/rpcping/cast.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package main

import (
"context"
"net/url"
"os"

gopi "github.com/djthorpe/gopi/v3"
table "github.com/djthorpe/gopi/v3/pkg/table"
)

func (this *app) RunCast(ctx context.Context, stub gopi.CastStub) error {
casts, err := stub.ListCasts(ctx)
if err != nil {
return err
} else if len(casts) == 0 {
return gopi.ErrNotFound
}

// Display platform information
table := table.New()

table.SetHeader(header{"Name"}, header{"Id"}, header{"Model"}, header{"Service"}, header{"State"})
for _, cast := range casts {
table.Append(cast.Name(), cast.Id(), cast.Model(), cast.Service(), cast.State())
}
table.Render(os.Stdout)

// Return success
return nil
}

func (this *app) RunCastApp(ctx context.Context, stub gopi.CastStub) error {
if err := stub.SetApp(ctx, *this.castId, gopi.CAST_APPID_MUTABLEMEDIA); err != nil {
return err
}

// Return success
return nil
}

func (this *app) RunCastLoad(ctx context.Context, stub gopi.CastStub) error {
if u, err := url.Parse("http://aurl/"); err != nil {
return err
} else if err := stub.LoadURL(ctx, *this.castId, u); err != nil {
return err
}

// Return success
return nil
}
17 changes: 9 additions & 8 deletions cmd/rpcping/units.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package main

import (
_ "github.com/djthorpe/gopi/v3/pkg/event" // gopi.Publisher
_ "github.com/djthorpe/gopi/v3/pkg/log" // gopi.Logger
_ "github.com/djthorpe/gopi/v3/pkg/mdns" // Multicast DNS
_ "github.com/djthorpe/gopi/v3/pkg/metrics" // Metrics Platform
_ "github.com/djthorpe/gopi/v3/pkg/rpc/client" // gRPC Client
_ "github.com/djthorpe/gopi/v3/pkg/rpc/metrics" // Metrics Service
_ "github.com/djthorpe/gopi/v3/pkg/rpc/ping" // Ping Service
_ "github.com/djthorpe/gopi/v3/pkg/rpc/server" // gRPC Server
_ "github.com/djthorpe/gopi/v3/pkg/event" // gopi.Publisher
_ "github.com/djthorpe/gopi/v3/pkg/log" // gopi.Logger
_ "github.com/djthorpe/gopi/v3/pkg/mdns" // Multicast DNS
_ "github.com/djthorpe/gopi/v3/pkg/metrics" // Metrics Platform
_ "github.com/djthorpe/gopi/v3/pkg/rpc/client" // gRPC Client
_ "github.com/djthorpe/gopi/v3/pkg/rpc/googlecast" // Googlecast Service
_ "github.com/djthorpe/gopi/v3/pkg/rpc/metrics" // Metrics Service
_ "github.com/djthorpe/gopi/v3/pkg/rpc/ping" // Ping Service
_ "github.com/djthorpe/gopi/v3/pkg/rpc/server" // gRPC Server
)
Loading

0 comments on commit 742e8da

Please sign in to comment.