//
//  MP_PlayerManager.swift
//  MusicPlayer
//
//  Created by Mr.Zhou on 2024/5/10.
//

import UIKit
import AVFoundation
import MediaPlayer
import AVKit
import Kingfisher
///播放器播放状态
enum MP_PlayerStateType:Int {
    ///未启动
    case Null = 0
    ///运行中
    case Playing = 1
    ///暂停中
    case Pause = 2
}
///播放器播放方式
enum MP_PlayerPlayType:Int {
    ///列表顺序播放
    case normal = 0
    ///列表随机播放
    case random = 1
    ///单曲播放（当前音乐无限循环）
    case single = 2
    var title:String{
        switch self {
        case .normal:
            return "顺序播放"
        case .random:
            return "随机播放"
        case .single:
            return "单曲循环"
        }
    }
}
///计时器状态
enum MP_TimerStateType:Int {
    ///运行
    case Resume = 0
    ///暂停
    case Suspend = 1
}

///播放器启动时执行事件（播放的音乐）
typealias MP_PlayTimerStartAction = () -> Void
///播放器运行时执行事件(当前时间值，最大时间值)
typealias MP_PlayTimerRunAction = (_ currentTime:TimeInterval, _ duration:TimeInterval) -> Void
///播放器结束时执行事件
typealias MP_PlayTimerEndAction = () -> Void
///播放器暂停时执行事件
typealias MP_PlayTimerPauseAction = () -> Void
///播放器继续时执行事件
typealias MP_PlayTimerResumeAction = () -> Void
///播放器终止时执行事件
typealias MP_PlayTimerStopAction = () -> Void
///播放器调整进度时执行事件
typealias MP_PlayTimerEditEndAction = () -> Void
///播放器缓存值执行事件
typealias MP_PlayCacheValueAction = (_ currentValue:TimeInterval, _ duration:TimeInterval) -> Void
///播放器
class MP_PlayerManager:NSObject{
    ///控制器单例
    static let shared = MP_PlayerManager()
    ///播放器
    private lazy var player:AVPlayer = {
        let player = AVPlayer()
        player.rate = 1
        return player
    }()
    //远程控制中心
    var center:MPRemoteCommandCenter?{
        didSet{
            print("更新了远程控制中心")
        }
    }
    ///延迟计时器
    private var timer:DispatchSourceTimer?
    ///延迟计时值
    private var times:TimeInterval = 0
    ///计时器队列
    private var queue:DispatchQueue?
    ///load模块
    var loadPlayer:MPPositive_PlayerLoadViewModel!{
        willSet{
            DispatchQueue.main.async {
                [weak self] in
                guard let self = self else {return}
                guard loadPlayer != nil else {
                    if newValue != nil {
                        //当load模块接受到新值的时候，发出通知，提醒底部模块状态切换
                        NotificationCenter.notificationKey.post(notificationName: .pup_bottom_show)
                    }
                    return
                }
                if newValue != nil {
                    //当load模块接受到新值的时候，发出通知，提醒底部模块状态切换
                    NotificationCenter.notificationKey.post(notificationName: .pup_bottom_show)
                }else {
                    //用户清空了load模块，隐藏播放器
                    NotificationCenter.notificationKey.post(notificationName: .player_delete_list)
                    playState = .Null
                    player.pause()
                    center?.playCommand.removeTarget(self)
                    center?.pauseCommand.removeTarget(self)
                    center?.nextTrackCommand.removeTarget(self)
                    center?.previousTrackCommand.removeTarget(self)
                    center?.changePlaybackPositionCommand.removeTarget(self)
                    center = nil
                    do {
                        try AVAudioSession.sharedInstance().setActive(false)
                    } catch {
                        print("Error deactivating audio session: \(error)")
                    }
                }
            }
        }
    }
    //当前音乐的字典
    private var currentInfo:[String:Any]?
    //是否展示最后一首状态
    private var isLast:Bool = false
    //设置是否页面展示最后一首状态
    func setLastStatus(bool:Bool) {
        isLast = bool
    }
    //当前播放器状态
    private var playState:MP_PlayerStateType = .Null{
        didSet{
            //当播放器状态发生变化时，对播放器按钮状态进行切换
            NotificationCenter.notificationKey.post(notificationName: .switch_player_status, object: playState)
        }
    }
    //是否因为广告原因延迟了播放（当广告加载时，延迟播放器状态切换）
    var isAdLate:Bool?{
        didSet{
            DispatchQueue.main.asyncAfter(deadline: .now()) {
                [weak self] in
                guard let self = self else {return}
                guard let ad = isAdLate, loadPlayer?.currentVideo != nil else {return}
                //当监听到插页广告的展示或消失时
                if ad == true {
                    //展示插页广告中
                    switch playState {
                    case .Null://当前音乐加载中
                        //直接暂停音乐
                        player.pause()
                    case .Playing://当前音乐播放中
                        //直接暂停音乐
                        player.pause()
                    case .Pause://当前音乐暂停中
                        //继续暂停
                        player.pause()
                    }
                }else {
                    //插页广告销毁了
                    switch playState {
                    case .Null://当前音乐加载中
                        //判断音乐本身是否有足够数据播放
                        if loadPlayer?.currentVideo?.resourcePlayerItem?.isPlaybackLikelyToKeepUp == true {
                            //具备足够的数据，让音乐恢复播放
                            playState = .Playing
                            player.play()
                        }else {
                            //不具备，不操作
                            playState = .Null
                            player.pause()
                        }
                    case .Playing://当前音乐播放中
                        playState = .Playing
                        //恢复播放
                        player.play()
                    case .Pause://当前音乐暂停中
                        playState = .Pause
                        //继续暂停
                        player.pause()
                    }
                }
            }
        }
    }
    
