播放器新增加载中状态

This commit is contained in:
zeng 2025-05-13 10:05:02 +08:00
parent e4d88bae10
commit b4b867b7d4
9 changed files with 126 additions and 51 deletions

View File

@ -29,13 +29,13 @@ class SPLoginViewController: SPViewController {
}()
private lazy var faceBookButton: UIButton = {
let button = createButton(title: "Login with Facebook", titleColor: .colorFFFFFF(), icon: UIImage(named: "facebook_icon_01"), background: .color0866FF())
let button = createButton(title: "movia_login_title_facebook".localized, titleColor: .colorFFFFFF(), icon: UIImage(named: "facebook_icon_01"), background: .color0866FF())
button.addTarget(self, action: #selector(handleFaceBookButton), for: .touchUpInside)
return button
}()
private lazy var appleButton: UIButton = {
let button = createButton(title: "Login with Apple", titleColor: .color333333(), icon: UIImage(named: "apple_icon_01"), background: .colorFFFFFF())
let button = createButton(title: "movia_login_title_apple".localized, titleColor: .color333333(), icon: UIImage(named: "apple_icon_01"), background: .colorFFFFFF())
button.addTarget(self, action: #selector(handleAppleButton), for: .touchUpInside)
return button
}()

View File

@ -11,7 +11,7 @@ class SPMineViewController: SPViewController {
private lazy var dataArr: [SPMineItem] = {
let arr = [
// SPMineItem(type: .language, iconImage: UIImage(named: "language_icon_01"), title: "movia_profile_Language".localized),
SPMineItem(type: .language, iconImage: UIImage(named: "language_icon_01"), title: "movia_profile_Language".localized),
SPMineItem(type: .feedBack, iconImage: UIImage(named: "feed_back_icon_01"), title: "movia_profile_Feedback".localized),
SPMineItem(type: .privacyPolicy, iconImage: UIImage(named: "privacy_policy_icon_01"), title: "movia_profile_Privacy_Policy".localized),
SPMineItem(type: .userAgreement, iconImage: UIImage(named: "user_agreement_icon_01"), title: "movia_profile_User_Agreement".localized),

View File

@ -139,7 +139,7 @@ class SPPlayerDetailViewController: SPPlayerListViewController {
// uploadPlayTime()
// }
}
/*
override func handleBack() {
guard isShowRecommand else {
super.handleBack()
@ -167,7 +167,7 @@ class SPPlayerDetailViewController: SPPlayerListViewController {
private func _handleBack() {
super.handleBack()
}
*/
}
extension SPPlayerDetailViewController {
@ -391,17 +391,10 @@ extension SPPlayerDetailViewController {
self.viewModel.currentPlayer?.seekToTime(toTime: (videoInfo.play_seconds ?? 0) / 1000)
}
} else {
self.scrollToItem(indexPath: .init(row: 0, section: 0), animated: false) { [weak self] in
guard let self = self else { return }
self.play()
}
self.scrollToItem(indexPath: .init(row: 0, section: 0), animated: false)
}
} else {
self.scrollToItem(indexPath: .init(row: 0, section: 0), animated: false) { [weak self] in
guard let self = self else { return }
self.play()
}
self.scrollToItem(indexPath: .init(row: 0, section: 0), animated: false)
}
}

View File

@ -39,6 +39,13 @@ class SPPlayerControlView: UIView {
}
}
///
var isLoading = false {
didSet {
progressView.isLoading = isLoading
}
}
var durationTime: Int = 0
var currentTime: Int = 0

View File

@ -82,7 +82,7 @@ class SPPlayerDetailRecommandView: HWPanModalContentView {
//MARK: HWPanModalPresentable
override func longFormHeight() -> PanModalHeight {
return PanModalHeightMake(.content, 540)
return PanModalHeightMake(.content, 540 + kSPTabbarSafeBottomMargin)
}
override func showDragIndicator() -> Bool {

View File

@ -70,14 +70,6 @@ class SPPlayerListCell: SPCollectionViewCell, SPPlayerProtocol {
self.controlView.progress = 0
self.coverImageView.isHidden = false
// if let model = model as? SPShortModel {
// self.controlView.model = model
// coverImageView.sp_setImage(url: model.image_url)
// } else if let model = model as? SPVideoDetailModel {
// self.controlView.model = model.shortPlayInfo
// coverImageView.sp_setImage(url: model.shortPlayInfo?.image_url)
// }
}
}
@ -210,4 +202,12 @@ extension SPPlayerListCell: SPPlayerDelegate {
}
}
func sp_player(_ player: SPPlayer, loadStateDidChange state: SPPlayer.LoadState) {
if state == .prepare || state == .stalled {
self.controlView.isLoading = true
} else {
self.controlView.isLoading = false
}
}
}

View File

@ -32,17 +32,39 @@ class SPPlayerProgressView: UIView {
///
private var panProgress: CGFloat = 0
var progressColor: UIColor = .color3D4556()
var progressColor: UIColor = .color3D4556() {
didSet {
self.backgroundColor = progressColor
}
}
var currentProgress: UIColor = .colorFFFFFF()
var lineWidth: CGFloat = 2
///
var isLoading = false {
didSet {
if isLoading {
if gradientTimer == nil {
gradientTimer = Timer.scheduledTimer(timeInterval: 0.05, target: YYWeakProxy(target: self), selector: #selector(handleGradientTimer), userInfo: nil, repeats: true)
}
} else {
gradientTimer?.invalidate()
gradientTimer = nil
}
}
}
///
private var isPaning: Bool = false
private var gradientTimer: Timer?
private var gradientValue: CGFloat = 0
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = .clear
self.backgroundColor = progressColor
let pan = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(sender:)))
self.addGestureRecognizer(pan)
@ -50,6 +72,7 @@ class SPPlayerProgressView: UIView {
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture(sender:)))
self.addGestureRecognizer(tap)
}
required init?(coder: NSCoder) {
@ -62,28 +85,59 @@ class SPPlayerProgressView: UIView {
setNeedsDisplay()
}
@objc private func handleGradientTimer() {
gradientValue += 0.1
if gradientValue > 1 {
gradientValue = 0
}
setNeedsDisplay()
}
override func draw(_ rect: CGRect) {
super.draw(rect)
guard let context = UIGraphicsGetCurrentContext() else { return }
let width = rect.width
let height = rect.height
var progress = self.progress
if self.isPaning {
progress = self.panProgress
if isLoading, !isPaning {
//
let colorSpace = CGColorSpaceCreateDeviceRGB()
let colors: [CGColor] = [
UIColor.clear.cgColor,
UIColor.white.cgColor,
UIColor.clear.cgColor
]
let locations: [CGFloat] = [0.0, gradientValue, 1.0]
guard let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: locations) else {
return
}
//
let startPoint = CGPoint(x: rect.minX, y: rect.minY)
let endPoint = CGPoint(x: rect.maxX, y: rect.maxY)
//
context.drawLinearGradient(gradient, start: startPoint, end: endPoint, options: [])
} else {
var progress = self.progress
if self.isPaning {
progress = self.panProgress
}
///
let progressPath = UIBezierPath(roundedRect: CGRect(x: 0, y: height - lineWidth, width: width, height: lineWidth), cornerRadius: lineWidth / 2)
context.addPath(progressPath.cgPath)
context.setFillColor(progressColor.cgColor)
context.fillPath()
///
let currentPath = UIBezierPath(roundedRect: CGRect(x: 0, y: height - lineWidth, width: width * progress, height: lineWidth), cornerRadius: lineWidth / 2)
context.addPath(currentPath.cgPath)
context.setFillColor(currentProgress.cgColor)
context.fillPath()
}
///
let progressPath = UIBezierPath(roundedRect: CGRect(x: 0, y: height - lineWidth, width: width, height: lineWidth), cornerRadius: lineWidth / 2)
context.addPath(progressPath.cgPath)
context.setFillColor(progressColor.cgColor)
context.fillPath()
///
let currentPath = UIBezierPath(roundedRect: CGRect(x: 0, y: height - lineWidth, width: width * progress, height: lineWidth), cornerRadius: lineWidth / 2)
context.addPath(currentPath.cgPath)
context.setFillColor(currentProgress.cgColor)
context.fillPath()
}
}

View File

@ -18,6 +18,9 @@ import ZFPlayer
///
@objc optional func sp_player(_ player: SPPlayer, playStateDidChanged state: SPPlayer.PlayState)
///
@objc optional func sp_player(_ player: SPPlayer, loadStateDidChange state: SPPlayer.LoadState)
///
@objc optional func sp_playTimeChanged(_ player: SPPlayer, currentTime: Int, duration: Int)
@ -41,10 +44,19 @@ class SPPlayer: NSObject {
case stopped
}
@objc enum LoadState: Int {
case unknown
case prepare
case playable
case playthroughOK
case stalled
}
weak var delegate: SPPlayerDelegate?
private(set) lazy var isPlaying = false
private(set) lazy var playState: PlayState = .unknown
private(set) lazy var loadState: LoadState = .unknown
/**
@ -228,18 +240,25 @@ extension SPPlayer {
} else if loadState == .playable, isPlaying, self.player.playState != .playStatePlaying {
self.start()
}
// switch loadState {
// case .prepare:
// spLog(message: "====")
// case .playable:
// spLog(message: "====")
// case .playthroughOK:
// spLog(message: "====")
// case .stalled:
// spLog(message: "====")
// default:
// break
// }
switch loadState {
case .prepare:
self.loadState = .prepare
// spLog(message: "====")
case .playable:
self.loadState = .playable
// spLog(message: "====")
case .playthroughOK:
self.loadState = .playthroughOK
// spLog(message: "====")
case .stalled:
self.loadState = .stalled
// spLog(message: "====")
default:
self.loadState = .unknown
break
}
self.delegate?.sp_player?(self, loadStateDidChange: self.loadState)
}
//

View File

@ -101,6 +101,8 @@
"movia_open_notification_info" = "Stay informed with popular recommendations and latest updates!";
"movia_top_today" = "Top Today";
"movia_play_now" = "Play Now";
"movia_login_title_facebook" = "Sign in with FaceBook";
"movia_login_title_apple" = "Sign in with Apple";
"movia_iap_error_toast_01" = "Invalid in-app purchase";