Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
Please login to access the resource
multimedia:apps
clementine
clementine-taglib2.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File clementine-taglib2.patch of Package clementine
From 4d29a0959bc30e55fa682d19c9e832227b68ad98 Mon Sep 17 00:00:00 2001 From: Jonas Kvinge <jonas@jkvinge.net> Date: Sun, 17 Mar 2024 15:32:40 +0100 Subject: [PATCH 3/3] Fix build with TagLib 2 Signed-off-by: Jonas Kvinge <jonas@jkvinge.net> --- CMakeLists.txt | 43 ++----------------- ext/libclementine-tagreader/cloudstream.cpp | 46 ++++++++++++++++++++- ext/libclementine-tagreader/cloudstream.h | 44 +++++++++++++++----- ext/libclementine-tagreader/tagreader.cpp | 34 ++++++++------- include/clementine-config.h.in | 2 +- 5 files changed, 102 insertions(+), 67 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 20e5a71..f063d3e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,7 +82,10 @@ pkg_check_modules(LIBMYGPO_QT5 libmygpo-qt5>=1.0.9) pkg_check_modules(LIBPULSE libpulse) pkg_check_modules(LIBXML libxml-2.0) pkg_check_modules(LIBSPOTIFY libspotify>=12.1.45) -pkg_check_modules(TAGLIB taglib) +pkg_check_modules(TAGLIB REQUIRED taglib>=1.11.1) +if (TAGLIB_VERSION VERSION_GREATER_EQUAL 2.0) + set(HAVE_TAGLIB2 ON) +endif() if (WIN32) find_package(ZLIB REQUIRED) @@ -129,44 +132,6 @@ if (Qt5LinguistTools_FOUND) set(QT_LCONVERT_EXECUTABLE Qt5::lconvert) endif() - -# Only use system taglib if it's greater than 1.11.1 -# There is a bug in version 1.11.1 corrupting Ogg files, see: https://github.com/taglib/taglib/issues/864 -# If you decide to use the systems taglib, make sure it has been patched with the following commit: -# https://github.com/taglib/taglib/commit/9336c82da3a04552168f208cd7a5fa4646701ea4 -# The current taglib in 3rdparty also has the following features used by Clementine: -# - Audio file detection by content. -# -if (TAGLIB_VERSION VERSION_GREATER 1.11.1) - option(USE_SYSTEM_TAGLIB "Use system taglib" ON) -else() - option(USE_SYSTEM_TAGLIB "Use system taglib" OFF) -endif() - -if (TAGLIB_FOUND AND USE_SYSTEM_TAGLIB) - if (TAGLIB_VERSION VERSION_GREATER 1.11.1) - message(STATUS "Using system taglib library") - else() - message(WARNING "Using system taglib library. Version 1.11.1 or less has a bug corrupting Ogg files, make sure your systems version has been patched!") - endif() - set(CMAKE_REQUIRED_INCLUDES "${TAGLIB_INCLUDE_DIRS}") - set(CMAKE_REQUIRED_LIBRARIES "${TAGLIB_LIBRARIES}") - check_cxx_source_compiles("#include <opusfile.h> - int main() { char *s; TagLib::Ogg::Opus::File opusfile(s); return 0;}" TAGLIB_HAS_OPUS) - set(CMAKE_REQUIRED_INCLUDES) - set(CMAKE_REQUIRED_LIBRARIES) -else() - message(STATUS "Using builtin taglib library") - set(TAGLIB_VERSION 1.11.1) - set(TAGLIB_INCLUDE_DIRS "${CMAKE_BINARY_DIR}/3rdparty/taglib/headers/taglib/;${CMAKE_BINARY_DIR}/3rdparty/taglib/headers/") - set(TAGLIB_LIBRARY_DIRS "") - set(TAGLIB_LIBRARIES tag) - set(TAGLIB_HAS_OPUS ON) - add_subdirectory(3rdparty/utf8-cpp) - add_subdirectory(3rdparty/taglib) - add_definitions(-DTAGLIB_STATIC) -endif() - if(LASTFM5_INCLUDE_DIRS AND LASTFM51_INCLUDE_DIRS) set(HAVE_LIBLASTFM1 ON) endif() diff --git a/ext/libclementine-tagreader/cloudstream.cpp b/ext/libclementine-tagreader/cloudstream.cpp index 60786fa..3e568f8 100644 --- a/ext/libclementine-tagreader/cloudstream.cpp +++ b/ext/libclementine-tagreader/cloudstream.cpp @@ -15,6 +15,8 @@ along with Clementine. If not, see <http://www.gnu.org/licenses/>. */ +#include "clementine-config.h" + #include "cloudstream.h" #include <taglib/id3v2framefactory.h> @@ -32,8 +34,14 @@ static const int kTaglibPrefixCacheBytes = 64 * 1024; // Should be enough. static const int kTaglibSuffixCacheBytes = 8 * 1024; } // namespace -CloudStream::CloudStream(const QUrl& url, const QString& filename, - const long length, const QString& auth) +CloudStream::CloudStream(const QUrl& url, + const QString& filename, +#ifdef HAVE_TAGLIB2 + const size_t length, +#else + const long length, +#endif + const QString& auth) : url_(url), filename_(filename), encoded_filename_(filename_.toUtf8()), @@ -91,7 +99,11 @@ void CloudStream::Precache() { clear(); } +#ifdef HAVE_TAGLIB2 +TagLib::ByteVector CloudStream::readBlock(size_t length) { +#else TagLib::ByteVector CloudStream::readBlock(ulong length) { +#endif const uint start = cursor_; const uint end = qMin(cursor_ + length - 1, length_ - 1); @@ -144,11 +156,19 @@ void CloudStream::writeBlock(const TagLib::ByteVector&) { qLog(Debug) << Q_FUNC_INFO << "not implemented"; } +#ifdef HAVE_TAGLIB2 +void CloudStream::insert(const TagLib::ByteVector&, TagLib::offset_t, size_t) { +#else void CloudStream::insert(const TagLib::ByteVector&, ulong, ulong) { +#endif qLog(Debug) << Q_FUNC_INFO << "not implemented"; } +#ifdef HAVE_TAGLIB2 +void CloudStream::removeBlock(TagLib::offset_t, size_t) { +#else void CloudStream::removeBlock(ulong, ulong) { +#endif qLog(Debug) << Q_FUNC_INFO << "not implemented"; } @@ -159,14 +179,22 @@ bool CloudStream::readOnly() const { bool CloudStream::isOpen() const { return true; } +#ifdef HAVE_TAGLIB2 +void CloudStream::seek(TagLib::offset_t offset, TagLib::IOStream::Position p) { +#else void CloudStream::seek(long offset, TagLib::IOStream::Position p) { +#endif switch (p) { case TagLib::IOStream::Beginning: cursor_ = offset; break; case TagLib::IOStream::Current: +#ifdef HAVE_TAGLIB2 + cursor_ = qMin(static_cast<size_t>(cursor_ + offset), length_); +#else cursor_ = qMin(ulong(cursor_ + offset), length_); +#endif break; case TagLib::IOStream::End: @@ -178,11 +206,25 @@ void CloudStream::seek(long offset, TagLib::IOStream::Position p) { void CloudStream::clear() { cursor_ = 0; } +#ifdef HAVE_TAGLIB2 + +TagLib::offset_t CloudStream::tell() const { return cursor_; } + +TagLib::offset_t CloudStream::length() { return length_; } + +#else + long CloudStream::tell() const { return cursor_; } long CloudStream::length() { return length_; } +#endif + +#ifdef HAVE_TAGLIB2 +void CloudStream::truncate(TagLib::offset_t) { +#else void CloudStream::truncate(long) { +#endif qLog(Debug) << Q_FUNC_INFO << "not implemented"; } diff --git a/ext/libclementine-tagreader/cloudstream.h b/ext/libclementine-tagreader/cloudstream.h index 7002b3a..24e31c2 100644 --- a/ext/libclementine-tagreader/cloudstream.h +++ b/ext/libclementine-tagreader/cloudstream.h @@ -18,6 +18,8 @@ #ifndef GOOGLEDRIVESTREAM_H #define GOOGLEDRIVESTREAM_H +#include "clementine-config.h" + #include <QList> #include <QNetworkAccessManager> #include <QObject> @@ -30,22 +32,38 @@ class CloudStream : public QObject, public TagLib::IOStream { Q_OBJECT public: - CloudStream(const QUrl& url, const QString& filename, const long length, + CloudStream(const QUrl& url, + const QString& filename, +#ifdef HAVE_TAGLIB2 + const size_t length, +#else + const long length, +#endif const QString& auth); // Taglib::IOStream virtual TagLib::FileName name() const; - virtual TagLib::ByteVector readBlock(ulong length); - virtual void writeBlock(const TagLib::ByteVector&); - virtual void insert(const TagLib::ByteVector&, ulong, ulong); +#ifdef HAVE_TAGLIB2 + virtual TagLib::ByteVector readBlock(size_t length) override; + virtual void insert(const TagLib::ByteVector&, TagLib::offset_t, size_t) override; + virtual void removeBlock(TagLib::offset_t, size_t) override; + virtual void seek(TagLib::offset_t offset, TagLib::IOStream::Position p) override; + virtual void truncate(TagLib::offset_t) override; + virtual TagLib::offset_t tell() const override; + virtual TagLib::offset_t length() override; +#else + virtual TagLib::ByteVector readBlock(ulong length) override; + virtual void insert(const TagLib::ByteVector&, ulong, ulong) override; virtual void removeBlock(ulong, ulong); - virtual bool readOnly() const; - virtual bool isOpen() const; - virtual void seek(long offset, TagLib::IOStream::Position p); - virtual void clear(); - virtual long tell() const; - virtual long length(); - virtual void truncate(long); + virtual void seek(long offset, TagLib::IOStream::Position p) override; + virtual void truncate(long) override; + virtual long tell() const override; + virtual long length() override; +#endif + virtual void writeBlock(const TagLib::ByteVector&) override; + virtual bool readOnly() const override; + virtual bool isOpen() const override; + virtual void clear() override; google::sparsetable<char>::size_type cached_bytes() const { return cache_.num_nonempty(); @@ -68,7 +86,11 @@ class CloudStream : public QObject, public TagLib::IOStream { const QUrl url_; const QString filename_; const QByteArray encoded_filename_; +#ifdef HAVE_TAGLIB2 + const size_t length_; +#else const ulong length_; +#endif const QString auth_; int cursor_; diff --git a/ext/libclementine-tagreader/tagreader.cpp b/ext/libclementine-tagreader/tagreader.cpp index e6fc559..c4e861b 100644 --- a/ext/libclementine-tagreader/tagreader.cpp +++ b/ext/libclementine-tagreader/tagreader.cpp @@ -38,9 +38,7 @@ #include <QUrl> #include <QVector> #include <memory> -#ifdef TAGLIB_HAS_OPUS #include <opusfile.h> -#endif #include <apetag.h> #include <oggflacfile.h> #include <popularimeterframe.h> @@ -198,7 +196,7 @@ void TagReader::ReadFile(const QString& filename, // Find album artists TagLib::APE::ItemListMap::ConstIterator it = items.find("ALBUM ARTIST"); if (it != items.end()) { - TagLib::StringList album_artists = it->second.toStringList(); + TagLib::StringList album_artists = it->second.values(); if (!album_artists.isEmpty()) { Decode(album_artists.front(), nullptr, song->mutable_albumartist()); } @@ -243,22 +241,22 @@ void TagReader::ReadFile(const QString& filename, } if (items.contains("BPM")) { - Decode(items["BPM"].toStringList().toString(", "), nullptr, + Decode(items["BPM"].values().toString(", "), nullptr, song->mutable_performer()); } if (items.contains("PERFORMER")) { - Decode(items["PERFORMER"].toStringList().toString(", "), nullptr, + Decode(items["PERFORMER"].values().toString(", "), nullptr, song->mutable_performer()); } if (items.contains("COMPOSER")) { - Decode(items["COMPOSER"].toStringList().toString(", "), nullptr, + Decode(items["COMPOSER"].values().toString(", "), nullptr, song->mutable_composer()); } if (items.contains("GROUPING")) { - Decode(items["GROUPING"].toStringList().toString(" "), nullptr, + Decode(items["GROUPING"].values().toString(" "), nullptr, song->mutable_grouping()); } @@ -565,8 +563,8 @@ void TagReader::ReadFile(const QString& filename, if (fileref->audioProperties()) { song->set_bitrate(fileref->audioProperties()->bitrate()); song->set_samplerate(fileref->audioProperties()->sampleRate()); - song->set_length_nanosec(fileref->audioProperties()->length() * - kNsecPerSec); + song->set_length_nanosec(fileref->audioProperties()->lengthInMilliseconds() * + kNsecPerMsec); } // Get the filetype if we can @@ -789,10 +787,8 @@ cpb::tagreader::SongMetadata_Type TagReader::GuessFileType( return cpb::tagreader::SongMetadata_Type_OGGSPEEX; if (dynamic_cast<TagLib::Ogg::Vorbis::File*>(fileref->file())) return cpb::tagreader::SongMetadata_Type_OGGVORBIS; -#ifdef TAGLIB_HAS_OPUS if (dynamic_cast<TagLib::Ogg::Opus::File*>(fileref->file())) return cpb::tagreader::SongMetadata_Type_OGGOPUS; -#endif if (dynamic_cast<TagLib::RIFF::AIFF::File*>(fileref->file())) return cpb::tagreader::SongMetadata_Type_AIFF; if (dynamic_cast<TagLib::RIFF::WAV::File*>(fileref->file())) @@ -1376,31 +1372,41 @@ bool TagReader::ReadCloudFile(const QUrl& download_url, const QString& title, std::unique_ptr<TagLib::File> tag; if (mime_type == "audio/mpeg" && title.endsWith(".mp3", Qt::CaseInsensitive)) { +#ifdef HAVE_TAGLIB2 + tag.reset(new TagLib::MPEG::File(stream.get(), true, + TagLib::AudioProperties::Accurate, + TagLib::ID3v2::FrameFactory::instance())); +#else tag.reset(new TagLib::MPEG::File(stream.get(), TagLib::ID3v2::FrameFactory::instance(), TagLib::AudioProperties::Accurate)); +#endif } else if (mime_type == "audio/mp4" || (mime_type == "audio/mpeg" && title.endsWith(".m4a", Qt::CaseInsensitive))) { tag.reset(new TagLib::MP4::File(stream.get(), true, TagLib::AudioProperties::Accurate)); } -#ifdef TAGLIB_HAS_OPUS else if ((mime_type == "application/opus" || mime_type == "audio/opus" || mime_type == "application/ogg" || mime_type == "audio/ogg") && title.endsWith(".opus", Qt::CaseInsensitive)) { tag.reset(new TagLib::Ogg::Opus::File(stream.get(), true, TagLib::AudioProperties::Accurate)); } -#endif else if (mime_type == "application/ogg" || mime_type == "audio/ogg") { tag.reset(new TagLib::Ogg::Vorbis::File(stream.get(), true, TagLib::AudioProperties::Accurate)); } else if (mime_type == "application/x-flac" || mime_type == "audio/flac" || mime_type == "audio/x-flac") { +#ifdef HAVE_TAGLIB2 + tag.reset(new TagLib::FLAC::File(stream.get(), true, + TagLib::AudioProperties::Accurate, + TagLib::ID3v2::FrameFactory::instance())); +#else tag.reset(new TagLib::FLAC::File(stream.get(), TagLib::ID3v2::FrameFactory::instance(), true, TagLib::AudioProperties::Accurate)); +#endif } else if (mime_type == "audio/x-ms-wma") { tag.reset(new TagLib::ASF::File(stream.get(), true, TagLib::AudioProperties::Accurate)); @@ -1431,7 +1437,7 @@ bool TagReader::ReadCloudFile(const QUrl& download_url, const QString& title, song->set_type(cpb::tagreader::SongMetadata_Type_STREAM); if (tag->audioProperties()) { - song->set_length_nanosec(tag->audioProperties()->length() * kNsecPerSec); + song->set_length_nanosec(tag->audioProperties()->lengthInMilliseconds() * kNsecPerMsec); } return true; } diff --git a/include/clementine-config.h.in b/include/clementine-config.h.in index eb6dbfc..8fa8772 100644 --- a/include/clementine-config.h.in +++ b/include/clementine-config.h.in @@ -48,11 +48,11 @@ #cmakedefine HAVE_OPENGL #cmakedefine HAVE_TRANSLATIONS #cmakedefine HAVE_SPOTIFY -#cmakedefine TAGLIB_HAS_OPUS #cmakedefine USE_INSTALL_PREFIX #cmakedefine USE_SYSTEM_PROJECTM #cmakedefine USE_SYSTEM_SHA2 #cmakedefine USE_BUNDLE +#cmakedefine HAVE_TAGLIB2 #define USE_BUNDLE_DIR "${USE_BUNDLE_DIR}" -- 2.44.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor