# `pyffstream`
A Python library to ease processing of video frames.
`pyffstream` is mostly a wrapper around external [FFmpeg][] processes (via
[`ffmpeg-python`][]) intended to be used with [OpenCV][].
[FFmpeg]: https://ffmpeg.org
[`ffmpeg-python`]: https://github.com/kkroening/ffmpeg-python
[OpenCV]: https://opencv.org
## Usage
`pyffstream` provides your application with a command line interface (CLI) and
handles reading and writing video files (with the original audio intact),
filtering the frames through a callback that you define. The API consists
mainly of the single function
```python
run(description, process, init=None, args_pre=None, args_post=None)
```
that takes the application description to present in the CLI and some
callbacks, all but one being optional:
- `process(args, state, frame, frame_num)`:
Takes:
- `args`: [`argparse.Namespace`][] containing parsed command line
arguments.
- `state`: arbitrary object returned by `init` (see below).
- `frame`: [`numpy.array`][] with shape
`(args.working_width, args.working_height, 3)` containing RGB data to
be processed.
- `frame_num`: integer in the range [`args.frame_start`,
`args.frame_end`) representing the number of the current frame.
Returns:
- `output_frame`: [`numpy.array`][] with shape
`(args.output_width, args.output_height, 3)` containing RGB output.
- `debug_frame`: [`numpy.array`][] with shape
`(args.working_width, args.working_height, 3)` containing RGB debug
output.
- `init(args)`:
Takes:
- `args`: [`argparse.Namespace`][] containing parsed command line
arguments.
Returns:
- `state`: arbitrary object passed to `process` (see above).
- `args_pre(parser)`, `args_post(parser)`:
Takes:
- `args`: [`argparse.ArgumentParser`][] before (for `args_pre`) or after
(for `args_post`) being filled with `pyffstream` arguments.
Returns nothing.
A number of hepler functions are also supplied:
- `resize(image, width, height, resample)`: wrapper around
[`PIL.Image.resize`][].
- `text(image, text, x, y, thickness, font=cv2.FONT_HERSHEY_SIMPLEX)`:
wrapper around [`cv2.putText`][] that automatically adjusts text placement
and scaling.
- `fix_rect(args, x, y, w, h)`: forces a rectangle to aspect ratio
`args.output_aspect` and to be inside `(0, 0, args.working_width,
args.working_height)`.
[`argparse.Namespace`]: https://docs.python.org/3/library/argparse.html#argparse.Namespace
[`argparse.ArgumentParser`]: https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser
[`numpy.array`]: https://numpy.org/doc/stable/reference/generated/numpy.array.html
[`PIL.Image.resize`]: https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.resize
[`cv2.putText`]: https://docs.opencv.org/master/d6/d6e/group__imgproc__draw.html#ga5126f47f883d730f633d74f07456c576
### Examples
Projects using `pyffstream`:
- [`autozoom`][]: Automatically zoom in on video content of interest.
[`autozoom`]: https://git.rcrnstn.net/rcrnstn/autozoom
## Installation
### With `pip`
```sh
python3 -m pip install git+https://git.rcrnstn.net/rcrnstn/pyffstream
```
### In `setuptools` `setup.py`
```python
from setuptools import setup
setup(
# ...
install_requires=[
'pyffstream @ git+https://git.rcrnstn.net/rcrnstn/pyffstream',
],
# ...
)
```
## License
Licensed under the [ISC license][], see the [`LICENSE`](LICENSE) file.
[ISC license]: https://en.wikipedia.org/wiki/ISC_license