// // mpvNowPlaying.go // mpvNowPlaying // // Created by Mr. Gecko on 4/2/16. // Copyright (c) 2016 Mr. Gecko's Media (James Coleman). All rights reserved. http://mrgeckosmedia.com/ // package main import ( "bufio" "encoding/json" "fmt" "github.com/dwbuiten/go-mediainfo/mediainfo" "log" "net" "net/http" "os/user" "path" "time" ) func MPVSocket() string { usr, err := user.Current() if err != nil { log.Fatal(err) } return path.Join(usr.HomeDir, ".config/mpv/mpv.sock") } type FloatResult struct { Data float64 `json:"data"` Error string `json:"error"` } func GetPropertyFloat(conn net.Conn, propertyName string) (float64, error) { fmt.Fprintln(conn, "{ \"command\": [\"get_property\", \""+propertyName+"\"] }") result, err := bufio.NewReader(conn).ReadBytes('\n') if err != nil { return -1, err } floatResult := new(FloatResult) err = json.Unmarshal(result, floatResult) if err != nil { log.Fatal("Config file error: ", err) } if floatResult.Error != "success" { return -1, fmt.Errorf(floatResult.Error) } return floatResult.Data, nil } type StringResult struct { Data string `json:"data"` Error string `json:"error"` } func GetPropertyString(conn net.Conn, propertyName string) (string, error) { fmt.Fprintln(conn, "{ \"command\": [\"get_property_string\", \""+propertyName+"\"] }") result, err := bufio.NewReader(conn).ReadBytes('\n') if err != nil { return "", err } stringResult := new(StringResult) err = json.Unmarshal(result, stringResult) if err != nil { log.Fatal("Config file error: ", err) } if stringResult.Error != "success" { return "", fmt.Errorf(stringResult.Error) } return stringResult.Data, nil } func SizeToString(size float64) string { sizes := []string{"Bytes", "KB", "MB", "GB", "TB", "PB"} currentSize := 0 for size >= 1024 { currentSize++ size /= 1024 } return fmt.Sprintf("%.02f %s", size, sizes[currentSize]) } type MPV struct { } type ReesultData struct { Result string `json:"result"` Error string `json:"error"` } func (m *MPV) ServeHTTP(writer http.ResponseWriter, request *http.Request) { defer request.Body.Close() writer.Header().Set("Content-Type", "application/json") reesultData := new(ReesultData) reesultData.Error = "success" conn, err := net.Dial("unix", MPVSocket()) if err != nil { reesultData.Error = "Nothing is currently playing" out, _ := json.Marshal(reesultData) writer.Write(out) log.Println(err) return } defer conn.Close() title, err := GetPropertyString(conn, "media-title") if err != nil { reesultData.Error = "Error occured attempting to gather information" out, _ := json.Marshal(reesultData) writer.Write(out) log.Println(err) return } playbackTimeFloat, err := GetPropertyFloat(conn, "playback-time") if err != nil { reesultData.Error = "Error occured attempting to gather information" out, _ := json.Marshal(reesultData) writer.Write(out) log.Println(err) return } playbackTime := time.Duration(playbackTimeFloat) * time.Second durationFloat, err := GetPropertyFloat(conn, "duration") if err != nil { reesultData.Error = "Error occured attempting to gather information" out, _ := json.Marshal(reesultData) writer.Write(out) log.Println(err) return } duration := time.Duration(durationFloat) * time.Second fileSize, err := GetPropertyFloat(conn, "file-size") if err != nil { log.Println(err) return } performer := "" album := "" videoFormat, err := GetPropertyString(conn, "video-format") if err != nil { log.Println(err) } if videoFormat == "" { workingDirectory, err := GetPropertyString(conn, "working-directory") if err != nil { log.Println(err) } filename, err := GetPropertyString(conn, "filename") if err != nil { log.Println(err) } filePath := path.Join(workingDirectory, filename) info, err := mediainfo.Open(filePath) if err != nil { log.Println(err) } else { defer info.Close() performer, err = info.Get("Performer", 0, mediainfo.General) if err != nil { log.Println(err) } album, err = info.Get("Album", 0, mediainfo.General) if err != nil { log.Println(err) } } } reesultData.Result = fmt.Sprintf("Now playing %v %v %v / %v (%d%%)", title, SizeToString(fileSize), playbackTime, duration, int64((playbackTimeFloat/durationFloat)*100)) if performer != "" { reesultData.Result = fmt.Sprintf("Now playing %v by %v from %v %v %v / %v (%d%%)", title, performer, album, SizeToString(fileSize), playbackTime, duration, int64((playbackTimeFloat/durationFloat)*100)) } out, _ := json.Marshal(reesultData) writer.Write(out) } func main() { mediainfo.Init() mpv := new(MPV) if err := http.ListenAndServe(":7076", mpv); err != nil { log.Fatal(err) } }