In cross-platform Qt development, QML provides concise and powerful multimedia support, allowing for easy video playback functionality through the <span>MediaPlayer</span> and <span>VideoOutput</span> components. However, when running QML video playback applications on Linux systems (especially Ubuntu/Debian-based), users often encounter issues such as “no sound” or “unable to play”. The root cause lies in the fact that Qt’s multimedia backend (such as GStreamer) relies on the system’s audio service, and the default installation of Qt may lack development support for the PulseAudio audio system.
This article will delve into this issue and provide a complete solution from environment configuration, code writing, to debugging verification, helping you achieve sound-enabled QML video playback on Linux.
1. Problem Phenomenon and Root Cause
1.1 Typical Error Manifestations
- The video displays normally, but there is no sound;
- The console outputs warnings similar to:
GStreamer-CRITICAL**: gst_element_make_from_uri: assertion 'type == GST_URI_SRC || type == GST_URI_SINK' failed Warning:"No decoder available for type 'audio/x-raw'." - Or it directly indicates that audio plugins are missing.
1.2 Root Cause Analysis
The Qt Multimedia module on Linux typically relies on the GStreamer multimedia framework. For GStreamer to output audio to the system, it must go through PulseAudio (the mainstream audio service for modern Linux desktops) or ALSA.
When you install Qt from official sources or online, its precompiled <span>libQt6Multimedia.so</span> (or the Qt5 version) may not be linked with PulseAudio support because the <span>libpulse-dev</span> development package was missing during the build.
β Solution: Install the PulseAudio development headers, then rebuild the Qt Multimedia module (or ensure that the complete dependencies are installed on the system).
2. Environment Preparation: Installing Necessary Dependencies
2.1 Install PulseAudio Development Package (Key Step)
# Ubuntu / Debian / Linux Mint
sudo apt-get update
sudo apt-get install libpulse-dev
# It is also recommended to install the complete GStreamer plugins
sudo apt-get install gstreamer1.0-plugins-base \
gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad \
gstreamer1.0-plugins-ugly \
gstreamer1.0-libav \
gstreamer1.0-pulseaudio
π‘
<span>libpulse-dev</span>provides headers such as<span>pulse/pulseaudio.h</span>, enabling Qt to activate the PulseAudio backend when building the Multimedia module.
2.2 Verify if PulseAudio is Running
# Check service status
pactl info
# You should see output similar to:
# Server Name: pulseaudio
# Default Sink: alsa_output.pci-0000_00_1f.3.analog-stereo
If it is not running, you can start it manually:
pulseaudio --start
3. Complete Implementation of QML Video Player
3.1 Project Structure
VideoPlayer/
βββ main.cpp
βββ main.qml
βββ VideoPlayer.pro (or CMakeLists.txt)
3.2 C++ Main Program (main.cpp)
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QLoggingCategory>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
// Optional: Enable multimedia debug logging
QLoggingCategory::setFilterRules(QStringLiteral("qt.multimedia.*=true"));
QQmlApplicationEngine engine;
const QUrl url(u"qrc:/main.qml"_qs);
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
3.3 QML Video Playback Interface (main.qml)
import QtQuick
import QtQuick.Controls
import QtMultimedia
ApplicationWindow {
id: window
width: 800
height: 600
visible: true
title: "QML Video Player on Linux"
MediaPlayer {
id: mediaPlayer
// Supports local files or network streams
source: "file:///home/user/videos/sample.mp4"
// or source: "https://example.com/video.mp4"
// Auto play (optional)
// autoPlay: true
// Error handling
onErrorChanged: {
if (error !== MediaPlayer.NoError) {
console.error("MediaPlayer error:", errorString)
}
}
}
VideoOutput {
id: videoOutput
anchors.fill: parent
source: mediaPlayer
}
// Control bar
Rectangle {
anchors.bottom: parent.bottom
width: parent.width
height: 60
color: "#333333"
Row {
anchors.centerIn: parent
spacing: 10
Button {
text: mediaPlayer.playbackState === MediaPlayer.PlayingState ? "βΈοΈ Pause" : "βΆοΈ Play"
onClicked: {
if (mediaPlayer.playbackState === MediaPlayer.PlayingState)
mediaPlayer.pause()
else
mediaPlayer.play()
}
}
Button {
text: "βΉοΈ Stop"
onClicked: mediaPlayer.stop()
}
Slider {
id: volumeSlider
from: 0
to: 1
value: mediaPlayer.volume
onValueChanged: mediaPlayer.volume = value
Layout.fillWidth: true
width: 150
}
Label {
text: "Volume: " + Math.round(volumeSlider.value * 100) + "%"
color: "white"
}
}
}
// Loading indicator
BusyIndicator {
anchors.centerIn: parent
running: mediaPlayer.status === MediaPlayer.Loading
visible: running
}
}
3.4 Project File (VideoPlayer.pro)
QT += quick multimedia
CONFIG += c++17
SOURCES += \
main.cpp
RESOURCES += qml.qrc
target.path = $$[QT_INSTALL_EXAMPLES]/multimedia/video
INSTALLS += target
π If using CMake, ensure to link
<span>Qt6::Multimedia</span>.
4. Compilation and Execution
4.1 Build with qmake
cd VideoPlayer
qmake
make -j$(nproc)
./VideoPlayer
4.2 Build with CMake (Recommended for Qt6)
# CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(VideoPlayer VERSION 1.0)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
find_package(Qt6 REQUIRED COMPONENTS Quick Multimedia)
qt_add_executable(VideoPlayer
main.cpp
main.qml
)
target_link_libraries(VideoPlayer PRIVATE Qt6::Quick Qt6::Multimedia)
Build command:
mkdir build && cd build
cmake ..
cmake --build .
./VideoPlayer
5. Debugging and Verification
5.1 Check if Qt Multimedia Plugin Includes PulseAudio
# Check multimedia plugins in the Qt installation directory
ls $QTDIR/plugins/mediaservice/
# Should normally include:
# libgstmediaplayer.so (GStreamer backend)
# libqtmedia_pulse.so β Key! PulseAudio audio plugin
If <span>libqtmedia_pulse.so</span> is missing, it indicates that Qt Multimedia is not correctly linked with PulseAudio, and you need to recompile Qt or install the official full version (e.g., by selecting “Full installation” through the online installer).
5.2 Enable Detailed Logging
Add the following in <span>main.cpp</span>:
qputenv("QT_LOGGING_RULES", "qt.multimedia.*=true");
During runtime, observe the console output to confirm that the audio pipeline is established successfully:
qt.multimedia.gstreamer: Created audio sink: pulsesink
6. Common Problem Troubleshooting
| Problem | Solution |
|---|---|
| Video with no sound | 1. Ensure that <span>libpulse-dev</span> is installed and the project is rebuilt. 2. Check if <span>pactl list sinks</span> shows any output devices. 3. Verify that the video file itself has an audio track. |
| Unable to play MP4/H.264 | Install <span>gstreamer1.0-libav</span> and <span>gstreamer1.0-plugins-ugly</span> |
| Black screen or stuttering | Try setting <span>videoOutput.fillMode = VideoOutput.PreserveAspectFit</span> |
| Network video fails to load | Ensure the URL is accessible and that GStreamer supports the protocol (e.g., HTTP/RTSP). |
7. Alternative Solution: Using VLC Backend (Advanced)
If GStreamer remains unstable, consider using QtVLC or Phonon-VLC, but this requires additional integration of the VLC library, which is more complex. For most scenarios, correctly configuring GStreamer + PulseAudio is sufficient.
8. Conclusion
To play videos with sound using QML on Linux, the key is to ensure that the Qt Multimedia module can correctly call the PulseAudio audio service. The following steps can resolve the issue:
β 1. Install development dependencies:
sudo apt-get install libpulse-dev gstreamer1.0-pulseaudio
β
2. Write standard QML video playback code (using <span>MediaPlayer</span> + <span>VideoOutput</span>);
β 3. Rebuild the project (ensuring it is linked to PulseAudio support);
β 4. Verify the existence of audio plugins and enable debug logging.
By following this guide, you will be able to build a fully functional, synchronized QML video playback application on mainstream Linux distributions such as Ubuntu, Debian, and Fedora.
Other
- Domestic Open Source: https://gitee.com/feiyangqingyun
- International Open Source: https://github.com/feiyangqingyun
- Project Collection: https://qtchina.blog.csdn.net/article/details/97565652
- Contact: WeChat feiyangqingyun
- Official Store: https://shop114595942.taobao.com/