Skip to content

Instantly share code, notes, and snippets.

@twitchyliquid64
Created November 2, 2017 09:22
Show Gist options
  • Save twitchyliquid64/be0c61ffc5d363ec4d25d7e9ce29664f to your computer and use it in GitHub Desktop.
Save twitchyliquid64/be0c61ffc5d363ec4d25d7e9ce29664f to your computer and use it in GitHub Desktop.
Demonstrates playing a local media file on a google home.
package main
import (
"context"
"errors"
"flag"
"fmt"
"io"
"net"
"net/http"
"os"
"time"
cast "github.com/barnybug/go-cast"
"github.com/barnybug/go-cast/controllers"
"github.com/barnybug/go-cast/discovery"
)
var (
deviceName = flag.String("name", "Master bedroom Home", "")
)
func findCastDeviceByName(ctx context.Context, name string, timeout int) (*cast.Client, error) {
ctx, cancel := context.WithTimeout(ctx, time.Duration(timeout)*time.Second)
defer cancel()
service := discovery.NewService(ctx)
go service.Run(ctx, time.Duration(timeout+1)*time.Second)
for {
select {
case c := <-service.Found():
if c.Name() == name {
return c, nil
}
case <-ctx.Done():
return nil, fmt.Errorf("timeout when searching for device %q", name)
}
}
}
func localAddr() (net.IP, error) {
ifaces, err := net.Interfaces()
if err != nil {
return nil, err
}
for _, i := range ifaces {
addrs, err := i.Addrs()
if err != nil {
return nil, err
}
for _, addr := range addrs {
var ip net.IP
switch v := addr.(type) {
case *net.IPNet:
ip = v.IP
case *net.IPAddr:
ip = v.IP
}
// process IP address
if !ip.IsLoopback() {
return ip, nil
}
}
}
return nil, errors.New("Could not find appropriate interface")
}
func playLocal() *http.Server {
done := false
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "audio/mp3")
src, err := os.Open("isolating.mp3")
if err != nil {
fmt.Printf("%v\n", err)
return
}
io.Copy(w, src)
src.Close()
done = true
})
serv := &http.Server{
Addr: ":8080",
Handler: mux,
}
go func() {
serv.ListenAndServe()
}()
return serv
}
func main() {
flag.Parse()
ctx := context.Background()
var err error
defer func() {
if err != nil {
fmt.Printf("Error: %v\n", err)
}
}()
ip, err := localAddr()
if err != nil {
return
}
client, err := findCastDeviceByName(ctx, *deviceName, 2)
if err != nil {
return
}
err = client.Connect(ctx)
if err != nil {
return
}
defer client.Close()
// status, err := client.Receiver().GetStatus(ctx)
// if err != nil {
// return
// }
//
// volumeLevel := 0.8
// muted := false
// _, err = client.Receiver().SetVolume(ctx, &controllers.Volume{Level: &volumeLevel, Muted: &muted})
// if err != nil {
// return
// }
//
// defer func() {
// client.Receiver().SetVolume(ctx, status.Volume)
// }()
server := playLocal()
defer server.Close()
media, err := client.Media(ctx)
if err != nil {
return
}
item := controllers.MediaItem{
ContentId: "http://" + ip.String() + ":8080/",
StreamType: "LIVE",
ContentType: "audio/mp3",
}
_, err = media.LoadMedia(ctx, item, 0, true, map[string]interface{}{})
if err != nil {
return
}
time.Sleep(9 * time.Second)
server.Shutdown(ctx)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment