Repository navigation
Releases: Cinomni/cinomni
Release list
Cinomni 0.1.0-alpha.4
A tunnel that is actually up, a title you can place, and profile 5 no longer painted the wrong colour.
A healthy WireGuard tunnel is accepted. A film is downloaded only when the release is that film. You
can move a title onto a shelf from the console, and release the pin. Dolby Vision profile 5 is no
longer given the HDR10 curve. Still an alpha: read Versioning for what that promises.
Known gaps in this alpha:
- A 4K HDR source that has to be converted on the CPU still does not play at the default limits. It
stops after a minute and says which setting to change. - The VPN drop drill has not been run. One Intel Arc A380 passed the startup hardware test (VAAPI
H.264 encode, HEVC encode, and decode). That is not a substitute for the drill in DEPLOYMENT.md on
your own installation. - Dolby Vision profile 5 is not given the HDR10 curve, and this image still cannot interpret that
colour. A conversion does not claim the colours are fixed.
Added
- A WireGuard peer you bring yourself.
VPN_SERVICE_PROVIDER=customnow forwards
WIREGUARD_PUBLIC_KEY,WIREGUARD_ENDPOINT_IPandWIREGUARD_ENDPOINT_PORTfrom.env. The
endpoint must be an IP. Leave them empty for a provider on gluetun's list. The private key stays
in.envand is not a setting. - Move one title, or release its pin, from the console. Console → Collections → Place a title
searches the library (or lists the titles already pinned), moves a title onto a shelf — which pins
it, so rules leave it there — and releases a pin so the rules place it again. The confirmation
warns when the move would let more people see the title, or hide it from people who can see it now.
Until now both actions existed only as API calls.
Fixed
- A healthy WireGuard tunnel is no longer refused. The kill-switch read only the main routing
table. A WireGuard tunnel leaves that default on the underlay so its own handshake can still
leave, and installs the route ordinary packets use in another table. Gluetun does this. The
sidecar reporteddefault-route-not-via-tunneland, underblock, refused to start. The check
is now the kernel's own lookup, the oneip route getperforms. A missing device, a lookup that
cannot be taken, a reply for a different address, and a household source address are still not
healthy. - Dolby Vision profile 5 is no longer tone-mapped with the HDR10 curve. That curve treats the
picture as PQ in a standard colour space, which is what painted a profile 5 file green or purple:
profile 5 has no HDR10 base layer, and this image's FFmpeg cannot interpret its colour. A conversion
of a file whose profile was read as 5 does not apply the curve, and the plan says so. Profiles 7 and
8 still tone-map from their HDR10 base layer. A Dolby Vision file whose profile could not be read is
still tone-mapped as HDR10. - A film is downloaded only when the release is that film. A film's releases were judged on
quality, size and format alone. An indexer that searches by text answers with anything carrying the
words, so a search for "Teddy" (2021) accepted a 2160p Teddy Swims concert, which was downloaded and
filed as the film, and series episodes with "Teddy" in their titles. A film release now needs the
catalog's title and, when it states a year, the catalog's year exactly: the same search offered the
French "Teddy" (2020) for the Tamil one. A release numbered as an episode is never a film. Each
rejection shows what was compared. A film whose releases use another name, such as its
original-language title, or another year, is now rejected; Download anyway still takes it by
hand. Files already in the library are not checked again.
Upgrade notes
Take a backup first, as for any upgrade. Nothing else needs doing by hand: the migrations run on start.
docker compose pull && docker compose up -dis what picks up the new sidecar. The published
0.1.0-alpha.3sidecar still refuses a policy-routed WireGuard tunnel.- If
.envsetsCINOMNI_IMAGE_TAG, change it to0.1.0-alpha.4before that pull. Unset, Compose
uses the default indocker-compose.yml, which this release moves.
Install or upgrade
Download docker-compose.yml and .env.example from this release, copy .env.example to
.env, set it up as DEPLOYMENT.md describes, and run:
docker compose pull
docker compose up -dTake a backup before upgrading an existing installation (DEPLOYMENT.md, Backup and restore).
| Image | Tag |
|---|---|
ghcr.io/cinomni/cinomni |
0.1.0-alpha.4 (0.1.0-alpha.4-hwaccel with VAAPI/QSV drivers) |
ghcr.io/cinomni/cinomni-torrent-sidecar |
0.1.0-alpha.4 |
ghcr.io/cinomni/cinomni-indexer-egress |
0.1.0-alpha.4 |
ghcr.io/cinomni/cinomni-flaresolverr |
0.1.0-alpha.4 |
Cinomni 0.1.0-alpha.3
Your own password, subtitles that fit, and a straight answer when a video is too heavy. An account
can change its password. Subtitles now download from OpenSubtitles, are checked to be for your title,
and are re-timed against the audio. A conversion the server cannot keep up with stops and says what to
change, instead of buffering. Still an alpha: read Versioning for what that promises.
Known gaps in this alpha:
- A 4K HDR source that has to be converted on the CPU still does not play at the default limits. It now
stops after a minute and says which setting to change (see Changed). - No real GPU and no real VPN tunnel drop have been tested (see Accepted risks in ROADMAP.md).
- Dolby Vision profile 5 tone-maps with wrong colours.
- Moving a single title to a collection by hand, or releasing its pin, has no console screen yet (the
API has both).
Added
- Change your own password. Your account → Password asks for the current password and the new one
twice. Changing it signs out every other device signed in to that account; the one you used stays
signed in. Until now only the database procedure in DEPLOYMENT.md could change a password. - Downloaded subtitles are checked against the audio and re-timed when they are off. A SubRip
or WebVTT subtitle is playable as soon as it lands; in the background, Cinomni then listens to
four-minute stretches at the start, middle and end of the video, works out how far the subtitle
is ahead or behind (up to a minute either way), and also detects a subtitle made for a 25 fps
release playing on a 23.976 fps one, or the reverse. When the start, middle and end agree and the
match is clear, it writes a corrected copy beside the original (<name>.<lang>.synced-<code>.srt) and
plays that. Otherwise it keeps the original and says why. The downloaded file is never changed.
On a title's page, under Subtitles, each subtitle shows the result ("Synced +1.24 s",
"Original kept: low confidence", and so on) with the reason. Administrators can Re-sync or
Revert to the downloaded file there. ASS subtitles and forced subtitles are not re-timed, and
subtitles you already have are not re-checked until you ask. It runs one subtitle at a time on its
own worker, so imports and downloads do not wait for it. It uses the FFmpeg configured for playback
(Playback__Ffmpeg__BinaryPath). If FFmpeg is missing or too slow, the subtitle stays as downloaded.
SetSubtitles__Sync__Enabled=falseto turn it off.
Changed
- A video too heavy for the server now says so instead of buffering for ever. A conversion that
stays slower than the video plays for a whole minute is ended, and the player says why and what an
administrator can change: the resolution settings, a hardware encoder, orCINOMNI_CPUS. A conversion
the system kills for running out of memory says so too, namingCINOMNI_MEMORY. - Conversions on the CPU are held to 1080p by default. A new setting, Console → Settings → Playback →
Software encoder maximum resolution, brings taller video down when no hardware encoder is used; set it
tooriginalfor the previous behaviour. A hardware encoder is not affected. - Slow starts no longer fail. Starting a conversion waits up to 20 seconds for its first segment,
instead of 5, before handing the stream to the player, so a heavy source no longer fails on a
playlist that did not exist yet.
Fixed
- Subtitles are downloaded from OpenSubtitles at all. Every search failed against the real API:
it answers anything but its own spelling of the search address with a redirect, which Cinomni does
not follow, and refuses a download that does not ask for JSON. Both are fixed. - The subtitle chosen is the one for your title. A candidate used to be scored only by its rating
on the provider, which is 0 for most files, so nothing was accepted. With the threshold lowered,
the first file returned won, and that was sometimes another film that only shared a word with the
release name. A candidate now has to match the title it is for: the same IMDb id, or the same title
and year for a film, and the same series and episode number for an episode. A subtitle for anything
else scores 0. Among the ones that match, the same release group, source and resolution as your
video ranks first, then downloads and trusted uploaders, and a machine translation ranks last. Films
are searched by IMDb id, or by title and year, instead of by release name. Each candidate keeps the
reason for its score.Subtitles__MinScorenow defaults to 40, which requires a matched identity. - A title that already carries a subtitle in your language is not searched again. The preference
names a language in two letters (en) and a video's own tracks are tagged in three (eng). Compared
literally they never matched, so every title was searched for a subtitle it already had, and the
download landed beside it. Only a text subtitle counts. A Blu-ray remux often carries a language only
as pictures (PGS or VobSub), which the player can show only by burning them into the video. That is a
full conversion, too slow for a 4K file on most servers. For such a language Cinomni downloads a text
subtitle, which plays without converting anything. - A subtitle in the wrong alphabet is passed over. A file labelled English but written in Hebrew
was downloaded as the English subtitle. A download is now checked against the alphabet of its
language, and up to three candidates are tried in order before the search waits for its next
attempt. - A converted title is no longer marked watched early. When the server had no runtime for a file,
the player reported the length of the converted stream so far as the film's length; catching up with
a slow conversion then marked the title watched a minute in, and the next play started from that wrong
length. The runtime now comes only from the server, or from the browser when it plays the file
directly; a converted stream with no known runtime records the position without marking anything. - The logs no longer grow without bound. The application wrote the SQL of every database command
atInformation, about 8 MB an hour on an idle installation, into a Docker log file nothing
rotated. It now leaves those out, and every service indocker-compose.ymland the VPN overlay
keeps at most three 10 MB log files. Recreate the containers (docker compose up -d) for the
rotation to apply; the logs already written stay until then.
Upgrade notes
Take a backup first, as for any upgrade. Nothing needs doing by hand: the migrations run on start.
docker compose pull && docker compose up -drecreates the containers, which is also what turns
the log rotation on.Subtitles__MinScorenow defaults to 40. If you set it yourself, a value under 40 accepts a
subtitle whose title could not be confirmed.- With SubDL configured, earlier versions could download a second subtitle for a language the video
already carried, and sometimes one for another title. Those files stay beside the video
(<name>.<lang>.srt); delete them by hand if you do not want them.
Install or upgrade
Download docker-compose.yml and .env.example from this release, copy .env.example to
.env, set it up as DEPLOYMENT.md describes, and run:
docker compose pull
docker compose up -dTake a backup before upgrading an existing installation (DEPLOYMENT.md, Backup and restore).
| Image | Tag |
|---|---|
ghcr.io/cinomni/cinomni |
0.1.0-alpha.3 (0.1.0-alpha.3-hwaccel with VAAPI/QSV drivers) |
ghcr.io/cinomni/cinomni-torrent-sidecar |
0.1.0-alpha.3 |
ghcr.io/cinomni/cinomni-indexer-egress |
0.1.0-alpha.3 |
ghcr.io/cinomni/cinomni-flaresolverr |
0.1.0-alpha.3 |
Cinomni 0.1.0-alpha.2
Collections that fill themselves. Titles can now be placed on collections by rules instead of
only by hand, and because a collection decides who can see a title, every change is previewed
before it is saved. Still an alpha: read Versioning for what that promises.
Known gaps in this alpha: the four listed under 0.1.0-alpha.1 still apply, and moving a single
title to a collection by hand, or releasing its pin, has no console screen yet (the API has both).
Added
- Rule-based collections. In Console → Collections, a collection can carry rules on
kind, genre, age rating, year, runtime, original language or title, and the collections are asked in
an order you set: the first rule that matches decides which shelf a title sits on, and therefore who
can see it. Every rule or order change can be previewed first, and the preview lists what would
move, including titles that would fall back to the open default collection. Titles are placed when
they are added and again when their metadata arrives. Saving is only possible after a preview, and
it warns when titles would leave a restricted collection for an open one. - New titles wait for their metadata while rules exist. A title added while any collection rule
exists is hidden from members until its metadata arrives, because until then the rules cannot see
its genres or age rating and it would otherwise sit on the open default collection. Administrators
see it with a notice; placing it by hand (through the API for now) also releases it. Titles added without a provider id are
not held, since nothing would ever release them.
Changed
- Moving a title to a collection by hand now pins it there. Rules leave a pinned title alone until
the pin is released.
Upgrade notes
Take a backup first, as for any upgrade. Nothing needs doing by hand: the migrations run on start.
- Titles that already sit outside the default collection are pinned by the upgrade, so saving the
first rule cannot move them and nobody gains or loses sight of anything. Existing collections are
asked in the order they were created.
Install or upgrade
Download docker-compose.yml and .env.example from this release, copy .env.example to
.env, set it up as DEPLOYMENT.md describes, and run:
docker compose pull
docker compose up -dTake a backup before upgrading an existing installation (DEPLOYMENT.md, Backup and restore).
| Image | Tag |
|---|---|
ghcr.io/cinomni/cinomni |
0.1.0-alpha.2 (0.1.0-alpha.2-hwaccel with VAAPI/QSV drivers) |
ghcr.io/cinomni/cinomni-torrent-sidecar |
0.1.0-alpha.2 |
ghcr.io/cinomni/cinomni-indexer-egress |
0.1.0-alpha.2 |
ghcr.io/cinomni/cinomni-flaresolverr |
0.1.0-alpha.2 |
Cinomni 0.1.0-alpha.1
The first public version, and an alpha. Everything the project has built so far, released for
people who run it knowingly: the movie and series flow works end to end and survives restarts, but
capabilities are still landing, there is no upgrade history yet, and the known gaps below are real.
Read Versioning for what an alpha does and does not promise.
Known gaps in this alpha:
- An account cannot change its password; recovering one needs the SQL in DEPLOYMENT.md.
- Transcoding a 4K HDR source on the CPU needs more than the default
CINOMNI_CPUS=4.0/
CINOMNI_MEMORY=2g; with the defaults, FFmpeg runs out of memory and playback stops. - No real GPU and no real VPN tunnel drop have been tested (see Accepted risks in ROADMAP.md).
- Dolby Vision profile 5 tone-maps with wrong colours.
Added
-
A player with real choices. The web player has its own controls (seek bar showing what is
buffered and how far a conversion has got, ±10 s, volume, speed, full screen, picture in picture)
and keyboard shortcuts. Viewers pick the audio track, the subtitles and a quality (1080p/720p/480p/
360p with a bitrate cap); audio and quality open a new stream from where they are, subtitles switch
in place. The tracks chosen are remembered per title. -
Subtitles in the browser. Text subtitles inside the file and the ones Cinomni fetched (SubRip,
ASS, WebVTT) are served as WebVTT and drawn by the player; an unmarked SubRip in Windows-1252 shows
its accents. Picture subtitles (PGS, VobSub) can be burned into the video, which always converts. -
Transcoding settings in the console. Console → Settings → Playback now holds the preferred
hardware backend, hardware decoding, the output codec (H.264, or HEVC when the device plays it and
the GPU encodes it), encoder speed and quality, a server-wide resolution and bitrate ceiling,
software threads, HDR tone mapping and its curve, audio channels and bitrate, and picture-subtitle
burn-in. Every key can also be pinned by environment variable (Playback__Transcoding__*). -
Hardware that is tested, not assumed. Each backend is tried with a real encode and decode at
startup (VAAPI, Quick Sync and NVENC on Linux, plus AMF on a host running natively on Windows), and
only what passes is used. The console shows every test and its failure, and Run hardware test
repeats it without a restart. -
HDR and Dolby Vision to SDR. A transcoded HDR10, HLG or Dolby Vision source is tone-mapped so it
no longer looks washed out; decode stays on the GPU where there is one. Dolby Vision profile 5 may
still show wrong colours. -
A conversion starts where you are. Resuming or seeking far into a transcoded film starts the
conversion there instead of waiting for it to catch up. The full timeline comes from the runtime
and bitrate Import now records for each file (migrationAddVersionRuntime, applied at startup);
a file imported earlier gets its runtime from the first time it is played. -
A content ceiling, per account and off by default. An administrator can hide titles above a
classification for one account. Unrated titles stay visible. Only US, ES, DE and GB have a ladder;
any other region cannot have a ceiling set. A ceiling does not survive a region change: it stops
applying, and the account page says so, rather than enforcing the old certificate under the new
rules. Administrators are not filtered. -
Declarative indexer login. A definition that declares a
session.loginblock now signs in with
the indexer's stored credential, keeps the session, and notices when the site expires it. The
indexer listing reports whether a login is declared, whether a session is held, and when it was
captured; testing an indexer reports whether the test searched authenticated. -
A build identity.
GET /api/system/inforeports the version, the commit and the build date, and
the web client shows them. A build that was not stamped says so rather than guessing (see
Which build am I running? in DEPLOYMENT.md). -
Indexer catalog sources. Cinomni ships no list of sites. The catalog in the console is empty
until you add a catalog source: a name and an https URL you choose, publishing a JSON manifest of
indexer definitions in Cinomni's own format (docs/indexer-catalog-format.md).
Cinomni fetches it when you add it and whenever you press Refresh, keeps the last valid manifest so
the catalog survives a restart or the source being down, and shows why a refresh failed. A manifest
with any invalid entry (including one that declares a login) is rejected whole and the previous one
kept. Two sources may offer the same key; each installs its own indexer. -
Published images and releases. Every image is published to GitHub Container Registry
(ghcr.io/cinomni/cinomni, its-hwaccelvariant, and the three sidecar images), stamped with the
version, the commit and the build date, anddocker-compose.ymlpulls them.CINOMNI_IMAGE_TAGin
.envchooses the version;docker-compose.build.ymlbuilds from source instead. -
Per-indexer credentials. Encrypted at rest under
CINOMNI_SECRET_KEY, write-only over HTTP.
Torznab indexers finally send their API key, which they never did before. -
Hardware transcoding on VAAPI, NVENC and QSV, behind two opt-in Compose overlays. Never run
against a real GPU; see Accepted risks in ROADMAP.md. -
An operator console at
/console, and a settings store that changes eleven keys without a
restart. -
A throttle on the anonymous credential routes. Login and first-run setup are rate-limited per
client address, answering 429 with aRetry-After; the permits and the window are settings an
operator changes without a restart. IPv6 clients are counted by /64 prefix, and a shared
concurrency backstop bounds simultaneous password verifications however many addresses appear.
Publishing beyond loopback needsCINOMNI_TRUSTED_PROXIESand a proxy that writes
X-Forwarded-Foritself (see DEPLOYMENT.md). -
Two-factor authentication (TOTP), per account and opt-in. Enroll from your own account with a
QR code or the secret, confirm with a code, and keep the ten single-use recovery codes it shows
once. Signing in becomes two steps: the password returns a short-lived challenge, and a code
answers it. Turning it off needs the password and a current code, and ends every other session.
Recovery codes work even ifCINOMNI_SECRET_KEYis lost, and DEPLOYMENT.md documents the way back
when those are gone too. -
A content security policy, and the hardening headers around it, on every response the Host
serves.script-src 'self'with nounsafe-inlineorunsafe-evalis what protects the session
token the client keeps inlocalStorage;Referrer-Policy: no-referrerstops the metadata
provider's image host from being told which page a viewer is on. HSTS is sent only over TLS, which
for this image means only behind a proxy that forwards the scheme. -
A cap on how many requests one account may have open at once. Off by default, so nothing
changes until an administrator sets it; a per-account limit overrides the installation default in
either direction, and zero lifts the cap. Open means pending or approved-and-not-yet-playable; a
rejected request and a fulfilled one both give the slot back, so the limit is on how much of the
approval queue one person occupies rather than on how much they may ask for over a lifetime. The
refusal names the numbers, so the interface can say "you have 5 of 5 open" rather than "no".
There is deliberately no download quota: an acquisition carries no account, because after
approval the spine runs on monitoring policy rather than on people, and one season pack can satisfy
what three people asked for. Bounding disk or bandwidth is an installation-level concern and a
different feature.
Fixed
-
A transcode no longer tries NVENC on a machine without an NVIDIA GPU. Detection took FFmpeg's
encoder list at its word, so every conversion first failed on NVENC and only then fell back to the
CPU. The NVIDIA overlay also asked for too little of the driver (computeis now included); without
it NVENC could not start at all. -
A file converted for a smaller screen is now actually scaled down, and a file with an extra
audio track the device cannot play (a DTS track beside an AAC one) is no longer converted entirely. -
The two-step sign-in no longer runs out early on a fast clock. The code screen counted down
to the server's expiry time using the browser's clock; a device running ahead of the server sent
its user back to the password before the request had expired. It now counts the lifetime the
server gives from when the reply arrived. -
Disabling an account, or giving up your own administrator role, asks first. Demoting yourself
also reloads who you are, so the console closes rather than refusing every click. -
A setting someone else changed meanwhile reloads instead of failing on every retry.
-
Failures that used to be silent now say so: unblocking a release, switching a notification
channel on or off, granting or revoking access to a collection, and reading who has that access. -
A title you just added stops offering "Add" and shows in the library without a reload.
-
Artwork choices have names a screen reader can announce.
-
Titles from the trending list arrive unwatched. Turning the list on used to start looking for
every title on it, up to forty every six hours. They are now catalogued with monitoring off: switch
on the ones you want from the title's page. When a household member's request for one of them is
approved, the approval switches it on. A title an approval finds already switched off (by the list,
or by you) is switched on...