mpvipc

package module
v0.0.0-...-abc9af4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 9, 2020 License: MIT Imports: 5 Imported by: 0

README

mpvipc

GoDoc Build Status MIT licensed

A Go implementation of mpv's IPC interface

Sample usage

  • Run mpv

    $ mpv some_file.mkv --input-unix-socket=/tmp/mpv_socket
    
  • Do things to it!

    package main
    
    import (
        "fmt"
        "log"
    
        "github.com/DexterLB/mpvipc"
    )
    
    func main() {
        conn := mpvipc.NewConnection("/tmp/mpv_rpc")
        err := conn.Open()
        if err != nil {
            log.Fatal(err)
        }
        defer conn.Close()
    
        events, stopListening := conn.NewEventListener()
    
        path, err := conn.Get("path")
        if err != nil {
            log.Fatal(err)
        }
        log.Printf("current file playing: %s", path)
    
        err = conn.Set("pause", true)
        if err != nil {
            log.Fatal(err)
        }
        log.Printf("paused!")
    
        _, err = conn.Call("observe_property", 42, "volume")
        if err != nil {
            fmt.Print(err)
        }
    
        go func() {
            conn.WaitUntilClosed()
            stopListening <- struct{}{}
        }()
    
        for event := range events {
            if event.ID == 42 {
                log.Printf("volume now is %f", event.Data.(float64))
            } else {
                log.Printf("received event: %s", event.Name)
            }
        }
    
        log.Printf("mpv closed socket")
    }
    

See more examples at the documentation.

All of mpv's functions and properties are listed here.

Documentation

Overview

Package mpvipc provides an interface for communicating with the mpv media player via it's JSON IPC interface

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CommandResult

type CommandResult struct {
	Status string      `json:"error"`
	Data   interface{} `json:"data"`
	ID     uint        `json:"request_id"`
}

type Connection

type Connection struct {
	// contains filtered or unexported fields
}

Connection represents a connection to a mpv IPC socket

func NewConnection

func NewConnection(socketName string) *Connection

NewConnection returns a Connection associated with the given unix socket

func (*Connection) Call

func (c *Connection) Call(arguments ...interface{}) (data interface{}, err error)

Call calls an arbitrary command and returns its result. For a list of possible functions, see https://mpv.io/manual/master/#commands and https://mpv.io/manual/master/#list-of-input-commands

Example
conn := NewConnection("/tmp/mpv_socket")

if err := conn.Open(); err != nil {
	log.Fatalln(err)
}
defer conn.Close()

// toggle play/pause
_, err := conn.Call("cycle", "pause")
if err != nil {
	log.Fatalln(err)
}

// increase volume by 5
_, err = conn.Call("add", "volume", 5)
if err != nil {
	log.Fatalln(err)
}

// decrease volume by 3, showing an osd message and progress bar
_, err = conn.Call("osd-msg-bar", "add", "volume", -3)
if err != nil {
	log.Fatalln(err)
}

// get mpv's version
version, err := conn.Call("get_version")
if err != nil {
	log.Fatalln(err)
}
fmt.Printf("version: %f\n", version.(float64))
Output:

func (*Connection) CallAsync

func (c *Connection) CallAsync(f func(v interface{}, err error), args ...interface{}) error

CallAsync does what Call does, but it does not block until there's a reply. If f is nil, then no reply is waited. f is called in the main loop, so it shouldn't do intensive work.

func (*Connection) Close

func (c *Connection) Close() error

Close closes the socket, disconnecting from mpv. It is safe to call Close() on an already closed connection.

func (*Connection) Get

func (c *Connection) Get(property string) (interface{}, error)

Get is a shortcut to Call("get_property", property)

Example
conn := NewConnection("/tmp/mpv_socket")

if err := conn.Open(); err != nil {
	log.Fatalln(err)
}
defer conn.Close()

// see if we're paused
paused, err := conn.Get("pause")
if err != nil {
	log.Fatalln(err)
}

if paused.(bool) {
	fmt.Printf("we're paused!\n")
} else {
	fmt.Printf("we're not paused.\n")
}

// see the current position in the file
elapsed, err := conn.Get("time-pos")
if err != nil {
	log.Fatalln(err)
}

fmt.Printf("seconds from start of video: %f\n", elapsed.(float64))
Output:

func (*Connection) IsClosed

func (c *Connection) IsClosed() bool

IsClosed returns true if the connection is closed. There are several cases in which a connection is closed:

1. Close() has been called

2. The connection has been initialised but Open() hasn't been called yet

3. The connection terminated because of an error, mpv exiting or crashing

It's ok to use IsClosed() to check if you need to reopen the connection before calling a command.

func (*Connection) ListenForEvents

func (c *Connection) ListenForEvents(onEvent func(*Event)) func()

ListenForEvents adds the given event callback into the listener set. The returned callback will return the channel when called. The given callback will be called in the main loop that listens for events, so any work should be distributed to another thread.

Example
conn := NewConnection("/tmp/mpv_socket")

if err := conn.Open(); err != nil {
	log.Fatalln(err)
}
defer conn.Close()

_, err := conn.Call("observe_property", 42, "volume")
if err != nil {
	log.Fatalln(err)
}

events := make(chan *Event, 1)
time5s := time.Tick(5 * time.Second)

cancel := conn.ListenForEvents(func(ev *Event) { events <- ev })
defer cancel()

for {
	select {
	case event := <-events:
		if event.ID == 42 {
			fmt.Printf("volume now is %f\n", event.Data.(float64))
		} else {
			fmt.Printf("received event: %s\n", event.Name)
		}
	case <-time5s:
		return
	}
}
Output:

func (*Connection) Open

func (c *Connection) Open() error

Open connects to the socket. Returns an error if already connected. It also starts listening to events, so ListenForEvents() can be called afterwards.

func (*Connection) Set

func (c *Connection) Set(property string, value interface{}) error

Set is a shortcut to Call("set_property", property, value)

Example
conn := NewConnection("/tmp/mpv_socket")
if err := conn.Open(); err != nil {
	log.Fatalln(err)
}
defer conn.Close()

// pause playback
if err := conn.Set("pause", true); err != nil {
	log.Fatalln(err)
}

// seek to the middle of file
if err := conn.Set("percent-pos", 50); err != nil {
	log.Fatalln(err)
}
Output:

func (*Connection) SetAsync

func (c *Connection) SetAsync(property string, value interface{}, f func(error)) error

SetAsync sets the property asynchronously. The returned error will only cover sending. f is optional; if it is not nil, then it'll be called afterwards.

type Event

type Event struct {
	// Name is the only obligatory field: the name of the event
	Name string `json:"event"`

	// Reason is the reason for the event: currently used for the "end-file"
	// event. When Name is "end-file", possible values of Reason are: "eof",
	// "stop", "quit", "error", "redirect", "unknown"
	Reason string `json:"reason"`

	// Prefix is the log-message prefix (only if Name is "log-message")
	Prefix string `json:"prefix"`

	// Level is the loglevel for a log-message (only if Name is "log-message")
	Level string `json:"level"`

	// Text is the text of a log-message (only if Name is "log-message")
	Text string `json:"text"`

	// ID is the user-set property ID (on events triggered by observed
	// properties)
	ID uint `json:"id"`

	// Data is the property value (on events triggered by observed properties)
	Data interface{} `json:"data"`

	// Error is present if Reason is "error."
	Error string `json:"error"`
}

Event represents an event received from mpv. For a list of all possible events, see https://mpv.io/manual/master/#list-of-events

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL