diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | COPYING | 3 | ||||
| -rw-r--r-- | README.md | 36 | ||||
| -rw-r--r-- | ff2mpv.go | 103 | ||||
| -rw-r--r-- | ff2mpv_386.go | 5 | ||||
| -rw-r--r-- | ff2mpv_amd64.go | 5 | ||||
| -rw-r--r-- | ff2mpv_arm.go | 5 | ||||
| -rw-r--r-- | ff2mpv_arm64.go | 5 | ||||
| -rw-r--r-- | go.mod | 1 | 
9 files changed, 164 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..585f016 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/ff2mpv-go @@ -0,0 +1,3 @@ +This software is released into the public domain. +It is provided "as is", without warranties or conditions of any kind. +Anyone is free to use, modify, redistribute and do anything with this software. diff --git a/README.md b/README.md new file mode 100644 index 0000000..821bf90 --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +ff2mpv-go +========= + +Native messaging host for [ff2mpv](https://github.com/woodruffw/ff2mpv/) written in Go. + +Since it is a native binary, it starts faster than the official Python or Ruby +implementations. + + +Requirements +------------ + +- [Firefox](https://www.mozilla.org/en-US/firefox/) 50 or later +- [ff2mpv](https://github.com/woodruffw/ff2mpv/) 3.0 or later +- [Go](https://golang.org/) 11 or later (probably works on older versions too) +- [mpv](https://mpv.io/) 0.21.0 or later + + +Installation +------------ + +- `go get git.clsr.net/util/ff2mpv-go` +- `ff2mpv-go --manifest > ~/.mozilla/native-messaging-hosts/ff2mpv.json` + +If `$GOBIN` is not in `$PATH`, specify the full path to the installed +executable (e.g. `$GOBIN/ff2mpv-go`) when running it. + +If a custom mpv command is required, manually clone the repository and edit the +`mpvCmd` variable in `ff2mpv.go`, then `go install` the package instead of the +`go get` step. + + +Usage +----- + +Use ff2mpv as normally. 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() +	} +} diff --git a/ff2mpv_386.go b/ff2mpv_386.go new file mode 100644 index 0000000..4e77e9a --- /dev/null +++ b/ff2mpv_386.go @@ -0,0 +1,5 @@ +package main + +import "encoding/binary" + +var endianness = binary.LittleEndian diff --git a/ff2mpv_amd64.go b/ff2mpv_amd64.go new file mode 100644 index 0000000..4e77e9a --- /dev/null +++ b/ff2mpv_amd64.go @@ -0,0 +1,5 @@ +package main + +import "encoding/binary" + +var endianness = binary.LittleEndian diff --git a/ff2mpv_arm.go b/ff2mpv_arm.go new file mode 100644 index 0000000..4e77e9a --- /dev/null +++ b/ff2mpv_arm.go @@ -0,0 +1,5 @@ +package main + +import "encoding/binary" + +var endianness = binary.LittleEndian diff --git a/ff2mpv_arm64.go b/ff2mpv_arm64.go new file mode 100644 index 0000000..4e77e9a --- /dev/null +++ b/ff2mpv_arm64.go @@ -0,0 +1,5 @@ +package main + +import "encoding/binary" + +var endianness = binary.LittleEndian @@ -0,0 +1 @@ +module git.clsr.net/util/ff2mpv-go  |