158 lines
6.9 KiB
Swift
158 lines
6.9 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]!
|
||
///随机播放列表
|
||
var randomVideos:[MPPositive_SongItemModel]!
|
||
///当前播放音乐ViewModel
|
||
var currentVideo:MPPositive_SongViewModel!{
|
||
willSet{
|
||
if newValue != nil {
|
||
if currentVideo != nil {
|
||
//当值变化时通知播放器页面,更新UI
|
||
NotificationCenter.notificationKey.post(notificationName: .positive_player_reload, object: currentVideo)
|
||
}else {
|
||
//当值变化时通知播放器页面,更新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.randomVideos = self.songVideos.shuffled()
|
||
self.listViewVideos = []
|
||
self.currentVideoId = currentVideoId
|
||
}
|
||
|
||
///将选中Video的上下2项包括本身总计3项Video进行补全转为ViewModel,并播放这首音乐
|
||
func improveData(_ targetVideoId:String) {
|
||
//获取targetVideoId的索引
|
||
guard let targetIndex = self.songVideos.firstIndex(where: {$0.videoId == targetVideoId}) else {
|
||
return
|
||
}
|
||
//对于选中Video的集合
|
||
var array:[MPPositive_SongItemModel] = []
|
||
array.append(self.songVideos[targetIndex])
|
||
//获取上一位
|
||
let previousIndex = targetIndex-1
|
||
if previousIndex >= 0 {
|
||
array.append(self.songVideos[previousIndex])
|
||
}
|
||
let nextIndex = targetIndex+1
|
||
if nextIndex < songVideos.count {
|
||
array.append(self.songVideos[nextIndex])
|
||
}
|
||
//获取完成,优先检索ViewModel,看看是否已存在补完video
|
||
let videoIDs = Set(listViewVideos.map({$0.song.videoId}))
|
||
//比较videoID,去掉已经补完的内容
|
||
array = array.filter({!videoIDs.contains($0.videoId)})
|
||
group = DispatchGroup()
|
||
//去重完毕,对剩下内容补完
|
||
for item in array {
|
||
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.1
|
||
item.audioUrls = resourceUrls.0
|
||
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})
|
||
self.group = nil
|
||
})
|
||
}
|
||
///重新获取指定歌曲资源
|
||
func remakeImproveData(_ completion:@escaping (() -> Void)) {
|
||
//当前歌曲不能播放,需要重新配置资源
|
||
improveDataforResouceAndCover(currentVideo.song) {[weak self] resourceUrls, coverUrls in
|
||
guard let self = self else {return}
|
||
currentVideo.song.resourceUrls = resourceUrls.1
|
||
currentVideo.song.audioUrls = resourceUrls.0
|
||
//成功更新资源,将重新补完的歌曲,放进listViewVideos中
|
||
listViewVideos.forEach({ item in
|
||
if item.song.videoId == self.currentVideo.song.videoId {
|
||
item.song.resourceUrls = self.currentVideo.song.resourceUrls
|
||
item.song.audioUrls = self.currentVideo.song.audioUrls
|
||
}
|
||
})
|
||
currentVideo.resourceAsset = .init(url: .init(string: currentVideo.song.resourceUrls!.first!)!)
|
||
currentVideo.resourcePlayerItem = .init(asset: currentVideo.resourceAsset!)
|
||
//当值变化时通知播放器页面,更新UI
|
||
NotificationCenter.notificationKey.post(notificationName: .positive_player_reload)
|
||
completion()
|
||
}
|
||
}
|
||
|
||
///移除选中的song,并更新listViewVideos,移除相同index的值
|
||
func removeData(_ targetVideoId:String) {
|
||
let targetIndex = songVideos.firstIndex(where: {$0.videoId == targetVideoId}) ?? 0
|
||
//将选中的音乐移除,同时更新listView
|
||
songVideos = songVideos.filter({$0.videoId != targetVideoId})
|
||
randomVideos = randomVideos.filter({$0.videoId != targetVideoId})
|
||
listViewVideos = listViewVideos.filter({$0.song.videoId != targetVideoId})
|
||
if currentVideo != nil {
|
||
//判断是否当前音乐
|
||
if currentVideo.song.videoId == targetVideoId {
|
||
//判断targetIndex是否大于最大音乐值
|
||
if targetIndex < songVideos.count {
|
||
let videoId = songVideos[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]), [String]?) -> Void)) {
|
||
//单曲补全需要调用player接口
|
||
MP_NetWorkManager.shared.requestPlayer(song) { resourceUrls, coverUrls in
|
||
completion(resourceUrls,coverUrls)
|
||
}
|
||
}
|
||
}
|