feat: get audio file properties from taglib
This commit is contained in:
parent
98d352a7c1
commit
35778d97bf
|
@ -14,6 +14,9 @@ set(CMAKE_CXX_STANDARD 11)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
find_package(Qt5 COMPONENTS Widgets Multimedia Network REQUIRED)
|
find_package(Qt5 COMPONENTS Widgets Multimedia Network REQUIRED)
|
||||||
|
find_package(PkgConfig)
|
||||||
|
|
||||||
|
pkg_check_modules(TagLib REQUIRED taglib)
|
||||||
|
|
||||||
set (EXE_NAME pmusic)
|
set (EXE_NAME pmusic)
|
||||||
|
|
||||||
|
@ -35,7 +38,8 @@ add_executable(${EXE_NAME}
|
||||||
ID3v2Pic.h
|
ID3v2Pic.h
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(${EXE_NAME} PRIVATE Qt5::Widgets Qt5::Multimedia Qt5::Network)
|
target_include_directories(${EXE_NAME} PRIVATE ${TagLib_INCLUDE_DIRS})
|
||||||
|
target_link_libraries(${EXE_NAME} PRIVATE Qt5::Widgets Qt5::Multimedia Qt5::Network ${TagLib_LINK_LIBRARIES})
|
||||||
|
|
||||||
# Extra build settings
|
# Extra build settings
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
|
|
24
README.md
24
README.md
|
@ -1,5 +1,6 @@
|
||||||
_**This is a not ready to use, toy project**_
|
_**This is a not ready to use, toy project**_
|
||||||
|
|
||||||
|
Since **I** just need a simple player which *just works* right now, so I did many things in a dirty way. Don't feel so weird if you saw something I did in this project is using a bad approach.
|
||||||
|
|
||||||
## Note
|
## Note
|
||||||
|
|
||||||
|
@ -13,6 +14,29 @@ Windows|[Supported Formats In DirectsShow](https://msdn.microsoft.com/en-us/libr
|
||||||
macOS|[Media formats supported by QuickTime Player](https://support.apple.com/en-us/HT201290)|Sorry, I don't know...
|
macOS|[Media formats supported by QuickTime Player](https://support.apple.com/en-us/HT201290)|Sorry, I don't know...
|
||||||
Unix/Linux|depends on [GStreamer](https://gstreamer.freedesktop.org/) plugins which user installed|[GStreamer Plug-ins: gst-plugins-base, gst-plugins-good, gst-plugins-ugly, gst-plugins-bad](https://gstreamer.freedesktop.org/documentation/additional/splitup.html?gi-language=c)
|
Unix/Linux|depends on [GStreamer](https://gstreamer.freedesktop.org/) plugins which user installed|[GStreamer Plug-ins: gst-plugins-base, gst-plugins-good, gst-plugins-ugly, gst-plugins-bad](https://gstreamer.freedesktop.org/documentation/additional/splitup.html?gi-language=c)
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
Current state, we need:
|
||||||
|
|
||||||
|
- `cmake` as the build system.
|
||||||
|
- `qt5` with `qt5-multimedia` since we use it for playback.
|
||||||
|
- `taglib` to get the audio file properties.
|
||||||
|
- `pkg-config` to find the installed taglib.
|
||||||
|
|
||||||
|
Then we can build it with any proper c++ compiler like g++ or msvc.
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
|
||||||
|
Just normal build process as other program. Nothing special ;)
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
Install the depts manually is a nightmare. I use [KDE Craft](https://community.kde.org/Craft) but MSYS2 should also works. FYI currently this project is not intended to works under Windows (it should works and I also did some simple test though).
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
|
||||||
|
I don't have a mac, so no support at all.
|
||||||
|
|
||||||
## About License
|
## About License
|
||||||
|
|
||||||
Since this is a toy repo, I don't spend much time about the license stuff. Currently this project use some assets and code from [ShadowPlayer](https://github.com/ShadowPower/ShadowPlayer), which have a very interesting license -- do whatever you want but cannot be used as homework -- obviously it's not a so called *free* license. I *may* do some license housecleaning works by replaceing the assets and code implementation when the code become reasonable, and the final codebase may probably released under MIT license.
|
Since this is a toy repo, I don't spend much time about the license stuff. Currently this project use some assets and code from [ShadowPlayer](https://github.com/ShadowPower/ShadowPlayer), which have a very interesting license -- do whatever you want but cannot be used as homework -- obviously it's not a so called *free* license. I *may* do some license housecleaning works by replaceing the assets and code implementation when the code become reasonable, and the final codebase may probably released under MIT license.
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
#include "ID3v2Pic.h"
|
#include "ID3v2Pic.h"
|
||||||
#include "FlacPic.h"
|
#include "FlacPic.h"
|
||||||
|
|
||||||
|
// taglib
|
||||||
|
#include <fileref.h>
|
||||||
|
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QMediaPlayer>
|
#include <QMediaPlayer>
|
||||||
#include <QMediaPlaylist>
|
#include <QMediaPlaylist>
|
||||||
|
@ -81,6 +84,43 @@ void MainWindow::loadPlaylistBySingleLocalFile(const QString &path)
|
||||||
playlist->setCurrentIndex(currentFileIndex);
|
playlist->setCurrentIndex(currentFileIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::setAudioPropertyInfoForDisplay(int sampleRate, int bitrate, int channelCount, QString audioExt)
|
||||||
|
{
|
||||||
|
QStringList uiStrs;
|
||||||
|
QStringList tooltipStrs;
|
||||||
|
|
||||||
|
auto channelStr = [](int channelCnt) {
|
||||||
|
switch (channelCnt) {
|
||||||
|
case 1:
|
||||||
|
return tr("Mono");
|
||||||
|
case 2:
|
||||||
|
return tr("Stereo");
|
||||||
|
default:
|
||||||
|
return tr("%1 Channels").arg(channelCnt);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (sampleRate >= 0) {
|
||||||
|
uiStrs << QString("%1 Hz").arg(sampleRate);
|
||||||
|
tooltipStrs << QString("Sample Rate: %1 Hz").arg(sampleRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bitrate >= 0) {
|
||||||
|
uiStrs << QString("%1 Kbps").arg(bitrate);
|
||||||
|
tooltipStrs << QString("Bitrate: %1 Kbps").arg(bitrate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channelCount >= 0) {
|
||||||
|
uiStrs << channelStr(channelCount);
|
||||||
|
tooltipStrs << QString("Channel Count: %1").arg(channelCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
uiStrs << audioExt;
|
||||||
|
|
||||||
|
ui->propLabel->setText(uiStrs.join(" | "));
|
||||||
|
ui->propLabel->setToolTip(tooltipStrs.join('\n'));
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::localSocketPlayAudioFiles(QVariant audioFilesVariant)
|
void MainWindow::localSocketPlayAudioFiles(QVariant audioFilesVariant)
|
||||||
{
|
{
|
||||||
QStringList urlStrList = audioFilesVariant.toStringList();
|
QStringList urlStrList = audioFilesVariant.toStringList();
|
||||||
|
@ -248,6 +288,8 @@ void MainWindow::on_playBtn_clicked()
|
||||||
if (m_mediaPlayer->mediaStatus() == QMediaPlayer::NoMedia) {
|
if (m_mediaPlayer->mediaStatus() == QMediaPlayer::NoMedia) {
|
||||||
loadFile();
|
loadFile();
|
||||||
m_mediaPlayer->play();
|
m_mediaPlayer->play();
|
||||||
|
} else if (m_mediaPlayer->mediaStatus() == QMediaPlayer::InvalidMedia) {
|
||||||
|
ui->propLabel->setText("Error: InvalidMedia");
|
||||||
} else {
|
} else {
|
||||||
if (QList<QMediaPlayer::State> {QMediaPlayer::PausedState, QMediaPlayer::StoppedState}
|
if (QList<QMediaPlayer::State> {QMediaPlayer::PausedState, QMediaPlayer::StoppedState}
|
||||||
.contains(m_mediaPlayer->state())) {
|
.contains(m_mediaPlayer->state())) {
|
||||||
|
@ -364,22 +406,32 @@ void MainWindow::initConnections()
|
||||||
QUrl fileUrl = media.canonicalUrl();
|
QUrl fileUrl = media.canonicalUrl();
|
||||||
#else
|
#else
|
||||||
QUrl fileUrl = media.request().url();
|
QUrl fileUrl = media.request().url();
|
||||||
#endif // QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
#endif // QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||||
|
|
||||||
ui->titleLabel->setText(fileUrl.fileName());
|
ui->titleLabel->setText(fileUrl.fileName());
|
||||||
|
ui->titleLabel->setToolTip(fileUrl.fileName());
|
||||||
|
|
||||||
if (fileUrl.isLocalFile()) {
|
if (fileUrl.isLocalFile()) {
|
||||||
|
QString filePath(fileUrl.toLocalFile());
|
||||||
|
QString suffix(filePath.mid(filePath.lastIndexOf('.') + 1));
|
||||||
|
suffix = suffix.toUpper();
|
||||||
|
|
||||||
|
TagLib::FileRef fileRef(filePath.toLocal8Bit().data());
|
||||||
|
if(!fileRef.isNull() && fileRef.audioProperties()) {
|
||||||
|
TagLib::AudioProperties *prop = fileRef.audioProperties();
|
||||||
|
setAudioPropertyInfoForDisplay(prop->sampleRate(), prop->bitrate(), prop->channels(), suffix);
|
||||||
|
}
|
||||||
|
|
||||||
using namespace spID3;
|
using namespace spID3;
|
||||||
using namespace spFLAC;
|
using namespace spFLAC;
|
||||||
|
|
||||||
QString filePath(fileUrl.toLocalFile());
|
if (suffix == "MP3") {
|
||||||
|
|
||||||
if (filePath.endsWith(".mp3")) {
|
|
||||||
if (spID3::loadPictureData(filePath.toLocal8Bit().data())) {
|
if (spID3::loadPictureData(filePath.toLocal8Bit().data())) {
|
||||||
QByteArray picData((const char*)spID3::getPictureDataPtr(), spID3::getPictureLength());
|
QByteArray picData((const char*)spID3::getPictureDataPtr(), spID3::getPictureLength());
|
||||||
ui->coverLabel->setPixmap(QPixmap::fromImage(QImage::fromData(picData)));
|
ui->coverLabel->setPixmap(QPixmap::fromImage(QImage::fromData(picData)));
|
||||||
spID3::freePictureData();
|
spID3::freePictureData();
|
||||||
}
|
}
|
||||||
} else if (filePath.endsWith(".flac")) {
|
} else if (suffix == "FLAC") {
|
||||||
if (spFLAC::loadPictureData(filePath.toLocal8Bit().data())) {
|
if (spFLAC::loadPictureData(filePath.toLocal8Bit().data())) {
|
||||||
QByteArray picData((const char*)spFLAC::getPictureDataPtr(), spFLAC::getPictureLength());
|
QByteArray picData((const char*)spFLAC::getPictureDataPtr(), spFLAC::getPictureLength());
|
||||||
ui->coverLabel->setPixmap(QPixmap::fromImage(QImage::fromData(picData)));
|
ui->coverLabel->setPixmap(QPixmap::fromImage(QImage::fromData(picData)));
|
||||||
|
|
|
@ -23,6 +23,7 @@ public:
|
||||||
|
|
||||||
void commandlinePlayAudioFiles(QStringList audioFiles);
|
void commandlinePlayAudioFiles(QStringList audioFiles);
|
||||||
void loadPlaylistBySingleLocalFile(const QString &path);
|
void loadPlaylistBySingleLocalFile(const QString &path);
|
||||||
|
void setAudioPropertyInfoForDisplay(int sampleRate, int bitrate, int channelCount, QString audioExt);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void localSocketPlayAudioFiles(QVariant audioFilesVariant);
|
void localSocketPlayAudioFiles(QVariant audioFilesVariant);
|
||||||
|
|
|
@ -301,7 +301,7 @@ QLabel#coverLabel {
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="propLabel">
|
<widget class="QLabel" name="propLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>44100 Hz | 233 Kbps | Stereo | MP3</string>
|
<string>Drag and drop file to load</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user