Clip transcoding: ffmpeg in the backend image, panel recipe in the node docs
This commit is contained in:
@@ -110,6 +110,49 @@ ring and streams bytes to connected screens. New frames eventually replace
|
||||
old ones. A volatile artifact returned as a run result is copied to persistent
|
||||
storage; emitted frames alone are not recorded as run artifacts.
|
||||
|
||||
### Making clips playable on an LVGL panel
|
||||
|
||||
A wall panel that renders dashboards natively, such as an ESP32-P4 running
|
||||
openpanel, decodes only H.264 Constrained Baseline (in software, about 29 fps
|
||||
at 640×360) and MJPEG. It refuses clips straight from a phone or camera, which
|
||||
are usually Main or High profile at 1080p or more. Re-encode those with a node
|
||||
that takes a `video` input port `clip` and has a `video` output port
|
||||
`panel_clip`:
|
||||
|
||||
```python
|
||||
import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
import fluksio
|
||||
|
||||
# H.264 Constrained Baseline, at most 640x360 and 15 fps, mono AAC.
|
||||
PANEL = [
|
||||
"-c:v", "libx264", "-profile:v", "baseline", "-level:v", "3.1",
|
||||
"-pix_fmt", "yuv420p", "-fpsmax", "15",
|
||||
"-vf", "scale=w=640:h=360:force_original_aspect_ratio=decrease:force_divisible_by=2",
|
||||
"-preset", "veryfast", "-crf", "23", "-g", "30",
|
||||
"-c:a", "aac", "-ac", "1", "-b:a", "64k", "-movflags", "+faststart",
|
||||
]
|
||||
|
||||
|
||||
def process(clip):
|
||||
source = fluksio.load_artifact(clip)
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
target = os.path.join(tmp, "panel.mp4")
|
||||
subprocess.run(
|
||||
["ffmpeg", "-nostdin", "-loglevel", "error", "-i", source, *PANEL, target],
|
||||
check=True,
|
||||
timeout=600,
|
||||
)
|
||||
name = os.path.splitext(clip.get("name") or "clip")[0] + "-panel.mp4"
|
||||
return {"panel_clip": fluksio.save_artifact(target, name, "video/mp4")}
|
||||
```
|
||||
|
||||
Use it only for clips headed for such a panel. Browsers play the originals,
|
||||
and the result plays there too, just smaller. The Docker image ships `ffmpeg`;
|
||||
a [remote worker](workers.md) needs it on its `PATH`.
|
||||
|
||||
## Printing
|
||||
|
||||
`print` and `fluksio.logger.info(...)` are captured in the node logs. The
|
||||
|
||||
Reference in New Issue
Block a user