Music_Player3/MusicPlayer/MP/MPPositive/ViewControllers/Player(播放器)/MPPositive_PlayerViewController.swift
2024-05-29 13:20:07 +08:00

504 lines
20 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// MPPositive_PlayerViewController.swift
// MusicPlayer
//
// Created by Mr.Zhou on 2024/4/29.
//
import UIKit
import Kingfisher
///b
class MPPositive_PlayerViewController: MPPositive_BaseViewController, UIViewControllerTransitioningDelegate {
//
enum PlayerShowType:Int {
///
case showCover = 0
///
case showLyric = 1
}
//View
private var topShowType:PlayerShowType = .showCover{
didSet{
setSwitchAnimation(topShowType)
}
}
//MARK: - View
//
private lazy var leftPopBtn:UIButton = {
let btn = UIButton()
btn.backgroundColor = .init(hex: "#FFFFFF", alpha: 0.15)
//
btn.layer.borderColor = UIColor(hex: "#FFFFFF", alpha: 0.3).cgColor
btn.layer.borderWidth = 1*width
btn.layer.cornerRadius = 21*width
btn.layer.masksToBounds = true
//
btn.setImage(UIImage(named: "Player_Pop'logo"), for: .normal)
btn.addTarget(self, action: #selector(disMissClick(_ :)), for: .touchUpInside)
return btn
}()
//View(SONG|LYRICS)
private lazy var switchActionView:UIView = createSwitchActionView()
//SONG()
private lazy var songBtn:UIButton = createStatueBtn("SONG", color: .init(hex: "#FFFFFF", alpha: 0.85), tag: 0)
//LYRICS
private lazy var lyricsBtn:UIButton = createStatueBtn("LYRICS", color: .init(hex: "#FFFFFF", alpha: 0.45), tag: 1)
//
private lazy var relatedBtn:UIButton = {
let btn = UIButton()
btn.setBackgroundImage(UIImage(named: "Player_Related'logo"), for: .normal)
btn.addTarget(self, action: #selector(relatedContentClick(_ :)), for: .touchUpInside)
return btn
}()
//MARK: -
//
private lazy var backImageView:UIImageView = {
let imageView:UIImageView = .init()
imageView.contentMode = .scaleAspectFill
return imageView
}()
//
private lazy var backBlurView:UIVisualEffectView = {
//
let blurEffect = UIBlurEffect(style: .dark)
//
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.alpha = 1
blurEffectView.isUserInteractionEnabled = false
return blurEffectView
}()
//MARK: -
//
private lazy var playBtn:UIButton = {
let btn:UIButton = .init()
btn.setBackgroundImage(UIImage(named: "Player_Pause'logo"), for: .normal)
btn.setBackgroundImage(UIImage(named: "Player_Player'logo"), for: .selected)
btn.addTarget(self, action: #selector(playClick(_ :)), for: .touchUpInside)
//
btn.isUserInteractionEnabled = false
return btn
}()
//
private lazy var listBtn:UIButton = {
let btn:UIButton = .init()
btn.setBackgroundImage(UIImage(named: "Player_List'logo"), for: .normal)
btn.addTarget(self, action: #selector(listClick(_ :)), for: .touchUpInside)
return btn
}()
//
private lazy var typeBtn:UIButton = {
let btn = UIButton()
btn.setBackgroundImage(UIImage(named: "List_NormolPlay'logo"), for: .normal)
btn.addTarget(self, action: #selector(typeClick(_ :)), for: .touchUpInside)
return btn
}()
//
private lazy var nextBtn:UIButton = {
let btn = UIButton()
btn.setBackgroundImage(UIImage(named: "Player_Next'logo"), for: .normal)
btn.addTarget(self, action: #selector(nextClick(_ :)), for: .touchUpInside)
return btn
}()
private lazy var perviousBtn:UIButton = {
let btn = UIButton()
btn.setBackgroundImage(UIImage(named: "Player_Pervious'logo"), for: .normal)
btn.addTarget(self, action: #selector(previousClick(_ :)), for: .touchUpInside)
return btn
}()
//View(View)
private lazy var coverView:MPPositive_PlayerCoverView = .init(frame: .init(x: 0, y: 0, width: screen_Width, height: 480*width))
//View
private lazy var lyricsView:MPPositive_PlayerLyricView = .init(frame: .init(x: 0, y: 0, width: screen_Width, height: 480*width))
var recommendBlock:(() -> Void)?
override func viewDidLoad() {
super.viewDidLoad()
//label
setTitle("")
configure()
//
NotificationCenter.notificationKey.add(observer: self, selector: #selector(playerReloadAction(_ :)), notificationName: .positive_player_reload)
NotificationCenter.notificationKey.add(observer: self, selector: #selector(statusSwitchAction(_:)), notificationName: .switch_player_status)
NotificationCenter.notificationKey.add(observer: self, selector: #selector(playerTypeSwitchAction(_:)), notificationName: .player_type_switch)
NotificationCenter.notificationKey.add(observer: self, selector: #selector(deleteListAction(_:)), notificationName: .player_delete_list)
//
MP_PlayerManager.shared.runActionBlock = { [weak self] (currentTime, duration) in
guard let self = self else { return }
//
coverView.durationLabel.text = setTimesToMinSeconds(currentTime)
//
let remain:TimeInterval = duration - currentTime
coverView.maxTimesLabel.text = setTimesToMinSeconds(remain)
//
let value = currentTime/duration
coverView.sliderView.value = Float(value)
}
//
MP_PlayerManager.shared.cacheValueBlock = { [weak self] progress in
guard let self = self else { return }
if progress <= 1 {
coverView.progressView.setProgress(progress, animated: false)
}else {
coverView.progressView.setProgress(1, animated: false)
}
}
switch MP_PlayerManager.shared.getPlayState() {
case .Null://
playBtn.isSelected = false
playBtn.isUserInteractionEnabled = false
case .Playing://
playBtn.isSelected = true
playBtn.isUserInteractionEnabled = true
default://
playBtn.isSelected = false
playBtn.isUserInteractionEnabled = true
}
}
deinit {
NotificationCenter.default.removeObserver(self)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//
if MP_PlayerManager.shared.loadPlayer.currentVideo != nil {
uploadUI()
}
}
//
private func configure() {
//View
navView.addSubview(leftPopBtn)
leftPopBtn.snp.makeConstraints { make in
make.width.height.equalTo(42*width)
make.left.equalToSuperview().offset(16*width)
make.centerY.equalToSuperview()
}
navView.addSubview(relatedBtn)
relatedBtn.snp.makeConstraints { make in
make.width.height.equalTo(24*width)
make.right.equalToSuperview().offset(-16*width)
make.centerY.equalToSuperview()
}
navView.addSubview(switchActionView)
switchActionView.snp.makeConstraints { make in
make.height.equalToSuperview()
make.width.equalToSuperview().multipliedBy(0.45)
make.center.equalToSuperview()
}
//
view.addSubview(backImageView)
backImageView.snp.makeConstraints { make in
make.left.right.top.bottom.equalToSuperview()
}
view.addSubview(backBlurView)
backBlurView.snp.makeConstraints { make in
make.left.right.top.bottom.equalToSuperview()
}
//
view.addSubview(lyricsView)
lyricsView.snp.makeConstraints { make in
make.top.equalTo(navView.snp.bottom)
make.left.right.equalToSuperview()
make.height.equalTo(480*width)
}
lyricsView.isHidden = true
view.addSubview(coverView)
coverView.snp.makeConstraints { make in
make.top.equalTo(navView.snp.bottom)
make.left.right.equalToSuperview()
make.height.equalTo(480*width)
}
coverView.isHidden = false
let bottomImageView:UIImageView = .init(image: .init(named: "Player_Bottom'mask"))
bottomImageView.contentMode = .scaleAspectFill
bottomImageView.isUserInteractionEnabled = false
view.addSubview(bottomImageView)
bottomImageView.snp.makeConstraints { make in
make.left.right.bottom.equalToSuperview()
make.height.equalTo(286*width)
}
//
let bottomView = createBottomView()
view.addSubview(bottomView)
bottomView.snp.makeConstraints { make in
make.left.right.bottom.equalToSuperview()
make.height.equalTo(200*width)
}
}
//View
private func createSwitchActionView() -> UIView {
let actionView:UIView = UIView()
actionView.backgroundColor = .clear
actionView.addSubview(songBtn)
songBtn.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.centerX.equalToSuperview().multipliedBy(0.5)
}
actionView.addSubview(lyricsBtn)
lyricsBtn.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.centerX.equalToSuperview().multipliedBy(1.5)
}
//线View
let lineView:UIView = .init()
lineView.backgroundColor = .init(hex: "#FFFFFF", alpha: 0.45)
actionView.addSubview(lineView)
lineView.snp.makeConstraints { make in
make.center.equalToSuperview()
make.width.equalTo(1*width)
make.height.equalTo(14*width)
}
//
return actionView
}
//
private func createStatueBtn(_ text:String = "text", color:UIColor, tag:Int) -> UIButton {
let btn = UIButton()
btn.setTitle(text, for: .normal)
btn.setTitleColor(color, for: .normal)
btn.titleLabel?.font = .systemFont(ofSize: 15, weight: .regular)
btn.tag = tag
btn.addTarget(self, action: #selector(switchActionClick(_ :)), for: .touchUpInside)
return btn
}
//View
private func createBottomView() -> UIView {
let bottomView:UIView = .init()
bottomView.backgroundColor = .clear
bottomView.addSubview(playBtn)
playBtn.snp.makeConstraints { make in
make.width.height.equalTo(66*width)
make.center.equalToSuperview()
}
bottomView.addSubview(listBtn)
listBtn.snp.makeConstraints { make in
make.right.equalToSuperview().offset(-20*width)
make.centerY.equalToSuperview()
make.width.height.equalTo(24*width)
}
bottomView.addSubview(typeBtn)
typeBtn.snp.makeConstraints { make in
make.left.equalToSuperview().offset(20*width)
make.centerY.equalToSuperview()
make.width.height.equalTo(24*width)
}
bottomView.addSubview(nextBtn)
nextBtn.snp.makeConstraints { make in
make.width.height.equalTo(20*width)
make.centerY.equalTo(playBtn.snp.centerY)
make.right.equalToSuperview().offset(-98*width)
}
bottomView.addSubview(perviousBtn)
perviousBtn.snp.makeConstraints { make in
make.width.height.equalTo(20*width)
make.centerY.equalTo(playBtn.snp.centerY)
make.left.equalToSuperview().offset(98*width)
}
return bottomView
}
//MARK: -
private func uploadUI() {
//
backImageView.kf.setImage(with: MP_PlayerManager.shared.loadPlayer.currentVideo?.coverUrl)
coverView.coverImageView.kf.setImage(with: MP_PlayerManager.shared.loadPlayer.currentVideo?.coverUrl)
coverView.titleLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.title
coverView.subtitleLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.subtitle
lyricsView.titleLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.title
lyricsView.subtitleLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.subtitle
lyricsView.lyricsLabel.text = MP_PlayerManager.shared.loadPlayer.currentVideo?.lyrics?.isEmpty == true ? "No Lyrics":MP_PlayerManager.shared.loadPlayer.currentVideo?.lyrics
coverView.loadBtn.isSelected = MP_PlayerManager.shared.loadPlayer.currentVideo?.isDlownd ?? false
coverView.collectionSongBtn.isSelected = MP_PlayerManager.shared.loadPlayer.currentVideo?.isCollection ?? false
coverView.restoreDownloadProgress()
}
//MARK: -
//
@objc private func playerReloadAction(_ sender:Notification) {
//
DispatchQueue.main.async {
[weak self] in
guard let self = self else {return}
uploadUI()
//
coverView.sliderView.value = 0
//
coverView.durationLabel.text = setTimesToMinSeconds(0)
//
coverView.maxTimesLabel.text = setTimesToMinSeconds(0)
//
MP_PlayerManager.shared.play { [weak self] in
guard let self = self else { return }
//playBtn
playBtn.isUserInteractionEnabled = true
}
}
}
//
@objc private func statusSwitchAction(_ sender:Notification) {
if sender.object != nil {
let state:MP_PlayerStateType = sender.object as! MP_PlayerStateType
DispatchQueue.main.async {
[weak self] in
switch state {
case .Playing:
self?.playBtn.isSelected = true
default:
self?.playBtn.isSelected = false
}
}
}
}
//
@objc private func playerTypeSwitchAction(_ sender:Notification) {
DispatchQueue.main.async {
[weak self] in
guard let self = self else {return}
switchPlayTypeBtnIcon(typeBtn)
}
}
//
@objc private func deleteListAction(_ sender:Notification) {
DispatchQueue.main.async {
[weak self] in
guard let self = self else {return}
dismiss(animated: true)
}
}
//MARK: -
//dismiss
@objc private func disMissClick(_ sender:UIButton) {
dismiss(animated: true)
}
//|
@objc private func switchActionClick(_ sender:UIButton) {
topShowType = .init(rawValue: sender.tag)!
}
//
private func setSwitchAnimation(_ sender: PlayerShowType) {
//segmentedView
switchActionView.isUserInteractionEnabled = false
switch sender {
case .showCover://
UIView.animate(withDuration: 0.4) {
[weak self] in
guard let self = self else {return}
//
coverView.alpha = 1.0
coverView.isHidden = false
//lyricView
lyricsView.alpha = 0.1
songBtn.setTitleColor(.init(hex: "#FFFFFF", alpha: 0.85), for: .normal)
lyricsBtn.setTitleColor(.init(hex: "#FFFFFF", alpha: 0.45), for: .normal)
} completion: { [weak self] (_) in
guard let self = self else {return}
//lyricListView
lyricsView.isHidden = true
//
switchActionView.isUserInteractionEnabled = true
}
case .showLyric://
UIView.animate(withDuration: 0.4) {
[weak self] in
guard let self = self else {return}
//
lyricsView.alpha = 1.0
lyricsView.isHidden = false
//coverView
coverView.alpha = 0.1
songBtn.setTitleColor(.init(hex: "#FFFFFF", alpha: 0.45), for: .normal)
lyricsBtn.setTitleColor(.init(hex: "#FFFFFF", alpha: 0.85), for: .normal)
} completion: { [weak self] (_) in
guard let self = self else {return}
//coverView
coverView.isHidden = true
//
switchActionView.isUserInteractionEnabled = true
}
}
}
//
@objc private func relatedContentClick(_ sender:UIButton) {
//dismiss
dismiss(animated: true) {[weak self] in
guard let self = self else {return}
if recommendBlock != nil {
recommendBlock!()
}
}
}
////
@objc private func playClick(_ sender:UIButton) {
guard MP_PlayerManager.shared.loadPlayer != nil else {
return
}
//
switch MP_PlayerManager.shared.getPlayState() {
case .Null:
//
MP_PlayerManager.shared.play { [weak self] in
guard let self = self else { return }
//
coverView.sliderView.value = 0
}
case .Playing:
//
MP_PlayerManager.shared.pause {
[weak self] in
}
case .Pause:
//
MP_PlayerManager.shared.resume {
[weak self] in
}
}
}
//
@objc private func listClick(_ sender:UIButton) {
if MP_PlayerManager.shared.loadPlayer != nil {
MPPositive_ModalType = .PlayerList
let listVC = MPPositive_PlayerListShowViewController()
listVC.transitioningDelegate = self
listVC.modalPresentationStyle = .custom
present(listVC, animated: true)
}
}
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
return MPPositive_PresentationController(presentedViewController: presented, presenting: presenting)
}
////
@objc private func typeClick(_ sender:UIButton) {
MPPositive_Debouncer.shared.call {
[weak self] in
guard let self = self else {return}
//
var value = MP_PlayerManager.shared.getPlayType().rawValue
value += 1
if value > 2 {
value = 0
}
MP_PlayerManager.shared.setPlayType(.init(rawValue: value)!)
}
}
//
@objc private func nextClick(_ sender:UIButton) {
MPPositive_Debouncer.shared.call {
[weak self] in
guard let self = self else {return}
coverView.sliderView.value = 0
playBtn.isUserInteractionEnabled = false
MP_PlayerManager.shared.nextEvent()
}
}
//
@objc private func previousClick(_ sender:UIButton) {
MPPositive_Debouncer.shared.call {
[weak self] in
guard let self = self else {return}
coverView.sliderView.value = 0
playBtn.isUserInteractionEnabled = false
MP_PlayerManager.shared.previousEvent()
}
}
}