Skip to content

Commit aa18887

Browse files
committed
Added error indicator for when an audio file can not be played; a list without a working file no longer gets stuck in an endless loop
1 parent 2a4bf52 commit aa18887

16 files changed

+129
-39
lines changed

app/ui/tools/audio/AudioInfoView.qml

+19-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
pragma ComponentBehavior: Bound
2-
32
import QtQuick
43
import QtQuick.Controls
54
import src
5+
import IconFonts
6+
import common
67

78
Item {
89
id: audio_info_frame
@@ -67,13 +68,27 @@ Item {
6768
delegate: Item {
6869
id: playlist_delegate
6970

70-
// TODO: type
7171
required property AudioFile modelData
7272
required property int index
7373

74-
width: playlist_view.width
74+
width: error_indicator.visible ? playlist_view.width + error_indicator.width : playlist_view.width
7575
height: playlist_text.height + 10
7676

77+
Text {
78+
id: error_indicator
79+
80+
visible: playlist_delegate.modelData.hadError
81+
82+
font: FontAwesome.fontSolid
83+
text: FontAwesome.triangleExclamation
84+
color: SettingsManager.colors.error
85+
anchors.top: parent.top
86+
anchors.bottom: parent.bottom
87+
anchors.left: parent.left
88+
anchors.leftMargin: 5
89+
verticalAlignment: Text.AlignVCenter
90+
}
91+
7792
Text {
7893
id: playlist_text
7994
clip: true
@@ -83,6 +98,7 @@ Item {
8398
font.pointSize: 10
8499
anchors.centerIn: parent
85100
width: parent.width - 10
101+
leftPadding: error_indicator.visible ? error_indicator.width + error_indicator.anchors.leftMargin : 0
86102
}
87103

88104
ToolTip {

src/tools/audio/audiotool.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ void AudioTool::next()
185185
{
186186
if (m_musicElementType == AudioElement::Type::Music)
187187
{
188-
musicPlayer.next();
188+
musicPlayer.next(false);
189189
}
190190
}
191191

src/tools/audio/metadata/metadatareader.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ void MetaDataReader::setMetaData(QMediaMetaData::Key key, const QVariant &value)
3838
case QMediaMetaData::CoverArtImage: {
3939
if (m_coverFile) m_coverFile->deleteLater();
4040

41+
if (value.value<QImage>().isNull())
42+
{
43+
m_metaData.cover({});
44+
break;
45+
}
46+
4147
m_coverFile = std::make_unique<QTemporaryFile>();
4248

4349
if (m_coverFile->open())
@@ -144,7 +150,7 @@ void MetaDataReader::loadMetaData(const QString &path, const QByteArray &data)
144150

145151
if (auto artist = tag->artist(); !artist.isEmpty())
146152
{
147-
m_metaData.artist(QString::fromStdString(artist.to8Bit(true)).split(", "));
153+
m_metaData.artist(QString::fromStdString(artist.to8Bit(true)).split(", "_L1));
148154
}
149155

150156
if (auto album = tag->album(); !album.isEmpty())

src/tools/audio/players/audioplayer.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public slots:
3131
virtual void stop() = 0;
3232
virtual void setVolume(int linear, int logarithmic) = 0;
3333
virtual void again() = 0;
34-
virtual void next() = 0;
34+
virtual void next(bool withError) = 0;
3535

3636
protected:
3737
static auto normalizeVolume(int volume) -> float;

src/tools/audio/players/bufferedaudioplayer.cpp

+42-13
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ void BufferedAudioPlayer::setIndex(qsizetype index)
5353
}
5454
else
5555
{
56-
next();
56+
next(true);
5757
}
5858
}
5959
}
@@ -110,14 +110,14 @@ auto BufferedAudioPlayer::loadPlaylist() -> QFuture<void>
110110
void BufferedAudioPlayer::handleUnsupportedMediaSource(const AudioFile &file)
111111
{
112112
qCWarning(gmAudioBufferedPlayer()) << "Media type" << file.source() << "is currently not supported.";
113-
next();
113+
next(true);
114114
}
115115

116116
void BufferedAudioPlayer::onFileReceived(const Files::FileDataResult &result)
117117
{
118118
if (!result.success() || result.data().isEmpty())
119119
{
120-
next();
120+
next(true);
121121
return;
122122
}
123123

@@ -149,8 +149,6 @@ void BufferedAudioPlayer::stop()
149149

150150
m_mediaPlayer.stop();
151151
state(AudioPlayer::State::Stopped);
152-
153-
m_playlist->clear();
154152
}
155153

156154
void BufferedAudioPlayer::setVolume(int linear, int logarithmic)
@@ -164,14 +162,29 @@ void BufferedAudioPlayer::again()
164162
m_mediaPlayer.setPosition(0);
165163
}
166164

167-
void BufferedAudioPlayer::next()
165+
void BufferedAudioPlayer::next(bool withError)
168166
{
169167
if (!m_element || m_playlist->isEmpty())
170168
{
171169
stop();
172170
return;
173171
}
174172

173+
if (withError)
174+
{
175+
auto *file = m_playlist->at(playlistIndex());
176+
if (file)
177+
{
178+
file->hadError(true);
179+
}
180+
181+
if (!m_playlist->hasElementsWithoutErrors())
182+
{
183+
stop();
184+
return;
185+
}
186+
}
187+
175188
// Complete random
176189
if (m_element->mode() == AudioElement::Mode::Random)
177190
{
@@ -201,7 +214,16 @@ void BufferedAudioPlayer::next()
201214
void BufferedAudioPlayer::onMediaPlayerPlaybackStateChanged(QMediaPlayer::PlaybackState newState)
202215
{
203216
qCDebug(gmAudioBufferedPlayer) << "Media player playback state changed:" << newState;
204-
if (newState == QMediaPlayer::PlayingState) state(State::Playing);
217+
if (newState == QMediaPlayer::PlayingState)
218+
{
219+
state(State::Playing);
220+
221+
auto *file = m_playlist->at(playlistIndex());
222+
if (file)
223+
{
224+
file->hadError(false);
225+
}
226+
}
205227
}
206228

207229
void BufferedAudioPlayer::onMediaStatusChanged(QMediaPlayer::MediaStatus status)
@@ -212,7 +234,7 @@ void BufferedAudioPlayer::onMediaStatusChanged(QMediaPlayer::MediaStatus status)
212234
{
213235
case QMediaPlayer::EndOfMedia:
214236
qCDebug(gmAudioBufferedPlayer()) << "End of media was reached, playing next file ...";
215-
next();
237+
next(false);
216238
break;
217239
case QMediaPlayer::BufferingMedia:
218240
state(State::Loading);
@@ -234,7 +256,7 @@ void BufferedAudioPlayer::onMediaPlayerErrorOccurred(QMediaPlayer::Error error,
234256

235257
if (error != QMediaPlayer::NoError)
236258
{
237-
next();
259+
next(true);
238260
}
239261
}
240262

@@ -244,7 +266,7 @@ void BufferedAudioPlayer::startPlaying()
244266

245267
if (m_element->mode() == AudioElement::Mode::Random)
246268
{
247-
next();
269+
next(false);
248270
return;
249271
}
250272

@@ -298,14 +320,21 @@ void BufferedAudioPlayer::loadWebFile(const QString &url)
298320
m_mediaPlayer.setSource(QUrl(url));
299321
m_mediaPlayer.play();
300322
m_audioOutput.setMuted(false);
323+
324+
QMediaMetaData metaData;
325+
metaData.insert(QMediaMetaData::Key::Title, "-");
326+
metaData.insert(QMediaMetaData::Key::Author, "-");
327+
metaData.insert(QMediaMetaData::Key::AlbumTitle, "-");
328+
metaData.insert(QMediaMetaData::Key::CoverArtImage, QImage());
329+
emit metaDataChanged(metaData);
301330
}
302331

303332
void BufferedAudioPlayer::loadYouTubeFile(AudioFile &file)
304333
{
305334
const Services::VideoId id(file.url());
306335
if (!id.isValid())
307336
{
308-
next();
337+
next(true);
309338
return;
310339
}
311340

@@ -314,7 +343,7 @@ void BufferedAudioPlayer::loadYouTubeFile(AudioFile &file)
314343
.then([this, &file](const Services::YouTubeVideo &video) {
315344
if (video.audioStreamUrl.isEmpty())
316345
{
317-
next();
346+
next(true);
318347
return;
319348
}
320349

@@ -333,7 +362,7 @@ void BufferedAudioPlayer::loadYouTubeFile(AudioFile &file)
333362
emit metaDataChanged(metaData);
334363
});
335364
})
336-
.onCanceled([this]() { next(); });
365+
.onCanceled([this]() { next(true); });
337366
}
338367

339368
void BufferedAudioPlayer::applyShuffleMode()

src/tools/audio/players/bufferedaudioplayer.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public slots:
4242
void stop() override;
4343
void setVolume(int linear, int logarithmic) override;
4444
void again() override;
45-
void next() override;
45+
void next(bool withError) override;
4646

4747
signals:
4848
void playlistChanged();

src/tools/audio/players/musicplayer.cpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -81,21 +81,27 @@ void MusicPlayer::handleUnsupportedMediaSource(const AudioFile &file)
8181
break;
8282
default:
8383
qCCritical(gmAudioMusic()) << "loadMedia() is not implemented for type" << file.source();
84-
next();
84+
next(true);
8585
break;
8686
}
8787
}
8888

