AVAudioPlayer enters an infinite loop if pause() is called very close to the end, and then playback is resumed with play()
Originator: | digipom | ||
Number: | rdar://32664362 | Date Originated: | June 8th, 2017 |
Status: | New | Resolved: | |
Product: | iOS SDK | Product Version: | 10.3.2 |
Classification: | Serious bug | Reproducible: | Yes |
Area: AVFoundation Summary: When stopping an AVAudioPlayer close to the end and then playing it again, it will enter into an infinite loop but without any audio being heard. The audio will not come back even after repeated play()/pause() attempts unless the player is de-inited and recreated. Steps to Reproduce: This can be reproduced by playing back audio, and then tapping pause just before the end. If done at the right moment, the playback will enter into an infinite loop without anything being heard. This code will reproduce it: import UIKit import AVFoundation class ViewController: UIViewController, AVAudioPlayerDelegate { var player: AVAudioPlayer? var intercept: Bool = true @IBOutlet weak var progressView: UIProgressView! @IBOutlet weak var playButton: UIButton! override func viewDidLoad() { super.viewDidLoad() let displayLink = CADisplayLink.init(target: self, selector: #selector(pollCurrentTime)) displayLink.add(to: RunLoop.main, forMode: RunLoopMode.defaultRunLoopMode) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } @IBAction func onPlayButtonTapped(_ sender: UIButton) { let asset = NSDataAsset(name:"TestRecording")! player = try! AVAudioPlayer(data: asset.data, fileTypeHint: "m4a") player!.delegate = self player!.play() playButton.isEnabled = false } func pollCurrentTime() { if let player = player { progressView.progress = Float(player.currentTime / player.duration) if intercept && progressView.progress > 0.97 { intercept = false player.pause() DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) { player.play() } } } else { progressView.progress = 0 } } func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) { cleanup() } func audioPlayerDecodeErrorDidOccur(_ player: AVAudioPlayer, error: Error?) { cleanup() } private func cleanup() { self.player = nil playButton.isEnabled = true intercept = true } } Expected Results: This should not happen. Observed Results: Happens on iPhone 6, iOS 10.3.2 Version: 10.3.2 (14F89) Notes: Additional notes: Seems that currentTime goes to 0 even though we paused close to the end, but neither of the two delegate methods were called. Configuration: iPhone 6s
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!
I actually have the same issue, just want to know if you have fix it? ----- edit: Based on my test, if you pause() or stop() the player at the very last 0.2s, it will enter the loop.