One device, however you connect it. The same mouse now keeps one device card and one set of settings across receiver and USB connections. Existing configurations migrate automatically and are backed up before the first save. (#876)
A redesigned device workspace makes larger setups easier to manage. A responsive grid, compact cards, clearer battery status, custom device names, scalable interface presets, and a dedicated action menu make devices faster to scan and configure.
Per-app profiles are now editable in the GUI. Pick an installed application from the new catalog, see which profile is active, and customize its button bindings without editing TOML. (#976)
Scrolling is smoother and more configurable. Built-in smooth scrolling, vertical sensitivity controls, preserved fractional motion, rebindable wheel tilt, and fixes for diverted high-resolution wheels deliver more consistent scrolling across main and thumb wheels. (#902, #925, #992)
Buttons can now distinguish a tap from a hold. TOML bindings can assign independent short- and long-press actions with a 500 ms threshold, while held shortcuts remain active until the button is released. (#961)
What's Changed
chore(gui): bump gpui-component to da4f9369 by @AprilNEA in #655
refactor(hid): centralize device identities by @AprilNEA in #831
docs(agents): scale local gate to affected packages by @AprilNEA in #696
feat(core,gui): make the main wheel's tilt rebindable (MX anywhere 2s,...) by @6lv1-blr in #902
fix(linux): install the app icon at every indexed hicolor size by @4ni1ak in #837
fix(gui): recognize mx ergo wheel tilt metadata by @AprilNEA in #905
ci: automate typo checks and consolidate configs by @AprilNEA in #906
refactor(gui): convert app state to entity events by @AprilNEA in #904
fix(mouse): compose thumb-wheel preset labels from translated action names by @NatsUIJM in #910
fix(linux): restore glibc 2.35 package baseline by @AprilNEA in #911
fix(gui): restore full-phrase thumb-wheel preset labels by @AprilNEA in #913
refactor(gui): componentize free-function builders by @AprilNEA in #914
fix(macos): honor XDG state dir in permission diagnostics by @AprilNEA in #915
fix(hid): improve Unifying receiver discovery reliability by @v14 in #853
feat(gui): add per-app profiles and redesign device workspace by @AprilNEA in #907
fix(macos): use reliable async-hid report writes by @sh3ll3x3c in #889
fix(hid): preserve usage pairs in native handle cache by @sh3ll3x3c in #882
fix: show Windows MSI completion and failure state by @mvanhorn in #819
feat(gui): make custom controls keyboard-operable by @AprilNEA in #916
style(gui): refine profile toolbar layout by @AprilNEA in #921
refactor(gui): clean up render paths and element ids by @AprilNEA in #926
fix(hidpp): read Unifying link encryption from bit 5, not the software-present bit by @AprilNEA in #924
refactor(gui): tighten typed rendering and async ownership by @AprilNEA in #931
refactor(gui): move device reads onto swr by @AprilNEA in #929
feat(gui): add scalable interface presets by @AprilNEA in #934
feat(agent): unify button Down/Up/Cancel lifecycle by @AprilNEA in #933
feat(i18n): add Turkish (tr) interface locale by @4ni1ak in #835
feat(gui): add switchable device gallery views by @AprilNEA in #927
refactor(gui): improve shared component quality by @AprilNEA in #966
feat(agent): hold shortcut output until button release by @AprilNEA in #960
fix(thumbwheel): scale remapped vertical scrolling by @hsearcy in #925
refactor(gui): structure app state by domain by @AprilNEA in #974
feat(gui): add installed application catalog picker by @AprilNEA in #976
feat(gui): add polished battery indicator by @AprilNEA in #983
feat(scroll): preserve precise scroll distances by @AprilNEA in #973
ci: replace target caches with sccache by @AprilNEA in #984
feat(scroll): add finite smooth scroll runtime by @AprilNEA in #975
feat(scroll): smooth diverted thumbwheel input by @AprilNEA in #977
feat(gui): polish the app catalog picker and device cards by @AprilNEA in #986
feat(scroll): add vertical scroll sensitivity by @AprilNEA in #978
feat(scroll): expose smooth scrolling setting by @AprilNEA in #979
refactor(gui): strengthen typed render boundaries by @AprilNEA in #981
fix(core,gui,agent): key device settings by identity, not by transport by @yuzi-co in #876
feat(agent): dispatch independent long-press actions by @AprilNEA in #961
refactor(agent): complete thumbwheel state machine by @AprilNEA in #968
fix(hid): preserve diverted wheel reporting by @AprilNEA in #992
v0.7.5 and v0.7.6 were tagged but never published β their macOS packaging failed before a single artifact was uploaded, so no release exists for either. Everything both of them contained ships here, and the changes below cover everything since v0.7.4.
What's Changed
docs(ci): map every CI job to a local command by @davidbudnick in #732
If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.
Added
System for Cross-domain Identity Management (SCIM) v2 (Enterprise):
JMAP: CalendarEvent/set support for updating and deleting synthetic ids (#2925).
Calendar:
Conference links in calendar invites and email alarms.
Translations for Arabic, Brazilian Portuguese, Bulgarian, Chinese Simplified, Chinese Traditional, Croatian, Czech, Finnish, Hebrew, Hindi, Hungarian, Indonesian, Japanese, Korean, Lithuanian, Norwegian BokmΓ₯l, Persian, Romanian, Russian, Slovak, Slovenian, Thai, Turkish, Ukrainian and Vietnamese.
Changed
Calendar: Updated HTTP RSVP page.
Fixed
DANE:
TLSA records are looked up whenever the MX RRset is signed, even when the MX host's own zone is not.
Mandatory DANE failures are permanent rather than temporary, bouncing messages that should be delayed.
Valid but unusable TLSA records fall back to the configured TLS strategy, permitting cleartext delivery where TLS is required.
S3: Fix outdated upstream af-south-1 region configuration.
Setup wizard: SQL directories set to use the main data store are now validated against the data store being configured.
CardDAV: Delete default address book id when deleting the default address book.
Redis: Sentinel deployments configured with rediss:// URLs now connect to the master over TLS instead of silently falling back to cleartext.
Email: Generated Message-ID headers use the hostname of the node that built the message instead of the configured server hostname.
MTA:
Do not send DMARC reports to local domains.
Messages addressed to an inboundReportAddresses match are only discarded when they actually contain a report (#1088).
Directory: Impersonation using the recovery admin fails when the impersonated account has not logged in before (LDAP and SQL directories).
WebUI: Failed logins open the browser's native credential prompt.
Cluster: Expired node id leases are released periodically rather than only during startup, so entries for removed nodes no longer remain Stale or Inactive indefinitely.
Added countFilterListeners, countActionListeners, and countInitListeners methods to the emitter, exposing the number of registered handlers for each event (#28117 by @ComfortablyCoding)
π Bug Fixes & Optimizations
@directus/app
Fixed MCP OAuth clients settings pages concatenating breadcrumbs into the page title (#28115 by @MHJahanbakhsh)
@directus/api
Fixed the WebSocket heartbeat leaking a websocket.message listener on each ping when a client failed to respond in time (#28117 by @ComfortablyCoding)
Stripped project_id when pulling settings, so a sync no longer copies one instance's identity onto another (#28132 by @lazerg)
@directus/sdk
Fixed unsubscribe() not removing subscriptions, causing them to persist across reconnects and accumulate for the lifetime of the client (#28117 by @ComfortablyCoding)
@directus/system-data
Removed user_created and date_created for update from recommended permissions for directus_shares (#28145 by @br41nslug)
If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.
Added
WebUI: oauthClientId setting in Application, which allows the WebUI to use a different OAuth client than the default.
Sieve: env.spam.score and env.spam.is_spam variables, which expose the spam filter result to system scripts running at the DATA stage.
CalDAV: vCardVersion setting in AddressBook, which allows the default vCard version to be specified when the client does not request a specific version.
Changed
MySQL & MariaDB: Key columns are now VARBINARY(255) with a full-length primary key instead of TINYBLOB. Note: Existing deployments should run, once per table, for each of the tables a, d, e, f, g, h, j, k, l, m, n, o, p, q, r, s, t, u, w, x and y the command ALTER TABLE a MODIFY k VARBINARY(255) NOT NULL;.
Fixed
ACME:
Order and authorization failures are never logged, so an order rejected by the CA.
An order rejected by the CA marks the renewal task as permanently failed.
CalDAV:
Attendee addresses whose mailto: URI percent-encodes a full name-addr are silently dropped from the scheduling snapshot.
Attendees whose calendar user address cannot be parsed should be flagged with SCHEDULE-STATUS=3.7.
The RSVP link in an iMIP invitation stamps PARTSTAT on the organizer's copy of the event only, leaving a local attendee's own copy at NEEDS-ACTION and sending the organizer no reply.
MKCALENDAR, MKCOL and PROPPATCH store the display name, description, time zone and the other per-user properties under the authenticated account rather than the account that owns the collection.
Directory:
An empty column, attribute or claim returned by an external directory is synchronized as an empty string rather than a missing value.
/api/discover splits the account name on @ without accounting for the % master user separator or the recovery administrator.
FoundationDB: Older chunked entries are not deleted.
IMAP: SETACL and DELETEACL fail to resolve an identifier spelled with uppercase characters.
iMIP: Invitations, replies and cancellations reference a TZID parameter with no matching VTIMEZONE component whenever the event was stored without one.
JMAP:
AddressBook/get: A new account's default address book is never recorded.
Email/get and Email/parse with fetchAllBodyValues return body values only for the parts listed in textBody or htmlBody, omitting every other text/* part in bodyStructure.
Email/set writes display names as an RFC 2047 encoded-word wrapped in a quoted-string, which RFC 2047 forbids.
Mailbox/set, AddressBook/set and Calendar/set store isSubscribed and the other per-user properties under the authenticated account rather than the account named in the request.
Principal/query returns no results when the name or email filter is spelled with uppercase characters.
FileNode/set: File nodes created over JMAP are returned with a <D:href> holding the raw name over WebDAV.
Meilisearch:
Queries return at most 1000 results, as the maxTotalHits pagination setting is left at the Meilisearch default.
Searches combining several terms return documents that match only some of them.
A task confirmation timeout is reported as a success when failOnTimeout is disabled.
Import: --import always aborts with the target database already containing data in the key range being imported.
MTA:
A domain catchAllAddress pointing to a mailing list or a sub-addressed mailbox is accepted at RCPT TO and then rejected at local delivery with 550 5.5.0 Mailbox not found.
is_local_address() and is_local_domain() expression functions do not match an address or domain spelled with uppercase characters.
Relay routes are rejected with host resolves loopback address, which prevents relaying through a local proxy or tunnel.
MySQL, MariaDB & PostgreSQL: Range scans, range deletions and store purges run as a single unbounded statement, so on servers that enforce a statement timeout they abort on large accounts and tasks such as account deletion can never complete.
Network: local_port and local_ip report the address Stalwart is bound to rather than the address the client connected to when the connection arrives through a trusted proxy.
Task manager:
totalDeadline is not enforced on tasks that fail with a specific retry time.
Indexing tasks are dropped after maxAttempts failures, so a search store that is unavailable or overloaded leaves messages permanently missing from the index.
Indexing tasks are dropped when the document metadata read returns no data, which can happen on SQL read replicas that have not yet caught up with the primary.
The DNS management task republishes the DKIM records of retired keys that the DKIM rotation task had already removed from the zone.
Sieve: spamtest returns only 1 or 10 (and spamtest :percent only 0 or 100), so scripts cannot act on intermediate spam scores.
Spam filter: MIME_BAD is tagged whenever the declared Content-Type of an attachment is not byte identical to the type detected from its magic bytes.
Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted (#28076) exists() now throws when the lookup itself fails, for example on a timeout, a connection error or rejected credentials, instead of also reporting false. Callers that relied on a false result for any failure need to handle the error. Note that S3 answers 403 rather than 404 for a missing object when the credentials cannot list the bucket, so granting s3:ListBucket is needed to keep getting a clean "missing" answer.
Fixed "Update Items" and "Delete Items" operations affecting every item in a collection when given an empty or missing key or query (#27759) Nothing to target is a no-op
"Update Items" and "Delete Items" operations now return null instead of falling back to every item whenever the configuration doesn't target anything β that is, when key is empty or missing (e.g. [], "") and query is empty or missing (e.g. {}). "Update Items" additionally returns null when there is nothing to write, i.e. an empty or missing payload (e.g. {}, or [] for a batch payload). Flows that relied on the previous fallback to every item can use {"limit": -1}.
Contradictory options error
"Update Items" and "Delete Items" operations now throw an error when both key and query are defined. "Update Items" also throws when key or query is combined with a batch payload.
Updated ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSION to match ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION (6000 px) (#28111)
The default maximum output dimension is now 6000 px. Users who rely on the previous limit of 3000 px can explicitly configure ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSION.
Used the pm2 bundled with @directus/api in the Docker images instead of installing a separate copy, so its dependencies follow the versions pinned by the workspace (#28120)
If you extend the Docker image: it now boots via CMD ["node", "docker-entrypoint.cjs"], which runs the same bootstrap then pm2-runtime sequence as before. pm2-runtime is no longer on the PATH, so a custom CMD that called it directly should hand off to docker-entrypoint.cjs instead. pm2 itself remains on the PATH for docker exec diagnostics.
@directus/api
Fixed "Update Items" and "Delete Items" operations affecting every item in a collection when given an empty or missing key or query (#27759 by @ComfortablyCoding)
@directus/storage-driver-cloudinary
Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted (#28076 by @dstockton)
@directus/storage-driver-s3
Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted (#28076 by @dstockton)
@directus/storage-driver-local
Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted (#28076 by @dstockton)
@directus/storage-driver-supabase
Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted (#28076 by @dstockton)
@directus/sdk
Updated outdated type definitions for directus_files, directus_collections, directus_deployments, directus_settings, and directus_users (#27945 by @kheiner)
β¨ New Features & Improvements
@directus/app
Added search-first AI tool discovery for chat and MCP tools, with schema pinned as a root chat tool. (#27797 by @bryantgillespie)
Added a caption field to the WYSIWYG image drawer, which wraps the image in a figure with a figcaption (#28026 by @alvarosabu)
Added the collection name appended to display template in item and drawer headers (#28078 by @AlexGaillard)
@directus/api
Added search-first AI tool discovery for chat and MCP tools, with schema pinned as a root chat tool. (#27797 by @bryantgillespie)
@directus/cli
Introduced @directus/cli (d6s / directus-cli) β a client-side CLI that syncs schema and configuration between Directus instances through committed JSON files, with sync pull, sync diff, sync push, and an interactive wizard (#27861 by @bryantgillespie)
@directus/types
Updated outdated type definitions for directus_files, directus_collections, directus_deployments, directus_settings, and directus_users (#27945 by @kheiner)
Removed dead βSave and Quitβ dropdown row outside the content item view (#28051 by @robluton)
Fixed relational items with unsaved nested values, such as newly added translated items in a content version, rendering as -- instead of their display template (#28010 by @alvarosabu)
Fixed the repeater interface options showing empty sub-fields, and dropping their key and type on save, when the sub-fields were created through the API without repeating the key and type inside their meta (#28041 by @lazerg)
Fixed relational fields showing stale values after a manual flow updated them (#28056 by @AlexGaillard)
Fixed the Markdown interface's Edit and Preview buttons not indicating which view is currently active (#28023 by @Aniket-a14)
Fixed silent failure of dragging & dropping files with an unrecognized extension into the file library (#28093 by @alvarosabu)
Fixed a request for a non-existent item when opening an item whose Many-to-One field references an unsaved parent (#27975 by @sourav-18)
Updated outdated type definitions for directus_files, directus_collections, directus_deployments, directus_settings, and directus_users (#27945 by @kheiner)
Fixed field configuration appearing to close when selecting related collection that switches interface (#28118 by @robluton)
Fixed the translations interface AI translation button only showing for admins (#28089 by @AlexGaillard)
Fixed SSO login redirecting to the last visited page instead of the originally requested page (#28080 by @AlexGaillard)
Stopped the policy creation modal from writing app access permission rows to the database, matching the policy detail page where app access permissions are applied at runtime instead of stored (#28101 by @alvarosabu)
Added block-level custom formats to the WYSIWYG interface, so block, selector and items entries in the Custom Formats option apply classes and attributes to paragraphs, headings and other block nodes from the Formats dropdown (#28044 by @alvarosabu)
Fixed WYSIWYG content the editor can't represent being hidden and unrestorable in the comparison modal (#28067 by @alvarosabu)
@directus/api
Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted (#28076 by @dstockton)
Added a batch-import regression test pinning that a negative temporary key maps like any other non-existent auto-increment key in merge mode (#27861 by @bryantgillespie)
Updated MCP tool descriptions and safety annotations for connector clients. (#28090 by @bryantgillespie)
Improved MS SQL Server reliability and performance by optimizing schema introspection and only enabling trigger compatibility when required (#27699 by @br41nslug)
Updated various dependencies to address CVEs (#28110 by @br41nslug)
Fixed slow extension sync from remote storage during startup. Added EXTENSIONS_STORAGE_MAX_CONCURRENCY to configure the maximum number of concurrent requests to the extensions storage location (#27989 by @dstockton)
Updated ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSION to match ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION (6000 px) (#28111 by @ComfortablyCoding)
Fixed TranslationsService.updateMany incorrectly rejecting single-row updates containing both key and language (#28001 by @suhailopensource)
Fixed collection names with surrounding whitespace being accepted on creation (#28038 by @lazerg)
Fixed WebSocket rate limiting breaking on shared Redis setups where keys must start with a per-project prefix. The WebSocket limiter now accepts RATE_LIMITER_WEBSOCKETS_* values as overrides, including RATE_LIMITER_WEBSOCKETS_KEY_PREFIX to override the Redis key prefix. (#28107 by @AlexGaillard)
@directus/storage-driver-azure
Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted (#28076 by @dstockton)
@directus/storage-driver-gcs
Fixed storage connections leaking when asset requests were cancelled or a transformation failed, which eventually made every asset request return a permission error until Directus was restarted (#28076 by @dstockton)
Improved MS SQL Server reliability and performance by optimizing schema introspection and only enabling trigger compatibility when required (#27699 by @br41nslug)
@directus/env
Fixed slow extension sync from remote storage during startup. Added EXTENSIONS_STORAGE_MAX_CONCURRENCY to configure the maximum number of concurrent requests to the extensions storage location (#27989 by @dstockton)
Updated ASSETS_TRANSFORM_IMAGE_MAX_OUTPUT_DIMENSION to match ASSETS_TRANSFORM_IMAGE_MAX_DIMENSION (6000 px) (#28111 by @ComfortablyCoding)
Updated ESLint dependencies eslint, @eslint/js, eslint-plugin-vue, and typescript-eslint. Replaced eslint-plugin-import with eslint-plugin-import-x (#28047 by @br41nslug)
prevent spamming of 'stream is closed' error during shutdown (#6062)
impose a minimum value to clock rate of always-available tracks (#6086) Clock rates below 10 caused the emission of empty samples. Fix the issue by imposing a minimum value of 8khz, that rises to 22khz in case of AAC.
fix race condition during sub-stream creation (#6075) (#6095) When a stream with always-available turned on switches from offline to online, or from a publisher to another, the reader mutex was not acquired during writing of codec parameters. This is now fixed.
restore ability to run the server in a read-only file system (#6098) This was temporarily lost after the introduction of the native MoQ QUIC listener.
fix deadlock when changing configuration through file and API (#6077) (#6101) When changing configuration in parallel by editing the configuration file and calling the API, the server could get into a deadlock that prevented any further action. This is fixed.
change default value of authHTTPExclude (#6103) by default, do not exclude any action from HTTP authentication. Old value triggered several security warnings.
add destFingerprint parameter (#6106) this allows to validate self-signed certificates of forward destinations.
pmp4: fix panic in case of bad input (bluenviron/mediacommon#354) the stsc box was not checked properly. This is now fixed.
pmp4: fix panic in case of bad input (bluenviron/mediacommon#355) The parser was not checking that the MP4 was properly sending addresses of samples, resulting in samples with invalid addresses. This is now fixed.
limit maximum amount of published tracks (#6087) this prevents clients from consuming an excessive amount of memory.
make /moq URL suffix optional (#6107) In order to establish a MoQ session with WebTransport, a /moq suffix was required until now. This is now optional in order to allow connecting to the server with the standard MoQ URL format.
impose maximum size on pending reordered bytes (#6112) Decrease the maximum memory that clients can take by imposing a maximum size of 100MB on the pending reordered bytes.
RTSP
accept relative digest URI (bluenviron/gortsplib#1118) RFC 2617 section 3.2.2 allows the digest URI to be either an absolute URI or a relative path. Some clients use the latter, which was rejected with "wrong URL" since urlMatches only accepted an exact match against the absolute request URL.
send initial RTCP sender report without waiting for a period (bluenviron/gortsplib#1052) (bluenviron/gortsplib#1111) (bluenviron/gortsplib#1120) Reports were emitted only on the ticker, so the first one arrived Period after Initialize (10s by default) and later still when no RTP packet had been sent by that first tick, since report() returns nil until then and the next opportunity is another Period away.
ensure that decoders can produce only output that does not crash encoders (bluenviron/gortsplib#1123)
inform about authentication failures (#5657) (#6072) Reply with NetStream.Play.Failed or NetStream.Publish.Unauthorized when a client is not authorized to play or publish. This makes clients like OBS to stop recreating the connection in case of authentication failures.
prefer hls.js on iOS too (#6090) In the embedded HLS reader, use hls.js on iOS, that was previously disabled due to compatibility issues that should have been solved.
unlock the session-in-query+iOS combination (#6088) this was previously blocked because the session in query was meant to be dynamic, therefore incompatible with static playlists required by iOS. It is not anymore, so we can support that.
stop using cookies with plain HTTP (#6089) in case of plain HTTP, fall back to query parameters, which are safer than HTTP cookies because they are not shared between different pages/domains, although they are visible in the URL.
improve performance by ignoring mDNS candidates (#4963) (#6064) mDNS candidates sometimes require a large CPU portion, they are not involved in any connectivity method mentioned in the documentation, they work in local networks only.
SRT
apply UDP read buffer size from configuration (#6069) Use upstream datarhei/gosrt's ListenerControl config field (datarhei/gosrt#144) to set SO_RCVBUF on the SRT listener's UDP socket.
RPI Camera
fix crash when secondary stream is enabled (#6060) (#6061)
prevent invalid MJPEG sizes (#6080) width and height of MJPEG frames must be multiple of 8 and less than 2048, otherwise they cannot be routed with RTP/RTSP.
Dependencies
code.cloudfoundry.org/bytefmt updated from v0.83.0 to v0.85.0
github.com/alecthomas/kong updated from v1.16.0 to v1.16.1
github.com/asticode/go-astits updated from v1.15.0 to v1.16.0
github.com/bluenviron/gohlslib/v2 updated from v2.4.2 to v2.4.3
github.com/bluenviron/gortmplib updated from v1.0.0 to v1.0.1
github.com/bluenviron/gortsplib/v5 updated from v5.6.3 to v5.6.4
github.com/bluenviron/mediacommon/v2 updated from v2.9.2 to v2.9.3
github.com/datarhei/gosrt updated from v0.11.0 to v0.11.1-0.20260812091715-a77b40bb4b76
github.com/pion/ice/v4 updated from v4.4.0 to v4.4.1
github.com/pion/transport/v4 updated from v4.0.2 to v4.1.0
github.com/stretchr/testify updated from v1.11.1 to v1.12.0
golang.org/x/crypto updated from v0.54.0 to v0.55.0
golang.org/x/net updated from v0.57.0 to v0.58.0
github.com/davecgh/go-spew removed
github.com/pion/srtp/v3 updated from v3.0.12 to v3.0.13
github.com/pmezard/go-difflib removed
golang.org/x/text updated from v0.40.0 to v0.41.0
hls.js updated from v1.6.16 to v1.7.0
Security
Binaries are compiled from source code by the Release workflow, which is a fully-visible process that prevents any change or external interference in produced artifacts.
Checksums of binaries are also published in a public blockchain by using GitHub Attestations, and they can be verified by running:
ls mediamtx_* | xargs -L1 gh attestation verify --repo bluenviron/mediamtx
You can verify checksums of binaries by downloading checksums.sha256 and running:
If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.
Added
Reporting: inboundReportMaxSize setting, which bounds the size of a decompressed inbound DMARC or TLS report (default 25MB).
RocksDB: cacheSize setting, which bounds the total memory shared by the block caches of every column family (default 128MB).
Changed
ASN & GeoIP: Default data source URLs now point at the ip-location-db GitHub releases, as the previously used npm packages are no longer updated. Existing installations keep their configured URLs and should update them following the ASN and GeoIP documentation.
JMAP: Identity/get keeps identities in sync with the account's e-mail addresses.
MTA: Queue scheduler no longer rescans the queue from the earliest pending event and coalesces bursts of delivery completions into a single scan.
RocksDB:
Column families are tuned for the access pattern of the data they hold.
Range iteration uses bounded iterators and no longer reads values when only keys were requested.
Fixed
JMAP:
Setting uploadTtl to 1ms triggers panic.
CalendarEvent/set does not assign organizerCalendarAddress nor send scheduling messages when an event is created with participants.
CalendarEvent/get omits isOrigin when it is listed explicitly in properties.
CalendarEventNotification/changes and FileNode/changes reject with cannotCalculateChanges the state that /get returned for an account with no change history.
CalendarEvent/set and ContactCard/set do not write a vanished tombstone for the previous CalDAV/CardDAV href when calendarIds or addressBookIds moves an item between collections.
CalDAV: Attendee addresses that percent-encode a display name into the mailto: URI are queued verbatim.
Calendar: Recurring events disappear from CalDAV time-range REPORTs and JMAP CalendarEvent/query results a few years after their first occurrence.
WebDAV:
When a file node references a parent folder that no longer exists, any request on a file collection panics.
MOVE on a folder honors a Depth header of 0 or 1 instead of always moving the whole subtree.
MTA:
DSN bounces are emitted with a malformed Message-ID wrapped in doubled angle brackets.
Delivery to any MX host whose name is an IDN A-label fails permanently.
Queue strategy and quota expressions that branch on source never match at enqueue.
MTA-STS:
Policies in testing mode are enforced, turning any TLS error into a permanent failure.
mx patterns published as U-labels never authorize the MX host they name.
DMARC:
Alignment compares identifiers in their A-label form.
External reporting addresses published as U-labels are rejected as unauthorized.
Spam filter:
Some rules misfire on internationalized addresses when the envelope and the headers spell the same domain in different label forms.
Punycode labels that do not re-encode to the label they came from are no longer decoded.
WebPush: Validate push URL and use application/octet-stream as Content-Type for encrypted payloads.
Directory:
Local group membership is cleared when the external directory is configured with a group claim or attribute that it does not return.
LDAP: Directories that store aliases as additional values of the primary address attribute provision no aliases.
Mail addressed to a domain alias is rejected with 550 Relay not allowed, unless the domain's primary name happened to be resolved earlier and is still cached.
RocksDB: bufferSize setting was applied to the unused default column family and had no effect.
Sieve: include statements fail to find system and user global scripts whose name contains uppercase characters.
Task manager: totalDeadline is measured from the time a task was created instead of its first failed attempt.
The NVIDIA SDK was updated to version 13 in this release. This means that the minimum supported driver version is now 570. If you experience any issues with NVENC, please ensure that your GPU driver version is fully up to date.
Important
Due to an update to Qt, macOS 12 is no longer supported. For macOS 12, please use OBS Studio 32.1.2.
32.2.2 Hotfix Changes
Fixed an issue where plugins might not load properly on the first start after updating OBS on Windows [notr1ch]
Blocked OBS Studio from running on macOS 12 [RytoEX]
Due to a Qt update, OBS Studio 32.2.x fails to launch on macOS 12. For macOS 12, please use OBS Studio 32.1.2.
32.2.1 Hotfix Changes
Fixed game capture failing after updating OBS if the previous hook was still in use [notr1ch]
32.2 New Features
Replaced add source dropdown with new dialog [Warchamp7]
Added copy paste functions to frontend API [exeldro]
Added filter to compose SDR into HDR [jpark37]
Added delete as a hotkey to delete sources on macOS [PatTheMav]
Added dynamic bitrate support to multitrack video [lexano-ivs]
Added missing file support for filters [exeldro]
Added ability for plugins to set custom icons for new source types [cg2121]
Improved FPS selector UX [jcm93]
Included .webp files when adding a directory to Image Slide Show source [TarunCore]
32.2 Changes
Forced Intel-based installations to update to Apple Silicon version on macOS [PatTheMav]
This change means that OBS Studio versions built for Intel-based Macs but running on Apple Silicon Macs will automatically update to OBS Studio built for Apple Silicon Macs. If an installation was using third-party plugins, those plugins will no longer load until replaced with Apple Silicon versions.
Fixed audio mixer state getting out of sync when changing settings via websockets or plugins [Warchamp7]
Added theming for checked QToolButtons [glikely]
Added minimum width to spinboxes [Warchamp7]
Changed new capture devices to use fallback frame rate by default [PatTheMav]
Improved OpenGL performance slightly on low-end machines [kkartaltepe]
Set minimum size for color source to 1 pixel [exeldro]
Disallowed overwriting the crash handler [sebastian-s-beckmann]
Applied process mitigation policies for Windows [notr1ch]
Adjusted description of multitrack video [jhnbwrs]
Improved DLL loading behavior on Windows [notr1ch]
Limited multitrack video config to Custom service [PatTheMav]
Removed redundant "Monitor Only" from the Advanced Audio Properties window [Warchamp7]
Mute and Monitor are handled independently in the new Audio Mixer
Removed Close button from What's New dialog [Warchamp7]
Removed margins from What's New dialog [Warchamp7]
32.2 Bug Fixes
Fixed OAuth and dock state save corruption [PatTheMav]
Fixed group bounds not resizing when removing items [howellrl]
Fixed canvas mixes not being restored after video reset [dsaedtler]
Fixed some erroneous crashes during shutdown [Warchamp7]
Fixed display capture sometimes capturing black after a duplicator failure [ThrowTop]
Fixed color of controls dock output buttons in System theme [shiina424]
Fixed virtual camera reset failures [stephematician]
Fixed potential crash when user discards changes in the settings window [suogesi]
Fixed incorrect return value in virtualcam filter [xtfo]
Fixed source toolbar buttons not working after dragging a source into a group [Warchamp7]
Fixed properties hint icon spacing [Warchamp7]
Fixed potential crash when a video device reconnects on macOS [jcm93]
Fixed an issue where PipeWire could fail on NVIDIA GPUs [hoshinolina]
If you are upgrading from v0.16.x, replace the binary (or run docker pull). If you are upgrading from v0.15.x and below, please read the upgrading documentation for more information on how to upgrade from previous versions.
WebDAV: Range and If-Range header support on file downloads (RFC 7233) (#2377).
Spam filter: url_original expression variable for Url rules.
Changed
Memory allocator: Replaced the unmaintained jemallocator crate with tikv-jemallocator (contributed by @checkraisefold).
ACME registry: Use description as label property.
Fixed
MTA:
Certificates for domains publishing an enforcing MTA-STS policy are always validated, even in the fallback TLS strategy.
DSN delivery date uses wrong timestamp.
FUTURERELEASE HOLDUNTIL uses Unix timestamps instead of RFC 3339 date-times.
JMAP:
EmailSubmission/query filtering on undoStatus contradicts EmailSubmission/get, reporting held FUTURERELEASE submissions as final instead of pending.
EmailSubmission/get requests without an ids argument iterates the wrong index.
CardDAV: Accept: text/vcard version negotiation is ignored whenever another parameter such as q or charset follows version=.
Calendar: Server-side scheduling messages place the text/calendar part outside the multipart/alternative and disposed as an attachment.
Sharing: Accounts holding the impersonate permission never have their ACL grants collected, so shared items are never listed in JMAP sessions, CalDAV/CardDAV discovery or IMAP.
IMAP:
COPY/MOVE into a shared folder fails with NO [ALREADYEXISTS] when the destination account already holds the message, leaving the message in the source mailbox and clients in a retry loop.
BODYSTRUCTURE and ENVELOPE return MIME parameters, Content-Description, subjects and display names as raw UTF-8 even to sessions that never enabled UTF8=ACCEPT.
support forwarding streams natively (#5558) It is now possible to define forward destinations for each path configuration. For each destination, the server will create a client that will forward the stream to the intended destination. Supported protocols are RTSP, RTMP, SRT. API and metrics have also been improved to allow monitoring the new forwarding system. Documentation: https://mediamtx.org/docs/features/forward
Media-Over-QUIC
support publishing and reading through native QUIC (#6039)
fix inability to read some AV1 streams with RTSP (#6001) (#6006) Since v1.16.0, temporal unit delimiters were not stripped from AV1 streams anymore. This has been restored, healing AV1 streams read with RTSP.
make multicast errors on single interfaces non-fatal (bluenviron/gortsplib#1115) (#5574) When writing multicast packets to several interfaces at one, a write error to a single interface was fatal and prevented writing to the other ones. Fix this.
client: change mapping between URL and tcURL, app, streamKey (bluenviron/gortmplib#94) (#4676) URLs passed to clients are now mapped into RTMP-native fields (tcURL, app, streamKey) in this way: tcURL contains URL without credentials and without fragment, app contains path and query of tcURL, streamKey contains the fragment.
muxer: recompute PTS of MPEG-TS AAC (bluenviron/gohlslib#379) iOS requires a precise timestamp that is often not available in AAC streams. Recompute timestamp from scratch.
WebRTC
sort tracks in a deterministic way (#5988) (#5989) When ingesting tracks with WebRTC, track order was randomized, preventing multi-track always-available streams from working reliably, since they require tracks to be ordered in a precise way. WebRTC tracks are not ordered by MID, RID, trackID and streamID respectively.
reset recomputed audio PTS if it drifts too much (#6021)
fix "packet lost" error when routing streams from WebRTC (#6034) Chrome sometimes sends empty packets, that are discarded by the server, but the sequence number of following packets is not recomputed, leading downstream packet loss detectors to emit errors. This is fixed.
SRT
improve log clarity (#5990) use message 'passphrase not provided by client' when clients do not provide passphrases.
close sources immediately when path is closed (#6038)
Dependencies
code.cloudfoundry.org/bytefmt updated from v0.82.0 to v0.83.0
github.com/MicahParks/jwkset updated from v0.11.0 to v0.11.3
github.com/MicahParks/keyfunc/v3 updated from v3.8.0 to v3.8.1
github.com/bluenviron/gohlslib/v2 updated from v2.4.1 to v2.4.2
github.com/bluenviron/gortmplib updated from v0.4.1 to v1.0.0
github.com/bluenviron/gortsplib/v5 updated from v5.6.2 to v5.6.3
github.com/go-git/go-billy/v5 updated from v5.9.0 to v5.9.1
github.com/go-git/go-git/v5 updated from v5.19.1 to v5.19.2
github.com/pion/ice/v4 updated from v4.3.0 to v4.4.0
github.com/pion/interceptor updated from v0.1.46 to v0.1.47
github.com/pion/webrtc/v4 updated from v4.2.17 to v4.2.18
github.com/quic-go/quic-go updated from v0.60.0 to v0.61.0
github.com/quic-go/webtransport-go updated from v0.11.1 to v0.12.0
github.com/pion/sctp updated from v1.11.0 to v1.11.1
golang.org/x/time updated from v0.14.0 to v0.15.0
Security
Binaries are compiled from source code by the Release workflow, which is a fully-visible process that prevents any change or external interference in produced artifacts.
Checksums of binaries are also published in a public blockchain by using GitHub Attestations, and they can be verified by running:
ls mediamtx_* | xargs -L1 gh attestation verify --repo bluenviron/mediamtx
You can verify checksums of binaries by downloading checksums.sha256 and running: