From cff36f68517806cd0ae28889d276012003d57012 Mon Sep 17 00:00:00 2001 From: clsr Date: Tue, 11 Dec 2018 18:24:52 +0100 Subject: Initial commit --- ff2mpv.go | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 ff2mpv.go (limited to 'ff2mpv.go') diff --git a/ff2mpv.go b/ff2mpv.go new file mode 100644 index 0000000..7f0c939 --- /dev/null +++ b/ff2mpv.go @@ -0,0 +1,103 @@ +package main + +import ( + "encoding/binary" + "encoding/json" + "fmt" + "io" + "os" + "os/exec" +) + +var mpvCmd = []string{"mpv", "--player-operation-mode=pseudo-gui", "--"} + +type ffRequest struct { + URL string `json:"url"` +} + +type ffManifest struct { + Name string `json:"name"` + Description string `json:"description"` + Path string `json:"path"` + Type string `json:"type"` + AllowedExtensions []string `json:"allowed_extensions"` +} + +func ff2mpv() { + // extract message length from the first 4 bytes + var l uint32 + // Go does not have an easy way to do sutff with native endianness without + // using usafe. Blame stupid WebExtension spec that uses *native* endianness in + // a *protocol*. Seriously, who designed that‽ + if err := binary.Read(os.Stdin, endianness, &l); err != nil { + panic(err) + } + if l > 1024*1024 { + panic(fmt.Sprintf("native messaging message length too large: %d", l)) + } + + // read raw message + buf := make([]byte, l) + if n, err := os.Stdin.Read(buf); err != nil { + panic(err) + } else if n != len(buf) { + panic(fmt.Sprintf("read message length %d does not match expected length %d", n, l)) + } + + // decode JSON + var data ffRequest + if err := json.Unmarshal(buf, &data); err != nil { + panic(err) + } + + // run mpv + args := append(mpvCmd, data.URL) + cmd := exec.Command(args[0], args[1:]...) + if err := cmd.Start(); err != nil { + panic(err) + } + + // respond + outmsg := []byte("{}") + outlen := uint32(len(outmsg)) + binary.Write(os.Stdout, endianness, outlen) + os.Stdout.Write(outmsg) +} + +func manifest() { + exe, err := os.Executable() + if err != nil { + panic(err) + } + data, err := json.MarshalIndent(ffManifest{ + Name: "ff2mpv", + Description: "ff2mpv's extenal manifest (ff2mpv-go)", + Path: exe, + Type: "stdio", + AllowedExtensions: []string{"ff2mpv@yossarian.net"}, + }, "", "\t") + if err != nil { + panic(err) + } + os.Stdout.Write(data) +} + +func usage(w io.Writer) { + fmt.Fprintf(os.Stderr, "args: %#v\n", os.Args) + fmt.Fprintf(w, "usage: %s [--manifest]\n", os.Args[0]) +} + +func main() { + arg := "" + if len(os.Args) == 2 { + arg = os.Args[1] + } + switch arg { + case "--manifest": + manifest() + case "--help": + usage(os.Stdout) + default: + ff2mpv() + } +} -- cgit