Replace Qt Multimedia with a native audio abstraction#10098
Conversation
There was a problem hiding this comment.
Pull request overview
This PR removes the Qt Multimedia dependency used only for the incoming-call ringtone by introducing an in-tree NotificationSoundPlayer QML type backed by native OS audio APIs (AVAudioPlayer / XAudio2 / libcanberra-or-noop). This reduces packaging/deployment overhead while preserving the QML call sites (play()/stop()).
Changes:
- Replace
SoundEffectusage inCallNotificationDialog.qmlwithNotificationSoundPlayerand drop theQtMultimediaimport. - Add
NotificationSoundPlayerimplementation + platform backends and register it for QML usage. - Wire up build system (platform sources, native link flags, optional libcanberra) and add a unit test + remove dead NSIS Qt5Multimedia DLL lines.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| test/testnotificationsoundplayer.cpp | Adds unit tests for QRC resolution and loop bookkeeping. |
| test/CMakeLists.txt | Registers the new NotificationSoundPlayer test target. |
| src/gui/tray/CallNotificationDialog.qml | Switches ringtone element from QtMultimedia SoundEffect to NotificationSoundPlayer. |
| src/gui/owncloudgui.cpp | Registers NotificationSoundPlayer as a QML type. |
| src/gui/notificationsoundplayer.h | Declares the new QML-facing API and backend interface hooks. |
| src/gui/notificationsoundplayer.cpp | Implements dispatcher logic and QRC-to-filesystem extraction caching. |
| src/gui/notificationsoundplayer_p.h | Defines the backend interface and factory function contract. |
| src/gui/notificationsoundplayer_win.cpp | Windows XAudio2 backend + WAV parsing. |
| src/gui/notificationsoundplayer_mac.mm | macOS AVAudioPlayer backend. |
| src/gui/notificationsoundplayer_linux.cpp | Linux libcanberra backend + noop fallback. |
| src/gui/CMakeLists.txt | Adds sources and platform link/defines (AVFoundation/Foundation, xaudio2, optional libcanberra). |
| cmake/modules/NSIS.template.in | Removes stale Qt5Multimedia DLL references from the installer template. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
The Qt Multimedia framework was pulled into the desktop client solely to play the call-notification ringtone in a loop via QML's SoundEffect. This introduces NotificationSoundPlayer, a thin in-tree C++ class that wraps the OS-native audio APIs (AVAudioPlayer on macOS, XAudio2 on Windows, libcanberra on Linux) and exposes the same minimal QML API the dialog needs. Removing the import lets macdeployqt drop the QtMultimedia framework and QML plugin from the bundle and unblocks shrinking the Windows installer. The dispatcher resolves qrc:/file:/plain-path sources, extracts QRC contents to the cache with an atomic-rename + QTemporaryFile fallback, and drives loop counting for backends that play one buffer at a time (Linux). Native-loop backends (macOS, Windows) play the whole sequence in one shot. Backend choice is platform-gated in CMake; libcanberra is a soft build dependency on Linux with a no-op fallback. Also deletes two dead Qt5Multimedia.dll references from the NSIS template that could never resolve in the current Qt6 build. Closes #9886 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: Iva Horn <iva.horn@nextcloud.com>
4296d11 to
a5243a0
Compare
|
|
Oké, plans might change. Possibly the call notification feature will be removed entirely from the files client due to the Nextcloud Talk desktop client available since the feature release. |




Summary
Replaces the Qt Multimedia framework — used in exactly one place, to loop the incoming-call ringtone in
CallNotificationDialog.qml— withNotificationSoundPlayer, a thin in-tree C++ class that wraps the OS-native audio APIs.AVAudioPlayervia Objective-C++numberOfLoops)XAudio2+ inline RIFF/fmt/data parserXAUDIO2_BUFFER::LoopCount)libcanberra(soft build dependency)The QML diff is one removed import and one renamed element;
ringSound.play()/ringSound.stop()call sites are unchanged. Native-loop backends play the whole sequence and signalfinishedonce; per-play backends signal after each play and the dispatcher re-issues until the loop count is exhausted.The dispatcher resolves
qrc:/file:/ plain-path sources, materialising QRC contents into the cache once with an atomic-rename andQTemporaryFilefallback for sandboxed runs.Two dead
Qt5Multimedia*.dllreferences in the NSIS template are deleted in the same commit (they could never resolve in the current Qt6 build).Closes #9886
Test plan
QtMultimedia.frameworkorqml/QtMultimedia/*(verified pre-merge:find Contents -iname '*Multimedia*'returns nothing).libcanberra-dev; on a Pulse host and a Pipewire host: trigger an incoming Talk call; same matrix.NotificationSoundPlayerTestpasses: coversresolveToFilesystemPath()(QRC extraction + idempotency,file://, plain path, empty, non-existent) and loop bookkeeping (per-play re-issues, native single-fire, stop-mid-sequence cancels).🤖 Generated with Claude Code