~dh


#14 add web-based UI 1 year, 19 days ago

~mpldr assigned ~dh to #14 on ~mpldr/uniview

#2 mpv interface 1 year, 28 days ago

on ~mpldr/uniview

Thank you very much for the connector, ~dh.

#2 mpv interface 1 year, 1 month ago

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)
}