Add volume control

This commit is contained in:
Anika Raemer 2021-03-14 14:42:32 +01:00
parent 5d5e3c6888
commit 4a83f971f3
14 changed files with 144 additions and 32 deletions

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject> <!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.8.2, 2019-08-01T21:13:48. --> <!-- Written by QtCreator 4.8.2, 2021-03-13T17:07:20. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>

View file

@ -1,4 +1,5 @@
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Controls 2.4
import QtGraphicalEffects 1.0 import QtGraphicalEffects 1.0
Item{ Item{
@ -6,7 +7,7 @@ Item{
property int margins: 20 property int margins: 20
RoundButton{ RoundImageButton{
id: backNavigation id: backNavigation
anchors.left: parent.left anchors.left: parent.left
anchors.top: parent.top anchors.top: parent.top
@ -16,11 +17,15 @@ Item{
} }
} }
RoundButton{ RoundImageButton{
id: closeApp id: closeAppButton
anchors.right: parent.right anchors.right: parent.right
anchors.top: parent.top anchors.top: parent.top
anchors.margins: container.margins anchors.margins: visible ? container.margins : 0
visible: container.height > 500
diameter: visible ? defaultDiameter : 0
imageSource: "qrc:/icon_close" imageSource: "qrc:/icon_close"
onClicked: { onClicked: {
Qt.quit(); Qt.quit();
@ -49,6 +54,24 @@ Item{
} }
} }
VolumeSlider{
id: volumeSlider
anchors{
right: parent.right
top: closeAppButton.bottom
bottom: controlPannel.top
margins: container.margins
topMargin: closeAppButton.visible ? 2*container.margins : container.margins
}
from: 34 // we cannot hear anything if lower than 35%
to: 100
stepSize: 1
value: musicModel.pAudioVolume
onValueChanged: {
console.log(musicModel.pAudioVolume, value);
musicModel.pAudioVolume = value;
}
}
PlayerControlPannel { PlayerControlPannel {
id: controlPannel id: controlPannel
anchors.left: parent.left anchors.left: parent.left

View file

@ -6,7 +6,7 @@ import QtQuick 2.0
Item { Item {
id: container id: container
property int margins: 20 property int margins: 20
RoundButton{ RoundImageButton{
id: back id: back
anchors.top: parent.top anchors.top: parent.top
@ -16,9 +16,9 @@ Item {
visible: navigationList.pIsBackVisible visible: navigationList.pIsBackVisible
onClicked: navigationList.navigateBack(); onClicked: navigationList.navigateBack();
} // RoundButton: navigate back } // MyRoundButton: navigate back
RoundButton{ RoundImageButton{
id: closeApp id: closeApp
anchors.right: parent.right anchors.right: parent.right
anchors.top: parent.top anchors.top: parent.top
@ -27,7 +27,7 @@ Item {
onClicked: { onClicked: {
Qt.quit(); Qt.quit();
} }
} // RoundButton: closeApp } // MyRoundButton: closeApp
Rectangle{ Rectangle{
anchors.left: parent.left anchors.left: parent.left

View file

@ -9,11 +9,11 @@ Item {
anchors.centerIn: parent anchors.centerIn: parent
spacing: container.spacing spacing: container.spacing
RoundButton{ RoundImageButton{
id: previous id: previous
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
width: 60 diameter: 60
imageSource: "qrc:/icon_previous" imageSource: "qrc:/icon_previous"
enabled: model.pHasPrevious enabled: model.pHasPrevious
@ -22,21 +22,21 @@ Item {
model.playPrevious(); model.playPrevious();
} }
} }
RoundButton{ RoundImageButton{
id: playPause id: playPause
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
width: 80 diameter: 80
imageSource: model.pIsPlaying ? "qrc:/icon_pause" : "qrc:/icon_play" imageSource: model.pIsPlaying ? "qrc:/icon_pause" : "qrc:/icon_play"
onClicked:{ onClicked:{
model.playPause(); model.playPause();
} }
} }
RoundButton{ RoundImageButton{
id: stop id: stop
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
width: 60 diameter: 60
imageSource: "qrc:/icon_stop" imageSource: "qrc:/icon_stop"
enabled: model.pIsPlaying enabled: model.pIsPlaying
@ -45,11 +45,11 @@ Item {
model.stopMusic(); model.stopMusic();
} }
} }
RoundButton{ RoundImageButton{
id: next id: next
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
width: 60 diameter: 60
imageSource: "qrc:/icon_next" imageSource: "qrc:/icon_next"
enabled: model.pHasNext enabled: model.pHasNext

View file

@ -7,6 +7,12 @@ import QtQuick.Controls 2.4
Button { Button {
id: container id: container
property alias imageSource: image.source property alias imageSource: image.source
// default button diameter -> default width, readonly
readonly property int defaultDiameter: 65
// button diameter -> width
property int diameter: defaultDiameter
// diameter of content image -> width
property int imageDiameter: 0.5*diameter
background: Rectangle{ background: Rectangle{
@ -15,14 +21,14 @@ Button {
color: "white" color: "white"
implicitWidth: 65 implicitWidth: container.diameter
implicitHeight: width implicitHeight: container.diameter
radius: width/2 radius: container.diameter/2
Image{ Image{
id: image id: image
anchors.centerIn: parent anchors.centerIn: parent
width: 30 width: container.imageDiameter
height: width height: width
source: "qrc:/icon_back" source: "qrc:/icon_back"
} }
@ -31,7 +37,7 @@ Button {
z: 1 z: 1
visible: !container.enabled visible: !container.enabled
anchors.centerIn: parent anchors.centerIn: parent
width: 30 width: image.width
height: width height: width
color: "#99ffffff" color: "#99ffffff"
} }

31
LenaPi/VolumeSlider.qml Normal file
View file

@ -0,0 +1,31 @@
import QtQuick 2.0
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.3
ColumnLayout {
property alias from: slider.from
property alias to: slider.to
property alias stepSize: slider.stepSize
property alias value: slider.value
spacing: 5
RoundImageButton{
id: increaseButton
imageSource: "qrc:///icon_increase_volume"
onClicked: slider.increase();
}
Slider{
id: slider
Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter
orientation: Qt.Vertical
from: 34 // we cannot hear anything if lower than 35%
to: 100
stepSize: 1
value: 50
}
RoundImageButton{
id: decreaseButton
imageSource: "qrc:///icon_decrease_volume"
onClicked: slider.decrease();
}
}

View file

@ -10,17 +10,20 @@ MusicController::MusicController(QObject *parent) : QObject(parent)
mVlc = new VlcInstance(VlcCommon::args(), this); mVlc = new VlcInstance(VlcCommon::args(), this);
mModel = new MusicModel(mVlc, this); mModel = new MusicModel(mVlc, this);
mPlayer = new VlcMediaListPlayer(mVlc); mPlayer = new VlcMediaListPlayer(mVlc);
mVlcAudio = new VlcAudio(mPlayer->mediaPlayer());
connect(mModel, &MusicModel::navigateTo, this, &MusicController::navigateTo); connect(mModel, &MusicModel::navigateTo, this, &MusicController::onNavigationRequest);
connect(mModel, &MusicModel::navigateTo, [this](NavigationItemModel*){
if(mModel->isPlaying()) mModel->playPause(); //connect(mModel, &MusicModel::play, mPlayer, &VlcMediaListPlayer::play);
connect(mModel, &MusicModel::play, [this](){
mVlcAudio->setVolume(mModel->getAudioVolume());
mPlayer->play();
}); });
connect(mModel, &MusicModel::play, mPlayer, &VlcMediaListPlayer::play);
connect(mModel, &MusicModel::stop, mPlayer, &VlcMediaListPlayer::stop); connect(mModel, &MusicModel::stop, mPlayer, &VlcMediaListPlayer::stop);
connect(mModel, &MusicModel::previous, mPlayer, &VlcMediaListPlayer::previous); connect(mModel, &MusicModel::previous, mPlayer, &VlcMediaListPlayer::previous);
connect(mModel, &MusicModel::next, mPlayer, &VlcMediaListPlayer::next); connect(mModel, &MusicModel::next, mPlayer, &VlcMediaListPlayer::next);
connect(mModel, &MusicModel::pause, mPlayer->mediaPlayer(), &VlcMediaPlayer::pause); connect(mModel, &MusicModel::pause, mPlayer->mediaPlayer(), &VlcMediaPlayer::pause);
connect(mModel, &MusicModel::audioVolumeChanged, mVlcAudio, &VlcAudio::setVolume);
connect(mPlayer, SIGNAL(nextItemSet(VlcMedia*)), mModel, SLOT(onNextMediaSet(VlcMedia*))); connect(mPlayer, SIGNAL(nextItemSet(VlcMedia*)), mModel, SLOT(onNextMediaSet(VlcMedia*)));
connect(mPlayer->mediaPlayer(), &VlcMediaPlayer::lengthChanged, mModel, &MusicModel::onLengthChanged); connect(mPlayer->mediaPlayer(), &VlcMediaPlayer::lengthChanged, mModel, &MusicModel::onLengthChanged);
@ -33,6 +36,7 @@ MusicController::MusicController(QObject *parent) : QObject(parent)
MusicController::~MusicController() MusicController::~MusicController()
{ {
mPlayer->deleteLater(); mPlayer->deleteLater();
mVlcAudio->deleteLater();
} }
void MusicController::initPlayer(NavigationItemModel *item) void MusicController::initPlayer(NavigationItemModel *item)
@ -58,3 +62,11 @@ void MusicController::setContextProperties()
if(!mContext) return; if(!mContext) return;
mContext->setContextProperty("musicModel", mModel); mContext->setContextProperty("musicModel", mModel);
} }
void MusicController::onNavigationRequest(NavigationItemModel *item)
{
if(mModel->isPlaying()) {
mModel->playPause();
}
emit navigateTo(item);
}

View file

@ -8,6 +8,7 @@
#include <VLCQtCore/Common.h> #include <VLCQtCore/Common.h>
#include <VLCQtCore/Instance.h> #include <VLCQtCore/Instance.h>
#include <VLCQtCore/MediaListPlayer.h> #include <VLCQtCore/MediaListPlayer.h>
#include <VLCQtCore/Audio.h>
class MusicModel; class MusicModel;
@ -31,12 +32,21 @@ private:
QQmlContext* mContext = Q_NULLPTR; QQmlContext* mContext = Q_NULLPTR;
MusicModel* mModel; MusicModel* mModel = Q_NULLPTR;
VlcInstance* mVlc; VlcInstance* mVlc = Q_NULLPTR;
VlcMediaListPlayer* mPlayer; VlcMediaListPlayer* mPlayer = Q_NULLPTR;
VlcAudio* mVlcAudio = Q_NULLPTR;
bool mIsMediaListSet = false; bool mIsMediaListSet = false;
private slots:
/**
* @brief Stop player if necessary and forward signal navigatTo
* @param item target of navigation request
* @see navigateTo(NavigationItemModel* item);
*/
void onNavigationRequest(NavigationItemModel* item);
}; };
#endif // MUSICCONTROLLER_H #endif // MUSICCONTROLLER_H

View file

@ -9,5 +9,7 @@
<file alias="icon_previous">resources/previous.jpg</file> <file alias="icon_previous">resources/previous.jpg</file>
<file alias="icon_stop">resources/stop.jpg</file> <file alias="icon_stop">resources/stop.jpg</file>
<file alias="icon_close">resources/close.png</file> <file alias="icon_close">resources/close.png</file>
<file alias="icon_increase_volume">resources/speaker_high_volume.png</file>
<file alias="icon_decrease_volume">resources/speaker_low_volume.png</file>
</qresource> </qresource>
</RCC> </RCC>

View file

@ -6,6 +6,7 @@
MusicModel::MusicModel(VlcInstance* instance, QObject *parent) : QObject(parent), MusicModel::MusicModel(VlcInstance* instance, QObject *parent) : QObject(parent),
mVlc(instance), mMedia(new VlcMediaList(instance)) mVlc(instance), mMedia(new VlcMediaList(instance))
{ {
/* nothing */
} }
MusicModel::~MusicModel() MusicModel::~MusicModel()
@ -101,6 +102,20 @@ bool MusicModel::hasPrevious() const
return mHasPrevious; return mHasPrevious;
} }
void MusicModel::setAudioVolume(int newVolume)
{
if(newVolume != mAudioVolume){
if(newVolume > 100){
mAudioVolume = 100;
} else if(newVolume < 0){
mAudioVolume = 0;
} else {
mAudioVolume = newVolume;
}
emit audioVolumeChanged(mAudioVolume);
}
}
double MusicModel::getProgress() const double MusicModel::getProgress() const
{ {
return mCurrentMediaItemProgress; return mCurrentMediaItemProgress;

View file

@ -18,6 +18,7 @@ class MusicModel : public QObject
Q_PROPERTY(QString pMediaLength READ getMediaLength NOTIFY mediaLengthChanged) Q_PROPERTY(QString pMediaLength READ getMediaLength NOTIFY mediaLengthChanged)
Q_PROPERTY(QString pTime READ getTime NOTIFY progressChanged) Q_PROPERTY(QString pTime READ getTime NOTIFY progressChanged)
Q_PROPERTY(QString pMediaTitle READ getMediaTitle NOTIFY mediaTitleChanged) Q_PROPERTY(QString pMediaTitle READ getMediaTitle NOTIFY mediaTitleChanged)
Q_PROPERTY(int pAudioVolume READ getAudioVolume WRITE setAudioVolume NOTIFY audioVolumeChanged)
signals: signals:
void navigateTo(NavigationItemModel *item); void navigateTo(NavigationItemModel *item);
@ -33,6 +34,7 @@ signals:
void progressChanged(); void progressChanged();
void mediaLengthChanged(); void mediaLengthChanged();
void mediaTitleChanged(); void mediaTitleChanged();
void audioVolumeChanged(int newVolume);
public: public:
MusicModel(VlcInstance* instance, QObject *parent = Q_NULLPTR); MusicModel(VlcInstance* instance, QObject *parent = Q_NULLPTR);
@ -54,6 +56,15 @@ public:
bool hasNext() const; bool hasNext() const;
bool hasPrevious() const; bool hasPrevious() const;
inline int getAudioVolume() const { return mAudioVolume; }
/**
* @brief Set audio volume. Information is transferred to VlcAudio
* @param newVolume value between 0 and 100 (audio level in percent)
* Ensures that volume is inbetween 0 and 100. If this range is exceeded,
* the volume is set to the lowest and highest allowed value, respectively.
*/
void setAudioVolume(int newVolume);
double getProgress() const; double getProgress() const;
QString getMediaTitle() const; QString getMediaTitle() const;
@ -79,10 +90,11 @@ private:
int mCurrentMediaItemLength = 0; int mCurrentMediaItemLength = 0;
int mCurrentTime = 0; int mCurrentTime = 0;
double mCurrentMediaItemProgress = 0; double mCurrentMediaItemProgress = 0;
int mAudioVolume{50};
QString mMediaTitle = QString(""); QString mMediaTitle = QString("");
NavigationItemModel* mCurrentItem = Q_NULLPTR; NavigationItemModel* mCurrentItem = Q_NULLPTR;
VlcMediaList* mMedia = Q_NULLPTR; VlcMediaList* mMedia = Q_NULLPTR;
VlcInstance* mVlc; VlcInstance* mVlc = Q_NULLPTR;
}; };
#endif // MUSICMODEL_H #endif // MUSICMODEL_H

View file

@ -4,11 +4,12 @@
<file>MainForm.ui.qml</file> <file>MainForm.ui.qml</file>
<file>NavigationListDelegate.qml</file> <file>NavigationListDelegate.qml</file>
<file>MyScrollView.qml</file> <file>MyScrollView.qml</file>
<file>RoundButton.qml</file> <file>RoundImageButton.qml</file>
<file>Navigation.qml</file> <file>Navigation.qml</file>
<file>MusicPlayer.qml</file> <file>MusicPlayer.qml</file>
<file>MediaProgress.qml</file> <file>MediaProgress.qml</file>
<file>PlayerButtons.qml</file> <file>PlayerButtons.qml</file>
<file>PlayerControlPannel.qml</file> <file>PlayerControlPannel.qml</file>
<file>VolumeSlider.qml</file>
</qresource> </qresource>
</RCC> </RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB