Qt Multimedia - how to force read tags from media file - qt

It seems to be QMediaPlayer doesn't read tags of playlist files without of executing method play() of current track. Is there a way to force read tags from QMediaPlayer playlist without of playing it?
Sorry if this if a noob question, but I spent a lot of time for searches.
Thanks

Don't waste your time to use QMediaPlayer to read tags (this solution works good, but difficult for many files in list), simply use TagLib or another open-source library.
For example, 3 simple steps to use TagLib in Qt:
1.Compile taglib from source:
$ pwd
/home/user/taglib-1.9.1
$ cmake .
$ make
It's enough to deploy working instance of tag library. Really :)
2.Include headers and library in your project, simply add this or your custom path to project file:
unix:!macx: LIBS += -L$$PWD/3rdparty/taglib-1.9.1/taglib/ -ltag
INCLUDEPATH += $$PWD/3rdparty/taglib-1.9.1/taglib/Headers
DEPENDPATH += $$PWD/3rdparty/taglib-1.9.1/taglib/Headers
3.Use it, very simple function to get media tags from files, in this example artist and title of track:
#include <fileref.h>
#include <tag.h>
QString gettags(QString mediafile){
QString string;
TagLib::FileRef file(mediafile.toUtf8());
TagLib::String artist_string = file.tag()->artist();
TagLib::String title_string = file.tag()->title();
QString artist = QString::fromStdWString(artist_string.toWString());
QString title = QString::fromStdWString(title_string.toWString());
string = artist + " - " + title;
return string;
}

For the current QT/OSX, use this project file snippet (change paths for your system)
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.11
LIBS += -L/Users/sir/prg.qt/TuneMerge/taglib-1.11.1/taglib/ -ltag -lz
INCLUDEPATH += /Users/sir/prg.qt/TuneMerge/taglib-1.11.1/
INCLUDEPATH += /Users/sir/prg.qt/TuneMerge/taglib-1.11.1/taglib/
INCLUDEPATH += /Users/sir/prg.qt/TuneMerge/taglib-1.11.1/taglib/toolkit/
DEPENDPATH += /Users/sir/prg.qt/TuneMerge/taglib-1.11.1/taglib

Related

Qt Plugin Loading fails (specified module could not be found)

For some reason I am unable to load my plugins anymore, although it has worked previously. I have a plugin loader code in my MainWindow, which is supposed to load every .dll found in a specific folder. The MainWindow Code contains the following:
Interface
#ifndef PLUGININTERFACE_H
#define PLUGININTERFACE_H
#include <QtPlugin>
// forward declarations
class MainWindow;
struct P3DData;
class PluginInterface
{
public:
virtual bool createPublisher(MainWindow*, P3DData*) = 0;
};
#define PLUGIN_INTERFACE_iid "PluginInterface"
Q_DECLARE_INTERFACE(PluginInterface, PLUGIN_INTERFACE_iid)
#endif // PLUGININTERFACE_H
loadPlugins()
bool MainWindow::loadPlugins()
{
QDir pluginsDir(qApp->applicationDirPath());
pluginsDir.cd("plugins");
const auto entryList = pluginsDir.entryList(QDir::Files);
for(const QString &fileName : entryList)
{
QString dllPath = pluginsDir.absoluteFilePath(fileName);
QPluginLoader* loader = new QPluginLoader(dllPath);
loaderList.push_back(loader);
QObject *plugin = loader->instance();
if (plugin)
{
pluginList.push_back(qobject_cast<PluginInterface *>(plugin));
pluginList.last()->createPublisher(this, simDataPtr);
pluginCount++;
continue;
}
else
{
qDebug() << "[PluginLoader] '" + fileName + "': " + loader->errorString();
delete loaderList.takeLast();
}
}
}
Besides my MainWindow, there is another subdir in my project, which is the plugin "Position". The plugin is deployed into the correct "plugins" folder, which the loadPlugin() method from the MainWindow iterates through. The plugin uses following code to implement the interface:
#include <QObject>
#include "MainWindow.h"
class PositionPublisher : public QObject, PluginInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "PluginInterface")
Q_INTERFACES(PluginInterface)
public:
PositionPublisher();
~PositionPublisher();
bool createPublisher(MainWindow* _window, P3DData* _simDataPtr) override;
//...
};
When trying to run loadPlugins() now, it checks the correct Position.dll file but the "if(plugin)" part returns false and loader->errorString() is executed giving the following error:
[PluginLoader] 'Position.dll': Cannot load library
F:\DEV\build\simNET\bin\plugins\Position.dll: Cannot find the
specified module.
I have already checked and tried the following:
the Plugins folder actually contains the Position.dll file
both projects (MainWindow and Plugin) are built in release mode
the dependencies of the plugin (two libs) exist and the specified path in the pro file is correct
.pro file of plugin:
QT += widgets
TEMPLATE = lib
CONFIG += c++11
CONFIG += plugin
CONFIG += release
SOURCES += \
Position.cpp \
PositionPubSubTypes.cpp \
PositionPublisher.cpp
HEADERS += \
Position.h \
PositionPubSubTypes.h \
PositionPublisher.h
DISTFILES += \
Position.idl
INCLUDEPATH += ../../application
TARGET = $$qtLibraryTarget(Position)
DESTDIR = ../../bin/plugins
INCLUDEPATH += "F:/DEV/prog/FastRTPSv1.5/include"
DEPENDPATH += "F:/DEV/prog/FastRTPSv1.5/include"
LIBS += -L"F:/DEV/prog/FastRTPSv1.5/lib/x64Win64VS2015" -lfastrtps-1.5
PRE_TARGETDEPS += F:/DEV/prog/FastRTPSv1.5/lib/x64Win64VS2015/fastrtps-1.5.lib
INCLUDEPATH += 'F:/Programme/Prepar3D v4/SDK/inc/SimConnect'
DEPENDPATH += 'F:/Programme/Prepar3D v4/SDK/inc/SimConnect'
LIBS += -L'F:/Programme/Prepar3D v4/SDK/lib/SimConnect' -lSimConnect
PRE_TARGETDEPS += 'F:/Programme/Prepar3D v4/SDK/lib/SimConnect/SimConnect.lib'
Does anyone have an idea why it does not load the plugin??
Qt plugin loader is trying to tell you that a Qt module used in your plugin doesn't exist so first you need to check which Qt modules your plugin depends on then,
If you're trying to run the application from Qt Creator itself, and it gives you this error, then maybe the DLL file got deleted for some reason or you're trying to use the plugin with a Qt version that doesn't have its needed modules. (for example, Qt6 doesn't contain the QtSerialPort module but Qt5 did (at the time of writing this)).
If you're trying to run the application directly outside Qt Creator then you need to copy the required module's dll file into your applications root directory.

Qt conditional file includes in .pro

I have a problem with including a file through ".pro" file.
If the ARCH equals "64bit" ,this is an environment variable of my system, I will include a 'function1.h' to my project.
else, include 'function2.h'
But only a message works properly and both files are included together.
I mean, I only can see a Project Message saying "Hello 64-bit" , but I can see two files in my project file list. function1.h and function2.h.
what's the problem and how can I make this out
here is my code
QT += quick
CONFIG += c++11
SOURCES += main.cpp
OS_IS = $$(ARCH)
equals(OS_IS,64bit){
message("Hello 64-bit")
HEADERS += function1.h
}else{
message("Hello 32-bit")
HEADERS += function2.h
}
...
Thank you in advance
I think that your problem must be in other place. This is working to me as expected:
OS_IS = $$(ARCH)
message("Headers before:" $$HEADERS)
equals(OS_IS,"64bit"){
message("Hello 64-bit")
HEADERS += function1.h
}else{
message("Hello 32-bit")
HEADERS += function2.h
}
message("Headers after:" $$HEADERS)

qmake and generated qm files

What is the best (proper) way to organize compiled translations (*.qm) into resources?
*.qm files referred in qrc file and generated by two (three) extra targets this way:
trans_update.commands = lupdate $$_PRO_FILE_
trans_update.depends = $$_PRO_FILE_
trans_release.commands = lrelease $$_PRO_FILE_
trans_release.depends = trans_update $$TRANSLATIONS
translate.depends = trans_release
QMAKE_EXTRA_TARGETS += trans_update trans_release translate deploy
CONFIG(release, debug|release) {
DESTDIR=release
PRE_TARGETDEPS += translate
}
but the problem is at the moment qmake runs first time, there're no qm files generated yet and make prints errors like:
RCC: Error in 'qml.qrc': Cannot find file ...
I don't like an idea of saving compiled qm files into VSC.
Is there a way to organize it nicely?
I like to point out a solution which I use in some projects. It might be far from perfect, but it works out nicely.
CONFIG(release, debug|release) {
TRANSLATION_TARGET_DIR = $${OUT_PWD}/release/translations
LANGUPD_OPTIONS = -locations relative -no-ui-lines
LANGREL_OPTIONS = -compress -nounfinished -removeidentical
} else {
TRANSLATION_TARGET_DIR = $${OUT_PWD}/debug/translations
LANGUPD_OPTIONS =
LANGREL_OPTIONS = -markuntranslated "MISS_TR "
}
isEmpty(QMAKE_LUPDATE) {
win32:LANGUPD = $$[QT_INSTALL_BINS]\lupdate.exe
else:LANGUPD = $$[QT_INSTALL_BINS]/lupdate
}
isEmpty(QMAKE_LRELEASE) {
win32:LANGREL = $$[QT_INSTALL_BINS]\lrelease.exe
else:LANGREL = $$[QT_INSTALL_BINS]/lrelease
}
langupd.command = \
$$LANGUPD $$LANGUPD_OPTIONS $$shell_path($$_PRO_FILE_) -ts $$_PRO_FILE_PWD_/$$TRANSLATIONS
langrel.depends = langupd
langrel.input = TRANSLATIONS
langrel.output = $$TRANSLATION_TARGET_DIR/${QMAKE_FILE_BASE}.qm
langrel.commands = \
$$LANGREL $$LANGREL_OPTIONS ${QMAKE_FILE_IN} -qm $$TRANSLATION_TARGET_DIR/${QMAKE_FILE_BASE}.qm
langrel.CONFIG += no_link
QMAKE_EXTRA_TARGETS += langupd
QMAKE_EXTRA_COMPILERS += langrel
PRE_TARGETDEPS += langupd compiler_langrel_make_all
There might be a sensful tweak to lupdate options because the various builds (release and debug) generate different *.ts files which then trigger a change in the used VCS.
I also like to guide the tended reader to an example where experts use it.
The recommended way -- which may not have been available at the time this question was originally asked would be to use
TRANSLATIONS += <your *.ts files>
CONFIG += lrelease embed_translations
If you really need/want to build the qm files separately, I'd point to what qmake does with the above config and adapt it according to your needs. See https://github.com/qt/qtbase/blob/5.15.2/mkspecs/features/lrelease.prf
(Basically, it creates and adds a list of resources to RESOURCES).

How to link to qaxserver.def entities properly

all
I'm trying to create ActiveX server with Qt5.2.0.
According to some pieces of information I have, to create a simple ActiveX server (which exports one object) it's enough to:
have such .pro file
TEMPLATE = lib
CONFIG += dll axserver
TARGET = simpleServer
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
QT += core
RC_FILE = qaxserver.rc
DEF_FILE = qaxserver.def
HEADERS += myserver.h
SOURCES += main.cpp
SOURCES += myserver.cpp
have such main.cpp file
#include "ActiveQt/QAxFactory"
#include "myserver.h"
QAXFACTORY_DEFAULT( MyServer, 5 id's )
the class should inherit QWidget and QAxBindable
there should be file qaxserver.rc. in my case it's content is 1 TYPELIB "simpleServer.pro"
there should be fie qaxserver.def with default contents:
; mfc_test.def : Declares the module parameters.
EXPORTS
DllCanUnloadNow PRIVATE
DllGetClassObject PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
DumpIDL PRIVATE
the problem is that these 5 names are undefined for Visual Studio's linker.
How to solve the problem?
the error is:
error LNK2001: unresolved external symbol DllCanUnloadNow
need to add QT += axserver in .pro file

Linking Qt DLL to Qt App - unresolved references

I've just installed Qt 4.7.4 and trying to make a simple Qt App that uses Qt DLL. I added export/import in a class in DLL through ifdef as usual but when compiling App I het unresolved references. I also set that App depends on the DLL.
Here are the main files:
Lib.pro
QT -= gui
TARGET = Lib
TEMPLATE = lib
DEFINES += LIB_LIBRARY
SOURCES += lib.cpp
HEADERS += lib.h\
Lib_global.h
symbian {
MMP_RULES += EXPORTUNFROZEN
TARGET.UID3 = 0xE10C4E25
TARGET.CAPABILITY =
TARGET.EPOCALLOWDLLDATA = 1
addFiles.sources = Lib.dll
addFiles.path = !:/sys/bin
DEPLOYMENT += addFiles
}
unix:!symbian {
maemo5 {
target.path = /opt/usr/lib
} else {
target.path = /usr/lib
}
INSTALLS += target
}
App.pro
QT += core gui
TARGET = App
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
lib.h
#ifndef LIB_H
#define LIB_H
#include "Lib_global.h"
#include <QString>
class LIBSHARED_EXPORT Lib {
public:
Lib();
~Lib();
QString Hello(QString a);
};
#endif // LIB_H
Lib_global.h
#ifndef LIB_GLOBAL_H
#define LIB_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(LIB_LIBRARY)
# define LIBSHARED_EXPORT Q_DECL_EXPORT
#else
# define LIBSHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // LIB_GLOBAL_H
What's wrong with this code? Why is it unresolved reference?
In App I just include "../Lib/lib.h" and try to use the class.
What looks to be missing is the link between your application and your dynamic library.
I usually do something like this for my desktop (linux) apps:
INCLUDEPATH += ./include
LIBS += -L./lib -lLib
Where:
INCLUDEPATH defines the path to where your shared library .h files are located.
LIBS defines the path to where your built library is.
You can find the relevant documentation here: QMake - Declaring Other Libraries
Updated:
I was able to build the project (Linux Qt v4.7.4) and link to the library using the code you posted. I will try to clarify as my response may not be entirely clear.
The INCLUDEPATH and LIBS variables must be added to the App.pro file.
For the linker to properly find the library the paths must be adjusted to the paths you are using for your project:
LIBS += -L PATH -l LIBNAME
Supposing your folder structure is similar to the following:
Project
|_ Lib (your sharded library project files)
|_ App (your application project files)
You would adjust the variables like so:
INCLUDEPATH += ../Lib
LIBS += -L../Lib -lLib
Note that you link differently depending on your platform, you can do something like this to cover Windows and Linux:
unix {
INCLUDEPATH += ../Lib
LIBS += -L../Lib -lLib
}
win32 {
INCLUDEPATH += ../Lib
LIBS += ../Lib.lib
}

Resources