Files
audiotube/src/main.cpp
T

143 lines
5.8 KiB
C++

// SPDX-FileCopyrightText: 2021 Jonah Brüchert <[email protected]>
//
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include <QSortFilterProxyModel>
#include <QUrl>
#include <QQuickWindow>
#include <QQuickStyle>
#include <QStyle>
#include <QStyleFactory>
#include <KLocalizedContext>
#include <KLocalizedString>
#include <KCrash>
#include <KAboutData>
#include <mprisplugin.h>
#include "clipboard.h"
#include "searchmodel.h"
#include "albummodel.h"
#include "videoinfoextractor.h"
#include "artistmodel.h"
#include "userplaylistmodel.h"
#include "errorhandler.h"
#include "playlistmodel.h"
#include "playerutils.h"
#include "library.h"
#include "thumbnailsource.h"
#include "blur.h"
#include "localplaylistmodel.h"
#include "localplaylistsmodel.h"
#include "playlistimporter.h"
#include <ThreadedDatabase>
constexpr auto URI = "org.kde.ytmusic";
Q_DECL_EXPORT int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// set default style and icon theme
QIcon::setFallbackThemeName(QStringLiteral("breeze"));
if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE") && QQuickStyle::name().isEmpty()) {
QQuickStyle::setStyle(QStringLiteral("org.kde.desktop"));
QApplication::setStyle(QStyleFactory::create(QStringLiteral("Breeze")));
}
// WORKAROUND: Force QtMultimedia gstreamer backend
/*
ffmpeg unfortunately loses the connection to youtube's servers with the following error message after ~2 minutes
at the time of writing (2023-10-29 with ffmpeg 6.0 and Qt 6.6.1)
[tls @ 0x561f31d3d500] Error in the pull function.
[tls @ 0x561f31d3d500] IO error: Connection reset by peer
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x561f3225e000] Packet corrupt (stream = 0, dts = 4590016).
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x561f3225e000] stream 0, offset 0x19c06c: partial file
[aac @ 0x561f3244bc00] Input buffer exhausted before END element found
*/
qputenv("QT_MEDIA_BACKEND", "gstreamer");
QCoreApplication::setOrganizationName(QStringLiteral("KDE"));
QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org"));
QCoreApplication::setApplicationName(QStringLiteral("audiotube"));
KLocalizedString::setApplicationDomain("audiotube");
KAboutData about(QStringLiteral("audiotube"),
i18n("AudioTube"),
QStringLiteral(AUDIOTUBE_VERSION_STRING),
i18nc("YouTube Music is a music streaming service by Google", "Stream music from YouTube Music"),
KAboutLicense::GPL_V3,
i18n("© 2021-2023 Jonah Brüchert, 2021-2023 KDE Community"));
about.addAuthor(i18n("Jonah Brüchert"), i18n("Maintainer"), QStringLiteral("[email protected]"));
about.addAuthor(i18n("Mathis Brüchert"), i18n("Designer"), QStringLiteral("[email protected]"));
about.setTranslator(i18nc("NAME OF TRANSLATORS", "Your names"), i18nc("EMAIL OF TRANSLATORS", "Your emails"));
about.setOrganizationDomain("kde.org");
about.setBugAddress("https://bugs.kde.org/describecomponents.cgi?product=audiotube");
auto future = YTMusicThread::instance()->version();
QCoro::connect(std::move(future), &app, [&about](const auto &version) {
about.addComponent(QStringLiteral("ytmusicapi"),
i18nc("YouTube Music is a music streaming service by Google",
"Unofficial API for YouTube Music"),
version);
KAboutData::setApplicationData(about);
});
QGuiApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("org.kde.audiotube")));
KCrash::initialize();
QQmlApplicationEngine engine;
MprisPlugin(&engine).registerTypes("org.nemomobile.qtmpris");
qmlRegisterType<SearchModel>(URI, 1, 0, "SearchModel");
qmlRegisterType<AlbumModel>(URI, 1, 0, "AlbumModel");
qmlRegisterType<VideoInfoExtractor>(URI, 1, 0, "VideoInfoExtractor");
qmlRegisterType<ArtistModel>(URI, 1, 0, "ArtistModel");
qmlRegisterType<PlaylistModel>(URI, 1, 0, "PlaylistModel");
qmlRegisterUncreatableType<PlaybackHistoryModel>(URI, 1, 0, "PlaybackHistoryModel","");
qmlRegisterType<QSortFilterProxyModel>(URI, 1, 0, "SortFilterModel");
qmlRegisterType<Blur>(URI, 1, 0, "Blur");
qmlRegisterType<LocalSearchModel>(URI, 1, 0, "LocalSearchModel");
qmlRegisterType<LocalPlaylistModel>(URI, 1, 0, "LocalPlaylistModel");
qmlRegisterType<LocalPlaylistsModel>(URI, 1, 0, "LocalPlaylistsModel");
qmlRegisterType<PlaylistImporter>(URI, 1, 0, "PlaylistImporter");
qmlRegisterSingletonType(URI, 1, 0, "About", [](QQmlEngine *engine, QJSEngine *) -> QJSValue {
return engine->toScriptValue(KAboutData::applicationData());
});
qmlRegisterSingletonType<UserPlaylistModel>(URI, 1, 0, "UserPlaylistModel", [](QQmlEngine *, QJSEngine *) {
return new UserPlaylistModel();
});
qmlRegisterSingletonType<ErrorHandler>(URI, 1, 0, "ErrorHandler", [](QQmlEngine *, QJSEngine *) {
return new ErrorHandler();
});
qmlRegisterSingletonType<PlayerUtils>(URI, 1, 0, "PlayerUtils", [](QQmlEngine *, QJSEngine *) {
return new PlayerUtils();
});
qmlRegisterSingletonType<Clipboard>(URI, 1, 0, "Clipboard", [](QQmlEngine *, QJSEngine *) {
return new Clipboard();
});
qmlRegisterSingletonInstance<Library>(URI, 1, 0, "Library", &Library::instance());
qmlRegisterType<ThumbnailSource>(URI, 1, 0, "ThumbnailSource");
qmlRegisterAnonymousType<FavouriteWatcher>(URI, 1);
qmlRegisterAnonymousType<WasPlayedWatcher>(URI, 1);
engine.rootContext()->setContextObject(new KLocalizedContext(&engine));
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
if (engine.rootObjects().isEmpty()) {
return -1;
}
return app.exec();
}