Library Conversion
Disc and cartridge images can be converted between formats with rom-converto, in two ways:
- Library conversion rewrites the files in your library to one storage format per platform, such as CHD for PlayStation or RVZ for GameCube, to save disk space.
- Download conversion leaves the library alone and converts a single download to a format the client asks for, for a handheld or emulator that can't read the stored one.
Enabling rom-converto
Set ROM_CONVERTO_ENABLED=true and restart the container. The CLI is probed on first use and its version logged. If the probe fails, a warning is logged and conversion stays off until the next restart.
| Variable | Default | Description |
|---|---|---|
ROM_CONVERTO_ENABLED |
false |
Enable the Convert library task and ?format= download conversions |
ROM_CONVERTO_TIMEOUT |
600 |
Seconds each rom-converto operation may run |
ROM_CONVERTO_MAX_CONCURRENCY |
2 |
Concurrent conversions per web or task worker |
With it enabled, scans also use the CLI to read title IDs and serials from the files of supported platforms (3DS, DS, PSP, PS Vita, PlayStation, PS2, PS3, GameCube, Wii, Wii U, Switch, Switch 2, Xbox and Xbox 360), which you can turn off with converto.scan_metadata.
Configuration
Admins set these options on the Conversion settings page, which writes them to the converto section of config.yml. You can also edit that section by hand:
converto:
download_conversion_enabled: true
platform_formats:
psx: chd
ps2: chd
ngc: rvz
wii: rvz
switch: nsz
| Key | Default | Description |
|---|---|---|
download_conversion_enabled |
false |
Offer converted downloads through ?format= |
platform_formats |
{} |
Library format per platform slug, used by the Convert library task. A platform left out is never converted. |
cache_max_size_gb |
20 |
Size cap of the converted download cache, in GB. 0 leaves it unbounded. |
cache_ttl_hours |
24 |
Hours a converted download stays cached after it was last served (at least 1) |
scan_metadata |
true |
Read title IDs with rom-converto during scans |
cache_ttl_hours and scan_metadata are only set in config.yml, and the settings page keeps whatever value they have there. An invalid value in this section stops RomM from starting, with an Invalid config.yml: converto... log line. For platform_formats, that's a platform rom-converto can't store or a format that isn't one of its library formats, and the log line lists the valid options.
Library formats
Only lossless conversions are offered as library formats, so a converted game holds the same data as the original:
| Platform | Slug | Library formats |
|---|---|---|
| Nintendo 3DS | 3ds |
z3ds, cia, cci |
| PlayStation Portable | psp |
chd, cso, zso, iso |
| PlayStation 2 | ps2 |
chd, cso, zso, iso |
| PlayStation, Saturn, Sega CD, Dreamcast | psx, saturn, segacd, dc |
chd |
| GameCube | ngc |
rvz, iso |
| Wii | wii |
rvz, iso, wbfs |
| Switch, Switch 2 | switch, switch-2 |
nsz, xcz, nsp, xci |
| Xbox 360 | xbox360 |
zar |
Each format accepts its own source files: CHD is made from .cue sheets or .iso images (and for PSP and PS2 also from .cso, .zso and .dax), RVZ from GameCube .iso, .gcm, .gcz and NKit images or Wii .iso, .wbfs, .wia, .gcz and NKit images, and NSZ from .nsp. A file with no route to the chosen format is counted as unsupported and left alone. The iso, cia, cci, nsp, xci and wbfs targets are uncompressed, so converting to one of them can grow your library rather than shrink it.
The Convert library task
Convert library is a manual task that converts every game on a platform with a library format, in place:
- Only matched games are converted, and unidentified ones are skipped because a converted file no longer hash-matches a DAT, so match them first.
- Games keep their identity: the database entry is updated to point at the new file, so saves, states, collections, notes and play history carry over. In a multi-file game, the
.m3uplaylists beside the files are rewritten to the new names. - Originals are deleted once their conversion succeeds and the game points at the new file. A conversion that fails, or whose output name is already taken, keeps the original.
- A
.cuesheet converts with its.bintracks, which are deleted along with it. A cue that shares tracks with another cue, or references a file outside its folder, is refused.
Because it deletes files, the task is flagged as destructive, and the UI asks you to type a confirmation before it runs. It's also single-instance, so asking to run it again while it's queued or running returns 409 Conflict. A full run can take hours on a large library, bounded per file by ROM_CONVERTO_TIMEOUT. When it finishes, the task reports how many files it converted, skipped as already converted, unmatched or unsupported, and failed, and how many bytes it saved.
Back up your library before the first run!
Download conversion
With download_conversion_enabled on, a client can ask for a single-file download in another format by adding ?format= to the download URL, with a comma-separated list of formats it can read in order of preference:
The response is one of:
| Response | When |
|---|---|
200 with the stored file |
The stored file is already in one of the listed formats |
200 with a converted copy |
A cached conversion exists, or a new one finishes within about 15 seconds |
202 with Retry-After: 30 |
A conversion is running. Repeat the request after the delay. |
406 Not Acceptable |
No listed format can be produced, the request covers more than one file, or conversion is off |
HEAD on the same URL reports the same outcome without starting a conversion. A conversion started by a download keeps running when the client stops waiting, and its result lands in the cache for the next request.
Any format rom-converto can reach from the stored file is allowed here, lossy ones included. DetailedRomSchema.download_formats lists the formats the caller can request for a game, which is empty for multi-file games, when conversion is off, and for callers who can't start a conversion. Only signed-in users can start one, so visitors in kiosk mode or on an unauthenticated download endpoint (DISABLE_DOWNLOAD_ENDPOINT_AUTH) get a cached copy or a 406. The web UI offers the same list as "Download as" on a game page.
The conversion cache
Converted downloads are cached in /romm/cache/converts. A copy expires cache_ttl_hours after it was last served, and when the cache would grow past cache_max_size_gb, the least recently served copies are evicted first. The Scheduled conversion cache cleanup task removes expired copies every day at 04:00. A conversion that failed is remembered, so it isn't retried on every request until its cache entry expires.
API
| Method | Path | Description |
|---|---|---|
PUT |
/api/config/converto_settings |
Replace download_conversion_enabled, cache_max_size_gb and platform_formats (needs platforms.write) |
GET |
/api/config |
CONVERTO holds the current settings, and CONVERTO_LIBRARY_TARGETS the library formats per platform |
GET |
/api/heartbeat |
CONVERTO reports whether rom-converto is enabled and available |
POST |
/api/tasks/run/convert_library |
Run the Convert library task (needs tasks.run) |
GET, HEAD |
/api/roms/{id}/content/{file_name}?format= |
Download in a requested format |