package main import ( "encoding/json" "fmt" "math/rand/v2" "mpv-discord-rpc/config" "net" "os" "path/filepath" "strings" "time" "github.com/hugolgst/rich-go/client" ) // const CLIENT_ID = "1452184186969657455" const SOCKET_PATH = "/tmp/mpvsocket" type MPVResponse struct { Data any `json:"data"` Error string `json:"error"` } func mpvCommand(command []any) (string, error) { conn, err := net.DialTimeout("unix", SOCKET_PATH, 1*time.Second) if err != nil { return "", err } defer conn.Close() cmd := map[string]any{"command": command} data, _ := json.Marshal(cmd) data = append(data, '\n') conn.Write(data) buf := make([]byte, 4096) n, err := conn.Read(buf) if err != nil { return "", err } var resp MPVResponse json.Unmarshal(buf[:n], &resp) if resp.Data != nil { return fmt.Sprintf("%v", resp.Data), nil } return "", fmt.Errorf("no data") } func cleanFilename(filename string) string { exts := []string{".mp3", ".flac", ".m4a", ".opus", ".ogg", ".wav"} for _, ext := range exts { filename = strings.ReplaceAll(filename, ext, "") } return filename } func randomStatePrefix() string { prefixes := []string{"Listening", "Vibing", "Jamming"} return prefixes[rand.IntN(len(prefixes))] } func isInMusicFolder(fp string, musicFolders []string) bool { for _, folder := range musicFolders { if strings.HasPrefix(folder, "~") { home, _ := os.UserHomeDir() folder = strings.Replace(folder, "~", home, 1) } if !filepath.IsAbs(folder) { home, _ := os.UserHomeDir() folder = filepath.Join(home, folder) } folder = filepath.Clean(folder) filePath := filepath.Clean(fp) if strings.HasPrefix(filePath, folder) { return true } } return false } func main() { var connected bool var lastSong string config, _:= config.GetConfig() for { if _, err := os.Stat(SOCKET_PATH); err == nil { if !connected { err := client.Login(config.ClientID) if err == nil { connected = true fmt.Println("Connected to Discord") } else { fmt.Println("Failed to connect to Discord, reconnecting 5s...") time.Sleep(5 * time.Second) continue } } filename, err := mpvCommand([]any{"get_property", "filename"}) fp, err := mpvCommand([]any{"get_property", "path"}) if err == nil && fp != "" && filename != "" && isInMusicFolder(fp, config.MusicFolders) { song := cleanFilename(filename) if song != lastSong { lastSong = song err = client.SetActivity(client.Activity{ State: randomStatePrefix() + " to music", Details: song, LargeImage: "music", LargeText: "MPV", }) if err != nil { fmt.Printf("✗ Failed to set activity: %v\n", err) } else { fmt.Printf("✓ Activity updated: %s\n", song) } } } else { fmt.Printf("✗ Connection broken, restart mpv to reconnect: %v\n", err) } time.Sleep(5 * time.Second) } else { if connected { client.Logout() connected = false fmt.Println("Disconnected from Discord") } time.Sleep(2 * time.Second) } } }