fix(windows): recover mpv audio output
This commit is contained in:
@@ -72,6 +72,7 @@ bool MpvPlayer::Initialize(HWND container, HWND flutter_window) {
|
|||||||
|
|
||||||
// Observe video-params/sig-peak for HDR detection
|
// Observe video-params/sig-peak for HDR detection
|
||||||
mpv_observe_property(mpv_, 0, "video-params/sig-peak", MPV_FORMAT_DOUBLE);
|
mpv_observe_property(mpv_, 0, "video-params/sig-peak", MPV_FORMAT_DOUBLE);
|
||||||
|
mpv_observe_property(mpv_, 0, "current-ao", MPV_FORMAT_STRING);
|
||||||
|
|
||||||
// Start event loop.
|
// Start event loop.
|
||||||
StartEventLoop();
|
StartEventLoop();
|
||||||
@@ -295,6 +296,12 @@ void MpvPlayer::SetEventCallback(EventCallback callback) {
|
|||||||
event_callback_ = std::move(callback);
|
event_callback_ = std::move(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MpvPlayer::ReloadAudioOutput() {
|
||||||
|
if (audio_reload_pending_) return;
|
||||||
|
audio_reload_pending_ = true;
|
||||||
|
CommandAsync({"ao-reload"}, [this](int) { audio_reload_pending_ = false; });
|
||||||
|
}
|
||||||
|
|
||||||
void MpvPlayer::StartEventLoop() {
|
void MpvPlayer::StartEventLoop() {
|
||||||
running_ = true;
|
running_ = true;
|
||||||
event_thread_ = std::thread(&MpvPlayer::EventLoop, this);
|
event_thread_ = std::thread(&MpvPlayer::EventLoop, this);
|
||||||
@@ -399,18 +406,18 @@ void MpvPlayer::HandleMpvEvent(mpv_event* event) {
|
|||||||
UpdateHDRMode(sigPeak);
|
UpdateHDRMode(sigPeak);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Audio recovery: when the device list changes and audio has fallen back
|
if (strcmp(prop->name, "current-ao") == 0) {
|
||||||
// to null output (e.g. after sleep/wake or device unplug), re-set
|
const char* current_ao = nullptr;
|
||||||
// audio-device to switch back to the real output.
|
if (prop->format == MPV_FORMAT_STRING && prop->data) {
|
||||||
|
current_ao = *static_cast<char**>(prop->data);
|
||||||
|
}
|
||||||
|
current_ao_is_null_ = current_ao && strcmp(current_ao, "null") == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Audio recovery for sleep/wake or unplugged devices.
|
||||||
// Mirrors mpv's TOOLS/lua/ao-null-reload.lua for embedded libmpv.
|
// Mirrors mpv's TOOLS/lua/ao-null-reload.lua for embedded libmpv.
|
||||||
if (strcmp(prop->name, "audio-device-list") == 0) {
|
if (strcmp(prop->name, "audio-device-list") == 0 && current_ao_is_null_) {
|
||||||
GetPropertyAsync("current-ao", [this](int ao_error, const std::string& current_ao) {
|
ReloadAudioOutput();
|
||||||
if (ao_error < 0 || current_ao != "null") return;
|
|
||||||
GetPropertyAsync("audio-device", [this](int device_error, const std::string& device) {
|
|
||||||
if (device_error < 0 || device.empty()) return;
|
|
||||||
SetProperty("audio-device", device);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SendPropertyChange(prop->name, &node);
|
SendPropertyChange(prop->name, &node);
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ class MpvPlayer {
|
|||||||
void HandleMpvEvent(mpv_event* event);
|
void HandleMpvEvent(mpv_event* event);
|
||||||
void SendPropertyChange(const char* name, mpv_node* data);
|
void SendPropertyChange(const char* name, mpv_node* data);
|
||||||
void SendEvent(const std::string& name, const flutter::EncodableMap& data = {});
|
void SendEvent(const std::string& name, const flutter::EncodableMap& data = {});
|
||||||
|
void ReloadAudioOutput();
|
||||||
uint64_t RegisterStatusRequest(StatusCallback callback);
|
uint64_t RegisterStatusRequest(StatusCallback callback);
|
||||||
StatusCallback TakeStatusRequest(uint64_t request_id);
|
StatusCallback TakeStatusRequest(uint64_t request_id);
|
||||||
uint64_t RegisterGetPropertyRequest(GetPropertyCallback callback);
|
uint64_t RegisterGetPropertyRequest(GetPropertyCallback callback);
|
||||||
@@ -95,6 +96,8 @@ class MpvPlayer {
|
|||||||
std::atomic<bool> running_{false};
|
std::atomic<bool> running_{false};
|
||||||
EventCallback event_callback_;
|
EventCallback event_callback_;
|
||||||
std::mutex callback_mutex_;
|
std::mutex callback_mutex_;
|
||||||
|
bool current_ao_is_null_ = false;
|
||||||
|
bool audio_reload_pending_ = false;
|
||||||
|
|
||||||
uint64_t next_reply_userdata_ = 1;
|
uint64_t next_reply_userdata_ = 1;
|
||||||
std::map<std::string, uint64_t> observed_properties_;
|
std::map<std::string, uint64_t> observed_properties_;
|
||||||
|
|||||||
Reference in New Issue
Block a user