talk in audio channel (not working yet)
This commit is contained in:
53
core/audio.go
Normal file
53
core/audio.go
Normal file
@ -0,0 +1,53 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
)
|
||||
|
||||
// playSound plays the current buffer to the provided channel.
|
||||
func playSound(s *discordgo.Session, guildID, channelID string, buffer []byte) (err error) {
|
||||
|
||||
// Join the provided voice channel.
|
||||
vc, err := s.ChannelVoiceJoin(guildID, channelID, false, true)
|
||||
if err != nil {
|
||||
log.Println("Could not find channel.")
|
||||
return err
|
||||
}
|
||||
|
||||
// Sleep for a specified amount of time before playing the sound
|
||||
time.Sleep(250 * time.Millisecond)
|
||||
|
||||
// Start speaking.
|
||||
vc.Speaking(true)
|
||||
|
||||
vc.OpusSend <- buffer
|
||||
|
||||
// Stop speaking
|
||||
vc.Speaking(false)
|
||||
|
||||
// Sleep for a specificed amount of time before ending.
|
||||
time.Sleep(250 * time.Millisecond)
|
||||
|
||||
// Disconnect from the provided voice channel.
|
||||
vc.Disconnect()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getAudioMessage(msg string) (filename string, out []byte) {
|
||||
curr_time := time.Now().Unix()
|
||||
filename = fmt.Sprintf("%d.ogg", curr_time)
|
||||
var cmd_args string = fmt.Sprintf("espeak-ng -s 120 -v mb-fr2 -p 30 '%s' --stdout | ffmpeg -i - -c:a libopus -f ogg pipe:1 2>/dev/null",
|
||||
maxString(msg, 300))
|
||||
cmd := exec.Command("sh", "-c", cmd_args)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
fmt.Println(fmt.Sprint(err))
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -41,6 +41,12 @@ func CommandInit() {
|
||||
"`/ggd [audio|tts] hello everyone`",
|
||||
MessageAudio)
|
||||
|
||||
SetCommand(
|
||||
[]string{"/ggd voca"},
|
||||
"Play audio message in vocal channel",
|
||||
"`/ggd voca let's go shopping`",
|
||||
MessageVocal)
|
||||
|
||||
SetCommand(
|
||||
[]string{"ping", "pong"},
|
||||
"*Check if the bot is alive*",
|
||||
|
||||
@ -3,7 +3,7 @@ package core
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"log"
|
||||
"math/rand"
|
||||
"sort"
|
||||
"strings"
|
||||
@ -12,20 +12,22 @@ import (
|
||||
"github.com/bwmarrin/discordgo"
|
||||
)
|
||||
|
||||
func getAudioMessage(msg string) (filename string, file *bytes.Reader) {
|
||||
curr_time := time.Now().Unix()
|
||||
filename = fmt.Sprintf("/tmp/%d.mp3", curr_time)
|
||||
var cmd_args string = fmt.Sprintf("espeak-ng -s 120 -v mb-fr2 -p 30 '%s' --stdout",
|
||||
maxString(msg, 300))
|
||||
cmd := exec.Command("sh", "-c", cmd_args)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
fmt.Println(fmt.Sprint(err))
|
||||
}
|
||||
file = bytes.NewReader(out)
|
||||
// This function will be called (due to AddHandler above) every time a new
|
||||
// guild is joined.
|
||||
func GuildCreate(s *discordgo.Session, event *discordgo.GuildCreate) {
|
||||
|
||||
if event.Guild.Unavailable {
|
||||
return
|
||||
}
|
||||
|
||||
for _, channel := range event.Guild.Channels {
|
||||
if channel.ID == event.Guild.ID {
|
||||
_, _ = s.ChannelMessageSend(channel.ID, "Airhorn is ready! Type !airhorn while in a voice channel to play a sound.")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getHelpMessage() string {
|
||||
// build list of possible commands
|
||||
// TODO: currently, the help needs to get value initiated at startup time to be built.
|
||||
@ -113,6 +115,45 @@ func MessagePing(s *discordgo.Session, m *discordgo.MessageCreate, message strin
|
||||
|
||||
func MessageAudio(s *discordgo.Session, m *discordgo.MessageCreate, message string) {
|
||||
var cleanMessage string = prepareTTSMessage(message)
|
||||
filename, file := getAudioMessage(cleanMessage)
|
||||
filename, out := getAudioMessage(cleanMessage)
|
||||
file := bytes.NewReader(out)
|
||||
s.ChannelFileSend(m.ChannelID, filename, file)
|
||||
}
|
||||
|
||||
func MessageVocal(s *discordgo.Session, m *discordgo.MessageCreate, message string) {
|
||||
log.Println("We get there (MessageVocal)")
|
||||
// Ignore all messages created by the bot itself
|
||||
// This isn't required in this specific example but it's a good practice.
|
||||
if m.Author.ID == s.State.User.ID {
|
||||
return
|
||||
}
|
||||
|
||||
// Find the channel that the message came from.
|
||||
c, err := s.State.Channel(m.ChannelID)
|
||||
if err != nil {
|
||||
// Could not find channel.
|
||||
return
|
||||
}
|
||||
|
||||
// Find the guild for that channel.
|
||||
g, err := s.State.Guild(c.GuildID)
|
||||
if err != nil {
|
||||
// Could not find guild.
|
||||
return
|
||||
}
|
||||
|
||||
var cleanMessage string = prepareTTSMessage(message)
|
||||
_, out := getAudioMessage(cleanMessage)
|
||||
|
||||
// Look for the message sender in that guild's current voice states.
|
||||
for _, vs := range g.VoiceStates {
|
||||
if vs.UserID == m.Author.ID {
|
||||
log.Println("We get there (MessageVocal) voice state for loop")
|
||||
err = playSound(s, g.ID, vs.ChannelID, out)
|
||||
if err != nil {
|
||||
fmt.Println("Error playing sound:", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
6
main.go
6
main.go
@ -20,8 +20,14 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
discord.Identify.Intents = discordgo.MakeIntent(discordgo.IntentsGuilds |
|
||||
discordgo.IntentsGuildMessages |
|
||||
discordgo.IntentsGuildVoiceStates)
|
||||
|
||||
|
||||
discord.AddHandler(core.MessageHandler)
|
||||
discord.AddHandler(core.MessageTalkback)
|
||||
discord.AddHandler(core.GuildCreate)
|
||||
|
||||
err = discord.Open()
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user