~rootmos/media

7b362dfa3c7f2a34614cf2bbdc0c2d2b3032b235 — Gustav Behm a month ago b324e07 + 648129c
Merge branch 'readme'
7 files changed, 150 insertions(+), 0 deletions(-)

A README.md
A doc/Makefile
A doc/README.in.md
A doc/README.md
A doc/include
A doc/player.py
A doc/viewer.py
A README.md => README.md +83 -0
@@ 0,0 1,83 @@
# media
[![builds.sr.ht status](https://builds.sr.ht/~rootmos/media.svg)](https://builds.sr.ht/~rootmos/media?)

My Python wrappers and around [feh](https://feh.finalrewind.org/) and [mpv](https://mpv.io/).

The package builds its own instances of forks of feh and mpv
([feh](https://git.sr.ht/~rootmos/feh), [mpv](https://git.sr.ht/~rootmos/mpv))
parametrizing the relevant [XDG directories](https://specifications.freedesktop.org/basedir-spec/latest/)
in order to obtain isolation from any already present configurations.

Other small features I've found useful are:
* [in mpv](https://git.sr.ht/~rootmos/mpv/commit/861b825ee9185b5b805886395b52f9170be6acda): expose wall-clock with nanosecond resolution
* [in feh](https://git.sr.ht/~rootmos/feh/commit/2ec742afe51a66669e71d0f20975f5196d29ca2b): add an alternative exit event (useful for breaking while loops: `while feh ...; do ...; end`)
* [in feh](https://git.sr.ht/~rootmos/feh/commit/f8a4cd7a0d998d7228cad9ff95b199f1f1880fdf): make feh play nice with Xmonad when viewing smaller images (maybe useful for other tiling window managers, but at least this solves it for me)

These wrappers primarily evolved from my inability to remember the flags when switching from `mplayer` to `mplayer2` to `mpv`.
My scheme being: one purposeful wrapper around whatever tool implements the functionality at the time:
`play`, `view` and [`edit`](https://git.sr.ht/~rootmos/dot-nvim).
So when fashions change, the implementation changes not the facade (hey I remember this from the [Gang of Four](https://en.wikipedia.org/wiki/Design_Patterns)).

The Python wrappers evolved to being capable of triggering callbacks in the Python host program.
The idea came from binding [feh's action keys](https://man.archlinux.org/man/feh.1#A) to use [socat](https://man.archlinux.org/man/socat1.1.en)
to sending back the trigger over a Unix socket.

## Examples
Following are two examples binding actions/keys in feh and mpv to Python callbacks.
These are [tested](.build.yml) ([results](https://builds.sr.ht/~rootmos/media))
using [xdotool](https://man.archlinux.org/man/xdotool.1)
and [Xvfb](https://man.archlinux.org/man/xvfb-run.1).

### Player
```python
import asyncio
import sys

from media.play import Player

sources = sys.argv[1:]

result = None
def sample_action(path, instance):
    global result
    result = True
    instance.terminate()

actions = [
    Player.Action(key="F1", f=sample_action),
]

async def amain():
    async with Player(mute=True).run(sources, actions) as i:
        rc = await i.wait()

asyncio.run(amain())
sys.exit(0 if result else 1)
```

### Viewer
```python
import asyncio
import sys

from media.view import Viewer

sources = sys.argv[1:]

result = None
def sample_action(path, instance):
    global result
    result = True
    instance.terminate()

actions = [
    Viewer.Action(number=1, f=sample_action),
]

async def amain():
    async with Viewer().run(sources, actions) as i:
        rc = await i.wait()

asyncio.run(amain())
sys.exit(0 if result else 1)
```

A doc/Makefile => doc/Makefile +2 -0
@@ 0,0 1,2 @@
README.md: README.in.md
	./include $< $@

A doc/README.in.md => doc/README.in.md +39 -0
@@ 0,0 1,39 @@
# media
[![builds.sr.ht status](https://builds.sr.ht/~rootmos/media.svg)](https://builds.sr.ht/~rootmos/media?)

My Python wrappers and around [feh](https://feh.finalrewind.org/) and [mpv](https://mpv.io/).

The package builds its own instances of forks of feh and mpv
([feh](https://git.sr.ht/~rootmos/feh), [mpv](https://git.sr.ht/~rootmos/mpv))
parametrizing the relevant [XDG directories](https://specifications.freedesktop.org/basedir-spec/latest/)
in order to obtain isolation from any already present configurations.

Other small features I've found useful are:
* [in mpv](https://git.sr.ht/~rootmos/mpv/commit/861b825ee9185b5b805886395b52f9170be6acda): expose wall-clock with nanosecond resolution
* [in feh](https://git.sr.ht/~rootmos/feh/commit/2ec742afe51a66669e71d0f20975f5196d29ca2b): add an alternative exit event (useful for breaking while loops: `while feh ...; do ...; end`)
* [in feh](https://git.sr.ht/~rootmos/feh/commit/f8a4cd7a0d998d7228cad9ff95b199f1f1880fdf): make feh play nice with Xmonad when viewing smaller images (maybe useful for other tiling window managers, but at least this solves it for me)

These wrappers primarily evolved from my inability to remember the flags when switching from `mplayer` to `mplayer2` to `mpv`.
My scheme being: one purposeful wrapper around whatever tool implements the functionality at the time:
`play`, `view` and [`edit`](https://git.sr.ht/~rootmos/dot-nvim).
So when fashions change, the implementation changes not the facade (hey I remember this from the [Gang of Four](https://en.wikipedia.org/wiki/Design_Patterns)).

The Python wrappers evolved to being capable of triggering callbacks in the Python host program.
The idea came from binding [feh's action keys](https://man.archlinux.org/man/feh.1#A) to use [socat](https://man.archlinux.org/man/socat1.1.en)
to sending back the trigger over a Unix socket.

## Examples
Following are two examples binding actions/keys in feh and mpv to Python callbacks.
These are [tested](.build.yml) ([results](https://builds.sr.ht/~rootmos/media))
using [xdotool](https://man.archlinux.org/man/xdotool.1)
and [Xvfb](https://man.archlinux.org/man/xvfb-run.1).

### Player
```python
@include "player.py"
```

### Viewer
```python
@include "viewer.py"
```

A doc/README.md => doc/README.md +1 -0
@@ 0,0 1,1 @@
../README.md
\ No newline at end of file

A doc/include => doc/include +23 -0
@@ 0,0 1,23 @@
# include
# 2024-11-05T21:56:53+01:00 SHA-256:5ba75751d3b08ec107418c906420f197de887430cbf7eaae0c300117b30b0608
# https://git.sr.ht/~rootmos/scripts f26dcdc3906f42721c86e2720fd02b7fcc6c4764
#!/bin/bash

set -o nounset -o pipefail -o errexit

INPUT=$1
OUTPUT=${2-/dev/stdout}

BASE_DIR=$(dirname "$INPUT")

TMP=$(mktemp)
trap 'rm -f $TMP' EXIT

awk '{
if(/^@include\s+"[^"]*"/) {
    rc = system(sprintf("cat %s/%s", "'"$BASE_DIR"'", $2))
    if(rc != 0) exit(rc)
} else {
    print($0)
} }' "$INPUT" > "$TMP"
cp "$TMP" "$OUTPUT"

A doc/player.py => doc/player.py +1 -0
@@ 0,0 1,1 @@
../tests/player.py
\ No newline at end of file

A doc/viewer.py => doc/viewer.py +1 -0
@@ 0,0 1,1 @@
../tests/viewer.py
\ No newline at end of file