kingslay / KSPlayer

A video player for iOS、macOS、tvOS、visionOS , based on AVPlayer and FFmpeg, support the horizontal, vertical screen. support adjust volume, brightness and seek by slide, SwiftUI, support subtitles.
https://apps.apple.com/app/tracyplayer/id6450770064
GNU General Public License v3.0
953 stars 193 forks source link

TV stays in HDR when i quit the player #446

Closed loicleser closed 1 year ago

loicleser commented 1 year ago

Hello, When I stop the player (from a HDR or dolby vision vidéo) my TV stay in HDR. Any idea how I can fix that?

Thanks

kingslay commented 1 year ago

用demo会有这个问题

loicleser commented 1 year ago

What do you mean? I don't understand ^^

kingslay commented 1 year ago

用demo会有这个问题吗?TracyPlayer

loicleser commented 1 year ago

No. When I test your demo I don't have the same problem.

kingslay commented 1 year ago

那可能就是你的代码有问题。没有对资源进行释放。

loicleser commented 1 year ago

I'm trying to do things differently. How do you detect if video is in SDR, HDR10 or dolbyVision?

Alanko5 commented 1 year ago

You need call reset player. Then displayCriteria reset to default. Or if deinit is called, DisplayCriteria is also set to default.

    public func resetPlayer() {
        KSLog("resetPlayer")
        state = .prepareToPlay
        bufferedCount = 0
        shouldSeekTo = 0
        player.playbackRate = 1
        player.playbackVolume = 1
        UIApplication.shared.isIdleTimerDisabled = false
        MPNowPlayingInfoCenter.default().nowPlayingInfo = nil
        #if os(tvOS)
        UIApplication.shared.windows.first?.avDisplayManager.preferredDisplayCriteria = nil
        #endif
    }
Alanko5 commented 1 year ago

I'm trying to do things differently. How do you detect if video is in SDR, HDR10 or dolbyVision?

https://github.com/kingslay/KSPlayer/blob/ee5dd0eda433c87acd61d7ff12b568a98ad9e136/Sources/KSPlayer/AVPlayer/PlayerDefines.swift#L135

public extension MediaPlayerTrack {
    var codecType: FourCharCode {
        mediaSubType.rawValue
    }

    func dynamicRange(_ options: KSOptions) -> DynamicRange {
        let cotentRange: DynamicRange
        if dovi != nil || codecType.string == "dvhe" || codecType == kCMVideoCodecType_DolbyVisionHEVC {
            cotentRange = .dolbyVision
        } else if transferFunction == kCVImageBufferTransferFunction_SMPTE_ST_2084_PQ as String { /// HDR
            cotentRange = .hdr10
        } else if transferFunction == kCVImageBufferTransferFunction_ITU_R_2100_HLG as String { /// HDR
            cotentRange = .hlg
        } else {
            cotentRange = .sdr
        }

        return options.availableDynamicRange(cotentRange) ?? cotentRange
    }

    var colorSpace: CGColorSpace? {
        KSOptions.colorSpace(ycbcrMatrix: yCbCrMatrix as CFString?, transferFunction: transferFunction as CFString?)
    }
}

/// Check supported modes for your TV
func availableDynamicRange(_ cotentRange: DynamicRange?) -> DynamicRange? {
        #if canImport(UIKit)
        let availableHDRModes = AVPlayer.availableHDRModes
        if let preferedDynamicRange = destinationDynamicRange {
            // value of 0 indicates that no HDR modes are supported.
            if availableHDRModes == AVPlayer.HDRMode(rawValue: 0) {
                return .sdr
            } else if availableHDRModes.contains(preferedDynamicRange.hdrMode) {
                return preferedDynamicRange
            } else if let cotentRange,
                      availableHDRModes.contains(cotentRange.hdrMode)
            {
                return cotentRange
            } else if preferedDynamicRange != .sdr { // trying update to HDR mode
                return availableHDRModes.dynamicRange
            }
        }
        #endif
        return cotentRange
}
loicleser commented 1 year ago

You need call reset player. Then displayCriteria reset to default. Or if deinit is called, DisplayCriteria is also set to default.

    public func resetPlayer() {
        KSLog("resetPlayer")
        state = .prepareToPlay
        bufferedCount = 0
        shouldSeekTo = 0
        player.playbackRate = 1
        player.playbackVolume = 1
        UIApplication.shared.isIdleTimerDisabled = false
        MPNowPlayingInfoCenter.default().nowPlayingInfo = nil
        #if os(tvOS)
        UIApplication.shared.windows.first?.avDisplayManager.preferredDisplayCriteria = nil
        #endif
    }

Yes I found it 5 minute ago. I was using the reset function of the playerView and this one is the reset function of the playerLayer.

Thanks