diff --git a/BilibiliLive/Component/Player/Plugins/SpeedChangerPlugin.swift b/BilibiliLive/Component/Player/Plugins/SpeedChangerPlugin.swift index 6ba63b6..732a6c1 100644 --- a/BilibiliLive/Component/Player/Plugins/SpeedChangerPlugin.swift +++ b/BilibiliLive/Component/Player/Plugins/SpeedChangerPlugin.swift @@ -8,13 +8,29 @@ import AVKit class SpeedChangerPlugin: NSObject, CommonPlayerPlugin { + private var notifyView: UILabel? + private weak var containerView: UIView? private weak var player: AVPlayer? private weak var playerVC: AVPlayerViewController? @Published private(set) var currentPlaySpeed: PlaySpeed = .default + func addViewToPlayerOverlay(container: UIView) { + containerView = container + } + + private func fadeOutNotifyView() { + UIView.animate(withDuration: 1.0, animations: { + self.notifyView?.alpha = 0.0 // Fade out to invisible + }) { _ in + self.notifyView?.removeFromSuperview() // Optionally remove from superview after fading out + } + } + func playerDidLoad(playerVC: AVPlayerViewController) { self.playerVC = playerVC + + currentPlaySpeed = Settings.mediaPlayerSpeed } func playerDidChange(player: AVPlayer) { @@ -25,6 +41,32 @@ class SpeedChangerPlugin: NSObject, CommonPlayerPlugin { playerVC?.selectSpeed(AVPlaybackSpeed(rate: currentPlaySpeed.value, localizedName: currentPlaySpeed.name)) } + func playerDidStart(player: AVPlayer) { + if notifyView == nil { + notifyView = UILabel() + notifyView?.backgroundColor = UIColor.black.withAlphaComponent(0.3) + notifyView?.textColor = UIColor.white + containerView?.addSubview(notifyView!) + notifyView?.numberOfLines = 0 + notifyView?.layer.cornerRadius = 10 // Set the corner radius + notifyView?.layer.masksToBounds = true // Enable masks to bounds + notifyView?.font = UIFont.systemFont(ofSize: 26) + notifyView?.textAlignment = NSTextAlignment.center + notifyView?.snp.makeConstraints { make in + // make.bottom.equalToSuperview().inset(20) // 20 points from the bottom + make.center.equalToSuperview() // Center horizontally + make.width.equalTo(300) // Set a width (optional) + make.height.equalTo(60) // Set a height (optional) + } + } + notifyView?.isHidden = false + notifyView?.text = "播放速度设置为 \(currentPlaySpeed.name)" + + DispatchQueue.main.asyncAfter(deadline: .now() + 2) { + self.fadeOutNotifyView() + } + } + func addMenuItems(current: inout [UIMenuElement]) -> [UIMenuElement] { let gearImage = UIImage(systemName: "gearshape") @@ -43,7 +85,7 @@ class SpeedChangerPlugin: NSObject, CommonPlayerPlugin { } } -struct PlaySpeed { +struct PlaySpeed: Codable { var name: String var value: Float } diff --git a/BilibiliLive/Component/Settings.swift b/BilibiliLive/Component/Settings.swift index ce473fc..cccdd6b 100644 --- a/BilibiliLive/Component/Settings.swift +++ b/BilibiliLive/Component/Settings.swift @@ -36,6 +36,9 @@ enum Settings { @UserDefaultCodable("Settings.mediaQuality", defaultValue: .quality_1080p) static var mediaQuality: MediaQualityEnum + @UserDefaultCodable("Settings.mediaPlayerSpeed", defaultValue: PlaySpeed.default) + static var mediaPlayerSpeed: PlaySpeed + @UserDefaultCodable("Settings.danmuArea", defaultValue: .style_75) static var danmuArea: DanmuArea diff --git a/BilibiliLive/Module/Personal/SettingsViewController.swift b/BilibiliLive/Module/Personal/SettingsViewController.swift index 52761e3..f152dc6 100644 --- a/BilibiliLive/Module/Personal/SettingsViewController.swift +++ b/BilibiliLive/Module/Personal/SettingsViewController.swift @@ -129,6 +129,12 @@ class SettingsViewController: UIViewController { optionString: MediaQualityEnum.allCases.map({ $0.desp })) { Settings.mediaQuality = $0 } + Actions(title: "默认播放速度", message: "默认设置为1.0", + current: Settings.mediaPlayerSpeed.name, + options: PlaySpeed.blDefaults, + optionString: PlaySpeed.blDefaults.map({ $0.name })) { + Settings.mediaPlayerSpeed = $0 + } Toggle(title: "Avc优先(卡顿尝试开启)", setting: Settings.preferAvc, onChange: Settings.preferAvc.toggle()) Toggle(title: "无损音频和杜比全景声", setting: Settings.losslessAudio, onChange: Settings.losslessAudio.toggle()) Toggle(title: "匹配视频内容", setting: Settings.contentMatch, onChange: Settings.contentMatch.toggle())