Objective-Cでこれを達成することについていくつかの投稿を見てきましたが、Swiftで同じことを行うことができませんでした。
具体的には、以下のaddPeriodicTimeObserverForInterval
の実装方法がわかりません。
var player : AVAudioPlayer! = nil
@IBAction func playAudio(sender: AnyObject) {
playButton.selected = !(playButton.selected)
if playButton.selected {
let fileURL = NSURL(string: toPass)
player = AVAudioPlayer(contentsOfURL: fileURL, error: nil)
player.numberOfLoops = -1 // play indefinitely
player.prepareToPlay()
player.delegate = self
player.play()
startTime.text = "\(player.currentTime)"
endTime.text = NSString(format: "%.1f", player.duration)
} else {
player.stop()
}
どんな援助も大歓迎です。
上記のDareの提案のおかげで、これをどのように達成したかを以下に示します。
var updater : CADisplayLink! = nil
@IBAction func playAudio(sender: AnyObject) {
playButton.selected = !(playButton.selected)
if playButton.selected {
updater = CADisplayLink(target: self, selector: Selector("trackAudio"))
updater.frameInterval = 1
updater.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSRunLoopCommonModes)
let fileURL = NSURL(string: toPass)
player = AVAudioPlayer(contentsOfURL: fileURL, error: nil)
player.numberOfLoops = -1 // play indefinitely
player.prepareToPlay()
player.delegate = self
player.play()
startTime.text = "\(player.currentTime)"
theProgressBar.minimumValue = 0
theProgressBar.maximumValue = 100 // Percentage
} else {
player.stop()
}
}
func trackAudio() {
var normalizedTime = Float(player.currentTime * 100.0 / player.duration)
theProgressBar.value = normalizedTime
}
@IBAction func cancelClicked(sender: AnyObject) {
player.stop()
updater.invalidate()
dismissViewControllerAnimated(true, completion: nil)
}
前回のコメントを詳しく述べると、これが私がそれを実装した方法であり、かなりうまく機能しているようです。任意のSwift修正は大歓迎です、私は今のところまだObj-Cの男です。
@IBAction func playAudio(sender: AnyObject) {
var playing = false
if let currentPlayer = player {
playing = player.playing;
}else{
return;
}
if !playing {
let filePath = NSBundle.mainBundle().pathForResource("3e6129f2-8d6d-4cf4-a5ec-1b51b6c8e18b", ofType: "wav")
if let path = filePath{
let fileURL = NSURL(string: path)
player = AVAudioPlayer(contentsOfURL: fileURL, error: nil)
player.numberOfLoops = -1 // play indefinitely
player.prepareToPlay()
player.delegate = self
player.play()
displayLink = CADisplayLink(target: self, selector: ("updateSliderProgress"))
displayLink.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode!)
}
} else {
player.stop()
displayLink.invalidate()
}
}
func updateSliderProgress(){
var progress = player.currentTime / player.duration
timeSlider.setValue(Float(progress), animated: false)
}
*ストーリーボードでタイムスライダーの範囲を0〜1に設定します
特にSwiftの場合、次のように処理できました。
scrubSlider
の最大値を、このメソッドでロードされた音楽ファイル(.mp3)の持続時間に設定しました
override func viewDidLoad() {
super.viewDidLoad()
do {
try player = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("bach", ofType: "mp3")!))
scrubSlider.maximumValue = Float(player.duration)
} catch {
//Error
}
_ = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: #selector(ViewController.updateScrubSlider), userInfo: nil, repeats: true)
}
私のプレーヤーは、スクラバーの値で設定された時間に音楽を再生するように設定されていました。
@IBAction func scrub(sender: AnyObject) {
player.currentTime = NSTimeInterval(scrubSlider.value)
}
Swift 4:で構文が変更されました
updater = CADisplayLink(target: self, selector: #selector(self.trackAudio))
updater.preferredFramesPerSecond = 1
updater.add(to: RunLoop.current, forMode: RunLoopMode.commonModes)
そして、関数(私は以前progressSlider.maxValueをplayer.durationに設定しました):
@objc func trackAudio() {
progressSlider.value = Float(player!.currentTime)
}