8989
void MusicPlayer::loadSpotifyFile(const AudioFile &file)
9090
{
91+
if (!SpotifyPlayer::canPlay())
92+
{
93+
next(true);
94+
return;
95+
}
96+
9197
m_spotifyPlayer.play(file.url());
9298
state(State::Playing);
9399
}
94100

95101
void MusicPlayer::onSpotifySongEnded()
96102
{
97103
qCDebug(gmAudioMusic()) << "Spotify song ended, starting next song ...";
98-
next();
104+
next(false);
99105
}
100106

101107
void MusicPlayer::onSpotifyStateChanged(State state)

src/tools/audio/players/soundplayercontroller.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@ public slots:
3333
emit stopAll();
3434
}
3535
void setVolume(int linear, int logarithmic) override;
36-
void next() override
37-
{ /* Not Implemented */
36+
void next(bool withError) override
37+
{
38+
/* Not Implemented */
39+
Q_UNUSED(withError)
3840
}
3941
void again() override
4042
{ /* Not Implemented */

src/tools/audio/players/spotifyplayer.cpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ SpotifyPlayer::SpotifyPlayer(MetaDataReader &mDReader, QObject *parent)
1818
connect(&m_metaDataTimer, &QTimer::timeout, this, &SpotifyPlayer::onMetaDataTimerTimeout);
1919
}
2020

21+
auto SpotifyPlayer::canPlay() -> bool
22+
{
23+
return isSpotifyAvailable();
24+
}
25+
2126
/// The current song has ended, stop any spotify activity and notify music player
2227
void SpotifyPlayer::onDurationTimerTimeout()
2328
{
@@ -42,7 +47,7 @@ auto SpotifyPlayer::isSpotifyAvailable() -> bool
4247
return false;
4348
}
4449

45-
qCWarning(gmAudioSpotify) << "Spotify connection is disabled.";
50+
qCWarning(gmAudioSpotify) << "Not connected to Spotify.";
4651
return false;
4752
}
4853

