Files
oembed-graphics/README.md
Aiden Wilson bba1ab5cee
All checks were successful
Build & Push Docker (latest) / verify (push) Successful in 9m29s
Build & Push Docker (latest) / build (push) Successful in 8s
Caspar Template
2026-05-29 22:51:32 +10:00

105 lines
3.4 KiB
Markdown

# oembed-graphics
Docker-hosted oEmbed graphics for broadcast workflows. It is inspired by
[webrecorder/oembed.link](https://github.com/webrecorder/oembed.link), but runs
as a normal container and exposes graphic URLs that can be loaded by CasparCG,
OBS Browser Source, OGraf, or any HTML-capable character generator.
## Run locally
```sh
npm install
npm start
```
Open `http://localhost:3000`.
## Run with Docker
```sh
docker compose up --build
```
The service listens on `http://localhost:3000`.
## Broadcast URL
Use `/graphic` with a source URL:
```txt
http://localhost:3000/graphic?url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DdQw4w9WgXcQ&width=1920&height=1080&transparent=1
```
Useful query parameters:
- `url`: required source URL to resolve through oEmbed.
- `width`: stage width, default `1920`.
- `height`: stage height, default `1080`.
- `transparent`: `1` for transparent output, default `1`.
- `chroma`: background color when transparent output is disabled, default `#00ff00`.
- `fit`: `contain` or `cover`, default `contain`.
- `scale`: graphic scale multiplier, default `1`.
- `wait`: `1` to keep the graphic hidden until embed media loads, default `1`.
- `readyDelay`: extra milliseconds to wait after media load before reveal, default `1000`.
- `maxWait`: safety timeout before reveal, default `10000`.
- `autoplay`: `1` to request autoplay for iframe and video embeds, default `1`.
- `muted`: `1` to mute embeds, default `1`. Most browsers require this for autoplay.
- `maxwidth`: sent to the oEmbed provider and capped at `500`, default `500`.
- `maxheight`: sent to the oEmbed provider, default `480`.
Autoplay is best-effort for social embeds. The graphic page keeps the original
social post HTML, adds provider autoplay parameters where possible, and runs a
small assist script that calls `play()` on any video element it can access.
Browsers still block scripts from controlling video inside cross-origin iframes,
which includes Twitter/X widget frames. For broadcast runtimes based on Chromium
or CEF, also allow autoplay at the browser layer when possible, for example with
`--autoplay-policy=no-user-gesture-required`.
The renderer caps every social card at `500px` wide so different providers line
up more consistently on a broadcast canvas. It still uses the oEmbed response's
height when present.
The service also supports the oembed.link-style form:
```txt
http://localhost:3000/https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DdQw4w9WgXcQ
```
## CasparCG template
Load `/caspar` as the browser template URL. It starts transparent and blank, then
renders when CasparCG sends `UPDATE` data.
Example template URL:
```txt
http://localhost:3000/caspar
```
Example JSON update payload:
```json
{
"url": "https://bsky.app/profile/bsky.app/post/3k...",
"width": 1920,
"height": 1080,
"scale": 1,
"transparent": true
}
```
The template also accepts a raw URL string or standard CasparCG XML
`templateData` with component ids such as `url`, `scale`, `fit`, `autoplay`,
`muted`, `readyDelay`, and `maxWait`.
## API
- `GET /api/oembed?url=...` returns the matched provider and raw oEmbed data.
- `GET /caspar` returns the CasparCG update-driven HTML template.
- `GET /providers` returns the loaded provider patterns.
- `GET /healthz` returns a health check response.
Provider data is loaded from `https://oembed.com/providers.json` and cached in
memory. Override with `PROVIDERS_URL`, `PROVIDERS_TTL_MS`, and
`OEMBED_TIMEOUT_MS` environment variables.