Allow stopping audio without stopping video.

This commit is contained in:
John Preston 2019-12-18 21:26:17 +03:00
parent a2b6e05cdf
commit 40d4353d05
9 changed files with 68 additions and 18 deletions

View file

@ -394,6 +394,7 @@ void Instance::playStreamed(
data->streamed = std::make_unique<Streamed>(
audioId,
std::move(shared));
data->streamed->instance.lockPlayer();
data->streamed->instance.player().updates(
) | rpl::start_with_next_error([=](Streaming::Update &&update) {

View file

@ -171,6 +171,14 @@ void AudioTrack::resume(crl::time time) {
Media::Player::mixer()->resume(_audioId, true);
}
void AudioTrack::stop() {
Expects(initialized());
if (_audioId.externalPlayId()) {
Media::Player::mixer()->stop(_audioId);
}
}
void AudioTrack::setSpeed(float64 speed) {
_options.speed = speed;
Media::Player::mixer()->setSpeedFromExternal(_audioId, speed);
@ -228,9 +236,7 @@ rpl::producer<crl::time> AudioTrack::playPosition() {
}
AudioTrack::~AudioTrack() {
if (_audioId.externalPlayId()) {
Media::Player::mixer()->stop(_audioId);
}
stop();
}
} // namespace Streaming

View file

@ -28,6 +28,9 @@ public:
void pause(crl::time time);
void resume(crl::time time);
// Allow to irreversibly stop only audio track.
void stop();
// Called from the main thread.
void setSpeed(float64 speed);
[[nodiscard]] rpl::producer<> waitingForData() const;

View file

@ -41,6 +41,10 @@ Instance::~Instance() {
}
}
bool Instance::valid() const {
return (_shared != nullptr);
}
const Player &Instance::player() const {
Expects(_shared != nullptr);
@ -77,6 +81,12 @@ void Instance::stop() {
_shared->player().stop();
}
void Instance::stopAudio() {
Expects(_shared != nullptr);
_shared->player().stopAudio();
}
void Instance::saveFrameToCover() {
Expects(_shared != nullptr);

View file

@ -36,6 +36,8 @@ public:
Fn<void()> waitingCallback);
~Instance();
[[nodiscard]] bool valid() const;
[[nodiscard]] const Player &player() const;
[[nodiscard]] const Information &info() const;
@ -43,6 +45,7 @@ public:
void pause();
void resume();
void stop();
void stopAudio();
void saveFrameToCover();
[[nodiscard]] bool active() const;

View file

@ -578,6 +578,15 @@ void Player::stop() {
stop(false);
}
void Player::stopAudio() {
if (!_video) {
stop();
} else if (_audio) {
_audioFinished = true;
_audio->stop();
}
}
void Player::updatePausedState() {
const auto paused = _pausedByUser || _pausedByWaitingForData;
if (_paused == paused) {
@ -666,7 +675,7 @@ void Player::start() {
_updates.fire({ WaitingForData{ true } });
}, _sessionLifetime);
if (guard && _audio) {
if (guard && _audio && !_audioFinished) {
_audio->playPosition(
) | rpl::start_with_next_done([=](crl::time position) {
audioPlayedTill(position);
@ -701,7 +710,13 @@ void Player::start() {
}, _sessionLifetime);
}
if (guard && _audio) {
trackSendReceivedTill(*_audio, _information.audio.state);
if (_audioFinished) {
if (!_video || _videoFinished) {
_updates.fire({ Finished() });
}
} else {
trackSendReceivedTill(*_audio, _information.audio.state);
}
}
if (guard && _video) {
trackSendReceivedTill(*_video, _information.video.state);

View file

@ -45,6 +45,9 @@ public:
void resume();
void stop();
// Allow to irreversibly stop only audio track.
void stopAudio();
[[nodiscard]] bool active() const;
[[nodiscard]] bool ready() const;

View file

@ -435,8 +435,7 @@ bool OverlayWidget::documentBubbleShown() const {
void OverlayWidget::clearStreaming() {
_fullScreenVideo = false;
if (_streamed) {
_streamed->instance.stop();
_streamed->instance.unlockPlayer();
_streamed->instance.stopAudio();
_streamed = nullptr;
}
}
@ -1860,8 +1859,7 @@ void OverlayWidget::displayDocument(
} else {
_doc->automaticLoad(fileOrigin(), item);
if (_doc->canBePlayed()) {
initStreaming();
if (_doc->canBePlayed() && initStreaming()) {
} else if (_doc->isVideoFile()) {
initStreamingThumbnail();
} else if (_doc->isTheme()) {
@ -1988,15 +1986,18 @@ void OverlayWidget::displayFinished() {
}
}
void OverlayWidget::initStreaming() {
bool OverlayWidget::initStreaming() {
Expects(_doc != nullptr);
Expects(_doc->canBePlayed());
if (_streamed) {
return;
return true;
}
initStreamingThumbnail();
createStreamingObjects();
if (!createStreamingObjects()) {
_doc->setInappPlaybackFailed();
return false;
}
Core::App().updateNonIdle();
@ -2008,6 +2009,7 @@ void OverlayWidget::initStreaming() {
}, _streamed->instance.lifetime());
startStreamingPlayer();
return true;
}
void OverlayWidget::startStreamingPlayer() {
@ -2071,13 +2073,17 @@ void OverlayWidget::streamingReady(Streaming::Information &&info) {
this->update(contentRect());
}
void OverlayWidget::createStreamingObjects() {
bool OverlayWidget::createStreamingObjects() {
_streamed = std::make_unique<Streamed>(
_doc,
fileOrigin(),
this,
static_cast<PlaybackControls::Delegate*>(this),
[=] { waitingAnimationCallback(); });
if (!_streamed->instance.valid()) {
_streamed = nullptr;
return false;
}
_streamed->instance.lockPlayer();
_streamed->withSound = _doc->isAudioFile()
|| _doc->isVideoFile()
@ -2090,6 +2096,7 @@ void OverlayWidget::createStreamingObjects() {
refreshClipControllerGeometry();
_streamed->controls.show();
}
return true;
}
QImage OverlayWidget::transformVideoFrame(QImage frame) const {
@ -2281,7 +2288,9 @@ void OverlayWidget::playbackPauseResume() {
_streamed->resumeOnCallEnd = false;
if (_streamed->instance.player().failed()) {
clearStreaming();
initStreaming();
if (!_doc->canBePlayed() || !initStreaming()) {
redisplayContent();
}
} else if (_streamed->instance.player().finished()) {
_streamingStartPaused = false;
restartAtSeekPosition(0);
@ -2516,7 +2525,7 @@ void OverlayWidget::paintEvent(QPaintEvent *e) {
}
float64 progress = (hidingDt >= 0) ? (hidingDt / st::mediaviewSaveMsgHiding) : (dt / st::mediaviewSaveMsgShowing);
_saveMsgOpacity.update(qMin(progress, 1.), anim::linear);
if (_saveMsgOpacity.current() > 0) {
if (_saveMsgOpacity.current() > 0) {
p.setOpacity(_saveMsgOpacity.current());
App::roundRect(p, _saveMsg, st::mediaviewSaveMsgBg, MediaviewSaveCorners);
st::mediaviewSaveMsgCheck.paint(p, _saveMsg.topLeft() + st::mediaviewSaveMsgCheckPos, width());
@ -2528,7 +2537,7 @@ void OverlayWidget::paintEvent(QPaintEvent *e) {
p.setOpacity(1);
}
if (!_blurred) {
auto nextFrame = (dt < st::mediaviewSaveMsgShowing || hidingDt >= 0) ? int(AnimationTimerDelta) : (st::mediaviewSaveMsgShowing + st::mediaviewSaveMsgShown + 1 - dt);
auto nextFrame = (dt < st::mediaviewSaveMsgShowing || hidingDt >= 0) ? int(AnimationTimerDelta) : (st::mediaviewSaveMsgShowing + st::mediaviewSaveMsgShown + 1 - dt);
_saveMsgUpdater.start(nextFrame);
}
} else {

View file

@ -258,11 +258,11 @@ private:
void refreshClipControllerGeometry();
void refreshCaptionGeometry();
void initStreaming();
[[nodiscard]] bool initStreaming();
void startStreamingPlayer();
void initStreamingThumbnail();
void streamingReady(Streaming::Information &&info);
void createStreamingObjects();
[[nodiscard]] bool createStreamingObjects();
void handleStreamingUpdate(Streaming::Update &&update);
void handleStreamingError(Streaming::Error &&error);