Wait for set state to finish before deleting pipeline
Setting state to GST_STATE_NULL sometimes blocks, to fix this use the threadpool to set the state to NULL and wait with deleting the pipeline until the state is changed. This fixes blocking the main thread when switching Spotify songs.
This commit is contained in:
@@ -1371,8 +1371,12 @@ void MainWindow::MediaStopped() {
|
||||
ui_->button_love->setEnabled(false);
|
||||
tray_icon_->LoveStateChanged(false);
|
||||
|
||||
track_position_timer_->stop();
|
||||
track_slider_timer_->stop();
|
||||
if (track_position_timer_->isActive()) {
|
||||
track_position_timer_->stop();
|
||||
}
|
||||
if (track_slider_timer_->isActive()) {
|
||||
track_slider_timer_->stop();
|
||||
}
|
||||
ui_->track_slider->SetStopped();
|
||||
tray_icon_->SetProgress(0);
|
||||
tray_icon_->SetStopped();
|
||||
@@ -1400,8 +1404,12 @@ void MainWindow::MediaPaused() {
|
||||
|
||||
ui_->action_play_pause->setEnabled(true);
|
||||
|
||||
track_position_timer_->stop();
|
||||
track_slider_timer_->stop();
|
||||
if (!track_position_timer_->isActive()) {
|
||||
track_position_timer_->start();
|
||||
}
|
||||
if (!track_slider_timer_->isActive()) {
|
||||
track_slider_timer_->start();
|
||||
}
|
||||
|
||||
tray_icon_->SetPaused();
|
||||
|
||||
@@ -1426,8 +1434,13 @@ void MainWindow::MediaPlaying() {
|
||||
ui_->track_slider->SetCanSeek(can_seek);
|
||||
tray_icon_->SetPlaying(enable_play_pause);
|
||||
|
||||
track_position_timer_->start();
|
||||
track_slider_timer_->start();
|
||||
if (!track_position_timer_->isActive()) {
|
||||
track_position_timer_->start();
|
||||
}
|
||||
if (!track_slider_timer_->isActive()) {
|
||||
track_slider_timer_->start();
|
||||
}
|
||||
|
||||
UpdateTrackPosition();
|
||||
|
||||
}
|
||||
@@ -1566,7 +1579,7 @@ void MainWindow::LoadPlaybackStatus() {
|
||||
const EngineBase::State playback_state = static_cast<EngineBase::State>(s.value("playback_state", static_cast<int>(EngineBase::State::Empty)).toInt());
|
||||
s.endGroup();
|
||||
|
||||
if (resume_playback && playback_state != EngineBase::State::Empty && playback_state != EngineBase::State::Idle) {
|
||||
if (resume_playback && (playback_state == EngineBase::State::Playing || playback_state == EngineBase::State::Paused)) {
|
||||
SharedPtr<QMetaObject::Connection> connection = make_shared<QMetaObject::Connection>();
|
||||
*connection = QObject::connect(&*app_->playlist_manager(), &PlaylistManager::AllPlaylistsLoaded, this, [this, connection]() {
|
||||
QObject::disconnect(*connection);
|
||||
@@ -1583,21 +1596,19 @@ void MainWindow::ResumePlayback() {
|
||||
Settings s;
|
||||
s.beginGroup(Player::kSettingsGroup);
|
||||
const EngineBase::State playback_state = static_cast<EngineBase::State>(s.value("playback_state", static_cast<int>(EngineBase::State::Empty)).toInt());
|
||||
int playback_playlist = s.value("playback_playlist", -1).toInt();
|
||||
int playback_position = s.value("playback_position", 0).toInt();
|
||||
const int playback_playlist = s.value("playback_playlist", -1).toInt();
|
||||
const int playback_position = s.value("playback_position", 0).toInt();
|
||||
s.endGroup();
|
||||
|
||||
if (playback_playlist == app_->playlist_manager()->current()->id()) {
|
||||
// Set active to current to resume playback on correct playlist.
|
||||
app_->playlist_manager()->SetActiveToCurrent();
|
||||
if (playback_state == EngineBase::State::Paused) {
|
||||
SharedPtr<QMetaObject::Connection> connection = make_shared<QMetaObject::Connection>();
|
||||
*connection = QObject::connect(&*app_->player(), &Player::Playing, &*app_->player(), [this, connection]() {
|
||||
QObject::disconnect(*connection);
|
||||
QTimer::singleShot(300, &*app_->player(), &Player::PlayPauseHelper);
|
||||
});
|
||||
if (playback_state == EngineBase::State::Playing) {
|
||||
app_->player()->Play(playback_position * kNsecPerSec);
|
||||
}
|
||||
else if (playback_state == EngineBase::State::Paused) {
|
||||
app_->player()->PlayWithPause(playback_position * kNsecPerSec);
|
||||
}
|
||||
app_->player()->Play(playback_position * kNsecPerSec);
|
||||
}
|
||||
|
||||
// Reset saved playback status so we don't resume again from the same position.
|
||||
@@ -1620,7 +1631,7 @@ void MainWindow::PlayIndex(const QModelIndex &idx, Playlist::AutoScroll autoscro
|
||||
}
|
||||
|
||||
app_->playlist_manager()->SetActiveToCurrent();
|
||||
app_->player()->PlayAt(row, 0, EngineBase::TrackChangeType::Manual, autoscroll, true);
|
||||
app_->player()->PlayAt(row, false, 0, EngineBase::TrackChangeType::Manual, autoscroll, true);
|
||||
|
||||
}
|
||||
|
||||
@@ -1637,14 +1648,14 @@ void MainWindow::PlaylistDoubleClick(const QModelIndex &idx) {
|
||||
switch (doubleclick_playlist_addmode_) {
|
||||
case BehaviourSettingsPage::PlaylistAddBehaviour::Play:
|
||||
app_->playlist_manager()->SetActiveToCurrent();
|
||||
app_->player()->PlayAt(source_idx.row(), 0, EngineBase::TrackChangeType::Manual, Playlist::AutoScroll::Never, true, true);
|
||||
app_->player()->PlayAt(source_idx.row(), false, 0, EngineBase::TrackChangeType::Manual, Playlist::AutoScroll::Never, true, true);
|
||||
break;
|
||||
|
||||
case BehaviourSettingsPage::PlaylistAddBehaviour::Enqueue:
|
||||
app_->playlist_manager()->current()->queue()->ToggleTracks(QModelIndexList() << source_idx);
|
||||
if (app_->player()->GetState() != EngineBase::State::Playing) {
|
||||
app_->playlist_manager()->SetActiveToCurrent();
|
||||
app_->player()->PlayAt(app_->playlist_manager()->current()->queue()->TakeNext(), 0, EngineBase::TrackChangeType::Manual, Playlist::AutoScroll::Never, true);
|
||||
app_->player()->PlayAt(app_->playlist_manager()->current()->queue()->TakeNext(), false, 0, EngineBase::TrackChangeType::Manual, Playlist::AutoScroll::Never, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2585,7 +2596,7 @@ void MainWindow::CommandlineOptionsReceived(const CommandlineOptions &options) {
|
||||
app_->player()->SeekTo(app_->player()->engine()->position_nanosec() / kNsecPerSec + options.seek_by());
|
||||
}
|
||||
|
||||
if (options.play_track_at() != -1) app_->player()->PlayAt(options.play_track_at(), 0, EngineBase::TrackChangeType::Manual, Playlist::AutoScroll::Maybe, true);
|
||||
if (options.play_track_at() != -1) app_->player()->PlayAt(options.play_track_at(), false, 0, EngineBase::TrackChangeType::Manual, Playlist::AutoScroll::Maybe, true);
|
||||
|
||||
if (options.show_osd()) app_->player()->ShowOSD();
|
||||
|
||||
|
||||
@@ -354,7 +354,7 @@ void Player::HandleLoadResult(const UrlHandler::LoadResult &result) {
|
||||
|
||||
if (is_current) {
|
||||
qLog(Debug) << "Playing song" << current_item->Metadata().title() << result.stream_url_ << "position" << play_offset_nanosec_;
|
||||
engine_->Play(result.media_url_, result.stream_url_, stream_change_type_, song.has_cue(), song.beginning_nanosec(), song.end_nanosec(), play_offset_nanosec_, song.ebur128_integrated_loudness_lufs());
|
||||
engine_->Play(result.media_url_, result.stream_url_, pause_, stream_change_type_, song.has_cue(), song.beginning_nanosec(), song.end_nanosec(), play_offset_nanosec_, song.ebur128_integrated_loudness_lufs());
|
||||
current_item_ = current_item;
|
||||
play_offset_nanosec_ = 0;
|
||||
}
|
||||
@@ -426,7 +426,7 @@ void Player::NextItem(const EngineBase::TrackChangeFlags change, const Playlist:
|
||||
return;
|
||||
}
|
||||
|
||||
PlayAt(i, 0, change, autoscroll, false, true);
|
||||
PlayAt(i, false, 0, change, autoscroll, false, true);
|
||||
|
||||
}
|
||||
|
||||
@@ -461,11 +461,10 @@ void Player::PlayPlaylistInternal(const EngineBase::TrackChangeFlags change, con
|
||||
if (i == -1) i = app_->playlist_manager()->active()->last_played_row();
|
||||
if (i == -1) i = 0;
|
||||
|
||||
PlayAt(i, 0, change, autoscroll, true);
|
||||
PlayAt(i, false, 0, change, autoscroll, true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Player::HandleStopAfter(const Playlist::AutoScroll autoscroll) {
|
||||
|
||||
if (app_->playlist_manager()->active()->stop_after_current()) {
|
||||
@@ -527,7 +526,7 @@ void Player::PlayPause(const quint64 offset_nanosec, const Playlist::AutoScroll
|
||||
int i = app_->playlist_manager()->active()->current_row();
|
||||
if (i == -1) i = app_->playlist_manager()->active()->last_played_row();
|
||||
if (i == -1) i = 0;
|
||||
PlayAt(i, offset_nanosec, EngineBase::TrackChangeType::First, autoscroll, true);
|
||||
PlayAt(i, false, offset_nanosec, EngineBase::TrackChangeType::First, autoscroll, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -606,7 +605,7 @@ void Player::PreviousItem(const EngineBase::TrackChangeFlags change) {
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
if (last_pressed_previous_.isValid() && last_pressed_previous_.secsTo(now) >= 2) {
|
||||
last_pressed_previous_ = now;
|
||||
PlayAt(app_->playlist_manager()->active()->current_row(), 0, change, Playlist::AutoScroll::Always, false, true);
|
||||
PlayAt(app_->playlist_manager()->active()->current_row(), false, 0, change, Playlist::AutoScroll::Always, false, true);
|
||||
return;
|
||||
}
|
||||
last_pressed_previous_ = now;
|
||||
@@ -616,11 +615,11 @@ void Player::PreviousItem(const EngineBase::TrackChangeFlags change) {
|
||||
app_->playlist_manager()->active()->set_current_row(i, Playlist::AutoScroll::Always, false);
|
||||
if (i == -1) {
|
||||
Stop();
|
||||
PlayAt(i, 0, change, Playlist::AutoScroll::Always, true);
|
||||
PlayAt(i, false, 0, change, Playlist::AutoScroll::Always, true);
|
||||
return;
|
||||
}
|
||||
|
||||
PlayAt(i, 0, change, Playlist::AutoScroll::Always, false);
|
||||
PlayAt(i, false, 0, change, Playlist::AutoScroll::Always, false);
|
||||
|
||||
}
|
||||
|
||||
@@ -718,9 +717,9 @@ void Player::VolumeDown() {
|
||||
|
||||
}
|
||||
|
||||
void Player::PlayAt(const int index, const quint64 offset_nanosec, EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle, const bool force_inform) {
|
||||
void Player::PlayAt(const int index, const bool pause, const quint64 offset_nanosec, EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle, const bool force_inform) {
|
||||
|
||||
pause_time_ = QDateTime();
|
||||
pause_time_ = pause ? QDateTime::currentDateTime() : QDateTime();
|
||||
play_offset_nanosec_ = offset_nanosec;
|
||||
|
||||
if (current_item_ && change & EngineBase::TrackChangeType::Manual && engine_->position_nanosec() != engine_->length_nanosec()) {
|
||||
@@ -748,13 +747,14 @@ void Player::PlayAt(const int index, const quint64 offset_nanosec, EngineBase::T
|
||||
return;
|
||||
}
|
||||
|
||||
pause_ = pause;
|
||||
stream_change_type_ = change;
|
||||
autoscroll_ = autoscroll;
|
||||
HandleLoadResult(url_handlers_[url.scheme()]->StartLoading(url));
|
||||
}
|
||||
else {
|
||||
qLog(Debug) << "Playing song" << current_item_->Metadata().title() << url << "position" << offset_nanosec;
|
||||
engine_->Play(current_item_->Url(), url, change, current_item_->Metadata().has_cue(), current_item_->effective_beginning_nanosec(), current_item_->effective_end_nanosec(), offset_nanosec, current_item_->effective_ebur128_integrated_loudness_lufs());
|
||||
engine_->Play(current_item_->Url(), url, pause, change, current_item_->Metadata().has_cue(), current_item_->effective_beginning_nanosec(), current_item_->effective_end_nanosec(), offset_nanosec, current_item_->effective_ebur128_integrated_loudness_lufs());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -866,6 +866,19 @@ void Player::Play(const quint64 offset_nanosec) {
|
||||
|
||||
}
|
||||
|
||||
void Player::PlayWithPause(const quint64 offset_nanosec) {
|
||||
|
||||
pause_time_ = QDateTime();
|
||||
play_offset_nanosec_ = offset_nanosec;
|
||||
app_->playlist_manager()->SetActivePlaylist(app_->playlist_manager()->current_id());
|
||||
if (app_->playlist_manager()->active()->rowCount() == 0) return;
|
||||
int i = app_->playlist_manager()->active()->current_row();
|
||||
if (i == -1) i = app_->playlist_manager()->active()->last_played_row();
|
||||
if (i == -1) i = 0;
|
||||
PlayAt(i, true, offset_nanosec, EngineBase::TrackChangeType::First, Playlist::AutoScroll::Always, true);
|
||||
|
||||
}
|
||||
|
||||
void Player::ShowOSD() {
|
||||
if (current_item_) emit ForceShowOSD(current_item_->Metadata(), false);
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ class PlayerInterface : public QObject {
|
||||
virtual void SaveVolume() = 0;
|
||||
|
||||
// Manual track change to the specified track
|
||||
virtual void PlayAt(const int index, const quint64 offset_nanosec, EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle, const bool force_inform = false) = 0;
|
||||
virtual void PlayAt(const int index, const bool pause, const quint64 offset_nanosec, EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle, const bool force_inform = false) = 0;
|
||||
|
||||
// If there's currently a song playing, pause it, otherwise play the track that was playing last, or the first one on the playlist
|
||||
virtual void PlayPause(const quint64 offset_nanosec = 0, const Playlist::AutoScroll autoscroll = Playlist::AutoScroll::Always) = 0;
|
||||
@@ -98,6 +98,7 @@ class PlayerInterface : public QObject {
|
||||
virtual void Pause() = 0;
|
||||
virtual void Stop(const bool stop_after = false) = 0;
|
||||
virtual void Play(const quint64 offset_nanosec = 0) = 0;
|
||||
virtual void PlayWithPause(const quint64 offset_nanosec) = 0;
|
||||
virtual void PlayHelper() = 0;
|
||||
virtual void ShowOSD() = 0;
|
||||
|
||||
@@ -159,7 +160,7 @@ class Player : public PlayerInterface {
|
||||
void LoadVolume() override;
|
||||
void SaveVolume() override;
|
||||
|
||||
void PlayAt(const int index, const quint64 offset_nanosec, EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle, const bool force_inform = false) override;
|
||||
void PlayAt(const int index, const bool pause, const quint64 offset_nanosec, EngineBase::TrackChangeFlags change, const Playlist::AutoScroll autoscroll, const bool reshuffle, const bool force_inform = false) override;
|
||||
void PlayPause(const quint64 offset_nanosec = 0, const Playlist::AutoScroll autoscroll = Playlist::AutoScroll::Always) override;
|
||||
void PlayPauseHelper() override { PlayPause(play_offset_nanosec_); }
|
||||
void RestartOrPrevious() override;
|
||||
@@ -182,6 +183,7 @@ class Player : public PlayerInterface {
|
||||
void Stop(const bool stop_after = false) override;
|
||||
void StopAfterCurrent();
|
||||
void Play(const quint64 offset_nanosec = 0) override;
|
||||
void PlayWithPause(const quint64 offset_nanosec) override;
|
||||
void PlayHelper() override { Play(); }
|
||||
void ShowOSD() override;
|
||||
void TogglePrettyOSD();
|
||||
@@ -228,6 +230,7 @@ class Player : public PlayerInterface {
|
||||
|
||||
PlaylistItemPtr current_item_;
|
||||
|
||||
bool pause_;
|
||||
EngineBase::TrackChangeFlags stream_change_type_;
|
||||
Playlist::AutoScroll autoscroll_;
|
||||
EngineBase::State last_state_;
|
||||
|
||||
Reference in New Issue
Block a user