fix: reload audio output on Windows wake from sleep

This commit is contained in:
edde746
2026-04-02 14:36:50 +02:00
parent 504da89223
commit 91db6d0e57
3 changed files with 35 additions and 0 deletions
+17
View File
@@ -147,6 +147,11 @@ std::optional<HRESULT> MpvCore::WindowProc(HWND hwnd, UINT message,
::RedrawWindow(flutter_window_, nullptr, nullptr,
RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN);
}
} else if (wparam == kPowerResumeTimerId) {
::KillTimer(flutter_window_, kPowerResumeTimerId);
if (power_resume_cb_) {
power_resume_cb_();
}
}
break;
}
@@ -170,6 +175,14 @@ std::optional<HRESULT> MpvCore::WindowProc(HWND hwnd, UINT message,
}
break;
}
case WM_POWERBROADCAST: {
if (wparam == PBT_APMRESUMEAUTOMATIC && power_resume_cb_) {
// Delay audio reload to let WASAPI fully reinitialize after wake.
::KillTimer(flutter_window_, kPowerResumeTimerId);
::SetTimer(flutter_window_, kPowerResumeTimerId, kPowerResumeAudioDelay, nullptr);
}
break;
}
case WM_CLOSE: {
::SendMessage(container_, WM_CLOSE, 0, 0);
for (const auto& [mpv_view, rect] : mpv_views_) {
@@ -202,6 +215,10 @@ RECT MpvCore::GetGlobalRect(int32_t left, int32_t top, int32_t right,
return rect;
}
void MpvCore::SetPowerResumeCallback(PowerResumeCallback callback) {
power_resume_cb_ = std::move(callback);
}
std::unique_ptr<MpvCore> MpvCore::instance_ = nullptr;
} // namespace mpv
+8
View File
@@ -4,6 +4,7 @@
#include <Windows.h>
#include <cmath>
#include <functional>
#include <map>
#include <memory>
#include <optional>
@@ -15,7 +16,9 @@ namespace mpv {
class MpvCore {
public:
static constexpr auto kPositionAndShowDelay = 300;
static constexpr auto kPowerResumeAudioDelay = 500;
static constexpr UINT_PTR kCompositionRestoreTimerId = 1001;
static constexpr UINT_PTR kPowerResumeTimerId = 1002;
static MpvCore* GetInstance();
static void SetInstance(std::unique_ptr<MpvCore> instance);
@@ -42,6 +45,10 @@ class MpvCore {
std::optional<HRESULT> WindowProc(HWND hwnd, UINT message, WPARAM wparam,
LPARAM lparam);
// Callback invoked when Windows resumes from sleep/hibernate.
using PowerResumeCallback = std::function<void()>;
void SetPowerResumeCallback(PowerResumeCallback callback);
private:
RECT GetGlobalRect(int32_t left, int32_t top, int32_t right, int32_t bottom);
@@ -53,6 +60,7 @@ class MpvCore {
bool was_window_hidden_due_to_minimize_ = false;
bool visible_ = true;
bool composition_enabled_ = false;
PowerResumeCallback power_resume_cb_;
static std::unique_ptr<MpvCore> instance_;
};
+10
View File
@@ -121,6 +121,16 @@ void MpvPlayerPlugin::HandleMethodCall(
RECT rect = {0, 0, 100, 100};
MpvCore::GetInstance()->CreateMpvView(player_->GetHwnd(), rect, 1.0);
// Reload audio output on wake from sleep to recover stale WASAPI sessions.
MpvCore::GetInstance()->SetPowerResumeCallback([this]() {
if (player_ && player_->IsInitialized()) {
auto device = player_->GetProperty("audio-device");
if (!device.empty()) {
player_->SetProperty("audio-device", device);
}
}
});
// Start hidden.
MpvCore::GetInstance()->SetVisible(false);
result->Success(flutter::EncodableValue(true));