diff --git a/linphone-desktop/resources.qrc b/linphone-desktop/resources.qrc index 235ed9ee0..c605eb269 100644 --- a/linphone-desktop/resources.qrc +++ b/linphone-desktop/resources.qrc @@ -401,6 +401,7 @@ ui/views/App/Styles/Main/MainWindowStyle.qml ui/views/App/Styles/Main/ManageAccountsStyle.qml ui/views/App/Styles/qmldir + ui/views/App/Styles/Settings/SettingsAudioStyle.qml ui/views/App/Styles/Settings/SettingsSipAccountsEditStyle.qml ui/views/App/Styles/Settings/SettingsVideoPreviewStyle.qml ui/views/App/Styles/Settings/SettingsWindowStyle.qml diff --git a/linphone-desktop/src/components/core/CoreManager.cpp b/linphone-desktop/src/components/core/CoreManager.cpp index e82140c01..4cf1ee2b7 100644 --- a/linphone-desktop/src/components/core/CoreManager.cpp +++ b/linphone-desktop/src/components/core/CoreManager.cpp @@ -29,6 +29,8 @@ #include #include +#define CBS_CALL_INTERVAL 20 + using namespace std; // ============================================================================= @@ -66,7 +68,7 @@ void CoreManager::init (QObject *parent, const QString &configPath) { mInstance = new CoreManager(parent, configPath); QTimer *timer = mInstance->mCbsTimer = new QTimer(mInstance); - timer->setInterval(20); + timer->setInterval(CBS_CALL_INTERVAL); QObject::connect(timer, &QTimer::timeout, mInstance, &CoreManager::iterate); } diff --git a/linphone-desktop/src/components/sound-player/SoundPlayer.cpp b/linphone-desktop/src/components/sound-player/SoundPlayer.cpp index fb4c2ed93..06f683bcc 100644 --- a/linphone-desktop/src/components/sound-player/SoundPlayer.cpp +++ b/linphone-desktop/src/components/sound-player/SoundPlayer.cpp @@ -20,11 +20,15 @@ * Author: Ronan Abhamon */ +#include + #include "../../Utils.hpp" #include "../core/CoreManager.hpp" #include "SoundPlayer.hpp" +#define FORCE_CLOSE_TIMER_INTERVAL 20 + using namespace std; // ============================================================================= @@ -37,7 +41,14 @@ public: private: void onEofReached (const shared_ptr &) override { - mSoundPlayer->stop(); + QMutex &mutex = mSoundPlayer->mForceCloseMutex; + + // Workaround. + // This callback is called in a standard thread of mediastreamer, not a QThread. + // Signals, connect functions, timers... are unavailable. + mutex.lock(); + mSoundPlayer->mForceClose = true; + mutex.unlock(); } SoundPlayer *mSoundPlayer; @@ -46,6 +57,11 @@ private: // ----------------------------------------------------------------------------- SoundPlayer::SoundPlayer (QObject *parent) : QObject(parent) { + mForceCloseTimer = new QTimer(this); + mForceCloseTimer->setInterval(FORCE_CLOSE_TIMER_INTERVAL); + + QObject::connect(mForceCloseTimer, &QTimer::timeout, this, &SoundPlayer::handleEof); + mHandlers = make_shared(this); mInternalPlayer = CoreManager::getInstance()->getCore()->createLocalPlayer("", "", nullptr); @@ -63,6 +79,7 @@ void SoundPlayer::pause () { return; } + mForceCloseTimer->stop(); mPlaybackState = SoundPlayer::PausedState; emit paused(); @@ -87,6 +104,7 @@ void SoundPlayer::play () { return; } + mForceCloseTimer->start(); mPlaybackState = SoundPlayer::PlayingState; emit playing(); @@ -97,9 +115,11 @@ void SoundPlayer::stop () { if (mPlaybackState == SoundPlayer::StoppedState) return; - mInternalPlayer->close(); + mForceCloseTimer->stop(); mPlaybackState = SoundPlayer::StoppedState; + mInternalPlayer->close(); + emit stopped(); emit playbackStateChanged(mPlaybackState); } @@ -118,6 +138,19 @@ int SoundPlayer::getPosition () const { // ----------------------------------------------------------------------------- +void SoundPlayer::handleEof () { + mForceCloseMutex.lock(); + + if (mForceClose) { + mForceClose = false; + stop(); + } + + mForceCloseMutex.unlock(); +} + +// ----------------------------------------------------------------------------- + void SoundPlayer::setError (const QString &message) { qWarning() << message; mInternalPlayer->close(); diff --git a/linphone-desktop/src/components/sound-player/SoundPlayer.hpp b/linphone-desktop/src/components/sound-player/SoundPlayer.hpp index ca9b3d7b8..afc9b24bf 100644 --- a/linphone-desktop/src/components/sound-player/SoundPlayer.hpp +++ b/linphone-desktop/src/components/sound-player/SoundPlayer.hpp @@ -25,10 +25,13 @@ #include +#include #include // ============================================================================= +class QTimer; + namespace linphone { class Player; } @@ -55,13 +58,13 @@ public: SoundPlayer (QObject *parent = Q_NULLPTR); ~SoundPlayer () = default; - void pause (); - void play (); - void stop (); + Q_INVOKABLE void pause (); + Q_INVOKABLE void play (); + Q_INVOKABLE void stop (); - void seek (int offset); + Q_INVOKABLE void seek (int offset); - int getPosition () const; + Q_INVOKABLE int getPosition () const; signals: void sourceChanged (const QString &source); @@ -73,6 +76,8 @@ signals: void playbackStateChanged (PlaybackState playbackState); private: + void handleEof (); + void setError (const QString &message); QString getSource () const; @@ -86,6 +91,11 @@ private: QString mSource; PlaybackState mPlaybackState = StoppedState; + bool mForceClose = false; + QMutex mForceCloseMutex; + + QTimer *mForceCloseTimer; + std::shared_ptr mInternalPlayer; std::shared_ptr mHandlers; }; diff --git a/linphone-desktop/ui/views/App/Settings/SettingsAudio.qml b/linphone-desktop/ui/views/App/Settings/SettingsAudio.qml index 4f6cc53b2..c8c7caa17 100644 --- a/linphone-desktop/ui/views/App/Settings/SettingsAudio.qml +++ b/linphone-desktop/ui/views/App/Settings/SettingsAudio.qml @@ -73,7 +73,40 @@ TabContainer { FileChooserButton { selectedFile: SettingsModel.ringPath - onAccepted: SettingsModel.ringPath = selectedFile + onAccepted: { + ringPlayer.stop() + SettingsModel.ringPath = selectedFile + } + + ActionSwitch { + anchors { + left: parent.right + leftMargin: SettingsAudioStyle.ringPlayer.leftMargin + } + + enabled: ringPlayer.playbackState === SoundPlayer.PlayingState + icon: 'pause' + + onClicked: { + if (enabled) { + ringPlayer.stop() + } else { + ringPlayer.play() + } + } + + SoundPlayer { + id: ringPlayer + + source: SettingsModel.ringPath + } + + Connections { + target: window + + onClosing: ringPlayer.stop() + } + } } } } diff --git a/linphone-desktop/ui/views/App/Styles/Settings/SettingsAudioStyle.qml b/linphone-desktop/ui/views/App/Styles/Settings/SettingsAudioStyle.qml new file mode 100644 index 000000000..b8c52a602 --- /dev/null +++ b/linphone-desktop/ui/views/App/Styles/Settings/SettingsAudioStyle.qml @@ -0,0 +1,10 @@ +pragma Singleton +import QtQuick 2.7 + +// ============================================================================= + +QtObject { + property QtObject ringPlayer: QtObject { + property int leftMargin: 10 + } +} diff --git a/linphone-desktop/ui/views/App/Styles/qmldir b/linphone-desktop/ui/views/App/Styles/qmldir index b18d02ec9..f098125ef 100644 --- a/linphone-desktop/ui/views/App/Styles/qmldir +++ b/linphone-desktop/ui/views/App/Styles/qmldir @@ -25,6 +25,7 @@ singleton MainWindowMenuBarStyle 1.0 Main/MainWindowMenuBarSty singleton MainWindowStyle 1.0 Main/MainWindowStyle.qml singleton ManageAccountsStyle 1.0 Main/ManageAccountsStyle.qml +singleton SettingsAudioStyle 1.0 Settings/SettingsAudioStyle.qml singleton SettingsSipAccountsEditStyle 1.0 Settings/SettingsSipAccountsEditStyle.qml singleton SettingsVideoPreviewStyle 1.0 Settings/SettingsVideoPreviewStyle.qml singleton SettingsWindowStyle 1.0 Settings/SettingsWindowStyle.qml