繁体   English   中英

在 Swift iOS MPMediaPlayer 应用程序中切换播放列表和设置计时器的问题

[英]Problems switching between playlists and setting timers in Swift iOS MPMediaPlayer app

我正在构建一个音乐播放器应用程序,旨在模仿广播或互联网流媒体自动化。 我已经成功地从播放列表中提取音乐并按上次播放日期进行过滤,这样歌曲就不会经常重复(对我的 iPod 感到非常恼火)。 我希望它每一刻钟从一个单独的播放列表中安排播放短电台 ID,然后返回到当前播放列表或切换到一个新的播放列表。 我遇到的障碍是让重复计时器等待歌曲结束后再播放 ID,并且在切换回音乐之前只播放一个 ID。 通知观察者……

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

……触发计时器……

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 播放列表中选择的媒体查询...

    @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”通知,而且还在继续播放而不是在一次播放后返回底部列出的函数,因为我无法找到任何方法来隔离第一个项目语音集合数组。

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

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 倍,否则我会遇到超出范围的错误,但这很容易避免。 只是想把它放在那里,以防其他人发现它有用,因为我似乎在其他任何地方都找不到它的例子。 干杯…

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM