Comment by ~dh on ~mpldr/uniview
package main import ( "bufio" "encoding/json" "flag" "fmt" "net" "os" "os/exec" "strings" "time" ) // command structure to interact with MPV type Command struct { Command []interface{} `json:"command"` RequestID int `json:"request_id,omitempty"` } type Answer struct { RequestID int `json:"request_id"` Error string `json:"error"` Data float64 `json:"data"` } // main function func main() { // parse command-line arguments flag.Parse() args := flag.Args() if len(args) < 1 { fmt.Println("Please specify a file path.") os.Exit(1) } filePath := args[0] // socket file path runtimeDir := os.Getenv("XDG_RUNTIME_DIR") if runtimeDir == "" { fmt.Println("$XDG_RUNTIME_DIR is not set. Using /tmp instead.") runtimeDir = "/tmp" } socketFile := runtimeDir + "/mpvsocket" // create directory if it dont exist if _, err := os.Stat(runtimeDir); os.IsNotExist(err) { err = os.Mkdir(runtimeDir, 0755) if err != nil { fmt.Println("error creating directory:", err) os.Exit(1) } } // create our command cmd := exec.Command("mpv", "--input-ipc-server="+socketFile, "--idle") // start mpv if err := cmd.Start(); err != nil { fmt.Println("error starting mpv:", err) os.Exit(1) } // wait for socket to be created // this can probably be done better, idk time.Sleep(1 * time.Second) // connect to socket conn, err := net.Dial("unix", socketFile) if err != nil { fmt.Println("error connecting to socket:", err) os.Exit(1) } defer conn.Close() // load the file loadCmd := Command{Command: []interface{}{"loadfile", filePath}} sendCommand(conn, loadCmd) // input reader reader := bufio.NewReader(os.Stdin) for { fmt.Print("Enter command: ") text, _ := reader.ReadString('\n') text = strings.Replace(text, "\n", "", -1) var cmd Command if text == "play" { cmd = Command{Command: []interface{}{"set_property", "pause", false}} } else if text == "pause" { cmd = Command{Command: []interface{}{"set_property", "pause", true}} } else if strings.HasPrefix(text, "jump") { splitText := strings.Split(text, " ") if len(splitText) < 2 { fmt.Println("Missing time parameter for jump command") continue } timeParam := splitText[1] cmd = Command{Command: []interface{}{"seek", timeParam, "absolute"}} } else if text == "query" { cmd = Command{Command: []interface{}{"get_property", "time-pos"}, RequestID: 1} } else { fmt.Println("Invalid command") continue } sendCommand(conn, cmd) } } // sendCommand takes and instruction and turns it into a command over a socket func sendCommand(conn net.Conn, cmd Command) { cmdJson, _ := json.Marshal(cmd) fmt.Fprintf(conn, string(cmdJson)+"\n") message, _ := bufio.NewReader(conn).ReadString('\n') if cmd.RequestID > 0 { var ans Answer json.Unmarshal([]byte(message), &ans) if ans.RequestID == cmd.RequestID { fmt.Println("timestamp:", ans.Data) return } } fmt.Print("server: " + message) }