2017-08-07 19 views
1

我有一个tableview,并在tableView中有多个单元格。
每个单元格都有一个AVAudioPlayer项目
而我面临一个问题。
我不知道如何管理AVAudioPlayer。
当我播放第一个AVAudioPlayer,然后播放第二个AVAudioPlayer时,声音会重叠。
如何在我的自定义单元格中停止第一个AVAudioPlayer并播放第二个AVAudioPlayer?
谢谢。
如何管理AVAudioPlayer isPlaying在每个tableviewCell中?

这是我的自定义单元格:

class TableViewCell: UITableViewCell { 

@IBOutlet weak var myImageView: UIImageView! 
@IBOutlet weak var myChatBubbleView: UIView! 
@IBOutlet weak var myDateLabel: UILabel! 
@IBOutlet weak var mySecondLabel: UILabel! 
@IBOutlet weak var myRecordPlayerBtn: MenuButton! 
private var timer:Timer? 
private var elapsedTimeInSecond:Int = 0 
var audioPlayer:AVAudioPlayer? 
var message:ChatroomMessage? 
var chatroomId:String = "" 
var delegate:PlayRecordDelegate? 

override func awakeFromNib() { 
    super.awakeFromNib() 
    // Initialization code 

    self.backgroundColor = defaultBackgroundColor 
    self.tintColor = defaultChatroomCheckButtonColor 

    myImageView.layer.masksToBounds = true 
    myImageView.layer.cornerRadius = defaultIconRadius 

    myChatBubbleView.backgroundColor = defaultChatGreenBubbleColor 
    myChatBubbleView.layer.cornerRadius = defaultButtonRadius 

    myDateLabel.textColor = defaultChatTimeColor 

    mySecondLabel.textColor = defaultChatTimeColor 
    mySecondLabel.isHidden = true 

    myRecordPlayerBtn.imageView?.animationDuration = 1 
    myRecordPlayerBtn.imageView?.animationImages = [ 
    UIImage(named: "img_myRocordPlaying1")!, 
    UIImage(named: "img_myRocordPlaying2")!, 
    UIImage(named: "img_myRocordPlaying3")! 
    ] 
} 

override func setSelected(_ selected: Bool, animated: Bool) { 
    super.setSelected(selected, animated: animated) 

    // Configure the view for the selected state 
} 

func loadByMessage(_ message:ChatroomMessage, chatroomId:String) { 
    self.message = message 
    self.chatroomId = chatroomId 

    myRecordPlayerBtn.addTarget(self, action: #selector(recordPlay), for: .touchUpInside) 
} 

func resetRecordAnimation() { 
    self.myRecordPlayerBtn.imageView!.stopAnimating() 
    self.myRecordPlayerBtn.isSelected = false 
} 

func recordPlay(_ sender: UIButton) { 

    self.myRecordPlayerBtn.imageView?.startAnimating() 

    let documentsDirectoryURL = try! FileManager().url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent("\(chatroomId)/Record/") 

    let fileName = message?.content.substring(from: 62) 
    let fileURL = documentsDirectoryURL.appendingPathComponent(fileName!) 
    if FileManager.default.fileExists(atPath: fileURL.path) { 

     let asset = AVURLAsset(url: URL(fileURLWithPath: fileURL.path), options: nil) 
     let audioDuration = asset.duration 
     let audioDurationSeconds = CMTimeGetSeconds(audioDuration) 
     self.elapsedTimeInSecond = Int(audioDurationSeconds) 

     if audioPlayer?.isPlaying == true { 

      audioPlayer?.stop() 

      DispatchQueue.main.async { 
       self.resetTimer(second: self.elapsedTimeInSecond) 
       self.startTimer() 
      } 

     } 

     updateTimeLabel() 
     startTimer() 

     audioPlayer = try? AVAudioPlayer(contentsOf: fileURL) 
     audioPlayer?.delegate = self 
     audioPlayer?.play() 

    }else{ 
     //don't have file in local 
     let recordUrl = URL(string: (message?.content)!) 
     URLSession.shared.downloadTask(with: recordUrl!, completionHandler: { (location, response, error) in 

      guard 
       let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200, 
       let mimeType = response?.mimeType, mimeType.hasPrefix("audio"), 
       let location = location, error == nil 
       else { return } 
      do { 
       try FileManager.default.moveItem(at: location, to: fileURL) 

       let asset = AVURLAsset(url: URL(fileURLWithPath: fileURL.path), options: nil) 
       let audioDuration = asset.duration 
       let audioDurationSeconds = CMTimeGetSeconds(audioDuration) 

       self.elapsedTimeInSecond = Int(audioDurationSeconds) 

       DispatchQueue.main.async { 
        self.updateTimeLabel() 
        self.startTimer() 
       } 

       self.audioPlayer = try? AVAudioPlayer(contentsOf: fileURL) 
       self.audioPlayer?.delegate = self 
       self.audioPlayer?.play() 

      } catch { 
       print(error) 
      } 
     }).resume() 
    } 
} 

func startTimer() { 

    timer?.invalidate() 
    timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { (timer) in 
     self.elapsedTimeInSecond -= 1 
     self.updateTimeLabel() 
    }) 
} 

func resetTimer(second:Int) { 
    timer?.invalidate() 
    elapsedTimeInSecond = second 
    updateTimeLabel() 
} 

func updateTimeLabel() { 

    let seconds = elapsedTimeInSecond % 60 
    let minutes = (elapsedTimeInSecond/60) % 60 

    mySecondLabel.isHidden = false 
    mySecondLabel.text = String(format: "%02d:%02d", minutes,seconds) 
} 
} 

extension TableViewCell:AVAudioPlayerDelegate { 

func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) { 

    let documentsDirectoryURL = try! FileManager().url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent("\(Id)/Record/") 
    let fileName = message?.content.substring(from: 62) 
    let fileURL = documentsDirectoryURL.appendingPathComponent(fileName!) 

    if FileManager.default.fileExists(atPath: fileURL.path) { 

     let asset = AVURLAsset(url: URL(fileURLWithPath: fileURL.path), options: nil) 
     let audioDuration = asset.duration 
     let audioDurationSeconds = CMTimeGetSeconds(audioDuration) 

     DispatchQueue.main.async { 
      self.resetTimer(second: Int(audioDurationSeconds)) 
      self.myRecordPlayerBtn.imageView!.stopAnimating() 
      self.myRecordPlayerBtn.imageView?.image = #imageLiteral(resourceName: "img_myRocordDefault") 
     } 
    } 
} 
} 

回答

0

可能首先初始化检查,如果您的播放器播放

if audioPlayer != nil{ 
      if audioPlayer?.isPlaying == true { 

       audioPlayer?.stop() 

       DispatchQueue.main.async { 
        self.resetTimer(second: self.elapsedTimeInSecond) 
        self.startTimer() 
       } 

      } 
     } 
+0

但如何管理不同细胞的audioPlayer并使它停止?这是在一个单元格中工作,并重复相同的点击。当我点击其他单元格时,这不起作用。声音会重叠。 –

+0

是否有任何特定的原因在tableViewCell类中做audioPlayer的东西?如果你想使用这种方法,在视图控制器中初始化一个audioPlayer并传递一个对tableviewcell的引用就会更好。另一种方法是将其从tableViewCell中完全取出并带入控制器。在那里你只有一个audioPlayer实例,你可以随心所欲地停下来玩,而不会产生声音重叠的问题。 –

0

如果你不希望在同一时间打两个音轨,你应该使用一个共享实例AVAudioPlayer 这对性能会更好,你可以在你的控制器中将实例定义为static var。它将在每个单元中访问。

0

我已经开发出一种音乐在线播放应用程序,我用在MusicPlayManager共享实例:

class MusicPlayManager{ 

    var player : AVAudioPlayer? 

    static let sharedInstance = MusicPlayManager.init() 

    private override init() { 
     super.init() 

    } 

// something else, such as palyNext, playPrevious methods 
} 

在你的viewController,您可以使用MusicPlayManager.sharedInstance.player

相关问题