Music_Player3/relax.offline.mp3.music/MP/MPPositive/Models/ViewModels/LoadViewModels/MPPositive_PlayerLoadViewModel.swift

202 lines
8.9 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_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{
DispatchQueue.main.asyncAfter(deadline: .now()) {
[weak self] in
guard let self = self else {return}
if newValue != nil {
MP_AnalyticsManager.shared.player_b_pvAction(newValue.song.videoId, videoname: newValue.title ?? "", artistname: newValue.song.shortBylineText ?? "")
if currentVideo != nil {
//UI
NotificationCenter.notificationKey.post(notificationName: .positive_player_reload, object: currentVideo)
}else {
//UI
NotificationCenter.notificationKey.post(notificationName: .positive_player_reload)
}
}
}
}
}
///ViewModel
var listViewVideos:[MPPositive_SongViewModel]!
///
var group:DispatchGroup?
///palyermodel
/// - Parameters:
/// - songs:
/// - firstVideoId:
init(_ songs:[MPPositive_SongItemModel], currentVideoId: String) {
super.init()
self.songVideos = songs
//
self.randomVideos = self.songVideos.shuffled()
self.listViewVideos = []
}
///Video14VideoViewModel,
func improveData(_ targetVideoId:String, isRandom:Bool = false) {
//Video
var array:[MPPositive_SongItemModel] = []
if isRandom {
//targetVideoId
guard let targetIndex = self.randomVideos.firstIndex(where: {$0.videoId == targetVideoId}) else {
return
}
array.append(self.randomVideos[targetIndex])
//
let previousIndex = targetIndex-1
if previousIndex >= 0 {
array.append(self.randomVideos[previousIndex])
}
let nextIndex = targetIndex+1
let lastIndex = targetIndex+2
if nextIndex < randomVideos.count {
array.append(self.randomVideos[nextIndex])
}
if lastIndex < randomVideos.count {
array.append(self.randomVideos[lastIndex])
}
}else {
//targetVideoId
guard let targetIndex = self.songVideos.firstIndex(where: {$0.videoId == targetVideoId}) else {
return
}
array.append(self.songVideos[targetIndex])
//
let previousIndex = targetIndex-1
if previousIndex >= 0 {
array.append(self.songVideos[previousIndex])
}
let nextIndex = targetIndex+1
let lastIndex = targetIndex+2
if nextIndex < songVideos.count {
array.append(self.songVideos[nextIndex])
}
if lastIndex < songVideos.count {
array.append(self.songVideos[lastIndex])
}
}
//ViewModelvideo
let videoIDs = Set(listViewVideos.map({$0.song.videoId}))
//videoID,
array = array.filter({!videoIDs.contains($0.videoId)})
group = DispatchGroup()
//,
for item in array {
group?.enter()
//idid
if item.lyricsID == nil || item.relatedID == nil {
improveDataforLycirsAndRelated(item) {[weak self] (result) in
item.lyricsID = result.0
item.relatedID = result.1
self?.group?.leave()
}
}else {
self.group?.leave()
}
group?.enter()
//videoID
if let resource = getDocumentsFileURL(item.videoId) {
//resource
item.resourceUrls = [resource]
//,ViewModellistViewVideos
listViewVideos.append(.init(item))
self.group?.leave()
}else {
//
//
improveDataforResouceAndCover(item) {[weak self] resourceUrls, coverUrls in
if let resourceUrls = resourceUrls {
item.resourceUrls = resourceUrls.0
item.itags = resourceUrls.1
item.mimeTypes = resourceUrls.2
}
item.coverUrls = coverUrls
//,ViewModellistViewVideos
self?.listViewVideos.append(.init(item))
self?.group?.leave()
}
}
}
group?.notify(queue: .main, execute: {
[weak self] in
//
self?.currentVideo = self?.listViewVideos.first(where: {$0.song.videoId == targetVideoId})
//
self?.listViewVideos = self?.listViewVideos.suffix(4)
self?.group = nil
})
}
///
func remakeImproveData(_ completion:@escaping (() -> Void)) {
//
improveDataforResouceAndCover(currentVideo.song) {[weak self] resourceUrls, coverUrls in
guard let self = self else {return}
if let resourceUrls = resourceUrls {
currentVideo.song.resourceUrls = resourceUrls.0
currentVideo.song.itags = resourceUrls.1
currentVideo.song.mimeTypes = resourceUrls.2
}
//listViewVideos
listViewVideos.forEach({ item in
if item.song.videoId == self.currentVideo.song.videoId {
item.song.resourceUrls = self.currentVideo.song.resourceUrls
item.song.itags = self.currentVideo.song.itags
item.song.mimeTypes = self.currentVideo.song.mimeTypes
}
})
// currentVideo.resourceAsset = .init(url: .init(string: currentVideo.song.resourceUrls!.first!)!)
// currentVideo.resourcePlayerItem = .init(asset: currentVideo.resourceAsset!)
// currentVideo.resourcePlayerItem = .init(url: .init(string: (currentVideo.song.resourceUrls?.first ?? ""))!, bitrate: Int64(currentVideo.song.bitrates?.first ?? 0), title: currentVideo.title, videoId: currentVideo.song.videoId)
currentVideo.configure()
//UI
NotificationCenter.notificationKey.post(notificationName: .positive_player_reload)
completion()
}
}
///songlistViewVideosindex
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)
}
}
}
}
//videoId
private func findVideoIdForDocument(_ videoId:String) -> Bool {
return MPPositive_DownloadItemModel.fetch(.init(format: "videoId == %@", videoId)).count != 0
}
}