Audio not playing from .qrc resources
-
With QRC, it's always a bit tricky, but I think it should work. Some things to try:
- verify that file exists in QRC with QFile / QFileInfo
- try
"qrc://music/sound.mp3"
and"qrc:/music/sound.mp3"
- do not use
QUrl::fromLocalFile
but a regularQUrl
constructorplayer->setMedia(QUrl("qrc:/music/sound.mp3"));
-
@Xena_o
As per qt doc.. If you want to know what error happened while loading media..Listen for the mediaStatusChanged() and error() signals to be notified when the media is loaded and when an error occurs during loading.
-
In that case, you should be able to get it working by opening the MP3 with QFile and passing it as second argument to
setMedia()
https://doc.qt.io/qt-5/qmediaplayer.html#setMedia:QFile file("qrc://music/sound.mp3"); if (file.open(QFile::Read)) { player->setMedia("qrc://music/sound.mp3", &file); } else { qDebug() << "Oops!"; }
-
for some reasons this code is not fine, i added #include <QFile>
seems cannot use audio from resources
@kshegunov it is available for reading, the test of opening it from local directory works well, seems just from resources it wont open
-
@Xena_o said in Audio not playing from .qrc resources:
for some reasons this code is not fine, i added #include <QFile>
Yet didn't check the
QMediaPlayer::setMedia
documentation - the inline annotations already tell you something's wrong on that row. TheQMediaContent
object has an implicit constructor fromQUrl
that's why you can useQUrl
directly. Try something like:QFile file(":/music/sound.mp3"); //< QFile doesn't know about protocols if (file.open(QFile::Read)) player->setMedia(QMediaContent(nullptr), &file); else qDebug() << "Oops!";
@kshegunov it is available for reading, the test of opening it from local directory works well, seems just from resources it wont open
Available for reading from the resource! Also please answer the question as well.
-
@kshegunov here is final code
QFile file(":/music/music/sound.mp3"); if (file.open(QIODevice::ReadOnly)) { player->setMedia(QMediaContent(nullptr), &file); } else { qDebug() << "Oops!"; }
the accepted code is : QIODevice::ReadOnly and not QFile::Read
the file is in resources.qrc, i dont know how to figure if it is availablethe ouptput: no oops, and QMediaPlayer::NoError QMediaPlayer::LoadingMedia
but still the sound is not playing. so far if i well understand, it is loading it, but thats it, not playing
player->setVolume(50); player->play();
this is doing nothing
-
@Xena_o said in Audio not playing from .qrc resources:
the accepted code is : QIODevice::ReadOnly and not QFile::Read
Yes, I don't compile example code before I post it, so there may be minor errors.
What does this output, have you checked the signals that are raised?
QObject::connect(player, &QMediaPlayer::bufferStatusChanged, this, [this] (int percent) -> void { qDebug() << "QMediaPlayer::bufferStatusChanged" << percent; }); QObject::connect(player, &QMediaPlayer::durationChanged, this, [this] (qint64 duration) -> void { qDebug() << "QMediaPlayer::durationChanged" << duration; }); QObject::connect(player, &QMediaPlayer::error, this, [this] (QMediaPlayer::Error code) -> void { qDebug() << "QMediaPlayer::Error" << code; }); QObject::connect(player, &QMediaPlayer::mediaStatusChanged, this, [this] (QMediaPlayer::MediaStatus status) -> void { qDebug() << "QMediaPlayer::mediaStatusChanged" << status; }); QObject::connect(player, &QMediaPlayer::stateChanged, this, [this] (QMediaPlayer::State state) -> void { qDebug() << "QMediaPlayer::stateChanged" << state; }); QFile file(":/music/music/sound.mp3"); if (file.open(QIODevice::ReadOnly)) { player->setMedia(QMediaContent(nullptr), &file); } else { qDebug() << "Oops!"; } player->setVolume(50); player->play();
-
@kshegunov alright it is saying the media is invalid :
QMediaPlayer::mediaStatusChanged QMediaPlayer::LoadingMedia
QMediaPlayer::stateChanged QMediaPlayer::PlayingState
QMediaPlayer::mediaStatusChanged QMediaPlayer::InvalidMediabut that is not true, it is an mp3 file, and it is reading from local directory, so why is it invalid from Resources ?!
-
@kshegunov Q_ASSERT(QFile::exists(filePath)); is not outputing anything and app is not crashing, so this means the file is available right? but still it is an invalid media, i tried to convert to .wav but still it is an invalid media !
-
i saw a post where people are copying the audio file from the resources file to a temporary local directory, then playing it from the local directory, then deleting it.
This means it is not possible to play audio from resources, its kind of insane, isnt it ?
-
const QString filePath(":/music/music/sound.mp3"); Q_ASSERT(QFile::exists(filePath)); QFile file2(QDir::tempPath() + "/temp0.mp3"); if (file2.open(QIODevice::ReadWrite)) { QFile workFile(filePath); if(workFile.open(QIODevice::ReadOnly)) { file2.write(workFile.readAll()); workFile.close(); } file2.close(); } player->setMedia(QUrl::fromLocalFile((QDir::tempPath() + "/temp0.mp3"))); player->setVolume(50); player->play();
this code is working, but its too bad i need to copy from resources to temporary file to be able to play the audio, that is bad...
-
@Xena_o said in Audio not playing from .qrc resources:
This means it is not possible to play audio from resources, its kind of insane, isnt it ?
I don't think that it's not possible.
Have you tried it usingQSound
instead ofQMediaPlayer
?@aha_1980 said that it worked:
How does your resource file look like?
-
@Pl45m4 wow i get a progress with this !
QSound::play(":/music/music/sound.mp3"); throws
QSoundEffect(qaudio): Error decoding source file::/music/music/sound.mp3but
QSound::play(":/music/music/sound.wav"); (i converted the file) this one is WORKING !
too bad it doesnt handle mp3 or maybe i need add extra params, will look it.
edit: seems QSound do not support mp3, too bad, well wav is better than nothing
thanks to everybody for participation and help :-)
-
@Xena_o I have checked by adding .mp3 files to resource in QT musicplayer example,
and it's working perfectly fine.I have accessed the url using
QUrl url = QUrl("qrc:///music/sound.mp3"); player->setMedia(url); player->play();
looks like there is no need to copy into temp file.
Got hint from Qt Doc for resources
https://doc.qt.io/qt-5/resources.htmlFor example, the file path :/images/cut.png or the URL qrc:///images/cut.png would give access to the cut.png file, whose location in the application's source tree is images/cut.png.
-
My example works with Qt 6.2.4. You can download it from DropBox here. Many thanks to the guys in this topic: How to play sounds using QMediaPlayer
QT += core gui multimedia greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++17 # You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ main.cpp \ widget.cpp HEADERS += \ widget.h # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target RESOURCES += \ audio.qrc
widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QtWidgets/QWidget> #include <QtMultimedia/QMediaPlayer> class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); private slots: void play(); private: QMediaPlayer mediaPlayer; }; #endif // WIDGET_H
widget.cpp
#include "widget.h" #include <QtCore/QUrl> #include <QtWidgets/QPushButton> #include <QtMultimedia/QAudioOutput> Widget::Widget(QWidget *parent) : QWidget(parent) { mediaPlayer.setSource(QUrl("qrc:/assets/audio/music.wav")); mediaPlayer.setAudioOutput(new QAudioOutput); QPushButton *playButton = new QPushButton("Play", this); connect(playButton, &QPushButton::pressed, this, &Widget::play); connect(&mediaPlayer, &QMediaPlayer::mediaStatusChanged, [=](QMediaPlayer::MediaStatus status) -> void{ qDebug() << "QMediaPlayer::mediaStatusChanged" << status;} ); } Widget::~Widget() { } void Widget::play() { mediaPlayer.play(); qDebug() << "play"; }
main.cpp
#include "widget.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; w.show(); return a.exec(); }
-