通过音乐循环

时间:2016-03-17 08:49:47

标签: swift

我有一个应用程序,我想通过音乐循环。基本上播放15秒的歌曲然后转到下一首歌。

我有一个struct(MusicLibrary),它包含一系列歌曲信息(一个名为SongItem的结构),包括iPhone上歌曲的persistentID。如果我只打印出它工作的歌曲的名称,这个结构是完美的。 (结尾在这篇文章的底部)

然后我有一个函数(playTheSong),它使用存储在歌曲对象中的persistentID和MPMusicPlayerController - MediaPlayer库的一部分。

当按下按钮时,第一首歌曲开始播放时会发生什么。 所有歌曲的持久性ID都打印到调试器输出,我不知道为什么。 15秒后第一首歌停止 - 我添加了这个计时器,然后转到下一首歌,但我在这里做的任何事情都不起作用。我认为这是因为歌曲结构的循环立即执行,这是我的问题。

我知道我在做一些非常愚蠢的事情,但不能指责它。

注意:这只适用于手机,因为模拟器没有音乐库。

这是我的ViewController。

import UIKit
import MediaPlayer

class RunningMusicViewController: UIViewController {
    var myMusic = MusicLibrary()

    let myMusicPlayer = MPMusicPlayerController()

    var timer: Int = 15
    var clock = NSTimer()

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func startMusicButton(sender: AnyObject) {

        // Get first song of our quiz and play it - Use the persistent ID.
        let songs = myMusic.getSongs()
        let totalSongs = songs.count

        clock = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "countdown", userInfo: nil, repeats: true)

        for index in 0..<totalSongs {

            playTheSong(songs, index: index)


        }

    }


    func playTheSong(songsInQuiz: [SongItem], index:Int) {
        let songToPlay: SongItem = songsInQuiz[index]
        print("Song ID=" + String(songToPlay.persistentID))
        let predicate = MPMediaPropertyPredicate(value: Int(songToPlay.persistentID), forProperty: MPMediaItemPropertyPersistentID)
        let songQuery = MPMediaQuery()
        songQuery.addFilterPredicate(predicate)
        myMusicPlayer.setQueueWithItemCollection(songQuery.collections![0])
        myMusicPlayer.play()
    }

    func countdown() {
        timer--
        // When the countdown hits zero we should stop the song.
        if timer==0 {
            myMusicPlayer.stop()
            clock.invalidate()
            timer = 15
        }

    }

}

这是MusicLibrary结构。

import Foundation
import MediaPlayer

struct MusicLibrary {
    var musicLibrary: [SongItem] = []

    let query = MPMediaQuery.songsQuery()
    var mediaCollection : MPMediaItemCollection {
        return MPMediaItemCollection(items: query.items!)
    }

    mutating func addSongs() {
        for index in 0..<mediaCollection.count {
            let mediaItem = mediaCollection.items[index]
            let songItem = SongItem(
                title: mediaItem.title!,
                album: mediaItem.albumTitle!,
                artist: mediaItem.artist!,
                artwork: mediaItem.artwork!,
                persistentID: mediaItem.persistentID,
                genre: mediaItem.genre!
            )

            musicLibrary.append(songItem)
        }
    }

    func getSong(index: Int)->SongItem {
        return musicLibrary[index]
    }

    func getSongs()->[SongItem] {
        return musicLibrary
    }

}

SongItem Struct

import Foundation
import MediaPlayer

struct SongItem {
    var title: String
    var album: String
    var artist: String
    var artwork: MPMediaItemArtwork
    var persistentID: UInt64
    var genre: String

    init(title: String, album: String, artist: String, artwork: MPMediaItemArtwork, persistentID: UInt64, genre: String) {
        self.title = title
        self.album = album
        self.artist = artist
        self.artwork = artwork
        self.persistentID = persistentID
        self.genre = genre
    }

}   

1 个答案:

答案 0 :(得分:1)

我会将视图控制器改为以下几行:

import UIKit
import MediaPlayer

class RunningMusicViewController: UIViewController {
    var index = 0
    var timer: NSTimer

    let myMusic = MusicLibrary()
    let myMusicPlayer = MPMusicPlayerController()
    let numSecondsToPlay = 15.0
    let songs = myMusic.getSongs()

    @IBAction func startMusicButton(sender: AnyObject) {
        playTheSong(index: 0)
        timer = NSTimer.scheduledTimerWithTimeInterval(numSecondsToPlay, target: self, selector: "playNextSong", userInfo: nil, repeats: true)
    }


    func playTheSong(index: Int) {
        let songToPlay: SongItem = songs[index]
        print("Song ID=" + String(songToPlay.persistentID))
        let predicate = MPMediaPropertyPredicate(value: Int(songToPlay.persistentID), forProperty: MPMediaItemPropertyPersistentID)
        let songQuery = MPMediaQuery()
        songQuery.addFilterPredicate(predicate)
        myMusicPlayer.setQueueWithItemCollection(songQuery.collections![0])
        myMusicPlayer.play()
    }

    func playNextSong() {
        myMusicPlayer.stop()
        if index < songs.count {
            playTheSong(index: index)
            index += 1
        }
        else {
            timer.invalidate()
        }
    }
}