简体   繁体   English

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

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

I am building a music player app meant to mimic radio or internet streaming automation.我正在构建一个音乐播放器应用程序,旨在模仿广播或互联网流媒体自动化。 I have already succeeded in pulling music from playlists and filtering by last date played so songs do not frequently repeat (a pet peeve about my iPod).我已经成功地从播放列表中提取音乐并按上次播放日期进行过滤,这样歌曲就不会经常重复(对我的 iPod 感到非常恼火)。 I want it to schedule playing short station IDs every quarter hour from a separate playlist, then return to the current playlist or switch to a new one.我希望它每一刻钟从一个单独的播放列表中安排播放短电台 ID,然后返回到当前播放列表或切换到一个新的播放列表。 The roadblocks I'm hitting are getting a repeating timer to wait until a song is over before playing an ID, and playing only one ID before switching back to music.我遇到的障碍是让重复计时器等待歌曲结束后再播放 ID,并且在切换回音乐之前只播放一个 ID。 A notification observer…通知观察者……

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

…trips a timer… ……触发计时器……

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

…that runs this function: ...运行此功能:

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

The media query that selects from the Voicers playlist…从 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()
    }

…not only interrupts a song when the timer goes off instead of using the “…NowPlayingItemDidChange” notification but also keeps playing instead returning to the function listed at bottom after one play, because I cannot land on any method for isolating the first item in the voiceCollection array. …不仅在计时器关闭时中断一首歌而不是使用“…NowPlayingItemDidChange”通知,而且还在继续播放而不是在一次播放后返回底部列出的函数,因为我无法找到任何方法来隔离第一个项目语音集合数组。

Update: It didn't take long to realize the timer approach was never happening.更新:没过多久就意识到计时器方法从未发生过。 The inherent latency of switching playlists on the fly meant hearing a second or two of the next song before the ID got going.动态切换播放列表的固有延迟意味着在 ID 开始之前听下一首歌曲的一两秒钟。 After a few days of research, I achieved a breakthrough in a Playground of iterating through two arrays and inserting items from one into the other at regular intervals.经过几天的研究,我在 Playground 中取得了突破,即遍历两个数组并定期将项目从一个数组插入另一个数组。 So after rewriting the function to call up both playlists, and shuffling, sorting, and filtering the resulting arrays as needed, this loop placed IDs after every 3 songs…因此,在重写函数以调用两个播放列表,并根据需要对结果数组进行混洗、排序和过滤后,此循环在每 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
}

Now it runs exactly as I want.现在它完全按照我的意愿运行。 The one remaining issue is to make certain I have at least 3 times as many available songs as IDs, or I get an out of range error, but that's easily avoided.剩下的一个问题是确保我的可用歌曲数量至少是 ID 的 3 倍,否则我会遇到超出范围的错误,但这很容易避免。 Just wanted to put this out there in case anyone else finds it useful, as there seemed to be no examples of it I could find anywhere else.只是想把它放在那里,以防其他人发现它有用,因为我似乎在其他任何地方都找不到它的例子。 Cheers…干杯…

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

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