# MetaMesh Plugin: OpenSubtitles A MetaMesh plugin that **fetches** subtitle sidecars from [OpenSubtitles](https://www.opensubtitles.com) (REST API v1) and links them to videos. This is the network-download counterpart to `subtitle-extractor`, which only pulls subtitles already embedded in the media file. ## Description For each video, the plugin: 1. Computes the OpenSubtitles **moviehash** (size + first/last 64 KiB, read over WebDAV) for exact-match accuracy. 2. Searches `/subtitles` by `moviehash` + `imdb_id`/`tmdb_id` (+ season/episode for TV), falling back to a title/year query only when no structured identifier is available. 3. Picks the single best subtitle per wanted language (exact moviehash match first, then popularity). 4. Logs in (JWT) and downloads each chosen file, writes it via WebDAV to `/files/plugin/opensubtitles/`, and registers the resulting CID on the video. **Note**: Runs on the **background** queue (external API calls, download quota). Depends on `tmdb` so `imdbid`/`tmdbid` are populated before it runs. ## Metadata Fields (written on the video record) | Field | Format | Description | |-------|--------|-------------| | `subtitles` | csv-set of `cid` | Fetched subtitle file CIDs (external/sidecar provenance, per METADATA_KEYS.md §8) | | `subtitleLanguages` | csv-set of `lang3` | Denormalized union of available subtitle languages | | `languages/` | key-set | Adds the subtitle language to the file's language set (§9) | Each downloaded subtitle is itself indexed as a first-class record under its own `midhash256` CID — only the CID is stored on the video, never a path. > **Migration note:** `subtitles` / `subtitleLanguages` are written as legacy > `csv-set` via `addToSet` to stay compatible with current consumers. They are > slated to migrate to `key-set` (METADATA_KEYS.md §14.12) in lockstep with the > other subtitle writers (`subtitle`, `subtitle-extractor`). ## Dependencies - Requires `file-info`, `filename-parser`, and `tmdb` (for `imdbid`/`tmdbid`). ## Configuration Set at runtime via the meta-sort REST API (never in `plugins.yml`): ```bash curl -k -X PUT https://metasort-dev.localhost:8180/api/plugins/opensubtitles/config \ -H "Content-Type: application/json" \ -d '{"apiKey":"YOUR_API_KEY","username":"YOUR_USER","password":"YOUR_PASS","languages":"en,fr"}' ``` | Field | Type | Required | Description | |-------|------|----------|-------------| | `apiKey` | string | Yes | OpenSubtitles API key (Consumer key from your account) | | `username` | string | For downloads | OpenSubtitles account username | | `password` | string | For downloads | OpenSubtitles account password | | `languages` | string | No | CSV of ISO 639-1 codes (default `en`) | | `userAgent` | string | No | User-Agent registered with OpenSubtitles | | `forceRecompute` | boolean | No | Re-fetch even if subs already present | > The API key alone permits **search**; **downloading** requires a logged-in > account (username + password → JWT). The free tier has a small daily download > quota — the plugin stops early and reports when quota is exhausted. ## API Endpoints | Endpoint | Method | Description | |----------|--------|-------------| | `/health` | GET | Health check | | `/manifest` | GET | Plugin manifest | | `/configure` | POST | Update configuration | | `/process` | POST | Process a file | ## Docker ```bash # From the plugin directory docker build -t metamesh-plugin-opensubtitles:main . ``` ## Environment Variables | Variable | Default | Description | |----------|---------|-------------| | `PORT` | `8080` | HTTP server port | | `WEBDAV_URL` | — | meta-sort WebDAV base (provided by the orchestrator) | | `CACHE_DIR` | `/cache` | Plugin cache mount | ## License MIT