mirror of https://github.com/procxx/kepka.git
Allow stopping audio without stopping video.
This commit is contained in:
parent
a2b6e05cdf
commit
40d4353d05
|
@ -394,6 +394,7 @@ void Instance::playStreamed(
|
||||||
data->streamed = std::make_unique<Streamed>(
|
data->streamed = std::make_unique<Streamed>(
|
||||||
audioId,
|
audioId,
|
||||||
std::move(shared));
|
std::move(shared));
|
||||||
|
data->streamed->instance.lockPlayer();
|
||||||
|
|
||||||
data->streamed->instance.player().updates(
|
data->streamed->instance.player().updates(
|
||||||
) | rpl::start_with_next_error([=](Streaming::Update &&update) {
|
) | rpl::start_with_next_error([=](Streaming::Update &&update) {
|
||||||
|
|
|
@ -171,6 +171,14 @@ void AudioTrack::resume(crl::time time) {
|
||||||
Media::Player::mixer()->resume(_audioId, true);
|
Media::Player::mixer()->resume(_audioId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioTrack::stop() {
|
||||||
|
Expects(initialized());
|
||||||
|
|
||||||
|
if (_audioId.externalPlayId()) {
|
||||||
|
Media::Player::mixer()->stop(_audioId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AudioTrack::setSpeed(float64 speed) {
|
void AudioTrack::setSpeed(float64 speed) {
|
||||||
_options.speed = speed;
|
_options.speed = speed;
|
||||||
Media::Player::mixer()->setSpeedFromExternal(_audioId, speed);
|
Media::Player::mixer()->setSpeedFromExternal(_audioId, speed);
|
||||||
|
@ -228,9 +236,7 @@ rpl::producer<crl::time> AudioTrack::playPosition() {
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioTrack::~AudioTrack() {
|
AudioTrack::~AudioTrack() {
|
||||||
if (_audioId.externalPlayId()) {
|
stop();
|
||||||
Media::Player::mixer()->stop(_audioId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Streaming
|
} // namespace Streaming
|
||||||
|
|
|
@ -28,6 +28,9 @@ public:
|
||||||
void pause(crl::time time);
|
void pause(crl::time time);
|
||||||
void resume(crl::time time);
|
void resume(crl::time time);
|
||||||
|
|
||||||
|
// Allow to irreversibly stop only audio track.
|
||||||
|
void stop();
|
||||||
|
|
||||||
// Called from the main thread.
|
// Called from the main thread.
|
||||||
void setSpeed(float64 speed);
|
void setSpeed(float64 speed);
|
||||||
[[nodiscard]] rpl::producer<> waitingForData() const;
|
[[nodiscard]] rpl::producer<> waitingForData() const;
|
||||||
|
|
|
@ -41,6 +41,10 @@ Instance::~Instance() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Instance::valid() const {
|
||||||
|
return (_shared != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
const Player &Instance::player() const {
|
const Player &Instance::player() const {
|
||||||
Expects(_shared != nullptr);
|
Expects(_shared != nullptr);
|
||||||
|
|
||||||
|
@ -77,6 +81,12 @@ void Instance::stop() {
|
||||||
_shared->player().stop();
|
_shared->player().stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Instance::stopAudio() {
|
||||||
|
Expects(_shared != nullptr);
|
||||||
|
|
||||||
|
_shared->player().stopAudio();
|
||||||
|
}
|
||||||
|
|
||||||
void Instance::saveFrameToCover() {
|
void Instance::saveFrameToCover() {
|
||||||
Expects(_shared != nullptr);
|
Expects(_shared != nullptr);
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,8 @@ public:
|
||||||
Fn<void()> waitingCallback);
|
Fn<void()> waitingCallback);
|
||||||
~Instance();
|
~Instance();
|
||||||
|
|
||||||
|
[[nodiscard]] bool valid() const;
|
||||||
|
|
||||||
[[nodiscard]] const Player &player() const;
|
[[nodiscard]] const Player &player() const;
|
||||||
[[nodiscard]] const Information &info() const;
|
[[nodiscard]] const Information &info() const;
|
||||||
|
|
||||||
|
@ -43,6 +45,7 @@ public:
|
||||||
void pause();
|
void pause();
|
||||||
void resume();
|
void resume();
|
||||||
void stop();
|
void stop();
|
||||||
|
void stopAudio();
|
||||||
void saveFrameToCover();
|
void saveFrameToCover();
|
||||||
|
|
||||||
[[nodiscard]] bool active() const;
|
[[nodiscard]] bool active() const;
|
||||||
|
|
|
@ -578,6 +578,15 @@ void Player::stop() {
|
||||||
stop(false);
|
stop(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::stopAudio() {
|
||||||
|
if (!_video) {
|
||||||
|
stop();
|
||||||
|
} else if (_audio) {
|
||||||
|
_audioFinished = true;
|
||||||
|
_audio->stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Player::updatePausedState() {
|
void Player::updatePausedState() {
|
||||||
const auto paused = _pausedByUser || _pausedByWaitingForData;
|
const auto paused = _pausedByUser || _pausedByWaitingForData;
|
||||||
if (_paused == paused) {
|
if (_paused == paused) {
|
||||||
|
@ -666,7 +675,7 @@ void Player::start() {
|
||||||
_updates.fire({ WaitingForData{ true } });
|
_updates.fire({ WaitingForData{ true } });
|
||||||
}, _sessionLifetime);
|
}, _sessionLifetime);
|
||||||
|
|
||||||
if (guard && _audio) {
|
if (guard && _audio && !_audioFinished) {
|
||||||
_audio->playPosition(
|
_audio->playPosition(
|
||||||
) | rpl::start_with_next_done([=](crl::time position) {
|
) | rpl::start_with_next_done([=](crl::time position) {
|
||||||
audioPlayedTill(position);
|
audioPlayedTill(position);
|
||||||
|
@ -701,7 +710,13 @@ void Player::start() {
|
||||||
}, _sessionLifetime);
|
}, _sessionLifetime);
|
||||||
}
|
}
|
||||||
if (guard && _audio) {
|
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) {
|
if (guard && _video) {
|
||||||
trackSendReceivedTill(*_video, _information.video.state);
|
trackSendReceivedTill(*_video, _information.video.state);
|
||||||
|
|
|
@ -45,6 +45,9 @@ public:
|
||||||
void resume();
|
void resume();
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
|
// Allow to irreversibly stop only audio track.
|
||||||
|
void stopAudio();
|
||||||
|
|
||||||
[[nodiscard]] bool active() const;
|
[[nodiscard]] bool active() const;
|
||||||
[[nodiscard]] bool ready() const;
|
[[nodiscard]] bool ready() const;
|
||||||
|
|
||||||
|
|
|
@ -435,8 +435,7 @@ bool OverlayWidget::documentBubbleShown() const {
|
||||||
void OverlayWidget::clearStreaming() {
|
void OverlayWidget::clearStreaming() {
|
||||||
_fullScreenVideo = false;
|
_fullScreenVideo = false;
|
||||||
if (_streamed) {
|
if (_streamed) {
|
||||||
_streamed->instance.stop();
|
_streamed->instance.stopAudio();
|
||||||
_streamed->instance.unlockPlayer();
|
|
||||||
_streamed = nullptr;
|
_streamed = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1860,8 +1859,7 @@ void OverlayWidget::displayDocument(
|
||||||
} else {
|
} else {
|
||||||
_doc->automaticLoad(fileOrigin(), item);
|
_doc->automaticLoad(fileOrigin(), item);
|
||||||
|
|
||||||
if (_doc->canBePlayed()) {
|
if (_doc->canBePlayed() && initStreaming()) {
|
||||||
initStreaming();
|
|
||||||
} else if (_doc->isVideoFile()) {
|
} else if (_doc->isVideoFile()) {
|
||||||
initStreamingThumbnail();
|
initStreamingThumbnail();
|
||||||
} else if (_doc->isTheme()) {
|
} else if (_doc->isTheme()) {
|
||||||
|
@ -1988,15 +1986,18 @@ void OverlayWidget::displayFinished() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverlayWidget::initStreaming() {
|
bool OverlayWidget::initStreaming() {
|
||||||
Expects(_doc != nullptr);
|
Expects(_doc != nullptr);
|
||||||
Expects(_doc->canBePlayed());
|
Expects(_doc->canBePlayed());
|
||||||
|
|
||||||
if (_streamed) {
|
if (_streamed) {
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
initStreamingThumbnail();
|
initStreamingThumbnail();
|
||||||
createStreamingObjects();
|
if (!createStreamingObjects()) {
|
||||||
|
_doc->setInappPlaybackFailed();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Core::App().updateNonIdle();
|
Core::App().updateNonIdle();
|
||||||
|
|
||||||
|
@ -2008,6 +2009,7 @@ void OverlayWidget::initStreaming() {
|
||||||
}, _streamed->instance.lifetime());
|
}, _streamed->instance.lifetime());
|
||||||
|
|
||||||
startStreamingPlayer();
|
startStreamingPlayer();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverlayWidget::startStreamingPlayer() {
|
void OverlayWidget::startStreamingPlayer() {
|
||||||
|
@ -2071,13 +2073,17 @@ void OverlayWidget::streamingReady(Streaming::Information &&info) {
|
||||||
this->update(contentRect());
|
this->update(contentRect());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverlayWidget::createStreamingObjects() {
|
bool OverlayWidget::createStreamingObjects() {
|
||||||
_streamed = std::make_unique<Streamed>(
|
_streamed = std::make_unique<Streamed>(
|
||||||
_doc,
|
_doc,
|
||||||
fileOrigin(),
|
fileOrigin(),
|
||||||
this,
|
this,
|
||||||
static_cast<PlaybackControls::Delegate*>(this),
|
static_cast<PlaybackControls::Delegate*>(this),
|
||||||
[=] { waitingAnimationCallback(); });
|
[=] { waitingAnimationCallback(); });
|
||||||
|
if (!_streamed->instance.valid()) {
|
||||||
|
_streamed = nullptr;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
_streamed->instance.lockPlayer();
|
_streamed->instance.lockPlayer();
|
||||||
_streamed->withSound = _doc->isAudioFile()
|
_streamed->withSound = _doc->isAudioFile()
|
||||||
|| _doc->isVideoFile()
|
|| _doc->isVideoFile()
|
||||||
|
@ -2090,6 +2096,7 @@ void OverlayWidget::createStreamingObjects() {
|
||||||
refreshClipControllerGeometry();
|
refreshClipControllerGeometry();
|
||||||
_streamed->controls.show();
|
_streamed->controls.show();
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage OverlayWidget::transformVideoFrame(QImage frame) const {
|
QImage OverlayWidget::transformVideoFrame(QImage frame) const {
|
||||||
|
@ -2281,7 +2288,9 @@ void OverlayWidget::playbackPauseResume() {
|
||||||
_streamed->resumeOnCallEnd = false;
|
_streamed->resumeOnCallEnd = false;
|
||||||
if (_streamed->instance.player().failed()) {
|
if (_streamed->instance.player().failed()) {
|
||||||
clearStreaming();
|
clearStreaming();
|
||||||
initStreaming();
|
if (!_doc->canBePlayed() || !initStreaming()) {
|
||||||
|
redisplayContent();
|
||||||
|
}
|
||||||
} else if (_streamed->instance.player().finished()) {
|
} else if (_streamed->instance.player().finished()) {
|
||||||
_streamingStartPaused = false;
|
_streamingStartPaused = false;
|
||||||
restartAtSeekPosition(0);
|
restartAtSeekPosition(0);
|
||||||
|
@ -2516,7 +2525,7 @@ void OverlayWidget::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
float64 progress = (hidingDt >= 0) ? (hidingDt / st::mediaviewSaveMsgHiding) : (dt / st::mediaviewSaveMsgShowing);
|
float64 progress = (hidingDt >= 0) ? (hidingDt / st::mediaviewSaveMsgHiding) : (dt / st::mediaviewSaveMsgShowing);
|
||||||
_saveMsgOpacity.update(qMin(progress, 1.), anim::linear);
|
_saveMsgOpacity.update(qMin(progress, 1.), anim::linear);
|
||||||
if (_saveMsgOpacity.current() > 0) {
|
if (_saveMsgOpacity.current() > 0) {
|
||||||
p.setOpacity(_saveMsgOpacity.current());
|
p.setOpacity(_saveMsgOpacity.current());
|
||||||
App::roundRect(p, _saveMsg, st::mediaviewSaveMsgBg, MediaviewSaveCorners);
|
App::roundRect(p, _saveMsg, st::mediaviewSaveMsgBg, MediaviewSaveCorners);
|
||||||
st::mediaviewSaveMsgCheck.paint(p, _saveMsg.topLeft() + st::mediaviewSaveMsgCheckPos, width());
|
st::mediaviewSaveMsgCheck.paint(p, _saveMsg.topLeft() + st::mediaviewSaveMsgCheckPos, width());
|
||||||
|
@ -2528,7 +2537,7 @@ void OverlayWidget::paintEvent(QPaintEvent *e) {
|
||||||
p.setOpacity(1);
|
p.setOpacity(1);
|
||||||
}
|
}
|
||||||
if (!_blurred) {
|
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);
|
_saveMsgUpdater.start(nextFrame);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -258,11 +258,11 @@ private:
|
||||||
void refreshClipControllerGeometry();
|
void refreshClipControllerGeometry();
|
||||||
void refreshCaptionGeometry();
|
void refreshCaptionGeometry();
|
||||||
|
|
||||||
void initStreaming();
|
[[nodiscard]] bool initStreaming();
|
||||||
void startStreamingPlayer();
|
void startStreamingPlayer();
|
||||||
void initStreamingThumbnail();
|
void initStreamingThumbnail();
|
||||||
void streamingReady(Streaming::Information &&info);
|
void streamingReady(Streaming::Information &&info);
|
||||||
void createStreamingObjects();
|
[[nodiscard]] bool createStreamingObjects();
|
||||||
void handleStreamingUpdate(Streaming::Update &&update);
|
void handleStreamingUpdate(Streaming::Update &&update);
|
||||||
void handleStreamingError(Streaming::Error &&error);
|
void handleStreamingError(Streaming::Error &&error);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue