0

我正在构建一个音乐播放器应用程序,旨在模仿广播或互联网流媒体自动化。我已经成功地从播放列表中提取音乐并按最后播放日期进行过滤,因此歌曲不会经常重复(我的 iPod 的一个小问题)。我希望它安排每一刻钟从单独的播放列表播放短站 ID,然后返回当前播放列表或切换到新播放列表。我遇到的障碍是让一个重复计时器等到一首歌结束后再播放一个 ID,并在切换回音乐之前只播放一个 ID。通知观察者……</p>

NotificationCenter.default.addObserver(self, selector:#selector(ViewController.quarterHour), name: NSNotification.Name.MPMusicPlayerControllerNowPlayingItemDidChange, object: nil)

…触发计时器…</p>

self.timer2 = Timer(fireAt: date, interval: 1, target: self, selector: #selector(ViewController.runVoicer(_:)), userInfo: nil, repeats: true)
self.timer2.tolerance = 0.1
        

…运行这个函数:

    @objc func quarterHour() {
        self.timer2 = Timer.scheduledTimer(timeInterval: 900, target: self, selector: #selector(ViewController.runVoicer(_:)), userInfo: nil, repeats: true)
        self.timer2.tolerance = 0.1
        }

从 Voicers 播放列表中选择的媒体查询…</p>

    @objc func runVoicer(_:AnyObject) {
        mp.pause()
        let queryVoice = MPMediaQuery.songs()
        let predicate = MPMediaPropertyPredicate(value: "Voicers",
                                                forProperty: MPMediaPlaylistPropertyName,
                                                comparisonType: .equalTo)
        queryVoice.addFilterPredicate(predicate)
        var collection = [MPMediaItem]()
        let unixDefault = Date(timeIntervalSince1970: 100)
        if let voicers = queryVoice.items {
            collection = voicers.sorted{$0.lastPlayedDate ?? unixDefault > $1.lastPlayedDate ?? unixDate}
        }
        let voiceCollection = MPMediaItemCollection(items: collection)
        mp.setQueue(with: voiceCollection)
            mp.play()
        fetchRockPlaylist()
    }

…不仅在计时器关闭而不是使用“…NowPlayingItemDidChange”通知时中断歌曲,而且在一次播放后继续播放而不是返回到底部列出的函数,因为我无法找到任何方法来隔离第一个项目语音集合数组。

4

1 回答 1

1

更新:没过多久就意识到计时器方法从未发生过。动态切换播放列表的固有延迟意味着在 ID 启动之前听到下一首或两首歌曲。经过几天的研究,我在 Playground 中取得了突破,即迭代两个数组并定期将项目从一个数组插入另一个数组。因此,在重写函数以调用两个播放列表,并根据需要对结果数组进行混洗、排序和过滤之后,此循环在每 3 首歌曲之后放置 ID……</p>

let arrayCount = voiceCollection.count
var interR = 0
var indexV = 0
// for loop iterates through rock collection by 3, inserts item from voice collection
    for i in 0..<arrayCount {
       rockSet.insert(voiceCollection[indexV], at:interR)
       interR += 4
       indexV += 1
}

现在它完全按照我的意愿运行。剩下的一个问题是确保我的可用歌曲数量至少是 ID 的 3 倍,否则我会收到超出范围的错误,但这很容易避免。只是想把它放在那里,以防其他人觉得它有用,因为我在其他任何地方似乎都找不到它的例子。干杯……</p>

于 2020-11-27T22:27:47.213 回答