mirror of
https://github.com/yattee/yattee.git
synced 2026-07-22 07:12:02 +00:00
Fix macOS permanent black video after player collapse/expand cycles
In separate-window mode, hide() keeps the ordered-out window's SwiftUI hierarchy alive (nilling contentViewController crashes AVKit), and its updateNSView unconditionally re-attached the shared MPVOGLView - stealing it into a window CoreAnimation never composites. The layer's silent skip-render fallback then consumed every frame flag, so video stayed black (climbing vo drops) until app restart. - Decline stealing the shared view from a visible container into a non-visible one; owner-initiated transfers bypass the guard - Only transfer to containers in visible windows or the window still tracked by ExpandedPlayerWindowManager; park the view otherwise and reclaim it when a container gains a window - Log skip-render frame consumption (rate-limited) and track render health counters (draws/skips/dropped draws) - Add a watchdog to the playback stats task that detects a stalled video output and re-attaches the view to a visible container - Don't mount player layouts during zero-size layout passes
This commit is contained in:
@@ -272,6 +272,26 @@ final class MPVOGLView: NSView {
|
||||
videoLayer?.resetFirstFrameTracking()
|
||||
}
|
||||
|
||||
/// Thread-safe snapshot of the layer's render-health counters.
|
||||
func renderHealthSnapshot() -> MPVRenderHealth? {
|
||||
videoLayer?.renderHealthSnapshot()
|
||||
}
|
||||
|
||||
/// Human-readable description of where this shared view is currently
|
||||
/// attached, for render-health diagnostics. Main thread only.
|
||||
var attachmentDescription: String {
|
||||
let superviewDesc: String
|
||||
if let container = superview as? MPVContainerNSView {
|
||||
superviewDesc = "container=\(container.shortID)"
|
||||
} else if let superview {
|
||||
superviewDesc = "superview=\(type(of: superview))"
|
||||
} else {
|
||||
superviewDesc = "superview=nil"
|
||||
}
|
||||
let windowDesc = window.map { "window=#\($0.windowNumber) visible=\($0.isVisible)" } ?? "window=nil"
|
||||
return "\(superviewDesc) \(windowDesc) bounds=\(Int(bounds.width))x\(Int(bounds.height))"
|
||||
}
|
||||
|
||||
/// Clear the view to black.
|
||||
func clearToBlack() {
|
||||
videoLayer?.clearToBlack()
|
||||
|
||||
Reference in New Issue
Block a user