@@ -153,7 +158,7 @@ void SpotifyPlayer::pausePlay()
153158
/**
154159
* @brief Switch to next song in playlist
155160
*/
156-
void SpotifyPlayer::next()
161+
void SpotifyPlayer::next(bool /*withError*/)
157162
{
158163
qCDebug(gmAudioSpotify) << "Skipping to next track ...";
159164

src/tools/audio/players/spotifyplayer.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@ class SpotifyPlayer : public AudioPlayer
1313
public:
1414
SpotifyPlayer(MetaDataReader &mDReader, QObject *parent = nullptr);
1515

16+
[[nodiscard]] static auto canPlay() -> bool;
17+
1618
public slots:
1719
void play(const QString &uri);
1820
void play() override;
1921
void pause() override;
2022
void stop() override;
2123
void pausePlay();
22-
void next() override;
24+
void next(bool withError) override;
2325
void again() override;
2426
void setVolume(int linear, int logarithmic) override;
2527

src/tools/audio/playlist/audioplaylist.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,13 @@ void AudioPlaylist::clear()
8787
{
8888
m_files.clear();
8989
}
90+
91+
auto AudioPlaylist::hasElementsWithoutErrors() const -> bool
92+
{
93+
foreach (const auto *file, m_files)
94+
{
95+
if (!file->hadError()) return true;
96+
}
97+
98+
return false;
99+
}

src/tools/audio/playlist/audioplaylist.h

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ class AudioPlaylist
3737
void shuffle();
3838
void clear();
3939

40+
[[nodiscard]] auto hasElementsWithoutErrors() const -> bool;
41+
4042
private:
4143
QList<AudioFile *> m_files;
4244
Type m_type = Type::Undefined;

0 commit comments

Comments
 (0)