diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 14bbb63a..2a834f2a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,485 +1,492 @@ include_directories(${elisa_BINARY_DIR}) set(elisaLib_SOURCES mediaplaylist.cpp musicaudiotrack.cpp progressindicator.cpp databaseinterface.cpp musiclistenersmanager.cpp managemediaplayercontrol.cpp manageheaderbar.cpp manageaudioplayer.cpp trackslistener.cpp elisaapplication.cpp modeldataloader.cpp notificationitem.cpp topnotificationmanager.cpp elisautils.cpp datatype.cpp abstractfile/abstractfilelistener.cpp abstractfile/abstractfilelisting.cpp filescanner.cpp viewmanager.cpp powermanagementinterface.cpp file/filelistener.cpp file/localfilelisting.cpp models/datamodel.cpp models/abstractmediaproxymodel.cpp models/gridviewproxymodel.cpp models/alltracksproxymodel.cpp models/singlealbumproxymodel.cpp models/trackmetadatamodel.cpp models/trackcontextmetadatamodel.cpp models/viewsmodel.cpp ) ecm_qt_declare_logging_category(elisaLib_SOURCES HEADER "indexersManager.h" IDENTIFIER "orgKdeElisaIndexersManager" CATEGORY_NAME "org.kde.elisa.indexers.manager" DEFAULT_SEVERITY Info ) ecm_qt_declare_logging_category(elisaLib_SOURCES HEADER "databaseLogging.h" IDENTIFIER "orgKdeElisaDatabase" CATEGORY_NAME "org.kde.elisa.database" DEFAULT_SEVERITY Info ) ecm_qt_declare_logging_category(elisaLib_SOURCES HEADER "abstractfile/indexercommon.h" IDENTIFIER "orgKdeElisaIndexer" CATEGORY_NAME "org.kde.elisa.indexer" DEFAULT_SEVERITY Info ) if (LIBVLC_FOUND) ecm_qt_declare_logging_category(elisaLib_SOURCES HEADER "vlcLogging.h" IDENTIFIER "orgKdeElisaPlayerVlc" CATEGORY_NAME "org.kde.elisa.player.vlc" DEFAULT_SEVERITY Info ) set(elisaLib_SOURCES ${elisaLib_SOURCES} audiowrapper_libvlc.cpp ) else() + ecm_qt_declare_logging_category(elisaLib_SOURCES + HEADER "qtMultimediaLogging.h" + IDENTIFIER "orgKdeElisaPlayerQtMultimedia" + CATEGORY_NAME "org.kde.elisa.player.qtMultimedia" + DEFAULT_SEVERITY Info + ) + set(elisaLib_SOURCES ${elisaLib_SOURCES} audiowrapper_qtmultimedia.cpp ) endif() if (ANDROID) set(elisaLib_SOURCES ${elisaLib_SOURCES} android/androidmusiclistener.cpp ) endif() if (KF5KIO_FOUND) set(elisaLib_SOURCES ${elisaLib_SOURCES} models/filebrowsermodel.cpp models/filebrowserproxymodel.cpp ) endif() if (KF5Baloo_FOUND) if (Qt5DBus_FOUND) ecm_qt_declare_logging_category(elisaLib_SOURCES HEADER "baloo/baloocommon.h" IDENTIFIER "orgKdeElisaBaloo" CATEGORY_NAME "org.kde.elisa.baloo" DEFAULT_SEVERITY Info ) set(elisaLib_SOURCES ${elisaLib_SOURCES} baloo/localbaloofilelisting.cpp baloo/baloolistener.cpp baloo/baloodetector.cpp ) qt5_add_dbus_interface(elisaLib_SOURCES ${BALOO_DBUS_INTERFACES_DIR}/org.kde.baloo.main.xml baloo/main) qt5_add_dbus_interface(elisaLib_SOURCES ${BALOO_DBUS_INTERFACES_DIR}/org.kde.baloo.fileindexer.xml baloo/fileindexer) qt5_add_dbus_interface(elisaLib_SOURCES ${BALOO_DBUS_INTERFACES_DIR}/org.kde.baloo.scheduler.xml baloo/scheduler) qt5_add_dbus_adaptor(elisaLib_SOURCES ${BALOO_DBUS_INTERFACES_DIR}/org.kde.BalooWatcherApplication.xml baloo/localbaloofilelisting.h LocalBalooFileListing) endif() endif() if (Qt5DBus_FOUND) set(elisaLib_SOURCES ${elisaLib_SOURCES} mpris2/mpris2.cpp mpris2/mediaplayer2.cpp mpris2/mediaplayer2player.cpp ) endif() if (UPNPQT_FOUND) set(elisaLib_SOURCES ${elisaLib_SOURCES} upnp/upnpcontrolcontentdirectory.cpp upnp/upnpcontentdirectorymodel.cpp upnp/upnpcontrolconnectionmanager.cpp upnp/upnpcontrolmediaserver.cpp upnp/didlparser.cpp upnp/upnplistener.cpp upnp/upnpdiscoverallmusic.cpp ) endif() if (KF5Baloo_FOUND) if (Qt5DBus_FOUND) qt5_add_dbus_interface(elisaLib_SOURCES ${BALOO_DBUS_INTERFACES_DIR}/org.kde.baloo.fileindexer.xml baloo/fileindexer) qt5_add_dbus_interface(elisaLib_SOURCES ${BALOO_DBUS_INTERFACES_DIR}/org.kde.baloo.scheduler.xml baloo/scheduler) set(elisaLib_SOURCES ${elisaLib_SOURCES} ../src/baloo/baloolistener.cpp ../src/baloo/localbaloofilelisting.cpp ) endif() endif() kconfig_add_kcfg_files(elisaLib_SOURCES ../src/elisa_settings.kcfgc ) set(elisaLib_SOURCES ${elisaLib_SOURCES} ../src/elisa_core.kcfg ) add_library(elisaLib ${elisaLib_SOURCES}) target_link_libraries(elisaLib LINK_PUBLIC Qt5::Multimedia LINK_PRIVATE Qt5::Core Qt5::Sql Qt5::Widgets Qt5::Concurrent Qt5::Qml KF5::I18n KF5::CoreAddons KF5::ConfigCore KF5::ConfigGui) if (KF5FileMetaData_FOUND) target_link_libraries(elisaLib LINK_PRIVATE KF5::FileMetaData ) endif() if (KF5KIO_FOUND) target_link_libraries(elisaLib LINK_PUBLIC KF5::KIOCore KF5::KIOFileWidgets KF5::KIOWidgets ) endif() if (KF5XmlGui_FOUND) target_link_libraries(elisaLib LINK_PUBLIC KF5::XmlGui ) endif() if (KF5ConfigWidgets_FOUND) target_link_libraries(elisaLib LINK_PUBLIC KF5::ConfigWidgets ) endif() if (KF5KCMUtils_FOUND) target_link_libraries(elisaLib LINK_PUBLIC KF5::KCMUtils ) endif() if (KF5Baloo_FOUND) if (Qt5DBus_FOUND) target_link_libraries(elisaLib LINK_PUBLIC KF5::Baloo ) endif() endif() if (Qt5DBus_FOUND) target_link_libraries(elisaLib LINK_PUBLIC Qt5::DBus ) if (KF5DBusAddons_FOUND) target_link_libraries(elisaLib LINK_PUBLIC KF5::DBusAddons ) endif() endif() if (LIBVLC_FOUND) target_include_directories(elisaLib PRIVATE ${LIBVLC_INCLUDE_DIR} ) target_link_libraries(elisaLib LINK_PRIVATE ${LIBVLC_LIBRARY} ) endif() if (ANDROID) target_link_libraries(elisaLib LINK_PUBLIC Qt5::AndroidExtras ) endif() generate_export_header(elisaLib BASE_NAME ElisaLib EXPORT_FILE_NAME elisaLib_export.h) set_target_properties(elisaLib PROPERTIES VERSION 0.1 SOVERSION 0 EXPORT_NAME ElisaLib ) if (NOT APPLE AND NOT WIN32) install(TARGETS elisaLib LIBRARY DESTINATION ${KDE_INSTALL_FULL_LIBDIR}/elisa NAMELINK_SKIP RUNTIME DESTINATION ${KDE_INSTALL_FULL_LIBDIR}/elisa BUNDLE DESTINATION ${KDE_INSTALL_FULL_LIBDIR}/elisa ) else() install(TARGETS elisaLib ${INSTALL_TARGETS_DEFAULT_ARGS}) endif() set(elisaqmlplugin_SOURCES elisaqmlplugin.cpp datatype.cpp elisautils.cpp ) if (KF5FileMetaData_FOUND) set(elisaqmlplugin_SOURCES ${elisaqmlplugin_SOURCES} embeddedcoverageimageprovider.cpp ) endif() add_library(elisaqmlplugin SHARED ${elisaqmlplugin_SOURCES}) target_link_libraries(elisaqmlplugin LINK_PRIVATE Qt5::Quick Qt5::Widgets KF5::ConfigCore KF5::ConfigGui elisaLib ) if (KF5FileMetaData_FOUND) target_link_libraries(elisaqmlplugin LINK_PRIVATE KF5::FileMetaData ) endif() set_target_properties(elisaqmlplugin PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/org/kde/elisa ) if (NOT APPLE AND NOT WIN32) set_target_properties(elisaqmlplugin PROPERTIES INSTALL_RPATH "${KDE_INSTALL_FULL_LIBDIR}/elisa;${CMAKE_INSTALL_RPATH}" ) endif() install(TARGETS elisaqmlplugin DESTINATION ${QML_INSTALL_DIR}/org/kde/elisa/) install(FILES qmldir DESTINATION ${QML_INSTALL_DIR}/org/kde/elisa) add_custom_target(copy) add_custom_target(copy2) file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/bin/org/kde/elisa) add_custom_command(TARGET copy PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/qmldir ${CMAKE_BINARY_DIR}/bin/org/kde/elisa/) add_custom_command(TARGET copy2 PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/plugins.qmltypes ${CMAKE_BINARY_DIR}/bin/org/kde/elisa/) add_dependencies(elisaqmlplugin copy copy2) if (Qt5Quick_FOUND AND Qt5Widgets_FOUND) set(elisa_SOURCES main.cpp windows/WindowsTheme.qml windows/PlatformIntegration.qml android/ElisaMainWindow.qml android/AndroidTheme.qml android/PlatformIntegration.qml android/AlbumsView.qml android/ArtistsView.qml android/TracksView.qml android/GenresView.qml qml/ElisaMainWindow.qml qml/ApplicationMenu.qml qml/BaseTheme.qml qml/Theme.qml qml/PlatformIntegration.qml qml/LabelWithToolTip.qml qml/RatingStar.qml qml/DraggableItem.qml qml/PassiveNotification.qml qml/TopNotification.qml qml/TopNotificationItem.qml qml/TrackImportNotification.qml qml/HeaderBar.qml qml/NavigationActionBar.qml qml/MediaPlayerControl.qml qml/ContextView.qml qml/ContextViewLyrics.qml qml/ContentView.qml qml/ViewSelector.qml qml/DataGridView.qml qml/TracksView.qml qml/AlbumView.qml qml/RecentlyPlayedTracks.qml qml/FrequentlyPlayedTracks.qml qml/MediaPlayListView.qml qml/PlayListBasicView.qml qml/PlayListEntry.qml qml/SimplePlayListView.qml qml/SimplePlayListEntry.qml qml/PlayListAlbumHeader.qml qml/BasicPlayListAlbumHeader.qml qml/MetaDataDelegate.qml qml/MediaTrackDelegate.qml qml/MediaAlbumTrackDelegate.qml qml/MediaTrackMetadataView.qml qml/GridBrowserView.qml qml/GridBrowserDelegate.qml qml/ListBrowserView.qml qml/FileBrowserDelegate.qml qml/FileBrowserView.qml qml/ScrollHelper.qml qml/FlatButtonWithToolTip.qml ) qt5_add_resources(elisa_SOURCES resources.qrc) set_property(SOURCE qrc_resources.cpp PROPERTY SKIP_AUTOMOC ON) set(elisa_ICONS_PNG ../icons/128-apps-elisa.png ../icons/64-apps-elisa.png ../icons/48-apps-elisa.png ../icons/32-apps-elisa.png ../icons/22-apps-elisa.png ../icons/16-apps-elisa.png ) # add icons to application sources, to have them bundled ecm_add_app_icon(elisa_SOURCES ICONS ${elisa_ICONS_PNG}) add_executable(elisa ${elisa_SOURCES}) target_include_directories(elisa PRIVATE ${KDSoap_INCLUDE_DIRS}) target_link_libraries(elisa LINK_PRIVATE elisaLib Qt5::Widgets Qt5::QuickControls2 KF5::I18n KF5::CoreAddons KF5::ConfigCore KF5::ConfigGui ) if (ANDROID) target_link_libraries(elisa LINK_PRIVATE Qt5::AndroidExtras Qt5::Svg Qt5::Sql Qt5::Concurrent KF5::Kirigami2 ) endif() if (KF5Crash_FOUND) target_link_libraries(elisa LINK_PRIVATE KF5::Crash ) endif() if (KF5Declarative_FOUND) target_link_libraries(elisa LINK_PRIVATE KF5::Declarative ) endif() if (NOT APPLE AND NOT WIN32) set_target_properties(elisa PROPERTIES INSTALL_RPATH "${KDE_INSTALL_FULL_LIBDIR}/elisa;${CMAKE_INSTALL_RPATH}" ) endif() install(TARGETS elisa ${INSTALL_TARGETS_DEFAULT_ARGS}) endif() if (KF5ConfigWidgets_FOUND AND KF5Declarative_FOUND) add_subdirectory(localFileConfiguration) endif() set(elisaImport_SOURCES elisaimport.cpp elisaimportapplication.cpp ) kconfig_add_kcfg_files(elisaImport_SOURCES ../src/elisa_settings.kcfgc ) set(elisaImport_SOURCES ${elisaImport_SOURCES} ../src/elisa_core.kcfg ) add_executable(elisaImport ${elisaImport_SOURCES}) target_link_libraries(elisaImport LINK_PRIVATE KF5::ConfigCore KF5::ConfigGui elisaLib ) if (KF5FileMetaData_FOUND) target_link_libraries(elisaImport LINK_PRIVATE KF5::FileMetaData ) endif() set(QML_IMPORT_PATH ${CMAKE_BINARY_DIR}/bin CACHE INTERNAL "qml import path" FORCE) if (ANDROID) kirigami_package_breeze_icons(ICONS elisa) endif() diff --git a/src/audiowrapper_qtmultimedia.cpp b/src/audiowrapper_qtmultimedia.cpp index 5fb96dbb..84ba0f8d 100644 --- a/src/audiowrapper_qtmultimedia.cpp +++ b/src/audiowrapper_qtmultimedia.cpp @@ -1,252 +1,254 @@ /* * Copyright 2017 Matthieu Gallien * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "audiowrapper.h" +#include "qtMultimediaLogging.h" + #include #include #include "config-upnp-qt.h" class AudioWrapperPrivate { public: QMediaPlayer mPlayer; qint64 mSavedPosition = 0.0; qint64 mUndoSavedPosition = 0.0; bool mHasSavedPosition = false; }; AudioWrapper::AudioWrapper(QObject *parent) : QObject(parent), d(std::make_unique()) { connect(&d->mPlayer, &QMediaPlayer::mutedChanged, this, &AudioWrapper::playerMutedChanged); connect(&d->mPlayer, &QMediaPlayer::volumeChanged, this, &AudioWrapper::playerVolumeChanged); connect(&d->mPlayer, &QMediaPlayer::mediaChanged, this, &AudioWrapper::sourceChanged); connect(&d->mPlayer, &QMediaPlayer::mediaStatusChanged, this, &AudioWrapper::statusChanged); connect(&d->mPlayer, &QMediaPlayer::mediaStatusChanged, this, &AudioWrapper::mediaStatusChanged); connect(&d->mPlayer, &QMediaPlayer::stateChanged, this, &AudioWrapper::playbackStateChanged); connect(&d->mPlayer, &QMediaPlayer::stateChanged, this, &AudioWrapper::playerStateChanged); connect(&d->mPlayer, QOverload::of(&QMediaPlayer::error), this, &AudioWrapper::errorChanged); connect(&d->mPlayer, &QMediaPlayer::durationChanged, this, &AudioWrapper::durationChanged); connect(&d->mPlayer, &QMediaPlayer::positionChanged, this, &AudioWrapper::positionChanged); connect(&d->mPlayer, &QMediaPlayer::seekableChanged, this, &AudioWrapper::seekableChanged); } AudioWrapper::~AudioWrapper() = default; bool AudioWrapper::muted() const { return d->mPlayer.isMuted(); } qreal AudioWrapper::volume() const { auto realVolume = static_cast(d->mPlayer.volume() / 100.0); auto userVolume = static_cast(QAudio::convertVolume(realVolume, QAudio::LinearVolumeScale, QAudio::LogarithmicVolumeScale)); return userVolume * 100.0; } QUrl AudioWrapper::source() const { return d->mPlayer.media().canonicalUrl(); } QMediaPlayer::Error AudioWrapper::error() const { if (d->mPlayer.error() != QMediaPlayer::NoError) { qDebug() << "AudioWrapper::error" << d->mPlayer.errorString(); } return d->mPlayer.error(); } qint64 AudioWrapper::duration() const { return d->mPlayer.duration(); } qint64 AudioWrapper::position() const { return d->mPlayer.position(); } bool AudioWrapper::seekable() const { return d->mPlayer.isSeekable(); } QAudio::Role AudioWrapper::audioRole() const { return d->mPlayer.audioRole(); } QMediaPlayer::State AudioWrapper::playbackState() const { return d->mPlayer.state(); } QMediaPlayer::MediaStatus AudioWrapper::status() const { return d->mPlayer.mediaStatus(); } void AudioWrapper::setMuted(bool muted) { d->mPlayer.setMuted(muted); } void AudioWrapper::setVolume(qreal volume) { auto realVolume = static_cast(QAudio::convertVolume(volume / 100.0, QAudio::LogarithmicVolumeScale, QAudio::LinearVolumeScale)); d->mPlayer.setVolume(qRound(realVolume * 100)); } void AudioWrapper::setSource(const QUrl &source) { d->mPlayer.setMedia({source}); } void AudioWrapper::setPosition(qint64 position) { d->mPlayer.setPosition(position); } void AudioWrapper::play() { d->mPlayer.play(); } void AudioWrapper::pause() { d->mPlayer.pause(); } void AudioWrapper::stop() { d->mPlayer.stop(); } void AudioWrapper::seek(qint64 position) { d->mPlayer.setPosition(position); } void AudioWrapper::setAudioRole(QAudio::Role audioRole) { d->mPlayer.setAudioRole(audioRole); } void AudioWrapper::mediaStatusChanged() { } void AudioWrapper::playerStateChanged() { switch(d->mPlayer.state()) { case QMediaPlayer::State::StoppedState: Q_EMIT stopped(); break; case QMediaPlayer::State::PlayingState: Q_EMIT playing(); break; case QMediaPlayer::State::PausedState: Q_EMIT paused(); break; } } void AudioWrapper::playerVolumeChanged() { QTimer::singleShot(0, [this]() {Q_EMIT volumeChanged();}); } void AudioWrapper::playerMutedChanged() { QTimer::singleShot(0, [this]() {Q_EMIT mutedChanged(muted());}); } void AudioWrapper::playerStateSignalChanges(QMediaPlayer::State newState) { QMetaObject::invokeMethod(this, [this, newState]() {Q_EMIT playbackStateChanged(newState);}, Qt::QueuedConnection); } void AudioWrapper::mediaStatusSignalChanges(QMediaPlayer::MediaStatus newStatus) { QMetaObject::invokeMethod(this, [this, newStatus]() {Q_EMIT statusChanged(newStatus);}, Qt::QueuedConnection); } void AudioWrapper::playerDurationSignalChanges(qint64 newDuration) { QMetaObject::invokeMethod(this, [this, newDuration]() {Q_EMIT durationChanged(newDuration);}, Qt::QueuedConnection); if (d->mHasSavedPosition) { setPosition(d->mSavedPosition); d->mHasSavedPosition = false; } } void AudioWrapper::playerPositionSignalChanges(qint64 newPosition) { QMetaObject::invokeMethod(this, [this, newPosition]() {Q_EMIT positionChanged(newPosition);}, Qt::QueuedConnection); } void AudioWrapper::playerVolumeSignalChanges() { QMetaObject::invokeMethod(this, [this]() {Q_EMIT volumeChanged();}, Qt::QueuedConnection); } void AudioWrapper::playerMutedSignalChanges(bool isMuted) { QMetaObject::invokeMethod(this, [this, isMuted]() {Q_EMIT mutedChanged(isMuted);}, Qt::QueuedConnection); } void AudioWrapper::playerSeekableSignalChanges(bool isSeekable) { QMetaObject::invokeMethod(this, [this, isSeekable]() {Q_EMIT seekableChanged(isSeekable);}, Qt::QueuedConnection); } void AudioWrapper::saveUndoPosition(qint64 position) { d->mUndoSavedPosition = position; } void AudioWrapper::restoreUndoPosition() { d->mHasSavedPosition = true; d->mSavedPosition = d->mUndoSavedPosition; } void AudioWrapper::savePosition(qint64 position) { if (!d->mHasSavedPosition) { d->mHasSavedPosition = true; d->mSavedPosition = position; - //qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapper::savePosition" << "restore old position" << d->mSavedPosition; + qCDebug(orgKdeElisaPlayerQtMultimedia) << "AudioWrapper::savePosition" << "restore old position" << d->mSavedPosition; } } #include "moc_audiowrapper.cpp"