138 lines
5.5 KiB
Swift
138 lines
5.5 KiB
Swift
//
|
||
// MPPositive_PlayerLoadViewModel.swift
|
||
// MusicPlayer
|
||
//
|
||
// Created by Mr.Zhou on 2024/5/9.
|
||
//
|
||
|
||
import UIKit
|
||
///播放器管理ViewModel
|
||
class MPPositive_PlayerLoadViewModel: NSObject {
|
||
/// 单曲列表
|
||
var songVideos:[MPPositive_SongItemModel]!
|
||
///当前播放音乐ViewModel
|
||
var currentVideo:MPPositive_SongViewModel!{
|
||
didSet{
|
||
if currentVideo != nil {
|
||
//当值变化时通知播放器页面,更新UI
|
||
NotificationCenter.notificationKey.post(notificationName: .positive_player_reload)
|
||
}
|
||
}
|
||
}
|
||
///当前播放音乐ID
|
||
var currentVideoId:String!
|
||
///单曲ViewModel列表
|
||
var listViewVideos:[MPPositive_SongViewModel]!
|
||
///异步请求组
|
||
var group:DispatchGroup?
|
||
///palyer管理model初始化方法
|
||
/// - Parameters:
|
||
/// - songs: 全部歌曲列表
|
||
/// - firstVideoId: 需要播放的第一首歌
|
||
init(_ songs:[MPPositive_SongItemModel], currentVideoId: String) {
|
||
super.init()
|
||
//清空数据
|
||
self.songVideos = songs
|
||
self.listViewVideos = []
|
||
self.currentVideoId = currentVideoId
|
||
}
|
||
|
||
///将选中Video的上下2项包括本身总计3项Video进行补全转为ViewModel,并播放这首音乐
|
||
func improveData(_ targetVideoId:String) {
|
||
guard let targetVideo = self.songVideos.first(where: {$0.videoId == targetVideoId}) else {
|
||
return
|
||
}
|
||
//对于选中Video的集合
|
||
var array:[MPPositive_SongItemModel] = []
|
||
//获取上一位
|
||
if let previous = self.songVideos.first(where: {$0.index == (targetVideo.index-1)}) {
|
||
array.append(previous)
|
||
}
|
||
array.append(targetVideo)
|
||
//获取下一位
|
||
if let next = self.songVideos.first(where: {$0.index == (targetVideo.index+1)}) {
|
||
array.append(next)
|
||
}
|
||
//获取完成,优先检索ViewModel,看看是否已存在补完video
|
||
let videoIDs = Set(listViewVideos.map({$0.song.videoId}))
|
||
//比较videoID,去掉已经补完的内容
|
||
array = array.filter({!videoIDs.contains($0.videoId)})
|
||
group = DispatchGroup()
|
||
//去重完毕,对剩下内容补完
|
||
array.forEach { item in
|
||
group?.enter()
|
||
//补全歌词id和相关内容id
|
||
improveDataforLycirsAndRelated(item) {[weak self] (result) in
|
||
item.lyricsID = result.0
|
||
item.relatedID = result.1
|
||
self?.group?.leave()
|
||
}
|
||
group?.enter()
|
||
//补全资源路径组和封面路径组
|
||
improveDataforResouceAndCover(item) {[weak self] resourceUrls, coverUrls in
|
||
item.resourceUrls = resourceUrls
|
||
item.coverUrls = coverUrls
|
||
//补全完成,转化为ViewModel,并添加进listViewVideos
|
||
self?.listViewVideos.append(.init(item))
|
||
self?.group?.leave()
|
||
}
|
||
}
|
||
group?.notify(queue: .main, execute: {
|
||
//补完转化完毕,重新排序
|
||
self.listViewVideos = self.listViewVideos.sorted(by: {$0.index < $1.index})
|
||
//排序完成,确定播放音乐
|
||
self.currentVideo = self.listViewVideos.first(where: {$0.song.videoId == targetVideoId})
|
||
|
||
})
|
||
}
|
||
///移除选中的song,并更新listViewVideos,移除相同index的值
|
||
func removeData(_ targetVideoId:String) {
|
||
let targetIndex = songVideos.firstIndex(where: {$0.videoId == targetVideoId})
|
||
//将选中的音乐移除,同时更新listView
|
||
songVideos = songVideos.filter({$0.videoId != targetVideoId})
|
||
listViewVideos = listViewVideos.filter({$0.song.videoId != targetVideoId})
|
||
//更新下标/索引
|
||
for (index, item) in songVideos.enumerated() {
|
||
item.index = index
|
||
}
|
||
listViewVideos.forEach { listModel in
|
||
songVideos.forEach { song in
|
||
if listModel.song.videoId == song.videoId {
|
||
listModel.index = song.index
|
||
listModel.song.index = song.index
|
||
}
|
||
if currentVideo.song.videoId == song.videoId {
|
||
currentVideo.index = song.index
|
||
currentVideo.song.index = song.index
|
||
}
|
||
}
|
||
}
|
||
|
||
//判断是否当前音乐
|
||
if currentVideo.song.videoId == targetVideoId {
|
||
if let videoId = songVideos.first(where: {$0.index == targetIndex})?.videoId {
|
||
//更新当前音乐
|
||
improveData(videoId)
|
||
}else {
|
||
//移除的是原来最后一首音乐,播放新的最后一首音乐
|
||
let videoId = songVideos.last?.videoId ?? ""
|
||
improveData(videoId)
|
||
}
|
||
}
|
||
}
|
||
///调用next对单曲数据歌词ID与相关ID补全
|
||
private func improveDataforLycirsAndRelated(_ song:MPPositive_SongItemModel, completion:@escaping(((String?,String?)) -> Void)) {
|
||
//单曲补全需要再次调用next接口
|
||
MP_NetWorkManager.shared.requestNextLyricsAndRelated(song){ result in
|
||
completion(result)
|
||
}
|
||
}
|
||
///调用player对资源路径和封面路径补全
|
||
private func improveDataforResouceAndCover(_ song:MPPositive_SongItemModel, completion:@escaping(([String]?, [String]?) -> Void)) {
|
||
//单曲补全需要调用player接口
|
||
MP_NetWorkManager.shared.requestPlayer(song) { resourceUrls, coverUrls in
|
||
completion(resourceUrls,coverUrls)
|
||
}
|
||
}
|
||
}
|