如何在当前播放结束时自动转到下一首曲目?
How to automatically go to the next track when the one is currently playing ends?
我是 swift 的新手,我想实现一段代码,帮助我在当前播放的歌曲结束时播放下一首歌曲。
我试图复制我的“@IBAction func nextAction”中的代码(效果很好):
@IBAction func nextAction(sender: AnyObject) {
self.nextTrack()
}
func nextTrack() {
if trackId == 0 || trackId < 4 {
if shuffle.on {
trackId = Int(arc4random_uniform(UInt32(library.count)))
}else {
trackId += 1
}
if let coverImage = library[trackId]["coverImage"]{
coverImageView.image = UIImage(named: "\(coverImage).jpg")
}
songTitleLabel.text = library[trackId]["title"]
artistLabel.text = library[trackId]["artist"]
audioPlayer.currentTime = 0
progressView.progress = 0
let path = NSBundle.mainBundle().pathForResource("\(trackId)", ofType: "mp3")
if let path = path {
let mp3URL = NSURL(fileURLWithPath: path)
do {
audioPlayer = try AVAudioPlayer(contentsOfURL: mp3URL)
audioPlayer.play()
NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(PlayerViewController.updateProgressView), userInfo: nil, repeats: true)
progressView.setProgress(Float(audioPlayer.currentTime/audioPlayer.duration), animated: false)
} catch let error as NSError {
print(error.localizedDescription)
}
}
}
}
并尝试将其放入这样的 if 条件中(在 viewDidLoad 中):
if audioPlayer.currentTime >= audioPlayer.duration {
self.nextTrack()
}
我没有任何错误,但在运行时此方法不起作用,歌曲结束而没有播放下一首。
为了让情况更清楚,这是我的控制器:
import UIKit
import AVFoundation
class PlayerViewController: UIViewController {
@IBOutlet weak var coverImageView: UIImageView!
@IBOutlet weak var progressView: UIProgressView!
@IBOutlet weak var songTitleLabel: UILabel!
@IBOutlet weak var artistLabel: UILabel!
@IBOutlet weak var shuffle: UISwitch!
var trackId: Int = 0
var library = MusicLibrary().library
var audioPlayer: AVAudioPlayer!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
if let coverImage = library[trackId]["coverImage"]{
coverImageView.image = UIImage(named: "\(coverImage).jpg")
}
songTitleLabel.text = library[trackId]["title"]
artistLabel.text = library[trackId]["artist"]
let path = NSBundle.mainBundle().pathForResource("\(trackId)", ofType: "mp3")
if let path = path {
let mp3URL = NSURL(fileURLWithPath: path)
do {
audioPlayer = try AVAudioPlayer(contentsOfURL: mp3URL)
audioPlayer.play()
NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(PlayerViewController.updateProgressView), userInfo: nil, repeats: true)
progressView.setProgress(Float(audioPlayer.currentTime/audioPlayer.duration), animated: false)
} catch let error as NSError {
print(error.localizedDescription)
}
}
}
override func viewWillDisappear(animated: Bool) {
audioPlayer.stop()
}
func updateProgressView(){
if audioPlayer.playing {
progressView.setProgress(Float(audioPlayer.currentTime/audioPlayer.duration), animated: true)
}
}
@IBAction func playAction(sender: AnyObject) {
if !audioPlayer.playing {
audioPlayer.play()
}
}
@IBAction func stopAction(sender: AnyObject) {
audioPlayer.stop()
audioPlayer.currentTime = 0
progressView.progress = 0
}
@IBAction func pauseAction(sender: AnyObject) {
audioPlayer.pause()
}
@IBAction func fastForwardAction(sender: AnyObject) {
var time: NSTimeInterval = audioPlayer.currentTime
time += 5.0
if time > audioPlayer.duration {
stopAction(self)
}else {
audioPlayer.currentTime = time
}
}
@IBAction func rewindAction(sender: AnyObject) {
var time: NSTimeInterval = audioPlayer.currentTime
time -= 5.0
if time < 0 {
stopAction(self)
}else {
audioPlayer.currentTime = time
}
}
@IBAction func previousAction(sender: AnyObject) {
if trackId != 0 || trackId > 0 {
if shuffle.on {
trackId = Int(arc4random_uniform(UInt32(library.count)))
}else {
trackId -= 1
}
if let coverImage = library[trackId]["coverImage"]{
coverImageView.image = UIImage(named: "\(coverImage).jpg")
}
songTitleLabel.text = library[trackId]["title"]
artistLabel.text = library[trackId]["artist"]
audioPlayer.currentTime = 0
progressView.progress = 0
let path = NSBundle.mainBundle().pathForResource("\(trackId)", ofType: "mp3")
if let path = path {
let mp3URL = NSURL(fileURLWithPath: path)
do {
audioPlayer = try AVAudioPlayer(contentsOfURL: mp3URL)
audioPlayer.play()
NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(PlayerViewController.updateProgressView), userInfo: nil, repeats: true)
progressView.setProgress(Float(audioPlayer.currentTime/audioPlayer.duration), animated: false)
} catch let error as NSError {
print(error.localizedDescription)
}
}
}
}
@IBAction func swipeDownAction(sender: AnyObject) {
self.close()
}
@IBAction func closeAction(sender: AnyObject) {
self.close()
}
@IBAction func nextAction(sender: AnyObject) {
self.nextTrack()
}
func close() {
self.dismissViewControllerAnimated(true, completion: nil)
}
func nextTrack() {
if trackId == 0 || trackId < 4 {
if shuffle.on {
trackId = Int(arc4random_uniform(UInt32(library.count)))
}else {
trackId += 1
}
if let coverImage = library[trackId]["coverImage"]{
coverImageView.image = UIImage(named: "\(coverImage).jpg")
}
songTitleLabel.text = library[trackId]["title"]
artistLabel.text = library[trackId]["artist"]
audioPlayer.currentTime = 0
progressView.progress = 0
let path = NSBundle.mainBundle().pathForResource("\(trackId)", ofType: "mp3")
if let path = path {
let mp3URL = NSURL(fileURLWithPath: path)
do {
audioPlayer = try AVAudioPlayer(contentsOfURL: mp3URL)
audioPlayer.play()
NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(PlayerViewController.updateProgressView), userInfo: nil, repeats: true)
progressView.setProgress(Float(audioPlayer.currentTime/audioPlayer.duration), animated: false)
} catch let error as NSError {
print(error.localizedDescription)
}
}
}
}
}
所有代码写在Xcode7.3.1
您应该使用 AVAudioPlayer
委托方法 audioPlayerDidFinishPlaying(player: AVAudioPlayer, successfully flag: Bool)
,它会在音频播放器播放完声音时调用。
像这样让你的PlayerViewController
确认AVAudioPlayerDelegate
协议:
class PlayerViewController: UIViewController, AVAudioPlayerDelegate {
确保将 self
设置为您创建的 audioPlayer 的代理,以便在 viewDidLoad
、previousAction
和 nextTrack
中执行此操作您需要添加的方法
audioPlayer.delegate = self
在这一行之后:
audioPlayer = try AVAudioPlayer(contentsOfURL: mp3URL)
现在您可以使用委托方法知道音频何时播放完毕并转到下一首曲目,只需将其添加到您的 class:
func audioPlayerDidFinishPlaying(player: AVAudioPlayer, successfully flag: Bool) {
if flag {
self.nextTrack()
} else {
// did not finish successfully
}
}
我是 swift 的新手,我想实现一段代码,帮助我在当前播放的歌曲结束时播放下一首歌曲。 我试图复制我的“@IBAction func nextAction”中的代码(效果很好):
@IBAction func nextAction(sender: AnyObject) {
self.nextTrack()
}
func nextTrack() {
if trackId == 0 || trackId < 4 {
if shuffle.on {
trackId = Int(arc4random_uniform(UInt32(library.count)))
}else {
trackId += 1
}
if let coverImage = library[trackId]["coverImage"]{
coverImageView.image = UIImage(named: "\(coverImage).jpg")
}
songTitleLabel.text = library[trackId]["title"]
artistLabel.text = library[trackId]["artist"]
audioPlayer.currentTime = 0
progressView.progress = 0
let path = NSBundle.mainBundle().pathForResource("\(trackId)", ofType: "mp3")
if let path = path {
let mp3URL = NSURL(fileURLWithPath: path)
do {
audioPlayer = try AVAudioPlayer(contentsOfURL: mp3URL)
audioPlayer.play()
NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(PlayerViewController.updateProgressView), userInfo: nil, repeats: true)
progressView.setProgress(Float(audioPlayer.currentTime/audioPlayer.duration), animated: false)
} catch let error as NSError {
print(error.localizedDescription)
}
}
}
}
并尝试将其放入这样的 if 条件中(在 viewDidLoad 中):
if audioPlayer.currentTime >= audioPlayer.duration {
self.nextTrack()
}
我没有任何错误,但在运行时此方法不起作用,歌曲结束而没有播放下一首。
为了让情况更清楚,这是我的控制器:
import UIKit
import AVFoundation
class PlayerViewController: UIViewController {
@IBOutlet weak var coverImageView: UIImageView!
@IBOutlet weak var progressView: UIProgressView!
@IBOutlet weak var songTitleLabel: UILabel!
@IBOutlet weak var artistLabel: UILabel!
@IBOutlet weak var shuffle: UISwitch!
var trackId: Int = 0
var library = MusicLibrary().library
var audioPlayer: AVAudioPlayer!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
if let coverImage = library[trackId]["coverImage"]{
coverImageView.image = UIImage(named: "\(coverImage).jpg")
}
songTitleLabel.text = library[trackId]["title"]
artistLabel.text = library[trackId]["artist"]
let path = NSBundle.mainBundle().pathForResource("\(trackId)", ofType: "mp3")
if let path = path {
let mp3URL = NSURL(fileURLWithPath: path)
do {
audioPlayer = try AVAudioPlayer(contentsOfURL: mp3URL)
audioPlayer.play()
NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(PlayerViewController.updateProgressView), userInfo: nil, repeats: true)
progressView.setProgress(Float(audioPlayer.currentTime/audioPlayer.duration), animated: false)
} catch let error as NSError {
print(error.localizedDescription)
}
}
}
override func viewWillDisappear(animated: Bool) {
audioPlayer.stop()
}
func updateProgressView(){
if audioPlayer.playing {
progressView.setProgress(Float(audioPlayer.currentTime/audioPlayer.duration), animated: true)
}
}
@IBAction func playAction(sender: AnyObject) {
if !audioPlayer.playing {
audioPlayer.play()
}
}
@IBAction func stopAction(sender: AnyObject) {
audioPlayer.stop()
audioPlayer.currentTime = 0
progressView.progress = 0
}
@IBAction func pauseAction(sender: AnyObject) {
audioPlayer.pause()
}
@IBAction func fastForwardAction(sender: AnyObject) {
var time: NSTimeInterval = audioPlayer.currentTime
time += 5.0
if time > audioPlayer.duration {
stopAction(self)
}else {
audioPlayer.currentTime = time
}
}
@IBAction func rewindAction(sender: AnyObject) {
var time: NSTimeInterval = audioPlayer.currentTime
time -= 5.0
if time < 0 {
stopAction(self)
}else {
audioPlayer.currentTime = time
}
}
@IBAction func previousAction(sender: AnyObject) {
if trackId != 0 || trackId > 0 {
if shuffle.on {
trackId = Int(arc4random_uniform(UInt32(library.count)))
}else {
trackId -= 1
}
if let coverImage = library[trackId]["coverImage"]{
coverImageView.image = UIImage(named: "\(coverImage).jpg")
}
songTitleLabel.text = library[trackId]["title"]
artistLabel.text = library[trackId]["artist"]
audioPlayer.currentTime = 0
progressView.progress = 0
let path = NSBundle.mainBundle().pathForResource("\(trackId)", ofType: "mp3")
if let path = path {
let mp3URL = NSURL(fileURLWithPath: path)
do {
audioPlayer = try AVAudioPlayer(contentsOfURL: mp3URL)
audioPlayer.play()
NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(PlayerViewController.updateProgressView), userInfo: nil, repeats: true)
progressView.setProgress(Float(audioPlayer.currentTime/audioPlayer.duration), animated: false)
} catch let error as NSError {
print(error.localizedDescription)
}
}
}
}
@IBAction func swipeDownAction(sender: AnyObject) {
self.close()
}
@IBAction func closeAction(sender: AnyObject) {
self.close()
}
@IBAction func nextAction(sender: AnyObject) {
self.nextTrack()
}
func close() {
self.dismissViewControllerAnimated(true, completion: nil)
}
func nextTrack() {
if trackId == 0 || trackId < 4 {
if shuffle.on {
trackId = Int(arc4random_uniform(UInt32(library.count)))
}else {
trackId += 1
}
if let coverImage = library[trackId]["coverImage"]{
coverImageView.image = UIImage(named: "\(coverImage).jpg")
}
songTitleLabel.text = library[trackId]["title"]
artistLabel.text = library[trackId]["artist"]
audioPlayer.currentTime = 0
progressView.progress = 0
let path = NSBundle.mainBundle().pathForResource("\(trackId)", ofType: "mp3")
if let path = path {
let mp3URL = NSURL(fileURLWithPath: path)
do {
audioPlayer = try AVAudioPlayer(contentsOfURL: mp3URL)
audioPlayer.play()
NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(PlayerViewController.updateProgressView), userInfo: nil, repeats: true)
progressView.setProgress(Float(audioPlayer.currentTime/audioPlayer.duration), animated: false)
} catch let error as NSError {
print(error.localizedDescription)
}
}
}
}
}
所有代码写在Xcode7.3.1
您应该使用 AVAudioPlayer
委托方法 audioPlayerDidFinishPlaying(player: AVAudioPlayer, successfully flag: Bool)
,它会在音频播放器播放完声音时调用。
像这样让你的
PlayerViewController
确认AVAudioPlayerDelegate
协议:class PlayerViewController: UIViewController, AVAudioPlayerDelegate {
确保将
self
设置为您创建的 audioPlayer 的代理,以便在viewDidLoad
、previousAction
和nextTrack
中执行此操作您需要添加的方法audioPlayer.delegate = self
在这一行之后:
audioPlayer = try AVAudioPlayer(contentsOfURL: mp3URL)
现在您可以使用委托方法知道音频何时播放完毕并转到下一首曲目,只需将其添加到您的 class:
func audioPlayerDidFinishPlaying(player: AVAudioPlayer, successfully flag: Bool) { if flag { self.nextTrack() } else { // did not finish successfully } }