2017-08-07 6 views
1

私はtableviewを持っていて、tableViewに複数のセルを持っています。
各セルにAVAudioPlayerの項目があります
そして、私は問題に直面しています。
AVAudioPlayerの管理方法がわかりません。
最初のAVAudioPlayerを再生してから、2番目のAVAudioPlayerを再生すると、サウンドが重なります。
カスタマイズしたセルで最初のAVAudioPlayerを停止し、2番目のAVAudioPlayerを再生するにはどうすればよいですか?
ありがとうございます。
各tableviewCellでAVAudioPlayerのisPlayingを管理するにはどうすればよいですか?

これは私のカスタマイズされた細胞である:

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にを使用して、それを作ることができますやめる?これは1つのセルで動作し、同じクリックを繰り返します。他のセルをクリックすると、これは機能しません。音が重なります。 –

+0

tableViewCellクラス内でaudioPlayerのことを行う特別な理由はありますか?このアプローチを使用する場合は、View Controllerで1つのaudioPlayerを初期化し、tableviewcellへの参照を渡す方が良いでしょう。もう1つの方法は、これをtableViewCellから完全に取り出して、コントローラに持っていくことです。そこには、サウンドの重なりの問題がなくても好きなように停止/再生できるaudioPlayerインスタンスが1つだけあります。 –

0

を再生している場合は、同時に2つのオーディオトラックを再生したくない場合はチェックして初期化しますAVAudioPlayer の共有インスタンスを使用することをお勧めします。パフォーマンスが向上し、コントローラーでインスタンスをstatic varと定義することができます。各セルでアクセス可能です。私は音楽palyerアプリケーションを開発している、と私はMusicPlayManagerで共有インスタンスを使用

0

:あなたのViewControllerで

class MusicPlayManager{ 

    var player : AVAudioPlayer? 

    static let sharedInstance = MusicPlayManager.init() 

    private override init() { 
     super.init() 

    } 

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

、あなたはMusicPlayManager.sharedInstance.player

関連する問題