func NewFakeMediaPlayer(driver ninja.Driver, conn *ninja.Connection, id int) (*fakeMediaPlayer, error) { name := fmt.Sprintf("Fancy Fake Media Player %d", id) ninja, err := devices.CreateMediaPlayerDevice(driver, &model.Device{ NaturalID: fmt.Sprintf("player-%d", id), NaturalIDType: "fake", Name: &name, Signatures: &map[string]string{ "ninja:manufacturer": "Fake Co.", "ninja:productName": "fakeMediaPlayer", "ninja:productType": "MediaPlayer", "ninja:thingType": "mediaplayer", }, }, conn) var fake *fakeMediaPlayer if err == nil { fake = &fakeMediaPlayer{ ninja: ninja, } err = fake.bindMethods() if err != nil { fake = nil } } else { fake = nil } return fake, err }
func NewPlayer(driver *sonosDriver, conn *ninja.Connection, zoneInfo *sonosZoneInfo) (*sonosZonePlayer, error) { id := zoneInfo.attributes.CurrentZoneGroupID name := zoneInfo.attributes.CurrentZoneGroupName nlog.Infof("Making media player with ID: %s Label: %s") player, err := devices.CreateMediaPlayerDevice(driver, &model.Device{ NaturalID: id, NaturalIDType: "sonos", Name: &name, Signatures: &map[string]string{ "ninja:manufacturer": "Sonos", "ninja:productName": "Sonos Player", "ninja:productType": "MediaPlayer", "ninja:thingType": "mediaplayer", }, }, conn) if err != nil { nlog.FatalError(err, "Failed to create media player device") } // At the moment I am using the first player in that zone // i need to know how this looks in a multi player situation. sonosUnit := zoneInfo.players[0] sp := &sonosZonePlayer{sonosUnit, logger.GetLogger("sonosZonePlayer"), player, time.Now()} err = sp.bindMethods() if err != nil { sp.log.FatalError(err, "Failed to bind channels to sonos device") } err = sp.updateState() if err != nil { sp.log.FatalError(err, "Failed to get initial device state") } return sp, nil }
func NewMediaPlayer(driver ninja.Driver, conn *ninja.Connection, info map[string]string, client *castv2.Client) (*MediaPlayer, error) { name := info["fn"] sigs := map[string]string{ "ninja:manufacturer": "Google", "ninja:productName": "Chromecast", "ninja:thingType": "mediaplayer", } for k, v := range info { sigs["chromecast:"+k] = v } player, err := devices.CreateMediaPlayerDevice(driver, &model.Device{ NaturalID: info["id"], NaturalIDType: "chromecast", Name: &name, Signatures: &sigs, }, conn) if err != nil { return nil, err } device := &MediaPlayer{ player: player, client: client, } player.ApplyVolume = device.applyVolume if err := player.EnableVolumeChannel(true); err != nil { player.Log().Fatalf("Failed to enable volume channel: %s", err) } player.ApplyPlayPause = device.applyPlayPause if err := player.EnableControlChannel([]string{"playing", "paused", "stopped", "buffering", "busy", "idle", "inactive"}); err != nil { player.Log().Fatalf("Failed to enable control channel: %s", err) } //_ = controllers.NewHeartbeatController(client, "Tr@n$p0rt-0", "Tr@n$p0rt-0") heartbeat := controllers.NewHeartbeatController(client, "sender-0", "receiver-0") heartbeat.Start() connection := controllers.NewConnectionController(client, "sender-0", "receiver-0") connection.Connect() device.receiver = controllers.NewReceiverController(client, "sender-0", "receiver-0") go func() { for msg := range device.receiver.Incoming { if err := device.onReceiverStatus(msg); err != nil { device.player.Log().Warningf("Failed to update status: %s", err) } } }() _, _ = device.receiver.GetStatus(time.Second * 5) //spew.Dump("Status response", status, err) //spew.Dump("Media namespace?", status.GetSessionByNamespace("urn:x-cast:com.google.cast.media")) device.media = controllers.NewMediaController(device.client, "sender-0", "") go func() { for { mediaStatus := <-device.media.Incoming if len(mediaStatus) == 0 { break } device.media.MediaSessionID = mediaStatus[0].MediaSessionID } }() return device, nil }
func newDevice(driver ninja.Driver, conn *ninja.Connection, projector dell.Projector) (*Device, error) { player, err := devices.CreateMediaPlayerDevice(driver, &model.Device{ NaturalID: projector.UUID, NaturalIDType: "dell-projector", Name: &projector.UUID, Signatures: &map[string]string{ "ninja:manufacturer": "Dell", "ninja:productName": "Projector", "ninja:thingType": "mediaplayer", "ip:serial": projector.UUID, }, }, conn) if err != nil { return nil, err } // player.ApplyIsOn = func() (bool, error) { // return true, nil // } // player.ApplyGetPower = func() (bool, error) { // return true, nil // } // Volume Channel player.ApplyVolumeUp = func() error { _, err := dell.SendCommand(projector, dell.Commands.Volume.Up) projector.Volume += 1 if err != nil { return err } return err } player.ApplyVolumeDown = func() error { _, err := dell.SendCommand(projector, dell.Commands.Volume.Down) projector.Volume -= 1 if err != nil { return err } return err } // player.ApplyVolume = func(state *channels.VolumeState) error { // // return nil // } player.ApplyToggleMuted = func() error { if projector.VolumeMuted == true { dell.SendCommand(projector, dell.Commands.Volume.Unmute) projector.VolumeMuted = false } else { dell.SendCommand(projector, dell.Commands.Volume.Mute) projector.VolumeMuted = true } player.UpdateVolumeState(&channels.VolumeState{Muted: &projector.VolumeMuted}) return err } // enable the volume channel, supporting mute (parameter is true) if err := player.EnableVolumeChannel(true); err != nil { player.Log().Errorf("Failed to enable volume channel: %s", err) } // on-off channel methods player.ApplyOff = func() error { player.UpdateOnOffState(false) dell.SendCommand(projector, dell.Commands.Power.Off) projector.PowerState = false return nil } player.ApplyOn = func() error { player.UpdateOnOffState(true) dell.SendCommand(projector, dell.Commands.Power.On) projector.PowerState = true return nil } player.ApplyToggleOnOff = func() error { if projector.PowerState == true { dell.SendCommand(projector, dell.Commands.Power.Off) } else { dell.SendCommand(projector, dell.Commands.Power.On) } return nil } // I can't find anywhere that the on/off states ever get set - on the sphereamid or in the app if err := player.EnableOnOffChannel("state"); err != nil { player.Log().Errorf("Failed to enable on-off channel: %s", err) } // NOTE: this is a workaround to get on/off when dragging to on/play or off/pause. Find a better way if possible // https://discuss.ninjablocks.com/t/mediaplayer-device-drivers/3776/2 (question asked) player.ApplyPlayPause = func(isPlay bool) error { if isPlay { player.UpdateControlState(channels.MediaControlEventPlaying) return player.ApplyOn() } else { player.UpdateControlState(channels.MediaControlEventPaused) return player.ApplyOff() } } if err := player.EnableControlChannel([]string{}); err != nil { player.Log().Errorf("Failed to enable control channel: %s", err) } return &Device{*player, &projector}, nil }