    ///获取播放器播放状态
    func getPlayState() -> MP_PlayerStateType {
        return playState
    }
    ///当前播放器播放方法
    private var playType:MP_PlayerPlayType = .normal{
        didSet{
            DispatchQueue.main.async {
                //当播放器播放方式变化后，发出通知
                NotificationCenter.notificationKey.post(notificationName: .player_type_switch)
            }
        }
    }
    ///获取播放器播放方法
    func getPlayType() -> MP_PlayerPlayType {
        return playType
    }
    /// 设置播放器播放方式
    /// - Parameter type: 新的类型
    func setPlayType(_ type:MP_PlayerPlayType) {
        playType = type
        print("播放器播放方法已经改为\(type.title)")
    }
    ///计时器状态
    private var timerType:MP_TimerStateType = .Suspend
    ///播放器启动时执行事件记录
    private var startActionBlock:MP_PlayTimerStartAction!
    ///播放器运行时执行事件记录
    var runActionBlock:MP_PlayTimerRunAction!
    ///播放器缓存值闭包
    var cacheValueBlock:MP_PlayCacheValueAction!
    ///播放实例状态的监听器
    private var statusObservation:NSKeyValueObservation?
    ///播放实例缓存值的监听器
    private var loadedTimeRangesObservation:NSKeyValueObservation?
    ///播放实例是否支持播放的监听器
    private var playbackLikelyToKeepUpObservation:NSKeyValueObservation?
    ///播放实例报错的监听器
    private var errorObservation:NSKeyValueObservation?
    private override init() {
        super.init()
        //初始化计时器
        timer?.cancel()
        queue = DispatchQueue(label: "com.playerTimer.timer",attributes: .concurrent)
        timer = DispatchSource.makeTimerSource(queue: queue)
        //设置计时器每0.1秒触发一次,误差在0.01秒
        timer?.schedule(deadline: .now(), repeating: .milliseconds(100), leeway: .milliseconds(10))
        // 设置计时器触发时执行的回调
        timer?.setEventHandler(handler: { [weak self] in
            //将计时值增加0.1秒
            self?.times += 0.1
        })
        // 添加观察者，监听播放结束事件
        NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlaying(_ :)), name: .AVPlayerItemDidPlayToEndTime, object: player.currentItem)
        //监听用户切换了音乐
        NotificationCenter.notificationKey.add(observer: self, selector: #selector(userSwitchCurrentVideoAction(_ :)), notificationName: .positive_player_reload)
        //监听网络状态恢复可用
        NotificationCenter.notificationKey.add(observer: self, selector: #selector(netWorkReachableAction(_ :)), notificationName: .net_switch_reachable)
        //监听蓝牙设备的状态
        NotificationCenter.default.addObserver(self, selector: #selector(handleAudioSessionRouteChangeAction(_ :)), name: AVAudioSession.routeChangeNotification, object: nil)
        //设置一个秒为刻度的时间值
        let interval:CMTime = .init(seconds: 1, preferredTimescale: .init(1))
        //为播放器添加运行时主线程每秒触发事件
        player.addPeriodicTimeObserver(forInterval: interval, queue: .main, using: { [weak self] (time) in
            guard let self = self else { return }
            cacheLoadTimes()
            //转化为当前播放进度秒值
            let currentDuration = CMTimeGetSeconds(time)
            //更新控制中心的进度条
            updateNowPlayingInfo()
            //获取当前播放音乐资源的最大时间值
            let maxDuration = getMusicDuration()
            if maxDuration.isNaN == false {
                //判断当值进度是否超越最大时间值
                if currentDuration <= maxDuration {
                    //没有，执行运行时时间
                    if runActionBlock != nil {
                        runActionBlock!(currentDuration, maxDuration)
                    }
                }
            }
        })
    }
    deinit {
        NotificationCenter.default.removeObserver(self)
        center?.playCommand.removeTarget(self)
        center?.pauseCommand.removeTarget(self)
        center?.nextTrackCommand.removeTarget(self)
        center?.previousTrackCommand.removeTarget(self)
        timer?.cancel()
        timer = nil
    }
    /// 开始播放音乐
    /// - Parameters:
    ///   - startAction: 开始播放时需要执行的事件
    ///   - runAction: 播放途中需要执行的事件
    ///   - endAction: 结束播放时需要执行的事件
    func play(startAction:MP_PlayTimerStartAction? = nil) {
        guard loadPlayer != nil, loadPlayer?.currentVideo != nil else {
            //当两项数据皆为空时，播放器无法播放
            print("Player No Data")
            return
        }
        //检索播放器状态
        switch playState {
        case .Null://未启动
            break
        case .Playing://启动中
            player.pause()
        case .Pause://暂停中
            break
        }
        //记录事件
        if startAction != nil {
            startActionBlock = startAction
        }
        //覆盖播放器原有的playerItem
        player.replaceCurrentItem(with: loadPlayer?.currentVideo?.resourcePlayerItem)
        if center == nil {
            setCommandCenter()
        }
        //启动计时器
        startTimer()
        //对当前播放PlayerItem设置监听状态
        if loadPlayer?.currentVideo?.isKVO == false {
            //准备状态
            statusObservation?.invalidate()
            statusObservation = loadPlayer?.currentVideo?.resourcePlayerItem?.observe(\.status, options: [.old,.new], changeHandler: { [weak self] item, change in
                guard let self = self else {return}
                if item.status == .readyToPlay {
                    //判断当前播放器是否在播放当前音乐中
                    if playState != .Playing {
                        //当statuVlaue值等于playerItem准备播放的值，说明已经准备好播放
                        print("当前音乐-\(loadPlayer?.currentVideo?.title ?? "") 已经准备好播放")
                    }
                }else {
                    if let currentVideo = loadPlayer?.currentVideo {
                        print("当前音乐-\(currentVideo.title ?? "") 未做好准备播放，失败原因是\(currentVideo.resourcePlayerItem.error?.localizedDescription ?? "")")
                        MP_AnalyticsManager.shared.player_b_failure_errorAction(currentVideo.song.videoId ?? "", videoname: currentVideo.title ?? "", artistname: currentVideo.song.shortBylineText ?? "", error: currentVideo.resourcePlayerItem.error?.localizedDescription ?? "Failed to buffer data")
                        if loadPlayer?.currentVideo?.isKVO == true {
                            suspendTimer()
                            loadPlayer?.currentVideo?.isKVO = false
                            statusObservation?.invalidate()
                            loadedTimeRangesObservation?.invalidate()
                            playbackLikelyToKeepUpObservation?.invalidate()
                            errorObservation?.invalidate()
                            //重新配置数据
                            loadPlayer?.remakeImproveData {
                                [weak self] in
                                self?.play()
                            }
                        }
                    }
                }
            })
            //当前缓冲值
            loadedTimeRangesObservation?.invalidate()
            loadedTimeRangesObservation = loadPlayer?.currentVideo?.resourcePlayerItem?.observe(\.loadedTimeRanges, options: [.old,.new], changeHandler: { [weak self] item, change in
                guard let self = self else {return}
                cacheLoadTimes()
            })
            //是否具备足够播放的能力
            playbackLikelyToKeepUpObservation?.invalidate()
            playbackLikelyToKeepUpObservation = loadPlayer?.currentVideo?.resourcePlayerItem?.observe(\.isPlaybackLikelyToKeepUp, options: [.old,.new], changeHandler: { [weak self] item, change in
                guard let self = self else {return}
                if let playbackLikelyToKeepUp = change.newValue, playbackLikelyToKeepUp == true {
                    if playState != .Playing && playState != .Pause {
                        //还未播放当前音乐，启动播放
                        playState = .Playing
                        //检索是否展示了插页广告
                        if isAdLate != true {
                            //当前是否上次播放展示状态，是的话，手动暂停
                            if isLast {
                                pause()
                                isLast = false
                            }else {
                                player.play()
                            }
                        }
                        //暂停计时器，并获取延时值
                        suspendTimer()
                        MP_AnalyticsManager.shared.player_b_success_actionAction(loadPlayer?.currentVideo?.song.videoId ?? "", videoname: loadPlayer?.currentVideo?.title ?? "", artistname: loadPlayer?.currentVideo?.song.shortBylineText ?? "")
                        //执行开始播放闭包
                        if startActionBlock != nil {
                            startActionBlock!()
                        }
                    }
                }else {
                    //没有足够的数据支持播放
                    player.pause()
                    playState = .Null
                }
            })
            //报错提醒
            errorObservation?.invalidate()
            errorObservation = loadPlayer?.currentVideo?.resourcePlayerItem?.observe(\.error, options: [.old,.new], changeHandler: { [weak self] item, change in
                guard let self = self else {return}
                if let error = change.newValue, let nsError = error {
                    print("当前音乐-\(loadPlayer?.currentVideo?.title ?? "") 未做好准备播放，失败原因是\(nsError.localizedDescription)")
                    MP_AnalyticsManager.shared.player_b_failure_errorAction(loadPlayer?.currentVideo?.song.videoId ?? "", videoname: loadPlayer?.currentVideo?.title ?? "", artistname: loadPlayer?.currentVideo?.song.shortBylineText ?? "", error: nsError.localizedDescription)
                }
            })
            loadPlayer?.currentVideo?.isKVO = true
            //将进度回归为0
            player.seek(to: .zero)
            updateNowPlayingInfo()
        }
    }
    ///启动计时器
    func startTimer() {
        guard timerType == .Suspend else {
            return
        }
        times = 0
        //运行计时器
        timer?.resume()
        timerType = .Resume
    }
    ///暂停计时器
    func suspendTimer() {
        guard timerType == .Resume else {
            return
        }
        //暂停计时器
        timer?.suspend()
        timerType = .Suspend
        guard times != 0 else {
            return
        }
        let times = Int(self.times)
        let msTimes = times*1000
        MP_AnalyticsManager.shared.player_b_delay_actionAction(loadPlayer?.currentVideo?.song.videoId ?? "", videoname: loadPlayer?.currentVideo?.title ?? "", artistname: loadPlayer?.currentVideo?.song.shortBylineText ?? "", delay: "\(msTimes)ms")
    }
    ///监听到音视频路由发生变化
    @objc private func handleAudioSessionRouteChangeAction(_ notification: Notification) {
        guard let info = notification.userInfo, let reasonValue = info[AVAudioSessionRouteChangeReasonKey] as? UInt, let reason = AVAudioSession.RouteChangeReason(rawValue:reasonValue) else {
            return
        }
        switch reason {
        case .newDeviceAvailable:// 新设备连接
            print("设备已连接")
            //继续运行
        case .oldDeviceUnavailable:// 设备断开
            print("设备已断开")
            //暂停当前播放
            pause()
        default:
            break
        }
    }
    ///网络状态恢复正常
    @objc private func netWorkReachableAction(_ sender:Notification) {
        //监听到网络状态恢复，检索当前播放器是否正在播放
        if loadPlayer?.currentVideo != nil {
            if playState == .Playing {
                //有音乐播放，获取当前播放进度
                let currentTime = loadPlayer?.currentVideo?.resourcePlayerItem?.currentTime() ?? .zero
                //手动调整播放时间点，以此重启播放器缓存
                player.seek(to: currentTime)
                player.play()
                playState = .Playing
            }
        }
    }
   
    //获取缓冲值
    private func cacheLoadTimes() {
        //获取当前播放Item的缓冲值组
        if let timeRanges = loadPlayer?.currentVideo?.resourcePlayerItem?.loadedTimeRanges.map({$0.timeRangeValue}), let first = timeRanges.first {
            //获取开始时间的秒数
            let startSeconds = first.start.seconds
            //获取缓冲区的持续时间
            let durationSeconds = first.duration.seconds
            //计算当前缓冲总时间
            let bufferedSeconds = startSeconds + durationSeconds
            //获取当前播放音乐资源的最大时间值
            let maxDuration = getMusicDuration()
            //传递缓存值
            if cacheValueBlock != nil {
                cacheValueBlock!(bufferedSeconds, maxDuration)
            }
        }
    }
    //MARK: - 获取当前音乐总长度
    ///获取音乐资源总时长
    private func getMusicDuration() -> TimeInterval {
        return CMTimeGetSeconds(player.currentItem?.duration ?? .zero)
    }
    
    //MARK: - 音乐播放结束
    //当前音乐播放结束时
    @objc private func playerDidFinishPlaying(_ sender:Notification) {
        //检索播放器对象
        guard playState == .Playing else {
            return
        }
        switch playType {
        case .single:
            //重播
            player.seek(to: CMTime.zero)
            player.play()
        default:
            //当前音乐播放器正在播放中，下一首
            nextEvent()
        }
    }
    //MARK: - 暂停播放
    ///内部暂停播放
    private func pause() {
        //检索播放状态，是否进行中
        guard playState == .Playing else {
            //未处于播放中
            print("Player is not in playing")
            return
        }
        //暂停播放器
        player.pause()
        //切换播放器状态
        playState = .Pause
    }
    /// 暂停播放
    /// - Parameter pauseAction: 暂停时要执行的事件
    func pause(_ pauseAction:MP_PlayTimerPauseAction? = nil) {
        //检索播放状态，是否进行中
        guard playState == .Playing else {
            //未处于播放中
            print("Player is not in playing")
            return
        }
        if pauseAction != nil {
            pauseAction!()
        }
        //暂停播放器
        player.pause()
        //切换播放器状态
        playState = .Pause
    }
    ///因为广告展示暂停
    func adToPause() {
        //强行转入加载状态
        playState = .Null
        player.pause()
    }
    ///因为广告注销继续
    func adToResume() {
        
    }
    //MARK: - 继续播放
    /// 继续播放
    /// - Parameter resumeAction: 继续时要执行的事件
    func resume(_ resumeAction:MP_PlayTimerResumeAction? = nil) {
        //检索播放状态，是否暂停中
        guard playState == .Pause else {
            //未处于暂停中
            print("Player is not paused")
            return
        }
        if resumeAction != nil {
            resumeAction!()
        }
        //继续播放器
        player.play()
        //切换播放器状态
        playState = .Playing
    }
    ///内部继续播放
    private func resume() {
        //检索播放状态，是否暂停中
        guard playState == .Pause else {
            //未处于暂停中
            print("Player is not paused")
            return
        }
        //继续播放器
        player.play()
        //切换播放器状态
        playState = .Playing
    }
    
    //MARK: - 停止播放
    //停止播放
    func stop() {
        //检索播放状态，是否已启动
        guard playState != .Null else {
            //未启动
            print("Player is not started")
            return
        }
        player.pause()
        playState = .Null
    }
    //MARK: - 切歌（上一首/下一首）
    ///上一首歌事件
    func previousEvent() {
        //将播放器状态调整未播放
        playState = .Null
        var nextIndex:Int = 0
        //判断当前音乐播放方式
        switch playType {
        case .random://随机，播放随机列表内容
            //检索当前列表是否为只有一首
            guard (loadPlayer?.randomVideos?.count ?? 0) != 1 else {
                player.seek(to: .zero)
                playState = .Playing
                player.play()
                return
            }
            for (index, item) in (loadPlayer?.randomVideos ?? []).enumerated() {
                if item.videoId == loadPlayer?.currentVideo?.song.videoId {
                    //找到播放音乐的索引
                    nextIndex = index - 1
                }
            }
            //假如next为负数，则直接播放列表最后一首
            if nextIndex < 0 {
                //播放列表最后一首
                let last = loadPlayer?.randomVideos?.last
                loadPlayer?.improveData(last?.videoId ?? "", isRandom: true)
            }else {
                //查询列表对应单曲
                if let song = loadPlayer?.randomVideos?[nextIndex] {
                    loadPlayer?.improveData(song.videoId ?? "", isRandom: true)
                }
            }
        default://常规播放或者单曲播放
            guard (loadPlayer?.songVideos?.count ?? 0) != 1 else {
                player.seek(to: .zero)
                playState = .Playing
                player.play()
                return
            }
            for (index, item) in (loadPlayer?.songVideos ?? []).enumerated() {
                if item.videoId == loadPlayer?.currentVideo?.song.videoId {
                    //找到播放音乐的索引
                    nextIndex = index - 1
                }
            }
            //假如next为负数，则直接播放列表最后一首
            if nextIndex < 0 {
                //播放列表最后一首
                let last = loadPlayer?.songVideos?.last
                loadPlayer?.improveData(last?.videoId ?? "")
            }else {
                //查询列表对应单曲
                if let song = loadPlayer?.songVideos?[nextIndex] {
                    loadPlayer?.improveData(song.videoId ?? "")
                }
            }
        }
    }
    ///下一首歌事件
    func nextEvent() {
        print("切换下一首")
        //将播放器状态调整未播放
        playState = .Null
        var nextIndex:Int = 0
        switch playType {
        case .random:
            guard let randomVideos = loadPlayer?.randomVideos, randomVideos.count != 1 else {
                player.seek(to: .zero)
                playState = .Playing
                player.play()
                return
            }
            for (index, item) in randomVideos.enumerated() {
                if item.videoId == loadPlayer?.currentVideo?.song.videoId {
                    //找到播放音乐的索引
                    nextIndex = index + 1
                }
            }
            //超出播放列表数
            if nextIndex > (randomVideos.count-1) {
                //播放列表第一首
                let first = randomVideos.first
                loadPlayer?.improveData(first?.videoId ?? "", isRandom: true)
            }else {
                //存在下一首,获取下一首ID，并播放
                if let song = loadPlayer?.randomVideos?[nextIndex] {
                    loadPlayer?.improveData(song.videoId ?? "", isRandom: true)
                }
            }
        default:
            guard let songVideos = loadPlayer.songVideos, songVideos.count != 1 else {
                player.seek(to: .zero)
                playState = .Playing
                player.play()
                return
            }
            for (index, item) in songVideos.enumerated() {
                if item.videoId == loadPlayer?.currentVideo?.song.videoId {
                    //找到播放音乐的索引
                    nextIndex = index + 1
                }
            }
            //超出播放列表数
            if nextIndex > (songVideos.count-1) {
                //播放列表第一首
                let first = songVideos.first
                loadPlayer?.improveData(first?.videoId ?? "")
            }else {
                //存在下一首,获取下一首ID，并播放
                if let song = loadPlayer?.songVideos?[nextIndex] {
                    loadPlayer?.improveData(song.videoId ?? "")
                }
            }
        }
    }
    ///监听到用户切换当前音乐
    @objc private func userSwitchCurrentVideoAction(_ sender:Notification) {
        //将播放器状态调整未播放
        playState = .Null
        //暂停播放
        player.pause()
        //优先获取传递的值
        if let video = sender.object as? MPPositive_SongViewModel {
            if video.isKVO == true {
                //切歌时移除KVO监听
                statusObservation?.invalidate()
                playbackLikelyToKeepUpObservation?.invalidate()
                errorObservation?.invalidate()
                loadedTimeRangesObservation?.invalidate()
                video.isKVO = false
            }
        }
        if cacheValueBlock != nil {
            cacheValueBlock!(0, 1)
        }
        if loadPlayer?.currentVideo != nil {
            //开始播放
            play(startAction: startActionBlock)
        }
    }
    
    ///播放器进度调整状态
    func setEditPorgressStatu() {
        guard playState != .Null else {
            return
        }
        //播放器进入暂停状态
        pause()
    }
    /// 调整播放器进度值，必须和 setEditPorgressStatu()搭配使用
    /// - Parameters:
    ///   - progress: 要调整进度值（保证在0-1范围内，超出该方法不会响应）
    func setEditProgressEnd(_ progress:Float, endAction:MP_PlayTimerEditEndAction? = nil) {
        guard playState != .Null else {
            return
        }
        guard progress >= 0, progress <= 1 else {
            return
        }
        //根据当前进度值设置时间节点
        let timePoint:Double = Double(progress)*getMusicDuration()
        //设置对应的时间值
        let time:CMTime = .init(seconds: timePoint, preferredTimescale: CMTimeScale(NSEC_PER_SEC))
        //调整播放器时间
        player.seek(to: time)
        //恢复播放
        resume()
        if endAction != nil {
            endAction!()
        }
    }
    //MARK: - 远程中心
    func setCommandCenter() {
        // 实例化远程控制中心
        center = MPRemoteCommandCenter.shared()
        //设置控制中心各项操作
        //播放
        center!.playCommand.addTarget(handler: { [weak self] (event) in
            guard let self = self else { return .noActionableNowPlayingItem}
            if loadPlayer?.currentVideo != nil && playState == .Pause  {
                resume()
                return .success
            }else {
                return .noActionableNowPlayingItem
            }
        })
        //暂停
        center!.pauseCommand.addTarget(handler: { [weak self] (event) in
            guard let self = self else { return .noActionableNowPlayingItem}
            if loadPlayer?.currentVideo != nil && playState == .Playing  {
                pause()
                return .success
            }else {
                return .noActionableNowPlayingItem
            }
        })
        //上一首
        center!.previousTrackCommand.addTarget { [weak self] (event) in
            guard let self = self else { return .noActionableNowPlayingItem}
            if loadPlayer?.currentVideo != nil && MP_NetWorkManager.shared.netWorkStatu == .reachable {
                previousEvent()
                return .success
            }else {
                return .noActionableNowPlayingItem
            }
        }
        //下一首歌
        center!.nextTrackCommand.addTarget { [weak self] (event) in
            guard let self = self else { return .noActionableNowPlayingItem}
            if loadPlayer?.currentVideo != nil  && MP_NetWorkManager.shared.netWorkStatu == .reachable  {
                nextEvent()
                return .success
            }else {
                return .noActionableNowPlayingItem
            }
        }
        //拖拽进度
        center?.changePlaybackPositionCommand.addTarget(handler: { [weak self] event in
            guard let self = self else { return .noActionableNowPlayingItem}
            guard MP_NetWorkManager.shared.netWorkStatu == .reachable else {
                return .noActionableNowPlayingItem
            }
            guard let positionEvent = event as? MPChangePlaybackPositionCommandEvent else {
                return .commandFailed
            }
            if loadPlayer?.currentVideo != nil {
                self.player.seek(to: CMTime(seconds: positionEvent.positionTime, preferredTimescale: 1))
                return .success
            }else {
                return .noActionableNowPlayingItem
            }
        })
    }
    //设置远程中心内容更新
    func updateNowPlayingInfo() {
        guard loadPlayer?.currentVideo != nil else {return}
        //设置info字典信息
        currentInfo = [:]
        //展示标题
        currentInfo![MPMediaItemPropertyTitle] = loadPlayer?.currentVideo?.title ?? ""
        //设置艺术家
        currentInfo![MPMediaItemPropertyArtist] = loadPlayer?.currentVideo?.song?.shortBylineText ?? ""
        //设置专辑
        currentInfo![MPMediaItemPropertyAlbumTitle] = loadPlayer?.currentVideo?.song?.longBylineText
        //当前时长
        currentInfo![MPNowPlayingInfoPropertyElapsedPlaybackTime] = CMTimeGetSeconds(player.currentItem?.currentTime() ?? .zero)
        //设置歌曲时长
        currentInfo![MPMediaItemPropertyPlaybackDuration] = CMTimeGetSeconds(player.currentItem?.duration ?? .zero)
        currentInfo![MPNowPlayingInfoPropertyPlaybackRate] = 1.0
        let reviewURL = URL(string: loadPlayer?.currentVideo?.song?.reviewUrls?.last ?? "")!
        KingfisherManager.shared.retrieveImage(with: reviewURL) { [weak self]result in
            switch result {
            case .success(let imageResult):
                let image = imageResult.image
                self?.currentInfo?[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: image.size, requestHandler: { size in
                        return image
                    })
                // 确保更新MPNowPlayingInfoCenter的操作在主线程中
                DispatchQueue.main.async {
                    //更新远程中心
                    MPNowPlayingInfoCenter.default().nowPlayingInfo = self?.currentInfo
                }
            case .failure(_):
                self?.currentInfo?[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: placeholderImage.size, requestHandler: { size in
                    return placeholderImage
                })
                // 确保更新MPNowPlayingInfoCenter的操作在主线程中
                DispatchQueue.main.async {
                    //更新远程中心
                    MPNowPlayingInfoCenter.default().nowPlayingInfo = self?.currentInfo
                }
            }
        }
    }

}

