// OnConnect event. First moves MumbleDJ into the default channel specified // via commandline args, and moves to root channel if the channel does not exist. The current // user's homedir path is stored, configuration is loaded, and the audio stream is set up. func (dj *mumbledj) OnConnect(e *gumble.ConnectEvent) { if dj.client.Channels.Find(dj.defaultChannel...) != nil { dj.client.Self.Move(dj.client.Channels.Find(dj.defaultChannel...)) } else { fmt.Println("Channel doesn't exist or one was not provided, staying in root channel...") } dj.audioStream = gumble_ffmpeg.New(dj.client) dj.audioStream.Volume = dj.conf.Volume.DefaultVolume if dj.conf.General.PlayerCommand == "ffmpeg" || dj.conf.General.PlayerCommand == "avconv" { dj.audioStream.Command = dj.conf.General.PlayerCommand } else { fmt.Println("Invalid PlayerCommand configuration value. Only \"ffmpeg\" and \"avconv\" are supported. Defaulting to ffmpeg...") } dj.client.AudioEncoder.SetApplication(gopus.Audio) dj.client.Self.SetComment(dj.conf.General.DefaultComment) if dj.conf.Cache.Enabled { dj.cache.Update() go dj.cache.ClearExpired() } }
func (a *adapter) ttsGoRoutine() { stream := gumble_ffmpeg.New(a.client) defer stream.Stop() stream.Volume = 0.25 for req := range a.speakChan { a.handleSpeakRequest(stream, req) } }
//OnConnect event - Looks for the developer in a channel, else moves to most populated channel func (jew *jewvis) OnConnect(e *gumble.ConnectEvent) { if jew.client.Channels.Find("JCC") != nil { jew.client.Self.Move(jew.client.Channels.Find("JCC")) // } else if jew.client.Users.Find("AnJew") != nil { // jew.client.Self.Move(jew.client.Users.Find("AnJew").Channel) // } else { // jew.client.Self.Channel.Send("Master could not be found, staying in channel...", false) } jew.audioStream = gumble_ffmpeg.New(jew.client) jew.audioStream.Volume = jew.conf.Volume.DefaultVolume jew.client.AudioEncoder.SetApplication(gopus.Audio) jew.client.Self.SetComment(jew.conf.General.DefaultComment) }
// OnConnect event. First moves MumbleDJ into the default channel specified // via commandline args, and moves to root channel if the channel does not exist. The current // user's homedir path is stored, configuration is loaded, and the audio stream is set up. func (dj *mumbledj) OnConnect(e *gumble.ConnectEvent) { if dj.client.Channels.Find(dj.defaultChannel...) != nil { dj.client.Self.Move(dj.client.Channels.Find(dj.defaultChannel...)) } else { fmt.Println("Channel doesn't exist or one was not provided, staying in root channel...") } dj.audioStream = gumble_ffmpeg.New(dj.client) dj.audioStream.Volume = dj.conf.Volume.DefaultVolume dj.client.AudioEncoder.SetApplication(gopus.Audio) dj.client.Self.SetComment(dj.conf.General.DefaultComment) if dj.conf.Cache.Enabled { dj.cache.Update() go dj.cache.ClearExpired() } }
func main() { files := make(map[string]string) var stream *gumble_ffmpeg.Stream flag.Usage = func() { fmt.Fprintf(os.Stderr, "Usage of %s: [flags] [audio files...]\n", os.Args[0]) flag.PrintDefaults() } gumbleutil.Main(func(client *gumble.Client) { stream = gumble_ffmpeg.New(client) client.Attach(gumbleutil.AutoBitrate) for _, file := range flag.Args() { key := filepath.Base(file) files[key] = file } }, gumbleutil.Listener{ // Connect event Connect: func(e *gumble.ConnectEvent) { fmt.Printf("audio player loaded! (%d files)\n", len(files)) }, // Text message event TextMessage: func(e *gumble.TextMessageEvent) { if e.Sender == nil { return } file, ok := files[e.Message] if !ok { return } stream.Source = gumble_ffmpeg.SourceFile(file) if err := stream.Play(); err != nil { fmt.Printf("%s\n", err) } else { fmt.Printf("Playing %s\n", file) } }, }) }
// OnConnect event. The config is loaded, then audio stream set up. func (jew *jewbot) OnConnect(e *gumble.ConnectEvent) { jew.audioStream = gumble_ffmpeg.New(jew.client) jew.audioStream.Volume = jew.conf.Volume.DefaultVolume if jew.conf.General.PlayerCommand == "ffmpeg" || jew.conf.General.PlayerCommand == "avconv" { jew.audioStream.Command = jew.conf.General.PlayerCommand } else { fmt.Println("Invalid PlayerCommand value, ffmpeg/avconv only") } jew.client.AudioEncoder.SetApplication(gopus.Audio) jew.client.Self.SetComment(jew.conf.General.DefaultComment) if jew.conf.Cache.Enabled { jew.cache.Update() go jew.cache.ClearExpired() } }
func main() { // Flags username := flag.String("username", "piepan-bot", "username of the bot") password := flag.String("password", "", "user password") server := flag.String("server", "localhost:64738", "address of the server") certificateFile := flag.String("certificate", "", "user certificate file (PEM)") keyFile := flag.String("key", "", "user certificate key file (PEM)") insecure := flag.Bool("insecure", false, "skip certificate checking") lock := flag.String("lock", "", "server certificate lock file") ffmpeg := flag.String("ffmpeg", "ffmpeg", "ffmpeg-capable executable for media streaming") var accessTokens strFlagSlice flag.Var(&accessTokens, "access-token", "server access token (can be defined multiple times)") flag.Usage = func() { fmt.Fprintf(os.Stderr, "piepan v0.7.0\n") fmt.Fprintf(os.Stderr, "usage: %s [options] [script files]\n", os.Args[0]) fmt.Fprintf(os.Stderr, "an easy to use framework for writing scriptable Mumble bots\n") flag.PrintDefaults() fmt.Fprintf(os.Stderr, "\nScript files are defined in the following way:\n") fmt.Fprintf(os.Stderr, " [type%c[environment%c]]filename\n", os.PathListSeparator, os.PathListSeparator) fmt.Fprintf(os.Stderr, " filename: path to script file\n") fmt.Fprintf(os.Stderr, " type: type of script file (default: file extension)\n") fmt.Fprintf(os.Stderr, " environment: name of environment where script will be executed (default: type)\n\n") fmt.Fprintf(os.Stderr, "Enabled script types:\n") fmt.Fprintf(os.Stderr, " Type Name\n") for _, ext := range piepan.PluginExtensions { fmt.Fprintf(os.Stderr, " %-12s %s\n", ext, piepan.Plugins[ext].Name) } } flag.Parse() // Configuration config := gumble.NewConfig() config.Username = *username config.Password = *password config.Address = *server config.Tokens = gumble.AccessTokens(accessTokens) client := gumble.NewClient(config) instance := piepan.New(client) audio := gumble_ffmpeg.New(client) audio.Command = *ffmpeg instance.Audio = audio if *insecure { config.TLSConfig.InsecureSkipVerify = true } if *lock != "" { gumbleutil.CertificateLockFile(client, *lock) } if *certificateFile != "" { if *keyFile == "" { keyFile = certificateFile } if certificate, err := tls.LoadX509KeyPair(*certificateFile, *keyFile); err != nil { panic(err) } else { config.TLSConfig.Certificates = append(config.TLSConfig.Certificates, certificate) } } client.Attach(gumbleutil.AutoBitrate) // Load scripts for _, script := range flag.Args() { if err := instance.LoadScript(script); err != nil { fmt.Fprintf(os.Stderr, "%s: %s\n", script, err) } } keepAlive := make(chan bool) exitStatus := 0 client.Attach(gumbleutil.Listener{ Disconnect: func(e *gumble.DisconnectEvent) { if e.Type != gumble.DisconnectUser { exitStatus = int(e.Type) + 1 } keepAlive <- true }, }) if err := client.Connect(); err != nil { fmt.Fprintf(os.Stderr, "%s\n", err) os.Exit(1) } <-keepAlive os.Exit(exitStatus) }
func main() { files := make(map[string]string) var stream *gumble_ffmpeg.Stream targetChannel := flag.String("channel", "Root", "channel the bot will join") gumbleutil.Main(func(_ *gumble.Config, client *gumble.Client) { var err error stream, err = gumble_ffmpeg.New(client) if err != nil { fmt.Printf("%s\n", err) os.Exit(1) } for _, file := range flag.Args() { key := filepath.Base(file) files[key] = file } }, gumbleutil.Listener{ // Connect event Connect: func(e *gumble.ConnectEvent) { fmt.Printf("GoMumbleSoundboard loaded (%d files)\n", len(files)) fmt.Printf("Connected to %s\n", e.Client.Conn().RemoteAddr()) if e.WelcomeMessage != "" { fmt.Printf("Welcome message: %s\n", e.WelcomeMessage) } fmt.Printf("Channel: %s\n", e.Client.Self().Channel().Name()) if *targetChannel != "" && e.Client.Self().Channel().Name() != *targetChannel { target := e.Client.Self().Channel().Find(*targetChannel) e.Client.Self().Move(target) fmt.Printf("Moved to: %s\n", target.Name()) } // Start webserver m := martini.Classic() // martini.Static() is used, so public/index.html gets automagically served m.Get("/files.json", func() string { keys := make([]string, 0, len(files)) for k := range files { keys = append(keys, k) } js, _ := json.Marshal(keys) return string(js) }) m.Get("/play/:file", func(params martini.Params) (int, string) { file, ok := files[params["file"]] if !ok { return 404, "not found" } stream.Stop() if err := stream.Play(file); err != nil { return 400, fmt.Sprintf("%s\n", err) } else { return 200, fmt.Sprintf("Playing %s\n", file) } }) m.Get("/stop", func() string { stream.Stop() return "ok" }) m.Run() }, }) }