我有一个应用程序,我想通过音乐循环。基本上播放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
}
}
答案 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()
}
}
}