//

//  ViewController.swift

//  MusicPlayer

//

//  Created by stayfoolish on 2018. 8. 27..

//  Copyright © 2018년 stayfoolish. All rights reserved.

//


import UIKit

import AVFoundation


class ViewController: UIViewController, AVAudioPlayerDelegate {


    var player: AVAudioPlayer!

    var timer: Timer!

    

    @IBOutlet var playPauseButton: UIButton!

    @IBOutlet var timeLabel: UILabel!

    @IBOutlet var progressSlider: UISlider!

    

    

    func initializePlayer() {

        

        guard let soundAsset: NSDataAsset = NSDataAsset(name: "sound") else {

            print("음원 파일 에셋을 가져올 수 없습니다")

            return

        }

        

        do {

            try self.player = AVAudioPlayer(data: soundAsset.data)

            self.player.delegate = self

        } catch let error as NSError {

            print("플레이어 초기화 실패")

            print("코드 : \(error.code), 메세지 : \(error.localizedDescription)")

        }

        

        self.progressSlider.maximumValue = Float(self.player.duration)

        self.progressSlider.minimumValue = 0

        self.progressSlider.value = Float(self.player.currentTime)

    }

    

    func updateTimeLabelText(time: TimeInterval) {

        let minute: Int = Int(time / 60)

        let second: Int = Int(time.truncatingRemainder(dividingBy: 60))

        let milisecond: Int = Int(time.truncatingRemainder(dividingBy: 1) * 100)

        

        let timeText: String = String(format: "%02ld:%02ld:%02ld", minute, second, milisecond)

        

        self.timeLabel.text = timeText

    }

    

    func makeAndFireTimer() {

        self.timer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true, block: { [unowned self] (timer: Timer) in

            

            if self.progressSlider.isTracking { return }

            

            self.updateTimeLabelText(time: self.player.currentTime)

            self.progressSlider.value = Float(self.player.currentTime)

        })

        self.timer.fire()

    }

    

    func invalidateTimer() {

        self.timer.invalidate()

        self.timer = nil

    }

    

    func addViewsWithCode() {

        self.addPlayPauseButton()

        self.addTimeLabel()

        self.addProgressSlider()

    }

    

    func addPlayPauseButton() {

        

        let button: UIButton = UIButton(type: UIButtonType.custom)

        button.translatesAutoresizingMaskIntoConstraints = false

        

        self.view.addSubview(button)

        

        button.setImage(UIImage(named: "button_play"), for: UIControlState.normal)

        button.setImage(UIImage(named: "button_pause"), for: UIControlState.selected)

        

        button.addTarget(self, action: #selector(self.touchUpPlayPauseButton(_:)), for: UIControlEvents.touchUpInside)

        

        let centerX: NSLayoutConstraint

        centerX = button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor)

        

        let centerY: NSLayoutConstraint

        centerY = NSLayoutConstraint(item: button, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.centerY, multiplier: 0.8, constant: 0)

        

        let width: NSLayoutConstraint

        width = button.widthAnchor.constraint(equalTo: self.view.widthAnchor, multiplier: 0.5)

        

        let ratio: NSLayoutConstraint

        ratio = button.heightAnchor.constraint(equalTo: button.widthAnchor, multiplier: 1)

        

        centerX.isActive = true

        centerY.isActive = true

        width.isActive = true

        ratio.isActive = true

        

        self.playPauseButton = button

    }

    

    func addTimeLabel() {

        let timeLabel: UILabel = UILabel()

        timeLabel.translatesAutoresizingMaskIntoConstraints = false

        

        self.view.addSubview(timeLabel)

        

        timeLabel.textColor = UIColor.black

        timeLabel.textAlignment = NSTextAlignment.center

        timeLabel.font = UIFont.preferredFont(forTextStyle: UIFontTextStyle.headline)

        

        let centerX: NSLayoutConstraint

        centerX = timeLabel.centerXAnchor.constraint(equalTo: self.playPauseButton.centerXAnchor)

        

        let top: NSLayoutConstraint

        top = timeLabel.topAnchor.constraint(equalTo: self.playPauseButton.bottomAnchor, constant: 8)

        

        centerX.isActive = true

        top.isActive = true

        

        self.timeLabel = timeLabel

        self.updateTimeLabelText(time: 0)

    }

    

    func addProgressSlider() {

        let slider: UISlider = UISlider()

        slider.translatesAutoresizingMaskIntoConstraints = false

        

        self.view.addSubview(slider)

        

        slider.minimumTrackTintColor = UIColor.red

        

        slider.addTarget(self, action: #selector(self.sliderValueChanged(_:)), for: UIControlEvents.valueChanged)

        

        let safeAreaGuide: UILayoutGuide = self.view.safeAreaLayoutGuide

        

        let centerX: NSLayoutConstraint

        centerX = slider.centerXAnchor.constraint(equalTo: self.timeLabel.centerXAnchor)

        

        let top: NSLayoutConstraint

        top = slider.topAnchor.constraint(equalTo: self.timeLabel.bottomAnchor, constant: 8)

        

        let leading: NSLayoutConstraint

        leading = slider.leadingAnchor.constraint(equalTo: safeAreaGuide.leadingAnchor, constant: 16)

        

        let trailing: NSLayoutConstraint

        trailing = slider.trailingAnchor.constraint(equalTo: safeAreaGuide.trailingAnchor, constant: -16)

        

        centerX.isActive = true

        top.isActive = true

        leading.isActive = true

        trailing.isActive = true

        

        self.progressSlider = slider

    }

    

    override func viewDidLoad() {

        super.viewDidLoad()

        // Do any additional setup after loading the view, typically from a nib.

        self.initializePlayer()

    }


    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

    

    func audioPlayerDecodeErrorDidOccur(_ player: AVAudioPlayer, error: Error?) {

        

        guard let error: Error = error else {

            print("오디오 플레이어 디코드 오류발생")

            return

        }

        

        let message: String

        message = "오디오 플레이어 오류 발생 \(error.localizedDescription)"

        

        let alert: UIAlertController = UIAlertController(title: "알림", message: message, preferredStyle: UIAlertControllerStyle.alert)

        

        let okAction: UIAlertAction = UIAlertAction(title: "확인", style: UIAlertActionStyle.default) { (action: UIAlertAction) -> Void in

            

            self.dismiss(animated: true, completion: nil)

        }

        

        alert.addAction(okAction)

        self.present(alert, animated: true, completion: nil)

    }

    

    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {

        self.playPauseButton.isSelected = false

        self.progressSlider.value = 0

        self.updateTimeLabelText(time: 0)

        self.invalidateTimer()

    }

    

    

    @IBAction func touchUpPlayPauseButton(_ sender: UIButton){

        

        sender.isSelected = !sender.isSelected

        

        if sender.isSelected{

            self.player?.play()

        } else {

            self.player?.pause()

        }

        

        if sender.isSelected {

            self.makeAndFireTimer()

        }else {

            self.invalidateTimer()

        }

        

    }


    @IBAction func sliderValueChanged(_ sender: UISlider) {

        self.updateTimeLabelText(time: TimeInterval(sender.value))

        if sender.isTracking { return }

        self.player.currentTime = TimeInterval(sender.value)

    }

    

    

}



+ Recent posts