diff --git a/src/audiowrapper.h b/src/audiowrapper.h index 5f469b6c..572073d8 100644 --- a/src/audiowrapper.h +++ b/src/audiowrapper.h @@ -1,196 +1,185 @@ /* * 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 . */ #ifndef AUDIOWRAPPER_H #define AUDIOWRAPPER_H #include "elisaLib_export.h" #include #include #include #include #include class AudioWrapperPrivate; class ELISALIB_EXPORT AudioWrapper : public QObject { Q_OBJECT Q_PROPERTY(bool muted READ muted WRITE setMuted NOTIFY mutedChanged) Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged) Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) Q_PROPERTY(QMediaPlayer::MediaStatus status READ status NOTIFY statusChanged) Q_PROPERTY(QMediaPlayer::State playbackState READ playbackState NOTIFY playbackStateChanged) Q_PROPERTY(QMediaPlayer::Error error READ error NOTIFY errorChanged) Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged) Q_PROPERTY(qint64 position READ position WRITE setPosition NOTIFY positionChanged) Q_PROPERTY(bool seekable READ seekable NOTIFY seekableChanged) - Q_PROPERTY(QAudio::Role audioRole - READ audioRole - WRITE setAudioRole - NOTIFY audioRoleChanged) - public: explicit AudioWrapper(QObject *parent = nullptr); ~AudioWrapper() override; bool muted() const; qreal volume() const; QUrl source() const; QMediaPlayer::MediaStatus status() const; QMediaPlayer::State playbackState() const; QMediaPlayer::Error error() const; qint64 duration() const; qint64 position() const; bool seekable() const; - QAudio::Role audioRole() const; - Q_SIGNALS: void mutedChanged(bool muted); void volumeChanged(); void sourceChanged(); void statusChanged(QMediaPlayer::MediaStatus status); void playbackStateChanged(QMediaPlayer::State state); void errorChanged(QMediaPlayer::Error error); void durationChanged(qint64 duration); void positionChanged(qint64 position); void currentPlayingForRadiosChanged(const QString &title, const QString &nowPlaying); void seekableChanged(bool seekable); void playing(); void paused(); void stopped(); - void audioRoleChanged(); - public Q_SLOTS: void setMuted(bool muted); void setVolume(qreal volume); void setSource(const QUrl &source); void setPosition(qint64 position); void saveUndoPosition(qint64 position); void restoreUndoPosition(); void play(); void pause(); void stop(); void seek(qint64 position); - void setAudioRole(QAudio::Role audioRole); - private Q_SLOTS: void mediaStatusChanged(); void playerStateChanged(); void playerMutedChanged(); void playerVolumeChanged(); private: void savePosition(qint64 position); void playerStateSignalChanges(QMediaPlayer::State newState); void mediaStatusSignalChanges(QMediaPlayer::MediaStatus newStatus); void playerErrorSignalChanges(QMediaPlayer::Error error); void playerDurationSignalChanges(qint64 newDuration); void playerPositionSignalChanges(qint64 newPosition); void playerVolumeSignalChanges(); void playerMutedSignalChanges(bool isMuted); void playerSeekableSignalChanges(bool isSeekable); friend class AudioWrapperPrivate; std::unique_ptr d; }; #endif // AUDIOWRAPPER_H diff --git a/src/audiowrapper_libvlc.cpp b/src/audiowrapper_libvlc.cpp index ba0b72cc..488587c3 100644 --- a/src/audiowrapper_libvlc.cpp +++ b/src/audiowrapper_libvlc.cpp @@ -1,596 +1,584 @@ /* * 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 "elisa-version.h" #include "vlcLogging.h" #include "powermanagementinterface.h" #include #include #include #if defined Q_OS_WIN #include typedef SSIZE_T ssize_t; #endif #include #include "config-upnp-qt.h" class AudioWrapperPrivate { public: PowerManagementInterface mPowerInterface; AudioWrapper *mParent = nullptr; libvlc_instance_t *mInstance = nullptr; libvlc_media_player_t *mPlayer = nullptr; libvlc_event_manager_t *mPlayerEventManager = nullptr; libvlc_media_t *mMedia = nullptr; qint64 mMediaDuration = 0; QMediaPlayer::State mPreviousPlayerState = QMediaPlayer::StoppedState; QMediaPlayer::MediaStatus mPreviousMediaStatus = QMediaPlayer::NoMedia; qreal mPreviousVolume = 100.0; qint64 mSavedPosition = 0.0; qint64 mUndoSavedPosition = 0.0; qint64 mPreviousPosition = 0; QMediaPlayer::Error mError = QMediaPlayer::NoError; bool mIsMuted = false; bool mIsSeekable = false; bool mHasSavedPosition = false; void vlcEventCallback(const struct libvlc_event_t *p_event); void mediaIsEnded(); bool signalPlaybackChange(QMediaPlayer::State newPlayerState); void signalMediaStatusChange(QMediaPlayer::MediaStatus newMediaStatus); void signalVolumeChange(int newVolume); void signalMutedChange(bool isMuted); void signalDurationChange(libvlc_time_t newDuration); void signalPositionChange(float newPosition); void signalSeekableChange(bool isSeekable); void signalErrorChange(QMediaPlayer::Error errorCode); }; static void vlc_callback(const struct libvlc_event_t *p_event, void *p_data) { reinterpret_cast(p_data)->vlcEventCallback(p_event); } AudioWrapper::AudioWrapper(QObject *parent) : QObject(parent), d(std::make_unique()) { d->mParent = this; d->mInstance = libvlc_new(0, nullptr); libvlc_set_user_agent(d->mInstance, "elisa", "Elisa Music Player"); libvlc_set_app_id(d->mInstance, "org.kde.elisa", ELISA_VERSION_STRING, "elisa"); d->mPlayer = libvlc_media_player_new(d->mInstance); if (!d->mPlayer) { qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapper::AudioWrapper" << "failed creating player" << libvlc_errmsg(); return; } d->mPlayerEventManager = libvlc_media_player_event_manager(d->mPlayer); libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerOpening, &vlc_callback, d.get()); libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerBuffering, &vlc_callback, d.get()); libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerPlaying, &vlc_callback, d.get()); libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerPaused, &vlc_callback, d.get()); libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerStopped, &vlc_callback, d.get()); libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerEndReached, &vlc_callback, d.get()); libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerEncounteredError, &vlc_callback, d.get()); libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerPositionChanged, &vlc_callback, d.get()); libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerSeekableChanged, &vlc_callback, d.get()); libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerLengthChanged, &vlc_callback, d.get()); libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerMuted, &vlc_callback, d.get()); libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerUnmuted, &vlc_callback, d.get()); libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerAudioVolume, &vlc_callback, d.get()); libvlc_event_attach(d->mPlayerEventManager, libvlc_MediaPlayerAudioDevice, &vlc_callback, d.get()); } AudioWrapper::~AudioWrapper() { if (d->mInstance) { libvlc_release(d->mInstance); } } bool AudioWrapper::muted() const { return d->mIsMuted; } qreal AudioWrapper::volume() const { if (!d->mPlayer) { return 100.0; } return d->mPreviousVolume; } QUrl AudioWrapper::source() const { if (!d->mPlayer) { return {}; } - - return {}/*d->mPlayer.media().canonicalUrl()*/; + if (d->mMedia) { + auto filePath = QString::fromUtf8(libvlc_media_get_mrl(d->mMedia)); + return QUrl::fromUserInput(filePath); + } + return {}; } QMediaPlayer::Error AudioWrapper::error() const { return d->mError; } qint64 AudioWrapper::duration() const { return d->mMediaDuration; } qint64 AudioWrapper::position() const { if (!d->mPlayer) { return 0; } if (d->mMediaDuration == -1) { return 0; } return qRound64(libvlc_media_player_get_position(d->mPlayer) * d->mMediaDuration); } bool AudioWrapper::seekable() const { return d->mIsSeekable; } -QAudio::Role AudioWrapper::audioRole() const -{ - if (!d->mPlayer) { - return {}; - } - - return {}/*d->mPlayer.audioRole()*/; -} - QMediaPlayer::State AudioWrapper::playbackState() const { return d->mPreviousPlayerState; } QMediaPlayer::MediaStatus AudioWrapper::status() const { return d->mPreviousMediaStatus; } void AudioWrapper::setMuted(bool muted) { if (!d->mPlayer) { return; } libvlc_audio_set_mute(d->mPlayer, muted); } void AudioWrapper::setVolume(qreal volume) { if (!d->mPlayer) { return; } //auto realVolume = static_cast(QAudio::convertVolume(volume / 100.0, QAudio::LogarithmicVolumeScale, QAudio::LinearVolumeScale)); libvlc_audio_set_volume(d->mPlayer, qRound(volume)); } void AudioWrapper::setSource(const QUrl &source) { if (source.isLocalFile()) { qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapper::setSource reading local resource"; d->mMedia = libvlc_media_new_path(d->mInstance, QDir::toNativeSeparators(source.toLocalFile()).toUtf8().constData()); } else { qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapper::setSource reading remote resource"; d->mMedia = libvlc_media_new_location(d->mInstance, source.url().toUtf8().constData()); } if (!d->mMedia) { qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapper::setSource" << "failed creating media" << libvlc_errmsg() << QDir::toNativeSeparators(source.toLocalFile()).toUtf8().constData(); d->mMedia = libvlc_media_new_path(d->mInstance, QDir::toNativeSeparators(source.toLocalFile()).toLatin1().constData()); if (!d->mMedia) { qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapper::setSource" << "failed creating media" << libvlc_errmsg() << QDir::toNativeSeparators(source.toLocalFile()).toLatin1().constData(); return; } } libvlc_media_player_set_media(d->mPlayer, d->mMedia); if (d->signalPlaybackChange(QMediaPlayer::StoppedState)) { Q_EMIT stopped(); } d->signalMediaStatusChange(QMediaPlayer::LoadingMedia); d->signalMediaStatusChange(QMediaPlayer::LoadedMedia); d->signalMediaStatusChange(QMediaPlayer::BufferedMedia); } void AudioWrapper::setPosition(qint64 position) { if (!d->mPlayer) { return; } if (d->mMediaDuration == -1 || d->mMediaDuration == 0) { savePosition(position); return; } libvlc_media_player_set_position(d->mPlayer, static_cast(position) / d->mMediaDuration); } void AudioWrapper::savePosition(qint64 position) { if (!d->mHasSavedPosition) { d->mHasSavedPosition = true; d->mSavedPosition = position; qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapper::savePosition" << "restore old position" << d->mSavedPosition; } } void AudioWrapper::saveUndoPosition(qint64 position) { d->mUndoSavedPosition = position; } void AudioWrapper::restoreUndoPosition() { d->mHasSavedPosition = true; d->mSavedPosition = d->mUndoSavedPosition; } void AudioWrapper::play() { if (!d->mPlayer) { return; } libvlc_media_player_play(d->mPlayer); } void AudioWrapper::pause() { if (!d->mPlayer) { return; } libvlc_media_player_pause(d->mPlayer); } void AudioWrapper::stop() { if (!d->mPlayer) { return; } libvlc_media_player_stop(d->mPlayer); } void AudioWrapper::seek(qint64 position) { setPosition(position); } -void AudioWrapper::setAudioRole(QAudio::Role audioRole) -{ - Q_UNUSED(audioRole) - // d->mPlayer.setAudioRole(audioRole); -} - void AudioWrapper::mediaStatusChanged() { } void AudioWrapper::playerStateChanged() { } void AudioWrapper::playerMutedChanged() { } void AudioWrapper::playerVolumeChanged() { } void AudioWrapper::playerStateSignalChanges(QMediaPlayer::State newState) { QMetaObject::invokeMethod(this, [this, newState]() { Q_EMIT playbackStateChanged(newState); switch (newState) { case QMediaPlayer::StoppedState: Q_EMIT stopped(); d->mPowerInterface.setPreventSleep(false); break; case QMediaPlayer::PlayingState: Q_EMIT playing(); d->mPowerInterface.setPreventSleep(true); break; case QMediaPlayer::PausedState: Q_EMIT paused(); d->mPowerInterface.setPreventSleep(false); break; } }, Qt::QueuedConnection); } void AudioWrapper::mediaStatusSignalChanges(QMediaPlayer::MediaStatus newStatus) { QMetaObject::invokeMethod(this, [this, newStatus]() {Q_EMIT statusChanged(newStatus);}, Qt::QueuedConnection); } void AudioWrapper::playerErrorSignalChanges(QMediaPlayer::Error error) { QMetaObject::invokeMethod(this, [this, error]() {Q_EMIT errorChanged(error);}, Qt::QueuedConnection); } void AudioWrapper::playerDurationSignalChanges(qint64 newDuration) { QMetaObject::invokeMethod(this, [this, newDuration]() {Q_EMIT durationChanged(newDuration);}, Qt::QueuedConnection); } 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 AudioWrapperPrivate::vlcEventCallback(const struct libvlc_event_t *p_event) { const auto eventType = static_cast(p_event->type); switch(eventType) { case libvlc_MediaPlayerOpening: qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerOpening"; signalMediaStatusChange(QMediaPlayer::LoadedMedia); break; case libvlc_MediaPlayerBuffering: qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerBuffering"; signalMediaStatusChange(QMediaPlayer::BufferedMedia); break; case libvlc_MediaPlayerPlaying: qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerPlaying"; signalPlaybackChange(QMediaPlayer::PlayingState); break; case libvlc_MediaPlayerPaused: qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerPaused"; signalPlaybackChange(QMediaPlayer::PausedState); break; case libvlc_MediaPlayerStopped: qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerStopped"; signalPlaybackChange(QMediaPlayer::StoppedState); break; case libvlc_MediaPlayerEndReached: qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerEndReached"; signalMediaStatusChange(QMediaPlayer::BufferedMedia); signalMediaStatusChange(QMediaPlayer::NoMedia); signalMediaStatusChange(QMediaPlayer::EndOfMedia); mediaIsEnded(); break; case libvlc_MediaPlayerEncounteredError: qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerEncounteredError"; signalErrorChange(QMediaPlayer::ResourceError); mediaIsEnded(); signalMediaStatusChange(QMediaPlayer::InvalidMedia); break; case libvlc_MediaPlayerPositionChanged: qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerPositionChanged"; signalPositionChange(p_event->u.media_player_position_changed.new_position); break; case libvlc_MediaPlayerSeekableChanged: qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerSeekableChanged"; signalSeekableChange(p_event->u.media_player_seekable_changed.new_seekable); break; case libvlc_MediaPlayerLengthChanged: qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerLengthChanged"; signalDurationChange(p_event->u.media_player_length_changed.new_length); if (mHasSavedPosition) { mParent->setPosition(mSavedPosition); mHasSavedPosition = false; } break; case libvlc_MediaPlayerMuted: qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerMuted"; signalMutedChange(true); break; case libvlc_MediaPlayerUnmuted: qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerUnmuted"; signalMutedChange(false); break; case libvlc_MediaPlayerAudioVolume: qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerAudioVolume"; signalVolumeChange(qRound(p_event->u.media_player_audio_volume.volume * 100)); break; case libvlc_MediaPlayerAudioDevice: qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "libvlc_MediaPlayerAudioDevice"; break; default: qCDebug(orgKdeElisaPlayerVlc) << "AudioWrapperPrivate::vlcEventCallback" << "eventType" << eventType; break; } } void AudioWrapperPrivate::mediaIsEnded() { libvlc_media_release(mMedia); mMedia = nullptr; } bool AudioWrapperPrivate::signalPlaybackChange(QMediaPlayer::State newPlayerState) { if (mPreviousPlayerState != newPlayerState) { mPreviousPlayerState = newPlayerState; mParent->playerStateSignalChanges(mPreviousPlayerState); return true; } return false; } void AudioWrapperPrivate::signalMediaStatusChange(QMediaPlayer::MediaStatus newMediaStatus) { if (mPreviousMediaStatus != newMediaStatus) { mPreviousMediaStatus = newMediaStatus; mParent->mediaStatusSignalChanges(mPreviousMediaStatus); } } void AudioWrapperPrivate::signalVolumeChange(int newVolume) { if (newVolume == -1) { return; } if (mPreviousPlayerState == QMediaPlayer::StoppedState) { return; } if (abs(int(mPreviousVolume - newVolume)) > 0.01) { mPreviousVolume = newVolume; mParent->playerVolumeSignalChanges(); } } void AudioWrapperPrivate::signalMutedChange(bool isMuted) { if (mIsMuted != isMuted) { mIsMuted = isMuted; mParent->playerMutedSignalChanges(mIsMuted); } } void AudioWrapperPrivate::signalDurationChange(libvlc_time_t newDuration) { if (mMediaDuration != newDuration) { mMediaDuration = newDuration; mParent->playerDurationSignalChanges(mMediaDuration); } } void AudioWrapperPrivate::signalPositionChange(float newPosition) { if (mMediaDuration == -1) { return; } auto computedPosition = qRound64(newPosition * mMediaDuration); if (mPreviousPosition != computedPosition) { mPreviousPosition = computedPosition; mParent->playerPositionSignalChanges(mPreviousPosition); } if (this->mMedia) { QString title = QLatin1String(libvlc_media_get_meta(this->mMedia, libvlc_meta_Title)); QString nowPlaying = QLatin1String(libvlc_media_get_meta(this->mMedia, libvlc_meta_NowPlaying)); Q_EMIT mParent->currentPlayingForRadiosChanged(title, nowPlaying); } } void AudioWrapperPrivate::signalSeekableChange(bool isSeekable) { if (mIsSeekable != isSeekable) { mIsSeekable = isSeekable; mParent->playerSeekableSignalChanges(isSeekable); } } void AudioWrapperPrivate::signalErrorChange(QMediaPlayer::Error errorCode) { if (mError != errorCode) { mError = errorCode; mParent->playerErrorSignalChanges(errorCode); } } #include "moc_audiowrapper.cpp" diff --git a/src/audiowrapper_qtmultimedia.cpp b/src/audiowrapper_qtmultimedia.cpp index f33daeb3..13c9ba10 100644 --- a/src/audiowrapper_qtmultimedia.cpp +++ b/src/audiowrapper_qtmultimedia.cpp @@ -1,300 +1,290 @@ /* * 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 "powermanagementinterface.h" #include "qtMultimediaLogging.h" #include #include #include "config-upnp-qt.h" class AudioWrapperPrivate { public: PowerManagementInterface mPowerInterface; 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) { qCDebug(orgKdeElisaPlayerQtMultimedia) << "AudioWrapper::setVolume" << 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) { qCDebug(orgKdeElisaPlayerQtMultimedia) << "AudioWrapper::setSource" << source; d->mPlayer.setMedia({source}); } void AudioWrapper::setPosition(qint64 position) { qCDebug(orgKdeElisaPlayerQtMultimedia) << "AudioWrapper::setPosition" << position; if (d->mPlayer.duration() <= 0) { savePosition(position); return; } d->mPlayer.setPosition(position); } void AudioWrapper::play() { qCDebug(orgKdeElisaPlayerQtMultimedia) << "AudioWrapper::play"; d->mPlayer.play(); if (d->mHasSavedPosition) { qCDebug(orgKdeElisaPlayerQtMultimedia) << "AudioWrapper::playerDurationSignalChanges" << "restore old position" << d->mSavedPosition; setPosition(d->mSavedPosition); d->mHasSavedPosition = false; } } void AudioWrapper::pause() { qCDebug(orgKdeElisaPlayerQtMultimedia) << "AudioWrapper::pause"; d->mPlayer.pause(); } void AudioWrapper::stop() { qCDebug(orgKdeElisaPlayerQtMultimedia) << "AudioWrapper::stop"; d->mPlayer.stop(); } void AudioWrapper::seek(qint64 position) { qCDebug(orgKdeElisaPlayerQtMultimedia) << "AudioWrapper::seek" << position; d->mPlayer.setPosition(position); } -void AudioWrapper::setAudioRole(QAudio::Role audioRole) -{ - d->mPlayer.setAudioRole(audioRole); -} - void AudioWrapper::mediaStatusChanged() { qCDebug(orgKdeElisaPlayerQtMultimedia) << "AudioWrapper::mediaStatusChanged"; } void AudioWrapper::playerStateChanged() { qCDebug(orgKdeElisaPlayerQtMultimedia) << "AudioWrapper::playerStateChanged"; switch(d->mPlayer.state()) { case QMediaPlayer::State::StoppedState: Q_EMIT stopped(); d->mPowerInterface.setPreventSleep(false); break; case QMediaPlayer::State::PlayingState: Q_EMIT playing(); d->mPowerInterface.setPreventSleep(true); break; case QMediaPlayer::State::PausedState: Q_EMIT paused(); d->mPowerInterface.setPreventSleep(false); break; } } void AudioWrapper::playerVolumeChanged() { qCDebug(orgKdeElisaPlayerQtMultimedia) << "AudioWrapper::playerVolumeChanged"; QTimer::singleShot(0, [this]() {Q_EMIT volumeChanged();}); } void AudioWrapper::playerMutedChanged() { qCDebug(orgKdeElisaPlayerQtMultimedia) << "AudioWrapper::playerMutedChanged"; QTimer::singleShot(0, [this]() {Q_EMIT mutedChanged(muted());}); } void AudioWrapper::playerStateSignalChanges(QMediaPlayer::State newState) { qCDebug(orgKdeElisaPlayerQtMultimedia) << "AudioWrapper::playerStateSignalChanges" << newState; QMetaObject::invokeMethod(this, [this, newState]() {Q_EMIT playbackStateChanged(newState);}, Qt::QueuedConnection); } void AudioWrapper::mediaStatusSignalChanges(QMediaPlayer::MediaStatus newStatus) { qCDebug(orgKdeElisaPlayerQtMultimedia) << "AudioWrapper::mediaStatusSignalChanges" << newStatus; QMetaObject::invokeMethod(this, [this, newStatus]() {Q_EMIT statusChanged(newStatus);}, Qt::QueuedConnection); } void AudioWrapper::playerDurationSignalChanges(qint64 newDuration) { qCDebug(orgKdeElisaPlayerQtMultimedia) << "AudioWrapper::playerDurationSignalChanges" << newDuration; QMetaObject::invokeMethod(this, [this, newDuration]() {Q_EMIT durationChanged(newDuration);}, Qt::QueuedConnection); } 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) { qCDebug(orgKdeElisaPlayerQtMultimedia) << "AudioWrapper::saveUndoPosition" << position; d->mUndoSavedPosition = position; } void AudioWrapper::restoreUndoPosition() { qCDebug(orgKdeElisaPlayerQtMultimedia) << "AudioWrapper::restoreUndoPosition"; d->mHasSavedPosition = true; d->mSavedPosition = d->mUndoSavedPosition; } void AudioWrapper::savePosition(qint64 position) { qCDebug(orgKdeElisaPlayerQtMultimedia) << "AudioWrapper::savePosition" << position; if (!d->mHasSavedPosition) { d->mHasSavedPosition = true; d->mSavedPosition = position; qCDebug(orgKdeElisaPlayerQtMultimedia) << "AudioWrapper::savePosition" << "restore old position" << d->mSavedPosition; } } #include "moc_audiowrapper.cpp"