Sim
Sim

Reputation: 76

How can I monitor currentPosition of AVMIDIPlayer, please?

I'm trying to make a simple music player. I want the label to display the current position of the AVMIDIPlayer. With my code the label is only updated once at the very beginning:

import UIKit
import AVFoundation
class ViewController: UIViewController {
    var player:AVMIDIPlayer = AVMIDIPlayer()
    var playerTime:Double = 999 {
        didSet {
            label.text = String(playerTime)
        }
    }

    @IBOutlet var label: UILabel!
    @IBAction func Play(_ sender: Any) {
        player.play()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        do {
            let audioPath = Bundle.main.path(forResource: “song”, ofType: "mid")
            try player = AVMIDIPlayer(contentsOf: NSURL(fileURLWithPath: audioPath!) as URL, soundBankURL: nil)
            playerTime = player.currentPosition
        }
        catch {
        }
    }
}

What have I missed, please? Thank you. Scarlett

Upvotes: 2

Views: 83

Answers (1)

nighttalker
nighttalker

Reputation: 946

The reason the label isn’t updating is you’re setting the text in viewDidLoad which is called only once. Use a Timer to update the label.

import UIKit
import AVFoundation
class ViewController: UIViewController {
    var player:AVMIDIPlayer = AVMIDIPlayer()
    var playerTime:Double = 999 {
        didSet {
            label.text = String(playerTime)
        }
    }
    var timer = Timer()

    @IBOutlet var label: UILabel!
    @IBAction func Play(_ sender: Any) {
        player.play()

        // this will execute every 0.1 seconds, allowing you to update the label.
        timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
            self.playerTime += 0.1

            let min = self.playerTime.truncatingRemainder(dividingBy: 3600)) / 60
            let sec = self.playerTime.truncatingRemainder(dividingBy: 60)

            self.label.text = String(format: "%02d:%02d", min, sec)
        }
    }

    func stop() {
        // when you stop playback
        timer.invalidate()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        do {
            let audioPath = Bundle.main.path(forResource: “song”, ofType: "mid")
            try player = AVMIDIPlayer(contentsOf: NSURL(fileURLWithPath: audioPath!) as URL, soundBankURL: nil)
            playerTime = player.currentPosition
        }
        catch {
        }

    }
}

Upvotes: 1

Related Questions