Updated docs
This commit is contained in:
@@ -1,77 +1,92 @@
|
|||||||
# mediapreview
|
# mediapreview
|
||||||
|
|
||||||
Low-level media preview converters plus an optional persistent worker pool
|
Generate compact AVIF preview images from images, videos, PDFs and office documents.
|
||||||
framework. All converters produce AVIF output.
|
|
||||||
|
|
||||||
## Layout
|
`mediapreview` is a small library of low-level converters. Give it a file path and
|
||||||
|
it returns AVIF bytes plus a response object telling you which backend handled it
|
||||||
|
and whether it succeeded.
|
||||||
|
|
||||||
| Module | Purpose |
|
## Install
|
||||||
|--------|---------|
|
|
||||||
| `mediapreview.backends.image` | Image → AVIF via pyvips (ffmpeg for HEIC/HEIF/AVIF) |
|
|
||||||
| `mediapreview.backends.video` | Video frame → AVIF via PyAV (HDR preserved) |
|
|
||||||
| `mediapreview.backends.pdf` | PDF/XPS/EPUB page → AVIF via PyMuPDF + pyvips |
|
|
||||||
| `mediapreview.backends` | `dispatch()` — pick a backend by path/mimetype |
|
|
||||||
| `mediapreview.formats` | Suffix sets, previewability and priority classification |
|
|
||||||
| `mediapreview.office` | OnlyOffice Document Server client + Docker bootstrap |
|
|
||||||
| `mediapreview.docker/` | Patched OnlyOffice image build context (ships in the wheel) |
|
|
||||||
| `mediapreview.pool` | Async persistent subprocess worker pool (optional) |
|
|
||||||
| `mediapreview.worker` | Worker subprocess entry point (framed stdin/stdout protocol) |
|
|
||||||
| `mediapreview.protocol` | msgspec wire structs (`PreviewRequest` / `PreviewResponse`) |
|
|
||||||
| `mediapreview.cache` | Thread-safe LRU cache for preview responses |
|
|
||||||
|
|
||||||
## Extras
|
```sh
|
||||||
|
uv add mediapreview[standard]
|
||||||
```bash
|
|
||||||
pip install mediapreview # image converter only (pyvips)
|
|
||||||
pip install mediapreview[pdf] # + PDF/XPS/EPUB (pymupdf)
|
|
||||||
pip install mediapreview[video] # + video (av, numpy)
|
|
||||||
pip install mediapreview[office] # + OnlyOffice client (httpx, pyjwt)
|
|
||||||
pip install mediapreview[worker] # + worker pool (blake3, tracerite)
|
|
||||||
pip install mediapreview[standard] # everything
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
`[standard]` pulls in every backend and the optional worker pool. Use the feature-specific extras to avoid dependencies not needed for your application.
|
||||||
|
|
||||||
Low-level, in-process:
|
## Quick start
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
from pathlib import Path
|
||||||
from mediapreview import dispatch
|
from mediapreview import dispatch
|
||||||
|
|
||||||
avif_bytes, resp = dispatch(path, quality=60, maxsize=512, maxzoom=2.0)
|
avif_bytes, resp = dispatch(
|
||||||
|
Path("photo.jpg"),
|
||||||
|
quality=60,
|
||||||
|
maxsize=512,
|
||||||
|
maxzoom=2.0,
|
||||||
|
)
|
||||||
|
|
||||||
|
if resp.ok:
|
||||||
|
Path("preview.avif").write_bytes(avif_bytes)
|
||||||
|
else:
|
||||||
|
print(resp.error)
|
||||||
```
|
```
|
||||||
|
|
||||||
Worker pool (isolates heavy imports and native crashes from the async loop):
|
`dispatch` picks the backend from the file extension or mimetype. You can also
|
||||||
|
call the backend functions directly:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from mediapreview.pool import start_preview_workers, shutdown_preview_workers
|
from mediapreview import process_image, process_pdf, process_video
|
||||||
|
|
||||||
|
avif, resp = process_image(Path("photo.jpg"), maxsize=512, quality=60)
|
||||||
|
avif, resp = process_pdf(Path("doc.pdf"), maxsize=512, quality=60, page_number=0)
|
||||||
|
avif, resp = process_video(Path("clip.mp4"), maxsize=512, quality=60)
|
||||||
```
|
```
|
||||||
|
|
||||||
One-shot CLI (works with the base install, no worker extra needed):
|
## Worker pool (optional)
|
||||||
|
|
||||||
|
Heavy native dependencies and crashes stay out of your async loop by running
|
||||||
|
previews in a pool of persistent subprocess workers.
|
||||||
|
|
||||||
|
```python
|
||||||
|
from mediapreview.pool import (
|
||||||
|
start_preview_workers,
|
||||||
|
shutdown_preview_workers,
|
||||||
|
run_preview,
|
||||||
|
)
|
||||||
|
|
||||||
|
await start_preview_workers()
|
||||||
|
try:
|
||||||
|
avif, resp = await run_preview(Path("doc.pdf"))
|
||||||
|
finally:
|
||||||
|
await shutdown_preview_workers()
|
||||||
|
```
|
||||||
|
|
||||||
|
Add the `worker` extra to use the pool.
|
||||||
|
|
||||||
|
## CLI
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mediapreview photo.jpg -o preview.avif # or: python -m mediapreview ...
|
mediapreview photo.jpg -o preview.avif
|
||||||
mediapreview doc.pdf -q 70 --maxsize 1024 # needs the matching backend extra
|
mediapreview doc.pdf -q 70 --maxsize 1024
|
||||||
|
mediapreview oosetup # build + run the bundled OnlyOffice container
|
||||||
```
|
```
|
||||||
|
|
||||||
## OnlyOffice Docker bootstrap
|
## OnlyOffice setup
|
||||||
|
|
||||||
A patched OnlyOffice image (configurable converter worker count) ships as
|
Office previews need an OnlyOffice Document Server. A patched Docker image ships
|
||||||
package data and can be built/started with:
|
inside the package and can be started with:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mediapreview oosetup # builds + runs "onlyoffice-mediapreview" on port 8988
|
mediapreview oosetup [name] [port]
|
||||||
```
|
```
|
||||||
|
|
||||||
Container name and port are optional positional args:
|
`oosetup` logs to stderr and prints one line on stdout:
|
||||||
`mediapreview oosetup [name] [port]`.
|
|
||||||
|
|
||||||
`oosetup` logs progress to stderr and prints exactly one line on stdout:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
ONLYOFFICE_JWT_SECRET=<token>
|
ONLYOFFICE_JWT_SECRET=<token>
|
||||||
```
|
```
|
||||||
|
|
||||||
If `ONLYOFFICE_JWT_SECRET` is already set in the environment it is used as-is
|
Set `ONLYOFFICE_JWT_SECRET` yourself to reuse an existing secret; otherwise a
|
||||||
(and echoed back); otherwise a random secret is generated. Persist the token
|
random one is generated.
|
||||||
wherever your deployment keeps its configuration and export it for later runs
|
|
||||||
— the caller owns the secret, mediapreview does not store it.
|
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
|
|||||||
[project]
|
[project]
|
||||||
name = "mediapreview"
|
name = "mediapreview"
|
||||||
dynamic = ["version"]
|
dynamic = ["version"]
|
||||||
description = "Low-level media preview converters and a worker pool framework"
|
description = "Fast media preview images of photos, videos, PDFs and office documents."
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.11"
|
requires-python = ">=3.11"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
|||||||
Reference in New Issue
Block a user