我在stackoverflow上看了很多类似的问题,虽然它们很有用,但我仍然不能在当前播放的歌曲结束时自动播放下一首歌曲。因为我从位置0开始播放歌曲数组,当我递增这个位置变量时,所有的歌曲不是应该一首接一首地播放,直到我到达数组中的最后一首歌曲吗?目前,在第一首歌曲结束播放后,第二首歌曲播放,其余的不播放。所以我的代码一次只能播放两首歌曲,一首接一首。我最初在configureUI()方法中设置歌曲,并尝试在底部的AVAudioplayer委托方法中增加歌曲。我感谢任何见解。
//
// PLayerViewController.swift
// Maanso
//
//
import UIKit
import AVFoundation
class PLayerViewController: UIViewController, AVAudioPlayerDelegate {
@IBOutlet var holder: UIView!
var Git = UILabel()
var gabayArray = [Gabays]()
var currentIndex = 0
var position: Int = 0
var player: AVAudioPlayer?
//user interface elements
var coverImageView: UIImageView!
var gabayName: UILabel!
var gabyaaName: UILabel!
//buttons
var playPauseButton: UIButton!
var backButton: UIButton!
var forwardButton: UIButton!
var timer: Timer!
override func viewDidLoad() {
super.viewDidLoad()
configure()
player!.delegate = self
// configureUI()
}
override func viewWillAppear(_ animated: Bool) {
if let player = player {
// player.play()
player.prepareToPlay()
}
}
override func viewDidLayoutSubviews() {
if holder.subviews.count == 0 {
configure()
}
}
func configure() {
//set up player
let gabay = gabayArray[position]
// let urlString = Bundle.main.path(forResource: gabay.gabayName, ofType: "mp3")
let urlString = Bundle.main.path(forResource: gabay.gabayName, ofType: "mp3")
do {
try AVAudioSession.sharedInstance().setMode(.default)
try AVAudioSession.sharedInstance().setActive(true, options: .notifyOthersOnDeactivation)
guard let urlString = urlString else{return}
player = try AVAudioPlayer(contentsOf: URL(string: urlString)!)
guard let player = player else{return}
player.volume = 0.5
player.play()
}
catch{
print("error is: \(error.localizedDescription)")
}
configureUI()
}
//MARK: - actions
@objc func volumeSliderChanged(_ slider: UISlider) {
let value = slider.value
//adjust player volume
guard let player = player else{return}
player.volume = value
}
@objc func playPauseButtonTapped(_ slider: UISlider) {
guard let player = player else{return}
if player.isPlaying {
player.stop()
playPauseButton.setBackgroundImage(UIImage(systemName: "play.fill"), for: .normal)
}else{
player.play()
playPauseButton.setBackgroundImage(UIImage(systemName: "pause.fill"), for: .normal)
}
}
@objc func backButtonTapped() {
if position > 0
{
position = position - 1
player!.stop()
for subview in holder.subviews {
subview.removeFromSuperview()
}
configure()
// configureUI()
}
}
@objc func forwardButtonTapped() {
if position < gabayArray.count - 1{
position = position + 1
player!.stop()
for subview in holder.subviews {
subview.removeFromSuperview()
}
configure()
// configureUI()
}
}
@objc func seekSliderChanged(_ slider: UISlider) {
let slider = slider
// let currentTime = player!.currentTime
let duration = player!.duration
slider.maximumValue = Float(duration)
let time = duration/duration
//seeking through current gabay
player!.currentTime = TimeInterval(slider.value)
// player!.play()
Timer.scheduledTimer(withTimeInterval: Double(time), repeats: true, block: {
_ in
slider.value = Float(self.player!.currentTime)
//TRYING TO MAKE THE SLIDER BE IN SYNC WITH song
})
}
public func configureUI() {
//set up user interface
let gabay = gabayArray[position]
//set up imagecoverview
coverImageView = UIImageView()
coverImageView.contentMode = .scaleAspectFill
coverImageView.image = UIImage(named: gabay.imageName)
coverImageView.translatesAutoresizingMaskIntoConstraints = false
holder.addSubview(coverImageView)
//set up the two labels
gabayName = UILabel()
gabayName.textAlignment = .center
gabayName.numberOfLines = 0
gabayName.translatesAutoresizingMaskIntoConstraints = false
gabayName.text = gabay.gabayName
gabayName.font = UIFont(name: "helvetica", size: 20)
holder.addSubview(gabayName)
gabyaaName = UILabel()
gabyaaName.translatesAutoresizingMaskIntoConstraints = false
gabyaaName.text = gabay.gabyaaName
gabyaaName.font = UIFont(name: "helvetica", size: 18)
gabyaaName.textAlignment = .center
gabyaaName.numberOfLines = 0
holder.addSubview(gabyaaName)
//set up sliders.
let volumeSlider = UISlider()
volumeSlider.value = 0.5
volumeSlider.translatesAutoresizingMaskIntoConstraints = false
volumeSlider.addTarget(self, action: #selector(volumeSliderChanged), for: .valueChanged)
volumeSlider.layer.cornerRadius = 8
volumeSlider.isUserInteractionEnabled = true
holder.addSubview(volumeSlider)
//seek through sider
let seekSlider = UISlider()
// seekSlider.isContinuous = true
seekSlider.minimumValue = 0
// seekSlider.maximumValue = Float(player!.duration)
seekSlider.isUserInteractionEnabled = true
seekSlider.translatesAutoresizingMaskIntoConstraints = false
// seekSlider.setThumbImage(UIImage(systemName: "thumbSmall"), for: .normal)
seekSlider.setThumbImage(UIImage(named: "thumb"), for: .normal)
seekSlider.addTarget(self, action: #selector(seekSliderChanged), for: .valueChanged)
holder.addSubview(seekSlider)
//set up buttons, play button
playPauseButton = UIButton()
playPauseButton.tintColor = .black
playPauseButton.setBackgroundImage(UIImage(systemName: "pause.fill"), for: .normal)
playPauseButton.translatesAutoresizingMaskIntoConstraints = false
playPauseButton.addTarget(self, action: #selector(playPauseButtonTapped), for: .touchUpInside)
holder.addSubview(playPauseButton)
//back button
backButton = UIButton()
backButton.tintColor = .black
backButton.setBackgroundImage(UIImage(systemName: "backward.fill"), for: .normal)
backButton.translatesAutoresizingMaskIntoConstraints = false
backButton.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside)
holder.addSubview(backButton)
//forward button
forwardButton = UIButton()
forwardButton.tintColor = .black
forwardButton.setBackgroundImage(UIImage(systemName: "forward.fill"), for: .normal)
forwardButton.translatesAutoresizingMaskIntoConstraints = false
forwardButton.addTarget(self, action: #selector(forwardButtonTapped), for: .touchUpInside)
holder.addSubview(forwardButton)
//volume buttons
let rightVolButton = UIButton()
rightVolButton.translatesAutoresizingMaskIntoConstraints = false
rightVolButton.setBackgroundImage(UIImage(systemName: "volume.3.fill"), for: .normal)
holder.addSubview(rightVolButton)
//set up constraints
NSLayoutConstraint.activate([
coverImageView.topAnchor.constraint(equalTo: holder.layoutMarginsGuide.topAnchor, constant: 80),
coverImageView.leadingAnchor.constraint(equalTo: holder.layoutMarginsGuide.leadingAnchor, constant: 0),
coverImageView.trailingAnchor.constraint(equalTo: holder.layoutMarginsGuide.trailingAnchor, constant: 0),
gabayName.topAnchor.constraint(equalTo: coverImageView.bottomAnchor, constant: 100),
gabayName.centerXAnchor.constraint(equalTo: holder.centerXAnchor),
gabyaaName.topAnchor.constraint(equalTo: gabayName.bottomAnchor, constant: 15),
gabyaaName.centerXAnchor.constraint(equalTo: holder.centerXAnchor),
//seek slider
seekSlider.topAnchor.constraint(equalTo: gabyaaName.topAnchor, constant: 30),
seekSlider.centerXAnchor.constraint(equalTo: holder.centerXAnchor),
seekSlider.widthAnchor.constraint(equalTo: holder.widthAnchor, multiplier: 0.8),
//buttons
playPauseButton.topAnchor.constraint(equalTo: seekSlider.bottomAnchor, constant: 25),
playPauseButton.centerXAnchor.constraint(equalTo: holder.centerXAnchor),
playPauseButton.widthAnchor.constraint(equalToConstant: 70),
playPauseButton.heightAnchor.constraint(equalToConstant: 70),
backButton.topAnchor.constraint(equalTo: seekSlider.bottomAnchor, constant: 25),
backButton.leadingAnchor.constraint(equalTo: holder.leadingAnchor, constant: 20),
backButton.widthAnchor.constraint(equalToConstant: 70),
backButton.heightAnchor.constraint(equalToConstant: 70),
forwardButton.topAnchor.constraint(equalTo: seekSlider.bottomAnchor, constant: 25),
forwardButton.trailingAnchor.constraint(equalTo: holder.trailingAnchor, constant: -20),
forwardButton.widthAnchor.constraint(equalToConstant: 70),
forwardButton.heightAnchor.constraint(equalToConstant: 70),
//volume slider
volumeSlider.topAnchor.constraint(equalTo: playPauseButton.bottomAnchor, constant: 30),
volumeSlider.centerXAnchor.constraint(equalTo: holder.centerXAnchor),
volumeSlider.widthAnchor.constraint(equalTo: holder.widthAnchor, multiplier: 0.8),
rightVolButton.topAnchor.constraint(equalTo: playPauseButton.bottomAnchor, constant: 35),
rightVolButton.trailingAnchor.constraint(equalTo: holder.layoutMarginsGuide.trailingAnchor, constant: 0),
])
}
//MARK: - AVAudioplayer delegate
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
if flag, position < gabayArray.count - 1 {
position = position + 1
for subview in holder.subviews{
subview.removeFromSuperview()
}
configure()
}
}
override func viewWillDisappear(_ animated: Bool) {
player?.stop()
}
}
1条答案
按热度按时间b4lqfgs41#
我能够解决这个问题,只需在最初加载音乐文件后设置播放器的代理。
1.使用AVAudioPlayer委托方法跟踪当前播放的歌曲何时结束。
1.在该方法中,检查当前播放的歌曲是否不是数组中的最后一首歌曲,如果不是,则递增增量变量。
1.调用初始配置音频的方法。对我来说,它是configure()方法。加载音频文件后,不要忘记在此方法中设置音频的委托。