Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a59e064778 | ||
|
|
655c4c66a7 | ||
|
|
407c128f65 | ||
|
|
59a261a5be | ||
|
|
ba4e1afefe | ||
|
|
98b53b81d8 | ||
|
|
8270cc0aa2 | ||
|
|
74207b1a87 | ||
|
|
77983445ce | ||
|
|
162190bcb8 | ||
|
|
86b92b20b7 | ||
|
|
2f5b60d548 | ||
|
|
c19661c977 | ||
|
|
82d101ca27 | ||
|
|
32f9c4e670 | ||
|
|
34c7225ab7 |
8
.github/ISSUE_TEMPLATE.md
vendored
8
.github/ISSUE_TEMPLATE.md
vendored
@@ -7,11 +7,9 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
See the FAQ before opening an issue: https://wiki.strawberrymusicplayer.org/wiki/FAQ
|
||||
Check the Changelog to see if the issue is already fixed: https://github.com/strawberrymusicplayer/strawberry/blob/master/Changelog
|
||||
If it's already fixed, try the latest development build from: https://builds.strawberrymusicplayer.org/
|
||||
For technical issues, questions and discussion please use the forum on https://forum.strawberrymusicplayer.org/
|
||||
Any issues related to feature requests will be closed. See the README for more details.
|
||||
- [ ] I have checked the [FAQ](https://wiki.strawberrymusicplayer.org/wiki/FAQ) for answers.
|
||||
- [ ] I have checked the [Changelog](https://github.com/strawberrymusicplayer/strawberry/blob/master/Changelog) that the issue is not already fixed.
|
||||
- [ ] I believe this issue is a bug, and not a general technical issue, question or feature requests that can be discussed on the [forum](https://forum.strawberrymusicplayer.org/).
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
19
.github/workflows/ccpp.yml
vendored
19
.github/workflows/ccpp.yml
vendored
@@ -2786,18 +2786,26 @@ jobs:
|
||||
run: |
|
||||
brew install pkg-config cmake ninja meson bison flex wget create-dmg gettext boost protobuf protobuf-c
|
||||
brew install glib glib-openssl glib-utils glib-networking gdk-pixbuf gobject-introspection orc
|
||||
brew install libffi openssl gnutls sqlite fftw libmtp libplist libsoup libxml2
|
||||
brew install libffi openssl gnutls sqlite fftw libmtp libplist libxml2
|
||||
brew install libogg libvorbis flac wavpack opus speex mpg123 lame twolame taglib chromaprint libbs2b libcdio libopenmpt faad2 faac fdk-aac musepack game-music-emu
|
||||
brew install gstreamer
|
||||
brew install qt6
|
||||
|
||||
- name: Use modified gstreamer plugin formulas
|
||||
run: |
|
||||
wget https://files.strawberrymusicplayer.org/patches/gstreamer.rb
|
||||
wget https://files.strawberrymusicplayer.org/patches/gst-plugins-base.rb
|
||||
wget https://files.strawberrymusicplayer.org/patches/gst-plugins-good.rb
|
||||
wget https://files.strawberrymusicplayer.org/patches/gst-plugins-bad.rb
|
||||
wget https://files.strawberrymusicplayer.org/patches/gst-plugins-ugly.rb
|
||||
mv gst-plugins-{base,good,bad,ugly}.rb /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/
|
||||
wget https://files.strawberrymusicplayer.org/patches/gst-libav.rb
|
||||
wget https://files.strawberrymusicplayer.org/patches/libsoup.rb
|
||||
mv gstreamer.rb gst-plugins-{base,good,bad,ugly}.rb gst-libav.rb libsoup.rb /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/
|
||||
|
||||
- name: Build and install libsoup
|
||||
run: brew install --build-from-source libsoup
|
||||
|
||||
- name: Build and install gstreamer
|
||||
run: brew install --build-from-source gstreamer
|
||||
|
||||
- name: Build and install gst-plugins-base
|
||||
run: brew install --build-from-source gst-plugins-base
|
||||
@@ -2812,7 +2820,7 @@ jobs:
|
||||
run: brew install --build-from-source gst-plugins-ugly
|
||||
|
||||
- name: Build and install gst-libav
|
||||
run: brew install gst-libav
|
||||
run: brew install --build-from-source gst-libav
|
||||
|
||||
- name: Build libgpod
|
||||
shell: bash
|
||||
@@ -2892,7 +2900,7 @@ jobs:
|
||||
upload-macos:
|
||||
name: Upload macOS DMG
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref == 'refs/heads/master'
|
||||
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/macos'
|
||||
needs:
|
||||
- build-macos
|
||||
steps:
|
||||
@@ -2911,4 +2919,3 @@ jobs:
|
||||
for i in $(find uploads -type f -name 'strawberry-*.dmg'); do
|
||||
rsync -e "ssh -p 50220 -o StrictHostKeyChecking=no" -va $i travis@echoes.jkvinge.net:/home/travis/builds/macos/
|
||||
done
|
||||
|
||||
|
||||
32
3rdparty/macdeployqt/shared.cpp
vendored
32
3rdparty/macdeployqt/shared.cpp
vendored
@@ -40,6 +40,8 @@
|
||||
#include <QDir>
|
||||
#include <QSet>
|
||||
#include <QList>
|
||||
#include <QVariant>
|
||||
#include <QVariantMap>
|
||||
#include <QStack>
|
||||
#include <QDirIterator>
|
||||
#include <QLibraryInfo>
|
||||
@@ -187,9 +189,7 @@ OtoolInfo findDependencyInfo(const QString &binaryPath)
|
||||
return info;
|
||||
}
|
||||
|
||||
static const QRegularExpression regexp(QStringLiteral(
|
||||
"^\\t(.+) \\(compatibility version (\\d+\\.\\d+\\.\\d+), "
|
||||
"current version (\\d+\\.\\d+\\.\\d+)(, weak)?\\)$"));
|
||||
static const QRegularExpression regexp(QStringLiteral("^\\t(.+) \\(compatibility version (\\d+\\.\\d+\\.\\d+), current version (\\d+\\.\\d+\\.\\d+)(, weak|, reexport)?\\)$"));
|
||||
|
||||
QString output = otool.readAllStandardOutput();
|
||||
QStringList outputLines = output.split("\n", Qt::SkipEmptyParts);
|
||||
@@ -220,6 +220,8 @@ OtoolInfo findDependencyInfo(const QString &binaryPath)
|
||||
for (const QString &outputLine : outputLines) {
|
||||
const auto match = regexp.match(outputLine);
|
||||
if (match.hasMatch()) {
|
||||
if (match.captured(1) == info.installName)
|
||||
continue; // Another arch reference to the same binary
|
||||
DylibInfo dylib;
|
||||
dylib.binaryPath = match.captured(1);
|
||||
dylib.compatibilityVersion = QVersionNumber::fromString(match.captured(2));
|
||||
@@ -300,11 +302,11 @@ FrameworkInfo parseOtoolLibraryLine(const QString &line, const QString &appBundl
|
||||
if (state == QtPath) {
|
||||
// Check for library name part
|
||||
if (part < parts.count() && parts.at(part).contains(".dylib")) {
|
||||
info.frameworkDirectory += "/" + (qtPath + currentPart + "/").simplified();
|
||||
info.frameworkDirectory += "/" + QString(qtPath + currentPart + "/").simplified();
|
||||
state = DylibName;
|
||||
continue;
|
||||
} else if (part < parts.count() && parts.at(part).endsWith(".framework")) {
|
||||
info.frameworkDirectory += "/" + (qtPath + "lib/").simplified();
|
||||
info.frameworkDirectory += "/" + QString(qtPath + "lib/").simplified();
|
||||
state = FrameworkName;
|
||||
continue;
|
||||
} else if (trimmed.startsWith("/") == false) { // If the line does not contain a full path, the app is using a binary Qt package.
|
||||
@@ -865,6 +867,18 @@ void changeInstallName(const QString &bundlePath, const FrameworkInfo &framework
|
||||
if (!framework.installName.isEmpty() && framework.installName != framework.sourceFilePath) {
|
||||
changeInstallName(framework.installName, deployedInstallName, binary);
|
||||
}
|
||||
// Workaround for the case when the library ID name is a symlink, while the dependencies
|
||||
// specified using the canonical path to the library (QTBUG-56814)
|
||||
QFileInfo fileInfo= QFileInfo(framework.installName);
|
||||
QString canonicalInstallName = fileInfo.canonicalFilePath();
|
||||
if (!canonicalInstallName.isEmpty() && canonicalInstallName != framework.installName) {
|
||||
changeInstallName(canonicalInstallName, deployedInstallName, binary);
|
||||
// some libraries' inner dependencies (such as ffmpeg, nettle) use symbol link (QTBUG-100093)
|
||||
QString innerDependency = fileInfo.canonicalPath() + "/" + fileInfo.fileName();
|
||||
if (innerDependency != canonicalInstallName && innerDependency != framework.installName) {
|
||||
changeInstallName(innerDependency, deployedInstallName, binary);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1078,7 +1092,7 @@ QString getLibInfix(const QStringList &deployedFrameworks)
|
||||
{
|
||||
QString libInfix;
|
||||
for (const QString &framework : deployedFrameworks) {
|
||||
if (framework.startsWith(QStringLiteral("QtCore")) && framework.endsWith(QStringLiteral(".framework"))) {
|
||||
if (framework.startsWith(QStringLiteral("QtCore")) && framework.endsWith(QStringLiteral(".framework")) && !framework.contains(QStringLiteral("5Compat"))) {
|
||||
Q_ASSERT(framework.length() >= 16);
|
||||
// 16 == "QtCore" + ".framework"
|
||||
const int lengthOfLibInfix = framework.length() - 16;
|
||||
@@ -1474,9 +1488,9 @@ bool deployQmlImports(const QString &appBundlePath, DeploymentInfo deploymentInf
|
||||
for (const QString &importPath : qmlImportPaths)
|
||||
argumentList << "-importPath" << importPath;
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
QString qmlImportsPath = QLibraryInfo::path(QLibraryInfo::Qml2ImportsPath);
|
||||
QString qmlImportsPath = QLibraryInfo::path(QLibraryInfo::QmlImportsPath);
|
||||
#else
|
||||
QString qmlImportsPath = QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath);
|
||||
QString qmlImportsPath = QLibraryInfo::location(QLibraryInfo::QmlImportsPath);
|
||||
#endif
|
||||
argumentList.append( "-importPath");
|
||||
argumentList.append(qmlImportsPath);
|
||||
@@ -1488,7 +1502,7 @@ bool deployQmlImports(const QString &appBundlePath, DeploymentInfo deploymentInf
|
||||
LogError() << "Could not start qmlimpoortscanner. Process error is" << qmlImportScanner.errorString();
|
||||
return false;
|
||||
}
|
||||
qmlImportScanner.waitForFinished();
|
||||
qmlImportScanner.waitForFinished(-1);
|
||||
|
||||
// log qmlimportscanner errors
|
||||
qmlImportScanner.setReadChannel(QProcess::StandardError);
|
||||
|
||||
@@ -2,6 +2,13 @@ Strawberry Music Player
|
||||
=======================
|
||||
ChangeLog
|
||||
|
||||
Version 1.0.9 (2022.09.03):
|
||||
|
||||
Bugfixes:
|
||||
* Fixed parsing album title from radio stream metadata (#1023).
|
||||
* (macOS) Fixed Strawberry not starting, incorrect rpath for libgcc_s.1.1.dylib (#1025).
|
||||
* (macOS) Fixed HTTP streaming.
|
||||
|
||||
Version 1.0.8 (2022.08.29):
|
||||
|
||||
Bugfixes:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
set(STRAWBERRY_VERSION_MAJOR 1)
|
||||
set(STRAWBERRY_VERSION_MINOR 0)
|
||||
set(STRAWBERRY_VERSION_PATCH 8)
|
||||
set(STRAWBERRY_VERSION_PATCH 9)
|
||||
#set(STRAWBERRY_VERSION_PRERELEASE rc1)
|
||||
|
||||
set(INCLUDE_GIT_REVISION OFF)
|
||||
|
||||
2
debian/control.in
vendored
2
debian/control.in
vendored
@@ -17,7 +17,7 @@ Build-Depends: debhelper (>= 11),
|
||||
libasound2-dev,
|
||||
libpulse-dev,
|
||||
libtag1-dev,
|
||||
libicu-devel,
|
||||
libicu-dev,
|
||||
@DEBIAN_BUILD_DEPENDS_QT_PACKAGES@,
|
||||
libgstreamer1.0-dev,
|
||||
libgstreamer-plugins-base1.0-dev,
|
||||
|
||||
@@ -91,7 +91,7 @@ int main(int argc, char **argv) {
|
||||
qLog(Error) << "First line" << first_line << "does not match" << filepath;
|
||||
success = false;
|
||||
}
|
||||
QRegularExpression regexp(QStringLiteral("^\\t(.+) \\(compatibility version (\\d+\\.\\d+\\.\\d+), current version (\\d+\\.\\d+\\.\\d+)(, weak)?\\)$"));
|
||||
QRegularExpression regexp(QStringLiteral("^\\t(.+) \\(compatibility version (\\d+\\.\\d+\\.\\d+), current version (\\d+\\.\\d+\\.\\d+)(, weak|, reexport)?\\)$"));
|
||||
for (const QString &output_line : output_lines) {
|
||||
|
||||
//qDebug() << "Final check on" << filepath << output_line;
|
||||
@@ -130,9 +130,6 @@ int main(int argc, char **argv) {
|
||||
else if (library.startsWith("/System/Library/") || library.startsWith("/usr/lib/")) { // System library
|
||||
continue;
|
||||
}
|
||||
else if (library.endsWith("libgcc_s.1.dylib")) { // fftw points to it for some reason.
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
qLog(Error) << "File" << filepath << "points to" << library;
|
||||
success = false;
|
||||
@@ -140,7 +137,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
else {
|
||||
qLog(Error) << "Could not parse otool output line:" << output_line;
|
||||
continue;
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1176,29 +1176,30 @@ void GstEnginePipeline::TagMessageReceived(GstMessage *msg) {
|
||||
bundle.lyrics = ParseStrTag(taglist, GST_TAG_LYRICS);
|
||||
|
||||
if (!bundle.title.isEmpty() && bundle.artist.isEmpty() && bundle.album.isEmpty()) {
|
||||
QStringList title_splitted;
|
||||
if (bundle.title.contains(" - ")) {
|
||||
QStringList title_splitted = bundle.title.split(" - ");
|
||||
bundle.artist = title_splitted.first().trimmed();
|
||||
bundle.title = title_splitted.last().trimmed();
|
||||
title_splitted = bundle.title.split(" - ");
|
||||
}
|
||||
else if (bundle.title.contains('~') && bundle.title.count('~') >= 2) {
|
||||
QStringList title_splitted = bundle.title.split('~');
|
||||
int i = 1;
|
||||
for (const QString &part : title_splitted) {
|
||||
else if (bundle.title.contains('~')) {
|
||||
title_splitted = bundle.title.split('~');
|
||||
}
|
||||
if (!title_splitted.isEmpty() && title_splitted.count() >= 2) {
|
||||
int i = 0;
|
||||
for (const QString &title_part : title_splitted) {
|
||||
++i;
|
||||
switch (i) {
|
||||
case 1:
|
||||
bundle.artist = part;
|
||||
bundle.artist = title_part.trimmed();
|
||||
break;
|
||||
case 2:
|
||||
bundle.title = part;
|
||||
bundle.title = title_part.trimmed();
|
||||
break;
|
||||
case 3:
|
||||
bundle.album = part;
|
||||
bundle.album = title_part.trimmed();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,21 +103,16 @@ void GstStartup::InitializeGStreamer() {
|
||||
|
||||
void GstStartup::SetEnvironment() {
|
||||
|
||||
QString bundle_path = QCoreApplication::applicationDirPath();
|
||||
#ifdef USE_BUNDLE
|
||||
|
||||
#ifdef USE_BUNDLE_DIR
|
||||
QString bundle_dir = USE_BUNDLE_DIR;
|
||||
if (!bundle_dir.isEmpty()) {
|
||||
bundle_path.append("/" + bundle_dir);
|
||||
}
|
||||
#endif
|
||||
QString app_path = QCoreApplication::applicationDirPath();
|
||||
QString bundle_path = app_path + "/" + USE_BUNDLE_DIR;
|
||||
|
||||
QString gio_module_path;
|
||||
QString gst_plugin_scanner;
|
||||
QString gst_plugin_path;
|
||||
QString gst_registry_filename;
|
||||
QString libsoup_library_path;
|
||||
|
||||
#ifdef USE_BUNDLE
|
||||
# if defined(Q_OS_WIN32) || defined(Q_OS_MACOS)
|
||||
gio_module_path = bundle_path + "/gio-modules";
|
||||
# endif
|
||||
@@ -126,14 +121,11 @@ void GstStartup::SetEnvironment() {
|
||||
gst_plugin_path = bundle_path + "/gstreamer";
|
||||
# endif
|
||||
# if defined(Q_OS_WIN32)
|
||||
//gst_plugin_scanner = bundle_path + "/gst-plugin-scanner.exe";
|
||||
gst_plugin_path = bundle_path + "/gstreamer-plugins";
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_WIN32) || defined(Q_OS_MACOS)
|
||||
gst_registry_filename = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + QString("/gst-registry-%1-bin").arg(QCoreApplication::applicationVersion());
|
||||
#endif
|
||||
# if defined(Q_OS_MACOS)
|
||||
libsoup_library_path = app_path + "/../Frameworks/libsoup-3.0.0.dylib";
|
||||
# endif
|
||||
|
||||
if (!gio_module_path.isEmpty()) {
|
||||
if (QDir(gio_module_path).exists()) {
|
||||
@@ -146,7 +138,7 @@ void GstStartup::SetEnvironment() {
|
||||
}
|
||||
|
||||
if (!gst_plugin_scanner.isEmpty()) {
|
||||
if (QFile(gst_plugin_scanner).exists()) {
|
||||
if (QFile::exists(gst_plugin_scanner)) {
|
||||
qLog(Debug) << "Setting GStreamer plugin scanner to" << gst_plugin_scanner;
|
||||
Utilities::SetEnv("GST_PLUGIN_SCANNER", gst_plugin_scanner);
|
||||
}
|
||||
@@ -167,11 +159,26 @@ void GstStartup::SetEnvironment() {
|
||||
}
|
||||
}
|
||||
|
||||
if (!gst_registry_filename.isEmpty()) {
|
||||
qLog(Debug) << "Setting GStreamer registry file to" << gst_registry_filename;
|
||||
Utilities::SetEnv("GST_REGISTRY", gst_registry_filename);
|
||||
if (!libsoup_library_path.isEmpty()) {
|
||||
if (QFile::exists(libsoup_library_path)) {
|
||||
Utilities::SetEnv("LIBSOUP3_LIBRARY_PATH", libsoup_library_path);
|
||||
}
|
||||
else {
|
||||
qLog(Debug) << "libsoup path does not exist:" << libsoup_library_path;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // USE_BUNDLE
|
||||
|
||||
|
||||
#if defined(Q_OS_WIN32) || defined(Q_OS_MACOS)
|
||||
QString gst_registry_filename = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + QString("/gst-registry-%1-bin").arg(QCoreApplication::applicationVersion());
|
||||
qLog(Debug) << "Setting GStreamer registry file to" << gst_registry_filename;
|
||||
Utilities::SetEnv("GST_REGISTRY", gst_registry_filename);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBPULSE
|
||||
Utilities::SetEnv("PULSE_PROP_media.role", "music");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
17
src/main.cpp
17
src/main.cpp
@@ -192,9 +192,20 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
QGuiApplication::setWindowIcon(IconLoader::Load("strawberry"));
|
||||
|
||||
#if defined(USE_BUNDLE) && (defined(Q_OS_LINUX) || defined(Q_OS_MACOS))
|
||||
qLog(Debug) << "Looking for resources in" << QCoreApplication::applicationDirPath() + "/" + USE_BUNDLE_DIR;
|
||||
QCoreApplication::setLibraryPaths(QStringList() << QCoreApplication::applicationDirPath() + "/" + USE_BUNDLE_DIR);
|
||||
#if defined(USE_BUNDLE)
|
||||
{
|
||||
QStringList library_paths;
|
||||
#ifdef Q_OS_MACOS
|
||||
library_paths.append(QCoreApplication::applicationDirPath() + "/../Frameworks");
|
||||
#endif
|
||||
#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
|
||||
library_paths.append(QCoreApplication::applicationDirPath() + "/" + USE_BUNDLE_DIR);
|
||||
#endif
|
||||
if (!library_paths.isEmpty()) {
|
||||
qLog(Debug) << "Looking for resources in" << library_paths;
|
||||
QCoreApplication::setLibraryPaths(library_paths);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Gnome on Ubuntu has menu icons disabled by default. I think that's a bad idea, and makes some menus in Strawberry look confusing.
|
||||
|
||||
@@ -137,7 +137,7 @@ add_test_file(src/mergedproxymodel_test.cpp false)
|
||||
add_test_file(src/sqlite_test.cpp false)
|
||||
add_test_file(src/tagreader_test.cpp false)
|
||||
add_test_file(src/collectionbackend_test.cpp false)
|
||||
add_test_file(src/collectionmodel_test.cpp true)
|
||||
add_test_file(src/collectionmodel_test.cpp false)
|
||||
add_test_file(src/songplaylistitem_test.cpp false)
|
||||
add_test_file(src/organizeformat_test.cpp false)
|
||||
add_test_file(src/playlist_test.cpp true)
|
||||
|
||||
Reference in New Issue
Block a user