web-dev-qa-db-ja.com

SwiftのUISliderとしてのオーディオ再生の進捗

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()
    }

どんな援助も大歓迎です。

17
allocate

上記の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)

}
25
allocate

前回のコメントを詳しく述べると、これが私がそれを実装した方法であり、かなりうまく機能しているようです。任意の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に設定します

7
Dare

特にSwiftの場合、次のように処理できました。

  1. 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)
    
    }
    
  2. 私のプレーヤーは、スクラバーの値で設定された時間に音楽を再生するように設定されていました。

    @IBAction func scrub(sender: AnyObject) {
    
        player.currentTime = NSTimeInterval(scrubSlider.value)
    
    }
    
4
Delabi

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)
 }
4
BlackVoid