From 35778d97bf8b8d85950578b4f61f5f9ce36b0d95 Mon Sep 17 00:00:00 2001 From: Gary Wang Date: Sun, 19 Apr 2020 18:22:21 +0800 Subject: [PATCH] feat: get audio file properties from taglib --- CMakeLists.txt | 6 ++++- README.md | 24 +++++++++++++++++++ mainwindow.cpp | 62 ++++++++++++++++++++++++++++++++++++++++++++++---- mainwindow.h | 1 + mainwindow.ui | 2 +- 5 files changed, 88 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 18a2d1e..ebc5cb1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,9 @@ set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Qt5 COMPONENTS Widgets Multimedia Network REQUIRED) +find_package(PkgConfig) + +pkg_check_modules(TagLib REQUIRED taglib) set (EXE_NAME pmusic) @@ -35,7 +38,8 @@ add_executable(${EXE_NAME} 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 if (WIN32) diff --git a/README.md b/README.md index a894c01..0f52726 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ _**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 @@ -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... 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 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. diff --git a/mainwindow.cpp b/mainwindow.cpp index fe2a9c4..6aeffc6 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -6,6 +6,9 @@ #include "ID3v2Pic.h" #include "FlacPic.h" +// taglib +#include + #include #include #include @@ -81,6 +84,43 @@ void MainWindow::loadPlaylistBySingleLocalFile(const QString &path) 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) { QStringList urlStrList = audioFilesVariant.toStringList(); @@ -248,6 +288,8 @@ void MainWindow::on_playBtn_clicked() if (m_mediaPlayer->mediaStatus() == QMediaPlayer::NoMedia) { loadFile(); m_mediaPlayer->play(); + } else if (m_mediaPlayer->mediaStatus() == QMediaPlayer::InvalidMedia) { + ui->propLabel->setText("Error: InvalidMedia"); } else { if (QList {QMediaPlayer::PausedState, QMediaPlayer::StoppedState} .contains(m_mediaPlayer->state())) { @@ -364,22 +406,32 @@ void MainWindow::initConnections() QUrl fileUrl = media.canonicalUrl(); #else 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->setToolTip(fileUrl.fileName()); + 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 spFLAC; - QString filePath(fileUrl.toLocalFile()); - - if (filePath.endsWith(".mp3")) { + if (suffix == "MP3") { if (spID3::loadPictureData(filePath.toLocal8Bit().data())) { QByteArray picData((const char*)spID3::getPictureDataPtr(), spID3::getPictureLength()); ui->coverLabel->setPixmap(QPixmap::fromImage(QImage::fromData(picData))); spID3::freePictureData(); } - } else if (filePath.endsWith(".flac")) { + } else if (suffix == "FLAC") { if (spFLAC::loadPictureData(filePath.toLocal8Bit().data())) { QByteArray picData((const char*)spFLAC::getPictureDataPtr(), spFLAC::getPictureLength()); ui->coverLabel->setPixmap(QPixmap::fromImage(QImage::fromData(picData))); diff --git a/mainwindow.h b/mainwindow.h index 3f87c2b..07dee36 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -23,6 +23,7 @@ public: void commandlinePlayAudioFiles(QStringList audioFiles); void loadPlaylistBySingleLocalFile(const QString &path); + void setAudioPropertyInfoForDisplay(int sampleRate, int bitrate, int channelCount, QString audioExt); public slots: void localSocketPlayAudioFiles(QVariant audioFilesVariant); diff --git a/mainwindow.ui b/mainwindow.ui index d8ceb04..d2e6382 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -301,7 +301,7 @@ QLabel#coverLabel { - 44100 Hz | 233 Kbps | Stereo | MP3 + Drag and drop file to load